相较上一版 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 通过。
40 lines
2.8 KiB
C
40 lines
2.8 KiB
C
/* Compile against an experiment's generated model/support, not production. */
|
|
#include <local_probe_support.c>
|
|
#define CHECK(x) do{if(!(x)){fprintf(stderr,"guard self-test failed line %d\n",__LINE__);return 1;}}while(0)
|
|
int main(void){
|
|
lp_start();CHECK(saved && lp_mask);
|
|
int group=-1,region=-1;
|
|
for(int g=0;g<LP_NC && group<0;g++)if(lp_mask&(UINT64_C(1)<<g))for(int p=0;p<LP_NO;p++)if(lp_plan[g][p]>=0){group=g;region=lp_plan[g][p];break;}
|
|
CHECK(group>=0);lp_color=group;lp_active=group+1;
|
|
double y[NSTATES]={0},p[LP_NP]={0},h[LP_NQ]={0},q[LP_NQ]={0},w[NOUTPUTS]={0},fb[LP_NFB]={0};
|
|
NativePropertyState states[LP_NPS]={0};
|
|
NativePipeCache pipes[LP_NPC]={0};NativeJacobianScalars jacobian={0};
|
|
NativePropertyCache context={.states=states,.count=1,.capacity=LP_NPS,.jacobian=&jacobian};
|
|
states[0].p=123;states[0].T=456;states[0].valid=NATIVE_PROPERTY_PT;states[0].jacobian=&jacobian;
|
|
lp_begin(.5,y);lp_snapshot(lp_before[region],&context,pipes);
|
|
states[0].rho=42;states[0].valid|=NATIVE_PROPERTY_RHO;
|
|
lp_snapshot(lp_after[region],&context,pipes);
|
|
lp_save(p,h,q,w,fb);lp_ready(1);
|
|
CHECK(lp_valid(.5,y));CHECK(!lp_valid(nextafter(.5,1),y));
|
|
int own=-1,other=-1;
|
|
for(int i=0;i<NSTATES;i++){if(lp_colors[i]==group)own=i;else other=i;}
|
|
CHECK(own>=0 && other>=0);y[own]=1;CHECK(lp_valid(.5,y));y[other]=1;CHECK(!lp_valid(.5,y));y[other]=0;
|
|
Snapshot *before=&saved->snapshots[lp_before[region]],*after=&saved->snapshots[lp_after[region]];
|
|
context.count=before->count;memcpy(states,before->states,before->count*sizeof(*states));memcpy(pipes,before->pipes,sizeof(pipes));
|
|
CHECK(lp_reuse(region,&context,pipes,p,h,q,w,fb));
|
|
CHECK(context.count==after->count && !memcmp(states,after->states,after->count*sizeof(*states)));
|
|
memcpy(states,before->states,before->count*sizeof(*states));context.count=before->count;
|
|
states[0].rho=nextafter(states[0].rho,1);CHECK(!lp_reuse(region,&context,pipes,p,h,q,w,fb));
|
|
memcpy(states,before->states,before->count*sizeof(*states));pipes[0].valid=1;CHECK(!lp_reuse(region,&context,pipes,p,h,q,w,fb));
|
|
memcpy(pipes,before->pipes,sizeof(pipes));context.count++;CHECK(!lp_reuse(region,&context,pipes,p,h,q,w,fb));
|
|
context.count=before->count;context.jacobian=NULL;CHECK(!lp_reuse(region,&context,pipes,p,h,q,w,fb));
|
|
int pure=-1;for(int r=0;r<LP_NR;r++)if(lp_before[r]==lp_after[r]){pure=r;break;}
|
|
CHECK(pure>=0);NativePropertyState held=states[0];NativePipeCache held_pipe=pipes[0];
|
|
size_t held_count=context.count;
|
|
CHECK(lp_reuse(pure,&context,pipes,p,h,q,w,fb));
|
|
CHECK(context.count==held_count && context.jacobian==NULL);
|
|
CHECK(!memcmp(&held,states,sizeof(held)) && !memcmp(&held_pipe,pipes,sizeof(held_pipe)));
|
|
lp_begin(.5,y);CHECK(!lp_valid(.5,y));
|
|
lp_finish();puts("exact context, pipe-cache, time, state and lifetime guards passed");return 0;
|
|
}
|