修复循环信号与事件采样并接入 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:
1 parent
1aac220084
commit
7611f13208
85 files changed
+11358
-33
No files matched your search
@@ -0,0 +1,49 @@
|
||||
"""Pair saved samples by forcing phase, never by the size of output errors.
|
||||
|
||||
All curves share ONE pair of row indices. No interpolation across jumps, no
|
||||
time shifting, and no use of force/pressure agreement to select a sample.
|
||||
The reference's nearest saved grid row is authoritative; a different native
|
||||
row is allowed only in the tiny output-timestamp roundoff window.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
def pair_saved_phases(native_times, reference_times, native_signals, reference_signals, grid, step):
|
||||
nt, rt, grid = map(np.asarray, (native_times, reference_times, grid))
|
||||
ns, rs = map(np.asarray, (native_signals, reference_signals))
|
||||
if ns.shape != (len(nt), rs.shape[1]) or len(rs) != len(rt):
|
||||
raise ValueError('Phase signatures must be rows by the same signal columns.')
|
||||
tolerance = step * 1e-7
|
||||
ni = np.full(len(grid), -1, dtype=int)
|
||||
ri = np.full(len(grid), -1, dtype=int)
|
||||
records = []
|
||||
for j, t in enumerate(grid):
|
||||
candidates = np.arange(np.searchsorted(nt, t-tolerance, side='left'),
|
||||
np.searchsorted(nt, t+tolerance, side='right'))
|
||||
references = np.arange(np.searchsorted(rt, t-tolerance, side='left'),
|
||||
np.searchsorted(rt, t+tolerance, side='right'))
|
||||
if not len(candidates) or not len(references):
|
||||
records.append(dict(gridIndex=j, time=float(t), status='missing-saved-sample'))
|
||||
continue
|
||||
# Prefer the later row on an exact tie / duplicate timestamp, matching
|
||||
# the comparison's existing right-side duplicate policy.
|
||||
ref = min(references, key=lambda i: (abs(rt[i]-t), -int(i)))
|
||||
closest = min(candidates, key=lambda i: (abs(nt[i]-t), -int(i)))
|
||||
matches = candidates[np.all(np.isclose(ns[candidates], rs[ref], rtol=1e-12, atol=1e-12), axis=1)]
|
||||
ri[j] = ref
|
||||
if not len(matches):
|
||||
records.append(dict(gridIndex=j, time=float(t), status='unmatched-forcing-phase',
|
||||
referenceTime=float(rt[ref]), referenceSignals=rs[ref].tolist(),
|
||||
nativeCandidateTimes=nt[candidates].tolist(),
|
||||
nativeCandidateSignals=ns[candidates].tolist()))
|
||||
continue
|
||||
chosen = min(matches, key=lambda i: (abs(nt[i]-t), -int(i)))
|
||||
ni[j] = chosen
|
||||
if chosen != closest:
|
||||
records.append(dict(gridIndex=j, time=float(t), status='matched-other-event-side',
|
||||
platformTime=float(nt[chosen]), referenceTime=float(rt[ref]),
|
||||
originalPlatformTime=float(nt[closest]),
|
||||
signals=ns[chosen].tolist(), referenceSignals=rs[ref].tolist()))
|
||||
return ni, ri, records
|
||||
Reference in new issue
Block a user