目录

数值耗散和数值频散

对非线性化项的处理

OpenFOAM程序最基本的架构

OpenFOAM里的代码和C++的区别

关于#include的文件

fvCFD.H

using namespace std

主函数main函数

编译

Make/options文件内容指定

报错咋办

OpenFOAM中的内置类型非常多

OpenFOAM中包含了一些自定义的宏

C++代码例子

OpenFOAM实例

代码封装


数值耗散和数值频散

由于cfd旨在用差分方程代替微分方程,所以差分方程是微分方程的逼近,但二者之间总有误差。误差由阶次不同,可造成解的耗散和频散,其中耗散就如给流场添加了人为的粘性一样,使得本来尖锐的突越变得平滑,分辨率降低。

简单的说截断项中偶数阶微分的存在使得解具有耗散性,奇数阶微分的存在使得解具有频散性。比如一道正弦曲线,耗散使之幅值变低,而频散使之相位和周期发生变化。

https://zhidao.baidu.com/question/399291950.html

对非线性化项的处理

由于非线性求解器非常复杂,因此在OpenFOAM均采用线性化处理。

OpenFOAM程序最基本的架构

每个程序会通过单独一个文件夹来包含(如myFirstFoam文件夹),在这个文件夹下,存在一个Make文件夹,Make中包含files和options文件。同时在myFirstFoam文件夹中,需要包含程序文件(如myFirstFoam.C)。

  • 目录文件夹下的.C文件是OpenFOAM/C++的主程序(注意大写);

  • Make文件夹是OpenFOAM特有的,里面主要包含两个文件files和options;

  • files用来指定OpenFOAM顺序进行编译的文件名称以及路径

  • options用来指定OpenFOAM需要调用的外挂库的路径以及名称

OpenFOAM里的代码和C++的区别

输出语句中的coutInfo替代,Info是OpenFOAM中用来输出的语句。不仅仅可以输出字符串,也可以输出其他各种的场(比如体向量场等)。后面的nl在OpenFOAM中用来表示换行,等同于C++中的endl

$(LIB_SRC)是一个环境变量,在OpenFOAM中等同于$(FOAM_SRC),其真实的位置可以通过键入echo $FOAM_SRC来查看。

关于#include的文件

后期编程的时候,则是用户需要自己去OpenFOAM源文件里面找的。需要什么头文件,就写什么头文件。举例,用户可能需要在编程环境中调用volScalarField类型,这样,就需要在程序最开始,将volScalarField这个类型进行包含。在OpenFOAM中,可以通过#include "volFields.H"来处理。其中的volFields.H,只能用户自己去找,没有规律。

fvCFD.H

OpenFOAM中fvCFD.H文件是一个非常大的框架,它把OpenFOAM中大部分的基本的类型都包含了,在初学不知道应该调用OpenFOAM具体的什么类型的时候,建议直接把fvCFD.H文件进行包含省去寻找具体头文件的过程。

using namespace std

using namespace std之后,就省去了std::,可以直接引用std空间里面的函数和变量。

一个中大型软件往往由多名程序员共同开发,会使用大量的变量和函数,不可避免地会出现变量或函数的命名冲突。当所有人的代码都测试通过,没有问题时,将它们结合到一起就有可能会出现命名冲突。

例如小李和小韩都参与了一个文件管理系统的开发,它们都定义了一个全局变量 fp,用来指明当前打开的文件,将他们的代码整合在一起编译时,很明显编译器会提示 fp 重复定义(Redefinition)错误。

为了解决合作开发时的命名冲突问题,C++ 引入了命名空间(Namespace)的概念。请看下面的例子:

namespace Li{  //小李的变量定义FILE fp = NULL;
}
namespace Han{  //小韩的变量定义FILE fp = NULL
}

小李与小韩各自定义了以自己姓氏为名的命名空间,此时再将他们的 fp 变量放在一起编译就不会有任何问题。

namespace 是C++中的关键字,用来定义一个命名空间,语法格式为:

namespace name{//variables, functions, classes
}

::是一个新符号,称为域解析操作符,在C++中用来指明要使用的命名空间。

http://c.biancheng.net/view/2192.html

主函数main函数

