本系列为极基础的OpenFOAM编程示例。
1 最简单的C++程序
下面是一个最简单的C++程序,常作为C++编程教材的第一个范例。
#include //包含头文件iostream
using namespace std; //使用命名空间std
//每个C++程序都必须包含一个main函数
int main(int argc ,char *argv[])
{
cout << "hello, c++!" << endl;
return 0;
}
此程序代码非常简单,实现的功能也很简单:仅在屏幕上打印出一行文本。
在Linux下可以使用任何文本编辑器(如vi、vim、emacs、vscode、gedit等)创建并编辑代码,本案例中我们将代码都放在OpenFOAM的run文件夹下的Demo/demo1子文件夹中,并命名为demo1.cpp。利用下面的命令创建文件:
cd $FOAM_RUN && mkdir Demo
cd Demo && mkdir demo1 && cd demo1
touch demo1.cpp
利用tree
命令查看当前文件结构,如下图所示,demo1文件夹下仅有一个名为demo1.cpp的源文件。
打开源文件,输入上面的程序代码,如下图所示。
保存文件demo1.cpp
。
在Linux中可以使用g++
对C++程序进行编译,从而得到可执行文件。在Linux终端利用cd
命令Demo/demo1
路径下,执行下面的命令进行编译:
g++ demo1.cpp -o demo1
此时在当前路径下生成可执行文件demo1
,如下图所示。输入./demo1
可执行该程序,其在屏幕上打印出一行字符。
此程序是如此的简单,并没有什么复杂的内容可讲,网络上随便找本C++教程都能够获取此程序的详细解释,本示例的目的也并不是要解释此程序。
2 OpenFOAM程序
上面的程序可以利用OpenFOAM提供的函数库进行改写。如改写成下面的形式:
#include "IOstreams.H"
using namespace Foam; //OpenFOAM定义的命名空间
int main(int argc, char *argv[])
{
// Info等同于标准C++中的cout,nl等同于endl
Info << "Hello, CPP!" << nl;
return 0;
}
保存该文件名为demo1OF.cpp。(注意:OpenFOAM习惯使用大写C作为扩展名,这里只是为了与前面的程序相对应而使用cpp扩展名)
相同的方式进行编译,然而出现了错误,如下图所示。
提示找不到头文件IOstreams.H
。
此文件是OpenFOAM重写的IO头文件,然而g++并不知道此文件的位置,于是提示找不到此文件。OpenFOAM提供了程序编译工具wmake
以帮助我们更方便地编译程序,该工具与Linux中常用的make
工具类似,不过要更加的简单。
使用wmake需要在当前路径下创建一个名为Make
的文件夹,并在Make文件夹中创建一个名为files
及options
的文件。
注:OpenFOAM提供了更简单的工具foamNewApp来快速创建文件结构。
”
利用下面的命令很容易实现:
mkdir Make
touch Make/files Make/options
此时文件夹结构如下图所示。
Make文件夹中的两个文件:
-
files
:指定源文件与目标文件的位置 -
options
:指定头文件与外部库的位置
这里需要修改这两个文件。
-
打开 files
文件,输入下面的内容
demo1OF.cpp
EXE = demo1OF
-
打开 options
文件,输入下面的内容
EXE_INC = -I$(FOAM_SRC)/finiteVolume/lnInclude
EXE_LIBS = -lfiniteVolume
这里的$FOAM_RUN
指的是OpenFOAM的src文件夹所在的位置,也可以使用$LIB_SRC
或者直接用src文件夹的绝对路径。
-
输入 ./demo1OF
运行程序
程序运行结果如下图所示。可以看到程序顺利执行。
可以看到,调用了OpenFOAM的C++程序编译起来也很简单,只是需要额外的填写Make文件夹中的files与options文件即可。
3 数据类型
OpenFOAM对基础C++类型进行了封装,如将int类型重定义为label
,将float或double类型重定义为scalar
,还有更复杂的向量类vector
与张量类tensor
,下面举几个简单例子看看。
3.1 基本数据类型
在Demo文件夹下利用下面的命令创建文件:
mkdir demo2 && cd demo2
mkdir Make
touch demo2.C Make/files Make/options
文件结构如下图所示。
-
打开 files
文件,输入下面的内容
demo2.C
EXE = demo2
-
打开 options
文件,输入下面的内容
EXE_INC = -I$(FOAM_SRC)/finiteVolume/lnInclude
-I$(FOAM_SRC)/meshTools/lnInclude
EXE_LIBS = -lfiniteVolume -lmeshTools
-
打开demo2.C,输入下面的内容
#include "fvCFD.H"
int main()
{
label a = 5; // label相当于int
scalar pi = 3.14159; // scalar相当于float或double
Info << a << "+" << pi << "=" << a+pi << nl;
Info << a << "*" << pi << "=" << a*pi << nl << nl;
return 0;
}
利用wmake
编译并运行,结果如下图所示。
3.2 标量、向量与张量
前面的案例可以看到,我们可以使用OpenFOAM重新包装过的数据类型。除了简单的label、scalar、word(字符串)类型之外,还可以使用更复杂的向量和张量类型。
如下面的例程demo3.C。
#include "fvCFD.H"
int main(int argc, char *argv[])
{
scalar a = 5.3; // 定义一个标量
vector m(1, 2, 3); // 定义一个向量
vector n(0.5, 0.25, 1.0);
tensor p(1, 2, 3, 4, 5, 6, 7, 8, 9); //定义一个3x3的张量
Info << "标量与向量相乘" << endl;
Info << a << "*" << m << "=" << a * m << endl;
Info << "两个向量相乘" << endl;
Info << m << "*" << n << "=" << m * n << endl;
Info << "两个向量点积" << endl;
Info << m << "." << n << "=" << (m & n) << endl;
Info << "张量与向量相乘" << endl;
Info << p << "&" << m << "=" << (p & m) << endl;
return 0;
}
files与options文件的编写规则与前面的案例相同,这里就不重复描述了。
运行结果如下图所示。
3.3 列表与场变量
除了标量、向量与张量外,OpenFOAM还定义了列表与场变量。列表与C++标准库中的List类使用方法基本一致。
看下面的例程。
#include "fvCFD.H"
int main(int argc, char *argv[])
{
// 定义一个包含10个标量值的列表
List;
for (int i = 0; i < 10; i++)
{
myList[i] = i;
}
Info << nl << myList << nl;
// 利用forAll输出myList列表中的各元素
// forAll是OpenFOAM对for语句的封装,在容器迭代过程中非常好用
forAll(myList, i)
{
Info << myList[i] << 't';
}
Info << nl << nl;
return 0;
}
编译及运行结果如下图所示。
场变量比较复杂,OpenFOAM中最常见的场变量包括volScalarField
与volVectorField
,分别表示体标量场与体向量场,在访问访问内部数据时会用到,这个以后有时间再说。
(本系列待续)
本篇文章来源于微信公众号: CFD之道
评论前必须登录!
注册