前端进度条性能优化、仿真结束后后处理优化;后端C代码生成流程优化:先识别来源,再按照已知未知量需求排序,最后局部求解

This commit is contained in:
ljz committed 2026-09-11 11:27:54 +08:00
1 parent 0dcb465d84
commit 91bd9fb252
77 files changed
+11223 -551

No files matched your search

@@ -0,0 +1,135 @@
# Amesim 与 C 计算顺序差异核查
日期:2026-09-10。分支:`system-optimization`;核查时提交:`0dcb465`。
本次对照当前 `tests/data/test-mql-8.json`、Amesim 2404 的生成代码和本机组件源码,并在 `test/amesim-order-study/` 中进行独立实验。正式模型、C 生成器、数值内核、积分器和雅可比策略均未修改。
## 结论与先前判断的修正
1. **这个 JSON 没有执行节点压力二分循环。** 实际编译得到 48 个压力组、48 个储气状态压力锚点,待求节点压力为 0。此前从通用生成器看到的“256 轮压力协调 × 每节点 48 次二分”分支不适用于本例。
2. **四通节点的参考口连接语义与 Amesim 存在偏差。** 8 个四通节点中只有 1 个直接接到相应储气状态端,另外 7 个的参考口接法不同,其中 3 个会引入流量与比焓的相互依赖。单纯把这些循环算快,不能解决与 Amesim 模型语义不一致的问题。
3. **当前生成器缺少热力变量的依赖排序。** 即使参考口修正,原生成器仍然运行全网流量/焓传播循环。实验中可以在编译时排好顺序,将全网流量计算降至每次状态求值 1 次,并移除该副本的全网焓迭代。
4. **管道内部的数值迭代是另一层问题。** 诊断中常见的是 PNL0001/2 流量函数的 16 次迭代耗尽;全网焓迭代并未耗尽上限。
## Amesim 为什么可以顺序计算
生成文件 `F:/CO2Project/Amesim/test_maql/test_mql_.c` 声明 132 个显式状态,声明隐式状态和生成隐式状态均为 0。文件第 10427 行说明部件按照满足输入依赖的顺序调用;三通、四通节点没有运行时计算函数调用,它们通过变量复用和加法展开。
其气动部件主要交换两类量:
- 储气部件提供当前压力、温度;管道和阀门据此计算质量流率、能量流率。
- 节点从参考口取得压力、温度并传给其他端口,把其他端口的质量流率和能量流率相加后送回参考口。
PN3NODE2/P4NODE2 的参考口是 **port 2**。这是一项固定的计算接口关系,与气体当时向哪个方向流动是两回事;交换参考口与其他口可能改变模型。
在该 Amesim 模型中,8 个四通节点的参考温度、压力全部直接复用 PNL0001 的储气状态。已将 `.var` 中的共享变量位置与生成代码 `GcontStateVarNum` 核对,确认对应项属于连续状态,而非仅根据图形位置推测。
| Amesim 节点 | 参考温度/压力所属管道 |
| --- | --- |
| pnnode4_16 | pneumatic_69 的 t2/p2 |
| pnnode4_17 | pneumatic_68 的 t2/p2 |
| pnnode4_18 | pneumatic_66 的 t2/p2 |
| pnnode4_19 | pneumatic_65 的 t2/p2 |
| pnnode4_20 | pneumatic_72 的 t2/p2 |
| pnnode4_21 | pneumatic_73 的 t2/p2 |
| pnnode4_22 | pneumatic_74 的 t2/p2 |
| pnnode4_23 | pneumatic_71 的 t2/p2 |
此时,温度/压力向支路传递,质量/能量流率向储气部件汇总,最后计算状态变化率。通过储气状态隔开了不同计算阶段,不需要先迭代求出所有连接量。
这里的显式系统仍可使用 BDF 等隐式积分方法;零系统隐式状态也不表示物性函数、管流函数或积分器内部绝无迭代。
## 当前 JSON 的具体偏差
当前网络有 156 个运行部件、178 条连接、132 个状态、1784 个输出、232 个气动端口。Amesim 部件与管线展开后,各数值组件类型数量与该 JSON 一致;数量一致不足以保证参考口关系一致。
| JSON 四通节点 | 当前 port_2 接到 | 独立实验中接到的对应储气端 |
| --- | --- | --- |
| amesim_p4node2_1 | amesim_pnl0001_13.port_2 | 原连接已满足 |
| amesim_p4node2_2 | amesim_pnvo001_2.port_2 | amesim_pnl0001_14.port_2 |
| amesim_p4node2_3 | amesim_pnvo001_3.port_2 | amesim_pnl0001_15.port_2 |
| amesim_p4node2_4 | amesim_pnvo001_4.port_2 | amesim_pnl0001_16.port_2 |
| amesim_p4node2_5 | amesim_pnl0001_21.port_1 | amesim_pnl0001_17.port_2 |
| amesim_p4node2_6 | amesim_pnl0001_25.port_1 | amesim_pnl0001_18.port_2 |
| amesim_p4node2_7 | amesim_pnl0001_26.port_1 | amesim_pnl0001_19.port_2 |
| amesim_p4node2_8 | amesim_pnl0001_27.port_1 | amesim_pnl0001_20.port_2 |
实验只在工程副本中交换后 7 个节点的 port_2/port_3 连线,让参考口连接到同一压力组中的储气状态端。物理支路数量、参数和动态状态没有增加。
对于 `_2/_3/_4`,当前 C 计算存在以下潜在反馈:
```text
阀门流量需要入口比焓
↓
入口比焓来自四通节点 port_2 的能量平衡
↓
该能量平衡又用到阀门流量
```
是否实际激活反馈还与流向有关。给低压侧供气时,阀门可使用另一侧已知比焓;反向流时则可能需要节点返回的比焓。本次反向流诊断使当前全网焓迭代从通常的 3 轮升至 10 轮。
编译时追踪显示:当前流量表达式读取 48 个端口比焓,其中 3 个无法仅由储气状态和简单赋值提前确定,正是 `_2/_3/_4.port_2`。调整参考口后的副本中,这 48 个输入全部可提前确定。
Python 元数据把这些气动端口都声明为 `bidirectional`。目前连接校验主要检查领域、端口占用和物理连接合同,没有针对该 Amesim 子模型检查“参考温度应由谁提供”的因果关系,因此能够接受这种与原 Amesim 接法不同的工程。
## 即使连接修正,为什么旧循环仍然存在
`extended.py` 先把无储气状态端口的比焓初始化为默认气体比焓,再按部件在网络中的顺序执行:
```text
计算全网流量 → 更新全部端口比焓 → 检查变化 → 必要时重复
```
它没有先区分:哪些比焓只需要复制已知状态,哪些流量依赖这些复制结果,哪些能量输出应在流量确定后再计算。全网焓循环结束后还额外计算一次全网流量。
在独立副本中,提前排序这些关系即可生成:
```text
恢复储气状态的物性
→ 传递流量计算所需的参考比焓
→ 计算一次全网流量
→ 按依赖顺序计算其余比焓和节点能量输出
→ 计算导数与展示输出
```
这说明质量/内能状态和比焓端口形式本身并不必然要求全网迭代。它们会增加局部物性反解的成本,但正确的连接和计算顺序仍可以消除本例的全网闭合循环。
## 独立实验结果
三个版本均为独立编译的 C 诊断程序:原模型及原生成器、仅调整参考口的模型及原生成器、调整参考口并按依赖顺序生成的模型。管道公式、误差阈值与物性函数保持相同。
使用初始状态、12 组质量/内能扰动状态,以及 1 组反向阀流状态,共 14 组。它们是用于检验依赖关系的状态点,不能作为完整 10 s 轨迹或 Amesim 曲线对齐的替代品。
| 每次状态求值的工作量 | 原模型 | 仅调整参考口 | 调整参考口并顺序计算 |
| --- | ---: | ---: | ---: |
| 常规诊断状态:全网焓循环 | 3 | 3 | 0 |
| 常规诊断状态:全网流量调用 | 4 | 4 | 1 |
| 反向流诊断:全网焓循环 | 10 | 3 | 0 |
| 反向流诊断:全网流量调用 | 11 | 4 | 1 |
后两个版本在全部 14 组状态的 **132 个导数与 1784 个输出上逐值完全一致**。这项对照隔离了计算顺序变化的影响。它没有比较“修正前后应该相同”:参考口修正确实会改变多个状态点的数值结果,必须按模型修正处理。
本次未进行新的 Amesim/EXE 全程速度或曲线比较。诊断文件中的单次微秒计时含计数开销,不能外推为完整仿真的加速倍数。
## 真正达到迭代上限的地方
本例生成的全网焓循环上限是 928 轮。本次 14 组状态中,原模型最多执行 10 轮,触顶次数为 0;节点压力二分没有生成。
在 12 组普通扰动状态中,每次原模型求值调用 PNL0001/2 支路流量 144 次,144 次均执行满内部 16 轮。顺序版本将该调用数降至 36 次,但这 36 次仍执行满 16 轮。当前函数耗尽循环后返回最后的近似流量,没有将其标记为不收敛错误。
PNL0003 两个储气状态之间的 Darcy 流量则使用固定 48 次二分。本例每次状态求值有 8 次此类管流计算,压力差非零时执行这些局部二分;这与“未知节点压力二分”不同。
因此,优化顺序应是:先对齐节点参考口语义并增加相应检查,再生成正确的静态计算顺序,随后单独检查管道内部的收敛判据和求根算法。管流近似对 BDF 数值差分和小步推进的影响仍需进一步量化;本次不对其贡献比例作结论。
## 证据与复现
- 结构快照和源文件哈希:`test/amesim-order-study/structure.json`。
- Amesim 状态索引与四通节点参考来源:`test/amesim-order-study/amesim-evidence.json`。
- 独立模型副本:`test/amesim-order-study/reference-port-experiment.json`;正式测试输入未覆盖。
- 14 组状态、计数和逐值差异:`probe-cases.json`、`probe-comparison.json`、`*-probes.jsonl`。
- 复现脚本:`.venv-win/Scripts/python.exe test/amesim-order-study/study.py`。
- 当前生成器:`app/simulation/native_codegen/extended.py:261`(物性)、`:362`(未知压力)、`:386`(焓传播)、`:409`(全网循环)。
- 当前管流:`native/components/kernels.c:246` 起;固定 48 次二分和 16/64 轮固定点迭代分别处理不同管流模型。
- Amesim 组件依据:`F:/amesim2404/amesim/libpn/submodels/PN3NODE2.c`、`P4NODE2.c`、`PNL0001.c`、`PNL0002.c`、`PNL0003.c`、`PNVO001.c`。
实验输出保存在 Git 忽略的 `/test/` 下。报告不复制 Siemens 组件实现;相关文件需使用本机已有 Amesim 安装读取。
@@ -0,0 +1,88 @@
# C 计算依赖排序验证(2026-09-10)
在 `system-optimization` 分支完成已知来源识别、依赖排序和局部循环划分,接入默认 C 编译入口使用的扩展生成路径。未修改管路内部求根、积分器、雅可比策略或用户模型接线。
## 本轮实现
| 原有处理 | 当前处理 |
| --- | --- |
| 对非储气端口先填默认焓,靠全网循环传递已知量 | 记录当前状态/已准备信号和物性的来源,参考量按依赖传递;初始猜测不作为已知来源 |
| 全网流量与端口焓反复更新 | 将流量、连接方程和焓传递拆为计算条目,按实际输入输出关系排序 |
| 一个未知量试算会刷新全网流量 | 自动划分局部循环;压力试算只刷新本块残差所需的关系 |
| 压力范围和焓初值使用全网信息 | 局部块使用自身已有压力边界和外部已知焓来源 |
图算法不依赖模型名称、组件实例顺序、画布方向或固定气体流向。节点参考别名与能量返回计算分离;常系数流量约束消元得到的表达式也参加排序。构建清单新增 `evaluationSchedule`,列出来源、计算条目和循环块,便于核查。
当前机械、信号、容积与气体物性准备阶段继续执行原有确定顺序;新图处理的是扩展生成器原先需要全网闭合的气动计算。紧凑储气拓扑原本已顺序计算,继续保留。没有恢复旧 Python 数值实现或旧 IR。
## 修正参考口模型
输入使用已有独立副本 `test/amesim-order-study/reference-port-experiment.json`。正式 `tests/data/test-mql-8.json` 和浏览器工程均未覆盖。对照 EXE 是上一轮已经包含管流精确输入缓存与粗糙度常量预计算的版本,因此本轮比较隔离了计算排序的影响。
- 132 个状态、1784 个输出;编译后形成 484 条气动计算关系,系统代数循环块为 0。
- 使用原有 14 组初始/扰动/反向状态,再逆序重访并重复前两组,共 30 次求值。两版全部成功,每次的全部导数与输出逐值一致。
- 独立插入执行计数后,30 次求值中每条计算关系均执行一次;计数不进入生产代码或计时版本。
### 相同时段的 BDF 对照
两版均使用 CVODE BDF、相对误差限 1e-7、最大积分步长 1e30 s。保持已有绝对误差策略,不绘图、不调用网页端。
| 指标 | 排序前 | 排序后 |
| --- | ---: | ---: |
| 完成的仿真时段 | 0~0.02 s | 0~0.02 s |
| 采样间隔 | 0.002 s | 0.002 s |
| 纯求解耗时(单次验证) | 2.368098 s | 1.645752 s |
| 求值次数 | 5123 | 5123 |
| 接受步数 | 169 | 169 |
| 拒绝步数 | 5 | 5 |
两版最终状态和完整采样序列逐值一致,单次耗时减少约 30.5%。这是相同时段的功能与耗时对照;当时另有回归验证任务运行,因此另用下述独立微基准检查提速幅度。
更短的 0~0.002 s 对照同样逐值一致,均为 304 次求值、25 个接受步和 1 个拒绝步。
### 独立 C 状态求值计时
使用同一批 14 组状态,在 C 内重复 200 次,共 2800 次系统求值;输入读取、进程启动、编译与输出写出不在计时内。两版各预热一次,交替计时 5 轮,取中位数:
| 排序前 | 排序后 | 加速倍数 |
| ---: | ---: | ---: |
| 1.686816 s | 1.156371 s | 1.459 |
计时版本不含诊断计数,校验和一致。这是状态求值的局部基准,不能直接代表任何模型的完整仿真倍数。
### 长时段验证的边界
尝试仿真到 10 s,每版限制执行 30 s:排序前推进到 0.0741618 s,排序后推进到 1.8645395 s,两版均返回执行超时。共同的 0、0.02、0.04、0.06 s 采样点逐值一致,但本轮没有取得完整 10 s 曲线对照。
另一次仿真终点为 0.06 s、采样间隔 0.002 s 的检查中,排序前在 30 s 限额内推进到 0.0487527 s,排序后用 25.022361 s 完成。共同的 25 个采样点逐值一致;将排序后该段全部 31 个采样状态分别送入两版 EXE,全部导数与输出也逐值一致。该次两版完成范围不同,不作为整段加速倍数。
上述不同采样/终点设置会影响积分运行,不能把两次计时直接混用,也不能用相同执行时间推进的仿真时长之比宣称提速。管流内部迭代及刚性积分的成本仍在,本轮未处理这两项。
## 通用性验证
- 2000 层逆序输入的依赖链正确排序并追溯到状态来源,不使用 Python 递归。
- 缺失来源、重复提供者、无来源的纯别名环均拒绝编译。
- 两个独立串联阻力压力循环与一个直算支路组合后,循环内各流量计算次数与独立运行相同;直算支路每次只执行一次。正反流及状态重访的结果均逐值一致。
- 打乱四通节点模型的组件和连接顺序后,仍无系统循环,各条目仅执行一次。常系数消元的求和顺序变化只产生浮点舍入级差异,使用远严于冻结基准的容差验证。
- 三支路的压力与混合焓耦合模型保留一个局部块;正反流、零压差与状态重访均通过质量/能量守恒检查。
- 现有 50 个冻结网络通过 C 数值对照;管流缓存、两种积分器、接口供需及编译入口的定向回归通过。
- `tests/data/native-skill-test.xml` 的 `skill-test` 回归完整完成 10 s,RK45 最大步长 0.001 s、rtol 1e-7,预热后单次纯求解 0.450283 s。它走原有紧凑路径,作为兼容性检查,不用于声称排序收益。
定向回归共 29 项通过。后端全量运行 276 项:首次 274 项通过、1 项锁定环境检查跳过、1 项因编译器版本查询返回空输出出错。重跑冻结网络时又有一次 EXE 初始化返回空输出;这两次均未触发数值不一致断言。受影响的网络 5 和 40 随后使用原冻结期望值单独复核通过。没有为此改动生产进程处理、冻结基准或数值容差;本次全量运行不能表述为一次全部通过,原始限制在此保留。
源文件与模型接入要求见 [C 求值排序规范](../standard/native-evaluation-schedule.md)。本轮条件表达式按所有可能分支保守记录依赖,尚未进行运行时流向特化;局部压力/焓求解保留既有方法,未宣称支持任意新非线性方程。
## 复现材料
`test/dependency-schedule-study/` 按仓库约定被 Git 忽略,包含:
- `baseline-build.json`、`scheduled-build.json`:两版 EXE 与构建清单。
- `schedule.json`、`model.c`:正式生成器输出的依赖清单与 C 源码。
- `verification.json`、`*-probes.jsonl`:30 次逐值验证。
- `benchmark.json`:5 轮交替计时及校验和。
- `integration-comparison*.json`、`bdf-*/result.json`:积分统计与原始序列,包括未完成的超时运行。
- `trajectory-probe-check.json`:长段共同采样及采样状态的求值对照。
- `skill-test/summary.json`:完整 `skill-test` 回归结果。
- `study.py`:`verify`、`benchmark`、`integrate`(0.002 s)、`short`(0.02 s)、`matched`(0.06 s)、`full`(10 s)模式;积分复现需选择新的输出目录,不能覆盖已有运行结果。
自动回归位于 `tests/test_native_schedule.py`,不依赖上述临时材料;纯依赖图测试已加入 Linux 合同检查,完整 C 执行测试由 Windows 数值回归自动发现。
@@ -0,0 +1,92 @@
**test-mql-4 仿真对照与耗时分析(2026-09-11)**
后续状态:本报告所述 C 修正已于 2026-09-11 合入正式网页后端,并完成重启及 HTTP 仿真核验,详见 [合入记录](../update-log/更新日志-2026-09-11.md)。以下正文保留合入前的实验过程与结论;其中“未合入正式内核”描述的是当时状态。
新增核查:后续直接查看网页 LSTP00A 接口力时,在额外保存的碰撞事件点发现约 1.50×10¹¹ N 的纳秒级瞬态峰。它不在本报告的 0.01 s 共同采样点对照范围内;不能把下面的曲线接近结论扩展为所有事件点输出一致。完整曲线、采样差异与内部步诊断见 [网页接口力对比报告](test-mql-4网页仿真与LSTP00A接口力对比-2026-09-11.md)。
在 `system-optimization` 分支工作区开展测试。原始 JSON 不能直接运行;修正参考口后,现有 C 内核仍在后半段陷入极小步长。测试副本经过参数对齐、管路计算修正和质量绝对误差限调整后,能够完整算到 10 s。最终验证版与 Amesim 的主要曲线接近,但仍有下面列出的局部差值,不能称为逐点完全一致。
本次只在 `/test/mql4-20260910` 中生成实验程序和数据;未将实验修改并入正式 C 内核,未改网页,未改雅各比矩阵算法,也未提交或推送。原始两个输入文件的 SHA256 复核通过,均未修改。
测试来源为 `F:/Downloads/test-mql-4.json` 和 `tests/data/test_mql_4.ame`。模型均为四支路气动机械系统;按元件类型和连接拓扑匹配后,均为 81 个元件、90 条连接、64 个动态状态。其中 26 个气体容腔产生 52 个状态,6 个质量块产生 12 个状态。Amesim 采用压力、温度状态,C 采用质量、内能状态;比较时转换到相同物理量。全部分支的元件对应关系保存在 `topology-mapping.json`。
**先解决输入和测试条件。** 原 JSON 的 `amesim_p4node2_2/3/4` 分别把 2 号参考口接到了阀门,3 号支路口接到了储气管端。供需校验报告 `CONNECTION_VARIABLE_SUPPLY_MISSING`,这是实际模型接线错误。仅在副本交换这三个节点的 2、3 号口,共修正六个端点;详见 `connection-corrections.json`。
AME 包内带有旧八支路结果和 C 源文件缓存。通过本机 Amesim 官方 API 重新编译运行四支路图纸后,EXE 日志确认 `64 unknowns`,新结果包含 0~10 s。对比采用这批新结果,未使用旧结果。归档 `.c` 缓存没有随本次保存更新,不能用它证明本次运行的代码结构;本次 Amesim 侧的依据是官方重编译、EXE 运行日志和新变量/结果文件。
AME 实际保存的积分设置为固定步长。测试副本已通过官方 API 改为 Standard 变步长、误差限 1e-7、最大步长 1e30、动态运行、不接续旧状态。JSON 的 BDF/max_step=1e30 被保留,rtol 显式设为 1e-7;当前网页后端默认 rtol=1e-6,因此不能用默认值冒充已对齐设置。两边输出间隔均为 0.01 s。Amesim 实际使用的自动算法和统计仅记录,不将复现 Amesim 求解算法作为本次目标。
此外有五处参数差异,按 AME 当前实际参数/初始值修正 JSON 副本:
| JSON 元件 | 参数 | 原 JSON | AME 对应值 |
|---|---|---:|---:|
| amesim_pnl00r_4 | 直径 | 14 mm | 10 mm |
| amesim_pnl0002_10 | 直径 | 20 mm | 10 mm |
| amesim_pnl0002_10 | 长度 | 2 m | 1 m |
| amesim_pnl0002_10 | 相对粗糙度 | 0.00225 | 0.00001 |
| amesim_pnl0002_10 | 初始绝对压力 | 100000 Pa | 101301.013 Pa |
最后一项不是 1.013 bar:AME 实际保存的 `pctr` 是表压 1.013 Pa,加环境压力 101300 Pa 得到 101301.013 Pa。交付文件为 `test-mql-4-corrected.json`,与实验输入 `test-mql-4-amesim-aligned.json` 和最终打包副本 `final/input.json` 内容相同。该 JSON 包含接线及参数修正,C 公式与质量绝对误差限的修改保存在实验程序中,不属于 JSON 内容。初次只比较气罐、气缸和机械量时未发现该差异;扩大到全部 64 个状态量后识别并修正。
**运行失败与其原因。** 仅修正接线、保留原 C 算法及 JSON 参数,BDF/rtol=1e-7 运行 120 s 后停在 4.926982415 s;已接受 285780 步、调用模型 651838 次。它是超时退出,并非已完成或进程崩溃。另一次 30 s 的诊断运行显示,约 4.9 s 后步长降至 7.23e-8~1.59e-7 s,主要控制误差的状态是 PNL0003 管内气体质量/内能。超时回调使 RHS 返回失败后,CVODE 会附带线性系统/Jacobian 失败日志;不能把这种派生日志误判为另一个独立的雅各比崩溃。
把五处参数中的前四处对齐,但保留原管路算法,40 s 内也只推进到 4.720248930 s,说明参数差异与慢速问题并不是同一件事。此阶段初始压力差异尚未修正,原始记录保留在 `matched-original`。
C 的 `PNL0003` 用了独立 Darcy 压降反求、固定 48 次二分;现有其他气体管路采用可压缩流量关系。在接近平衡时,前者的流量对很小的压差过于敏感,给积分器造成很快的局部动态。只把 PNL0003 切到项目已有可压缩流量关系的实验中,同一份只修正接线的模型便在 18.03 s 墙钟内跑完 10 s,接受步数降至 9074;这验证了管路公式是主要卡顿来源之一,并不表示只减少二分次数就能获得相同效果。
最终 C 验证版还让 PNL0001 按流动方向选择上游温度,并统一氦气管路流量计算和诊断使用的黏度表达式。原实现存在“一个用途使用 Sutherland,另一个用途使用 NASA 表达式”的不一致。它们是物理输入/计算一致性修正,不是全局求解顺序调整。各项实验的源文件和统计均保留;没有据单次速度变化声称某一项具有普遍的固定加速比。
另一个已验证问题是小管腔质量状态的绝对误差限。旧 C 对所有气体质量和内能状态都给 1e-8(各自 SI 单位)。对质量只有约 1e-5~1e-3 kg 的小容腔,1e-8 kg 会盖过 rtol=1e-7,允许的相对质量误差远大于 1e-7。两边名义 rtol 相同,不代表压力/温度精度相同。
在相同已对齐模型和管路公式上,仅把质量绝对误差限调为 1e-14 kg,保留能量 1e-8 J、速度/位移 1e-12,模型调用从 61246 降到 24941,线性化触发的模型调用从 48960 降到 16768。阀流量最大差从 0.1652 g/s 降至约 0.0160 g/s,9.53~9.58 s 附近的异常小流量尖峰明显降低。更严格的容腔质量控制在此模型上改善了稳定性,反而更快;1e-14 kg 是本次试验值,不能直接作为任意尺寸新模型的统一默认值,应按容腔尺度定义误差权重。
**曲线对比。** 在共同的 1001 个采样时间点比较 64 个状态对应的物理量,并补充 8 条孔口/阀流量,共 72 条曲线。压力统一为绝对压力;AME 的 g/s 转为 kg/s,并按端口流入/流出约定处理符号。没有绘图。最终验证版的最大绝对差为:
| 量 | 最大绝对差 | 对应量 | 时间 |
|---|---:|---|---:|
| 位移 | 0.646855 μm | `amesim_mecmas21_9.x` | 1.22 s |
| 速度 | 3.41015 μm/s | `amesim_mecmas21_9.v` | 1.22 s |
| 压力 | 198.27 Pa | `amesim_pnl0001_14.p` | 0.05 s |
| 温度 | 0.00962632 K | `amesim_pnl0002_1.T` | 0.08 s |
| 质量流量 | 0.0160272 g/s | `amesim_pnvo001_3.port_2.m_flow` | 1.89 s |
主要储气罐和气缸的压力差比表中管路局部压力峰值更小。位移末值停在规定的 -0.72 m 和 0.37 m。882 个输出序列全部有限,完整输出含两个碰撞事件点共 1003 点;闭合气路总质量初值为 2.78334124184 kg,全程最大漂移 8.44e-15 kg。三次重复 C 运行的完整序列及最终状态逐值相同。
原来主要腔室约 50 kPa 的差异,在参数对齐后降到几十 Pa,主要差异可归因于输入参数。仍有约 198 Pa 的管内短时偏差;收紧质量绝对误差限后这一峰值基本没有变化,因此不能用质量容差解释所有剩余偏差。两边还有管路阻力近似、物性计算和积分/事件处理的差别;本次没有逐项证明这 198 Pa 的唯一来源,也未建立“所有输出逐点满足 1e-7 相对差”的验收结论。接近零流量时应使用绝对误差或工作范围归一化,不能只看瞬时相对百分比。
还做了一次针对管内迭代上限的独立检查:在最终版本基础上,把相应管流求解的最大迭代次数从 16 提高到 64,仍得到约 200 Pa 的最大压力差、0.00991 K 的最大温度差。增加迭代次数没有消除该局部偏差,不能把剩余差异直接归因于这个迭代上限。该诊断保存在 `matched-v4-pnl3-compressible-upstream-viscosity-nasa-mass-atol-tight-pipe`,最终交付和计时仍采用 v3。
**速度对比。** 最终版本与 Amesim 在同一台机器交错运行各三次,取中位数。下表的主要速度指标是各程序报告的求解 CPU 时间,编译和进程启动不计入;另外列出进程墙钟供核对。结果序列保存一致,未涉及网页或绘图。
| 项目 | Amesim 当前图纸重编译版 | 最终 C 验证版 |
|---|---:|---:|
| 完成仿真时间 | 10 s | 10 s |
| 求解 CPU 中位数 | 1.14062 s | 4.01562 s |
| 进程墙钟中位数 | 4.1550 s | 6.5606 s |
| 接受积分步数 | 2456 | 5137 |
| 程序报告的模型/函数计算次数 | 33143 | 24941 |
| 程序报告的 Jacobian 计算次数(仅记录) | 382 | 262 |
C 的纯求解墙钟中位数为 4.4412 s;求解 CPU 比值约为 3.52。进程墙钟包含启动、授权、结果整理与写文件,不能拿它替代求解时间。两套程序的函数统计口径并不保证一次调用执行同样多的工作,不直接用调用数相除推导单函数性能。原 C 没有完成全程,因此不报告“原 C 完整运行耗时”或从仿真推进比例外推完整速度。
**C 内部的耗时证据。** 另编译一个只加计数/计时的版本,按嵌套调用排除重复计时;以下占比的分母是 C 模型 RHS 计算时间。该诊断运行不作为上述正式计时结果。
| 计算 | 次数 | 模型 RHS 时间占比 |
|---|---:|---:|
| model_eval | 24,941 | 5.72% |
| native_pipe_flow | 548,702 | 49.39% |
| native_medium_orifice | 199,528 | 8.22% |
| native_medium_gas | 648,466 | 9.21% |
| native_temperature_ph | 608,716 | 20.13% |
| native_pipe_diagnostics | 548,702 | 7.18% |
| native_contact | 99,764 | 0.16% |
这里 `model_eval` 一行指去掉列出的子函数后的模型调度、赋值及机械平衡等剩余工作。模型 RHS 合计约占诊断求解墙钟的 96.4%。C 求解器线性化共触发 16768 次 RHS,占全部 24941 次的 67.2%;这是“为何重复计算”的另一种切分,与上表不能相加。
本模型生成的 236 项流体运算组成零循环依赖块,已经按依赖顺序一次执行;当前主要开销不能再解释为 Python 数值积分或多层全局压力/焓值循环。真正重的是一次 RHS 内反复算管流、反算温度、求氦气物性,以及积分器在试算/线性化时反复调用整套计算。
后续优先事项是:先把本次确认的物理公式和误差权重修正做成通用内核变更并补独立部件验证;再消除同一 RHS 内的重复物性换算、共享管流所需物性;把只用于显示的雷诺数、流速、摩擦系数等从每次 RHS 移到采样输出阶段;最后改进管内阻力方程的收敛策略和未收敛诊断。雅各比相关实现暂不改。
Amesim 算法信息仅留档:当前 Standard 自动运行统计为 Adams 727 步、BDF 1729 步,处理 8 次不连续事件;日志记录启用了其自适应 Jacobian 计算。按用户最新要求,不将 Amesim 的具体算法作为后续实现标准。
**可复现文件。** 全部位于 `test/mql4-20260910`:`final/` 是本次 C 验证包,包含模型 C、公共计算 C、运行时快照、EXE、DLL、输入 JSON、哈希清单和运行脚本;`final/run-bdf.ps1` 显式指定本次求解参数;`final/input.json` 导入现有网页时仍由正式旧版 C 内核运行,不等同于此实验 EXE。`run_ame.py` 使用本机 Amesim 官方 API,`experiment.py` 保留各阶段实验,`compare.py` 生成比较指标,`benchmark-v3/` 保存三次对照计时,`cost-profile-v3/` 保存函数计时,`verification-final.json` 保存基本验证,`amesim-fresh/test_mql_4.ame` 保存重新计算的 Amesim 参考结果。
@@ -0,0 +1,70 @@
# test-mql-4 网页仿真与 LSTP00A 接口力对比
2026-09-11,在网页导入 `test-mql-4-corrected.json`,点击“运行仿真”,完整算到 10 s,再通过“下载结果文件”导出本次原始结果。网页显示 1003 个采样点,未发生仿真失败。
**结论:常规采样点的接触力很接近,但完整网页曲线与 Amesim 已保存曲线不一致。网页额外保存的一个碰撞事件点有约 1.50×10¹¹ N 的瞬时峰值。** 不能仅凭常规采样点上的小误差,宣称整条力曲线一致。
## 本次仿真时间
| 口径 | 本次结果 |
|---|---:|
| 点击运行后至结果可查看 | 约 7 s |
| C 纯求解墙钟 | 3.650152 s |
| C 求解 CPU | 3.515625 s |
| 原生子进程墙钟(含结果整理等) | 5.238736 s |
| 构建缓存检查 | 0.167409 s(命中缓存) |
| 模型计算次数 / 接受步数 | 24941 / 5137 |
页面控制台“开始仿真”为 01:53:06,“仿真完成”为 01:53:13;前端日志只显示整秒,因此约 7 s 不是毫秒精度测量,也不包含用户后来打开曲线窗口的时间。纯求解时间直接来自本次网页导出文件。网页全程与纯求解之差包含准备、子进程启动、结果生成、传输和前端接收,不能全部归于进度条。
设置为 BDF、相对误差限 1e-7、最大积分步长 1e30 s、输出间隔 0.01 s、仿真区间 0~10 s。初始 5173 开发页面未完成渲染,实际成功测试使用后端提供的 `http://127.0.0.1:8000/` 页面。一次先前标签页在任务启动后不可用,其时间不计入本次结果。
## 部件与接口对应
用户所称 `lstp001` 在当前模型中对应 `LSTP00A` 第 1 个实例,即 JSON 的 `amesim_lstp00a_1`,网页显示名为 `elasticendstop_9_副本`。根据连接拓扑,它对应 Amesim 的 `elasticendstop_8`,不是仅按显示名中的数字匹配。
| 网页变量 | 对照 Amesim 变量 | 方向处理 |
|---|---|---|
| `amesim_lstp00a_1.port_1.f` | `f1@elasticendstop_8` | 同号直接比较 |
| `amesim_lstp00a_1.port_2.f` | `f2@elasticendstop_8` | Amesim 值取负后比较 |
本系统端口力统一取流入元件为正,两个端口的力相反。Amesim 变量清单明确将此模型的 f2 标为 f1 的重复量,已保存的两个数组也完全相同。因此第二接口符号不同本身不能判定为力计算错误。
## 完整曲线与常规采样对照
![接口力曲线对比](../../test/mql4-web-force-20260911/lstp00a-force-comparison.png)
第 1 实例在 1001 个共同的 0.01 s 采样点上:网页峰值为 272620.924818 N,Amesim 已保存峰值为 272621.136490 N;最大绝对差 0.577026 N,均方根差 0.135705 N。最大差相当于 Amesim 峰值的 0.000212%,该百分比是按峰值归一化,不是接近零力时的瞬时相对误差。
顺带核对全部四个接触元件的接口 1;接口 2 统一方向后有同样的误差:
| JSON 实例 | Amesim 对应实例 | 共同采样点最大差 | 均方根差 | 最大差 / Amesim 峰值 |
|---|---|---:|---:|---:|
| 1 | `elasticendstop_8` | 0.577026 N | 0.135705 N | 0.000212% |
| 2 | `elasticendstop_9` | 0.578578 N | 0.136276 N | 0.000212% |
| 3 | `elasticendstop_10` | 1.134175 N | 0.140897 N | 0.000416% |
| 4 | `elasticendstop_11` | 0.729195 N | 0.136876 N | 0.000267% |
但是网页还保存了 1.201137556938643 s 和 1.225339087445038 s 两个事件点。第一个事件点,四个接触元件均出现约 1.49859×10¹¹ N 的力;Amesim 本次保存的曲线没有这一时刻的数据,其相邻采样为 1.20 s 和 1.21 s。上图左上保留网页原始事件点,右上只用于展示共同采样点的一致程度,两者不可混为一个比较口径。
## 尖峰来源与持续时间
在 t = 1.201137556938643 s,170000 kg 的负载到达 0.37 m 理想限位。本系统将该负载速度置零;与它相接触的 50 kg 活塞一侧仍为 1.498587803347 m/s。接触参数为刚度 1e11 N/m、阻尼 1e11 N/(m/s),当时穿透量约 1.47291297e-06 m,阻尼已经几乎全量参与。
按当前公式,弹性项为 147291.297 N,阻尼项为 149858720230.815 N,合计 149858867522.112 N。这个数值直接对应网页上的尖峰,并非力单位换算造成。
另编译一个仅记录事件附近内部接受步的诊断程序,使用同一输入、公式和容差。记录开关不改变已有 1003 个输出点,已逐值核验。碰撞后力值约 0.348 ns 降到一半、1.154 ns 降到 10%、2.336 ns 降到 1%;这与 50 kg / 1e11 N·s/m ≈ 0.5 ns 的阻尼时间尺度吻合。
因此有两个叠加因素:理想限位突然改变速度,配合极大阻尼形成纳秒级瞬态;网页结果保存了瞬态最高事件点,却没有保存紧接着的纳秒级回落点。用直线把该点连接到 1.20 s、1.21 s,会把非常窄的峰画成毫秒级宽峰。
目前只能证明 Amesim 的**已保存曲线**没有采到该峰,不能据此断言 Amesim 内部没有同类瞬态,也不能把两者完整力曲线的差异简单归因于 C 语言或积分器精度。按此前要求,本次不以 Amesim 的内部算法作为实现标准。
此前的 72 条曲线对照主要覆盖状态量和阀流量,且只比较共同采样点,没有验证这两个新增事件点处的接触力。这是此次网页检查新增发现的覆盖缺口。
下一步应先明确碰撞时刻输出采用哪一侧的状态,并保存事件前后及必要的快速衰减点,让曲线按真实时间分辨率表达瞬态;常规采样比较仍可保留,但不能靠删去峰值来宣称物理问题已经解决。如果要消除模型本身的极短冲击,应再评估理想刚性限位及接触阻尼参数的物理取值。
## 数据与复核
本次导出的原始结果为 `test/mql4-web-force-20260911/web-result.simresult`,可在网页“加载结果文件”中复现。核对了其中所有元件参数和连接端点,均与交付 JSON 相同。Amesim 数据来自上一轮对 `tests/data/test_mql_4.ame` 官方重新编译所得的 `test/mql4-20260910/amesim-fresh/test_mql_4.ame`,未使用原归档内旧八支路缓存。
同目录 `summary.json` 保存计时、逐部件误差及源文件哈希;`force-series.json` 保存原始和共同采样力数据;`event-trace/accepted-event.jsonl` 保存内部步诊断;`lstp00a-force-comparison.svg` 提供矢量图。生产求解代码及两个用户原始输入文件本次均未修改。
@@ -0,0 +1,61 @@
# 管路重复计算优化核查(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 忽略;生产代码与回归测试不依赖这些临时材料。
@@ -3,6 +3,7 @@
状态:2026-09-10 更新为 Python 声明、C 数值实现
适用对象:人工开发者、代码生成工具和 AI 编程助手
配套读取规范:[组件库分类、发现与读取规范 v1](component-library-spec-v1.md)
端口供需规范:[气动端口变量供需合同](port-computation-contract.md)
## 1. 文档目标
@@ -147,9 +148,12 @@ def create(
PortDefinition.pneumatic(
"port_a",
nominal_role="bidirectional",
computation=THERMODYNAMIC_SUPPLY,
)
```
上例适用于提供温度/压力的储气端,`THERMODYNAMIC_SUPPLY` 从 `core.port_computation` 导入。阀门或管道阻力端应按实际模型选择 `FLOW_SUPPLY`;不能给所有气动端口套用同一个供需模板。
气动端口包含:
| 变量 | 角色 | 连接规则 | SI 单位 |
@@ -157,12 +161,14 @@ PortDefinition.pneumatic(
| `p` | `effort` | `equal` | `Pa` |
| `m_flow` | `flow` | `sumToZero` | `kg/s` |
| `h_outflow` | `stream` | `streamMix` | `J/kg` |
| `volume` | `signal` | `directed` | `m3` |
| `volume_flow` | `signal` | `directed` | `m3/s` |
必须遵守:
- `m_flow > 0` 表示质量流入当前组件。
- `nominal_role` 只用于界面和默认布局,不限制实际流向。
- 物理连接是非因果的,连接线端点顺序不代表流向。
- 物理连接的端点顺序不代表流向;具体子模型仍可规定固定的变量供需,例如 PN3NODE2 的参考口。
- 所有声明端口必须使用 `register_declared_port()` 创建。
- `DISPLAY.ports` 必须与 `PORTS` 名称集合完全一致。
- 分支连接使用三通等连接元件,不能让一个物理端口直接连接多条边。
@@ -174,6 +180,49 @@ PortDefinition.pneumatic(
- 把 `port_a` 固定解释为真实入口、把 `port_b` 固定解释为真实出口。
- 直接绕过端口状态读写其他组件对象。
### 7.1 新元件先写逐变量接口表
新模型必须先在模型说明中列明每个端口的下列信息,再写元数据和 C 代码:
| 信息 | 必须回答的问题 |
| --- | --- |
| 物理含义、机器名、SI 单位 | 传递的是温度还是比焓?能量还是能量流率? |
| 提供方/使用方 | 该变量由本部件提供、从对端取得,还是需要连接方程共同确定? |
| 提供方式 | 来自当前状态、固定值、另一个端口的别名,还是由公式计算? |
| 计算依赖 | 计算该输出具体需要哪些输入、状态和参数?不要只写“依赖某部件”。 |
| 符号与坐标 | 正号代表流入还是流出?机械量采用什么方向?映射原模型时是否取反? |
| 必需性及默认值 | 缺少对端变量时能否用有物理依据的默认值?何时应当报错? |
| 条件变化 | 参数是否改变可用端口、输入输出关系?反向流、零流量或切换时怎样处理? |
固定参数放在 `PARAMETERS`,例如管径、长度、初始温度 `T0`;随仿真变化的端口量放在接口定义中,例如当前温度 `T`。固定开度变体可以有意用参数代替开度信号,但应使用独立模型类型并说明差异。
### 7.2 供需声明与当前实现边界
`PORTS` 是权威来源。当前 `PortComputation` 的 `inputs/outputs` 支持 `p`、`T`、`m_flow`、`H_flow` 四个气动量;`reference_port` 只表达 p/T 从另一个端口输入复制的关系。前端目录与 JSON/XML 校验从注册表恢复这些声明,工程快照不能覆盖它们。
`H_flow` 表示能量流率(W),只用于当前接口供需检查,不能当作已经存在的 C 运行时端口字段;运行时仍使用 `h_outflow` 和质量流率。两种表达的单位、符号及零流量处理必须在 C 方程中正确转换。
- `mode="fixed"` 表示该子模型的接口供需是固定要求;它不表示输出数值为常量,也不是固定积分步长。
- `mode="equation"` 表示允许连接方程联合确定变量。必须有相应 C 求解能力支持,不得为了绕过错误接线而随意改为此模式。
- 新移植部件如有明确的固定输入输出,应按原始接口声明并验证。现有非节点部件采用 `equation` 是本阶段保留已有联合求解能力的策略,不能把它当作所有 Amesim 子模型的原始接口定义。
- 新模型需要声明容积、机械量、任意输出依赖或可选输入默认值时,应先同步扩展供需数据结构、注册器、目录 schema、前后端检查与测试。当前四变量接口尚不能完整承载这些信息,不得只在注释或 JSON 中添加编译器不读取的字段。
### 7.3 从 Amesim 移植时的对照要求
以明确的 Amesim 版本和**子模型编号**为依据读取端口变量表及其实现;图标相同或端口数量相同不足以证明模型等价。每个原始变量都应有映射记录:保留、换名、单位/符号变换、由其他量导出、仅保留默认值,或明确不支持。
既要记录普通输入/输出,也要记录状态、固定输出、别名、取反别名、可选输入及默认值。例如 PNCH012 的容积输入和 MECMAS21 的加速度端口量,不能因为当前四变量气动模板没有对应字段就不作说明。
接口方向对齐、局部公式对齐和完整仿真曲线对齐是三项不同的验证;不能用其中一项替代其他两项。实验组件及自行简化的变体,不应宣称与 Amesim 原子模型一比一相同。
### 7.4 为计算排序准备元件步骤
元件说明和 C 接入应区分:状态/物性输出、连接量与局部代数计算、状态导数、展示输出。例如储气元件先由当前状态提供温度和压力,得到流量后再算导数,不能把整个元件当作一个不可拆分的步骤。
端口供需合同不承载任意计算步骤的依赖图。当前扩展 C 生成器使用 `Computation` 记录内置气动方程的输入、输出与 C 语句,再自动排序及划分局部循环。新模型须显式接入这些计算关系;只注册 `PORTS/PARAMETERS` 不会自动生成数值方程。参考值复制与能量汇总应拆开,多输出 C 调用必须正确列出读取参数与写出结果,见 [C 求值排序规范](native-evaluation-schedule.md)。
新增或修改接口至少验证:合法连接、输入无人提供、冲突连接、参考链及参考环、反向/零流量、可选输入默认值、单位/符号映射,以及独立解析或外部基准下的 C 结果。没有对应机制的能力必须标记为尚未支持。
## 8. 参数建模规范
所有用户可配置输入必须使用 `ParameterDefinition`:
@@ -0,0 +1,54 @@
# C 求值的依赖排序与局部求解
本文说明当前内置模型的扩展 C 生成路径。Python 仅在编译时整理计算关系,运行时仍由独立 C 程序完成物性、连接量、局部迭代和积分。没有恢复旧 Python 数值内核或旧 IR 包。
## 执行过程
1. 从当前状态、参数和时间信号准备机械位置/速度、容积及储气物性。压力和焓的储气来源在此确定;可变容积仍使用当前机械状态,不把加速度或下一时刻状态当作已知量。
2. 将气动连接计算记录为独立条目,每条列明输入、输出和 C 语句。参考口的别名传递与节点能量汇总分开,管路/阀门流量与储气状态导数分开。
3. 根据生产者与使用者关系自动排序。没有循环的关系执行一次;互相依赖的关系组成局部块,先完成该块,再计算使用其结果的关系。
4. 计算机械力平衡、状态变化率和结果输出,再由原有 RK45/BDF 推进时间。
这里的“一次”指一次 `model_eval` 系统状态求值。积分器为误差控制、数值差分或步长重试而进行的多次求值仍然必要,不能把它们当作重复调用删掉。
紧凑的储气锚定生成路径已经直接按依赖执行,继续保留。扩展路径使用同一套图算法处理不同内置组件组合,不依据模型名称、实例名称、画布位置或固定流向写特例。
## 编译结构
`app/simulation/native_codegen/schedule.py` 提供:
- `Computation`:稳定标识、输出、输入、C 语句、计算类别,以及压力平衡残差(适用时)。
- `EvaluationSchedule`:检查来源与重复提供者,划分相互依赖的块,并按依赖排序。
- `emit()`:生成直接计算语句和局部 C 求解函数。
- `report()`:输出来源、输入输出关系及循环块清单,保存到构建清单的 `evaluationSchedule`。
连接流量的常系数线性消元仍在编译阶段完成;消元得到的中间表达式也参加排序,不把整组连接方程作为不可拆分的大步骤。图遍历不用 Python 递归,长参考链不会受递归深度限制。
`knownSources` 记录进入该阶段前已准备好的来源;`blocks` 给出执行顺序、输入、输出、来源和未知压力;`operations` 给出逐条关系。循环初值不算作已知来源。缺少输入来源、重复输出提供者、没有热力来源的纯别名环在编译时拒绝。
## 局部循环规则
- 未知压力仅使用该块已有的压力边界确定试算范围。单个压力试算只刷新其质量平衡所需的流量关系;不调用全网流量函数。
- 一个块内存在多个相互影响的压力时,保留现有逐压力二分与扫掠方法,最多 256 轮扫掠,每次二分 48 轮,质量平衡阈值仍为 1e-11 kg/s。
- 焓传播确有循环时,从该块外已经提供的焓值初始化该块;只检查本块输出变化。相对变化阈值仍为 1e-12,轮数上限为 `max(64, 4×本块待更新焓值数量)`。
- 压力与焓同时互相依赖时,在这个局部块内保留嵌套求解。迭代到上限仍未满足条件,或出现非有限数值,返回求值失败;不把未完成的局部闭合当作成功。
- 条件表达式记录所有可能分支的依赖,覆盖反向与零流量。此做法较为保守:某个特定工况下能进一步简化的关系仍可能留在小循环内。本版没有实现运行时分支特化。
管路自身的摩擦/流量求根属于元件内部计算。本轮没有改其算法或 16/64/48 轮上限,也没有改积分器或雅可比策略。系统循环的来源检查和局部划分不代表任意新非线性方程都已得到数值求解支持。
## 新模型如何接入
除了模型的物理接口表,还要在 C 生成实现中拆出能独立执行的关系:
```python
operations.append(Computation.assignment(
f'alias:{component.name}.port_1', target_h, reference_h, 'alias'))
```
单个赋值的输入从编译器生成的受控表达式中提取。提取器只识别本生成器的 `p/h/q/w/fb` 数组与气体物性字段,不解析用户输入的 C 代码。调用写出多个结果的 C 函数时,必须显式列出实际读取的参数和写出的结果;把输出指针误当作输入,会制造虚假循环。
没有依赖流量的参考值复制必须单独列出,不能与需要流量的能量计算合并为一个条目。共享状态、机械/信号准备和气体物性阶段仍需要在现有 C 接入中实现;仅注册 `PORTS/PARAMETERS` 不会自动产生方程。
新增能力至少检查:来源缺失、多个提供者、长参考链、组件与连接顺序打乱、正反流和零压差、两个独立循环互不重算、耦合压力/混合循环的质量能量守恒,以及独立数值基准。当前自动排序对象是已接入的内置方程,不接受任意外部 C 代码。
对应测试:`tests/test_native_schedule.py`、`tests/test_native_catalog.py`。本轮模型对照记录见 [计算排序验证记录](../other/C计算依赖排序验证-2026-09-10.md)。
@@ -0,0 +1,89 @@
# 气动端口变量供需合同
本合同在 Python 编译阶段和前端建模阶段使用,数值计算仍由 C 执行。它不改变状态、输出键、积分器、雅可比策略或管流算法。
## 物理连接与计算供需
`nominalRole=bidirectional` 表示气体可双向流动,不表示温度、压力、流量都可以任意选择提供者。`side`、旋转和镜像只负责显示,也不改变计算供需。
端口新增 `computation` 字段,与已有 `variables` 物理合同分开:
```json
{
"name": "port_2",
"computation": {
"mode": "fixed",
"inputs": ["p", "T"],
"outputs": ["m_flow", "H_flow"]
}
}
```
四个量分别是压力(Pa)、温度(K)、质量流率(kg/s)和能量流率(W)。`H_flow` 是用于接口校验的能量传递量,不是比焓 `h_outflow`(J/kg),不增加新的运行时端口字段。当前 C 内核仍使用质量流率与比焓计算能量传递。
`inputs` 是该接口从对端取得的量;`outputs` 是该接口向对端提供的量;输出不必全部被对端使用,例如堵头只提供零流量,不读取节点传出的温度。
## 当前声明范围
| 端口 | 需要 | 提供 |
| --- | --- | --- |
| PN3NODE2/P4NODE2 的 port_2 | p、T | m_flow、H_flow |
| PN3NODE2/P4NODE2 的其他口 | m_flow、H_flow | p、T(来自 port_2) |
| PNCH023/012、PNL0003、实验气瓶/气罐的储气口 | m_flow、H_flow | p、T |
| PNL0001 的 port_2 | m_flow、H_flow | p、T |
| PNL0001 的 port_1、PNL0002 两端、阀门、孔口及阻力管 | p、T | m_flow、H_flow |
| PNRP17 的气动口 | p、T | m_flow、H_flow(零) |
| PNPL01 堵头 | 无 | m_flow、H_flow(零) |
| 实验 Tee | 由连接方程共同确定 | 无固定的参考温度来源声明 |
本次覆盖上述四类气动量。容积、容积变化率、机械连接和信号连接继续使用原有校验及方程;不将其默认为已经完成逐变量供需校验。
## 与 Amesim 接口的一致性边界
2026-09-10 对照本机 Amesim 2404 的子模型端口变量表。下表比较的是变量接口,不能据此推断所有数值公式、默认参数和完整仿真结果均已一致。
| 模型 | 已对齐部分 | 尚未完整表达或有意不同的部分 |
| --- | --- | --- |
| PNOR001、PNVO001、PNL00R | 两侧 p/T 输入、质量和能量流率输出的方向 | 输出之间的符号反转/别名、每个输出的全部依赖尚未作为通用元数据声明 |
| PNL0001/2/3、PNCH023 | 对应端口四个核心量的供需方向 | Amesim 的温度/压力状态在本实现中由质量/内能状态换算,接口表示并非逐字段相同 |
| PNCH012 | 四个核心气动量方向 | 各端口的容积、容积变化率输入及默认零值尚未纳入 `computation` |
| PN3NODE2、P4NODE2 | port_2 参考输入,其他端口 p/T 别名,质量/能量汇总方向 | 容积及容积变化率的输入、汇总与默认值尚未纳入 `computation` |
| PNRP17 | 气动 p/T 输入和零质量/能量流率输出的方向 | 扫掠容积、容积变化率输出、机械端各变量的供需未纳入新合同;零流量性质目前写在模型说明而非通用常量字段 |
| PNPL01 | 不需要温度/压力输入,提供零质量/能量流率 | Amesim 还提供零容积、零容积变化率;常量来源及这两个量尚未纳入 `computation` |
| F000、FORC、MECMAS21、LSTP00A、LMECHN1 | 保留现有机械变量与 C 连接方程 | 尚未逐变量声明完整因果关系;MECMAS21 原端口含加速度,当前统一机械端口仅含 x/v/f;原模型取反别名还需在映射中明确坐标变换 |
| STEP0、UD00、PNVO001/FORC 控制信号 | 现有信号输入/输出方向检查 | 尚无统一的状态/常量/别名/公式依赖描述,不能把所有信号的物理量和单位视为已完整对齐 |
| PNVO001 固定开度变体 | 气动侧四量方向 | 本项目用开度参数替代原 PNVO001 的控制信号,是有意设计的变体 |
| 实验组件、介质定义组件 | 使用本项目自己的模型/介质注册合同 | 不作为 Amesim 原子模型完整接口的等价证明 |
本项目所有气动端口都带有通用的 `volume/volume_flow` 物理字段,不代表每个元件都按 Amesim 同样方式读取和提供它们;是否存在字段与是否有正确供需声明需要分别核对。
依据为本机 `F:/amesim2404/amesim/` 下 `libpn/submodels/`、`libpcd/submodels/`、`libmec/submodels/`、`libsig/submodels/` 中对应编号的 `.c` 文件。新增元件应遵守 [组件模型建模规范第 7 节](component-model-authoring-spec-v1.md#7-端口建模规范),先完成逐变量映射表,再实现和验证。
## 两种校验模式
- `fixed`:固定计算接口。目前用于 Amesim 三通、四通节点。与其连接时,双方声明需要的量都必须由对端声明提供,否则拒绝。参考口不能接阀门的压力/温度输入端;普通支路口不能接储气端来替代参考口。
- `equation`:保留通过连接方程联合确定变量的能力。供需描述是该部件局部计算接口,不能仅凭两个局部输入相接就断言系统无解。两端均为此模式时,仍交由现有方程与能力检查处理,例如阻力串联和已支持的储气容腔耦合。
这一区分避免把所有物理网络当作定向信号线。局部供需校验通过,不保证全系统可以顺序计算。当前 C 生成器已对内置模型的气动计算增加依赖排序与局部循环划分,依据实际计算关系安排执行;它与本节的端口连接合同职责不同,见 [C 求值排序规范](native-evaluation-schedule.md)。
节点支路的 `referencePort: "port_2"` 声明其 p/T 来源。模型校验会沿这种别名关系追溯,允许多级节点串接到真实储气状态,拒绝没有实际来源的参考环和中途中断的参考链。检查过程复用已确认的来源,不依赖 Python 递归深度。
## 一致的入口和提示
权威定义是组件类的 `PORTS`,从注册表发布到组件目录。JSON 中保存的端口信息只是快照,加载时使用当前目录恢复,执行 XML 也不接受工程自定义供需规则。
- 画布:供需不匹配的目标口不会作为可连接目标;接触吸附使用同一规则。悬停显示需要/提供的量和不兼容原因。
- 旧工程:保留供需不匹配的现有连线供检查、修改,不自动交换参考口或删线。原有的无效端口、重复占用等结构损坏处理不变。
- 检查模型及运行仿真:报告具体部件、端口和缺少的量,错误未处理前不启动求解。
- JSON/XML/API/直接构造网络:后端独立检查,不能靠删除或伪造前端快照绕过。
- 两条 C 生成入口:在生成前再次检查连接及参考来源。
错误码:`CONNECTION_VARIABLE_SUPPLY_MISSING`、`REFERENCE_SUPPLY_CYCLE`、`REFERENCE_SUPPLY_UNCONNECTED`。
## 开发与验证
供需数据结构与后端检查位于 `app/simulation/core/port_computation.py`,前端对应实现位于 `frontend/src/portComputation.ts`。新增固定接口应在模型 `PORTS` 中声明,并提供合法连接、供需冲突、流向/连线顺序反转和参考链的测试。
本次没有修改浏览器工程、正式 `test-mql-8.json` 或历史数值基准。旧节点 smoke 测试改为将参考口接到储气状态;另保留明确的错误接线拒绝测试。历史 50 个冻结网络仍能通过新合同并执行原 C 数值对照。
浏览器测试从实际 Python 组件目录读取供需信息,覆盖目标筛选、悬停原因、错误旧连线保留和仿真前拦截,防止前后端合同不一致。
+1
View File
@@ -192,6 +192,7 @@ XML 不能通过写一个新端口名来扩展组件,也不能通过修改字
- 两端同为物理端口或同为信号端口;
- 两端 `domain` 和完整变量合同一致;
- 信号连接恰好连接一个 `output` 和一个 `input`;
- 固定气动接口的变量供需互补,节点参考温度/压力来源没有闭合引用环;详见 [气动端口变量供需合同](port-computation-contract.md);
- 一个信号输出可以驱动多个输入,但每个信号输入只能有一个驱动;
- 同一物理端口只使用一次;分支必须使用显式 Tee/节点组件;
- 不允许自连接或重复端点对。
@@ -25,3 +25,64 @@
- 删除未接入当前 C 路径的旧 IR Python 包、专属 schema、规范、冻结示例与测试,同步移除 CI 测试入口。C 生成继续直接使用校验后的网络结构,求解算法未改动。
- 删除旧求解器优化任务清单、后端效率调研、2026-08-15 性能评估及 Python/C 迁移可行性计划,清理文档索引。保留 C 实现记录和数值回归基准,新优化计划后续重列。
- 本地 37 项相关测试中 36 项通过、1 项 Linux 锁定环境检查按配置跳过,包含 50 个网络的冻结数值对照。`skill-test` 完成 10 s,RK45 最大步长 0.001 s、rtol 1e-7,单次纯求解 0.293462 s;本次用于确认清理后正常运行,不作为性能优化结论。
## 18:58
- 新增独立的连接线子模型交互 demo:按“绘图 → 子模型 → 参数 → 检查”操作,固定 P4NODE2,通过连线选择兼容管路并自动确定方向。演示包含四条连接、连续选型、参数保留和恢复初始示例。
- 使用独立页面与浏览器存储键,未修改主应用、正式工程、组件或求解器。演示只检查局部接口和参数,不执行仿真;移除 `frontend/public/demos/amesim-submodels/` 即可撤回。
- Edge 浏览器检查通过:兼容筛选、连续选型、反向接口、参数校验、刷新恢复、更换型号保留共同参数、删除重连、独立重置及窄屏布局;确认未发起后端 API 请求。
## 19:19
- 新增 `frontend/public/demos/pipe-submodels/` 管路子模型 demo,采用左侧管路库、中间固定模型图、右侧属性/参数表和底部检查信息的布局。默认进入子模型模式,只开放 PNL00R、PNL0001/2/3;上一版保留用于对照。
- 固定部件坐标及连接关系,禁止拖动、改路由、删除和重新连接;缩放/空白区平移仅改变观察视口。子模型阶段参数只读,参数阶段可编辑,使用独立浏览器存储。
- Edge 验证位置锁定、兼容筛选、预览/应用、连续选型、参数校验和保留、反向端口映射、刷新/重置、三种窗口宽度通过;未调用后端,不执行仿真。正式应用与求解内核未改动。
## 20:14
- 为气动端口新增温度、压力、质量流率和能量流率的供需声明;Amesim 三通/四通节点采用固定参考口校验,普通方程端口保留联立求解能力。多级节点会追溯参考来源,拒绝无来源的循环引用和中断链。
- 同一合同贯通组件目录、画布目标筛选与悬停提示、模型检查、JSON/XML/API 和 C 编译入口。旧工程供需错误连线保留供修正,禁止靠旧端口快照绕过校验。
- 未改用户浏览器工程、正式 test-mql-8 输入、积分/管流公式或计算顺序。旧测试文件中的错误参考口会被拒绝,此前独立实验中调整参考口的副本通过校验。
- 后端全量 269 项中 268 项通过、1 项锁定环境检查跳过,包含 50 个冻结网络的 C 数值对照;4 项 Chrome 测试及前端 TypeScript/生产构建通过。说明见 `docs/standard/port-computation-contract.md`。
## 20:38
- 对照 Amesim 2404 的气动、机械和信号子模型端口表,补充接口一致性边界:核心气动四量供需方向已对齐;容积与容积变化率、机械逐变量方向/加速度、常量与别名等尚未完整进入新供需合同。
- 更新元件建模规范第 7 节,要求新增元件先列逐变量接口、单位与符号映射、输出来源和计算依赖,并区分当前可执行元数据与后续需扩展的能力。说明中明确固定开度 PNVO001 是本项目变体。
- 本次仅更新规范和过时的模型说明文字,未改数值实现或用户工程;文档差异格式检查通过。
## 21:14
- 管流摩擦计算中的粗糙度常量提到内部循环外;生成的 C 在单次系统状态求值内复用完全相同输入的管流结果,每次积分器试算重新初始化缓存,不改变公式、迭代上限、计算顺序或雅可比策略。
- 修正参考口的独立模型副本在 30 次求值中,132 个导数和 1784 个输出逐值一致;原 14 组状态的实际管流求解次数从 2352 降至 672。14 项相关回归通过,包含 50 个冻结网络及无气动端口模型。
- 单独审计确认原 PNL0001/2 的 16 轮方法存在收敛不足,本次没有更换求根算法。系统层面仍应优先开发通用依赖排序与局部循环识别,缓存不替代该工作。未运行本轮完整轨迹或网页/Amesim 对比;范围和微基准限制见 `docs/other/管路重复计算优化核查-2026-09-10.md`。
## 22:40
- 扩展 C 生成器新增计算关系的来源检查、依赖排序与局部循环划分;参考别名与能量计算拆分,未耦合关系直接执行,压力试算只刷新本块残差所需的流量。循环初值和压力边界来自所在区域,构建清单保存 `evaluationSchedule` 供核查。
- 修正参考口的独立模型生成 484 条计算关系、0 个系统代数循环块,30 次求值中每条关系均执行一次,132 个导数及 1784 个输出逐值一致。BDF 同样完成 0.02 s 时,采样与最终状态完全相同,单次纯求解从 2.368098 s 降至 1.645752 s;独立 C 求值基准约提速 1.459 倍。
- 新增长链、独立循环隔离、反向流、连接顺序打乱、压力与混合焓耦合及守恒测试,定向 29 项通过。全量 276 项中 1 项环境检查跳过,遇到进程偶发空输出的相关网络已单独复核通过;保留全量未一次全绿的记录。
- `skill-test` 完整完成 10 s。大模型两版完整 10 s 尝试均触及 30 s 执行限额,本轮不宣称已完成其全程速度或 Amesim 曲线对齐。管流求根、积分器、雅可比及用户接线保持不变;规范与详情见 `docs/standard/native-evaluation-schedule.md`、`docs/other/C计算依赖排序验证-2026-09-10.md`。
## 21:17 前端仿真期间性能优化(第 1、2 项)
- 结果流采用增量 NDJSON 解码:仅扫描新分块,跨块长行保留片段,在换行/结束时一次合并,避免对完整结果反复扫描和复制。保留 UTF-8 跨字节、CRLF、空行、末行无换行及解析错误传播行为。
- 进度与日志迁入控制台独立订阅的状态容器,不再触发顶层建模工作区渲染。普通进度每 250 ms 合并显示最新值;阶段变化、异常、停止、完成及关键操作日志即时更新。重复可见状态不通知,结束时清除待刷新进度,日志保留既有 400 条上限。
- 活动监测仍逐条处理原始消息,30 秒数据流超时和接受步/内部活动停滞规则未调整;后端接口、C 求解器、数值精度、采样和原始结果未改动。本轮不实施第 3、4 项(结果复制/存储、曲线绘图),后续实施时同样补充压力与数据一致性测试。
- 新增 `frontend/tests/e2e/simulation-performance.spec.ts`,9 项测试覆盖百万数值、1 KiB/64 KiB 分块、10 万条进度合并、300 元件/300 连接下的 1 万条进度冲击、终止状态不被旧进度覆盖,以及真实停滞恢复流程;所有后端响应均为测试模拟,不运行实际求解器。
- 隔离 Chrome 中,同一 18,565,846 字节结果按 64 KiB 分块,旧/新解析三次耗时分别为 1854.5/128.1、1929.5/81.1、1720.8/76.7 ms;逐项比对 100 万个数值一致。300 元件页面的 1 万条进度没有触发工作区重新渲染。100 变量 × 10000 采样点的应用接收至可用检查约 429 ms(包含现有结果复制/存储尝试和测试检查延迟,不含真实网络传输与求解)。
- 33 项相关回归全部通过,覆盖新增压力测试、活动监测、超时、原生/旧结果恢复以及控制台/复制粘贴。TypeScript 与生产构建通过,仍有原有主包超过 500 kB 的提示。测试服务器启动偶发超时后,使用临时配置直接启动 Vite 完成测试,临时配置已移除。
- 上述耗时是本机合成数据的前端专项测试,不代表完整工程求解时间或端到端仿真的加速比例。
## 22:25 结果保存与曲线性能优化(第 3、4 项)
- 发布仿真结果时直接使用本次请求独占的数值结果,不再对整份结果执行 `structuredClone`;工程快照仍独立复制,防止后续建模修改污染结果。
- 新结果改用 IndexedDB 后台分块保存:每块最多 32768 个双精度数值,每批约 1 MiB,并在批次间让出主线程。全部写入成功后才更新 sessionStorage 中不足 200 字节的恢复指针,避免同步序列化整份结果及原有小容量限制。
- 兼容读取旧版 sessionStorage 结果;后台恢复不覆盖新生成/新载入的结果,过期保存不能覆盖更新结果。保存失败保留内存中的结果和上次完整缓存,控制台提示导出;后台保存未完成时离开页面会触发浏览器提示。只清理本页产生的过期/未完成缓存,不清理用户工程或结果文件。
- 曲线样本、坐标范围、单位换算和按视口选取的绘图点增加缓存;移除对大样本数组使用 `Math.min(...数组)` / `Math.max(...数组)` 的写法,以及多曲线全样本拼接。缓存使用弱引用或有限条目,避免无限保留历史视口和单位切换数据。
- 单曲线、同单位多曲线、上下分区曲线均按可见时间区间和像素列保留首点/最小值/最大值/末点,保持原顺序、线段断点和窗口边界外的相邻点。完整原始数据继续用于游标读数、结果文件及 CSV,不减少后端采样,不改变求解公式或精度;既有机械事件孤立力尖峰的连续曲线显示规则保留。
- 新增 `results-performance.spec.ts` 的 6 项压力/一致性测试:百万点极值与像素路径上限、断点和重复时刻、百万双精度数值保存/恢复、保存失败和新旧请求竞争、每条 25 万点的三种曲线窗口及完整导出、浏览器新旧路径生成对照。更新原生结果恢复测试适配异步缓存。
- 本机 Chrome 专项测试:1,000,000 个数值对应 JSON 约 18.6 MB,后台保存约 47.8 ms、恢复约 32.4 ms,保存期间其他定时任务运行 16 次,整份结果 JSON 序列化调用为 0,恢复指针 84 字节,逐值精确一致。25 万点路径旧方式约 111 ms,新方式首次约 27 ms、100 次缓存重绘平均约 0.688 ms;路径命令从 250000 降至 1679,原始 250000 点全部保留。这些是数据处理/路径生成耗时,不等同于浏览器实际帧率或求解器加速比例。
- 三个实际结果窗口同时显示五条 25 万点曲线,路径点数分别为 722、1002、1001、1001、1000;单位切换、游标读数、滚轮缩放、刷新恢复和完整结果导出通过。导出按浏览器保存的原始数据逐项精确比对,而不是在 Node 中重新计算三角函数。
- 相关 59 项测试均已通过(一次组合运行 58 项通过,修正导出测试基准后补跑相关 14 项全部通过);包含上一轮 1、2 项压力测试、活动监测/停止恢复、建模交互和结果系统图回归。TypeScript 与生产构建通过,保留原有主包体积提示;临时直接启动 Vite 的测试配置已移除。
- 本轮不运行真实求解器,未修改后端。压力测试仅使用隔离浏览器和合成数据,不影响用户浏览器工程。
@@ -0,0 +1,49 @@
# 2026-09-11:C 管路验证版合入网页后端
后续网页检查补充:LSTP00A 接口力在新增碰撞事件点存在极短高峰,原有共同采样点回归没有覆盖该现象。详情及对原曲线一致性结论的限定见 [接口力对比报告](../other/test-mql-4网页仿真与LSTP00A接口力对比-2026-09-11.md)。
在 `system-optimization` 工作区,将 test-mql-4 验证版的修正合入正式原生编译和求解路径,并重启本机 `127.0.0.1:8000` 后端。网页通过 `5173` 端口代理调用的新仿真已经使用这些修正。未提交或推送 Git。
## 合入内容
- PNL0003 的两段储气状态之间,采用与 PNL0001/2 相同的可压缩管流关系及小压差平滑处理,移除独立 Darcy 反求和固定 48 次二分分支。
- PNL0001 按实际流向选择上游温度;流量计算和雷诺数、摩擦系数、流速诊断使用同一侧的温度。
- 氦气管流与诊断统一使用已有 NASA 黏度表达式;理想空气等介质保留原有黏度模型。
- 两条 C 代码生成路径统一生成按物理量区分的绝对误差限:质量 `1e-14 kg`、内能 `1e-8 J`、速度 `1e-12 m/s`、位移 `1e-12 m`。这是本轮验证的默认值,尚未实现按模型尺寸自动缩放或用户自定义绝对误差限。
- 网页后端默认相对误差限从 `1e-6` 调整为 `1e-7`,与此次对照设置一致,并在结果诊断中返回实际 `rtol`。积分方法、最大步长和输出间隔仍取自用户模型。
雅各比算法、求解器类型和前端操作流程未修改。构建缓存会根据模型及 C 源文件内容自动生成新的键,无需手动删除旧缓存。用户仍需导入修正后的 JSON;内核更新不会自动改动已保存模型的接线或参数。
## 验证结果
经真实 HTTP 请求 `http://127.0.0.1:5173/api/system-xml/simulate-stream`,修正后的 test-mql-4 以 BDF、相对误差限 `1e-7`、最大步长 `1e30` 完成 0~10 s:
| 指标 | 本次运行 |
|---|---:|
| 纯求解墙钟 | 4.4088 s |
| 求解 CPU | 4.1719 s |
| HTTP 全程 | 9.3444 s |
| 模型计算次数 | 24941 |
| 接受步数 | 5137 |
| 进度事件数 | 50 |
HTTP 全程包含进程启动、结果整理、序列化和传输等,不应把它与纯求解的差额全部归因于进度条。本次是后端合入验证,未测量浏览器绘图时间。
72 条物理曲线在共同的 1001 个时间点上,与重新编译的 Amesim 四支路模型比较。最大压力差 `198.2697 Pa`、温度差 `0.009626 K`、位移差 `0.646855 μm`、速度差 `3.41015 μm/s`、质量流量差 `0.0160272 g/s`,与先前 C 验证版一致。剩余局部差异仍按原报告记录,未声称完全消除。闭合气路总质量最大漂移约 `1.20e-14 kg`。
另外,通过同一 HTTP 路径运行仓库 `native-skill-test.xml`:RK45、最大步长 0.001 s,完成 10 s 仿真,纯求解墙钟 `0.5205 s`,CPU `0.4531 s`。
29 项相关测试通过,包括两种积分器、完整元件目录、依赖排序、管流缓存、正反向上游温度、平衡附近管流、守恒和网页流式求解。目录测试中与旧 Python 管流公式有关的断言,改为保留独立热力学基准并校验守恒;其他模型继续进行完整旧基准对照。新增 Amesim 曲线基准覆盖 72 条曲线、57 个选定时间点,用于持续回归;本次 HTTP 核验使用完整的 1001 个共同时间点。
## 文件
- 正式代码:`native/components/kernels.c`、`app/simulation/native_codegen/{compiler,extended,tolerances,runner}.py`、`app/simulation/backends.py`。
- 回归:`tests/test_native_pipe_physics.py`、`tests/test_native_catalog.py`、`tests/data/test-mql-4-corrected.xml`、`tests/data/test-mql-4-amesim-reference.json`。
- 执行记录:`test/mql4-backend-integration-20260911/` 内的 `http-verification.json`、`http-result.json`、`http-events.json`、`skill-test-http-summary.json`、`physics.log`、`regression-final.log`。
- 用户输入文件仍为 [test-mql-4-corrected.json](../../test/mql4-20260910/test-mql-4-corrected.json)。
复核命令:
```powershell
./.venv-win/Scripts/python.exe -m unittest tests.test_native_pipe_physics tests.test_native_codegen tests.test_native_pipe_cache tests.test_native_catalog tests.test_native_schedule tests.test_amesim_pnl0001_xml tests.test_amesim_pnl0002_pnl0003_xml tests.test_native_only_backend -v
```