本帖描述 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 |

