(OpenFOAM入门学习资料)icoFoam学习笔记

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

|---icoFoam 求解器名称
|-createFields.H 场变量的声明和初始化
—————————————————————————————————————————————
Info<< "Reading transportProperties\n" << endl; //屏幕提示读入参数控制文件,等价于 C++中std::cout
//声明属性字典类对象,该对象由constant 文件夹下的“transportProperties”初始化创建。

IOdictionary transportProperties
(
IOobject
//其实IOobject,顾名思义就是输入输出对象,它完成的是一个桥梁的作用,即连接要构造的类及硬盘中的
相应文件。

这可以通过其成员函数objectStream()了解到,当完成了“搭桥”之后,便可通过这一成员函数返
回硬盘文件对应的输入流,从而从输入流中读入将要构造的类的相关信息//
(
"transportProperties", // 文件名称
runTime.constant(), // 文件位置,case/constant
mesh, // 网格对象
IOobject::MUST_READ_IF_MODIFIED, //如果更改,必须读入
IOobject::NO_WRITE // 不对该文件进行写操作
)
);
//字典查询黏性,以便初始化带有单位的标量
dimensionedScalar nu
(
transportProperties.lookup("nu")
);
//屏幕提示创建压力场
Info<< "Reading field p\n" << endl;
//创建压力场
volScalarField p //声明一个带单位的标量场,网格中心存储变量。

(
IOobject // IOobject主要从事输入输出控制
(
"p", // 压力场初始文件名称
runTime.timeName(), // 文件位置,由case中的system/controlDict中的startTime控制// Tips:runTime是类Time的一个对象,runTime.timeName()其实就是当前运行到的物理时间(非
稳态物理问题的时间),你程序运行到了5.1 s,runTime.timeName()就会将字符串“5.1”返回给你,
OpenFOAM在对不同时刻的数据进行存取的时候就是靠着这个字符串。

runTime.constant()返回的
就是case下那个constant文件夹的名字,这个名字可以改的,默认为constant。

OpenFOAM根据
case文件夹里面的system/controlDict里面对输出的设置来确定当前时刻时候输出,如果当前时刻
输出的话,outputTime()就为true,就输出数据了//
mesh, // 网格对象,主要从事对象注册,以便由runTime.write()控制输出
IOobject::MUST_READ, //必须读入
IOobject::AUTO_WRITE //根据controlDict中的设置进行自动write
),
mesh //速度场所用的网格对象,在createMesh.H创建
);
//提示并创建速度场,向量场,体储存变量
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
// 创建界面流率
# include "createPhi.H" //把createPhi.H中的代码加进程序里面去
//表面场,phi,界面流率,储存在体之间的交界面上。

表面场(surface…)不能和体积场(vol…)直接计算,因为他们储存在不同的地方,大小不同。

可以将体积场转化为表面场(运用fvc::interpplate()),或者由表面场转化为体积场(运用fvc::reconstruct())进行计算。

代码位于src » finiteVolume » cfdTools » incompressible如下:
surfaceScalarField phi
(
IOobject
(
“phi”,
runtime.timeName(),
mesh,
IOobject::No_READ,
IOobject::AUTO_WRITE,
),
fvc::interpolate(U) & mesh.sf()
//U是体积场,运用插值转为表面场和表面积场进行相乘来初始化流率,mesh.Sf()返回网格交接面面积矢量。

);
//设定压力参考cell的index 和参考值
//只有求解区域所有的压力边界都为第二类边界条件是,下面的值才会用到。

如果有第一类边界条件。

//压力参考值为这点边界值。

对于不可压缩流动压力值为相对值,下面的参考值的大小对结果无影响。

