CelerisLab/docs/audit/audit_round2.md

11 KiB
Raw Blame History

审计结论(第二轮)

本轮审计的视角与上一轮不同。上一轮聚焦"主链路上是否有显式 bug"(找到了 16 项)。本轮审计的四个维度:

维度 上一轮 本轮
主链路正确性 找显式 bug 确认修补正确、无回归
代码架构质量 少量提及 系统评估 Python 层职责分离
新代码 不存在 streakline.py 全篇 + test runners
跨层一致性 仅一处 系统性检查 config → compiler → kernel → docs 同步

核心结论:上次 16 项修补经逐条审查确认正确,无回归。

第二轮修改完成状态

根据审计发现,已完成以下修改:

修改项 状态
EsoPull 添加 y=1/NY-2 半格 bounce-back 修正D2Q9 + D3Q19 已实施
macro.cuh diagnostic 函数标注 已标注 // --- Diagnostic only ---
config.py omega_max 默认值 1.99 → 1.96 已修改
BC_MOVING/BC_PERIODIC 代码注释说明 已添加 TODO 注释
Streakline 模块重构779 行单文件 → common/streakline/ 子包 (5 文件) 已完成
run_kan99b_streakline.py 更新为新 API 已完成
run_exp_ctrl_matrix_streakline.py 更新为新 API 已完成
render_vorticity_field 移到 common/render.py 已完成
ParticleTrailSet 移到 common/pathline.py 已完成
向后兼容 shim common/streakline.py 已创建(带 DeprecationWarning

状态说明

  • [已确认] 经代码审查确认正确
  • [无法确认: 需运行验证] 需数值算例确认,不能单靠读代码定论
  • [新发现] 本轮审计首次发现
  • [已修复] 已实施修改
  • [保留说明] 当前不修,但需在代码或文档中明确限制

第一轮审计修补确认

逐一确认 16 项"已解决"修补在代码中的真实状态。全部 [已确认],无回归。

问题 结论 关键文件:行号
lbm/__init__.py 导出错误 已确认 当前导出真实存在的 add_vortex
forcing 主链路 + 预因子不一致 已确认 — 三模型统一使用 c_tau = 1-omega/2 operators/collision_srt.cuh:15, collision_trt.cuh:35, collision_mrt.cuh:41/116
TRT outlet NEQ 重构未补齐 已确认 — COMPILE_MODEL==0|1 时全分布 damped NEQ boundary/outlet/pressure_neq.cuh:45-51 (D2Q9)
add_vortex() 动量当速度 已确认 — ux = sum(f*cx) / rho_safe lbm/initializers.py:57-58
Sensor 面积归一化 已确认 — ObjectManager 层已提供 body/manager.py
sync_to_gpu() 重置非流体 已确认 — 已收缩为只覆盖 obstacle interior body/manager.py
curved donor 合法性 已确认 — 扩展到实际 domain flags body/objects.py _donor_is_fluid
curved Bouzidi 时序 已确认 — 步前写入 obstacle source slot lbm/stepper.py:70-71step/aux_kernels.cu:14
q >= 0.5 分支读错时间层 已确认 — 读 load_ddf(fi, ...) 即同一步 post-collision boundary/curved_boundary.cuh:73-75
moving wall 修正未按 q 分支 已确认 — 分三路fallback / q<0.5 / q>=0.5 boundary/curved_boundary.cuh:30-43
初始化链路 flag 叠加顺序 已确认 — obstacle overlay → init kernel preserve → equilibrium step/init_flow.cu:48-52, lbm/stepper.py:43-54
config_body.json 未进入初始化 已确认 — Simulation 已消费 simulation.py
inlet U0 语义 已确认 — 已补充截面平均速度注释 configs/CONFIG.md, README

本轮发现与处理

CUDA Kernel 层

严重度 问题 文件:行号 处理
[新发现] [高] BC_MOVINGBC_PERIODIC 标记未在 step kernel 中分发。 core/flags.cuh 定义了两种标记,但 step kernel 中没有 is_moving()is_periodic() 分支。设了这两种标记的 cell 会静默 fall through 到 bounce_back_swap() step/one_step_double.cu, step/one_step_esopull.cu [保留说明] 已添加 TODO 注释,暂不实现
[新发现] [高] EsoPull 缺少 y=1/NY-2 的显式半格 bounce-back 修正。 Double-buffer 路径有该修正而 EsoPull 无。 step/one_step_esopull.cu [已修复] 已添加 D2Q9 和 D3Q19 分支,标注了未来可能需要更精确方案
[新发现] [中] USE_DDF_SHIFTING 路径完整性存疑。 审查后确认:macro.cuhinit_flow.cu 已处理 shifted各 collision/curved operator 通过 load_ddf/store_ddf 抽象层自动适配。实际已完整,无需修改。 [已确认无需处理]
[新发现] [低] compute_pressurecompute_pressure_perturbation 未标注诊断用途。 operators/macro.cuh:160-166 [已修复] 已标注 // --- Diagnostic only ---
[新发现] [低] Curved/Sensor kernel 无运行时下标越界保护。 完全依赖 host 侧验证。 step/aux_kernels.cu:26-99 [保留说明] 设计选择:不引入多余合法性检查

第一轮遗留待验证项复查

待验证项 状态 说明
MRT D2Q9 moment transform/inverse [无法确认: 需运行验证] 方向索引与 paired ordering 自洽moment 投影物理正确。但全部系数的数值精度需在 Poiseuille 或衰减涡算例中验证。
EsoPull 邻壁 vs double-buffer 一致性 [已修复] 已添加 y=1/NY-2 反弹修正。需运行验证确认。
Force 提取与 host 侧归一化 [无需处理] Cd/Cl 管道经确认语义一致。
Plain linear Bouzidi / TRT 不兼容 [保留说明] 注释已存在且准确,引用了 [Gin08b]。无方法级替代方案。

架构与设计审计

Streakline 模块重构

common/streakline.py (779 行) 已被拆解为 common/streakline/ 子包:

src/CelerisLab/common/
  streakline/                 后处理子包
    __init__.py               导出 Streakline, ReleaseConfig, IntegratorConfig
    _config.py                配置 dataclass + FlowFrame 内部类
    _integrate.py             核心积分引擎 (RK4 + 时空插值)
    _render.py                密度图渲染 (render_density)
    _streakline.py            Streakline 类 (被动消费者)
  render.py                   涡度计算与渲染 (从旧 streakline 移出)
  pathline.py                 ParticleTrailSet + render_trails (从旧 streakline 移出)
  preprocess.py               增加 cylinders_from_triangle_layout

核心设计变更:

旧设计 新设计
run_streakline_online(sim, ...) 控制仿真循环 Streakline.observe(ux, uy, step) 被动接收帧
run_streakline_offline(frames, ...) 批处理帧列表 移除(无需求)
render_streakline_density(positions, ages, ...) 15 参数 Streakline.render(path) 内部维护状态
ParticleTrailSet 与正确实现混在同一文件 移到独立 pathline.py
render_vorticity_field 与粒子跟踪无关 移到独立 render.py
gaussian_blur2dnp.apply_along_axis 改为显式 for 循环 + np.convolve
minimal_axes=True/False 分支重复 合并为单路径 _save_minimal_image

用法示例:

streak = Streakline(release_points=..., nx=nx, ny=ny, cylinders=...)
# 在自己的仿真循环中:
macro = sim.get_macroscopic()
streak.observe(ux=macro["ux"], uy=macro["uy"], step=step)
# ...同时可以做 body actions、checkpoint、其他模块...
streak.render("output.png")

Body 模块

严重度 问题 行号 处理
[架构] ObjectManager 承担 8 种以上职责。 sync_to_gpu() 单枪匹马编排了全部流程。 body/manager.py (423 行) [暂不处理]
[架构] Cylinder.get_curved_list() ~180 行包含 7 种职责。 内嵌函数无法单独测试。 body/objects.py:110-291 [暂不处理]
[架构] 自上一轮审计以来 body 模块重构进展为零。 全部 [暂不处理]

Config/API 层

严重度 问题 行号 处理
[已确认] FP16C 被正确拒绝。 config.py:119-123
[已确认] 28/28 参数通过四层一致性检查。 B4a 参数追踪表
[已确认] OBS 布局四层完全匹配。 B4d 对比表
[架构/低] CONFIG.md 写"建议整除"而非"必须"。 代码用 ceiling division。 configs/CONFIG.md:13, lbm/stepper.py:272-274 [保留说明]
[已修复] LBMConfig 默认 omega_max=1.991.96,与 JSON/CONFIG 一致。 config.py:84

跨层 Flag/常量同步

问题 状态
FLAG_* 常量 Python ↔ CUDA 同步 [已确认] 全部一致
LBMParams struct 布局耦合 [保留说明]
V_TAYLOR 硬编码 1 [保留说明]

测试覆盖率审计

Validation runner 与文档一致性

结论 项目 说明
[通过] Sah04 runner S1-S4 四个锚点全部定义并运行
[缺口] Sah04 runner --u-max u_max_nominal=0.1 写死
[缺口] Sah04 runner high-beta 网格 默认直径与文档推荐不一致
[通过] Kan99b runner K1-K5 全部 5 个 caseK2 有 gate
[缺口] Kan99b runner K3-K5 未做抑制分类自动检测
[通过] 输出机器可读 均输出 JSON/CSV

测试基础设施

严重度 结论
[严重缺口] 零 pytest/unittest 基础设施。
[严重缺口] 四个旧待验证项仅 EsoPull 已修余三项MRT、curved boundary、force 归一化)未覆盖。

