Files
SystemSimulationApp/docs/other/八路采样失败与曲线差异定位-2026-09-14.md
T

194 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 八路采样失败与曲线差异定位
日期:2026-09-14。分支:`system-optimization`。本次只定位,未修改生产代码、原始 JSON 或原始 Amesim 文件。
## 结论
| 现象 | 判定 | 证据 |
|---|---|---|
| 50 s 仿真、0.001 s 采样退出 64 | 触发结果容量限制;错误解释和日志保留有缺陷,不是积分失败 | 进入积分前预计约 746 MiB,超过固定 256 MiB 限制;同一 EXE 关闭历史结果保存后完成 50 s |
| 启动阶段约 163 kPa、105 K 差异 | **主要是节点能量传递 bug** | 仅在诊断生成代码中按各支路能量流求和,50 s 对比的最大压力差降至 44 Pa、温差降至 0.37 K |
| 循环切换点约 1.29 MN 力差 | 比较时刻位于切换点不同侧,且存在信号边界计算不一致;不能直接归为 BDF 算法误差 | 32.4 s 两端读取了不同信号阶段;44 s 的事件定位与信号求值在同一个 double 时间上不一致 |
| 高温物性差别 | 氦气黏度和热物性分段实现有遗漏 | 相同 p、T 下直接调用双方物性;高温黏度明显不同,但单独调整它不能消除主要温差 |
| 管流小幅差别 | 摩擦系数公式的近似差异,属于模型实现差异 | 不经过积分,在相同边界状态下仍有流量差;常温探针测试点最大约 0.234% |
| 其余很小的差别 | 包含已知物性/管流公式差异及数值误差,尚不能全部指定为积分算法差别 | 节点诊断后仍非逐位一致;没有证据要求先更换 BDF 或矩阵求解方式 |
## 1. 测试对象与范围
沿用上份报告的八路循环模型及参数审计结果:157 个组件、178 条连接,1092 项公开参数已核对。平台采用 BDF;Amesim 保留标准变步长隐式配置,未假定其内部算法、误差权重与 CVODE 完全相同。
原始文件在本次结束时的 SHA256 与开始前一致:
- `tests/data/test-mql-8-corrected.json`:`60ed16c71b72be4ae71ca7980f4f8cdcdf6b4c4c8950863c2390960b71ced4`
- `tests/data/test_mql.ame`:`251b2f17c24ea02c1ab48f9f441a0ec38e7920627ea7e6870392326424a517c5`
循环比较基准使用 `test/mql8-cyclic-20260914/` 内上次保留的模型副本。诊断实验集中在 `test/diagnosis-20260914/`。对 188 个已跟踪的 app/native/frontend 文件逐一核对开始、结束时的哈希,变化数量为 0;保留工作区此前已有改动。
## 2. 0.001 s 采样为什么退出 64
这里的 0.001 是**采样时间间隔**,即每秒保存 1000 次,不是积分器的最大步长。
`native/runtime/main.c:163` 在调用 `native_solve` 前检查预计结果容量:
`(仿真时长 / 采样间隔 + 1024) × (状态数 + 输出数) × 8 字节`
八路模型有 132 个状态、1784 个输出。50 s、0.001 s 时:
`(50000 + 1024) × (132 + 1784) × 8 = 782095872 字节 = 745.865 MiB`
固定上限是 268435456 字节,即 256 MiB。超限直接 `return 64`,没有进入积分,也没有写结构化结果或解释原因。因此这不是 GCC、CVODE 或操作系统实际分配内存失败。
使用同一缓存 EXE 的复现结果:
| 配置 | 结果 | 时间 |
|---|---|---|
| 50 s,采样 0.001 s,保存历史结果 | 退出码 64,无结果文件,日志 0 字节 | 进程约 0.054 s |
| 1 s,采样 0.001 s,保存历史结果 | 正常完成 1 s | 求解 2.613 s |
| 50 s,采样参数仍为 0.001 s,`--solve-only` | 正常完成 50 s | 求解 12.187 s |
这些耗时用于判别失败阶段,不是重复测量后的性能基准。
目前保存的是全部输出,不仅是界面选择绘制的曲线。结果写出阶段还会一次性申请 `采样数 × 输出数` 的数组,并再次检查 256 MiB。因此单纯移除前面的限制也不构成完整解决方案。
`runner.py:122` 将“无结果文件”解释成通用 Native worker 错误;`runner.py:151` 的临时目录随后被清理,所以错误文字中的日志路径可能已不存在。本次给出的原始临时日志路径也已不存在,但保留工作目录的复现清楚确认了退出原因。
后续建议:
1. 启动前给出“结果容量超限”、状态/输出/采样数量、预计容量和上限,后端也要校验。
2. 原生程序返回明确的资源限制错误;异常时保留或回传日志,不能只指向随后被删除的路径。
3. 分块计算、写出历史输出,或支持选择保存变量。前端、HTTP 与 CLI 使用一致的限制和错误含义。
4. 当前模型 50 s 对该前置检查的采样间隔阈值约为 0.00303237 s;0.004 s 可通过此项容量检查。已实测可正常运行的旧配置是 0.01 s。通过容量检查不代表对其他运行问题作保证。
## 3. 主要压力、温度差异:节点没有完整传递能量流
### 3.1 具体代码路径
- `app/simulation/native_codegen/extended.py:452`:PN3NODE2/P4NODE2 将支路流量和焓折算成参考口的一个焓值。
- `extended.py:457` 起:只有部分流向进行补偿,并在净流量接近零时使用正则化的倒数。
- `extended.py:615`:储气元件按流向选择“流入焓”或“本腔体焓”,再乘该口的净质量流量。
这套表达对于普通单支路换向可以成立,但对于一边进、一边出的多支路汇合节点不够。**净质量流量与净能量流必须分别求和;不能依据净质量流量的正负决定整组支路只携带一个来源的能量。**
Amesim 本机安装的 `libpn/submodels/PN3NODE2.c` 和 `P4NODE2.c` 声明参考口分别汇总各支路的质量流、焓流、体积及体积变化率。它们直接对带符号的焓流求和,并不先除以净质量流量再折回能量。
例如,一支路送入 2 kg/s、比焓 2000 J/kg,另一支路送出 3 kg/s、比焓 1000 J/kg:净质量流是流出 1 kg/s,但净能量流是流入 1000 W。把它当成“净流出 1 kg/s × 本腔体 1000 J/kg”,会得到流出 1000 W,连方向都反了。
### 3.2 在实际八路模型中捕捉到的错误
把 Amesim 在 0.0004 s 的完整物理状态送给原平台 C 方程计算。压力、温度、位移等状态匹配后,`amesim_p4node2_8` 向 `amesim_pnl0001_20` 传递的能量为:
| 量 | 数值 |
|---|---:|
| 净质量流入管腔 | −0.0525535 kg/s |
| 支路 1 的能量流 | +7.080728 MW |
| 支路 3 的能量流 | −4.770562 MW |
| 支路 4 的能量流 | +0.027449 MW |
| 按支路求和应计入的能量 | **+2.337615 MW** |
| 原代码计入的能量 | **−1.252658 MW** |
| 少计的能量流 | **3.590273 MW** |
以上全部来自**同一组状态下的一次方程计算**,不需要比较积分器。这直接证明存在能量传递错误。
### 3.3 隔离因果实验
在诊断目录生成独立 C 模型,只把节点参考口传给储气元件的能量改为支路能量求和。没有改正式 Python/C 文件、管路公式、物性、积分器或原模型参数。
双方误差限取 1e-10、最大步长 1e30;50 s 全程按共同 0.01 s 网格比较:
| 指标 | 原实现 | 仅调整诊断副本的节点能量 |
|---|---:|---:|
| 最大压力差 | 163359.89 Pa | **43.96 Pa** |
| 最大温度差 | 105.24 K | **0.373 K** |
| 排除信号切换点前后 0.02 s 后的最大力差 | 约 5131 N | **1.373 N** |
| 是否完成 50 s | 是 | 是 |
因此主要压力、温度偏差已定位为模型连接层的能量计算 bug,不是“换一种积分方法自然产生的正常差别”。诊断生成代码只用于验证原因,不是已经合入的通用修复。
后续应在 C 连接计算中明确传递带符号的能量流,质量流和能量流独立守恒;不要依赖“能量流除以接近零的净质量流”来构造参考口焓。正式修复还需覆盖节点串联、流向同时相反、净流量为零但有热量交换等情况。
## 4. 排查过的其他原因
### 积分步长和误差限
此前已从 1e-8 收紧至 1e-10,主要误差不消失。本次进一步比较前 0.02 s:最大积分步长由 1e30 降至 1e-5 s,采样间隔为 1e-5 s。0.01 s 的最大压力差仍约 163359.8 Pa,最大温差仍约 105.237 K。
细采样还发现启动过程真正的短时最大差约为 276.66 kPa 和 125.05 K,分别出现在约 0.00042 s 和 0.00055 s。上份报告的 163 kPa、105 K 是共同 0.01 s 网格上的最大差,不是对所有内部时刻取最大。
### 物性及储气方程
在已经初始化真实氦气介质的 Amesim 生成程序副本中,调用官方库的 p、T 物性接口和储气方程;与直接包含平台原始物性 C 文件的探针比较。
- 同 p、T 下,密度和低于 6000 K 的焓基本一致。
- 分别输入质量变化、能量输入、压缩体积三种情况,双方储气压力/温度变化率基本一致;高温处残余差异与热物性分段遗漏相符。
- Amesim 的温度有效域警告不表示温度被强行截为 1500 K;直接测试表明它仍在高温状态上计算。
- 平台氦气黏度始终使用第一段公式,Amesim 数据在 1000 K 和 5000 K 换段。5000 K 时平台黏度低约 3.48%,9600 K 时低约 5.51%。
- 平台定比热的氦气理想热物性也未覆盖 Amesim 6000 K 以上的数据段。在 9600 K 探针点,焓相对差约 2.72e-7、比热相对差约 4.70e-6;它不是这次 105 K 温差的主要来源。
仅在隔离副本补上黏度分段,前 0.15 s 最大温差只从 105.237 K 降至 105.104 K,压力差从 163359.89 Pa 降至 163032.28 Pa。主因被明确排除。
### 管路摩擦公式
使用同 p、T、压力比、管径、长度和粗糙度,直接比较 Amesim `pn2pipefr_` 与原生 `native_pipe_flow`,不进行时间积分。探针包含 3 个压力、4 个温度、5 个压力比,共 60 点。
300 K 测试点的最大流量相对差约 0.234%,1000 K 约 0.241%。这些点的可压缩流量参数基本一致,摩擦系数不同。平台 `native/components/modules/pipe.c:8` 使用拟合、混合的摩擦系数公式,不能视为与 Amesim 实现完全相同;高温差异还叠加黏度分段遗漏。
节点能量和黏度同时在诊断副本调整后,前 0.15 s 最大压力差约 24.26 Pa,温差约 0.453 K。单项误差并不保证同方向变化,不能只凭某个最大温差略升就否定已确认的黏度缺项。剩余小误差尚未完全拆分为摩擦近似、热物性分段和积分误差各自的份额。
### 自由质量块的巨大位移数值
上份报告单列的 `amesim_mecmas21_9` 质量为 100 kg,静摩擦、库仑摩擦、黏性摩擦均为零,不启用限位;模型施加的循环力达到 1e17 N。其位移本身约为 1e17 m 量级,不能把绝对位移差直接与正常行程元件比较。收紧误差限后的 50 s 节点诊断对比,最大位移差约 2.04e8 m,相对该位移量级约为十亿分之几。这里具有明显的误差尺度和数值累计特征,未发现与主要节点能量 bug 相当的力学公式错误证据;尚未对这一自由质量块另做解析解误差分解。
## 5. 循环信号切换点与力尖峰
### 同一个显示时间,不一定处于同一阶段
收紧误差限后的原始结果:
| 原始保存时刻 | 平台/来源 | 信号 1 | 信号 2 | LSTP00A_1 力 |
|---|---|---:|---:|---:|
| 32.4 | 平台 | 49000 | 0 | 468633.757 N |
| 32.40000000000221 | Amesim | 1e17 | 1e12 | 1756893.431 N |
平台的事件时间计算为 `32.400000000000006`,所以采样时刻 `32.4` 位于切换前;Amesim 上述结果位于切换后。这些时间在界面上都会显示为 32.4 s。模型信号幅值和接触阻尼非常大,微小时间差造成的小速度差会被阻尼放大为很大的力差。
节点能量诊断后,32.4 s 处仍有约 1.288 MN 的差别,但排除切换窗口后的力差降到 1.373 N,说明这与主要能量 bug 是两个问题。当前证据不支持把切换点差别直接判为 LSTP00A 力公式错误。
### 信号求值和事件定位本身也存在不一致
`native/components/modules/signal.c:8` 用 `fmod` 求周期内时间;`signal.c:26` 起用“周期数乘周期再加阶段偏移”定位事件。
独立 C 探针直接调用这两个原始函数:事件定位返回 44 s,但在完全相同的 double 值 44 上,信号求值仍返回上一阶段的 1e17;到 `nextafter(44, +∞)` 才返回 49000。54 s 也可复现类似现象。**这是可重复的边界一致性缺陷,不需要运行积分器即可触发。**
后续应让阶段判定、事件定位及结果采样共享同一套边界定义,并明确保存切换前值、切换后值或两者。不能用任意放宽时间容差的方式把所有邻近时刻混在一起。
### 普通采样会漏掉很窄的尖峰
平台原始结果还保存了约 32.40035510065 s 的额外事件点,力约 −2.0839e14 N,0.01 s 共同网格并不包含它。为排除“平台独有尖峰”,在 Amesim 生成 C 的诊断副本中记录该窗口的内部方程计算,也捕捉到相同时刻、相同量级的负尖峰(约 −2.0839e14 N)。这些内部计算含事件和试算调用,不能把它们全部当作已经接受的普通输出采样。
因此既不能拿平台额外事件点与 Amesim 的粗采样曲线直接逐点相比,也不能把上份报告的共同网格指标当作全时间域尖峰误差。后续事件验收应分别比较同侧极限、事件时间、事件后的状态及窄窗口波形。
## 6. 后续修复顺序建议
1. 先修复节点能量传递:这是已证实影响主要物理结果的 bug。
2. 修复采样容量错误的校验、说明和日志保留;再安排分块结果输出。
3. 统一循环信号的事件与采样边界。
4. 补齐氦气分段物性,明确管路摩擦公式对齐标准;之后再量化剩余积分误差。
本次没有合入以上修改,也没有调整求解器、矩阵或生产工具链。
## 7. 可复核证据
以下路径均相对 `test/diagnosis-20260914/`:
- `sampling-reproduction.json`:退出 64、短仿真及 solve-only 的命令和结果。
- `initial-convergence-summary.json`:启动瞬间细采样、最大步长收紧实验。
- `same-state-flow-comparison.json`、`replay-state-*.json`:将 Amesim 物理状态送入原平台 C 方程。
- `node-energy-balance.json`:各支路能量及漏算量。
- `node-energy-replacements.json`、`node-energy-model.c`:只用于因果验证的生成代码改动。
- `node-energy-final-comparison.json`:独立诊断程序完成 50 s 的曲线指标,以及节点加黏度实验。
- `properties-summary.json`、`volume-comparison.json`、`native-flows.csv`、`ame-flow-probe/flow-probe.csv`:直接物性、储气方程及管流对比。
- `signal-boundaries.csv`、`force-event-samples.json`、`event-force-probe-summary.json`:循环边界和窄尖峰证据。
- `production-source-verification.json`:188 个生产文件哈希核对结果。
所有诊断源码、实验模型副本及日志均保留在该目录,可在后续正式修复时复用。