CelerisLab/docs/validation_specs/Force_region_validation.md
Frank14f b110591433 feat(body): add force_region, fix sensor API, reorganize docs
- Add force_region object type: local Guo forcing via sparse compact list
- ForceRegionSoA container, ForceRegionKernel, stepper dispatch
- add_body("force_region", ...) + set_force(id, fx, fy) API
- Fix read_sensor(normalize=...) not being passed from Simulation layer
- Fix force_region incorrectly entering curved cut-link path (P0 blocker)
- Clean up module boundaries: body/__init__ no longer imports from lbm
- Circluar import fix: common/streakline <-> pathline
- Package data globs fixed for recursive kernel files
- Version unified to 0.3.0
- Performance analysis: pycuda launch overhead vs GPU compute at various grid sizes
- Nsight Systems + Nsight Compute profiling data and report
- Documentation reorganized under docs/ (audit, validation_specs)
- README overhaul: multi-body examples, validated benchmarks, force_region docs

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 18:07:55 +08:00

14 KiB
Raw Permalink Blame History

Force region 验证清单

这份清单面向当前已经实现的最小版 force_region

  • 2D
  • 圆形 footprint
  • 运行时设置均匀 fx, fy
  • operator-split 的局部 Guo forcing 修正
  • 不与 sensor 绑定

当前最合理的验证思路不是一次追求“单一终极 benchmark”而是分三层推进

  1. 代码回归层:先确认新功能没有破坏旧链路
  2. 物理正确性层:先做最稳的流体响应验证
  3. 研究使用层:再进入圆柱尾迹中的局部强迫实验

文献上LBM forcing 的核心依据仍是 Guo forcing 的离散处理 [Guo02d]。对 body-force 驱动的通道流Poiseuille 流是最经典的基准之一,[Zou95b] 给出了平板间 Poiseuille 流的解析结果,[Guo02d] 也把 steady Poiseuille flow 作为 forcing 验证的一部分。对空间变化 forcing 的风险与误差来源,[Sil20b] 给出了很直接的提醒:非均匀 body force 会把离散误差暴露得更明显,因此验证必须包含网格、黏度、幅值三个维度的稳健性检查。

一句话总策略

先不要一上来把 force_region 扔进圆柱尾迹做复杂控制。先用最简单、最容易解释的流场把它跑顺:

  • 零强迫回归
  • 单方向局部加速
  • 长通道近似 Poiseuille
  • 再进圆柱尾迹

第一层

必做回归检查

这些检查不依赖文献,但必须先过。

编号 目的 设置 预期结果 是否阻塞
R1 新功能不引入假障碍 只加 force_region,不加圆柱 n_curved == 0flag 场不出现 obstacle / curved 覆盖
R2 零强迫不改变解 force_region,但 fx=fy=0 与无 force_region 基线一致,或只剩舍入级差异
R3 force 设置后可持续生效 set_force() 后步进,再触发一次 action 刷新链路 force 不被静默清零
R4 符号方向正确 同一算例跑 +fx-fx 主流响应方向相反,幅值同量级

R2 很关键。它回答的是:当前实现是不是“只是多了一条 dormant 数据链”,而不是“只要建了 force_region 就改了解”。

第二层

物理正确性主验证

这部分建议按从简单到复杂的顺序做。

Case A

静止流场中的单圆局部加速

这是最小物理 sanity check。

设置建议

  • 格子:nx = 256, ny = 128
  • 碰撞:先用 SRTLES 关闭
  • 流动初值:入口速度设为 0 或足够小,先得到近静止背景流
  • 不加圆柱
  • force region
    • 圆心 (96, 64)
    • 半径 r = 12
    • 先做 fx > 0, fy = 0
  • 强迫幅值:从小值开始,例如 fx = 1e-6, 5e-6, 1e-5
  • 每组运行到准稳态或至少足够长,使局部响应明显

该看什么

  • ux 在 force region 附近应整体偏正
  • 区域下游应形成沿 +x 延伸的动量尾迹
  • uy 的主量级应明显小于 ux
  • fx 改成负值后,整幅图应沿 x 方向近似镜像

