修复循环信号与事件采样并接入 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
+32
-5
@@ -86,6 +86,16 @@ int native_append(NativeRun *r, double t, const double *y) {
|
||||
return native_samples_append(r,t,y);
|
||||
}
|
||||
|
||||
/* The integrators already stop at the left-adjacent double of an internal
|
||||
* time event. Preserve that actual endpoint and the continuous state at the
|
||||
* event, so output replay can evaluate BOTH forcing phases without snapping
|
||||
* a regular-grid timestamp or changing integration history. */
|
||||
int native_time_boundary_samples(NativeRun *r,double boundary,const double *state) {
|
||||
if (!r->options.record_samples || boundary>=r->options.stop) return 1;
|
||||
return native_samples_append(r,nextafter(boundary,-INFINITY),state) &&
|
||||
native_samples_append(r,boundary,state);
|
||||
}
|
||||
|
||||
/* Amesim helium data domains: EOS, ideal Cp/h, viscosity. Warnings describe
|
||||
* the property use, not a component. Trial/Newton/Jacobian evaluations never
|
||||
* publish warnings; replay of output samples is also side-effect free. */
|
||||
@@ -166,12 +176,14 @@ static double locate_breakaway(NativeRun *r,int index,double left,double right,
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "contact_events.h"
|
||||
|
||||
int native_accept(NativeRun *r, double t, double next, const double *old,
|
||||
const double *trial, NativeDense dense, void *context,
|
||||
double *accepted_time, double *accepted_state) {
|
||||
double when[2*(NSTOPS+NFRICTIONS+1)], bounds[2*(NSTOPS+NFRICTIONS+1)];
|
||||
double restitution[2*(NSTOPS+NFRICTIONS+1)], thresholds[2*(NSTOPS+NFRICTIONS+1)];
|
||||
int indices[2*(NSTOPS+NFRICTIONS+1)], friction[2*(NSTOPS+NFRICTIONS+1)], count=0;
|
||||
double when[2*(NSTOPS+NFRICTIONS+NCONTACTS+1)], bounds[2*(NSTOPS+NFRICTIONS+NCONTACTS+1)]={0};
|
||||
double restitution[2*(NSTOPS+NFRICTIONS+NCONTACTS+1)]={0}, thresholds[2*(NSTOPS+NFRICTIONS+NCONTACTS+1)]={0};
|
||||
int indices[2*(NSTOPS+NFRICTIONS+NCONTACTS+1)], friction[2*(NSTOPS+NFRICTIONS+NCONTACTS+1)], count=0;
|
||||
for (int j=0;j<NSTOPS;j++) {
|
||||
NativeStop s=model_stops[j]; int v=s.velocity_index, x=v+1;
|
||||
double vt0=1e-12*fmax(fabs(old[v]),1), vt1=1e-12*fmax(fabs(trial[v]),1);
|
||||
@@ -219,6 +231,9 @@ int native_accept(NativeRun *r, double t, double next, const double *old,
|
||||
bounds[count]=restitution[count]=thresholds[count]=0;count++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if NCONTACTS
|
||||
if(!contact_candidates(r,t,next,old,trial,dense,context,when,indices,friction,&count)) return -1;
|
||||
#endif
|
||||
double stop=next;
|
||||
for (int i=0;i<count;i++) stop=fmin(stop,when[i]);
|
||||
@@ -232,8 +247,17 @@ int native_accept(NativeRun *r, double t, double next, const double *old,
|
||||
}
|
||||
if (count) {
|
||||
if (!dense(context,stop,accepted_state)) return -1;
|
||||
/* Keep the last representable pre-event sample before applying a
|
||||
* reset. Discrete modes are part of the saved state, never replayed
|
||||
* from a mutable global mode. An event at the current step start has
|
||||
* no new left interval; do not invent or back-date a sample. */
|
||||
double before=nextafter(stop,-INFINITY);
|
||||
if (r->options.record_samples && before>=t && before<stop) {
|
||||
double sy[NSTATES];
|
||||
if (!dense(context,before,sy) || !native_samples_append(r,before,sy)) return -1;
|
||||
}
|
||||
for (int i=0;i<count;i++) if (fabs(when[i]-stop)<=1e-12*fmax(fabs(stop),1)) {
|
||||
if(friction[i]>=0) continue;
|
||||
if(friction[i]!=-1) continue;
|
||||
double incoming=accepted_state[indices[i]];
|
||||
accepted_state[indices[i]]=fabs(incoming)<=thresholds[i]?0:-restitution[i]*incoming;
|
||||
accepted_state[indices[i]+1]=bounds[i];
|
||||
@@ -242,7 +266,7 @@ int native_accept(NativeRun *r, double t, double next, const double *old,
|
||||
/* Stop/reverse only at an accepted event. The discrete mode travels
|
||||
* with saved states so replayed results and Jacobian trials are pure. */
|
||||
double drives[NFRICTIONS];
|
||||
for(int i=0;i<count;i++) if(friction[i]<0 && fabs(when[i]-stop)<=1e-12*fmax(fabs(stop),1)) {
|
||||
for(int i=0;i<count;i++) if(friction[i]==-1 && fabs(when[i]-stop)<=1e-12*fmax(fabs(stop),1)) {
|
||||
for(int j=0;j<NFRICTIONS;j++) if(model_frictions[j].velocity_index==indices[i]) {
|
||||
double velocity=accepted_state[indices[i]];
|
||||
accepted_state[model_frictions[j].mode_index]=velocity>0?1:(velocity<0?-1:0);
|
||||
@@ -254,6 +278,9 @@ int native_accept(NativeRun *r, double t, double next, const double *old,
|
||||
accepted_state[f.velocity_index]=0;
|
||||
accepted_state[f.mode_index]=fabs(drives[j])>f.breakaway_force ? (drives[j]>0?1:-1) : 0;
|
||||
}
|
||||
#endif
|
||||
#if NCONTACTS
|
||||
contact_commit(r,stop,accepted_state,when,indices,friction,count);
|
||||
#endif
|
||||
if (!native_append(r,stop,accepted_state)) return -1;
|
||||
while (r->options.start+r->sample_index*r->options.sample_step<=stop) r->sample_index++;
|
||||
|
||||
Reference in new issue
Block a user