main函数是一个特殊的函数,在可执行的OpenFOAM/C++程序中,它总是最先运行的代码。int main()声明了一个叫做main的函数,它没有参数。如果有参数的话,它们的名称应该出现在小括号()。但具有一个返回值,类型为int,因此在程序的最后,会存在一行代码return 0;。最简单的理解方法是,将所有的主程序函数头都写成int main()(当然你可以写成void main(),它并不需要返回值)。但其中的main是不能变的,大小写也不能变,必须这样写。

编译

OpenFOAM中所有的程序(库)的编译器调用命令为:wmake,用户应该切换到程序目录下,运行wmake

Make/options文件内容指定

options用来指定OpenFOAM需要调用的外挂库的路径以及名称

报错咋办

同时注意,在提示missing separator错误之后,即使添加好\也依然会报错。这时候需要用wclean命令清空一下,再运行wmake。提醒:某些情况下如果Gcc编译器不匹配你的OpenFOAM版本号,也会出现类似问题。这也解释了,为什么比较高版本的OpenFOAM需要比较高版本的Gcc编译器。

OpenFOAM中的内置类型非常多

比如:

  • volScalarField 体标量场:比如CFD中定义在网格上的温度场;

  • volVectirField 体矢量场:比如CFD中定义在网格上的速度场;

  • fvScalarMatrix 标量矩阵:比如CFD中离散湍流动能生成的稀疏线性系统;

  • autoPtr OpenFOAM智能指针:OpenFOAM自定义的智能指针;

  • processor 处理器边界类型:并行计算的处理器边界类型;

在这里并不能够全部列举。这需要同学们在以后使用OpenFOAM的过程中持续的摸索。

常用类总结:http://blog.sina.com.cn/s/blog_5333fbde0100dagt.html

对于程序,最常用到的,也是最底层的就是数据,在OpenFOAM中引入了三类基础数据类型:标量scalar, 向量vector, 张量tensor.这三个中数据类型,也是FOAM中最基础的三个类。(还有一个比较重要的就是bool和label,前者就是是非型,及对错型,只不过是更扩展一些,后者是标签型数据,相当于c中的整型。关于更多的其它数据类型可以参看目录..\src\OpenFOAM\primitives里面)

在上述数据类的基础上,增加场(field)的概念,就引入了标量场scalarField, 向量场vectorField, 张量场tensorField.实际上这三个类又是field类的typedef,如typedef field<scalar> saclarField。这些场类中都有对应的成员函数进行加减乘除运算,还有复杂的点积叉积等。说到这field class,其实他就像是一个数据存放的区域一样,存放上scalar,那它成了标量场scalarField。这些类中可以有接口实现数据的计算。从field类中又派生出了FieldField类,这个就是说场中场类,其实这个主要用于边界条件类的一个基类。因为边界条件算是网格类场中的一个特殊的场,后面会介绍。

比field类高一点的就是几何场类 GeometricField class,其相比field class多了纪录场位置的相关信息。说到这里请大家注意他和polyMesh class的区别,后者只是纪录网格的结构,如点的位置、面的组成、体的组成等等,polyMesh class中对应有pointMesh,surfaceMesh,volMesh等类,从字面上很容易理解其处理和记录网格点、网格面、网格体等信息。而GeometricField类,其则是记录了在什么样的网格上有量a的相关信息或数据。它包括了内部区域、边界区域(GeometricBoundaryField class)、网格、尺度单位、计算的先前时间阶的值等。在该类中有常用的三种(实际上还有其他的许多,可以参看OpenFOAM网上说明):volScalarField体标量场,volVectorField体向量场,volTensorField体张量场。这里说的场与field有所不同,这里指的是网格区域上所对应的数据信息。上述的vol就是指ployMesh中的volMesh,如volscalarField类来说:

    volScalarField p(IOobject("p",runTime.timeName(),mesh,IOobject::MUST_READ,IOobject::AUTO_WRITE),mesh);

这是读入标量压力场文件,把压力值存储到网格体中心。为加深对GeometricField类的理解,贴张PG中的图片:

除了体的向量标量张量场外,还有面标量场surfaceScalarField、面向量场surfaceVectorField、面张量场surfaceTensorField。看下面的例子:

    surfaceScalarField phi(IOobject("phi",runTime.timeName(),mesh),fvc::interpolate(alpha)*phia+ fvc::interpolate(beta)*phib);

