psiReactionThermo class in OpenFOAM

The psiReactionThermo class in OpenFOAM

In the createFieds.H in coalChemistryFoam solver, a psiReactionThermo object is defined as:

1
2
autoPtr<psiReactionThermo> pThermo(psiReactionThermo::New(mesh));
psiReactionThermo& thermo = pThermo();

The object pThermo is initialized using the New function defined in psiReactionThermo.C as:

1
2
3
4
5
6
7
8
Foam::autoPtr<Foam::psiReactionThermo> Foam::psiReactionThermo::New
(
const fvMesh& mesh,
const word& phaseName
)
{
return basicThermo::New<psiReactionThermo>(mesh, phaseName);
}

Here the phaseName is defined as word::null. The return of this New function is defined in basicThermoTemplates.C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
template<class Thermo>
Foam::autoPtr<Thermo> Foam::basicThermo::New
(
const fvMesh& mesh,
const word& phaseName
)
{
IOdictionary thermoDict
(
IOobject
(
phasePropertyName(dictName, phaseName),
mesh.time().constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
)
);

typename Thermo::fvMeshConstructorTable::iterator cstrIter =
lookupThermo<Thermo, typename Thermo::fvMeshConstructorTable>
(
thermoDict,
Thermo::fvMeshConstructorTablePtr_
);

return autoPtr<Thermo>(cstrIter()(mesh, phaseName));
}

The dictName here is defined in basicThermo.C as:

1
const Foam::word Foam::basicThermo::dictName("thermophysicalProperties");

The phasePropertyName function is defined in basicThermo.H as:

1
2
3
4
5
6
7
8
static word phasePropertyName
(
const word& name,
const word& phaseName
)
{
return IOobject::groupName(name, phaseName);
}

Here in the New function the phasePropertyName will be thermophysicalProperties as the phaseName here is a word::null. The two parameters in New function are all settled, then we can go through the function body. First an IOdictionary object is built called thermoDict. This object will search the file which has a name of phasePropertyName in the constant folder. Then the cstrIter will be assigned with a function called lookupThermo. The types fvMeshConstructorTable and fvMeshConstructorTablePtr_ are all defined in the declareRunTimeSelectionTable in the psiReactionThermo.H:

1
2
3
4
5
6
7
8
declareRunTimeSelectionTable
(
autoPtr,
psiReactionThermo,
fvMesh,
(const fvMesh& mesh, const word& phaseName),
(mesh, phaseName)
);

This is a run time selection macro, we will not explain this in detail here. The function lookupThermo will be called then:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
template<class Thermo, class Table>
typename Table::iterator Foam::basicThermo::lookupThermo
(
const dictionary& thermoDict,
Table* tablePtr
)
{
if (thermoDict.isDict("thermoType"))
{
const dictionary& thermoTypeDict(thermoDict.subDict("thermoType"));

Info<< "Selecting thermodynamics package " << thermoTypeDict << endl;

if (thermoTypeDict.found("properties"))
{
.........
}
else
{
const int nCmpt = 7;
const char* cmptNames[nCmpt] =
{
"type",
"mixture",
"transport",
"thermo",
"equationOfState",
"specie",
"energy"
};

// Construct the name of the thermo package from the components
const word thermoTypeName
(
word(thermoTypeDict.lookup("type")) + '<'
+ word(thermoTypeDict.lookup("mixture")) + '<'
+ word(thermoTypeDict.lookup("transport")) + '<'
+ word(thermoTypeDict.lookup("thermo")) + '<'
+ word(thermoTypeDict.lookup("equationOfState")) + '<'
+ word(thermoTypeDict.lookup("specie")) + ">>,"
+ word(thermoTypeDict.lookup("energy")) + ">>>"
);

return lookupThermo<Thermo, Table>
(
thermoTypeDict,
tablePtr,
nCmpt,
cmptNames,
thermoTypeName
);
}
}
else
{
......
}
}

First it goes into the isDict function, which is used to check if a certain sub-dict is existing or not. The curly bracket {} is necessary for checking if the dict exists or not. If the thermoType sub-dict exists, a new dictionary called thermoTypeDict is built. And the Info will also show this sub-dict. In the tutorial simplifiedSiwek, this thermoTypeDict is:

1
2
3
4
5
6
7
8
9
{
type hePsiThermo;
mixture reactingMixture;
transport sutherland;
thermo janaf;
energy sensibleEnthalpy;
equationOfState perfectGas;
specie specie;
}

Then we will check if the properties is found in this dictionary. Of course it is not found in this dictionary, therefore the else loop will be conducted. The thermoTypeName in this tutorial is:

1
hePsiThermo<reactingMixture<sutherland<janaf<perfectGas<specie>>,sensibleEnthalpy>>>

Then the function will search this thermoTypeName in the table built in the run time selection part. First the function lookupThermo will be called:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template<class Thermo, class Table>
typename Table::iterator Foam::basicThermo::lookupThermo
(
const dictionary& thermoTypeDict,
Table* tablePtr,
const int nCmpt,
const char* cmptNames[],
const word& thermoTypeName
)
{
// Lookup the thermo package
typename Table::iterator cstrIter = tablePtr->find(thermoTypeName);

// Print error message if package not found in the table
if (cstrIter == tablePtr->end())
{
........
}

return cstrIter;
}

In this function, the cstrIter will be initialized from the object tablePtr. Here a initialization flow will be conducted as the inheritance relationship of the psiReactionThermo class.