62 lines
5.3 KiB
Markdown
62 lines
5.3 KiB
Markdown
# 管路重复计算优化核查(2026-09-10)
|
||
|
||
本轮减少管流的重复求值,并检查原内部迭代的数值误差。它不替代编译阶段的通用计算排序,也没有解决管流迭代耗尽上限后仍返回近似结果的问题。
|
||
|
||
## 修改范围
|
||
|
||
- `native/components/kernels.c`:将只依赖相对粗糙度的摩擦系数项提到内部循环外;其余公式、运算顺序、误差阈值和 16/64/48 轮限制保持不变。
|
||
- `native/include/kernels.h`:增加管流输入与结果缓存。键包含两端压力、温度、几何参数、管流类型和全部介质常量,逐项完全相同才复用结果;不保存非有限结果。
|
||
- `app/simulation/native_codegen/extended.py`:每个需要参与全网流量计算的管流支路分配一个缓存,在每次 `model_eval` 内重新清零。不同积分器试算之间不复用,不改变压力、流量或焓传播顺序。PNL0003 原本在全网循环外计算,保持直接调用。
|
||
|
||
这轮减少的是同一次系统状态求值中的重复管流计算。积分器、雅可比策略、物理模型及用户工程未调整。
|
||
|
||
## 原管流方法的误差
|
||
|
||
从已修正参考口的独立模型副本 `test/amesim-order-study/reference-port-experiment.json`,在初始、扰动和反向流等 14 组状态中捕获 2352 次调用、432 组不同管流输入。用相同摩擦关系的 80 轮二分求根作为独立精度参照,得到:
|
||
|
||
| 管流类型 | 不同输入数 | 流量相对误差中位数 | 最大相对误差 |
|
||
| --- | ---: | ---: | ---: |
|
||
| PNL00R(保留原层流捷径) | 49 | 4.92×10⁻¹³ | 6.67×10⁻¹² |
|
||
| PNL0001/2 支路 | 333 | 2.36×10⁻⁶ | 3.22×10⁻⁵ |
|
||
| PNL0003 内部支路 | 50 | 2.42×10⁻¹⁵ | 1.09×10⁻¹⁴ |
|
||
|
||
PNL0001/2 的 333 组输入中,有 330 组的相对误差超过 10⁻⁷。这里比较的是本项目的同一标量方程,不是 Amesim 曲线,也不能把积分器误差限直接等同于允许的管流误差。结果说明原 16 轮方法的收敛性需要单独修正,不能以维持旧数值结果作为最终精度标准。
|
||
|
||
## 一致性与工作量
|
||
|
||
保留本轮修改前的已编译 EXE,与修改后 EXE 对照。14 组原状态顺序、14 组逆序及前 2 组重访,共 30 次求值,全部成功;每次 132 个导数和 1784 个输出逐值完全一致。重访用于检查缓存不会引入跨试算的历史依赖。
|
||
|
||
最终运行 `python -m unittest tests.test_native_pipe_cache tests.test_native_catalog tests.test_native_codegen tests.test_native_only_backend -q`,14 项全部通过,包含 50 个冻结网络的数值对照及 RK45/BDF 执行。回归发现并修正了无气动端口模型中的多余缓存声明;这些模型不再生成该局部变量。初次运行存在编译子进程超时,最终使用本机工具链环境完成验证。
|
||
|
||
另用独立计数版本统计原 14 组状态,计数逻辑不进入计时程序:
|
||
|
||
| 实际调用 | 修改前 | 修改后 |
|
||
| --- | ---: | ---: |
|
||
| PNL00R 求解 | 224 | 56 |
|
||
| PNL0001/2 支路求解 | 2016 | 504 |
|
||
| PNL0003 内部支路求解 | 112 | 112 |
|
||
| 管流求解合计 | 2352 | 672 |
|
||
| 摩擦系数计算(含展示输出) | 42743 | 15794 |
|
||
|
||
这相当于管流求解调用减少 71.4%,但全网流量函数本身的执行次数没有减少。
|
||
|
||
本机 C 状态求值微基准:输入读取在计时外,每轮 2800 次求值;预热后交替测量各 5 轮,中位数从 2.868505 s 降至 1.490497 s,约 1.92 倍。计时期间另有回归编译任务,数据只用于观察局部收益;调用计数不受此影响。没有进行本轮完整 10 s 轨迹、网页端或 Amesim 对照,不能将该倍数解释为整机加速。
|
||
|
||
## 后续优先顺序
|
||
|
||
已完成的端口供需合同主要负责连接校验,不能等同于已经生成最合适的计算顺序。系统层面应先把每个输出的依赖列清楚,提前传递可由当前状态确定的量,按依赖执行能直接计算的表达式,仅将真正互相依赖的部分组成局部求解块。排序依据是变量依赖,不是画布位置或气体流向;反向流也必须覆盖。
|
||
|
||
此前独立排序实验已在修正参考口的该模型中,把通常每次状态求值的全网流量调用从 4 次降到 1 次,并保持 14 组状态的导数和输出一致。该实验尚不是生产中的通用排序器,也没有证明全部复杂模型都能消除迭代。
|
||
|
||
因此,应优先开发通用依赖排序和局部循环识别,再解决管流内部求根的收敛判据与算法,并用完整积分轨迹检查时间、步数和数值误差。缓存可以作为保留局部迭代时的补充,不能承担系统计算组织的职责。
|
||
|
||
## 复现材料
|
||
|
||
- `test/pipe-flow-study/baseline_kernels.c`、`baseline_kernels.h`、`baseline-build.json`:修改前快照和 EXE 清单。
|
||
- `study.py`、`residual-audit.jsonl`:原始调用捕获与标量求根审计。`study.py` 的捕获阶段应使用修改前生成器;已有快照不要覆盖。
|
||
- `verify.py`、`*-verification.jsonl`:修改前后 EXE 的 30 次逐值对照。
|
||
- `benchmark.py`、`benchmark-results.json`:独立计数及纯 C 状态求值微基准。
|
||
- `tests/test_native_pipe_cache.py`:缓存命中、每项输入失效、反向流、介质值变更、独立缓存与非有限结果校验。
|
||
|
||
`test/` 诊断材料按仓库约定被 Git 忽略;生产代码与回归测试不依赖这些临时材料。
|