CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM (https://www.cfd-online.com/Forums/openfoam/)
-   -   Read inside a class (https://www.cfd-online.com/Forums/openfoam/77973-read-inside-class.html)

tonyuprm July 8, 2010 15:00

Read inside a class
 
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

juho July 8, 2010 15:09

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
)

tonyuprm July 8, 2010 15:47

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

kathrin_kissling July 9, 2010 02:24

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

olesen July 9, 2010 03:23

Quote:

Originally Posted by tonyuprm (Post 266466)
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.

tonyuprm July 12, 2010 15:43

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

olesen July 13, 2010 02:19

Quote:

Originally Posted by tonyuprm (Post 266962)
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.

tonyuprm July 13, 2010 11:07

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;

}


olesen July 13, 2010 12:34

Quote:

Originally Posted by tonyuprm (Post 267072)
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.

tonyuprm July 13, 2010 12:44

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

olesen July 13, 2010 12:52

Quote:

Originally Posted by tonyuprm (Post 267092)
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.

tonyuprm July 13, 2010 13:14

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;

}


olesen July 14, 2010 02:35

Quote:

Originally Posted by tonyuprm (Post 267097)
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.


All times are GMT -4. The time now is 16:02.