预期结果

这个 case 没有一个成熟的“标准 benchmark 数字”,但应满足最基本物理响应:

  • 加速方向与 force 方向一致
  • 幅值随 fx 单调增强
  • 小 force 下解的结构应平滑,不应出现棋盘格、局部爆点或非对称破缺

判定标准

检查项 通过标准
方向性 fx > 0 时主响应沿 +xfx < 0 时相反
单调性 增大 fx 后,局部 ux 峰值与尾迹强度单调增大
对称性 在无背景横向偏置时,上下半区统计应近似对称
稳定性 小幅强迫下不出现数值振荡或孤立噪点

这个 case 的作用不是给出论文级定量结论,而是先证明:局部 forcing 至少在最简单流场中按直觉工作。

Case B

长通道中的近 Poiseuille 验证

这是最重要的文献支持主验证。

Poiseuille 流是 LBM forcing 的经典基准,[Guo02d] 用 steady Poiseuille flow 验证 forcing 处理,[Zou95b] 给出了平板间 Poiseuille 流的解析形式。对当前代码,最现实的做法不是强行构造完全理想的周期通道,而是在长通道中用超大圆形 force region 近似全域恒定体力驱动,只在远离入口和出口的位置取剖面比较。

建议设置

  • 格子:nx = 1024, ny = 128
  • 碰撞:先用 SRT;通过后再试 TRT / MRT
  • LES关闭
  • 圆柱:不加
  • 入口速度:尽量设小,避免 inlet 自身主导流场
  • force region
    • 圆心放在通道中段,例如 (512, 64)
    • 半径取足够大,使绝大多数通道内部 fluid cell 都被覆盖,例如 r = 600
  • 强迫方向:fx > 0, fy = 0
  • 强迫幅值:先从小值开始,避免压缩性误差,例如 1e-6 量级

为什么这样设

当前 force_region 只有圆形 footprint没有全域矩形 forcing也没有 x 周期边界。因此最稳妥的近似是:

  • 用超大圆把中部通道几乎全覆盖
  • 只在远离入口和出口的位置取横截面
  • 检查剖面是否接近抛物线

该比对什么

对 fully developed Poiseuille经典剖面是抛物线 [Zou95b]


 u(y) = u_{max}\left(1 - \frac{y^2}{L^2}\right)

其中中心线速度最大,壁面速度为 0。对当前代码最重要的不是把解析常数拟合到最后一位而是确认以下结构性特征

  • 中部横截面是单峰抛物形
  • 中心线最大
  • 贴壁速度接近 0
  • uy 远小于 ux
  • 沿 x 方向进入发展段后,剖面变化减小

推荐取样方式

在以下几个 x 位置取横截面:

  • x = 256
  • x = 512
  • x = 768

只要中后段两条剖面几乎重合,就说明流场已经接近 fully developed可拿来与抛物线拟合。

预期结果

  • 中段与后段 ux(y) 应近似抛物线 [Guo02d, Zou95b]
  • fx 增大,剖面整体抬高,但形状仍保持单峰抛物型
  • 中段以后,剖面随 x 的变化应减弱

如何定量判定

建议做三个量:

