审计结论(第二轮)
本轮审计的视角与上一轮不同。上一轮聚焦"主链路上是否有显式 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-71 → step/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_MOVING 与 BC_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.cuh 和 init_flow.cu 已处理 shifted,各 collision/curved operator 通过 load_ddf/store_ddf 抽象层自动适配。实际已完整,无需修改。 |
— |
[已确认无需处理] |
| [新发现] [低] |
compute_pressure 与 compute_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_blur2d 用 np.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.99 → 1.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 个 case,K2 有 gate |
| [缺口] |
Kan99b runner K3-K5 |
未做抑制分类自动检测 |
| [通过] |
输出机器可读 |
均输出 JSON/CSV |
测试基础设施
| 严重度 |
结论 |
| [严重缺口] |
零 pytest/unittest 基础设施。 |
| [严重缺口] |
四个旧待验证项仅 EsoPull 已修,余三项(MRT、curved boundary、force 归一化)未覆盖。 |
建议的最低测试覆盖面(优先级排列)
- MRT 单元测试(uniform flow / Poiseuille / decaying vortex)— 单元级
- 力系数归一化测试 — 单元级
- Curved boundary 单列测试 — 单元级
- EsoPull vs double-buffer 一致性(Poiseuille 流对比)— 单元/集成级
- 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-63,Ww = 0.0f)
- Curved boundary 仍是圆形几何特化,没有为任意离散几何留出入路径
LBMParams struct 布局 在 Python struct.pack 与 CUDA struct 之间硬耦合
- CONFIG.md NT 整除性措辞:写"建议",代码用 ceiling division
修改项汇总
| 类别 |
计数 |
| 第一轮修补确认 |
12 项全部 [已确认] |
| 本轮已修复 |
6 项 |
| 保留说明 |
10 项 |
| 暂不处理 |
Body 重构 / 测试基础设施 / Validation runner 缺口 |