286 lines
24 KiB
Markdown
286 lines
24 KiB
Markdown
# SystemSimulationApp 仿真性能评估(2026-08-15)
|
||
|
||
> 代码基线:`model-development@6a06489`,随后只加入本报告所述的可选埋点和基准工具。
|
||
> 本次评估的是前端流式接口实际使用的 System XML 求解路径;所有时间均为本机实测,不代表其他机器的绝对性能。
|
||
> 2026-08-16 已按本报告建议实现“仿真内独立物性缓存”“worker 启动暖机”、高刚度试探压力边界修复、方程关联块闭合、代数稀疏回退、外部 volume 跨域 ODE Jacobian 修正和 dense output 惰性构造;原始基线数据保留用于对照,当前大型 XML 复验见第 11 节。
|
||
|
||
## 1. 结论
|
||
|
||
1. **压力—流量闭合是原始基线的首要热点。** 2026-08-15 深度审计中,三个气动短算例有 71%~85% 的计时落在 `PressureFlowSolver.solve()` 的包含时间内。它同时包含残差组装及其触发的物性调用,不能与物性时间相加;2026-08-16 已完成方程块与稀疏首轮,当前现状见第 11 节。
|
||
2. **物性调用存在很高的完全相同输入重复率。** 按每次代数闭合重置精确输入影子集合后,空气链路、空气分支和氦气阶跃的重复率分别为 91.2%、96.5% 和 82.3%。空气公式很便宜,不能只凭重复率加缓存;Peng–Robinson 氦气更值得优化。
|
||
3. **评估基线已有的两项氦气 LRU 精确缓存有效。** 冷缓存审计中,`properties_from_mU` 命中率 95.5%,`temperature_from_pressure_enthalpy` 命中率 78.6%;21 次配对端到端测试中,暖缓存比每次清空缓存快约 7.9%。这些数据描述 2026-08-15 的原始基线,后续实现见第 9 节。
|
||
4. **长仿真的时间主要花在积分阶段。** 10 s 氦气均压算例耗时约 10.6~11.5 s,其中标准埋点测得积分占 90.5%,初始化约 4.2%,逐采样点后处理约 5.0%。
|
||
5. **结果 JSON 暂不是这些算例的首要矛盾。** 四个短算例的最终 NDJSON 结果约 29~59 KiB,编码中位数约 0.4~1.2 ms;501 个采样点的长算例约 507 KiB,编码约 18.5 ms。
|
||
6. **首次仿真有明显冷启动。** 新 Python 进程第一次短算例约 0.71 s,预热后同类算例约 0.06~0.13 s。剖析表明首次进入 SciPy 求解路径的惰性导入占了主要差额;这是服务首请求延迟,不是稳态吞吐。
|
||
7. **用户提供的高刚度 XML 已能完成 10 s 仿真。** 原始基线在 `0.000175 s` 左右因 `Initial guess is outside of provided bounds` 失败;原因是压力优化下界为 1 Pa,排除了 RK45 合法产生的、仍严格大于 0 Pa 的亚帕试探值。2026-08-16 将优化器压力下界放宽到 0 Pa 后,构成方程仍要求压力严格为正,完整 RK45 仿真通过且没有触发可恢复重试。
|
||
8. **闭合不再固定执行第二次全网压力求解,也不再把一个大物理岛等同于一个求解块。** 每次闭合仍先保证全网成立;stream 更新后,只重算声明为 stream-sensitive 的方程—未知量关联块。物理连通岛只是安全范围,当前 `secondaryBlockCount` 是真实方程块数;无法安全分类的自定义模型会保守回退原全网路径。
|
||
9. **历史物理岛版收益取决于模型拓扑。** `off` 模式配对测试中,空气链、空气分支、氦气阶跃、机械接触和高刚度短算例分别改善 7.9%、6.5%、0.6%、21.4% 和 14.6%。这些数据保留作纵向基线,但该版已由方程关联块实现取代。
|
||
10. **大型分支 XML 的 `0.69 s` 现象已定位并完整跑通。** 输入 SHA-256 为 `2fb95e65f5de0c85a6a17802aef74ea004087323fd00fd8d01acf0184ff71d48`,含 98 个组件、472 个代数未知量、74 个 ODE 状态。根因是外部 volume 跨域耦合在 ODE Jacobian 依赖图中漏 12 个实测显著项,而不是线程死锁;修正后结构由 1092 非零/27 色变为 1284 非零/31 色。最终稳定代码连续三次完整 `0~0.81 s` 用时 79.049 s、74.658 s 和 85.103 s,积分统计均为 `nfev/njev/nlu=3393/226/667`、接受步 1009。
|
||
11. **代数非线性回退已有可信声明图上的稀疏保护链。** 先求本轮未闭合方程块的 union sparse;失败恢复原始 `x0` 后做 global sparse,再失败才做 dense。受控扰动微基准在相同 `max_nfev=20` 下把真实残差回调由 3796 降至 164、墙钟约 7.357 s 降至 0.634 s(约 11.6 倍);活动接触或不可信声明仍走兼容 dense 路径。
|
||
12. **首轮其他优化均按适用范围解释。** worker 暖机已覆盖 sparse `least_squares` 的 LSMR 路径;dense output 仅在跨采样点或需要状态事件时构造,但本次大型 XML 含状态事件,因此没有本案收益。机械 `atol` 的 `1e-12→1e-10` A/B 约快 16%,但会改变机械误差合同,未采用;外层 thermofluid 流量固定点相对容差的 `1e-12→1e-9` A/B 反而增加 BDF 步数并改变轨迹,也未采用。
|
||
|
||
## 2. 埋点实现与污染控制
|
||
|
||
性能开关由进程启动环境变量 `SIMULATIONAPP_PROFILE` 决定:
|
||
|
||
| 模式 | 用途 | 记录内容 | 适合场景 |
|
||
| --- | --- | --- | --- |
|
||
| `off` | 正常运行,默认值 | 不在响应中加入性能数据;装饰器在模块加载时直接返回原函数 | 正式仿真和最终性能对比 |
|
||
| `standard` | 低开销阶段统计 | XML 校验、网络编译、系统构造、初始化、积分、后处理、结果组装 | 日常定位“大阶段” |
|
||
| `audit` | 深度审计 | 再展开 RHS、代数闭合、压力流量、stream、刷新、导数和物性内核 | 短算例诊断、调用频率与缓存评估 |
|
||
|
||
一次运行使用一个 `ContextVar` 隔离的 `PerformanceTrace`,不会把不同仿真任务的阶段计数混在一起。成功或失败的求解结果在 profiling 模式下都会把快照放入 `diagnostics.performance`。主要字段为:
|
||
|
||
- 阶段:`calls`、`inclusiveNs`、`selfNs`、`maxNs`、`errors`;
|
||
- 物性:上述时间字段,以及介质、操作、缓存查询/命中/未命中;
|
||
- audit 专有:闭合内精确输入唯一数/重复数、逆解迭代总数/最大值/收敛与未收敛次数;
|
||
- `propertyOutermostNs`:只累计最外层物性调用,避免把嵌套 PR 内核时间重复相加。
|
||
|
||
标准模式只保留低频的大阶段计时。21 次氦气阶跃配对运行中,标准模式相对关闭模式的中位开销为 1.9%;四个短算例分开校准为 0.5%~2.9%。audit 会逐次生成精确指纹并计时,短算例可慢到约 2.5~5 倍,因此 audit 数据用于定位和计数,最终优化收益必须回到 `off` 模式复测。
|
||
|
||
将当前代码的 `off` 模式与备份提交 `6a06489` 同时运行 21 次氦气阶跃,墙钟中位数差为约 0.3%,处于本机噪声范围。也就是说,默认关闭时没有观察到稳定的热路径退化。
|
||
|
||
## 3. 测试方法
|
||
|
||
环境:Windows 11、Python 3.12.3、SciPy 1.18.0、64 位 Intel 处理器。仓库没有 PyInstaller/Nuitka 等可执行文件构建链,本次直接使用项目实际启动后端的 `.venv-win` 解释器。把同一 Python 代码再包成单文件只会混入解包和启动成本,不会使这里的求解内核更接近生产路径。
|
||
|
||
基准工具入口:
|
||
|
||
```powershell
|
||
.venv-win\Scripts\python.exe -m app.simulation.benchmark_performance `
|
||
--mode audit --warmups 1 --runs 3 `
|
||
--factory "helium_step=tests.test_amesim_pnvo001_signal_xml:high_pressure_helium_step_project" `
|
||
--output app/data/performance-evaluations/helium-step.json
|
||
```
|
||
|
||
工具默认传入取消检查回调,从而走与前端流式仿真相同的低层逐步积分路径。它记录墙钟、进程 CPU、最终 NDJSON 编码、输入 SHA-256 和完整性能快照。原始 JSON 写入被 Git 忽略的 `app/data/performance-evaluations/`,避免把机器相关的大量样本提交到仓库。
|
||
|
||
本次代表算例:
|
||
|
||
| 算例 | 内容 | 暖机后 `off` 墙钟中位数 | 重复次数 |
|
||
| --- | --- | ---: | ---: |
|
||
| `air_chain` | 空气气缸—节流孔—管路—储罐 | 62.4 ms | 9 |
|
||
| `air_branched` | 空气分支网络 | 130.3 ms | 9 |
|
||
| `helium_step` | 高压 PR 氦气、信号阶跃阀 | 65.2 ms | 9 |
|
||
| `mechanical_contact` | MECMAS21/LSTP00A 弹性接触 | 33.0 ms | 9 |
|
||
| `helium_long` | 10 s PR 氦气均压、501 个输出点 | 10.63 s | 1 |
|
||
|
||
短算例先暖机 2 次再测 9 次;缓存 A/B 使用两个同时启动的独立进程各暖机 5 次、测量 21 次,以尽量抵消瞬时系统负载。长算例只测 1 次,因此它只用于判断数量级与阶段占比。
|
||
|
||
## 4. 深度阶段结果
|
||
|
||
下表时间是 audit 中位数,会包含审计自身开销;调用数和相对热点比绝对时间更可靠。
|
||
|
||
| 算例 | RHS | 完整闭合 | 压力流量求解 | 压力流量包含时间占 audit 总时间 | 物性调用 | 闭合内精确重复率 |
|
||
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
|
||
| `air_chain` | 33 | 37 | 74 | 77.0% | 4,265 | 91.2% |
|
||
| `air_branched` | 23 | 26 | 56 | 84.6% | 7,378 | 96.5% |
|
||
| `helium_step` | 79 | 102 | 235 | 71.2% | 11,121 | 82.3% |
|
||
| `mechanical_contact` | 74 | 78 | 156 | 29.5% | 0 | 不适用 |
|
||
|
||
这是 2026-08-15 原始基线的闭合数据:当时每次闭合先做 1 次压力求解,然后最多执行 25 轮 `stream → pressure-flow` 固定点,理论上最多 26 次;四个算例平均为 2.00、2.15、2.30 和 2.00 次/闭合。随后 2026-08-16 的第一版先把后续重算缩到 stream-sensitive 物理连通岛;该历史版本又被当前方程关联块版取代。当前做法是在安全物理范围内只重算敏感方程实际关联的块,没有敏感块时不强制第二次压力求解。这样裁剪的是无效重算,不是删除真实耦合。
|
||
|
||
## 5. 物性调用与缓存结果
|
||
|
||
氦气阶跃的冷缓存 audit 代表运行:
|
||
|
||
| 操作 | 调用 | 命中/未命中 | 命中率 | 真实逆解次数 | 平均迭代 | 最大迭代 | 未收敛 |
|
||
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
|
||
| `properties_from_mU` | 1,930 | 1,843 / 87 | 95.5% | 87 | 3.99 | 5 | 0 |
|
||
| `temperature_from_pressure_enthalpy` | 398 | 313 / 85 | 78.6% | 85 | 5.00 | 5 | 0 |
|
||
|
||
在原始基线中,暖机后以相同配置重复运行,这两项在代表快照中均为 100% 命中,说明当时的进程级精确 LRU 能跨同配置运行复用确定性轨迹。关闭埋点的端到端配对结果为:暖缓存中位数 77.05 ms,每次清空缓存为 83.69 ms;换算为暖缓存约快 7.9%。
|
||
|
||
audit 的自身时间排序还显示:`isentropic_density_pressure_factor` 调用 398 次,`density` 业务入口及 PR 密度内核各调用 1,198 次,PR `compressibility_roots` 调用 1,712 次。同一 `(p,T)` 周围存在“等熵因子内部求密度,随后流量公式再次求密度”的重复机会。这里应优先复用同一闭合内的精确结果或合并 API;不要用四舍五入/容差键缓存,否则会在残差函数中制造平台并影响 ODE/least-squares 的有限差分。
|
||
|
||
空气算例虽然精确重复率更高,但理想气体公式本身只有少量算术。对这些廉价函数增加字典查询可能比重算更慢,应先做专门 A/B,不应套用氦气结论。
|
||
|
||
## 6. 输出与失败样本
|
||
|
||
| 算例 | 最终结果大小 | NDJSON 编码中位数 |
|
||
| --- | ---: | ---: |
|
||
| `air_chain` | 29.2 KiB | 0.39 ms |
|
||
| `air_branched` | 59.1 KiB | 1.21 ms |
|
||
| `helium_step` | 55.5 KiB | 1.10 ms |
|
||
| `mechanical_contact` | 51.4 KiB | 0.62 ms |
|
||
| `helium_long` | 507.4 KiB | 18.48 ms |
|
||
|
||
用户高刚度 XML 的输入 SHA-256 为 `27048a99da0a21922d75785b760c3b5d04be3349b8aef6fbfedfd811d87ef1d5`。原始 audit 失败运行记录到 80 次 RHS、83 次闭合、165 次压力流量求解,最后一项各有 1 次错误;其 1.08 s 只代表历史失败路径,不能当作完整模型性能。允许严格正的亚帕试探压力后,同一模型已完成 10 s,当前完整性能结果见第 10 节。
|
||
|
||
## 7. 后续优化顺序
|
||
|
||
1. **[2026-08-16 已落实方程块与稀疏首轮] 优化压力流量执行计划。** 压力/流量方程、显式赋值、热流依赖和方程—未知量关联图已预编译;每轮 stream 更新后只重算敏感方程块。非线性时先做可信未闭合块的 union sparse,失败从原 `x0` 做 global sparse→dense;自定义、活动接触或结构不安全的网络保守回退兼容路径。后续仍可评估 equality group 真正消元和解析 Jacobian。
|
||
2. **[2026-08-16 已落实] 减少 PR 物性重复。** 复用组件当前 `(m,U,V)` 的状态恢复结果,并缓存相同输入的密度和等熵因子;沿用精确键、有界容量和按仿真隔离原则。
|
||
3. **[2026-08-16 已落实] 处理冷启动。** worker 在 FastAPI lifespan 中完成无业务副作用的 SciPy/XSD 微型暖机后再接收请求;不要把约 0.65 s 冷启动归因到每次仿真。
|
||
4. **长算例再看后处理复用。** 当前代表长算例的积分占 90.5%,所以积分/闭合仍优先;当采样更密或变量更多时,再评估复用已接受状态闭合、按需变量和降采样。
|
||
5. **[2026-08-16 已落实] 修复高刚度 XML 的压力试探边界。** 优化器允许严格正的亚帕试探值,物理构成方程仍拒绝零压和负压;该模型已用 10 s RK45 回归验证,不需要把这类合法试探误报为可恢复拒步。
|
||
6. **[2026-08-16 已落实] 补全外部 volume 的跨域 ODE Jacobian 依赖。** 机械位移写入气室容积后,气动储能与机械力平衡必须在状态稀疏图中双向关联;大型分支 XML 据此完整跑通。机械 `atol` 放宽虽有约 16% 的单次改善但改变精度合同;flow 固定点容差放宽反而增加步数,均未采用。
|
||
7. **[2026-08-16 已落实] dense output 惰性构造。** 仅当已接受步跨越下一样本或需要状态事件时构造插值;含状态事件的模型每步仍需要,不将其宣传为大型分支 XML 的收益来源。
|
||
|
||
## 8. 本次评估边界
|
||
|
||
- 没有固定 CPU 亲和性或关闭后台程序,短算例绝对时间存在数毫秒波动,因此以中位数和配对实验为主。
|
||
- audit 会显著改变廉价函数的单次耗时;不能把 audit 的物性毫秒数直接当成关闭埋点后的真实占比。
|
||
- 原始基线的 LRU 命中/未命中来自调用前后的全局 `cache_info()` 差值;本报告当时均为单任务运行。该并发统计限制已由第 9 节的仿真内独立缓存消除。
|
||
- 直接抛出 `HTTPException` 的校验/执行异常会结束 trace,但当前不会把快照附到错误响应;demo 属于返回 `failed` 部分结果的路径,所以本报告能够取得其失败快照。
|
||
- 本批没有测峰值 RSS、1/2/4 并发吞吐、浏览器解析/绘图或 8/32 单元拓扑扩展曲线。
|
||
- 没有为评估引入新的近似缓存、容差调整或求解器算法变更;所有性能结论都与数值优化改动解耦。
|
||
|
||
## 9. 2026-08-16 缓存与启动暖机复验
|
||
|
||
原先两个函数级 LRU 会在 Python 进程内跨仿真共享条目。现已改为每次仿真通过
|
||
`ContextVar` 创建独立缓存,并在运行结束后整体释放;并发任务不会共享缓存或
|
||
命中统计。每个“物性操作 + 介质实例”使用独立的 C 层有界 LRU,默认上限为
|
||
8192 项。当前只缓存四条有明确重复收益的氦气路径:密度、等熵密度—压力因子、
|
||
`properties_from_mU` 和 `temperature_from_pressure_enthalpy`。
|
||
|
||
同一个高压氦气阶跃算例的冷缓存 audit 结果为:
|
||
|
||
| 操作 | 调用 | 命中 / 未命中 | 命中率 |
|
||
| --- | ---: | ---: | ---: |
|
||
| `density` | 578 | 403 / 175 | 69.7% |
|
||
| `isentropic_density_pressure_factor` | 398 | 310 / 88 | 77.9% |
|
||
| `properties_from_mU` | 1,930 | 1,843 / 87 | 95.5% |
|
||
| `temperature_from_pressure_enthalpy` | 398 | 313 / 85 | 78.6% |
|
||
|
||
四项合计 2,869 次命中、435 次未命中、435 个最终条目,未发生驱逐。PR 三次根
|
||
计算从原审计的 1,712 次降到 689 次。关闭埋点、各自预热 5 次并测量 21 次时,
|
||
缓存开启/完全关闭的墙钟中位数在本机分别为 71.6 ms 和 154.0 ms。这个对比表示
|
||
“四项缓存整体”相对“完全不缓存”的收益,不能误解为相对旧版两个 LRU 又提升
|
||
53.5%。缓存开关两次运行的完整 `series` 和 `final` SHA-256 一致。
|
||
|
||
10 s、501 个输出点的氦气均压算例单次复验中,缓存开启和关闭分别用时
|
||
14.18 s 与 26.64 s;开启时命中 400,571 次、未命中 96,427 次。四个缓存均达到
|
||
各自 8192 项上限,共发生 63,659 次 LRU 驱逐,但仍完成到 10 s。该长算例每种
|
||
配置只测了一次,只能说明容量上限确实生效且仍有收益,不能作为稳定百分比承诺。
|
||
|
||
worker 暖机只执行内存中的一维 BDF、`least_squares`、`brentq`、稀疏 Jacobian
|
||
分组和 XSD 编译,不运行用户模型、不写文件、不填充氦气业务缓存。当前暖机还显式
|
||
覆盖携带 `jac_sparsity`、使用 sparse LSMR trust-region 子问题的代数路径,避免真实
|
||
用户任务第一次触发该 SciPy 分支时再承担惰性初始化。三个新进程的
|
||
中位数为:不暖机首个仿真 709.1 ms;启动暖机本身 637.1 ms;暖机后的首个仿真
|
||
69.8 ms,同进程第二次约 68~74 ms。也就是说总初始化成本没有消失,而是被
|
||
移到服务宣告就绪之前。
|
||
|
||
## 10. 2026-08-16 历史物理岛版闭合复验
|
||
|
||
> 本节保留方程关联块实现之前的物理岛版数据,用于纵向对照。它已不是当前执行计划;当前结果见第 11 节。
|
||
|
||
该轮把 signal 源/连接、stream 组件/端口/连接以及气动外部 volume 组件/连接的
|
||
静态查找移到系统构造阶段;运行时仍按每个状态执行实际传播和热力刷新。压力流量
|
||
闭合先进行一次全网求解,再根据预编译的依赖声明,只对 stream-sensitive 的物理
|
||
连通块做后续固定点重算。对未声明依赖的自定义 stream 组件、跨组件方程或非方阵
|
||
物理岛,执行计划保守回退到原全网求解,不以性能换取模型兼容性。
|
||
|
||
该历史版本的 `off` 模式配对结果如下。表中百分比是同一模型、同一数值配置下的墙钟改善,适合
|
||
判断优化方向,不是跨机器速度承诺:
|
||
|
||
| 算例 | 历史物理岛版相对原全网闭合的改善 |
|
||
| --- | ---: |
|
||
| `air_chain` | 7.9% |
|
||
| `air_branched` | 6.5% |
|
||
| `helium_step` | 0.6% |
|
||
| `mechanical_contact` | 21.4% |
|
||
| high-stiffness short | 14.6% |
|
||
|
||
`helium_step` 在该历史版本里只有一个需要在 stream 后继续求解的敏感物理岛,因此 0.6% 的改善处于
|
||
小幅范围;不能用其他无敏感岛模型的收益夸大氦气模型的效果。积分完成后的后处理
|
||
也没有跳过闭合:每个输出采样点仍重新应用状态、执行完整 `_close_current_state()`
|
||
并提取结果,只是闭合内部使用同一安全执行计划。
|
||
|
||
完整 high-stiffness 10 s 算例的历史 `off` 基线约为 28.126 s;本轮全部改动后的
|
||
多次运行中位数为 13.694 s。这个跨版本对比同时包含本轮多项改动,不能把差额全部
|
||
归因于物理岛裁剪。为了单独核对当时的闭合计划,在同版代码上做 optimized/forced-global
|
||
对照,墙钟分别为 14.676 s 和 16.929 s,完整 `series` 完全一致;这组受控对比才
|
||
直接反映该模型的执行计划收益。
|
||
|
||
当前诊断已经进一步消除旧命名歧义:`secondaryPhysicalIslandCount` 表示安全分类的
|
||
物理范围,`secondaryBlockCount` 表示方程—未知量关联图中的真实块数,
|
||
`secondaryUnknownCount` 表示这些方程块合计未知量。`solveCount` 统计实际求解器调用,
|
||
`closurePassCount` 单列发生过压力求解的闭合 pass;`last` 中还包含
|
||
`residualEvaluations`、`jacobianMode`、dense/方程块回退状态。不能再把
|
||
`secondaryBlockCount` 解释为物理岛数。
|
||
|
||
## 11. 2026-08-16 大型分支 XML 与方程块首轮复验
|
||
|
||
验证输入 `test_mql-full-branches-01-04.xml` 的 SHA-256 为
|
||
`2fb95e65f5de0c85a6a17802aef74ea004087323fd00fd8d01acf0184ff71d48`。模型规模如下:
|
||
|
||
| 项目 | 数量 |
|
||
| --- | ---: |
|
||
| 组件 | 98 |
|
||
| ODE 状态 | 74 |
|
||
| 压力/流量/机械代数未知量与方程 | 472 / 472 |
|
||
| 代数声明图结构非零 | 919(约 0.413%) |
|
||
| 全部独立代数方程块 | 58 |
|
||
| stream 后续敏感方程块 | 9,合计 192 个未知量 |
|
||
|
||
### 11.1 `0.69 s` 慢区的根因与完整结果
|
||
|
||
旧代码在 `0.69 s` 左右不是线程死锁:它仍会缓慢前进,但 BDF 在刚性变化区大量
|
||
缩步、重建有限差分 Jacobian 和执行 LU。定位出的结构错误是气动外部 volume
|
||
跨域耦合没有完整进入 ODE 状态依赖图。机械位置先写入气室容积,气室压力又反馈到
|
||
机械力平衡;旧图只沿普通物理端口追踪,漏掉这条闭环中的 12 个实测显著导数项。
|
||
|
||
修正后,状态稀疏图由 1092 个非零项、27 个颜色组变为 1284 个非零项、31 个颜色组。
|
||
颜色数增加是因为补上了真实依赖,并非回退到更差算法;完整 Jacobian 让 BDF 少走
|
||
错误 Newton 方向和重复试步。功能收口过程中的较早阶段测量为 92.187 s;最终稳定
|
||
代码连续三次完整 `0~0.81 s` 分别用时 79.049 s、74.658 s 和 85.103 s,数值工作量一致:
|
||
|
||
| 指标 | 结果 |
|
||
| --- | ---: |
|
||
| `nfev` | 3393 |
|
||
| `njev` | 226 |
|
||
| `nlu` | 667 |
|
||
| 接受步 | 1009 |
|
||
| 求解器启动次数 | 3 |
|
||
| 压力流量求解 | 28008,全部 seeded |
|
||
| 方程块/dense 非线性回退 | 0 / 0 |
|
||
| 三次 full-response 规范 JSON SHA-256 | `454cd11aece1c4a2296a88e2c1dd592eeace28565e342235fb7a7df34de5b18f` |
|
||
| `physical-solution-v1` SHA-256 | `04982f427867801c582fea81c6e2da0b726bd8a61d7894b311e4a807b19e89a7` |
|
||
|
||
这里的 full-response 哈希覆盖完整响应,所以诊断字段增删也会改变它。为稳定比较物理
|
||
结果,`physical-solution-v1` 只把 `{status, simulatedUntil, requestedStopTime, series,
|
||
final}` 投影为待哈希对象;schema 名只是外部标签,不进入对象。两种口径都使用
|
||
`json.dumps(sort_keys=True,separators=(",",":"),ensure_ascii=False)` 后计算 SHA-256。
|
||
旧 `09b5c7…` 是聚合诊断和最终 union 路径收口前的 full-response 哈希,响应结构不同,
|
||
不作为最终结果,也不能与当前口径直接比较。
|
||
|
||
容差 A/B 必须分开解释:机械状态 `atol` 从 `1e-12` 放宽到 `1e-10` 的单次测试约快
|
||
16%,但会改变机械状态与事件的误差合同,当前未采用;外层 thermofluid 流量固定点
|
||
相对容差从 `1e-12` 放宽到 `1e-9` 后,BDF 内部步数反而增加并改变积分轨迹,也未
|
||
采用。完整成功来自依赖图修正和闭合优化,不是牺牲积分精度或闭合精度。
|
||
|
||
### 11.2 stream 方程块与受控 A/B
|
||
|
||
第一次压力流量求解仍承担“全网必须成立”的语义;但可信声明图允许它在非线性时只把
|
||
本轮未闭合的独立方程块合并成一个 union sparse 问题,而不是固定构造 472 变量的
|
||
dense 问题。stream 更新后的固定点进一步只处理 9 个敏感方程块、合计 192 个未知量,
|
||
不再因为机械总线把拓扑连成一个大物理岛,就重复求解全部 472 个未知量。
|
||
|
||
在相同当前代码、相同 `0~0.01 s` 区间做 optimized/forced-global 配对,墙钟分别为
|
||
16.200 s 和 18.584 s,物理解与 `series` 逐值一致。这组对照隔离的是后续 stream
|
||
闭合作用域;它不包含完整 `0.81 s` 慢区的全部收益,不能与最终完整运行直接换算百分比。
|
||
|
||
### 11.3 非线性稀疏回退与其他首轮项
|
||
|
||
全局非线性回退当前采用兼容保护链:可信声明图先求未闭合方程块的 union sparse;
|
||
若块解失败,先把所有共享端口未知量恢复到原始 `x0`,再做 global sparse;若 sparse
|
||
仍未达到既有残差合同,再次从原 `x0` 做 global dense。活动接触会改变坐标/活动集,
|
||
不可信自定义声明也可能漏依赖,这两类不冒险使用静态稀疏图,继续走 dense 兼容路径。
|
||
|
||
受控扰动微基准在相同 `max_nfev=20` 下得到:
|
||
|
||
| 路径 | 真实残差回调 | 墙钟 |
|
||
| --- | ---: | ---: |
|
||
| dense | 3796 | 7.357 s |
|
||
| sparse | 164 | 0.634 s |
|
||
|
||
同一评估预算下约为 11.6 倍的回退成本改善;两条路径在 20 次优化器评估内都没有收敛,
|
||
所以这是“数值 Jacobian 试算成本”微基准,不是整体仿真加速承诺。诊断用
|
||
`residualEvaluations` 记录真实残差回调,避免仅看 SciPy `nfev` 漏掉内部差分调用。
|
||
|
||
worker 暖机现已覆盖带 `jac_sparsity` 的 sparse LSMR `least_squares` 路径。逐步积分的
|
||
dense output 也改为只在当前步跨越下一采样点或需要状态事件定位时构造;本 XML 含
|
||
状态事件,所以每步仍需要插值,这项优化对最终 79.049 s/74.658 s/85.103 s 复验没有收益。
|