这里的phi既是一个面向量场对象,他用来是纪录单元体面上流过的通量值

除了常用到的标量向量张量的几何场外,还有一些特殊量的场:surfaceSymmTensor面对称张量几何场、体球面张量场等等。几何场里面还有一个比较重要的类就是GeometricBoundaryField,用来专门对边界进行处理的一个类。

OpenFOAM中包含了一些自定义的宏

其中一些语句可用来执行CFD专属的循环。比如forAll()语句是非常常用的OpenFOAM语句。看下面的代码:

forAll(U, cellI)
{U[cellI] = vector(1, 0, 0);
}

其中forAll()为一种遍历,其需要传入两个参数,在上面的例子中,第一个参数为U(一个volScalarField),则此forAll()表示对整个计算域的网格进行循环。括号内的U[cellI] = vector(1, 0, 0);表示对每个网格的U[cellI]进行赋值。需要注意的是,上面的例子并不对U的边界进行处理。

如果forAll()内传入surfaceScalarField,则对内部的面进行循环,例如:

forAll(phi, index)
{phi[index] = 0.0;
}

上面的代码将phi内部的面赋值为0。同样的,本例子不对phi的边界进行处理。

C++代码例子

double shit(double a, int b);//函数返回double类型,名称为shit(),传入一个double类型a,一个int类型bint main()
{double whatName;double a = 2.1;int b = 0;whatName = shit(a, b);//调用shit()函数并将返回值赋给whatNamereturn 0;
}double shit(double a, int b)//函数定义
{
//函数具体计算代码略
}
//函数返回double类型,名称为shit(),传入一个double类型a,一个int类型b
double shit(double a, int b);
{
//函数具体计算代码略
}int main()
{double whatName;double a = 2.1;int b = 0;whatName = shit(a, b);//调用shit()函数并将返回值赋给whatNamereturn 0;
}

OpenFOAM实例

//在main()函数之前的函数定义,返回volScalarField类型,函数名为Function()
volScalarField Function
(//传入一个volVectorField类型volVectorField U,//传入一个dimensionedScalar类型dimensionedScalar nu
)
{
//略
}int main()
{volScalarField p = Function(velocity, nu);//声明一个volScalarField类型叫做p//将Function(velocity, nu)函数返回的volScalarField赋值给p
}

代码封装

我们把类的声明放在了.H文件中,类的实现放在了.C文件中,对这个.C文件进行编译,可以形成一个库(后缀为.so)。同时,在主程序内,将类的.H文件进行包含,同时在options文件中嵌入库文件,即可将程序成功编译。如果同学们想把自己的库函数封装,需要进行下面的步骤:

  • 在自己的电脑上编写类的.H文件和.C文件;

  • 编译出库文件;

  • 拷贝.H文件和库文件给其他用户,其他用户的程序文件中即可调用这个库,并调用其中的库函数(类接口);

需要注意的是,你并不需要把.C文件拷贝给其他人,其他人即可调用你的库(你的函数实现)。这,就是非常典型的类封装过程。因为你的.C文件包含了所有函数实现,且没有被外传。

很多软件都是进行的类似的操作,很有可能同学们下载了一款软件,其中包含了大量的.so文件(在windows下后缀为.dll的文件),然后包含若干的文件头。很明显,这就是封装后的代码。

同时提醒的是,OpenFOAM为一款开源CFD求解器,并不支持闭源行为。

