OpenFOAM 湍流模型模板框架分析(一):顶层设计
Contents
背景
在 OpenFOAM 2.3.0 时,Henry G. Weller 开始采用基于原则设计的方式重构湍流模型代码。在这个版本中,新旧代码共存。旧代码位于 turbulenceModel 文件夹中,新的采用基于原则设计的代码则位于 TurbulenceModel 文件夹中(注意大小写)。
而到 OpenFOAM 3.0.0 发布时,turbulenceModel 文件夹被删除,同时旧代码全部被移除,整个湍流模型框架完全用基于原则设计的方式实现。
基于原则设计
基于原则设计(policy-based design)是 C++ 泛型编程的一种设计模式。具体来说是采用 C++ 的模板技术,将类设计为类模板(class template),并使该类模板继承自模板参数。
基于原则设计有两种形式:一种是模板参数为普通类,另一种是模板参数也为类模板。例如:
|
|
其中 PolicyBasedClass
是一个基于原则设计的类,它继承自模板参数 Policy1
和 Policy2
。这两个模板参数又被称为原则类(policy classes)。
OpenFOAM 中的湍流模型代码用到的是第一种形式,接下来分析框架的具体实现。
湍流模型抽象基类
TurbulenceModel
是湍流模型的抽象基类,它的声明如下:
|
|
其中的 BasicTurbulenceModel
是一个原则类,同时也是 TurbulenceModel
的基类。
继承关系
TurbulenceModel
偏特化后派生出 4 个类,分别是:IncompressibleTurbulenceModel
、CompressibleTurbulenceModel
、PhaseIncompressibleTurbulenceModel
和 PhaseCompressibleTurbulenceModel
。这 4 个类为单相/多相流、不可压/可压缩流的组合。
它们的声明如下:
IncompressibleTurbulenceModel
|
|
CompressibleTurbulenceModel
|
|
PhaseIncompressibleTurbulenceModel
|
|
PhaseCompressibleTurbulenceModel
|
|
TurbulenceModel的继承关系(点击图片放大)
模板参数
Alpha
Alpha
代表多相流中的相分数,通过不同类型的 Alpha
,实现单相流/多相流的模拟。
- 单相流:相分数可以看作是1,
Alpha
=geometricOneField
- 多相流:相分数随空间位置变化,
Alpha
=volScalarField
提示
geometricOneField
可以被认为是一个所有体心值为1的 volScalarField
。
Rho
Rho
代表流体密度,通过不同类型的 Rho
,实现不可压缩/可压缩流的模拟。
-
不可压缩流体:密度不随空间位置变化,
Rho
=geometricOneField
-
可压缩流体:密度随空间位置变化,
Rho
=volScalarField
。
提示
不可压缩流求解器中的流体控制方程中不涉及密度,所以密度可以认为是 geometricOneField
。
BasicTurbulenceModel
BasicTurbulenceModel
是原则类,也是 TurbulenceModel
的基类。这个模板参数的可选参数为 incompressibleTurbulenceModel
和 compressibleTurbulenceModel
。这两个类均派生自 turbulenceModel
,均为纯虚类,需要在派生类中实现相关的纯虚函数。代码位于
- $FOAM_SRC/TurbulenceModels/incompressible/incompressibleTurbulenceModel.H
- $FOAM_SRC/TurbulenceModels/compressible/compressibleTurbulenceModel.H
提示
incompressibleTurbulenceModel
是描述不可压缩流体湍流模型的类,记住在这里它是一个原则类,被 IncompressibleTurbulenceModel<TransportModel>
继承。
compressibleTurbulenceModel
是描述可压缩流体湍流模型的类,也是一个原则类,被 CompressibleTurbulenceModel<TransportModel>
继承。
TransportModel
TransportModel
代表输运模型,这个参数对应的类用来描述和计算流体粘度。对于不同类型的流体有不同实现。
-
不可压缩流体:
TransportModel
=transportModel
transportModel
代码位于 $FOAM_SRC/transportModels/incompressible/transportModel/
提示
transportModel
是一个描述不可压缩流体输运模型的抽象类,它可以派生出许多类,如描述单相流的 singlePhaseTransportModel
,描述两相分层流 incompressibleTwoPhaseMixture
等。
-
可压缩流体:
TransportModel
=fluidThermo
fluidThermo
代码位于 $FOAM_SRC/thermophysicalModels/basic/fluidThermo/
提示
fluidThermo
是一个描述可压缩流体热力学模型的类,它继承自 basicThermo
和 compressibleTransportModel
,派生出两个类:基于可压缩性描述的类 psiThermo
和基于密度描述的类 rhoThermo
。这两个类又派生出其他类。
湍流模型类模板特化
OpenFOAM 对 TurbulenceModel
进行偏特化后,又进一步派生出 4 个类。从代码上看,用于多相流的两个类 PhaseIncompressibleTurbulenceModel
和 PhaseCompressibleTurbulenceModel
明显没有单相流的 IncompressibleTurbulenceModel
和 CompressibleTurbulenceModel
完成度高。
IncompressibleTurbulenceModel
IncompressibleTurbulenceModel
接受一个模板参数 TransportModel
。对于不可压流体,这个参数为 transportModel
,特化后得到 IncompressibleTurbulenceModel<transportModel>
,同时在 incompressible
命名空间下定义类型别名 turbulenceModel
。
|
|
可知 turbulenceModel
是一个全特化的类,特化的模板参数如下:
Alpha
=geometricOneField
Rho
=geometricOneField
BasicTurbulenceModel
=incompressibleTurbulenceModel
TransportModel
=transportModel
CompressibleTurbulenceModel
CompressibleTurbulenceModel
与 IncompressibleTurbulenceModel
类似,也接受一个模板参数。对于可压缩流体,这个参数为 fluidThermo
,特化后得到 CompressibleTurbulenceModel<fluidThermo>
。这个类并没有直接定义类型别名,而是作为模板参数传递给另一个类模板 ThermoDiffusivity
,然后在 compressible
命名空间下定义类型别名turbulenceModel
。
|
|
PhaseIncompressibleTurbulenceModel
PhaseIncompressibleTurbulenceModel
没有在湍流模型框架中特化。目前只有一个求解器 DPMFoam
使用 。PhaseIncompressibleTurbulenceModel
在求解器源码中进行特化:
|
|
PhaseCompressibleTurbulenceModel
PhaseCompressibleTurbulenceModel
的模板特化放在求解器中,如 twoPhaseEulerFoam
、reactingTwoPhaseEulerFoam
以及 reactingMultiphaseEulerFoam
等。这块的代码较杂乱,并没有统一风格。如:
|
|
关于湍流模型框架的顶层设计先介绍到这里,下篇文章我们将介绍三个重要的类模板。