CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   multiphaseEulerFoam: PtrDictionary<phaseModel> phases_ of multiphasesystem fluid (https://www.cfd-online.com/Forums/openfoam-programming-development/128930-multiphaseeulerfoam-ptrdictionary-phasemodel-phases_-multiphasesystem-fluid.html)

maybee January 24, 2014 05:45

multiphaseEulerFoam: PtrDictionary<phaseModel> phases_ of multiphasesystem fluid
 
hi,

when creating the object multiphasesystem fluid (U,phi) in solver multiphaseEulerFoam (see createFields.H) the submember "PtrDictionary<phaseModel> phases_" is initialized in the constructor of "multiphasesystem" with

Code:

phases_(lookup("phases"), phaseModel::iNew(U.mesh())),
"phases" is a entry within file "transportProperties" where the coexistant phases of the case are briefly described (no initial field is given here ! ).

Later in the solvers source code when solving for the phasefractions with method solve() and within this method solveAlphas "PtrDictionary<phaseModel> phases_" is apperently used for accessing the phasefraction fields like

Code:

forAllIter(PtrDictionary<phaseModel>, phases_, iter) 
        {
            phaseModel& phase = iter();   
            volScalarField& alpha = phase;
          .
          .
          .
        }

I have two questions about this:

1. When initializing "PtrDictionary<phaseModel> phases_" in the first codesnippet are the objects of type "phaseModel" which the pointers of "PtrDictionary<phaseModel> phases_" are pointing to initialized too? If yes, in what way are they stored and can they be accessed without using "PtrDictionary<phaseModel> phases_"?

2. I suggest that with the code in the second codesnippet the phasefractions (volScalarFields) of "PtrDictionary<phaseModel> phases_" are accessed and changed, but I can't find any code in the previous solver-code where the initial phasefraction fields (which are stored in files of the 0 folder, e.g. see 0 folder of example case bubble column -> files alphaair, alphawater) are saved in the elements (phaseModel objects) of "PtrDictionary<phaseModel> phases_" . Can someone explain me where this is happening?

greetings
maybee

GerhardHolzinger January 24, 2014 06:41

Have a look on the class phaseModel.


There you might see - otherwise you need to believe me - that the class phaseModel is derived from the class volScalarField.

Code:

class phaseModel
:
    public volScalarField
{
/* class definition */
}

So, the class phaseModel is actually an extended volScalarField. Now, the question is, what is stored in this volScalarField?

The answer lies in phaseModel.C. In the constructor of the class to be precise.

Code:

Foam::phaseModel::phaseModel
(
    const word& name,
    const dictionary& phaseDict,
    const fvMesh& mesh
)
:
    volScalarField
    (
        IOobject
        (
            "alpha" + name,
            mesh.time().timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        mesh
    ),

To understand the meaning of the code above you need to find out what an initialization list of a constructor in C++ is. However, the short answer is: phaseModel stores the volume fraction directly.

Thus, the following code is perfectly ok.

Code:

forAllIter(PtrDictionary<phaseModel>, fluid.phases(), iter)
{
    phaseModel& phase = iter();
    const volScalarField& alpha = phase;



To your first question:

As multiphaseEulerFoam supports n phases, you might want to use an inteligent data structure to store the phases. You can think of the PtrDictionary as a list in which each phase is an entry. So the solver is written in a way, that whenever something applies to all phases, this list is traversed. Thus, the programmer does not need to care how many phases there will be.

So the access to the phases via the PtrDictionary and a forAll loop is the only thing that makes really sense in this case.

If you have a solver with a fixed number of phases, such as twoPhaseEulerFoam, then you can omit the PtrDictionary and access the phases directly (as phase1 and phase2).

maybee January 24, 2014 08:07

hi,

first of all thx for the answer, but I still have some quesitons left.
In the work I am currently doing I have to implement about seven fields for each phase and afterwards to access the fields seperately for different calculations.
I don't want to create this fields in the "createFields.H section" since they should be available for each phase and otherwise I would have to create the fields always manually in dependancy of the number of phases in the "createFields.H section". Sure, I can implement the fields in class "phaseModels", but how can I access the different fields within "PtrDictionary<phaseModel> phases_" afterwards? Any ideas how to do this?

Edit: Perhaps it would be good if I could understand the following forAllIter- loop, especially the operator () which is used on iter and define other operators that access the new fields I define in class phaseModel:

Code:


forAllIter(PtrDictionary<phaseModel>, phases_, iter)  //fuer alle Phasen
        {
            phaseModel& phase = iter();

I have already posted a thread, because of the operator () which is used on iter:

http://www.cfd-online.com/Forums/ope...ses_-iter.html

GerhardHolzinger January 24, 2014 08:58

Have a look on the phaseModel class.

You access the properties of a phase with access function of the phaseModel.

The following piece of code is from UEqns.H of multiphaseEulerFoam

Code:

volVectorField& U = phase.U();
This is the way how you can access your own fields.

The class phaseModel contains the velocity as private data. This is exactly the way you could implement your own fields.

maybee January 24, 2014 09:14

Code:

forAllIter(PtrDictionary<phaseModel>, fluid.phases(), iter)     
325 {
326    phaseModel& phase = iter();                   
327    const volScalarField& alpha = phase;   
328    volVectorField& U = phase.U();

Ok, but there is one thing that I still don't understand when looking at this:
In line 326 local object "phaseModel& phase" gets the content of "iter" which should be the actual phaseModel-object.
Afterwards in line 327 we get the phasefraction field out of "phase" with "const volScalarField& alpha = phase;" ? -> Is the fact that there is defined the "const volScalarField& alpha" extracting the phasefraction-field out of "phaseModel& phase" ?
And finally as you mentioned in line 328 we get the velocity field of the actuall phase with
Code:

volVectorField& U = phase.U()

GerhardHolzinger January 24, 2014 09:17

Quote:

Originally Posted by GerhardHolzinger (Post 471592)
Have a look on the class phaseModel.
the class phaseModel is derived from the class volScalarField.

Do you understand the concept of inheritance in object oriented programming?

maybee January 24, 2014 09:26

Quote:

Quote:
Originally Posted by GerhardHolzinger View Post
Have a look on the class phaseModel.
the class phaseModel is derived from the class volScalarField.

Do you understand the concept of inheritance in object oriented programming?
Generally yes. When an object of a class is created and the class is derived from one or more other classes the object also possesses all the members of the base-class(es).

Still, when looking at

Code:

forAllIter(PtrDictionary<phaseModel>, fluid.phases(), iter)     
325 {
326    phaseModel& phase = iter();                   
327    const volScalarField& alpha = phase;   
328    volVectorField& U = phase.U();

I don't know how "const volScalarField& alpha" directly becomes with line 327 the phasefraction field since "phase" has many submembers, e.g. "volVectorField U_;" ?

GerhardHolzinger January 24, 2014 09:31

As I wrote before, phaseModel is derived from volScalarField. So essentially the object IS the phase volume fraction field. If you take a look on the constructor of the class phaseModel, it reads the phase fraction field, when an object of the class phaseModel is created.

Furthermore, phaseModel contains a number of member data and methods. This data and methods provide the addional functionality you can observe being used in multiphaseEulerFoam.

Have a look at object orientation.

maybee January 27, 2014 06:05

hi again,

thx for the answers - it helped me a lot :).
One more question:

The "phaseModel constructor"

Code:

Foam::phaseModel::phaseModel
(
    const word& name,
    const dictionary& phaseDict,
    const fvMesh& mesh
)
.
.
.

takes three input parameters as shown above, but since the "phaseModel objects" are constructed like

Code:

phases_(lookup("phases"), phaseModel::iNew(U.mesh())),
in the initializer list of the "multiphasesystem constructor" with the construction of "PtrDictionary<phaseModel> phases_" I have to ask what are exactly the input parameters passed to the "phaseModel constructor" ?
My guess is that the input parameters are gathered by the input stream Istream& is (first input parameter) of the "PtrDictionary constructor":

Code:

template<class T>
  45 template<class INew>
  46 Foam::PtrDictionary<T>::PtrDictionary(Istream& is, const INew& iNew)
  47 :
  48    DictionaryBase<DLPtrList<T>, T>(is, iNew)
  49 {}

Is this right and if yes how or is there any reference to read how it is done?

greetings
maybee

GerhardHolzinger January 27, 2014 06:24

Obviously the method iNew() of the class phaseModel is used to construct the phaseModel objects.

If you have a look at the method iNew()

Code:

phaseModel
        (
            const word& phaseName,
            const dictionary& phaseDict,
            const fvMesh& mesh
        );

        //- Return clone
        autoPtr<phaseModel> clone() const;

        //- Return a pointer to a new phase created on freestore
        //  from Istream
        class iNew
        {
            const fvMesh& mesh_;

        public:

            iNew
            (
                const fvMesh& mesh
            )
            :
                mesh_(mesh)
            {}

            autoPtr<phaseModel> operator()(Istream& is) const
            {
                dictionaryEntry ent(dictionary::null, is);
                return autoPtr<phaseModel>
                (
                    new phaseModel(ent.keyword(), ent, mesh_)
                );
            }
        };

You will find the call to the constructor of the phaseModel class.

The internals of the way multiphaseEulerFoam are best explained by someone who took part in the development or by someone who understands the internals of OpenFOAM better than me.


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