优化端口传递物性参数方式,减少上下游元件重复计算量

This commit is contained in:
ljz committed 2026-09-11 14:42:19 +08:00
1 parent 91bd9fb252
commit 5d5a2e1843
12 files changed
+773 -65

No files matched your search

@@ -0,0 +1,203 @@
# 物性与管流分段性能分析(2026-09-11)
后续实现已完成:见 [物性复用与管流求根实现及验证](物性复用与管流求根实现及验证-2026-09-11.md)。本文保留为实施前的剖析与隔离实验记录;最新生产实现、计时和回归结论以实现报告为准。
本次沿用网页端已验证的 `test-mql-4-corrected.json`,直接测试网页后端使用的 C 求解程序。结论是:两个方向都值得优化,但物性应优先减少重复反算,管流则应改进收敛方法并检查残差。把迭代次数直接调小,不能可靠地解决问题。
隔离试验中,完整 10 秒仿真的纯求解耗时从 **3.119 秒降至 2.102 秒,中位耗时缩短 32.6%**。这些是 `/test` 内的实验结果;本次没有更改网页后端的生产内核,也没有修改系统雅各比矩阵。
**测试对象与测量口径**
- 输入:`test/mql4-20260910/test-mql-4-corrected.json`,与上一轮网页端对照使用同一模型。
- 配置:真实氦气 Peng–Robinson 物性;CVODE/BDF;仿真 0~10 s;相对误差限 `1e-7`;最大积分步长 `1e30`;状态绝对误差限沿用生产配置。
- 规模:64 个状态,882 个输出;本模型的编译计算顺序已经形成,无代数环。当前检查的是这个顺序内部的成本。
- 代码:`system-optimization` 分支,构建标识 `a23de3b825eaacc2df5b61f524df66ec3f92da943acb5a9a98aaf4ba479fb02f`。试验脚本首先核验生产 C 源文件与构建清单的哈希一致。
- 性能比较:每个方案独立进程运行三轮,交错执行,报告中位数。只统计 C 求解阶段,使用 `--solve-only`,不含 Python 前处理、编译、进程启动、曲线输出、网页交互和绘图。
- 正确性比较另跑完整输出,保存 0.01 s 网格及事件点;对组合方案另外记录碰撞附近内部积分点。
- 分段测试是在一次连续求解中计数,按方程试算的时间归入区间,**没有在分段边界重启求解器**。试算可能回退、拒绝或越过区间边界,因此这些数据表示“为该区间试算花了多少成本”,不是各段独立启动的时间。
- 计时探针和详细计数、输入采集分两次执行;二者的全部输出序列均与未插桩基准逐点完全一致。插桩运行总耗时为 3.600 s,同批完整输出基准为 3.211 s,探针约增加 12% 耗时。因此下面函数时间用于定位成本,最终加速比使用无探针程序测量。
本次没有重跑 Amesim;数值对照读取此前官方重新编译运行的 `amesim-fresh/test_mql_4.ame`。不将历史 Amesim 耗时与本次机器负载不同的测量混合计算加速比。
**1.时间花在哪个阶段**
基准共执行 24,941 次系统方程计算,接受 5,137 个积分步,发生 2 次状态切换。下表中的时间是探针测得的方程计算时间,不包括方程外的求解器工作。
| 仿真时间区间 / s | 方程计算次数 | 方程计算耗时 / s | 占全部方程计算时间 |
|---|---:|---:|---:|
| 0~0.01 | 760 | 0.068 | 1.9% |
| 0.01~0.8 | 12,042 | 1.757 | 49.9% |
| 0.8~1.20 | 2,165 | 0.272 | 7.7% |
| 1.20~1.202,包含首次碰撞 | 1,186 | 0.146 | 4.1% |
| 1.202~1.23,包含第二次限位事件 | 2,451 | 0.313 | 8.9% |
| 1.23~2 | 4,333 | 0.668 | 19.0% |
| 2~10 | 2,004 | 0.299 | 8.5% |
| 合计 | 24,941 | 3.522 | 100% |
接近一半的工作发生在 0.01~0.8 s。最后 8 秒仿真只占约 8.5% 的方程计算时间。碰撞附近确实需要处理很快的变化,但本次测量不支持“主要时间都花在碰撞瞬间”的判断。
另有 16,768 次方程计算来自线性求解器估算数值导数,占全部方程调用的 67.2%。这部分已经包含在表内,不能另加一次。它意味着物性和管流计算会随系统试算反复执行。本轮保留现有雅各比矩阵处理方式,只降低每次试算成本。
**2.把物性和管流迭代分开后,结论发生了什么变化**
下表按互不重复的函数耗时分类:例如管路内部调用的可压缩流动计算,记在“可压缩流动系数”中,不再记入“管流摩擦迭代”。
| 计算内容 | 插桩耗时 / s | 占方程计算时间 | 调用次数 |
|---|---:|---:|---:|
| 可压缩流动系数:等熵修正、密度、临界/亚音速关系等 | 1.009 | 28.6% | 728,296 |
| 管流摩擦迭代 | 0.945 | 26.8% | 483,678 次进入循环 |
| 用压力、焓反求温度 | 0.728 | 20.7% | 646,040 |
| 从质量、内能恢复气体状态 | 0.328 | 9.3% | 648,466 |
| 管路诊断量:雷诺数、速度、摩擦系数等 | 0.252 | 7.2% | 548,702 |
| 管路其余准备工作 | 0.093 | 2.6% | 548,702 次管流调用 |
| 系统组装、阀口剩余计算、接触力等 | 0.166 | 4.7% | — |
因此,不能把整个 `native_pipe_flow` 函数的时间都解释成“内部摩擦迭代太慢”。它首先还要计算黏度、真实气体修正以及可压缩流动系数。表中 28.6% 的项目也包含流量公式中的幂函数等,不是全部都属于物性查询。
本次计数还发现:一次完整求解累计调用约 **620 万次气体状态方程求根**、348 万次焓偏差计算和829万次摩擦系数计算。现在这些均运行在 C 内核中,当前问题已经是物理计算量和重复调用量,不能继续归因于 Python 语言开销。
**3.物性为什么贵,应该怎样优化**
当前真实氦气的 `p,h → T` 过程大致如下:先用理想气体关系猜温度,再代入真实气体关系计算焓,看是否吻合,然后更新温度。每次更新又要解一次气体状态方程,并计算对数等函数。
| 反算对象 | 次数 | 平均迭代次数 | 观察到的最多次数 | 达到16次上限且未收敛 |
|---|---:|---:|---:|---:|
| 质量、内能恢复温度 | 648,466 | 4.41 | 5 | 0 |
| 压力、焓恢复温度 | 646,040 | 4.38 | 5 | 0 |
物性反算在这个工况下并不存在迭代失控;主要问题是一次略贵的计算被调用了很多遍。C 输入重放试验中,`p,h → T` 平均约 **1.065 μs/次**,几十万次累加后就成为明显成本。
更重要的是,这 646,040 次调用,在同一次方程计算中,都能找到压力、焓完全相同的上游气体状态。温度此前已经算出来了。其中 369,553 次还是对相同压力、焓的重复请求,占 57.2%。
通俗地说,目前有些路径在做:“先算出温度,把它换成焓传给下一个部件,下一个部件又把同一压力下的焓反算成温度。”这个模型中,优先消除这条往返路径,比单独把反算公式加快更有价值。
已验证的两个层次:
1. **同一次试算中,相同输入只反算一次。** 完全相同的介质、压力、焓使用同一个结果。纯求解耗时减少 11.0%,全部882个输出及时间序列逐点完全一致,方程调用数也不变。
2. **传递与压力、焓对应的已知温度。** 如果气体状态已经提供了同一组压力、焓,直接使用其温度;找不到时仍调用原来的反算。单独使用这一方案,纯求解耗时减少 16.7%。采集的17,527个气体状态中,源温度与反算温度最大只差 `1.08e-10 K`,但微小数值变化仍会改变 BDF 的后续试算路径,所以不能承诺逐位相同。
通用实现建议是建立一个“本次方程计算的物性状态”结构,保存介质身份、压力、焓、温度及已经算出的密度、黏度等。编译器知道量来自哪个状态时,直接传递状态引用;不知道时再查询或反算。缓存由求解上下文持有,不依赖整个进程中的可变全局状态。
必须遵守物理含义:**相同焓并不代表相同温度**。节流后的压力改变了,或者支路发生焓混合,就不能直接沿用原来的温度。缓存必须核对介质与完整输入,未来两相介质还需要区分物性区域。每次试算更新或失效缓存;本轮实验不采用“数值差不多就复用”,以免把求解器正在估算的细小变化抹掉。
还有两个次级机会:
- `valve → isentropic → local_isentropic` 已经求过上游密度,返回阀口后又按相同 `p,T` 求了一遍。可以让一次物性更新同时提供密度、热容和所需导数,把公共中间量复用。该方向还未纳入本轮完整系统加速结果。
- 已知内能、压力、密度时,可以利用 `h = u + p/ρ` 得到焓,避免再从 `p,T` 求一遍真实气体焓。对采集状态的微基准,气体状态恢复从 **0.484 降至 0.247 μs/次**,约减少49%;与原式的最大焓差为 `1.67e-7 J/kg`。这是物性定义层面的通用机会,但必须先核对各介质的能量参考点与实现一致性。本轮只完成了单项验证,没有把该收益算进完整系统的32.6%。
对于确实需要反算的状态,后续再考虑使用上一次温度作初始猜测、利用局部热容改善更新、加区间保护与失败回退。初始猜测只能帮助收敛,不能绕过结果残差检查。查表、插值等近似方案暂不作为第一步,因为本轮已经找到无需近似的重复计算。
**4.管流为什么反复迭代,而且到上限仍没有收敛**
当前过程是:猜流量 → 算雷诺数 → 算摩擦系数 → 用新摩擦系数重新算流量 → 新旧流量各取一半 → 重复。每次调用又从“摩擦系数等于0.02”的固定猜测开始。
| 管路类别 | 调用次数 | 未进入循环的次数 | 达到上限且未收敛 | 占全部调用 |
|---|---:|---:|---:|---:|
| PNL00R(kind 0) | 49,882 | 49,644 | 0 | 0% |
| PNL0001/2(kind 1) | 399,056 | 8,028 | 390,268 | 97.8% |
| PNL0003(kind 3) | 99,764 | 7,352 | 92,412 | 92.6% |
PNL00R 大多走层流公式,确实进入迭代的少量调用最多需要62次,但都在其64次上限内收敛。PNL0003 的92,412次循环全部走满16次;PNL0001/2 的非零流动调用也几乎如此。
代码达到上限后直接返回当前流量,没有要求最终残差合格。这不只是速度问题,还意味着当前局部流量并未都达到代码宣称的收敛精度。
“新旧各取一半”虽然温和,却会限制收敛速度。例如层流关系下,在解附近一次更新大约只把误差缩至原来的75%;16次后仍可能剩下初始误差的约1%。充分粗糙的湍流区,即使摩擦系数已经近似恒定,仍然反复取平均,也会继续消耗循环。真实过渡区更不能依靠固定次数保证精度。
对实际仿真每37次调用抽取一组输入,重放得到14,830组管流输入,覆盖正流7,362组、反流6,951组、等压517组。压力约0.1~15.3 MPa,温度约173~526 K。
本次把相同的管流关系写成 `Re² × f(Re) = K`,以左右两边的相对差衡量残差。`K` 来自原来的物性、压力、温度及几何关系,没有换用新的物理流量公式。
| 类别 | 旧方法残差中位数 | 旧方法残差90分位 | 旧方法残差99分位 | 新方法最大残差 |
|---|---:|---:|---:|---:|
| PNL0001/2 | `7.51e-6` | 3.07% | 15.9% | `9.59e-10` |
| PNL0003 | `2.82e-6` | `1.85e-5` | 2.19% | `6.38e-11` |
相对残差在流量接近零时会很大,不能直接当成系统流量误差。即使只看新流量绝对值大于 `1e-8 kg/s` 的输入,旧方法的最大方程残差仍分别为21.6%和12.3%。在全部重放输入上,新旧流量的最大绝对差分别为 **`2.91e-6 kg/s`、`1.93e-6 kg/s`**。因此既要看残差,也要看流量的绝对变化和系统曲线。
针对这一点,实验采用带区间保护的局部 Newton 求根:根据当前偏差决定下一次改多少;如果下一次估计越界,则用区间二分回退。保留原有摩擦系数公式、层流分支、流向、可压缩修正及近平衡平滑。这里计算的是管路内部一个量的斜率,没有修改系统雅各比矩阵。
| 同一批输入的 C 微基准 | 旧方法 / μs每次 | 实验方法 / μs每次 | 时间减少 |
|---|---:|---:|---:|
| 只计算摩擦迭代,物性和几何系数提前准备 | 1.619 | 0.555 | 65.7% |
| 整个管流计算,包含物性准备 | 3.369 | 2.043 | 39.4% |
PNL0001/2 真正进入新迭代时平均4.40次,PNL0003平均4.08次,最多6次。用独立的100次二分求解同一方程作参照,新流量最大差约 `1.1e-13 kg/s`。
另测906组独立工况,覆盖雷诺数 `1e-6~1e9`、相对粗糙度 `0~0.1`:无非有限结果,最多7次迭代,与二分结果最大相对差 `3.62e-11`。部分工况确实触发了区间回退,最多2次。这个标量求根部分通过 `K` 与介质物性分离,因此可以复用于采用同一阻力方程的不同气体与几何参数。其他阻力模型应提供自己的残差函数和物理适用区间,不能直接套用氦气物性公式。
正式实现还应返回 `converged / iterations / residual / fallback` 等状态;超过上限时继续可靠回退或报告失败,不能静默返回未经检查的数值。
**5.完整系统能节省多少时间**
下表全部使用无性能探针的可执行程序,三轮交错运行。每个方案都运行到10 s。
| 方案 | 求解墙钟中位数 / s | 三轮范围 / s | CPU中位数 / s | 比基准减少 | 方程计算次数 |
|---|---:|---|---:|---:|---:|
| 当前生产算法基准 | 3.119 | 3.111~3.165 | 3.172 | — | 24,941 |
| 只复用完全相同输入的物性反算结果 | 2.775 | 2.772~2.807 | 2.844 | 11.0% | 24,941 |
| 直接使用对应气体状态的已知温度 | 2.599 | 2.573~2.607 | 2.672 | 16.7% | 25,493 |
| 只替换管流内部求根方法 | 2.500 | 2.496~2.508 | 2.578 | 19.8% | 24,626 |
| 已知温度复用+管流求根 | 2.102 | 2.091~2.108 | 2.172 | 32.6% | 28,164 |
组合方案虽然单次计算明显加快,方程调用次数却增加约12.9%。它改变了局部流量精度与微小舍入,BDF在这个敏感模型上的步长选择随之变化。因此,“单次管流快39%”不等于“整个系统快39%”,两个单项收益也不能直接相加。真实的完整系统收益应以上表为准。
相同输入复用方案和直接传递温度的方案是两个层次,不应叠加计算11.0%与16.7%。组合实验包含的是后一种物性方案。
**6.是否牺牲了仿真结果**
只复用相同反算输入的方案,包含事件点在内的全部输出完全一致。其余方案保持同一物理方程,但不会逐位相同,必须检查结果差异。
组合方案与基准在0.01 s公共网格上的比较,针对此前对照的72条压力、温度、位移、速度和阀口流量曲线:
| 量 | 最大绝对差 |
|---|---:|
| 压力 | 19.3 Pa |
| 温度 | 0.00586 K |
| 位移 | `2.06e-7 m` |
| 速度 | `1.78e-6 m/s` |
| 阀口质量流量 | `9.36e-5 kg/s` |
流量最大差可能发生在短暂变化附近,不能只拿最后时刻或少量输出点作结论。上述72条量的完整公共网格已经比较;与存档Amesim的回归对照另外采用原有57个指定时间点,不能将其称为每个内部积分点均一致。
与Amesim在这57个指定时间点的对照中,组合方案最大压力差约199.8 Pa、最大温度差0.01154 K;基准对应约198.3 Pa、0.00963 K。位移、速度、阀口流量差仍在同一数量级。新方案没有消除原有模型/数值差异,也没有显示出数量级上的恶化。详情按曲线存入 `accuracy.json`。
此前关注的第一个 LSTP 接口力单独比较:
- 1001个公共网格点,与Amesim存档力曲线的最大差:基准0.5770 N,组合方案0.5766 N。
- 第一次碰撞时间相对基准变化约 `−4.32e-8 s`,第二次约 `−1.52e-7 s`。
- 第一次事件的瞬时峰值从 `1.498588675e11 N` 变为 `1.498588441e11 N`,相对变化约 `−1.56e-7`。
- 另行记录内部接受的积分点后,峰值降至一半的时间均约0.348 ns,降至1%的时间均约2.336 ns。记录探针也未改变组合方案原有输出。
所以本轮加速没有跳过或删除此前发现的纳秒级力脉冲。Amesim存档在这附近没有相同密度的内部采样,仍不能据此判断其内部是否存在同样脉冲。这项既有对照限制继续保留。
这些验证支持方案继续进入正式开发,并不等价于所有模型、所有介质均已通过生产回归。
**7.建议的通用实施顺序**
1. **先补可观测性和收敛判据。** 把本轮的调用次数、迭代分布、未收敛次数、最大残差做成可选诊断,默认关闭详细计时。每条管路分别累计,便于新增模型后直接定位。改变流量算法前保存基准。
2. **将物性复用做进编译与运行上下文。** 第一步采用完整输入一致的缓存,获得本轮已证明的低风险收益;随后让编译器沿供需关系传递物性状态引用,跳过已有温度的反算。焓混合、压力改变、介质改变时重新构造状态。未来介质各自实现 `pT / ph / rho-u` 更新及可复用的派生量。
3. **统一管路标量求根器。** 将介质与几何计算形成的系数交给局部求根器,保留各管路已有的物理分支;以流量绝对误差和相对残差共同验收。区间保护、失败回退和统计接口作为公共能力,不按具体实例编号写特例。局部斜率可由阻力模型提供,缺少时仍有不依赖斜率的区间方法。
4. **合并物性中间量,再分离仅用于显示的诊断量。** 复用上游密度、热容和等熵计算中间量;验证 `h=u+p/ρ` 快路径。对雷诺数、显示速度等,编译器检查是否被其他模型或控制器使用;只有确认为纯输出时才移到采样阶段。不能一律关闭,因为新增模型可能把这些量接入反馈。
5. **逐项做系统回归,再合并收益。** 检查不同气体、正反流、等压、层流、过渡区、粗糙管、限位事件和小体积储气模型;同时保存稳态输出和事件附近内部点。每个方案单独测,再测组合,接受与拒绝步数也要记录。保持本轮所用系统雅各比矩阵策略,避免混入其他变化。
优先顺序上,建议尽快处理管流“达到上限仍返回”的行为,同时先落地完全一致输入的物性复用。前者关系到局部方程是否真的解好,后者已有逐点一致和约11%完整系统收益的证据。更进一步的状态传递与管流求根组合,已有约32.6%的隔离试验收益,可以作为第一轮正式优化的目标;不把这一百分比保证给其他模型。
**复现与文件**
所有原始记录与实验程序位于:`F:/Master/SystemSimulationApp/test/property-pipe-profile-20260911/`。
| 文件 | 内容 |
|---|---|
| `profile.py` | 核验源码哈希,构建基准、分段计时、独立计数和输入采集程序 |
| `timed/profile.json` | 各阶段独占耗时、调用次数、迭代直方图 |
| `counters/profile.json`、`counters/replay.txt` | 缓存命中机会及49,818条气体/反算/管流采集输入 |
| `experiments.py` | 完全相同输入缓存、已知温度复用、管流求根及组合方案生成器 |
| `microbench.py`、`micro-summary.json` | C重放微基准、残差、906组独立工况检查 |
| `benchmark.py`、`benchmark.json` | 无探针的三轮交错纯求解测量及逐次结果 |
| `analyze.py`、`accuracy.json` | 公共网格、Amesim存档及事件点的数值比较 |
| `trace_combined.py`、`event-validation.json` | 组合方案碰撞附近内部积分点检查 |
| `baseline/`、`cache_exact/`、`known_temperature/`、`pipe_root/`、`combined/` | 各自的C源文件、可执行程序、完整结果及日志 |
在仓库根目录,用 `.venv-win/Scripts/python.exe` 依次运行上述 `profile.py`、`experiments.py`、`microbench.py`、`benchmark.py`、`analyze.py` 可复现主结果。需要本机现有GCC及SUNDIALS开发环境。事件记录脚本会拒绝向既有记录追加,避免混合两次结果;重跑时应指定新的实验输出目录。
`/test` 按现有仓库规则被Git忽略;本报告进入文档目录。正式合入时需把通用实现和必要回归测试迁入对应源码目录,本轮实验代码不作为已经上线的功能。
@@ -0,0 +1,143 @@
# 物性复用与管流求根:实现及验证
已在 `system-optimization` 工作区将三项物性优化接入正式 C 内核:共享同一次试算的物性状态、复用等熵计算中的上游密度,以及用已有内能、压力和密度求焓。两条代码生成路径均已接入。此前验证过的管流求根方案也已一并落实。
最终版本中,MQL4 的纯求解中位耗时从 **3.138 s 降至1.391 s,减少55.7%**;skill-test 从 **0.255 s 降至0.139 s,减少45.6%**。本机后台已启动新版本,通过真实 HTTP 流式仿真请求验证,结果与独立EXE逐点一致。本次没有提交或推送Git。
**物性状态如何共享**
每次生成的 `model_eval` 都在自己的栈上建立 `NativePropertyCache`,随后将同一个上下文传给部件和局部压力、焓闭合计算。记录保存介质参数副本、压力、温度、焓、密度、黏度,以及已算出的等熵修正系数和指数;标志位区分哪些量已经有效。
气体容腔恢复状态后,先登记已有的温度、焓和密度。管路、阀口需要温度时,按介质与精确的压力、焓查找。相同状态直接读取温度,未知状态仍使用原来的反算。需要密度、黏度或等熵修正时,仅补算缺少的量,后续计算继续复用。
这一版采用完整输入查询和共享状态引用,尚未把所有端口都静态替换成无需查询的状态指针;它已经覆盖当前两条生成路径的相关气体、阀口和管路调用。
有效性规则如下:
- 压力和焓必须精确匹配,压力、温度查询也必须精确匹配。没有“差不多就沿用”的近似缓存。
- 介质按全部数值参数核对,并保存参数副本;改变压力、焓、介质参数,都不会误用旧状态。
- 节流后的压力变化、气流混合产生的新焓,会触发新状态查询或反算。同焓不能直接推断同温度。
- 每次系统试算重新初始化缓存;不同仿真、线程和独立调用不共享可变全局缓存。没有把上一时刻的物性直接拿来代替本次试算。
- 编译器按模型规模分配16~256条记录,控制栈空间。容量满后转为正常计算,不丢失正确性。未来大规模模型可进一步改善索引与容量策略。
- 真实氦气在临界温度以下及临界温度处,保留原有气相根和PH反算路径;不把本次优化当作两相物性支持。
**两个次级机会的实现**
第一项已落实到可压缩流动函数内部。等熵修正计算出的上游密度,直接用于随后流量、流速计算。上下游状态分别保存;下游压力、温度不同就有自己的记录。同一个状态的等熵系数也可以重复使用。管路诊断中的重复黏度计算同时合并。
第二项在当前真实氦气单根区域使用 `h = u + p/ρ`。这里的 `u` 为已有比内能,`p` 为绝对压力,`ρ` 为已有密度,单位分别为J/kg、Pa、kg/m³。与本内核的内能和焓参考点一致,避免再次从压力、温度求真实气体焓。低温的原有气相根选择保留回退。理想气体已有的简单焓表达式继续使用。
这些优化没有引入物性查表、插值或额外近似。
**管流收敛修正为什么一并接入**
最初只接入全组物性优化时,MQL4仍能运行到10 s,但PNL0002_10的一条温度曲线在存档参考点的最大偏差为0.019965 K,超过现有0.015 K门槛。分项试验表明,极小的物性数值变化会改变BDF的试算路径;结合前一轮“管流几乎总达到16次上限”的证据,不能把这个完整系统偏差简单解释为物性公式算错,也不能只保留更快的计时。
因此一并接入此前试验的管流求根方案,并保持原有曲线门槛。最终完整1001个公共时间点上的最大温度差为0.009901 K,通过验收。上述分项结果保留在 `decomposition.json` 和 `final-benchmark.json`,未以放宽误差门槛代替修正。
管流仍使用原有可压缩关系、摩擦系数混合公式、流向和近平衡平滑。内部将流量关系整理为 `Re² × f(Re) = K`,使用带区间保护的局部Newton求根;越界则二分回退。PNL00R原有的直接层流分支保留。
返回前会在实际返回点检查方程相对残差,要求不超过 `1e-9`,同时使用局部流量变化判据。接口 `native_pipe_resistance` 可返回收敛状态、迭代次数、二分回退次数和残差;异常输入或达到上限仍不合格时返回非有限失败值,交由现有模型有效性检查拒绝,不再静默接受未收敛的流量。
这里仅使用管流内部一个标量关系的斜率。系统雅各比矩阵策略、BDF/RK45积分器和模型误差设置均未调整。
**实测耗时:完整系统与分项对照**
性能测试使用独立EXE,关闭性能探针,三轮交错运行并取中位数。只统计C求解过程,不含Python前处理、编译、进程启动、结果输出、网页传输或绘图。全部运行至10 s。
MQL4:BDF,相对误差限 `1e-7`,最大积分步长 `1e30`,其余状态绝对误差限沿用生产配置。
| 方案 | 求解中位耗时 / s | 三轮范围 / s | 方程调用次数 | 说明 |
|---|---:|---|---:|---|
| 修改前基准 | 3.138 | 3.126~3.175 | 24,941 | 原有物性和管流迭代 |
| 仅局部密度、黏度去重 | 3.027 | 3.021~3.108 | 24,941 | 全部时间及输出序列逐点完全一致 |
| 全组物性优化,保留旧管流迭代 | 1.974 | 1.973~2.030 | 24,612 | 温度参考门槛未通过,不作为最终版本 |
| 最终组合,但关闭焓直接计算 | 1.518 | 1.514~1.611 | 24,481 | 用于评估第二个次级机会 |
| 最终组合:全部物性优化+管流求根 | **1.391** | **1.382~1.456** | **24,262** | 完整曲线验收通过 |
局部密度、黏度去重单独减少约3.5%完整系统耗时;在最终组合中加入焓直接计算,耗时从1.518降至1.391 s,进一步减少约8.4%。后一项也伴随试算路径变化,因此不是单纯的函数微基准。两项与主物性复用、管流求根存在重叠,不能将各百分比直接相加。
skill-test采用仓库 `tests/data/native-skill-test.xml`,这是之前skill-test模型的回归输入;RK45、最大步长0.001 s、相对误差限 `1e-7`:
| 方案 | 求解中位耗时 / s | 方程调用次数 | 接受步数 |
|---|---:|---:|---:|
| 修改前 | 0.255 | 60,278 | 10,022 |
| 最终版本 | 0.139 | 60,278 | 10,022 |
skill-test的计算次数和步数相同,这一组能更直接地反映每次物性计算变轻带来的收益。它没有MQL4中的管路网络,因而也验证了物性优化在另一种模型和积分器下的效果。
**计算次数确实减少了多少**
另行构建只加计数、不用于性能比较的程序,限定在系统方程回调内计数,排除初始化和输出重算。计数版的全部序列分别与对应无探针版本完全一致。
| MQL4求解中的计算 | 修改前 | 最终版本 |
|---|---:|---:|
| 真实气体状态方程求根 | 6,202,660 | 690,869 |
| 压力、焓反求温度 | 646,040 | **0** |
| 黏度计算 | 1,626,172 | 333,213 |
| 摩擦系数普通计算函数 | 8,285,496 | 1,360,592 |
最后一行只统计普通摩擦系数函数。新Newton步骤还会在“摩擦系数及其斜率”联合函数中计算摩擦关系,因此不能据此声称全部摩擦计算工作减少了同样比例;管流性能应以上面的完整计时及独立求根验证为准。
PH反算降至0,仅说明本模型的请求都能找到本次试算的已知状态。对压力变化、焓混合、其他模型和不适用快路径的低温工况,反算功能仍然存在。
**曲线、守恒和事件验证**
与此前官方重新编译的四支路Amesim存档比较,72条压力、温度、位移、速度和阀口流量曲线使用完整1001个共同输出时间点。没有重跑Amesim或重新解读其内部算法。
| 量 | 最大绝对差 | 原有验收门槛 |
|---|---:|---:|
| 压力 | 199.863 Pa | 250 Pa |
| 温度 | 0.009901 K | 0.015 K |
| 位移 | `7.49e-7 m` | `2e-6 m` |
| 速度 | `2.64e-6 m/s` | `1e-5 m/s` |
| 阀口质量流量 | `1.55e-5 kg/s` | `3e-5 kg/s` |
闭合气路总质量最大漂移约 `1.33e-14 kg`。
LSTP四个接口力另行比较。第一个接口力在共同网格上与Amesim的最大差为0.6135 N;四个接口中最大差为1.123 N。新增事件点未并入普通网格误差,以免把瞬时峰值插值成虚假的长三角形。
首次碰撞时间为1.201137461445 s,峰值约 `1.49858577e11 N`,相对修改前的峰值变化约 `−1.94e-6`。另行记录内部接受的积分点:峰值降至一半约0.348 ns,降至1%约2.336 ns。事件记录不改变最终输出序列,先前发现的极短脉冲没有被省略。Amesim存档缺少同等密度的内部采样,仍不能由本次验证断言其内部是否存在同一脉冲。
skill-test的输出时间序列一致,最大压力差约 `1.70e-7 Pa`,最大温度差约 `2.39e-12 K`;所检查的位移、速度和力序列完全一致。
**后台已生效**
检查时本机8000端口无运行中的服务,随后以当前工作区启动后台。启动日志确认数值引擎为 `native`。真实请求:
`POST http://127.0.0.1:8000/api/system-xml/simulate-stream`
此次请求完成0~10 s,C纯求解1.507 s,HTTP全程3.967 s,收到21个进度事件。HTTP时间包含前处理、进程启动、输出序列化及传输,不能与纯求解时间等同,也未包含浏览器绘图测量。
后台返回的构建标识为 `9fdd91da210e189d1e44de686d6109bbdb5be56c284450b41364486160bfe494`,与最终独立EXE相同;全部时间和输出序列逐点一致。后台日志、启动进程号及HTTP结果均保存在实验目录。
**回归与通用性边界**
最终完整复核命令的25项相关测试在23.898 s内全部通过(`regression-final.log`),包含:
- 50组元件网络的冻结物性参考、守恒及未改变模型的完整参考对照;两条代码生成路径。
- BDF、RK45、原生后端默认路径,以及不依赖NumPy/SciPy的编译导入路径。
- 缓存跨试算失效、独立上下文、容量耗尽回退、一个浮点单位的压力变化、焓变化及每个介质参数变化。
- 真实氦气与含温度相关热容的理想气体,在100~1000 K、`1e4~1e8 Pa`的状态往返检查,以及低温氦气保留原有路径的检查。
- 管流求根的2718组工况:雷诺数 `1e-6~1e9`、相对粗糙度0~0.1,三个不同流量尺度;均与独立100次二分求解比较。检查返回残差、区间回退、非法输入失败、零流量和PNL00R层流分支。
- 独立压力回路与直接支路组合前后的结果隔离、流向反转、焓混合回路,以及MQL4的已有曲线验收。
旧冻结参考中的PNL流量包含原先迭代达到上限的值。现在所有PNL共用检查残差的求根器,因此保留这些网络的独立物性与守恒参考,并由独立二分、管路物理测试和Amesim系统曲线验证流量;没有要求新算法重现旧的未收敛迭代值。
一次目录复测曾有两个短进程的 `--init` 返回空标准输出;随后这两个进程各自连续5次核验正常,50组目录整套复测也通过。未为此增加忽略错误或自动重试逻辑,原始与复测日志均保留。
**代码与复现记录**
- C接口与实现:`native/include/kernels.h`、`native/components/kernels.c`。
- 生成与上下文传递:`app/simulation/native_codegen/compiler.py`、`extended.py`、`schedule.py`。
- 新增及更新测试:`tests/test_native_properties.py`、`test_native_pipe_physics.py`、`test_native_catalog.py`。
- 本次数据:`test/property-implementation-20260911/`,包括 `final-benchmark.json`、`counter-audit.json`、`http-and-curves.json`、`event-audit.json` 及完整结果、源文件、EXE和日志。
- 前一轮剖析与原型:`test/property-pipe-profile-20260911/`,原报告保留为历史测试记录。
复核命令:
```powershell
./.venv-win/Scripts/python.exe -m unittest tests.test_native_properties tests.test_native_pipe_cache tests.test_native_pipe_physics tests.test_native_codegen tests.test_native_schedule tests.test_native_catalog tests.test_native_only_backend -v
```
实验记录和生成EXE遵循现有 `/test` 忽略规则;正式实现、测试和文档位于受版本管理的目录。本次未修改用户输入JSON、Amesim文件或前端模型参数。