Files
SystemSimulationApp/docs/other/MASS与LSTP事件独立实验及八路对比-2026-09-17.md
T
ljz 7611f13208 修复循环信号与事件采样并接入 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 通过。
2026-09-17 23:50:13 +08:00

172 lines
17 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.
# MASS 与 LSTP 事件独立实验及八路对比
日期:2026-09-17。环境:Windows、本项目 Python 3.12、原生 C、CVODE BDF;组件专项同时覆盖 RK45。
## 1. 本次实验回答什么
以已经完成 UD00 边界修复、事件输出语义修改的当前平台为基线,独立比较 `off`、`mass`、`lstp`、`all` 四种配置。循环和非循环各运行 50 s;每种配置保留完整结果,再做 5 次轮换顺序的纯求解计时。
**实验实现放在 `tests/manual/`,没有把新事件启用到默认平台。已有信号修复、输出语义、组件公式、雅可比分色及物性复用保留。** 因此本文的“未修改”特指本轮新增机械事件关闭,不是回退到此前有信号边界问题的版本。
MASS 的新增事件在当前八路工况中没有带来精度改善,纯求解耗时中位数增加 **31%–34%**。LSTP 的非循环最大力差降低 **9.90%**,本次耗时没有明显增加,但循环工况 32.4 s 的主要力差没有改善,部分其他误差反而增大。两类一起开启,精度与只开 LSTP 相同,耗时增加 **22%–23%**。
## 2. 独立实现与隔离方式
当前 `native/` 冻结为 `test/mechanical-events-20260917/source-control/native/`。`off` 直接用这个副本;其他配置用另一份副本追加实验运行代码,编译缓存、可执行文件、结果存储均放在本次实验目录。
[实验程序构建](../../tests/manual/mechanical_event_variant.py)在原生成源码后追加事件描述与释放驱动力求值入口。每次构建均断言原生成源码仍是逐字相同的前缀,状态键、求值调度和雅可比稀疏结构一致。正常 RHS、Jacobian 和物性缓存路径没有替换。八路仍为 132 个状态、1,784 个输出、27 个雅可比颜色。
生产源码的前后 SHA-256 核验、原模型前缀核验与积分计数用于区分“新增事件改变积分轨迹”和“破坏已有优化”。这些检查不代表新事件本身没有计算成本。
最终核验:46 个生产源码文件前后哈希相同,控制副本与当前 `native/` 相同;所有配置仍采用 `colored-difference` 和输出语义 v2。两组 `off` 的全部比较数组与上一轮输出语义基线完全一致。见[隔离及结果核验](../../test/mechanical-events-20260917/baselines/evidence-verification.json)与[生产源码哈希](../../test/mechanical-events-20260917/baselines/production-verification.json)。
### MASS
- 弹性上下限:分别检查 `xmin - x`、`x - xmax` 过零,定位接触和脱离。
- 非负接触力模式:在接触区内额外检查未截断力 `K*p + D(p)*v_relative` 过零。允许负力的模式不添加这个截断事件。
- 理想/恢复限位保持后的释放:在已贴限位、速度接近零时,检查不施加限位约束的加速度是否转向允许运动的方向。
- 原有碰撞、恢复系数和摩擦事件继续按原逻辑处理。弹性事件不重置速度或位置;保持后的释放从约束位置、零速度继续。
为隔离已有优化,释放驱动力来自独立整模型求值,没有修改原 RHS 以共享中间量。`releaseRhsCalls` 单独记录这项成本,并计入 `nfev`。这是**本实验实现**的代价,不是所有 MASS 事件实现必然付出的代价。
### LSTP
按原公式的同一运算顺序计算 `gap = gap0 + x2 - x1`,检查 `-gap` 的过零。非负力模式再检查接触区内的原始力过零;允许负力时不检查力截断。事件不施加硬碰撞式速度重置。
### 公共定位与输出
[实验运行库](../../tests/manual/mechanical_events_runtime.c)在积分接受步的密集插值上二分定位;浮点区间不可再分时停止。同一浮点时刻发生的事件合并提交并重启一次。仅在事件真正接受后更新防重复触发记录;试算、雅可比求值和输出重放不更新物理模式,输出仍由原公式计算。
相对速度换向时,先按换向点分段找间隙根,以覆盖步首尾间隙同号但中间接触/脱离的情况;孤立切触不制造虚假来回事件。这仍依赖积分步已经解析运动,不能保证捕获一个接受步内任意多次未解析的高频振荡。根的二分精度也不等于积分状态精度。
沿用上一轮 `outputSemantics.version=2`:记录事件左邻时刻和接受后的事件时刻。没有调整比较点来挑选误差更小的力值。
## 3. 组件独立验证
验证包括解析解、物理守恒、现有 Amesim 参考回路和无事件回归,代码见[专项测试](../../tests/test_mechanical_event_experiment.py)。
| 测试 | 验证依据 |
| --- | --- |
| MASS 弹性上下限 | 阻尼振子的解析接触持续时间及出界速度;两个最大步长、BDF/RK45 |
| MASS 保持后释放 | 连续斜坡驱动,1 s 释放;上下限镜像,最终速度和位置解析值 |
| MASS 原有恢复碰撞 | 恢复系数 0.5;与事件关闭版逐样本、最终状态和启动次数对照 |
| LSTP 两质量弹性碰撞 | 解析接触/脱离时刻、速度交换、总动量和动能加弹性势能 |
| MASS/LSTP 非负力 | 接触区内力截断事件、非负输出、MASS 截断时刻解析值 |
| 指数阻尼与两种力模式 | MASS/LSTP、BDF/RK45、extended 生成路径,检查完成且无事件抖振 |
| 无接触、初始贴边静止、持续接触 | 无多余重启,原始输出与关闭版完全一致 |
| 同号间隙与切触 | 已知二次多项式密集输出:准确找到 0.4/0.6 s 两根,切触不造事件 |
| 已有 Amesim 回路 | `friction_ideal`、`friction_elastic`、`joint_mechanical`,按现有参考值核验 |
弹性接触时刻/速度允许误差 2e-6,连续释放时刻 1e-8 s,解析截断时刻 3e-6 s;守恒断言另设独立公差。Amesim 参考来自现有 `amesim-component-semantics-2404.json`,这里不声称重新测出了 Amesim 的内部根定位算法。八路则使用本轮重新运行的 Amesim 结果。
**9 个测试方法全部通过**,覆盖 38 种模型/配置/求解器组合,另含 2 个解析密集输出场景。按开发顺序分批执行,力截断条件补全后专门复跑相关测试;日志有重复方法,不能把各批数量直接相加。证据:[首批 6 项](../../test/mechanical-events-20260917/isolated-verified.log)、[截断复测及参考回归 3 项](../../test/mechanical-events-20260917/independent-reference-tests.log)、[恢复碰撞回归 1 项](../../test/mechanical-events-20260917/restitution-regression.log)。
## 4. 八路比较口径
循环参照为 `tests/data/test_mql.ame`,非循环参照为已审计的 `test/node-fixes-amesim-20260914/test_mql.ame`。输入用上轮已对齐的工程副本,原 AME 和用户工程不修改。每个工况重新执行一次 Amesim,作为四种配置共同的参考;平台 BDF、0–50 s、输出间隔 0.01 s、误差限数值 1e-8。
八路包含 10 个 MASS:9 个无限位、1 个理想限位,没有弹性限位 MASS;8 个 LSTP 均允许负力,接触刚度与阻尼均为 1e11,指数阻尼距离约 1e-7 m。因此八路不覆盖全部新增模式,必须结合前面的组件测试判断。
每个比较点先核验 8 个 STEP 和 2 个 UD00 的完整驱动组合,再让全部 238 条曲线共用同一对真实保存行,不跨信号跳变插值。另检查八个 `gap < 0` 标志。信号阶段匹配不等于两边浮点时间完全相同,也不代表验证了网格之间的全部接触事件。
全部 8 次准确性运行均正常结束,全部比较输出有限;各自 **5,001/5,001 个时刻成功配对,信号最大差为 0,接触/分离标志不匹配为 0**。没有删除未匹配点来改善指标。
## 5. 八路准确性结果
### 汇总
下表列 `off → lstp`。`mass` 在 238 条已比较曲线上与 `off` 完全一致,`all` 与 `lstp` 完全一致,因此不重复相同列。
| 指标 | 循环:off → lstp | 非循环:off → lstp |
| --- | --- | --- |
| 最大接触力绝对差,N | 1,285,489.483041 → 1,285,489.485624 | 1.456532 → **1.312403** |
| 上项发生时间,s | 32.4 → 32.4 | 0.01 → 0.01 |
| 平静段最大力差,N | 0.275890 → **0.212043** | 0.275890 → **0.154170** |
| 最大压力差,Pa | 65.686768 → **61.105785** | 65.686768 → **61.105785** |
| 最大温度差,K | 0.395395 → **0.389714** | 0.395395 → **0.389714** |
| 最大间隙差,m | 1.293005e-8 → **5.474060e-8,增大** | 1.293005e-8 → **1.581826e-8,增大** |
| 最大质量流量差,kg/s | 1.326797e-5 → **2.424649e-5,增大** | 5.663171e-6 → **2.424649e-5,增大** |
| 最大焓流差,W | 141.920203 → **18.688805** | 141.920203 → **18.688805** |
| 明确非零且相对差超过 5% 的曲线样本数 | 56 → **32** | 30 → **6** |
“平静段”沿用已有定位统计:t≥0.1 s,避开信号边界前后 0.02 s;它不能替代包含事件点的完整指标。5% 是诊断筛查线,不是工程验收公差。循环的 32 个超线样本仍含接触力 24、速度 2、质量流 4、焓流 2;非循环剩余质量流 4、焓流 2。
最大压力差降低约 6.97%,温度差降低约 1.44%;循环/非循环平静段最大力差分别降低约 23.14%/44.12%。但间隙和质量流量的最大绝对差增大,因此不能称为所有指标全面改善。新增最大流量差发生在 0.09 s、`amesim_pn3node2_1.reference_mass_flow`;该点参考流量约 0.02098 kg/s,绝对差约为参考值的 0.116%。原有小流量样本的相对差计数减少,与这一绝对误差增大可以同时发生。
### 八个支路分别看
以下均为各支路完整 0–50 s 网格的最大绝对力差,单位 N。支路编号对应 `amesim_lstp00a_1…8`。循环均发生在 32.4 s,非循环均发生在 0.01 s。
| 支路 | 循环 off | 循环 lstp | 非循环 off | 非循环 lstp |
| --- | ---: | ---: | ---: | ---: |
| 1 | 1,285,489.480 | 1,285,489.479 | 1.450464 | 1.306552 |
| 2 | 1,285,489.483 | 1,285,489.479 | 1.456532 | 1.312398 |
| 3 | 1,285,489.482 | 1,285,489.486 | 1.456530 | 1.312403 |
| 4 | 1,285,489.478 | 1,285,489.480 | 1.450460 | 1.306567 |
| 5 | 1,285,489.475 | 1,285,489.483 | 1.447450 | 1.299400 |
| 6 | 1,285,489.475 | 1,285,489.481 | 1.446239 | 1.298499 |
| 7 | 1,285,489.477 | 1,285,489.478 | 1.446238 | 1.298504 |
| 8 | 1,285,489.478 | 1,285,489.477 | 1.447445 | 1.299415 |
非循环八路均改善,循环八路的大力差均基本不变。完整精度数据见[汇总](../../test/mechanical-events-20260917/baselines/effect-summary.json)、[逐支路](../../test/mechanical-events-20260917/baselines/branch-force-summary.json)、[全部物理量分组](../../test/mechanical-events-20260917/baselines/group-summary.json)。
### 实际新增了哪些事件
两组工况都只有 8 个新增 LSTP 接触事件,全部发生在 **6.5966840909145208e-9 s**,合并为一次积分重启;之后没有检测到新的 LSTP 接触/脱离。当前采用允许负力模式,因此没有力截断事件。
两组都没有新增 MASS 弹性接触或连续释放事件。当前模型没有弹性限位 MASS;理想限位的相关驱动跳变已有时间事件负责重新启动,没有额外触发本次连续释放根。不能用“本模型未触发”推断其他驱动下不需要释放事件;连续斜坡测试已验证释放能正确发生。
循环 32.4 s 仍使用平台实际时刻 `32.400000000000006` 和 Amesim `32.40000000000221`。驱动阶段一致,但约 2.20e-12 s 的实际时间差与高刚度连续状态的影响仍未分离。新增的启动间隙事件不能替代对此的检查。
额外事件保存点的最大绝对接触力仍约为循环 **2.084e14 N**、非循环 **4.035e11 N**,与 `off` 基本同量级;这些点没有同分辨率 Amesim 参考,未计入上述准确性判断。
## 6. 求解耗时与成本来源
每组、每配置运行 **5 次纯求解**,轮换配置顺序。计时排除编译和结果重放/序列化;完整输出准确性运行另存。下表为墙钟中位数,括号为五次最小–最大值,百分比相对本次同工况 `off`,不与上轮不同时间运行的单次秒数混比。
| 配置 | 循环耗时,s | 相对 off | 非循环耗时,s | 相对 off |
| --- | ---: | ---: | ---: | ---: |
| off | 14.334(14.209–14.664) | — | 9.583(8.978–10.293) | — |
| mass | 19.220(18.035–20.428) | **+34.09%** | 12.565(12.190–14.599) | **+31.12%** |
| lstp | 13.605(13.369–15.221) | **−5.09%** | 8.871(8.661–9.044) | **−7.43%** |
| all | 17.697(17.003–19.600) | **+23.46%** | 11.653(11.246–11.852) | **+21.60%** |
LSTP 的运行范围与基线有重叠,五次试验不构成普遍提速保证;本次没有明显增加耗时,且积分步数下降。MASS 的范围与基线明显分离,额外开销同时有计算次数支持。各配置五次计时的积分计数完全重复,并与完整输出运行一致。
| 工况/配置 | 接受步 | 拒步 | RHS 求值 nfev | 求解器启动 | 额外释放驱动力求值 |
| --- | ---: | ---: | ---: | ---: | ---: |
| 循环 off | 19,606 | 1,552 | 85,570 | 20 | 0 |
| 循环 mass | 19,606 | 1,552 | 122,240 | 20 | **36,670** |
| 循环 lstp | 16,934 | 1,137 | 81,067 | 21 | 0 |
| 循环 all | 16,934 | 1,137 | 112,331 | 21 | 31,264 |
| 非循环 off | 11,238 | 885 | 56,299 | 5 | 0 |
| 非循环 mass | 11,238 | 885 | 78,561 | 5 | **22,262** |
| 非循环 lstp | 9,980 | 742 | 54,412 | 6 | 0 |
| 非循环 all | 9,980 | 742 | 74,172 | 6 | 19,760 |
LSTP 循环/非循环分别执行 135,472/79,840 次元件步检查、2,196/963 次密集插值调用,实际只增加一次事件重启;其检查直接使用状态,不调用整模型 RHS。MASS 单独开启时,轨迹、步数和原有重启次数没变,多出的 nfev 恰好等于释放驱动力整模型求值次数。这解释了为什么“没有新事件发生”仍可能有明显耗时。
CPU 时间中位数也支持同一方向:循环 off/mass/lstp/all 为 13.891/18.266/13.062/16.984 s,非循环为 9.328/11.969/8.609/11.281 s。全部独立计时见[循环](../../test/mechanical-events-20260917/baselines/full/timings.json)、[非循环](../../test/mechanical-events-20260917/baselines/noncyclic/timings.json)。
## 7. 结论适用范围与下一步
1. **当前八路不宜直接把本实验 MASS 释放检查作为默认路径。** 其新增事件在这两组工况中没有触发,结果不变而存在额外计算。对于连续驱动力导致的限位释放,专项解析测试证明事件机制有作用;后续若集成,应优先从已有 RHS 获取释放驱动力,或仅计算必要依赖,再重新计时。
2. **LSTP 可以作为后续生产集成候选,但本次仍保留在实验中。** 它补齐了接触边界定位,部分误差降低,间隙和质量流量最大误差也有回退;不能据此声称循环八路的主要力差已解决,也不能把这一模型中的耗时结果推广到频繁接触/脱离的模型。正式集成前应根据展示关注量确认这些取舍。
3. **循环力峰仍应检查同一实际时刻的连续状态。** 32.4 s 的信号阶段已经一致,新增间隙事件仍未消除差异。下一步应核对细时间窗中的位移、速度、间隙和力,区分实际保存时刻偏移、高刚度响应及已有硬限位处理的影响。
纳秒级启动事件的定位时刻是本次平台数值轨迹上的根,没有同分辨率 Amesim 根时刻验证。额外事件保存点的巨大力峰同样保留,没有平滑或删除,也没有把缺少同分辨率参考的峰值当成准确性结论。
## 8. 复现与证据
[运行说明](../../tests/manual/mechanical_events_experiment.md)、[八路运行脚本](../../tests/manual/evaluate_mechanical_events.py)、[指标汇总脚本](../../tests/manual/summarize_mechanical_events.py)。
```powershell
.\.venv-win\Scripts\python.exe -X utf8 -m unittest tests.test_mechanical_event_experiment -v
.\.venv-win\Scripts\python.exe -X utf8 tests/manual/evaluate_mechanical_events.py --output test/mechanical-events-new-run --repeats 5
.\.venv-win\Scripts\python.exe -X utf8 tests/manual/summarize_mechanical_events.py test/mechanical-events-new-run
```
八路脚本依赖本工作站 Amesim 2404 及已有对齐工程;主输出目录必须是新目录。构建阶段出现过 Windows 缓存发布拒绝与 GCC 子进程启动/停滞,保留已完成运行后续跑,最后一次恢复使用 `--resume --serial-build`。串行选项只改变实验构建调度,不改变编译参数、模型、事件实现或求解器设置;构建及其等待均不计入上述纯求解时间。
本轮完整数据位于 Git 忽略的 `test/mechanical-events-20260917/`;代码、测试和本文可跟踪保存。每个配置目录有 `comparison.json`、`curves.npz`、`phase-pairing.json`、完整原始结果、事件日志及五次计时目录。