🎉 Welcome to Aerosand!.

08_firstApp

0. 前言

之前讨论了编译原理、动态库的链接和 OpenFOAM 常见的类,现在我们使用 OpenFOAM ,完成一个较为完整的开发流程。

本文主要讨论

  • 理解 OpenFOAM 标准应用的文件架构
  • 认识使用脚本
  • 认识应用开发测试流程
  • 调用其他位置的开发库
  • 编译运行 firstApp 项目

1. fvCFD.H

在实际开发中,除了之前提到了 vector 和 tensor 等,我们还需要用到更多的和 FVM 相关的类来离散求解偏微分方程。OpenFOAM 提供 fvCFD.H ,其中包含了大部分和 FVM 相关的头文件,包括 tensor 类等。使用 fvCFD.H 可以大大减少主源码要写的头文件数量。

终端输入命令,查找 fvCFD.H 文件

terminal
find $FOAM_SRC -iname fvcfd.h

终端输出如下

terminal
/usr/lib/openfoam/openfoam2406/src/finiteVolume/cfdTools/general/include/fvCFD.H
/usr/lib/openfoam/openfoam2406/src/finiteVolume/lnInclude/fvCFD.H

显然 fvCFD.H 在 finiteVolume 库里,所以需要另外在 Make/options 中包含、链接。

Tip

OpenFOAM 库是低层库,已配置为自动依赖。而 finiteVolume 库属于高层库,依赖于众多低层库,需要手动配置。

我们可以将上篇代码中的原生头文件替换成 fvCFD.H ,并配置相关的 Make 文件。

2. 项目

我们使用 OpenFOAM 提供的方式创建求解器应用基础模板,并在此基础上进行开发。

终端输入命令,建立本文项目

terminal
ofsp
foamNewApp ofsp_08_firstApp
code ofsp_08_firstApp

2.1. 源代码

下面将讨论源代码。

2.2. 测试算例

对于不同的求解器,可以拷贝一个对应的原生算例用于测试求解器的开发。对于本项目来说,测试算例仅仅用于通过求解器语法检查。

终端输入命令,拷贝测试算例

terminal
cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity/cavity debug_case

2.3. 脚本文件

使用脚本可以方便用户开发测试。以本项目为例,我们新建脚本如下

终端输入命令,新建脚本

terminal
code caserun caseclean

脚本 caserun 主要是负责应用编译成功后,测试算例的运行,可以写入如下内容

/caserun
#!/bin/bash
# 首行告诉系统使用bash解释器执行脚本

# 对测试算例画网格,并输出日志到测试算例路径下
blockMesh -case debug_case | tee debug_case/log.mesh
# 输出信息“画网格完成”
echo "Meshing done."

# 对测试算例运行求解器,并输出日志到测试算例路径下
ofsp_08_firstApp -case debug_case | tee debug_case/log.run

脚本 caseclean 主要是负责清理应用到到编译前状态,如果应用要修改,那么测试算例也要还原到运行前的状态,可以写入如下内容

/caseclean
#!/bin/bash

# 删除测试算例中所有的日志文件
rm -rf debug_case/log.*

# 清理测试算例
foamCleanTutorials debug_case
# 输出信息“清理完成”
echo "Cleaning done."

2.4. 说明文件

为了方便后续阅读、开发和使用,我们还应该准备说明文件。

终端输入命令,新建说明文件

terminal
code README.md

说明文件内容如下

/README.md
## About

这是ofsp系列中,我们创建的第一个OpenFOAM标准应用。

## Bio

- Aerosand @ Aerosand

## Caution

需要使用 OpenFOAM v2406 及更新版本。

## Deploy

准备好环境和所有的文件。

在根目录下执行终端命令

清理并重新编译应用

1. wclean
2. wmake
   
清理并重新计算测试算例

1. ./caseclean
2. ./caserun

## Event

@ 20250903
- 增加清理脚本 ok

@ 20250901
- 新建应用 ok

建议遵循 About-Bio-Caution-Deploy-Event 的 A-B-C-D-E 原则书写说明文件,尽量表述清楚必要信息。

3. 文件结构

可以看到该项目的文件结构如下

终端输入命令