label pRefCell = 0;
scalar pRefValue = 0.0;
//通过查询system/fvSolution 下的PISO 进行更新压力参考cell更新并设定参考值
setRefCell(p, mesh.solutionDict().subDict("PISO"), pRefCell, pRefValue);
—————————————————————————————————————————————
|-icoFoam.C 求解器主程序
—————————————————————————————————————————————#include "fvCFD.H"
//主程序入口
int main(int argc, char *argv[])
{
#include "setRootCase.H" //创建case根目录,位于src/OpenFoam/include
#include "createTime.H" //创建time对象runTime,位于src/OpenFoam/include
#include "createMesh.H" //创建网格对象mesh,位于src/OpenFoam/include
#include "createFields.H" //创建场对象,位于src/OpenFoam/include
#include "initContinuityErrs.H" //创建连续性误差,位于src/OpenFoam/include
Info<< "\nStarting time loop\n" << endl; //提示开始时间循环
while (runTime.loop()) //如果时间不是0,开始循环
{
Info<< "Time = " << runTime.timeName() << nl << endl; //显示当前物理时间
//读入piso 控制参数,写在runTime 循环中,以便运行过程中的修改生效,位于src » finiteVolume » cfdTools » general » include
#include "readPISOControls.H"
#include "CourantNo.H" //计算courant 数,位于src/finiteVolume/cfdTools/incompressible
fvVectorMatrix UEqn //构造速度方程
(
fvm::ddt(U) //隐式离散生成矩阵类,该项会被加到UEqn 中的A上
+ fvm::div(phi, U) // 隐式离散矩阵类,该项加到UEqn 中的A上
- fvm::laplacian(nu, U) // 隐式离散,该项从UEqn 中的A上减下来,因为前面是负号。

);
//应当指出上面方程中并没有包含grad(p),动量方程中所有的项要么在压力方程中要么在动
量方程中,而不同时在两个方程中。

//求解动量方程,下面方程中的p 由上一时刻p计算,下面求解称为速度预测。

solve(UEqn == -fvc::grad(p));
// --- PISO loop ---- 速度修正步
for (int corr=0; corr<nCorr; corr++)
{
//根据预测的速度值求解系数矩阵对角元素的倒数
volScalarField rAU(1.0/UEqn.A());
// 更新速度,See Hrv Jasak's thesis eqn. 3.137 and Henrik Rusche's thesis, eqn. 2.43
U = rAU*UEqn.H();
// 计算表面流律
// ddtPhiCorr 用来考虑差值速度场计算的流律和实际流律的差别
phi = (fvc::interpolate(U) & mesh.Sf())
+ fvc::ddtPhiCorr(rAU, U, phi);
adjustPhi(phi, U, p); //调整边值,以便满足连续性条件
//网格非正交性循环,如果网格是正交的,可以设定nNonOrthCorr=1
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
//设定压力方程并进行求解
fvScalarMatrix pEqn
(
fvm::laplacian(rAU, p) == fvc::div(phi)
);
pEqn.setReference(pRefCell, pRefValue);
pEqn.solve();
//根据新求解的压力,更新表面流律
if (nonOrth == nNonOrthCorr)
{
phi -= pEqn.flux();
}
}
//计算连续性方程误差, 位于src/finiteVolume/cfdTools/incompressible
#include "continuityErrs.H"
//根据新的压力,修正速度
U -= rAU*fvc::grad(p);
//修正速度边界(主要针对第二类边界条件)
U.correctBoundaryConditions();
}
runTime.write(); //输出计算结果
//显示执行时间,CPU 时间
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
} // end of the time step loop
//提示运行结束。

Info<< "End\n" << endl;
//返回0
return 0;
}
—————————————————————————————————————————————|-icoFoam.dep 依赖文件
|-Make
|-files 编译需要的源程序文件和生成的目标文件
files文件主要干两件事
(1)指定哪些文件需要编译,这里的文件是代码文件,也就是.C文件,而不包括.H文件
(2)指定你要编译的类型,是编译成库,还是编译成可执行文件,以及编译成的库文件或者可执行文件的名字。

下面是icoFoam的Make文件夹下的files文件的内容
—————————————————————————————————————————————icoFoam.C
EXE = $(FOAM_APPBIN)/icoFoam —————————————————————————————————————————————要编译的代码文件直接将名字写到里面就行了(icoFoam.C),如果有多个代码文件,直接一个一个列在上面就行了。

下面(EXE = $(FOAM_APPBIN)/icoFoam)为编译程序类型(EXE=)说明要编译成可执行文件,等号右面为编译后的文件放在什么地方。

这一行也可以不写,他会将编译的可执行文件放到当前文件夹,名字为OpenFOAM.out.。

如果你要编译成库的话请采用“LIB= ...”等号后面放编译的库文件所在的目录,一般编译库文件命名为lib...,这是一个习惯,而非规定。

|-options 编译选项,如链接库等
options文件也是干两件事
(1)指定编译的头文件所在的目录,如果说所用的头文件在当前文件夹或者标准C++的头文件,无需指定。

(2)指定编译当前程序所用到的库。

下面为icoFoam下的options文件的内容—————————————————————————————————————————————
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = \
-lfiniteVolume —————————————————————————————————————————————EXE_INC=用于所运用到的头文件所在的目录,EXE_LIB用来指定所有到的库。

注意这里的库为OpenFOAM中的库或者你自己写的库,C++的标准库无需在这添加。

因此如果你不使用OpenFOAM中的库,而是自己独立编写C++程序,并且所有的头文件都在当前的根目录,options里无需指定任何东西。

相关文档
最新文档