指标 解释 通过建议
抛物线拟合残差 用最小二乘拟合 u(y)=a-b(y-yc)^2 中后段残差明显小于入口附近
发展段一致性 比较两个下游截面 两条曲线基本重合
横向速度污染 `max uy

关于误差的解释

不要把这个 case 解释得过头。因为当前代码的边界条件并不是“理想周期 x + 纯 body-force 驱动”,所以更合理的表述是:

  • 这是一个近 Poiseuille 验证
  • 它主要验证 force_region 是否能在长通道里生成正确的 fully-developed 流动结构
  • 它不是对解析解逐点 machine-accuracy 的测试

另外,[Zou95b] 指出 bounce-back 边界会引入一阶壁面误差。因此如果壁面附近有明显偏差,不必立刻把它归咎于 force_region 本身;重点看的是中部剖面形状与下游收敛行为 [Zou95b]。

Case C

幅值扫描

这个 case 用来回答:当前 operator-split forcing 在多大范围内是“线性可解释”的。

设置建议

复用 Case B只扫描 fx

  • 1e-6
  • 2e-6
  • 5e-6
  • 1e-5
  • 2e-5

预期结果

在小 force 区间内:

  • 中心线速度大致随 fx 单调增加
  • 抛物剖面形状保持不变,仅幅值放大
  • 若开始出现明显非对称、密度波动或剖面畸变,说明已进入“不再适合作为线性基准”的区间

该记录的量

  • 中心线最大速度
  • 下游某截面的体积流量
  • rho 偏离 1 的最大值

这一步的目的不是证明某个严格比例律,而是找到一个数值上舒服的工作区间。后面做圆柱尾迹控制时,应优先选这个区间内的 force 幅值。

Case D

网格与黏度稳健性

这是空间变化 forcing 必须做的检查,[Sil20b] 对这一点尤其值得参考。该文的核心提醒不是“所有非均匀 forcing 都会错”,而是:空间变化 body force 更容易把离散误差暴露出来,因此需要明确看网格和黏度敏感性 [Sil20b]。

推荐做法

选用 Case B 或 Case A 中一个已经表现稳定的设置,然后做:

网格扫描

  • 256 x 64
  • 512 x 128
  • 1024 x 256

保持物理几何比例一致。

黏度扫描

固定一个小 force 幅值,扫两到三个 nu

预期结果

  • 网格加密后,主剖面与主流结构应收敛
  • 黏度变化会改变速度幅值和扩散尺度,但不应引入新的奇怪畸变
  • 如果某个设置对黏度特别敏感,优先检查强迫是否过强、局部 Mach 数是否过高、或 region 是否离边界太近

如何解读

[Sil20b] 的重点是在 TRT 下讨论空间变化 force 的离散误差来源,并指出某些 force 展开会引入额外不一致项。当前实现采用的是一个 operator-split 的局部 Guo 修正,而不是把空间变化 force 直接并入 OneStep 的逐格 collision。因此这一步更应被视为

  • 对当前实现的数值稳健性检查
  • 而不是与 [Sil20b] 的离散系统逐条同构比较

第三层

研究使用前的圆柱尾迹验证

在前两层都通过后,再进入最关心的 case圆柱尾迹中的局部 forcing。

这里最重要的不是先追一个“标准答案数值”,而是先建立可解释的响应地图

Case E

圆柱后方局部推流

可用你已经验证过的固定圆柱 baseline先选最稳的低 Re 工况,例如二维层流涡街基线。

建议设置

  • 使用你当前已经验证可靠的 2D 固定圆柱基线
  • 先选一个自然涡街清晰、但还不太剧烈的 Re
  • force region 放在圆柱后方近尾迹区

例如:

  • 圆柱中心 (xc, yc)
  • force region 中心可先试:
    • (xc + 2D, yc)
    • (xc + 3D, yc)
  • 半径先从 0.3D0.8D
  • 先做 fx > 0, fy = 0

该看什么

  • 尾迹中心线速度是否回升
  • 近尾迹回流区是否缩短
  • Cl 振幅是否降低
  • Cd_mean 是否变化
  • 涡脱落频率 St 是否偏移
  • streakline / vorticity 图是否出现更对称或更拉长的尾迹结构

预期结果

对于圆柱尾迹中的外加 forcing不同 forcing 形式都说明了同一个大方向:局部强迫会改写尾迹结构、拖曳、升力波动与脱落频率。[Kim05b] 虽然研究的是壁面 blowing/suction 而不是体力区,但其结果清楚表明:分布式 forcing 可以显著抑制或改变 Kármán 涡街,从而改变 mean drag 与 lift fluctuation [Kim05b]。

对当前 force_region,更合理的预期是:

  • fx > 0:尾迹被顺流“拉长”,回流区可能缩短
  • 足够合适的位置和幅值下:Cl_rms 下降,尾迹更接近对称
  • 过强 forcing可能引入新的不稳定结构而不是单调“变好”

判定方式

建议不要只看一张图,至少同时记录:

作用
Cd_mean 看平均阻力变化
Cl_rms 看升力波动是否被抑制
St 看脱落频率是否移动
vorticity / streakline 图 看结构是否更对称、更拉长、或出现新模态

这个 case 的定位

这是研究型验证,不是严格 benchmark。

更准确地说,它回答的是:

  • force_region 是否足够稳定和可控,能够进入尾迹控制实验
  • 不同位置、半径、幅值是否产生可解释的流场响应

而不是:

  • 某个单一数字是否必须匹配文献到几个百分点

推荐的执行顺序

建议按下面顺序推进。

顺序 算例 作用
1 R1-R4 先清掉实现错误
2 Case A 验证最基本物理响应
3 Case B 做文献支持最强的主验证
4 Case C 找到安全幅值区间
5 Case D 看网格与黏度稳健性
6 Case E 进入圆柱尾迹研究

每个算例建议保存的输出

为了后面快速回看,建议每个 case 固定保存下面这些量。

输出 是否必需 说明
配置文件快照 必需 保证能复现实验
fx, fy 与 region 几何 必需 force center, radius, amplitude
一张 ux 场图 必需 看主流响应
一张 vorticity 图 推荐 看结构变化
一条下游横截面 ux(y) 必需 Poiseuille 与 channel 类验证最关键
rho 最大偏离 推荐 监控压缩性污染
若有圆柱:Cd_mean, Cl_rms, St 必需 尾迹控制最关键

最低通过线

如果时间紧,只要先达到下面这三条,就可以开始把 force_region 用进研究实验:

  1. 零强迫回归通过
  2. 静止流场中局部加速方向正确、幅值单调
  3. 长通道中下游横截面能稳定收敛到近抛物剖面

做到这三条,说明这个新功能至少已经:

  • 不破坏旧功能
  • 有正确方向性
  • 能在最经典的 body-force 场景中生成合理结构

如何解读失败

若 Case A 失败

优先怀疑:

  • action slot 读写
  • force region footprint
  • is_fluid(flag[k]) 过滤
  • ForceRegionKernel 写回 DDF 的路径

若 Case B 失败

优先怀疑:

  • force region 是否真的覆盖了足够长的通道中段
  • inlet/outlet 是否过强地主导了解
  • force 幅值是否太大
  • 取样截面是否还在入口发展段

若 Case D 失败

优先怀疑:

  • spatially varying forcing 本身的离散误差被放大
  • 当前 operator-split 修正对该参数区间不够稳
  • 需要收缩到更小 force、更低 Mach、更细网格

最后的建议

当前 force_region 最适合先被当作一个研究工具,而不是一开始就当作“已严格 benchmark 的标准物理模块”。最稳妥的路线是:

  • 用 [Guo02d] 和 [Zou95b] 支撑主验证思路
  • 用 [Sil20b] 提醒自己必须做稳健性检查
  • 用 [Kim05b] 作为圆柱尾迹控制的高层参考,理解应该关注哪些响应量

这样做,既能尽快把功能用于研究,也不会把验证叙事说得过头。

参考依据

  • Guo, Zheng, Shi 讨论了 forcing term 的离散效应,并将 steady Poiseuille flow 作为数值验证的一部分 [Guo02d]
  • Zou, Hou, Doolen 给出了平板间 Poiseuille 流的解析解,并指出 bounce-back 壁面会引入一阶误差 [Zou95b]
  • Silva 分析了空间变化 body force 在 LBM 中的离散误差来源,说明非均匀 forcing 必须做网格与黏度稳健性检查 [Sil20b]
  • Kim 和 Choi 表明分布式 forcing 可以显著改变圆柱尾迹、drag、lift fluctuation 和 shedding mode可作为圆柱尾迹研究阶段的高层参照 [Kim05b]