OpenFOAM 中的模块广泛使用 Run Time Selection(RTS)机制,因此 OpenFOAM 的求解器中,只需要设定模型的调用接口。算例具体使用的是哪个模型,则是在运行时才确定的,而且可以在算例运行过程中修改选中的模型。
Run Time Selection(RTS) 机制的系列博文可以参考 www.sourceflux.de
这里主要分析 OpenFOAM 中湍流模型框架中的 RTS。
declareRunTimeSelectionTable 宏函数的主要功能是声明了一个 hashTable,并定义了一个指向这个hashTable 的指针, 然后还声明了几个辅助的类。
declareRunTimeSelectionTable
hashTable
defineRunTimeSelectionTable 宏函数的主要作用是对 declareRunTimeSelectionTable 中的 hashTable 指针进行了初始化。
defineRunTimeSelectionTable
addToRunTimeSelectionTable 的主要作用是将当前类的类名以及返回当前类的对象的一个函数分别作为 hashTable 的 key 和 value 插入到 hashTable 中。
addToRunTimeSelectionTable
下面来看这些宏函数在湍流模型框架中是如何使用的。
1
turbulenceModel 类
类体中,调用:
declareRunTimeNewSelectionTable 宏函数。
declareRunTimeNewSelectionTable
注意这里用的是 declareRunTimeNewSelectionTable!与 declareRunTimeSelectionTable 区别在于:declareRunTimeNewSelectionTable 这个宏函数定义的插入到 hashTable 中的那个函数,返回值不是派生类的对象,而是派生类中的 New 函数的返回值!
New
RASModel
RAS
类体外,调用
turbulenceModel
turbulenceModel 类下一层的派生类是 RASModel 和 LESModel 。
LESModel
先来看 RASModel,这个类类体里调用了 declareRunTimeSelectionTable 。
类体外调用了
defineRunTimeSelectionTable(RASModel, dictionary);
同时,RASModel类 本身又添加到了 turbulenceModel 中建立的 hashTable 里: addToRunTimeSelectionTable(turbulenceModel, RASModel, turbulenceModel);
addToRunTimeSelectionTable(turbulenceModel, RASModel, turbulenceModel);
RASModel 类之下的派生类,就是具体的湍流模型了,以 kEpsilon 模型为例:
kEpsilon
kEpsilon具体的湍流模型,如kEpsilon ,只需要添加到上面基类中创建的 hashTable 中,就能保证其能被调用到。
这里是添加到了 RASModel 中创建的 hashTable 里。
3
LESModel 类也是继承自 turbulenceModel 的,所以其处理方法跟 RASModel 是一样的。不过 LES 类的模型的继承关系略比 RAS 类的复杂一点。
LES
LES 模型继承关系图
在这个图中,中间层的 GenEddyVisc 等4个虚线框中的类不是作为具体的湍流模型来调用的,这里有必要看一下这样的中间类在 RTS 机制中是怎么处理的。
GenEddyVisc
检查这几个类的代码,可以发现:
GenEddyVisc 和 GenSGSStress 中只是在类体外调用了 defineTypeNameWithName(GenEddyVisc, "GenEddyVisc");
GenSGSStress
defineTypeNameWithName(GenEddyVisc, "GenEddyVisc");
scaleSimilarity 在类体中调用了 TypeName,类体外调用了 defineTypeNameAndDebug
scaleSimilarity
TypeName
defineTypeNameAndDebug
DESModel 中没有任何处理。
DESModel
typeName
因此,湍流模型的调用过程大致为:
求解器里创建一个turbulenceModel 类型的autoPtr,并调用 turbulenceModel::New 来初始化。从 turbulenceProperties 文件中读取关键字。
假设,读取到 simulationType 为 RASModel ,则 turbulenceModel::New 的 cstrIter() 返回的是 RASModel::New,于是 cstrIter()(U, phi, transport, turbulenceModelName) 则是在调用 RASModel::New。
然后, RASModel::New 从 RASProperties 文件里读取关键字,并根据读取到的内容,从 RASModel 类中创建的 hashTable 里查找对应的湍流模型,假设从 RASProperties 中读取到的是 kEpsilon, 则返回一个 kEpsilon 模型的对象。
最终结果是,求解器里创建的turbulenceModel 类型的 autoPtr 指向了 kEpsilon 类的对象,这就实现了对 kEpsilon 模型的调用。