修复循环信号与事件采样并接入 LSTP 接触定位,补充八路验证及复用实验

相较上一版 Jacobian 确定性复用更新,本次补齐事件边界一致性、结果两侧采样及接触事件定位;保留已有物性复用和组件力学公式。

- 统一 UD00 信号求值与下一事件查询的绝对时间边界,修复循环边界浮点舍入导致的阶段错位、重复或漏报,并覆盖零时长、多阶段及长周期场景。
- 引入原生输出语义 v2:保留规则网格真实时间,补充内部时间事件和状态事件的左邻及事件后采样,按保存时间、状态和离散模式重放结果。
- 两条代码生成路径均发出 LSTP 接触描述,默认定位间隙过零及非负力模式的力截断;仅在接受事件时更新防重复记录,增加 contactEvents 诊断计数。
- 补充 MASS/LSTP 独立事件实验、八路全曲线与驱动阶段配对评估,以及 Amesim 不连续点输出对照和力差定位报告;MASS 新增释放机制仍保留为独立实验。
- 保存局部 probe、context 访问与回退、shadow replay、R288 real skip/typed replay 及阀门数值尾部诊断工具和报告;未证明净收益的实验不启用为生产默认优化。
- 更新原生运行说明和元件建模规范,补充信号边界、输出语义、接触事件和实验依赖回归测试。

验证:五组专项回归共 34 项全部通过;37 个待提交 Python 文件语法检查通过;git diff --cached --check 通过。
This commit is contained in:
ljz committed 2026-09-17 23:50:13 +08:00
1 parent 1aac220084
commit 7611f13208
85 files changed
+11358 -33

No files matched your search

