本帖描述 OpenFOAM 热物理库的框架结构(以OF-7为基础,同时也尝试追踪自OpenFOAM开创以来,整个热物理库的架构变迁过程),希望对你有用。
OF-7
UML 类图
下图是热物理库部分类的 UML 类图。欲获取更佳阅读体验,可以右键在新标签页打开该图。
OF-7 UML
求解器中创建对象
solver
中的 createFields.H
中:
autoPtr<psiReactionThermo> pThermo(psiReactionThermo::New(mesh)); |
创建 thermo
,在 reactingFoam
自带算例中,创建的是 hePsiThermo
的对象,但是这里 thermo 是基类 psiReactionThermo
的引用,即只能使用 psiReactionThermo
这一继承链的方法。
basicSpecieMixture& composition = thermo.composition(); |
创建 composition
,是指系统中的混合物。可以调用继承链中 mixture
这一分支的方法。
燃烧类的求解器中,一般都没有对单个组分进行操作,这些操作都在热物理库里边进行。
multiComponentMixture
类中的私有数据 speciesData_
的类型是 PtrList<sutherlandTransport<species::thermo<janafThermo<perfectGas<specie>>,sensibleEnthalpy>>>
,它是组分的 list
,可以用它获取组分的所有信息。solver 中可以通过 multiComponentMixture
(solver
中composition
的类型是 basicSpecieMixture
,需要强制转换成 multiComponentMixture
才行 ) 的 speciesData()
或者 getLocalThermo(speciei)
这两个函数来调用。如:
dynamic_cast<const multiComponentMixture<gasHThermoPhysics>&>(composition).speciesData()[speciei].rho(p,T) |
也可以通过 multiComponentMixture
的派生类 reactingMixture
来调用。
dynamic_cast<const reactingMixture<gasHThermoPhysics>&>(composition).speciesData()[speciei].rho(p,T) |
也可以通过派生类的派生类 SpecieMixture
来调用。
dynamic_cast<const SpecieMixture<reactingMixture<gasHThermoPhysics>>&>(composition).speciesData()[speciei].rho(p,T) |
上述操作说明可以使用组分列表调用单个组分的函数(即 sutherlandTransport<species::thermo<janafThermo<perfectGas<specie>>,sensibleEnthalpy>>
继承链中的任何函数),如 speciesData_[i].rho(p, T)
,这里的 rho(p,T)
来自于 perfectGas
类。
也可以在求解器中重新构造组分列表:
autoPtr<psiReactionThermo> pThermo(psiReactionThermo::New(mesh)); |
gasHThermoPhysics
是 sutherlandTransport<species::thermo<janafThermo<perfectGas<specie>>,sensibleEnthalpy>>
的别名,它是单个组分的类型。
事实上,multiComponentMixture
类中的函数 cellMixture
函数可以用于获取 mixture_
。
template<class ThermoType> |
使用方法参考 hePsiThermo.C
const scalarField& hCells = this->he_; |
RTS 选择热物理模型
从字典文件的设置开始
下面介绍我们是如何从 thermophysicalProperties
字典文件中的下列设置构建对象的:
thermoType |
solver 中创建模型:
autoPtr<psiReactionThermo> pThermo(psiReactionThermo::New(mesh)); |
这个函数定义于 psiReactionThermo
:
Foam::autoPtr<Foam::psiReactionThermo> Foam::psiReactionThermo::New |
它调用了 basicThermo
中的 New
函数:
template<class Thermo> |
调用了 2 参数的 lookupThermo:
basicThermoTemplates.C 中的 lookupThermo
函数:
template<class Thermo, class Table> |
最后返回值是调用 5 个参数的 lookupThermo
函数:
template<class Thermo, class Table> |
第一个 lookupThermo
函数的作用是,将 thermophysicalProperties
字典文件中的设置翻译成:
hePsiThermo<reactingMixture<sutherland<janaf<perfectGas<specie>>,sensibleEnthalpy>>> |
但该字符串并不是最终的 class
,比如 janaf
,实际上类名是 janafThermo
。
第二个 lookupThermo
函数的作用就是,根据该字符串,在 RTS
库中找到我们选择的类。
那么上面提到的省略版字符串,怎么和 RTS
库中的组合匹配的呢?下面来看 RTS
库的生成过程。
RTS 库的生成
按照Giskard 博客提到的 RTS
流程:
- 基类类体里调用
TypeName
和declareRunTimeSelectionTable
两个函数,类体外面调用defineTypeNameAndDebug
和defineRunTimeSelectionTable
两个函数。- 基类中需要一个静态
New
函数作为selector
。- 派生类类体中需要调用
TypeName
函数,类体外调用defineRunTimeSelectionTable
和addToRunTimeSelectionTable
两个宏函数。
我们发现:makeReactionThermo.H
中有两个重要函数:defineThermoPhysicsReactionThermo
和 makeThermoPhysicsReactionThermos
。
下面一一介绍:
defineThermoPhysicsReactionThermo
其中的 defineThermoPhysicsReactionThermo
, 这个函数通过一组形参列表得到 CThermo##Mixture##ThermoPhys
,然后再转换成一串简化的字符串。这里的形参列表就是实例化所需要提供的各种类,对应(psiReactionThermo,hePsiThermo,reactingMixture,sutherlandTransport)
。
|
如:
hePsiThermo |
变成 RTS
库中保存的字符串:hePsiThermo<reactingMixture<sutherland<janaf<perfectGas<specie>>,sensibleEnthalpy>>>
隐藏了一些信息,如 psiReactionThermo
和 SpecieMixture
。
具体过程:typeName()
依次调用 reactingMixture
,sutherlandTransport
, species::thermo
, janafThermo
, sensibleEnthalpy
, perfectGas
, specie
的 typeName()
。返回值依次是:
"reactingMixture<" + ThermoType::typeName() + '>' |
最底层的 specie
类只有一个 ClassName("specie")
;
我们找到一个文件className.H
中:
所以这里的意义就在于用简化版的字符串表示完整的类型。而简化版的字符串则是读取 thermophysicalProperties 之后稍作处理得到的。(在前面的2 参数的 lookupThermo 中)
makeThermoPhysicsReactionThermos
定义如下:
|
调用了上边的 defineThermoPhysicsReactionThermo
用于创建 RTS
中的 typeName
,调用了 addThermoPhysicsThermo
(位于 makeThermo.H
), 用于写入到 RTS
哈希表。makeThermoPhysicsReactionThermos
函数的形参:(BaseThermo,BaseReactionThermo,CThermo,Mixture,ThermoPhys)
,这是实例化需要提供的所有信息。
比如其中的一种组合:makeThermoPhysicsReactionThermos(psiThermo,psiReactionThermo,hePsiThermo,reactingMixture,gasHThermoPhysics)
(所有的组合在 psiReactionThermos.C
中列出)。
这里调用 4 个 addThermoPhysicsThermo 函数是为何?假定先分析第一个 addThermoPhysicsThermo 函数:
|
BaseThermo_
是 basicThermo
,CThermoMixtureThermoPhys_
是hePsiThermo##reactingMixture##gasHThermoPhysics
。
这里的 addToRunTimeSelectionTable
函数定义于 addToRunTimeSelectionTable.H
中:
|
addfvMeshConstructorToTable
这个类是在 runTimeSelectionTables.H
文件中的 declareRunTimeSelectionTable
宏函数中定义的。
所以 addThermoPhysicsThermo
中创建了一个 baseType::addfvMeshConstructorToTable<thisType>
类的对象 add##thisType##fvMesh##ConstructorTo##baseType##Table_
,而该对象构造时会往哈希表中插入键和值,即派生类的名字和 New 函数,此函数返回指向派生类对象的基类指针。
这里的基类 baseType
是 basicThermo
,派生类 thisType
是 hePsiThermo##reactingMixture##gasHThermoPhysics
,这里是省略版。
OF-8
OF-8 去除了 reactingMixture
这个类!
它的成员 speciesComposition_
移至 multiComponentMixture
中。
另外 multiComponentMixture
还新增了 readSpeciesData
和 readSpeciesComposition
这两个函数,用于初始化 specieThermos_
和 speciesComposition_
。
之前(OF-7)化学反应的信息是保存在 reactingMixture
中,然后复制引用到 StandardChemistryModel
中的 reactions_
现在(OF-8)是直接保存在 StandardChemistryModel
中的 reactions_
。
化学反应的信息在 StandardChemistryModel
中,以前(OF-7)是
const PtrList<Reaction<ThermoType>>& reactions_; |
以前(OF-7)是下面这样,调用的是复制构造函数,因为所有的化学反应的信息都包含在 reactingMixture
中!
reactions_ |
现在(OF-8)是
const ReactionList<ThermoType> reactions_; |
现在在 StandardChemistryModel
中是这样构造:
reactions_ |
调用的是这个构造函数:
//- Construct from thermo list, objectRegistry and dictionary |
下图是热物理库部分类的 UML 类图。欲获取更佳阅读体验,可以右键在新标签页打开该图。
OF-8 UML
OF-10
OF-10 UML
OF-1.1
OF-1.1 UML
reactingFoam
autoPtr<hCombustionThermo> thermo |
CASE/constant/thermodynamicProperties
thermoType hMixtureThermo<reactingMixture>; |
typedef sutherlandTransport<specieThermo<janafThermo<perfectGas> > > |
OF-1.2
OF-1.2 UML
typedef sutherlandTransport<specieThermo<janafThermo<perfectGas> > > |
reactingFoam:
autoPtr<hCombustionThermo> thermo |
CASE/constant/thermophysicalProperties:
thermoType hMixtureThermo<reactingMixture>; |
OF-1.3
OF-1.3 UML
typedef sutherlandTransport<specieThermo<janafThermo<perfectGas> > > |
reactingFoam:
autoPtr<hCombustionThermo> thermo |
CASE/constant/thermophysicalProperties:
thermoType hMixtureThermo<reactingMixture>; |
OF-1.4
OF-1.4 UML
typedef sutherlandTransport<specieThermo<janafThermo<perfectGas> > > |
reactingFoam:
autoPtr<hCombustionThermo> thermo |
CASE/constant/thermophysicalProperties:
thermoType hMixtureThermo<reactingMixture>; |
OF-1.5
OF-1.5 UML
typedef sutherlandTransport<specieThermo<janafThermo<perfectGas> > > |
reactingFoam:
autoPtr<hCombustionThermo> thermo |
CASE/constant/thermophysicalProperties:
thermoType hMixtureThermo<reactingMixture>; |
OF1.2到OF1.5继承关系没有发生任何变化。
OF-1.6
OF-1.6 UML
typedef sutherlandTransport<specieThermo<janafThermo<perfectGas> > > |
reactingFoam:
autoPtr<psiChemistryModel> pChemistry |
CASE/constant/thermophysicalProperties:
thermoType hPsiMixtureThermo<reactingMixture<gasThermoPhysics>>; |
OF-1.7.0
OF-1.7.0 UML
typedef sutherlandTransport<specieThermo<janafThermo<perfectGas> > > |
reactingFoam:
autoPtr<psiChemistryModel> pChemistry |
CASE/constant/thermophysicalProperties:
thermoType hsPsiMixtureThermo<reactingMixture<gasThermoPhysics>>; |
OF-2.0.x
OF-2.0.x UML
reactingMixture
的模板是 gasThermoPhysics
,所以UML图中仍旧写的是 sutherlandTransport
typedef sutherlandTransport<specieThermo<janafThermo<perfectGas> > > gasThermoPhysics; |
reactingFoam:
autoPtr<psiChemistryModel> pChemistry |
CASE/constant/thermophysicalProperties:
thermoType hsPsiMixtureThermo<reactingMixture<gasThermoPhysics>>; |
OF-2.3.x
OF-2.3.x UML
相比于2.0.x,把显焓 hs 抽象成了一个类 sensibleEnthalpy。
reactingFoam:
autoPtr<combustionModels::psiCombustionModel> reaction |
CASE/constant/thermophysicalProperties:
thermoType |
OF-4.x
OF-4.x UML
reactingFoam:
autoPtr<combustionModels::psiCombustionModel> reaction |
CASE/constant/thermophysicalProperties:
thermoType |