修复循环信号与事件采样并接入 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
@@ -373,6 +373,11 @@ def _compile_storage_anchored_program(network: SimulationNetwork) -> NativeProgr
|
||||
raise NativeCapabilityError(f"Native output coverage is incomplete: {sorted(missing)}")
|
||||
|
||||
stops = [(si(c, "v"), c.xmin, c.xmax) for c in masses if int(c.stoptype) == 1]
|
||||
from .contacts import contact_table
|
||||
contact_source, contact_header = contact_table([
|
||||
(si(mass_at(c, 'port_1'), 'v'), si(mass_at(c, 'port_2'), 'v'),
|
||||
c.gap0, c.kcont, c.rcont, c.Pdis, int(c.discContactOption), 1)
|
||||
for c in components if c.model_type == 'amesim_lstp00a'])
|
||||
stop_c = ",".join(f"{{{v},{_number(lo)},{_number(hi)},0,0,0,0}}" for v, lo, hi in stops) or "{0,0,0,0,0,0,0}"
|
||||
next_event = []
|
||||
for index, c in signal_specs:
|
||||
@@ -384,6 +389,7 @@ def _compile_storage_anchored_program(network: SimulationNetwork) -> NativeProgr
|
||||
source = '\n'.join([
|
||||
'#include "model.h"', '#include <math.h>', *declarations,
|
||||
f"const NativeStop model_stops[{max(1,len(stops))}] = {{{stop_c}}};",
|
||||
contact_source,
|
||||
f"const double model_atol[NSTATES] = {{{','.join(map(state_absolute_tolerance, state_keys))}}};",
|
||||
"const char *const model_output_keys[NOUTPUTS] = {" + ",".join(json.dumps(v.key, ensure_ascii=True) for v in variables) + "};",
|
||||
"int model_init(double *y) {", *init, "return 1; }",
|
||||
@@ -408,6 +414,7 @@ int model_property_temperatures(double t,const double *y,NativePropertyTemperatu
|
||||
#define NSTATES {len(state_keys)}
|
||||
#define NOUTPUTS {len(variables)}
|
||||
#define NSTOPS {len(stops)}
|
||||
{contact_header}
|
||||
extern const NativeStop model_stops[{max(1,len(stops))}];
|
||||
extern const double model_atol[NSTATES];
|
||||
extern const char *const model_output_keys[NOUTPUTS];
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
"""Emit state-only LSTP event descriptors for both native lowering paths."""
|
||||
from .compiler import _number
|
||||
|
||||
|
||||
def contact_table(contacts):
|
||||
"""Rows: velocity indices, gap, stiffness, damping, depth, force option,
|
||||
subtract-first flag. Keep the force expression's floating operation order.
|
||||
Position follows velocity in each reviewed mechanical state pair.
|
||||
"""
|
||||
rows = []
|
||||
for v1, v2, gap, stiffness, damping, depth, option, subtract_first in contacts:
|
||||
rows.append('{' + ','.join((str(v1), str(v2), _number(gap),
|
||||
_number(stiffness), _number(damping), _number(depth),
|
||||
str(option), str(subtract_first))) + '}')
|
||||
count = len(rows)
|
||||
header = f'''#define NCONTACTS {count}
|
||||
typedef struct {{
|
||||
int velocity1, velocity2;
|
||||
double gap0, stiffness, damping, depth;
|
||||
int signed_force, subtract_first;
|
||||
}} NativeContact;
|
||||
extern const NativeContact model_contacts[{max(1, count)}];'''
|
||||
source = f'const NativeContact model_contacts[{max(1, count)}] = {{' + (','.join(rows) or '{0,0,0,0,0,0,0,0}') + '};'
|
||||
return source, header
|
||||
@@ -723,6 +723,12 @@ def compile_extended_program(network):
|
||||
policy='immutable canonical baseline for gas, PH inversion, density and pipe roots; changed inputs recomputed',
|
||||
verification='uncached canonical dense differences')
|
||||
np,ng,nq=max(1,len(pgroups)),max(1,gas_count),max(1,len(pneu))
|
||||
from .contacts import contact_table
|
||||
contact_source, contact_header = contact_table([
|
||||
(states[mass_groups[groups.find(ep(c, 'port_1'))][0].name, 'v'],
|
||||
states[mass_groups[groups.find(ep(c, 'port_2'))][0].name, 'v'],
|
||||
c.gap0, contact_stiffness(c), c.rcont, c.Pdis, int(c.discContactOption), 0)
|
||||
for c in components if c.model_type == 'amesim_lstp00a'])
|
||||
# Advanced-friction reference runs at 5 N and 7 N confirm Amesim 2404's
|
||||
# 0.1% breakaway hysteresis. Simple friction uses the exact static threshold.
|
||||
source='\n'.join(['#include "model.h"','#include <math.h>','#include <string.h>',*declarations,
|
||||
@@ -731,6 +737,7 @@ def compile_extended_program(network):
|
||||
num(sum(c.fstick*(1.001 if int(c.frictionType)==2 else 1) for c in dry))+'}'
|
||||
for group,dry,threshold in friction_groups) or '{0,0,0,0}')+'};',
|
||||
f'const NativeStop model_stops[{max(1,len(stops))}] = {{'+(','.join('{'+str(s[0])+','+','.join(num(v) for v in s[1:])+'}' for s in stops) or '{0,0,0,0,0,0,0}')+'};',
|
||||
contact_source,
|
||||
'const double model_atol[NSTATES] = {'+','.join(map(state_absolute_tolerance, state_keys or ['dummy']))+'};',
|
||||
'const char *const model_output_keys[NOUTPUTS] = {'+(','.join(json.dumps(v.key,ensure_ascii=True) for v in variables) or '""')+'};',
|
||||
*jacobian.source_lines(),
|
||||
@@ -774,6 +781,7 @@ int model_property_temperatures(double t,const double *y,NativePropertyTemperatu
|
||||
#define NOUTPUTS {max(1,len(variables))}
|
||||
#define NSTOPS {len(stops)}
|
||||
#define NFRICTIONS {len(friction_groups)}
|
||||
{contact_header}
|
||||
extern const NativeFriction model_frictions[{max(1,len(friction_groups))}];
|
||||
int model_friction_drives(double t,const double *y,double *drives);
|
||||
extern const NativeStop model_stops[{max(1,len(stops))}];
|
||||
|
||||
Reference in new issue
Block a user