本篇分析 OpenFOAM-3.0 中湍流模型的 RTS 机制。RTS 机制主要是通过调用几个相关的宏函数来实现的,所以,分析 RTS 机制需要将相关的宏函数展开。四类湍流模型,机制是类似的,这里以单相不可压缩湍流模型为例,后文会给出所有其他湍流模型相关的宏函数的展开结果,供读者参考。
RTS 机制的基础这里不再重复了,读者若对这里涉及到 RTS 机制的名称感兴趣,可以参考我以前对 RTS 机制的解读。
2. RTS 机制
单相不可压缩湍流模型类,在 Make/files
文件里包含的其中一个是 src/TurbulenceModels/incompressible/turbulentTransportModels/turbulentTransportModels.C
turbulentTransportModels.C,这个文件里包含了一些通用的湍流模型模板类,并调用了一些宏函数来实现 RTS 相关的,这里将宏函数展开看看这个文件究竟实现了怎样的功能。
1 | makeBaseTurbulenceModel |
这个宏函数调用1
2
3
4
5
6
7
8makeBaseTurbulenceModel
(
geometricOneField,
geometricOneField,
incompressibleTurbulenceModel,
IncompressibleTurbulenceModel,
transportModel
);
展开结果为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
59namespace Foam
{
typedef TurbulenceModel
<
geometricOneField,
geometricOneField,
incompressibleTurbulenceModel,
transportModel
> transportModelincompressibleTurbulenceModel;
defineTemplateRunTimeSelectionTable // 对TurbulenceModel类中定义的 hashTable 进行了初始化
(
transportModelincompressibleTurbulenceModel,
dictionary
);
typedef IncompressibleTurbulenceModel<transportModel> transportModelIncompressibleTurbulenceModel;
typedef laminar<transportModelIncompressibleTurbulenceModel> LaminartransportModelIncompressibleTurbulenceModel;
defineNamedTemplateTypeNameAndDebug(LaminartransportModelIncompressibleTurbulenceModel, 0);
addToRunTimeSelectionTable // 将laminar 模型加到定义在 TurbulenceModel 类中的hashTable
(
transportModelincompressibleTurbulenceModel,
LaminartransportModelIncompressibleTurbulenceModel,
dictionary
);
typedef RASModel<transportModelIncompressibleTurbulenceModel> RAStransportModelIncompressibleTurbulenceModel;
defineNamedTemplateTypeNameAndDebug(RAStransportModelIncompressibleTurbulenceModel, 0);
// 对 RASModel类中定义的hashTable进行了初始化
defineTemplateRunTimeSelectionTable
(RAStransportModelIncompressibleTurbulenceModel, dictionary);
// 将 RASModel 添加到 TurbulenceModel 中定义的hashTable
addToRunTimeSelectionTable
(
transportModelincompressibleTurbulenceModel,
RAStransportModelIncompressibleTurbulenceModel,
dictionary
);
typedef LESModel<transportModelIncompressibleTurbulenceModel> LEStransportModelIncompressibleTurbulenceModel;
defineNamedTemplateTypeNameAndDebug(LEStransportModelIncompressibleTurbulenceModel, 0);
// 对LESModel类中定义的hashTable进行了初始化
defineTemplateRunTimeSelectionTable
(LEStransportModelIncompressibleTurbulenceModel, dictionary);
// 将 LESModel 添加到 TurbulenceModel 中定义的hashTable
addToRunTimeSelectionTable
(
transportModelincompressibleTurbulenceModel,
LEStransportModelIncompressibleTurbulenceModel,
dictionary
);
}
makeRASModel(SpalartAllmaras)
展开结果为1
2makeTemplatedTurbulenceModel
(transportModelIncompressibleTurbulenceModel, RAS, SpalartAllmaras)
继续展开结果为
1 | defineNamedTemplateTypeNameAndDebug |
makeLESModel(Smagorinsky)
展开结果为1
2makeTemplatedTurbulenceModel
(transportModelIncompressibleTurbulenceModel, LES, Smagorinsky)
继续展开结果为
1 | defineNamedTemplateTypeNameAndDebug |
注意,这里给 kEpsilon
和 Smagorinsky
模型代入的模板参数是 transportModelIncompressibleTurbulenceModel
,即 IncompressibleTurbulenceModel<transportModel>
。
上面给出了单相不可压缩湍流模型是如何添加到各自该所属的 hashTable 里的。接着,以单相不可压缩模型为例,看看湍流模型的调用过程。
在 pisoFoam
求解器中,湍流模型接口的定义如下1
2
3
4
5autoPtr<incompressible::turbulenceModel> turbulence
(
incompressible::turbulenceModel::New(U, phi, laminarTransport)
);
// laminarTransport 是 singlePhaseTransportModel 的一个对象
incompressible::turbulenceModel
是 IncompressibleTurbulenceModel<transportModel>
的别名。
这里调用的是 IncompressibleTurbulenceModel
类的 New
函数。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
30template<class TransportModel>
Foam::autoPtr<Foam::IncompressibleTurbulenceModel<TransportModel> >
Foam::IncompressibleTurbulenceModel<TransportModel>::New
(
const volVectorField& U,
const surfaceScalarField& phi,
const TransportModel& transport,
const word& propertiesName
)
{
return autoPtr<IncompressibleTurbulenceModel>
(
static_cast<IncompressibleTurbulenceModel*>(
TurbulenceModel
<
geometricOneField,
geometricOneField,
incompressibleTurbulenceModel,
TransportModel
>::New
(
geometricOneField(),
geometricOneField(),
U,
phi,
phi,
transport,
propertiesName
).ptr())
);
返回的是 TurbulenceModel
类的 New
函数。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
60template
<
class Alpha,
class Rho,
class BasicTurbulenceModel,
class TransportModel
>
Foam::autoPtr
<
Foam::TurbulenceModel<Alpha, Rho, BasicTurbulenceModel, TransportModel>
>
Foam::TurbulenceModel<Alpha, Rho, BasicTurbulenceModel, TransportModel>::New
(
const alphaField& alpha,
const rhoField& rho,
const volVectorField& U,
const surfaceScalarField& alphaRhoPhi,
const surfaceScalarField& phi,
const transportModel& transport,
const word& propertiesName
)
{
// get model name, but do not register the dictionary
// otherwise it is registered in the database twice
const word modelType
(
IOdictionary
(
IOobject
(
IOobject::groupName(propertiesName, U.group()),
U.time().constant(),
U.db(),
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
)
).lookup("simulationType")
);
Info<< "Selecting turbulence model type " << modelType << endl;
typename dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(modelType);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorInFunction
<< "Unknown TurbulenceModel type "
<< modelType << nl << nl
<< "Valid TurbulenceModel types:" << endl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<TurbulenceModel>
(
cstrIter()(alpha, rho, U, alphaRhoPhi, phi, transport, propertiesName)
);
}
这里通过读取 turbulenceProperties
文件,查找关键字 simulationType
(只能是 RAS
或 LES
),并据此从定义在 TurbulenceModel
类中 hashTable 中找对应的模型,然后返回的模型(可能是 RAStransportModelIncompressibleTurbulenceModel
, RASfluidThermoCompressibleTurbulenceModel
, RASsinglePhaseTransportModelPhaseIncompressibleTurbulenceModel
, RASphaseModelPhaseCompressibleTurbulenceModel
)的 New
函数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
51template<class BasicTurbulenceModel>
Foam::autoPtr<Foam::RASModel<BasicTurbulenceModel> >
Foam::RASModel<BasicTurbulenceModel>::New
(
const alphaField& alpha,
const rhoField& rho,
const volVectorField& U,
const surfaceScalarField& alphaRhoPhi,
const surfaceScalarField& phi,
const transportModel& transport,
const word& propertiesName
)
{
// get model name, but do not register the dictionary
// otherwise it is registered in the database twice
const word modelType
(
IOdictionary
(
IOobject
(
IOobject::groupName(propertiesName, U.group()),
U.time().constant(),
U.db(),
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
)
).subDict("RAS").lookup("RASModel")
);
Info<< "Selecting RAS turbulence model " << modelType << endl;
typename dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(modelType);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorInFunction
<< "Unknown RASModel type "
<< modelType << nl << nl
<< "Valid RASModel types:" << endl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<RASModel>
(
cstrIter()(alpha, rho, U, alphaRhoPhi, phi, transport, propertiesName)
);
}
这个 New
函数中需要读取 RAS
子字典,从中读取 RASModel
关键字,并据此从定义在 RASModel
类中的 hashTable 中查找到对应的湍流模型,并返回湍流模型的构造函数1
2
3
4 return autoPtr<RASModel>
(
cstrIter()(alpha, rho, U, alphaRhoPhi, phi, transport, propertiesName)
);
其他三类湍流模型,机制是类似的,这里不再详述,仅给出三个链接,供大家参考:单相可压缩湍流模型,多相不可压缩湍流模型,多相可压缩湍流模型