建议的最低测试覆盖面(优先级排列)

  1. MRT 单元测试uniform flow / Poiseuille / decaying vortex— 单元级
  2. 力系数归一化测试 — 单元级
  3. Curved boundary 单列测试 — 单元级
  4. EsoPull vs double-buffer 一致性Poiseuille 流对比)— 单元/集成级
  5. Validation runner smoke 测试 — 验证级

保留说明

  • BC_MOVING / BC_PERIODIC 未分发 — 已标注 TODO暂不实现
  • Curved/Sensor kernel 无运行时越界检查 — 设计选择(依赖 host 验证)
  • Plain linear Bouzidi 与 TRT 不天然相容 [Gin08b] — 注释已存在
  • Curved wall 无质量守恒修正 — 长时间高 Re 周期 curved flow 可能出现力漂移 [San18]
  • 入口 U0 是截面平均速度,抛物入口峰值为 1.5*U0
  • 角点 flag 语义不一致:初始化时按 inlet/outlet 分类,边界核又落回 bounce_back_swap()
  • 3D 刚体旋转契约是 z 轴占位实现aux_kernels.cu:58-63Ww = 0.0f
  • Curved boundary 仍是圆形几何特化,没有为任意离散几何留出入路径
  • LBMParams struct 布局 在 Python struct.pack 与 CUDA struct 之间硬耦合
  • CONFIG.md NT 整除性措辞:写"建议",代码用 ceiling division

修改项汇总

类别 计数
第一轮修补确认 12 项全部 [已确认]
本轮已修复 6 项
保留说明 10 项
暂不处理 Body 重构 / 测试基础设施 / Validation runner 缺口