计算流体和OpenFoam
计算流体和OpenFoam
从硕士的计算数学到现在的流体的应用数学,算来也有五年的时间了.一直希望能寻找一个半专业的软件可以做计算流体的学习和研究.
所谓半专业,是说一方面我们可以很傻瓜的如ansys,fluent那样,使用他们的模型直接进行数值模拟,另一方面我们又可以很轻易的修改模型.构建自己的模型.编写自己的算法.
所以第一次接触OpenFoam时,就被她完全的吸引了.如此的贴和我的要求.更有魅力的是,她是一个开源软件,展现给我们的不仅仅是cfd,更是一种编写模拟软件的教程.
甚至我们自己可以试着学习怎么去开发这样的大型数值计算软件.
下面的例子来源于苏军伟博士的新浪博客,及我们园区的浪子禾月.
一 代码解释
例:OpenFOAM>>solver>>basic>>laplacianFoam
//createFields.H
/************************************************/
- //-屏幕提示。Info 等价于 C++中std::cout,Info间接调用cout
- Info<< "Reading field T\n" << endl;
- //这是一个类的初始化.volScalarField 类T对象的初始化.
- //-声明一个标量场,网格中心存储变量。该场是通过读入文件(IOobject and MUST_READ)进行设置,并根据controlDict中的设置进行自动write,由write.H中的runTime.write()来执行write();。
- volScalarField T
- (
- IOobject
- (
- "T", //对应case根目录下的目录T,是数据存储的方式
- runTime.timeName(),// T目录下的时间名称, 初始的是0目录,
- mesh,
- IOobject::MUST_READ,
- IOobject::AUTO_WRITE
- ),
- mesh
- );
- //- 提示读入参数控制文件
- Info<< "Reading transportProperties\n" << endl;
- //- 参数控制文件声明过文件形式读入
- IOdictionary transportProperties
- (
- IOobject
- (
- "transportProperties", //文件名字
- runTime.constant(), //文件位置,case文件夹中constant子文件夹
- mesh,
- IOobject::MUST_READ,//通过read一个文件,初始化
- IOobject::NO_WRITE //并不根据时间对文件进行写
- )
- );
- //-提出读入扩散律
- Info<< "Reading diffusivity DT\n" << endl;
- //-通过查询参数控制文件,初始化带有单位的标量,lookup中的“DT”为关键字
- dimensionedScalar DT
- (
- transportProperties.lookup("DT")
- );
//laplacianFoam.C (OpenFoam2.4.0)
- 1 #include "fvCFD.H"//-cfd头文件,包括大多数cfd计算需要的头文件,在src » finiteVolume » cfdTools » general » include
- 2 #include "simpleControl.H"
3
4 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
5
6 int main(int argc, char *argv[])
7 {
8 #include "setRootCase.H"
9
10 #include "createTime.H"
11 #include "createMesh.H"
12 #include "createFields.H"
13
14 simpleControl simple(mesh);
15
16 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
17
18 Info<< "\nCalculating temperature distribution\n" << endl;
19
20 while (simple.loop())
21 {
22 Info<< "Time = " << runTime.timeName() << nl << endl;
23
24 while (simple.correctNonOrthogonal())
25 {
26 solve
27 (
28 fvm::ddt(T) - fvm::laplacian(DT, T)
29 );
30 }
31
32 #include "write.H"
33
34 Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
35 << " ClockTime = " << runTime.elapsedClockTime() << " s"
36 << nl << endl;
37 }
38
39 Info<< "End\n" << endl;
40
41 return 0;
42 }
1 #include "fvCFD.H" //-cfd头文件,包括大多数cfd计算需要的头文件,在src » finiteVolume » cfdTools » general » include- 2
- 3
- 4 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
- 5 //主程序入口
- 6 int main(int argc, char *argv[])
- 7 {
- 8 //设置rootcase,根据输入参数argc 和 argv对
- 9 # include "setRootCase.H"
- 10
- 11 //-创建时间,下面的runTime控制
- 12 # include "createTime.H"
- 13
- 14 //创建网格,根据constant文件中polyMesh文件夹中的网格数据,创建网格对象mesh,位于src » OpenFOAM » include
- 15 # include "createMesh.H"
- 16
- 17 //创建场对象,在前面已经说明
- 18 # include "createFields.H"
- 19
- 20 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
- 21 //提示计算温度分布
- 22 Info<< "\nCalculating temperature distribution\n" << endl;
- 23 //计算主控制流程
- 24 for (runTime++; !runTime.end(); runTime++)
- 25 {
- 26 //提示当前计算时间
- 27 Info<< "Time = " << runTime.timeName() << nl << endl;
- 28 //读入simple算法参数,位于
- 29
- 30 src » finiteVolume » cfdTools » general » include
- 31
- 32 # include "readSIMPLEControls.H"
- 33 //对于网格非正交循环修正。
- 34 for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
- 35 {
- 36 //求解拉普拉斯方程,这里的solve是Foam空间的全局函数,内参数为fvMatrix,fvm表示隐式离散,返回有限容积稀疏矩阵类fvMatrix对象,具体对象中内容,以后说明
- 37 solve
- 38 (
- 39 fvm::ddt(T) - fvm::laplacian(DT, T)
- 40 );
- 41 }
- 42 //对求解变量进行写
- 43 # include "write.H"
- 44 //提示执行时间及CPU耗时
- 45 Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
- 46 << " ClockTime = " << runTime.elapsedClockTime() << " s"
- 47 << nl << endl;
- 48 }
- 49 //提示程序结束
- 50 Info<< "End\n" << endl;
- 51
- 52 return(0);
- 53 }
//write.H
- 1 if (runTime.outputTime())
- 2 {
- 3 volVectorField gradT = fvc::grad(T); //计算温度梯度,向量场
- 4
- 5 //声明3个变量,分别以gradT的三个方向的分量进行初始化。
- 6
- 7 volScalarField gradTx
- 8 (
- 9 IOobject
- 10 (
- 11 "gradTx", //变量名字
- 12 runTime.timeName(), //位置
- 13 mesh, //mesh,主要用于对象注册,根据runTime进行写
- 14 IOobject::NO_READ, //
- 15 IOobject::AUTO_WRITE //自动写
- 16 ),
- 17 gradT.component(vector::X) //用场初始话,vector::X 枚举变量,可直接写0 //gradT.component(0)
- 18 );
- 19
- 20 volScalarField gradTy
- 21 (
- 22 IOobject
- 23 (
- 24 "gradTy",
- 25 runTime.timeName(),
- 26 mesh,
- 27 IOobject::NO_READ,
- 28 IOobject::AUTO_WRITE
- 29 ),
- 30 gradT.component(vector::Y)
- 31 );
- 32
- 33 volScalarField gradTz
- 34 (
- 35 IOobject
- 36 (
- 37 "gradTz",
- 38 runTime.timeName(),
- 39 mesh,
- 40 IOobject::NO_READ,
- 41 IOobject::AUTO_WRITE
- 42 ),
- 43 gradT.component(vector::Z)
- 44 );
- 45
- 46 //对场进行写
- 47 runTime.write();
- 48 }
二 C文件
我们重点分析C文件
//laplacianFoam.C (OpenFoam2.4.0)
- 1 #include "fvCFD.H"//-cfd头文件,包括大多数cfd计算需要的头文件,在src » finiteVolume » cfdTools » general » include
- 2 #include "simpleControl.H"
3
4 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
5
6 int main(int argc, char *argv[])
7 {
8 #include "setRootCase.H"
9
10 #include "createTime.H"
11 #include "createMesh.H"
12 #include "createFields.H"
13
14 simpleControl simple(mesh);
15
16 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
17
18 Info<< "\nCalculating temperature distribution\n" << endl;
19
20 while (simple.loop())
21 {
22 Info<< "Time = " << runTime.timeName() << nl << endl;
23
24 while (simple.correctNonOrthogonal())
25 {
26 solve
27 (
28 fvm::ddt(T) - fvm::laplacian(DT, T)
29 );
30 }
31
32 #include "write.H"
33
34 Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
35 << " ClockTime = " << runTime.elapsedClockTime() << " s"
36 << nl << endl;
37 }
38
39 Info<< "End\n" << endl;
40
41 return 0;
42 }
10-12行我们建立了场的网格,即我们将向量附着在了几何空间上,形成了一个场.也就是说,目前我们有了数学上所描述的温度场T.此时,T还没有任何东西,是0标量场.