第7章 uFVM 与 OpenFOAM® 中的有限体积网格(The Finite Volume Mesh in OpenFOAM® and uFVM)
作者
本章由 F. Moukalled、L. Mangani 和 M. Darwish 合著。本章是 Ch 6 网格规范的"实现篇" —— 把"理论上 FVM 网格需要什么信息"转化为"在 uFVM(MATLAB 教学代码)与 OpenFOAM(C++ 工业代码)这两套代码中,具体怎么存储、怎么读取、怎么处理"。本章是全书"工程实用价值"最高的一章之一。
内容概述
本章的核心目标是把 Ch 6 抽象的 FVM 网格规范,落到两套具体代码的数据结构与文件组织上。
§7.1 uFVM —— 教学性、MATLAB 写成的非结构 FVM 代码。uFVM 共享 OpenFOAM 的核心数据结构(mesh fields + boundary conditions),但用更简单的实现技术。
§7.1.1 OpenFOAM 测试用例 —— OpenFOAM 的标准测试用例组织为 3 个目录:
- 0/(或 0.orig/):时间步 0 时的场初始化与边界条件(U、p、T 等)
- constant/:物理属性(transportProperties)+ 网格(polyMesh/)
- system/:求解控制(controlDict、fvSchemes、fvSolution)
OpenFOAM 的著名 cavity 算例(顶盖驱动方腔流)是入门示例,验证 uFVM 的网格读取功能。
§7.1.2 polyMesh 目录 —— 5 个核心文件:
- points:cell 顶点的 \((x, y, z)\) 坐标列表
- faces:face 的顶点索引列表(每个 face 由若干顶点构成)
- owner:每个 face 的 owner cell 索引(内部面 + 边界面都有 owner)
- neighbour:内部面的 neighbour cell 索引(边界面的 neighbour = -1)
- boundary:边界 patch 列表(name、type、nFaces、startFace)
§7.1.3 uFVM 网格读取 —— uFVM 通过 cfdReadOpenFoamMesh 脚本读取 OpenFOAM 网格,存储为 MATLAB struct:
- m.nodes:每个 node 的 centroid、index、iFaces、iElements
- m.faces:每个 face 的 iNodes、iOwner、iNeighbour、centroid、Sf、area、CN、geoDiff、T、gf、walldist
- m.elements:每个 cell 的 index、iNeighbours、iFaces、iNodes、volume、faceSign
- m.boundaries:patch 名、起始 face 索引、face 数量
§7.2 OpenFOAM —— 工业级、C++ 写成的开源 FVM 代码。OpenFOAM 的 polyMesh 类(src/OpenFOAM/meshes/polyMesh/)实现了与 uFVM 等价的网格数据结构,但用 C++ 类 + 模板 + 智能指针实现。
§7.2.1 OpenFOAM 测试用例的扩展 —— 除了 0/、constant/、system/,OpenFOAM 还有:
- constant/dynamicMeshDict:动网格配置
- system/blockMeshDict:blockMesh 网格生成配置
- system/snappyHexMeshDict:snappyHexMesh 网格生成配置
- system/fvSchemes:离散化格式选择(gradScheme、divScheme、laplacianScheme、interpolationScheme 等)
- system/fvSolution:求解器选择(SIMPLE、PISO)、线性求解器、容差、亚松弛因子
§7.2.2 OpenFOAM 的场与方程组装 —— OpenFOAM 的 GeometricField<Type, PatchField, GeoMesh> 模板类实现了 FVM 场存储;fvMatrix<Type> 类实现了 FVM 线性系统组装(与 Ch 5 Eq. 5.43 完全对应)。fvm::div(phi, U)、fvm::laplacian(nu, U)、fvm::ddt(U) 等显式操作符对应 Ch 8-14 的各项离散化方法。
§7.3 场的数据结构 —— uFVM 的 cfdField、cfdMesh 与 OpenFOAM 的 GeometricField、polyMesh 的对应关系。
§7.4 边界条件 —— uFVM 的 cfdBoundary 与 OpenFOAM 的 fvPatchField 的对应关系。fixedValue、fixedGradient、zeroGradient、mixed、cyclic、symmetryPlane 等边界条件类型在两套代码中的实现方式。
§7.5 线性系统的存储 —— 稀疏矩阵的 CSR / CSC / COO 存储格式。OpenFOAM 使用 lduAddressing(Lower-Diagonal-Upper addressing)存储稀疏矩阵,相比 CSR 更适合非结构网格的 FVM 离散化。
§7.6 闭包 —— 本章的"代码实现视角"是 Ch 8-14 各项数值方法实现的"前置基础"。
核心方程与概念
本章以数据结构与文件格式为主,公式较少,但每个公式都是工业 CFD 实践的关键。
一、OpenFOAM 测试用例的目录结构(Fig. 7.1, §7.1.1)
cavity/
├── 0/ # 时间步 0 的场初始化
│ ├── U # 速度场
│ └── p # 压力场
├── constant/
│ ├── transportProperties # 黏度等
│ └── polyMesh/ # 网格
│ ├── points
│ ├── faces
│ ├── owner
│ ├── neighbour
│ └── boundary
└── system/
├── controlDict # 时间步长、起止时间
├── fvSchemes # 离散格式
└── fvSolution # 求解器
二、polyMesh 5 文件的格式(§7.1.2, Listing 7.1-7.11)
points:每行一个 \((x, y, z)\),如(32 16 0.9377383239)。header 标nPoints。faces:每行一个 face,由若干顶点索引构成,如4(36 573 589 52)。header 标nFaces。owner:每行一个 cell 索引,对应 face 的 owner。nCells是最大 owner 索引 + 1。neighbour:每行一个 cell 索引,对应内部 face 的 neighbour(边界面对应 -1)。header 标nInternalFaces。boundary:patch 列表,每 patch 包含 name、type、nFaces、startFace。
三、uFVM 数据结构(§7.1.3, Listing 7.13-7.17)
每个 node 存储:
- centroid:\((x, y, z)\) 坐标
- index:node 编号
- iFaces:相邻 face 索引列表
- iElements:相邻 element 索引列表
每个 face 存储:
- iNodes:构成 face 的 node 索引列表
- iOwner:owner cell 索引
- iNeighbour:neighbour cell 索引(边界面 = -1)
- centroid、Sf、area:几何量
- CN、T、geoDiff、gf、walldist:距离向量与几何因子
每个 element 存储:
- iNeighbours、iFaces、iNodes:邻接关系
- volume、centroid:几何量
- faceSign:标志 element 在每个 face 上是 owner (+1) 还是 neighbour (-1)
四、稀疏矩阵存储的 ldu 格式(§7.5)
OpenFOAM 使用 lduMatrix(Lower-Diagonal-Upper Matrix)存储稀疏矩阵,相比通用的 CSR 格式,更适合 FVM 的非结构网格:
- 对角元素存储为稠密数组
- 非对角元素按"owner + neighbour"对应存储
- 通过 lduAddressing 数组(lowerAddr、upperAddr)索引非对角元素
lduMatrix 的存储结构与 Ch 5 Eq. 5.43 的 \(a_C \phi_C + \sum_F a_F \phi_F = b_C\) 形式直接对应 —— 每个 cell 的"对角系数"是 \(a_C\),"上对角 + 下对角"非零元素对应 \(\sum_F a_F\)。对角占优要求
这是 FVM 离散化解的存在唯一性与稳定性的必要条件(Ch 5.4 节有界性原则)。
五、OpenFOAM 的显式离散算符(§7.2.2)
fvm::ddt(phi):瞬态项离散(Ch 13),对应
$\(\frac{\partial \phi}{\partial t}\bigg|_P \approx \frac{\phi_P^{n+1} - \phi_P^n}{\Delta t}\)$
fvm::div(flux, phi):对流项离散(Ch 11-12),对应
$\(\oint_{\partial V_P} \rho \mathbf{v} \phi \cdot d\mathbf{S} = \sum_f \rho \mathbf{v}_f \phi_f \cdot \mathbf{S}_f\)$
fvm::laplacian(coeff, phi):扩散项离散(Ch 8),对应
$\(\oint_{\partial V_P} \Gamma \nabla \phi \cdot d\mathbf{S} = \sum_f \Gamma_f \nabla \phi_f \cdot \mathbf{S}_f\)$
fvc::grad(phi):梯度显式计算(Ch 9),对应
$\(\nabla \phi_P = \frac{1}{V_P} \sum_f \phi_f \mathbf{S}_f\)$
每个算符返回一个 fvMatrix<Type>,可直接组装为线性系统 \(\mathbf{A} \mathbf{x} = \mathbf{b}\) 通过线性求解器(Ch 10)求解。
关键结论
- OpenFOAM 与 uFVM 在数据结构上高度同构:都基于"节点 → 面 → 控制体"三层拓扑,加上 owner / neighbour 关系与几何量存储。这种"数据结构同构"是 uFVM 能直接读取 OpenFOAM 网格的根本原因。
- OpenFOAM 的 polyMesh 5 文件是 FVM 网格的最小完备集:
points、faces、owner、neighbour、boundary这 5 个文件足够推导出 Ch 6 列举的所有几何量与拓扑关系。其他所有"派生量"(面积向量、距离向量、形心、体积)都由这 5 个文件计算。 - lduMatrix 存储格式适合 FVM:相比通用的 CSR 格式,ldu 格式直接对应 Eq. 5.43 的"对角 + 上对角 + 下对角"结构,对 FVM 离散化的矩阵组装与求解更友好。
- OpenFOAM 的
fvm::/fvc::命名空间:fvm::(隐式)返回fvMatrix,fvc::(显式)返回GeometricField。这种命名约定清晰地分离了"参与线性系统组装的项"和"显式计算的项",是 OpenFOAM API 的核心设计。 - boundary patch 的 type 决定了边界条件的实现:
fixedValue/fixedGradient/zeroGradient/mixed/cyclic/symmetryPlane等 patch type 与 Ch 5 §5.5 的边界条件处理规则一一对应。Ch 18 会详细讨论 OpenFOAM 的边界条件实现机制。
挑战和开放性问题
- 大数据量网格的 I/O 性能 —— OpenFOAM 网格以 ASCII 文本存储,工业级 CFD 算例的网格可能包含数亿 cell,I/O 成为瓶颈。OpenFOAM 提供
foamFormat binary选项可显著加速,但兼容性较差。 - 稀疏矩阵求解器的预条件子 —— OpenFOAM 6+ 引入
PETSc/AMGCL等外部求解器,但默认GAMG(Geometric-Algebraic Multigrid)在某些病态问题上仍收敛困难。 - 并行 IO 与网格分解 —— 大规模并行 CFD 中,网格分解(scotch、metis、kahip)、并行 IO(HDF5、SST)的实现细节是工业 CFD 的关键,本书未深入。
- 动网格数据结构 —— OpenFOAM 的
dynamicMotionSolverFvMesh、dynamicRefineFvMesh等动网格实现涉及复杂的拓扑变化数据结构,本书未展开。 - GPU 加速 —— OpenFOAM 在 2016 年仍以 CPU 为主,GPU 加速(如
AMGX、cuPDE)是后续发展方向,本书未涉及。 - cellZone / faceZone / pointZone —— OpenFOAM 的 zone 机制(用于区分流体 / 固体区域、转子 - 静子交界面等)未在本书展开。
个人反思与批判性分析
本章是全书"工程实用性"密度最高的一章,给出 uFVM 与 OpenFOAM 的完整数据结构与文件组织。本章对 OpenFOAM 用户的价值在于:OpenFOAM 的官方文档虽然完备,但很少系统性地把"为什么 OpenFOAM 要这样组织 mesh 数据"讲清楚。本章恰好填补了这一空白。
从写作特点看:
- "教学代码 + 工业代码"双轨对比 —— uFVM 与 OpenFOAM 的数据结构一一对应(MATLAB struct ↔ C++ class),读者可以同时在两套代码上验证同一数值方法。这种"理论 → 教学实现 → 工业实现"的三级递进是 Moukalled 这本教材的核心教学设计。
- polyMesh 5 文件的"最小完备集"思想 —— 本章把 OpenFOAM 看似复杂的网格数据结构简化为 5 个文件,每个文件的格式、header、示例都清晰展示。这对 OpenFOAM 自定义 solver 开发者是必备知识。
- MATLAB
structvs C++class的设计哲学对比 —— uFVM 的struct字段名是字符串,运行时刻可动态修改;OpenFOAM 的class字段名是编译时确定的,运行时刻不可修改。这种"动态 vs 静态"的设计哲学对比,对学习"教学代码 → 工业代码"的过渡非常有价值。
但本章也存在不足:
- OpenFOAM 的
GeometricField模板类没有完整展开 ——GeometricField<Type, PatchField, GeoMesh>三个模板参数的含义(Type = scalar/vector/tensor、PatchField = boundary condition 类、GeoMesh = volMesh/surfaceMesh/pointMesh)未详细解释。这是 OpenFOAM 自定义场类型开发的关键。 lduMatrix与稀疏矩阵求解器的关系 —— 本章给出lduMatrix的存储结构,但未详细说明它如何与PCG、GAMG、PBiCG等线性求解器(Ch 10 详述)配合使用。- 对 OpenFOAM 第三方库(CGAL、PETSc、METIS、Scotch)的接口未提及 —— 工业级 OpenFOAM 使用涉及大量第三方数学库,本书完全未提及。
- 缺少对
mapFields、setFields、funkySetFields等网格操作工具的介绍 —— 这些是 OpenFOAM 网格与场初始化 / 转换的核心工具。
总体而言,本章是 OpenFOAM 工程实践的"入门百科",对需要进入 OpenFOAM 二次开发(自定义 solver、自定义边界条件、自定义湍流模型)的读者是必读章节。本章与 Ch 6 一起构成 FVM 网格的"理论 + 实践"完整闭环。
重要参考文献
- [X1] OpenFOAM Foundation (2014) The Open Source CFD Toolbox — User Guide. (OpenFOAM 官方文档)
- [X2] OpenFOAM Foundation (2014) OpenFOAM: The Open Source CFD Toolbox — Programmer's Guide. (OpenFOAM 内部数据结构与 API)
- [X3] Jasak H. (1996) Error Analysis and Estimation for the Finite Volume Method with Applications to Fluid Flows. PhD Thesis, Imperial College. (OpenFOAM 早期开发者的博士论文,OpenFOAM 数据结构与 FVM 离散化误差的原始设计文档)
- [X4] Weller H.G., Tabor G., Jasak H., Fureby C. (1998) A tensorial approach to computational continuum mechanics using object-oriented techniques. Computers in Physics, 12(6): 620-631. (OpenFOAM 早期论文,介绍面向对象的 FVM 实现)
- [X5] Moukalled F., Mangani L., Darwish M. (2016) uFVM source code. Available at: https://feaweb.aub.edu.lb/research/cfd. (uFVM 官方下载链接)
- [X6] Geuzaine C., Remacle J.F. (2009) Gmsh: a three-dimensional finite element mesh generator with built-in pre- and post-processing facilities. International Journal for Numerical Methods in Engineering, 79(11): 1309-1331. (Gmsh 网格生成工具)
- [X7] Karypis G., Kumar V. (1998) METIS: A Software Package for Partitioning Unstructured Graphs, Partitioning Meshes, and Computing Fill-Reducing Orderings of Sparse Matrices. University of Minnesota. (METIS 网格分解工具)
- [X8] Balay S., et al. (2019) PETSc Users Manual. Argonne National Laboratory. (PETSc 求解器库)