1、学习型仿真工程师
2、理工科学子和教授
3、OpenFOAM软件兴趣爱好者和应用者
通过源代码学习OpenFOAM编程,显然不是为了直接编译运行仓库中的程序文件。本系列教程的目的是解读并练习程序的编译、配置以及测试运行过程。
OpenFOAM本质上是一个C 类库,其包含了从底层数值算法到高层应用求解器的所有细节代码。用户可以在此类库的基础上开发自己专有的CFD程序。然而OpenFOAM代码是一个极其庞大的代码库,想要灵活运用其基础代码也不是一件容易的事情,尤其是高层库更是经过了逐层封装,想要理清源代码之间的相互关系并灵活运用这些代码,除了阅读代码文档之外,多动手写代码也是必不可少的。
本系列课程的内容来自github
仓库地址:https://github.com/UnnamedMoose/BasicOpenFOAMProgrammingTutorials。
仓库所有者:Artur K Lidtke。
仓库中提供了17个tutorials。每个tut中都包含了源代码及Make文件夹,可以直接编译运行。
我们是想通过源代码学习OpenFOAM编程,显然不是为了直接编译运行仓库中的程序文件。本系列教程的目的是解读并练习程序的编译、配置以及测试运行过程。
案例内容包括:
Tutorial 0 - Hello world
配置环境,利用OpenFOAM编写一个简单的程序,其输出一条简单的信息。
Tutorial 1 - Input and output
演示从指定字典中读取数据,并将其输出到指定的文件中。
Tutorial 2 - Command line arguments
演示如何将参数和选项传递给自定义应用程序。
Tutorial 3 - Understanding the mesh
讨论OpenFOAM的网格描述如何工作,并介绍用于与网格交互的代码接口。
Tutorial 4 - Basic field operations
介绍场对象的概念,使用内置的运算符从OpenFOAM原生文件中读取值,以及手动计算场变量的值。
Tutorial 5 - Basic parallel computing
以Tutorial 4中开发的求解器为例,介绍使用OpenFOAM和OpenMPI进行并行计算的速成课程。描述了OpenFOAM处理并行区域分解的方式,展示了用于并行节点之间通信的基本操作,并将basic求解器升级为并行工作。
Tutorial 6 - Custom classes
演示如何添加一个新类来扩展OpenFOAM的功能,并给出了一个从OpenFOAM对象派生类的示例实现。从IOdictionary类派生一个新的类,目的是添加一个自定义方法,列出dict文件的内容,同时保留所有的基准功能。
Tutorial 7 - Custom libraries
演示如何编译外部库并将其添加到OpenFOAM。通过将教程4和5中“solver”的关键功能移动到一个独立的库中,然后将其与求解器代码的其余部分相链接来实现。
Tutorial 8 - Custom boundary condition
演示如何实现自定义边界条件。这里没有引入定制的实用工具,而是实现了一个库。这定义了一个入口条件,允许在管道入口指定边界层分布。
BC利用派生自fixedValue的类实现,添加了几个控制参数,允许指定入口分布。需要注意的关键方法是两个构造函数(默认构造函数和一个从字符串构造BC的构造函数)以及.updateCoeffs()。
测试案例是一条直管道,其流动可用基本的simpleFoam求解器进行求解。需要注意的是0.org/U文件中BC的定义,以及system/controlDict文件中所包含的定制库。案例在粗糙网格上使用3D RANS进行计算,因此在低端计算机上需要几分钟进行求解。边界条件的影响可以通过绘制通过管道的x速度图并注意入口边界层分布以及它对计算结果的影响来查看。
Tutorial 9 - Runtime post processing utility
讨论运行时后处理工具的实现,该工具使用topoSet计算通过指定网格面的流量。
该工具被实现为一个运行时后处理对象,该对象派生自OpenFOAM内置的fvMeshFunctionObject及logFiles类。其在每个所需的时间步对通过指定的网格面的法向速度进行积分,将计算结果写入到文件,并在屏幕上打印出来。
案例需要注意的内容为:
构造函数
writeFileHeader()函数
createFileNames()函数
write()函数
它们实现了工具背后的实际数**算。需要注意的是,该工具被编译为一个库,然后按照OpenFOAM运行时工具的约定链接到主求解器。
测试用例与教程8中的管道相同,只是本案例使用均匀的流入边界。值得注意的是system/topoSet中的faceZone的定义。可以通过在paraview中选择Include zones并应用Extract block过滤器来可视化。当simpleFoam解算器运行时,该工具将在postProcessing目录中创建输出文件。
Tutorial 10 - Transport equation
案例介绍求解简单的标量输运方程背后的概念。
Tutorial 11 - Modifying the mesh
展示如何通过点生成不同类型的网格,并将生成的网格导出到OpenFOAM案例中。
建议查看meshPoints.pdf及Gmsh文件,以便更好地了解网格是如何从点构造的。
Tutorial 12 - Adding a custom momentum source
展示了ActuatorDisk动量源的修改版本,该动量源不使用cell Set来标记要应用该源的网格,取而代之的是,它标识构造器内部的网格,该构造函数允许更容易地调整disk参数,并且可以进一步开发以包括动态变化。
实现的主要部分位于customActuationDiskSourceTemplates.C中,网格格选择算法在customActuationDiskSource.C的类构造函数中实现。本教程主要展示fvOption对象如何构造,以及如何修改它以满足需要。
Tutorial 13 - Waves
贡献者: Ramkumar
案例实现了一个求解波动方程的基本求解器。本教程的主要目的是介绍如何使用OpenFOAM C 求解自定义方程。教程Tutorial10提供了在已求解的速度场上求解输运方程的思路,该方程是稳态的。而在本案例,波动方程是以瞬态形式求解的。此求解器需要一个名为h的新物理场,它表示计算域中波的振幅。
测试用例是一个简单的二维波模拟,初始条件是将单个峰值振幅区域放置在二维面的中心。模拟计算了波如何通过反射传播和诱导新的波,它们的相长干涉和相消干涉也可以清楚地看到。几何体/网格是一个尺寸为1x1x0.01的长方体,厚度方向生成一层网格厚度,顶部面和底部面为empty边界条件。
Tutorial 14 - The SIMPLE Algorithm
贡献者: Ramkumar
显示了如何执行矩阵运算,以便使用SIMPLE算法求解流动控制方程。值得注意的是,该代码仅用于显示方程是如何求解的。因此,省略了优化和收敛检查条件,使代码更易于理解。
使用的测试用例求解了2D通道流。以下是理解本教程所需的前提条件:
CFD在线维基词条(非常简短,几乎没有细节,但很简洁)
https://www.cfd-online.com/Wiki/SIMPLE_algorithm
这个YouTube视频使用与代码中相同的矩阵表示法:
https://www.*******.com/watch?v=ahdW5TKacok
相当详细但简明扼要的笔记:
https://quickersim.com/tutorial/tutorial-2-numerics-simple-scheme
Tutorial 15 - Discretisation schemes
以一般标量输运方程中使用的对流通量为例,展示了在OpenFOAM中如何处理离散化的基本流程。导出的格式合并了线性插值和迎风插值,以演示如何实现自定义行为。需要注意的关键地方是OFtutorial15.H中定义的Weight例程。
使用的测试用例是一个简单的一维流,具有无量纲标量场,在x方向上转换跳跃。观察混合格式如何比纯上风更准确,且能避免简单线性格式的过冲。
推荐阅读书目:
WolfDynamics关于OpenFOAM中CFD理论的幻灯片:
http://www.wolfdynamics.com/training/OF_WS2020/traning_session2020.pdf
Tutorial 16 - Lagrangian Particle Tracking
开发了一个定制的应用程序,用于跟踪通过现有流场的无质量粒子。本教程介绍以下概念:
设置模拟时间,以便在特定保存的时间步长读取数据。
数据类型point和pointList,它们只不过是专用于坐标的矢量数据类型。
一种用于获取给定点坐标所在的网格id的网格函数。
拉格朗日无质量颗粒跟踪。
编写用于可视化颗粒轨迹的VTK文件。