@@ -0,0 +1,95 @@
# 事件输出语义修改与八路基线复测
日期:2026-09-17。Windows,本项目 Python 3.12、原生 C、CVODE BDF;独立测试同时覆盖 RK45。
## 1. 结论
**已完成输出语义修改、专项测试,以及循环/非循环两组 50 s 八路基线重跑。两组各 5,001 个比较时刻均找到同一信号驱动阶段的样本,信号比较误差归零;循环接触力尖峰差仍然存在。**
本次修改只增加事件两侧的保存样本并明确比较规则,没有补充接触事件。前后对照均使用已经修复 UD00 的内核,避免把此前信号修复与本次输出修改混在一起归因。修改前的原生源码快照保存在 `test/output-semantics-20260917/control-source/native/`。
## 2. 输出语义怎样改变
- 规则采样时间仍按实际浮点数解释,不把网格点吸附到事件,不提前切换信号。
- 对仿真区间内部的时间事件,保存 `nextafter(boundary, -INFINITY)` 和 `boundary`。前者是旧积分段实际到达的终点;后者保留连续状态,用事件后的信号重放输出。两者是相邻的真实浮点时刻,不是两个重名时间戳。
- 对已注册的机械状态事件,在当前积分区间可用时,保存事件左邻时刻的插值状态,然后保存事件后的接受状态。这保留了碰撞前后速度及各自模式。初始即时事件没有新左侧区间,不倒填样本。
- 同一实际时间依然以后一次接受状态为准;序列严格递增。结果增加 `outputSemantics.version=2`,已有状态/输出块格式和变量集合保持兼容。
- 新增样本同样走既有有界缓冲、存储配额和输出重放流程。纯求解模式不保存这些样本。
主要实现:[公共事件采样](../../native/runtime/common.c)、[BDF](../../native/runtime/cvode_solver.c)、[RK45](../../native/runtime/rk45.c)、[结果元数据](../../native/runtime/main.c)。注册与重放要求见[组件开发规范 12.2](../standard/component-model-authoring-spec-v1.md#122-事件输出与重放)。
## 3. 如何保证比较阶段一致
当前八路有 8 个 STEP 和 2 个 UD00,UD00 各启用阶段均为常值。比较程序先取 Amesim 在名义网格附近实际保存的样本,再在平台保存样本中寻找相同的完整信号组合。
- 时间候选窗口仍为输出间隔的 `1e-7`,本次即 `1e-9 s`;它只用于匹配保存时间的舍入差,不修改求解时间或事件时间。
- 10 个信号必须同时一致;所有 238 条曲线共用同一对样本行,不按接触力、压力或误差大小选择样本。
- 不跨跳变插值;缺失对应阶段时明确记录未配对,不把错误配对纳入同阶段指标。旧的纯时间匹配指标另存为 `raw-time-comparison.json`,用于审计。
- 本规则针对本次分段常值信号;脚本遇到 UD00 斜坡会明确拒绝,避免把“输出值相近”错误地推广为所有信号的阶段标识。
- 额外核验八个接触件的带符号间隙:两组全部已配对点的 `gap<0` 标志一致。但这不是对网格之间所有接触/脱离时刻的验证,也不声称复原了 Amesim 的全部内部离散模式。
修改前循环工况缺少 4 个时刻的同阶段样本,非循环缺少 1 个;修改后两组均为 **5,001/5,001 配对,未配对 0 个**,没有删除事件点。循环改配时刻为 0.8、10.8、32.4、44 s;非循环为 0.8 s。真实时间、选中的信号值及原始行记录在各组 `phase-pairing.json`。
## 4. 第一次测试与回归
首先执行输出/相位配对、循环 UD00、存储专项共 18 项,全部通过;另补非网格时刻阶跃测试 1 项,通过。随后结果传输、HTTP 返回、取消/异常处理、恢复碰撞及摩擦保持回归 11 项通过,共 **30 项**。
关键验证包括:32.4 s 浮点边界前后分属不同阶段时正确配对;Amesim 保留事件前值时选用平台左侧样本;缺失阶段或任一驱动不同则明确拒绝;BDF/RK45 保存非网格阶跃两侧;碰撞前后速度分别为约 1 和 −0.5 m/s;有/无采样的积分最终状态及计数一致;二进制存储与 JSON 返回一致。
证据:[18 项首次通过日志](../../test/output-semantics-20260917/verified-first-tests.log)、[非网格阶跃](../../test/output-semantics-20260917/off-grid-test.log)、[11 项附加回归](../../test/output-semantics-20260917/additional-regression.log)。测试过程中一次解析碰撞时间断言过严:原设 1e-9 s,实际偏差约 2.61e-8 s;按该数值积分测试的目的改为 1e-6 s。事件两侧相邻浮点时间及速度断言未放宽。编译器偶发启动失败由既有重试恢复。
## 5. 八路基线结果
使用原有 AME 作为参照,在副本中审计并对齐参数、连接和运行设置。两组均重新执行 Amesim 归档中的程序及平台程序,没有用旧曲线代替本次运行。循环采用当前 `tests/data/test_mql.ame`;非循环采用此前已审计的 `test/node-fixes-amesim-20260914/test_mql.ame`。时间 0–50 s,输出间隔 0.01 s,两边误差限数值 1e-8。原始工程文件未修改。
下表“修改前”是保留了 UD00 修复的本次对照运行,采用旧的纯时间配对;“修改后”使用新增事件样本和同阶段配对。每项均包含事件网格点。
| 指标 | 循环:修改前 → 修改后 | 非循环:修改前 → 修改后 |
| --- | --- | --- |
| 信号最大绝对差 | 约 1e17 → **0** | 约 1e17 → **0** |
| 接触力最大绝对差 | 1,285,489.483 → **1,285,489.483 N** | 1.456532 → **1.456532 N** |
| 压力最大绝对差 | 65.686768 → **65.686768 Pa** | 65.686768 → **65.686768 Pa** |
| 温度最大绝对差 | 0.395395 → **0.395395 K** | 0.395395 → **0.395395 K** |
| 明确非零且相对差超过 5% 的曲线样本数 | 63 → **56** | 32 → **30** |
| 修改后信号阶段不匹配的比较点 | **0** | **0** |
| 修改后八路接触/分离标志不匹配的比较点 | **0** | **0** |
5% 仍是诊断筛查线,不是工程验收公差。循环剩余 56 个超线曲线样本为接触力 24、速度 2、质量流 23、焓流 7;非循环剩余 30 个为质量流 23、焓流 7。事件之外的小流量/焓流差异未因本次修改消失。历史初评中的 61 个不能直接当作本次修改前计数,因为本次对照的 UD00 已修复。
### 32.4 s 为何仍需继续查
选中的平台时刻为 `32.400000000000006`,Amesim 为 `32.40000000000221`。两边 UD00 均为事件后的值,第 2 路间隙均为负、处于接触区,但力仍分别为 **468,662.661 N** 与 **1,754,152.144 N**。
本次证据只排除了“信号前值对信号后值”的误配,不能排除高刚度过程对约 `2.20e-12 s` 实际时间差的敏感性,也不能证明缺少接触事件就是该误差的唯一原因。弹性接触力取决于连续位移/速度;切换信号输出不会直接把这些连续状态改成 Amesim 的值。
共同 10 ms 网格仍不是原始瞬态的上界:循环额外事件点中约 **2.084e14 N** 的绝对力峰仍存在;非循环原始峰值约 **4.035e11 N**。这些原始峰未被平滑、删除或纳入不具备同分辨率参考的精度结论。循环在 t≥0.1 s 且避开信号边界前后 0.02 s 的定位统计中,最大力差约 **0.276 N**,不能替代完整事件段验收。
## 6. 是否改变求解与耗时
对两组修改前后原始结果逐项核验:全部旧样本仍保留原始时间,1,784 条原输出在这些时刻数值完全一致,最终状态和全部下列积分计数也一致。这支持本次为输出/对照语义修改,没有改变八路积分轨迹。
| 项目 | 循环:修改前 → 修改后 | 非循环:修改前 → 修改后 |
| --- | --- | --- |
| 实际保存点数 | 5,010 → 5,028 | 5,002 → 5,006 |
| 接受步数 | 19,606 → 19,606 | 11,238 → 11,238 |
| 拒步计数 | 1,552 → 1,552 | 885 → 885 |
| 方程求值 | 85,570 → 85,570 | 56,299 → 56,299 |
| 求解器启动次数 | 20 → 20 | 5 → 5 |
| 雅可比刷新 | 1,835 → 1,835 | 1,270 → 1,270 |
| 线性 setup 次数 | 6,028 → 6,028 | 3,603 → 3,603 |
| 求解耗时,单次 | 11.945 → 11.572 s | 7.357 → 7.469 s |
| 平台进程耗时,单次 | 18.339 → 17.851 s | 13.638 → 13.869 s |
这些单次耗时有运行波动,不能据此声称性能提升或给出可靠开销百分比;可以确认没有新增积分重启与 RHS 求值。新增保存和输出重放仍有实际工作量。
## 7. 后续判断与复现
输出阶段误配已消除,可将这两组作为接下来修改的基线。继续判断循环接触力峰前,应在同一实际时刻或足够细的共同时间窗口核对位移、速度、间隙和接触力,区分保存时间偏移、动态响应及接触事件定位的影响;现有结果不支持直接把全部力峰差归因于接触事件缺失。
汇总证据:[前后效果对照](../../test/output-semantics-20260917/effect-summary.json)、[修改后运行汇总](../../test/output-semantics-20260917/after/summary.json)、[循环阶段配对](../../test/output-semantics-20260917/after/full/phase-pairing.json)、[非循环阶段配对](../../test/output-semantics-20260917/after/noncyclic/phase-pairing.json)。
```powershell
.\.venv-win\Scripts\python.exe -X utf8 tests/manual/evaluate_mql8_correctness.py --output test/output-semantics-rerun --ame-home F:/AMESim2404/Amesim --align-cyclic-from-ame --noncyclic-ame test/node-fixes-amesim-20260914/test_mql.ame --noncyclic-project tests/data/test-mql-8-corrected.json --profiles full noncyclic
```
输出目录必须是新目录。`--native-source` 可指定本次冻结源码作修改前对照;`tests/manual/summarize_output_semantics.py` 核验 before/after 两组结果。原始结果位于 Git 忽略的 `test/output-semantics-20260917/`;代码、测试与本报告为可跟踪交付。