terminal
tree
.
├── caseclean
├── caserun
├── debug_case
│   ├── 0
│   │   ├── p
│   │   └── U
│   ├── constant
│   │   ├── polyMesh
│   │   │   ├── boundary
│   │   │   ├── faces
│   │   │   ├── neighbour
│   │   │   ├── owner
│   │   │   └── points
│   │   └── transportProperties
│   ├── log.mesh
│   ├── log.run
│   └── system
│       ├── blockMeshDict
│       ├── controlDict
│       ├── decomposeParDict
│       ├── fvSchemes
│       ├── fvSolution
│       └── PDRblockMeshDict
├── Make
│   ├── files
│   └── options
└── ofsp_08_firstApp.C

4. 测试

终端输入命令,运行脚本

terminal
wclean
wmake
./caseclean
./caserun

如果运行提醒 Permission denied,那就需要给脚本权限

terminal
chmod +x caserun caseclean

虽然我们还没有给求解器写入任何开发代码,但是 OpenFOAM 提供的求解器基础模板在测试算例存在的情况下,仍然可以运行。

终端输出信息有两段

第一段是划分网格的输出日志

terminal
/*---------------------------------------------------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  2406                                  |
|   \\  /    A nd           | Website:  www.openfoam.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
Build  : _9bfe8264-20241212 OPENFOAM=2406 patch=241212 version=2406
Arch   : "LSB;label=32;scalar=64"
Exec   : blockMesh -case debug_case
Date   : Sep 01 2025
Time   : 18:09:17
Host   : aerosand
PID    : 200553
I/O    : uncollated
Case   : /home/aerosand/github/data_project/openfoam_sharing/ofsp/ofsp_08_firstApp/debug_case
nProcs : 1
trapFpe: Floating point exception trapping enabled (FOAM_SIGFPE).
fileModificationChecking : Monitoring run-time modified files using timeStampMaster (fileModificationSkew 5, maxFileModificationPolls 20)
allowSystemOperations : Allowing user-supplied system call operations

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Create time

Creating block mesh from "system/blockMeshDict"
Creating block edges
No non-planar block faces defined
Creating topology blocks

Creating topology patches - from boundary section

Creating block mesh topology - scaling/transform applied later

Check topology

        Basic statistics
                Number of internal faces : 0
                Number of boundary faces : 6
                Number of defined boundary faces : 6
                Number of undefined boundary faces : 0
        Checking patch -> block consistency

Creating block offsets
Creating merge list (topological search)...

Creating polyMesh from blockMesh
Creating patches
Creating cells
Creating points with scale (0.1 0.1 0.1)
    Block 0 cell size :
        i : 0.005 .. 0.005
        j : 0.005 .. 0.005
        k : 0.01 .. 0.01

No patch pairs to merge

Writing polyMesh with 0 cellZones
----------------
Mesh Information
----------------
  boundingBox: (0 0 0) (0.1 0.1 0.01)
  nPoints: 882
  nCells: 400
  nFaces: 1640
  nInternalFaces: 760
----------------
Patches
----------------
  patch 0 (start: 760 size: 20) name: movingWall
  patch 1 (start: 780 size: 60) name: fixedWalls
  patch 2 (start: 840 size: 800) name: frontAndBack

End

Meshing done.

第二段是求解器运行的输出日志

terminal
/*---------------------------------------------------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  2406                                  |
|   \\  /    A nd           | Website:  www.openfoam.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
Build  : _9bfe8264-20241212 OPENFOAM=2406 patch=241212 version=2406
Arch   : "LSB;label=32;scalar=64"
Exec   : ofsp_08_firstApp -case debug_case
Date   : Sep 01 2025
Time   : 18:09:17
Host   : aerosand
PID    : 200555
I/O    : uncollated
Case   : /home/aerosand/github/data_project/openfoam_sharing/ofsp/ofsp_08_firstApp/debug_case
nProcs : 1
trapFpe: Floating point exception trapping enabled (FOAM_SIGFPE).
fileModificationChecking : Monitoring run-time modified files using timeStampMaster (fileModificationSkew 5, maxFileModificationPolls 20)
allowSystemOperations : Allowing user-supplied system call operations

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Create time


ExecutionTime = 0 s  ClockTime = 0 s

End

5. 原生主源码

代码 ofsp_08_firstApp.C

/ofsp_08_firstApp.C
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | www.openfoam.com
     \\/     M anipulation  |
-------------------------------------------------------------------------------
    Copyright (C) 2025 AUTHOR,AFFILIATION
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.

Application
    ofsp_08_firstApp

Description
	这部分是 OpenFOAM 的注释内容,提供该应用的必要介绍。
\*---------------------------------------------------------------------------*/

