CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM

Read inside a class

Register Blogs Community New Posts Updated Threads Search

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   July 8, 2010, 16:00
Default Read inside a class
  #1
Member
 
Tony
Join Date: Jun 2010
Posts: 54
Rep Power: 16
tonyuprm is on a distinguished road
Hi,

I'm trying to create a function within a class which reads into a dictionary file but I keep getting the following error:

error: ārunTimeā was not declared in this scope

Here is the function in which I'm trying to do this.

void ReadInput()
{
IOdictionary turbineInputDict
(
IOobject
(
"turbineInputDict",
runTime.time().constant(),
runTime,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
}

Is there some way to do this?

Thanks,

Tony
tonyuprm is offline   Reply With Quote

Old   July 8, 2010, 16:09
Default
  #2
Member
 
Juho Peltola
Join Date: Mar 2009
Location: Finland
Posts: 89
Rep Power: 17
juho is on a distinguished road
At least one way to do it: If your class has a volume field as a member variable, for example U_, you can access the time directories with:


IOdictionary turbineInputDict
(
IOobject
(
"turbineInputDict",
U_.time().constant(),
U_.mesh(),
IOobject::MUST_READ,
IOobject::NO_WRITE
)
juho is offline   Reply With Quote

Old   July 8, 2010, 16:47
Default
  #3
Member
 
Tony
Join Date: Jun 2010
Posts: 54
Rep Power: 16
tonyuprm is on a distinguished road
Hi Juho,

I am still getting the same error. I dont have a volume field as a member variable. Is there any other way to do this?

Thanks,

Tony
tonyuprm is offline   Reply With Quote

Old   July 9, 2010, 03:24
Default
  #4
Senior Member
 
Kathrin Kissling
Join Date: Mar 2009
Location: Besigheim, Germany
Posts: 134
Rep Power: 17
kathrin_kissling is on a distinguished road
Hi Tony,

this would be a snippet I know, it works.


IOdictionary setSomethingDict
(
IOobject
(
"setSomethingDict",
runTime.system(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);

The dictonary would be present in the system folder respectively.
But could you try just to get an information whether runTime is present at all.

Did you include
# include "createTime.H"

Can you try to get the info statement

Info<< "Time = " << runTime.value() << endl;

From what class are you trying to call the dictionary?

Hope this helps

Kathrin
kathrin_kissling is offline   Reply With Quote

Old   July 9, 2010, 04:23
Default
  #5
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by tonyuprm View Post
Hi Juho,

I am still getting the same error. I dont have a volume field as a member variable. Is there any other way to do this?
If you don't have anything that somehow resolves to an objectRegistry, you'll have great difficulty obtaining the IOobject that you need for the IOdictionary ... and difficulties registering that IOobject as well!

If you don't have any objectRegistry at all, I'm guessing that you are writing a utility that works with dictionaries directly. In this case, you can just use an IFstream directly - see the source code for expandDictionary, perhaps that does it for you.
olesen is offline   Reply With Quote

Old   July 12, 2010, 16:43
Default
  #6
Member
 
Tony
Join Date: Jun 2010
Posts: 54
Rep Power: 16
tonyuprm is on a distinguished road
Quote:
At least one way to do it: If your class has a volume field as a member variable, for example U_, you can access the time directories with:


IOdictionary turbineInputDict
(
IOobject
(
"turbineInputDict",
U_.time().constant(),
U_.mesh(),
IOobject::MUST_READ,
IOobject::NO_WRITE
)
Hi,

I will eventually use velocity inside this class so I guess there should be a volume field inside the class. How can I point to the velocity field from inside my class? I'm guessing U_ is a pointer.

Thanks,

Tony
tonyuprm is offline   Reply With Quote

Old   July 13, 2010, 03:19
Default
  #7
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by tonyuprm View Post
Hi,

I will eventually use velocity inside this class so I guess there should be a volume field inside the class. How can I point to the velocity field from inside my class? I'm guessing U_ is a pointer.
Not a pointer, but a (const or non-const) reference. As an example you can take a look at src/turbulenceModels/compressible/turbulenceModel/turbulenceModel.{C,H} for an idea. Note that you'll need a non-const reference if you actually want to manipulate the velocity field somehow.
olesen is offline   Reply With Quote

Old   July 13, 2010, 12:07
Default
  #8
Member
 
Tony
Join Date: Jun 2010
Posts: 54
Rep Power: 16
tonyuprm is on a distinguished road
Thanks, that worked.

Now I'm running into a new problem. I am reading the variables inside my constructor. I want to use the variables I read inside other functions of my class. The variables are being read inside my constructor but I cannot use them outside the constructor. Here is the part of the code that does this. When it prints inside the constructor the values are correct (the ones read) but when I try to use the print() function it will just print a null variable.

Code:
// * * * * * * * * * * * * *  Declarations * * * * * * * * * * * * * * * * * //

static const scalar degrad=Foam::mathematicalConstant::pi/180.0;    //degrees to radian conversion
tensor RM;                                //Rotation matrix
vector bladePointDummie;                        //dummie for matrix multiplication
static int turbineNum;
static const List<vector> nacLocation;
static const List<scalar> theta;
static const List<scalar> phiz;
static const List<scalar> hubLength;
static const List<scalar> bladeNumber;
static const List<scalar> bladeLength;
static const List<scalar> bladeAngle;
static const List<scalar> pointNumber;
static const List<scalar> hubRadius;
static const List<scalar> wrad;
static const List<scalar> epsilon;
static const List<scalar> spheredelta;
static const List<scalar> smearRadii;


// * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * //
windTurbines::windTurbines(volVectorField& U_)
{

IOdictionary turbineInputDict
(
IOobject
(
"turbineInputDict",
U_.time().constant(),
U_.mesh(),
IOobject::MUST_READ,
IOobject::NO_WRITE
) 
);


static const List<vector> nacLocation
(
    turbineInputDict.lookup("nacLocation")
);

Info<<"test"<<endl;
Info<<nacLocation<<endl;
Info<<"test"<<endl;

}

// * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * * //

void windTurbines::print()
{
Info<<"test"<<endl;
Info<< nacLocation <<endl;
Info<<"test"<<endl;

}
tonyuprm is offline   Reply With Quote

Old   July 13, 2010, 13:34
Default
  #9
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by tonyuprm View Post
Thanks, that worked.

Now I'm running into a new problem. I am reading the variables inside my constructor. I want to use the variables I read inside other functions of my class. The variables are being read inside my constructor but I cannot use them outside the constructor. Here is the part of the code that does this. When it prints inside the constructor the values are correct (the ones read) but when I try to use the print() function it will just print a null variable.

Code:
// * * * * * * * * * * * * *  Declarations * * * * * * * * * * * * * * * * * //

static const scalar degrad=Foam::mathematicalConstant::pi/180.0;    //degrees to radian conversion
tensor RM;                                //Rotation matrix
vector bladePointDummie;                        //dummie for matrix multiplication
static int turbineNum;
static const List<vector> nacLocation;
static const List<scalar> theta;
static const List<scalar> phiz;
static const List<scalar> hubLength;
static const List<scalar> bladeNumber;
static const List<scalar> bladeLength;
static const List<scalar> bladeAngle;
static const List<scalar> pointNumber;
static const List<scalar> hubRadius;
static const List<scalar> wrad;
static const List<scalar> epsilon;
static const List<scalar> spheredelta;
static const List<scalar> smearRadii;


// * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * //
windTurbines::windTurbines(volVectorField& U_)
{

IOdictionary turbineInputDict
(
IOobject
(
"turbineInputDict",
U_.time().constant(),
U_.mesh(),
IOobject::MUST_READ,
IOobject::NO_WRITE
) 
);


static const List<vector> nacLocation
(
    turbineInputDict.lookup("nacLocation")
);

Info<<"test"<<endl;
Info<<nacLocation<<endl;
Info<<"test"<<endl;

}

// * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * * //

void windTurbines::print()
{
Info<<"test"<<endl;
Info<< nacLocation <<endl;
Info<<"test"<<endl;

}

You have multiple problems.
1. You declare and use nacLocation within the constructor, which will obviously mask the class-level variable.
2. Making nacLocation static means that you cannot really be reading from an IOdictionary as you are currently attempting since that bit of code relies on non-static members.
olesen is offline   Reply With Quote

Old   July 13, 2010, 13:44
Default
  #10
Member
 
Tony
Join Date: Jun 2010
Posts: 54
Rep Power: 16
tonyuprm is on a distinguished road
Is there a way to read the variable and declare it as static const? I want to be able to use this variable throughout the class, not only inside the constructor.

Thanks,

Tony
tonyuprm is offline   Reply With Quote

Old   July 13, 2010, 13:52
Default
  #11
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by tonyuprm View Post
Is there a way to read the variable and declare it as static const? I want to be able to use this variable throughout the class, not only inside the constructor.
I think you are having a slight misunderstanding here. If you declare the variable as 'static const' this means two things:
- static = it will be available directly without a class instance
- const = the contents cannot be adjusted.

If you think about the first part, however, that means that you would expect this following code snippet to work:
Code:
int main()
{
    Info<< "locations: " << windturbines.nacLocation << endl;
    return 0;
}
Note that I didn't supply any other information about the case, the IOdictionary or whatever. You've declared that the data member is available directly without a class instance, which is how I've used it.
olesen is offline   Reply With Quote

Old   July 13, 2010, 14:14
Default
  #12
Member
 
Tony
Join Date: Jun 2010
Posts: 54
Rep Power: 16
tonyuprm is on a distinguished road
I do want it to be static and constant. But the thing is I want to declare the variable as I read it. I can do this inside the constructor but then the variable cannot be accessed outside the constructor by member functions. What I would like to do is declare the variable the following way:

const List<vector> nacLocation(turbineInputDict.lookup("nacLocation") );

and be able to use it within all class member functions. If I do this inside the constructor my member functions cannot access this variable.

What I have tried in order to accomplish this is declaring a variable in my class (outside the constructor) as static. Then inside my constructor I create another variable as a const which reads the data from the dictionary file and then stores it on the static variable created outside the constructor.

Here is the code I have so far:

Code:
// * * * * * * * * * * * * *  Declarations * * * * * * * * * * * * * * * * * //

static const scalar degrad=Foam::mathematicalConstant::pi/180.0;    //degrees to radian conversion
tensor RM;                                //Rotation matrix
vector bladePointDummie;                        //dummie for matrix multiplication

static int turbNum;
static List<vector> nacLocation;
static List<scalar> theta;
static List<scalar> phiz;
static List<scalar> hubLength;
static List<scalar> bladeNumber;
static List<scalar> bladeLength;
static List<scalar> bladeAngle;
static List<scalar> pointNumber;
static List<scalar> hubRadius;
static List<scalar> wrad;
static List<scalar> epsilon;
static List<scalar> spheredelta;
static List<scalar> smearRadii;


// * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * //
windTurbines::windTurbines(volVectorField& U_)
{

IOdictionary turbineInputDict
(
IOobject
(
"turbineInputDict",
U_.time().constant(),
U_.mesh(),
IOobject::MUST_READ,
IOobject::NO_WRITE
) 
);

const int turbNum2 (readScalar(turbineInputDict.lookup("turbNum")));
const List<vector> nacLocation2(turbineInputDict.lookup("nacLocation"));
const List<scalar> theta2(turbineInputDict.lookup("theta"));
const List<scalar> phiz2(turbineInputDict.lookup("phiz"));
const List<scalar> hubLength2(turbineInputDict.lookup("hubLength"));
const List<scalar> bladeNumber2(turbineInputDict.lookup("bladeNumber"));
const List<scalar> bladeLength2(turbineInputDict.lookup("bladeLength"));
const List<scalar> bladeAngle2(turbineInputDict.lookup("bladeAngle"));
const List<scalar> pointNumber2(turbineInputDict.lookup("pointNumber"));
const List<scalar> hubRadius2(turbineInputDict.lookup("hubRadius"));
const List<scalar> wrad2(turbineInputDict.lookup("wrad"));
const List<scalar> epsilon2(turbineInputDict.lookup("epsilon"));
const List<scalar> spheredelta2(turbineInputDict.lookup("spheredelta"));
const List<scalar> smearRadii2(turbineInputDict.lookup("smearRadii"));

turbNum=turbNum2;
nacLocation=nacLocation2;
theta=theta2;
phiz=phiz2;
hubLength=hubLength2;
bladeNumber=bladeNumber2;
bladeLength=bladeLength2;
bladeAngle=bladeAngle2;
pointNumber=pointNumber2;
hubRadius=hubRadius2;
wrad=wrad2;
epsilon=epsilon2;
spheredelta=spheredelta2;
smearRadii=smearRadii2;

}
tonyuprm is offline   Reply With Quote

Old   July 14, 2010, 03:35
Default
  #13
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by tonyuprm View Post
I do want it to be static and constant. But the thing is I want to declare the variable as I read it. I can do this inside the constructor but then the variable cannot be accessed outside the constructor by member functions. What I would like to do is declare the variable the following way:

const List<vector> nacLocation(turbineInputDict.lookup("nacLocation") );

and be able to use it within all class member functions. If I do this inside the constructor my member functions cannot access this variable.

What I have tried in order to accomplish this is declaring a variable in my class (outside the constructor) as static. Then inside my constructor I create another variable as a const which reads the data from the dictionary file and then stores it on the static variable created outside the constructor.

Here is the code I have so far:

Code:
// * * * * * * * * * * * * *  Declarations * * * * * * * * * * * * * * * * * //

static const scalar degrad=Foam::mathematicalConstant::pi/180.0;    //degrees to radian conversion
tensor RM;                                //Rotation matrix
vector bladePointDummie;                        //dummie for matrix multiplication

static int turbNum;
static List<vector> nacLocation;
static List<scalar> theta;
static List<scalar> phiz;
static List<scalar> hubLength;
static List<scalar> bladeNumber;
static List<scalar> bladeLength;
static List<scalar> bladeAngle;
static List<scalar> pointNumber;
static List<scalar> hubRadius;
static List<scalar> wrad;
static List<scalar> epsilon;
static List<scalar> spheredelta;
static List<scalar> smearRadii;


// * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * //
windTurbines::windTurbines(volVectorField& U_)
{

IOdictionary turbineInputDict
(
IOobject
(
"turbineInputDict",
U_.time().constant(),
U_.mesh(),
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);

const int turbNum2 (readScalar(turbineInputDict.lookup("turbNum")));
const List<vector> nacLocation2(turbineInputDict.lookup("nacLocation"));
const List<scalar> theta2(turbineInputDict.lookup("theta"));
const List<scalar> phiz2(turbineInputDict.lookup("phiz"));
const List<scalar> hubLength2(turbineInputDict.lookup("hubLength"));
const List<scalar> bladeNumber2(turbineInputDict.lookup("bladeNumber"));
const List<scalar> bladeLength2(turbineInputDict.lookup("bladeLength"));
const List<scalar> bladeAngle2(turbineInputDict.lookup("bladeAngle"));
const List<scalar> pointNumber2(turbineInputDict.lookup("pointNumber"));
const List<scalar> hubRadius2(turbineInputDict.lookup("hubRadius"));
const List<scalar> wrad2(turbineInputDict.lookup("wrad"));
const List<scalar> epsilon2(turbineInputDict.lookup("epsilon"));
const List<scalar> spheredelta2(turbineInputDict.lookup("spheredelta"));
const List<scalar> smearRadii2(turbineInputDict.lookup("smearRadii"));

turbNum=turbNum2;
nacLocation=nacLocation2;
theta=theta2;
phiz=phiz2;
hubLength=hubLength2;
bladeNumber=bladeNumber2;
bladeLength=bladeLength2;
bladeAngle=bladeAngle2;
pointNumber=pointNumber2;
hubRadius=hubRadius2;
wrad=wrad2;
epsilon=epsilon2;
spheredelta=spheredelta2;
smearRadii=smearRadii2;

}

Okay, now I see what you are trying to do ... it won't work the way you are attempting it though. Use methods instead of accessing the variables directly and you'll get what you want. Here's a chopped down rough idea:

Code:
// the .H file:
class windTurbines
{
    // Private data

    // Static data members
    static List<vector> nacLocation_;
    static List<scalar> hubRadius_;

public:


    //- Construct from dictionary
    windTurbines(const dictionary& dict);


    //- initialize static variables
    static void initFromDict(const dictionary& dict);


    // Access

    static const List<vector>& nacLocation()
    {
        return nacLocation_;
    }

    static const List<scalar>& hubRadius()
    {
        return hubRadius_;
    }

};


// the .C file

// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

List<vector> windTurbines::nacLocation_;
List<vector> windTurbines::hubRadius_;


// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //

void windTurbines::initFromDict(const dictionary& dict)
{
    dict.lookup("nacLocation") >> nacLocation_;
    dict.lookup("hubRadius") >> hubRadius_;
}


// * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * //
windTurbines::windTurbines(const dictionary& dict)
{
    initFromDict(dict);
}
To use this code, you could use this type of code snippet:
Code:
Info<< "location: " << windTurbines.nacLocation() << endl;

windTurbines.initFromDict
(
    IOdictionary
    (
        IOobject
        (
            "turbineInputDict",
            U.time().constant(),
            U.mesh(),
            IOobject::MUST_READ,
            IOobject::NO_WRITE
        )
    )
);

Info<< "location: " << windTurbines.nacLocation() << endl;
Note that while the storage of nacLocation_ etc is no longer const (if it were, you couldn't read into it later), the access via the nacLocation() method *is* const and thus delivers what you want.

Of course when you see the code, you'll notice something else: almost everything is static access, so you don't really need the constructor either.

BTW: from the data organization with lots of lists of values, it looks like you are converting a Fortran program. Why isn't a single windTurbine the base class instead?
For example,

Code:
// the .H file:
class windTurbines
{
    // Private data
    static vector nacLocation_;
    static scalar hubRadius_;

public:

    //- Construct from dictionary entry
    windTurbine(const dictionary& dict);

    // Access
    const vector& nacLocation() const
    {
        return nacLocation_;
    }

    scalar hubRadius() const
    {
        return hubRadius_;
    }
};


// the .C file
// * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * * * //
windTurbine::windTurbine(const dictionary& dict)
:
    nacLocation_(dict.lookup("nacLocation")),
    hubRadius_(readScalar(dict.lookup("hubRadius"))
{}
And then you could simply have a List<windTurbine> to store everything.
IMO it is much more logical that way and you could use this type of construct:
Code:
    List<windTurbine> turbines;
    // some code

    // later
    forAll(turbines, turbineI)
    {
       Info<<"turbine:" << turbineI
           << " nacLocation:" << turbines[turbineI].nacLocation()
           << " hubRadius:" << turbines[turbineI].hubRadius()
           << endl;
    }
To read in your list, you'd probably find an IOPtrList useful. There are several examples in the OpenFOAM code base, the PorousZones is one that immediately falls to mind.
olesen is offline   Reply With Quote

Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Field value inside a boundary condition class pcaron OpenFOAM Programming & Development 14 October 17, 2022 10:40
OpenFOAM on MinGW crosscompiler hosted on Linux allenzhao OpenFOAM Installation 127 January 30, 2009 20:08
Phase locked average in run time panara OpenFOAM 2 February 20, 2008 15:37
Errors running allwmake in OpenFOAM141dev with WM_COMPILE_OPTION%3ddebug unoder OpenFOAM Installation 11 January 30, 2008 21:30
meshing F1 front wing Steve FLUENT 0 April 17, 2003 13:37


All times are GMT -4. The time now is 19:07.