openFOAM C++代码的一些特性相关推荐

  1. 那些开源程序中让人叹为观止的代码 - 1 浏览器特性判断

    浏览器特性判断 解决问题:判断某事件/方法在当前浏览器中是否支持 开源程序:Modernizr 众所周知,各个不同的浏览器对于代码渲染的实现也各自为政百花齐放,虽然有W3C在维护着标准,但是由于市面上 ...

  2. html中写一个占内存很大死循环代码,HTML5新特性Bug:这12行代码分分钟让你浏览器崩溃iPhone重启...

    使用这十二行JavaScript代码能让firefox.chrome.safari等众多浏览器崩溃,甚至让iPhone重启? 起因 今天刷推特的时候发现Cyber Security@cyber__se ...

  3. C++ 随心记5 C++17 较好用的新特性 (一)令代码简洁的特性

    这部分大体包括语法糖(封装优化好的库函数或模块),以及一些令代码更简洁.可读性更强的函数与库. 1. 结构化绑定 C++ 17以前,使用for循环遍历map / unordered_map 时候需要声 ...

  4. openfoam安装中出现allmake error_深入理解 OpenFOAM 环境与编译过程

    深入理解 OpenFOAM 环境变量与编译 操作系统选择 由于 OpenFOAM 在 Linux 平台开发和测试,在非 Linux 平台无法直接对软件进行编译和安装,所以在非 Linux 平台上最简便 ...

  5. 三,ES6中需要注意的特性(重要)

    -----书接上文,前文中我们总结了关于JS的组成部分以及如何快速开展学习JS,相信已经有很多朋友掌握到这些方法.接下来就从更深的ECMAScript开始说起. 1.什么是ES6? ECMAScrip ...

  6. java 静态代码块 多线程,Java多线程编程笔记10:单例模式

    立即加载:"饿汉模式" 立即加载就是指使用类的时候已经将对象创建完毕,常见的实现方法就是直接new实例化.也就是在调用方法前,实例就被创建了.示例代码如下所示: class MyO ...

  7. 微软发布代码智能新基准数据集CodeXGLUE,多角度衡量模型优劣

    来源 | 微软研究院AI头条 编者按:代码智能(code intelligence)目的是让计算机具备理解和生成代码的能力,并利用编程语言知识和上下文进行推理,支持代码检索.补全.翻译.纠错.问答等场 ...

  8. Lombok!代码简洁神器还是代码“亚健康”元凶?

    以下文章来源方志朋的博客,回复"666"获面试宝典 关于Lombok,DD是一个重度用户,从我编写的Spring Boot教程还是Spring Cloud教程中,都可以看到几乎每个 ...

  9. 微服务测试之静态代码扫描

    静态代码扫描为整个发展组织增加价值.无论您在开发组织中发挥的作用如何,静态代码扫描解决方案都具有附加价值,拥有软件开发中所需要的尖端功能,最大限度地提高质量并管理软件产品中的风险. 背景 微服务架构模 ...

最新文章

  1. java1.8新增超实用Map方法——Map.getOrDefault()和Map.value()方法详解
  2. java中定义类的关键字为_在Java中,定义类的关键字是__________________.
  3. gradle不能下载最新依赖包问题
  4. 读取STM32单片机-ID操作
  5. c++实现解析文件路径
  6. 学python要有多少英语词汇量测试_非常适合新手的一个Python爬虫项目: 打造一个英文词汇量测试脚本!...
  7. Mac搭建PHP+rabbitMQ环境
  8. kubernetes 升级到1.6
  9. Mybatis Sql 大于号小于号不兼容
  10. python制作软件安装包_Python安装包及开发工具
  11. 基于JMP的神经网络设计案例分析
  12. Python实现直角坐标系求两点间距离
  13. 基于esp32的物联网设计
  14. 百度云网盘一直显示“下载请求中”,一个 解决办法
  15. 细说Java性能测试第三课 性能测试详解2
  16. RuntimeError: iter() is only supported inside of tf.function or when eager execution is enabled.
  17. 魔方机器人大赛——视觉算法
  18. ERROR 1366(HY000)报错解决方法
  19. 【线性代数】6-7:SVD分解(Singular Value Decomposition-SVD)
  20. 如何实现一个精简版的redux-saga

热门文章

  1. 基于arm-linux-gcc版本,音乐视频播放器mplayer
  2. ffmpeg笔记(一)音视频基础
  3. 三维重建方法--激光or视觉
  4. word里如何在□里打√!框框里打勾!!!!!
  5. 0xc0000225无法进系统_U盘装win10后无法进系统错误代码0xc0000225怎么修复
  6. 线下 Meetup 预告|从原理到实战,详解 Database Plus 的互联网最佳实践
  7. mysql pid无法写入_ERROR /usr/libexec/mysqld:写入文件'/var/run/mysqld/mysqld.pid'时出错(错误代码:28)...
  8. python学习(五)--打印错误信息
  9. Springboot启动后频繁打印错误日志 /null/swagger-ui.html解决方案
  10. 线性规划-pulp-复杂矩阵