相较上一版 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 通过。
172 lines
17 KiB
Markdown
172 lines
17 KiB
Markdown
# 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`、完整原始结果、事件日志及五次计时目录。
|