· 靳贺伟 · 网格基础 · 18 min read
OpenFOAM v2512 动态加密网格:dynamicRefineFvMesh 原理、设置与应用
详细介绍 OpenFOAM v2512 dynamicRefineFvMesh 的单元细化与粗化机制、阈值场、层级约束、通量修正、时间步控制、VOF 和局部高梯度应用。
本文以 OpenCFD 发布的 OpenFOAM v2512 为基准。
dynamicRefineFvMesh是运行时拓扑变化网格:它根据指定场值细化或粗化单元,但不等同于通用误差估计型 AMR,也不能独立替代固体运动网格。
1. 为什么需要动态加密
静态局部加密必须预先知道高梯度将出现在哪里。如果气液界面、火焰、激波或污染物团随时间移动,为整个可能路径统一布置细网格会造成大量无效单元。
动态加密的目标是:
- 高梯度结构到达某处时自动细化;
- 结构离开后自动粗化;
- 把计算资源集中在当前最需要分辨的区域;
- 在可接受单元数下提高局部空间分辨率。
基本逻辑为:
读取监测场
↓
筛选满足细化阈值的单元
↓
检查最大层级、缓冲层和最大单元数
↓
分裂单元
↓
筛选满足粗化条件的单元
↓
合并可粗化的同源子单元
↓
映射场并修正通量由于单元数量和连接关系发生变化,动态加密本质上属于拓扑变化网格。
2. dynamicRefineFvMesh 的细化机制
OpenFOAM 的典型三维六面体细化会把一个父单元分裂为 8 个子单元;二维或挤出类算例的实际分裂受网格维度和约束影响。
若初始特征长度为 (\Delta x_0),细化层级为 (l),理想情况下:
[ \Delta x_l=\frac{\Delta x_0}{2^l} ]
三维单元体积约为:
[ V_l=\frac{V_0}{8^l} ]
因此细化层级每增加一级,局部空间分辨率提高一倍,但三维局部单元数最多增加约 8 倍。两级细化若覆盖范围过大,单元数会迅速膨胀。
3. 细化层级与 2:1 约束
相邻单元层级差过大,会导致悬挂节点结构复杂、面分割不规则和离散误差增大。动态加密通常通过缓冲层和一致性检查限制层级跳变。
nBufferLayers 用于在细化区域周围保留过渡层。例如:
nBufferLayers 1;可使细网格与粗网格之间不直接发生过于突兀的层级变化。
需要理解:缓冲层并不是额外的物理模型,它会显著扩大实际细化区域。估算单元数时不能只统计满足阈值的核心单元。
4. v2512 的基本字典结构
在 constant/dynamicMeshDict 中可采用:
dynamicFvMesh dynamicRefineFvMesh;
dynamicRefineFvMeshCoeffs
{
refineInterval 1;
field alpha.water;
lowerRefineLevel 0.001;
upperRefineLevel 0.999;
unrefineLevel 0.0001;
nBufferLayers 1;
maxRefinement 2;
maxCells 2000000;
correctFluxes
(
(phi U)
(rhoPhi none)
);
dumpLevel true;
}各参数的含义如下。
4.1 refineInterval
每隔多少个时间步检查一次细化/粗化:
refineInterval 1;表示每个时间步都检查。若网格更新开销较大,可设为 2、5 或更大,但移动结构可能在两次检查之间跨过多个粗网格单元。
4.2 field
用于判断细化的体标量场。例如:
field alpha.water;表示根据水相体积分数加密。也可使用温度、组分、压力或用户计算得到的标量指示场。
4.3 lowerRefineLevel 与 upperRefineLevel
满足:
[ L_{lower}<\phi<L_{upper} ]
的单元进入细化候选。
VOF 中使用 0.001 < alpha.water < 0.999,意图是捕捉含有两相的界面单元,而不是加密纯气相或纯液相。
4.4 unrefineLevel
用于判定粗化。粗化阈值应与细化阈值形成一定滞回,避免单元在临界值附近反复细化—粗化。
不同字段的合适数值不同,不能把相分数示例直接套用于温度或涡量。
4.5 maxRefinement
允许的最大细化层级:
maxRefinement 2;若初始单元尺寸为 8 mm,理想最细尺寸约为:
[ 8/2^2=2\ \text{mm} ]
4.6 maxCells
全域最大单元数上限。达到上限后,即使有单元满足阈值,也不能继续无限细化。
maxCells 应结合内存、并行规模和每时间步可接受计算时间确定,而不是简单设成极大值。
4.7 correctFluxes
网格拓扑改变后,需要为面通量指定修正方式:
correctFluxes
(
(phi U)
(rhoPhi none)
);每一对表示通量场及用于重构的相关场。不同求解器中的通量名称不同,应核对求解器源码和初始场。错误设置可能导致拓扑更新后连续性恶化。
4.8 dumpLevel
设置为 true 时输出细化层级场,便于在 ParaView 中检查哪些区域被加密以及最高层级是否符合预期。
5. 选择细化指示场
5.1 直接物理场
可直接使用:
- 相分数
alpha.water; - 温度
T; - 某组分质量分数;
- 压力
p; - 湍动能
k。
但阈值区间是“场值范围”,不等同于梯度。若希望追踪温度梯度而不是某一温度区间,应先构造梯度指标场。
5.2 梯度或涡量指示场
可通过函数对象、postProcess、coded function object 或自定义求解器生成:
[ I_T=|\nabla T|, \qquad I_Y=|\nabla Y|, \qquad I_\omega=|\nabla\times U| ]
然后令 field 指向该标量场。
应注意:若指示场只在写出时更新,而动态网格每步都读取,则可能使用滞后的指标。必须确认指示场的计算时机早于网格更新。
5.3 组合指示场
复杂问题可能需要同时关注火焰面、液滴和壁面附近。dynamicRefineFvMesh 的基本配置通常围绕一个标量场,因此可构造组合指标:
[ I=\max\left( \frac{|\nabla T|}{I_{T,ref}}, \frac{|\nabla Y_f|}{I_{Y,ref}}, \frac{|\omega|}{I_{\omega,ref}} \right) ]
再按统一阈值细化。组合时必须进行无量纲化,避免量纲和数量级不同的变量互相淹没。
6. 动态加密与有限体积守恒
单元分裂后,父单元上的守恒量需要分配给子单元;粗化时,多个子单元需要合并到父单元。
对于体积分量 (q),理想映射应满足:
[ \sum_{c\in old}q_cV_c
\sum_{c\in new}q_cV_c ]
重点检查:
- 总质量;
- 各相体积;
- 各组分质量;
- 总焓;
- 动量;
- 颗粒或污染物总量。
某些变量经过有界性修正后,局部数值会被截断,这可能与严格积分守恒产生冲突。VOF 中尤其需要同时检查:
[ 0\le \alpha \le 1 ]
以及全域液相体积是否随网格更新产生异常漂移。
7. 时间步:最细网格决定限制
细化后最小 (\Delta x) 变小,流动 Courant 数增大:
[ Co=\frac{|U|\Delta t}{\Delta x} ]
若局部细化两级,(\Delta x) 降为原来的四分之一,在速度不变时,保持相同 Co 需要把时间步降为原来的四分之一。
VOF 还要考虑界面 Courant 数;可压缩流和激波问题还受声速限制。动态加密后若仍使用原固定时间步,常出现:
- 相分数发散;
- 压力振荡;
- 新细化区残差突然升高;
- 最大 Co 周期性超限。
建议启用自适应时间步并设置合理 maxCo、maxAlphaCo 和 maxDeltaT。
8. 动态加密的一般使用流程
第一步:完成无动态加密的基准算例
先在静态网格上确保:
- 边界条件正确;
- 物理模型稳定;
- 时间步可接受;
- 基本守恒成立。
不要用动态加密掩盖基础算例本身的问题。
第二步:确定“需要解析的结构”
明确目标是:
- 界面厚度;
- 火焰面;
- 涡结构;
- 激波;
- 污染物前沿;
- 局部温度梯度。
细化指标应与研究目标对应。
第三步:估算最细网格和最大单元数
根据初始尺寸和 maxRefinement 计算最细尺寸,并估计细化区域体积。应提前评估:
- 内存;
- 每步计算时间;
- 写文件体积;
- 并行负载不均衡;
- 时间步缩小倍数。
第四步:设置阈值并可视化层级
开启:
dumpLevel true;短时运行后在 ParaView 查看:
- 细化区是否跟随目标结构;
- 是否加密了大面积无关区域;
- 是否存在频繁闪烁;
- 缓冲层是否过宽;
- 是否达到
maxCells。
第五步:监控拓扑更新时的残差和守恒
将每次细化时刻与以下曲线对齐:
- 最大 Co;
- 连续性误差;
- 总相体积;
- 力和力矩;
- 出口质量流量;
- 线性求解器迭代数。
若每次网格更新都产生显著尖峰,需要调整阈值、更新间隔、通量修正或时间步。
9. VOF 自由界面应用
动态加密最常见的应用是 VOF。相分数界面位于:
[ 0<\alpha<1 ]
因此可使用:
field alpha.water;
lowerRefineLevel 0.001;
upperRefineLevel 0.999;
unrefineLevel 0.0001;但应注意:
- 数值扩散会使界面变厚,导致细化范围扩大;
- 细化本身不能替代合适的界面压缩格式;
- 自由界面穿过粗细网格过渡区时可能产生曲率和表面张力噪声;
- 小液滴粗化后可能直接消失;
- 接触线附近还受壁面网格和接触角模型影响。
验证应包括液相总体积、界面形状、波高/液滴尺寸和网格层级独立性。
10. 火焰和反应流应用
可根据温度区间、燃料/氧化剂梯度、反应速率或进度变量加密火焰区。
例如构造进度变量:
[ c=\frac{T-T_u}{T_b-T_u} ]
对 (0.05<c<0.95) 区域细化。
风险包括:
- 化学时间尺度比流动时间尺度更严格;
- 细化后网格 Peclet 数变化;
- 湍流—化学模型参数可能依赖滤波尺度或网格尺度;
- 火焰面快速移动时
refineInterval过大会丢失前沿。
LES 中动态网格改变滤波宽度,亚格子模型和统计稳定性需要单独评估。
11. 激波与可压缩流应用
可使用压力梯度、密度梯度或马赫数变化构造指标:
[ I_p=|\nabla p|, \qquad I_\rho=|\nabla \rho| ]
动态加密可以提高激波位置分辨率,但并不会自动保证非振荡。仍需要:
- 合适的激波捕捉格式;
- 限制器;
- 可压缩通量;
- 声学 Courant 数控制;
- 粗细网格过渡区反射检查。
12. 污染物、羽流和多相输运应用
对于移动污染物团或热羽流,可根据浓度区间、浓度梯度、温度梯度或涡量细化。
在工业通风中,动态加密适合研究短时释放、局部射流和移动污染团;对于长时间统计、全车间稳定浓度场,频繁拓扑变化可能得不偿失,静态分区加密通常更稳健。
颗粒 Lagrangian 计算还需注意:
- 网格更新后颗粒所在单元需要重新定位;
- 小单元增多会增加颗粒追踪开销;
- 颗粒源项映射到新单元时应保持守恒;
- 动态粗化可能降低近壁沉积分辨率。
13. 并行计算与负载均衡
细化区域随时间移动会导致处理器负载失衡。某些处理器可能拥有大量细化单元,其他处理器仍为空闲。
应监控:
- 各处理器单元数;
- 网格更新耗时;
- 线性求解耗时;
- 并行通信;
- 是否需要动态重新分区。
即使总单元数受 maxCells 限制,严重负载失衡也会使并行效率下降。对高核数计算,动态加密区域的运动路径应在初始分区策略中考虑。
14. 常见错误与修正
14.1 单元数迅速达到 maxCells
原因可能是阈值范围太宽、指示场有噪声、缓冲层过多或最大层级过高。先查看 cellLevel,不要直接提高上限。
14.2 细化区频繁闪烁
说明细化与粗化判据缺少滞回,或指示场在阈值附近振荡。可调整 unrefineLevel、平滑指示场或增大 refineInterval。
14.3 网格更新后连续性误差增大
检查 correctFluxes、压力校正次数、时间步和新增面通量的构造方式。
14.4 相分数出现越界
检查 VOF 离散格式、界面 Courant 数、通量修正及拓扑更新后的有界性处理。
14.5 动态加密没有出现在预期位置
检查:
field是否为当前时间存在的volScalarField;- 阈值单位和数值范围;
- 指示场是否在网格更新前刷新;
maxRefinement和maxCells是否已限制继续细化。
15. 动态加密与静态加密的选择
| 问题特征 | 推荐策略 |
|---|---|
| 高梯度位置固定 | 静态局部加密 |
| 高梯度沿已知狭窄路径移动 | 静态带状加密或动态加密对比 |
| 界面/火焰位置未知且大范围移动 | 动态加密 |
| 需要稳定长期统计 | 优先静态网格 |
| 单元数预算严格、局部结构短时出现 | 动态加密 |
| LES 且统计尺度敏感 | 谨慎使用,验证滤波尺度变化影响 |
动态加密的价值在于资源分配,不意味着结果自动达到网格独立。
16. 验证清单
- 无动态加密基准算例已稳定;
- 指示场与研究目标一致;
- 阈值具有明确物理或数值依据;
- 最细网格尺寸满足目标尺度;
-
nBufferLayers和层级过渡合理; -
maxCells与内存预算匹配; -
correctFluxes与求解器通量名称一致; - 网格更新后连续性和有界性可接受;
- 时间步根据最细单元重新确定;
- 完成最大层级、阈值和更新间隔敏感性分析;
- 与统一细网格或实验结果交叉验证。