#include "fvCFD.H"
// 包含了和FVM有关的类、函数等

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

int main(int argc, char *argv[])
{
    #include "setRootCase.H"
    // 建立命令行参数
    // 检查确定算例目录
    // 后续会详细讨论
    
    #include "createTime.H"
    // 创建并初始化时间控制对象Time
    // 后续会详细讨论

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    Info<< nl;
    // Info是OpenFOAM提供打印信息、格式化输出的全局对象
    // nl是OpenFOAM提供的换行符(newline)
    
    runTime.printExecutionTime(Info);
    // 用来打印程序运行时间的函数调用

    Info<< "End\n" << endl;

    return 0;
}


// ************************************************************************* //

6. 使用开发库

在该项目中,我们有选择的使用上一篇讨论所开发的 Aerosand 库中的某个类。

6.1. 主源码

代码 ofsp_08_firstApp.C 修改为

/ofsp_08_firstApp.C
#include "fvCFD.H"

#include "class1.H" // 调用我们想要的开发库头文件名称

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

int main(int argc, char *argv[])
{
    #include "setRootCase.H"
    #include "createTime.H"


    label a = 1;
    scalar pi = 3.1415926;
    Info<< "Hi, OpenFOAM!" << " Here we are." << nl
	    << a << " + " << pi << " = " << a + pi << nl
	    << a << " * " << pi << " = " << a * pi << nl
	    << endl;

    class1 mySolver;
    mySolver.SetLocalTime(0.2);
    Info<< "\nCurrent time step is : " << mySolver.GetLocalTime() << endl;

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

    Info<< nl;
    runTime.printExecutionTime(Info);

    Info<< "End\n" << endl;

    return 0;
}

6.2. 项目 Make

项目 Make/files

/Make/files
ofsp_08_firstApp.C

EXE = $(FOAM_USER_APPBIN)/ofsp_08_firstApp

Caution

注意,这里需要链接的是上一篇讨论建立的开发库。

项目 Make/options

/Make/options
EXE_INC = \
    -I$(LIB_SRC)/finiteVolume/lnInclude \
    -I$(LIB_SRC)/meshTools/lnInclude \
    -I../ofsp_07_tensor/Aerosand/lnInclude

EXE_LIBS = \
    -lfiniteVolume \
    -lmeshTools \
    -L$(FOAM_USER_LIBBIN) \
    -lAerosand

我们再次解释其写法

  • 前缀 EXE 表示这是可执行文件的配置(前缀 LIB 表示是库文件的配置)
  • 后缀 INC 表示包含路径
    • 使用 -I 标志指定头文件搜索路径
    • 通常指向 OpenFOAM 模块的 lnInclude 目录(链接包含目录)
    • 可以包含系统头文件路径或第三方库头文件路径
  • 后缀 LIBS 表示库链接(直接链接无需链接任何库,可以留空不写)
    • 使用 -l 标志指定需要链接的库
    • 库名称不需要前缀 lib 和后缀 .so(如 -lfiniteVolume 对应 libfiniteVolume.so
    • 使用 -L 标志指定库搜索路径
  • 路径可以采用多种写法
    • $(LIB_SRC) 通常由 OpenFOAM 环境变量相对路径组合而成
    • 常见写为 -I$(FOAM_SRC)/finiteVolume/lnInclude 也可以
    • 绝对地址 -I/usr/lib/openfoam/openfoam2306/src/finiteVolume/lnInclude
    • 相对地址 -I../ofsp_07_tensor/Aerosand/lnInclude

7. 编译运行

因为上一篇讨论的 Aerosand 库已经编译成功,这里不用再次编译,直接调用即可。

terminal
wclean
wmake
./caseclean
./caserun

终端输出如下(仅摘取有主要变化的片段)

terminal
...

Create time

Hi, OpenFOAM! Here we are.
1 + 3.14159 = 4.14159
1 * 3.14159 = 3.14159


Current time step is : 0.2

ExecutionTime = 0.01 s  ClockTime = 0 s

End

8. 小结

本文完成讨论

  • 理解 OpenFOAM 标准应用的文件架构
  • 认识使用脚本
  • 认识应用开发测试流程
  • 调用其他位置的开发库
  • 编译运行 firstApp 项目
Last updated on