高温氦气物性补全;三通四通能量计算bug修正

This commit is contained in:
ljz committed 2026-09-15 17:57:20 +08:00
1 parent 6fc9afe41d
commit 2b07d996cf
133 files changed
+5230 -253310

No files matched your search

+95 -20
View File
@@ -10,6 +10,7 @@
#include <sunmatrix/sunmatrix_dense.h>
#include <sunlinsol/sunlinsol_dense.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <sundials/sundials_math.h>
#ifndef MODEL_JACOBIAN_COLORED
@@ -195,59 +196,126 @@ static void counters(NativeRun *r, void *solver) {
CVodeGetNumLinRhsEvals(solver,&value); r->linear_rhs+=(unsigned long)value;
}
static void cv_snapshot(NativeRun *r,void *solver) {
CVodeGetCurrentTime(solver,&r->cvode_internal_time);
CVodeGetLastStep(solver,&r->cvode_last_step);
CVodeGetCurrentStep(solver,&r->cvode_next_step);
}
static void cv_failure(NativeRun *r,int flag,const char *operation) {
char message[256];
r->cvode_flag=flag;
snprintf(message,sizeof(message),"CVODE operation %s failed (return code %d) at simulation time %.17g s.",
operation,flag,r->final_time);
native_fail(r,"solver-error",operation,message);
}
#define CV_CHECK(call) do { int code_=(call); if(code_<0) { \
cv_failure(r,code_,#call); goto cleanup; } } while(0)
int native_bdf(NativeRun *r) {
SUNContext ctx=NULL;
if (SUNContext_Create(SUN_COMM_NULL,&ctx)) return 0;
if (SUNContext_Create(SUN_COMM_NULL,&ctx))
return native_fail(r,"initialization-failure","SUNContext_Create","Cannot create SUNDIALS context.");
N_Vector y=N_VNew_Serial(NSTATES,ctx), atol=N_VNew_Serial(NSTATES,ctx), scratch=N_VNew_Serial(NSTATES,ctx);
SUNMatrix matrix=NULL; SUNLinearSolver linear=NULL; void *solver=NULL;
int success=0;
int success=0, initialized=0;
CvContext context={.run=r};
if (!y || !atol || !scratch) goto cleanup;
const char *allocation="N_VNew_Serial";
if (!y || !atol || !scratch) goto allocation_failure;
memcpy(N_VGetArrayPointer(y),r->final_state,NSTATES*sizeof(double));
memcpy(N_VGetArrayPointer(atol),model_atol,NSTATES*sizeof(double));
matrix=SUNDenseMatrix(NSTATES,NSTATES,ctx);
if (!matrix) goto cleanup;
allocation="SUNDenseMatrix";
if (!matrix) goto allocation_failure;
linear=SUNLinSol_Dense(y,matrix,ctx);
if (!linear) goto cleanup;
allocation="SUNLinSol_Dense";
if (!linear) goto allocation_failure;
solver=CVodeCreate(CV_BDF,ctx);
if (!solver) goto cleanup;
allocation="CVodeCreate";
if (!solver) goto allocation_failure;
context.solver=solver;
double t=r->options.start;
if (CVodeInit(solver,cv_rhs,t,y)<0 || CVodeSetUserData(solver,&context)<0 ||
CVodeSVtolerances(solver,r->options.rtol,atol)<0 ||
CVodeSetLinearSolver(solver,linear,matrix)<0 ||
CVodeSetMaxStep(solver,r->options.max_step)<0) goto cleanup;
r->cvode_return_time=t;
CV_CHECK(CVodeInit(solver,cv_rhs,t,y));
initialized=1;
CV_CHECK(CVodeSetUserData(solver,&context));
CV_CHECK(CVodeSVtolerances(solver,r->options.rtol,atol));
CV_CHECK(CVodeSetLinearSolver(solver,linear,matrix));
CV_CHECK(CVodeSetMaxStep(solver,r->options.max_step));
#if MODEL_JACOBIAN_COLORED
if (valid_coloring()) {
context.weights=N_VClone(y);
if (!context.weights) goto cleanup;
allocation="N_VClone";
if (!context.weights) goto allocation_failure;
if (r->jacobian_verify) {
context.reference=SUNDenseMatrix(NSTATES,NSTATES,ctx);
if (!context.reference) goto cleanup;
allocation="SUNDenseMatrix (verification)";
if (!context.reference) goto allocation_failure;
}
context.colored=1; r->jacobian_colored=1;
if (CVodeSetJacFn(solver,cv_jacobian)<0) goto cleanup;
CV_CHECK(CVodeSetJacFn(solver,cv_jacobian));
}
#endif
r->starts++;
CvDense dense={solver,scratch};
while (t<r->options.stop) {
double boundary=model_next_break(t,r->options.stop);
if (!isfinite(boundary) || boundary<=t || boundary>r->options.stop) {
native_fail(r,"invalid-boundary","model_next_break","Model returned an invalid next time boundary.");
goto cleanup;
}
double end=boundary<r->options.stop?nextafter(boundary,-INFINITY):boundary;
if (CVodeSetStopTime(solver,end)<0) goto cleanup;
CV_CHECK(CVodeSetStopTime(solver,end));
while (t<end) {
if (!native_poll(r,t) || r->accepted>10000000 || r->events>10000) goto cleanup;
if (!native_poll(r,t)) goto cleanup;
if (r->accepted>10000000 || r->events>10000) {
native_fail(r,"resource-limit","integration",r->events>10000?
"Native state-transition limit exceeded.":"Native accepted-step limit exceeded.");
goto cleanup;
}
double old[NSTATES], accepted[NSTATES], next=t;
memcpy(old,N_VGetArrayPointer(y),sizeof(old));
int flag=CVode(solver,end,y,&next,CV_ONE_STEP);
if (flag<0 || next<=t) goto cleanup;
r->cvode_flag=flag; r->cvode_return_time=next;
if (flag<0) { cv_failure(r,flag,"CVode"); goto cleanup; }
if (!isfinite(next)) {
native_fail(r,"nonfinite-time","CVode","CVODE returned a non-finite simulation time."); goto cleanup;
}
for (int i=0;i<NSTATES;i++) if (!isfinite(N_VGetArrayPointer(y)[i])) {
native_fail(r,"nonfinite-state","CVode","CVODE returned a non-finite accepted state."); goto cleanup;
}
if (next<t || next>end) {
native_fail(r,next<t?"time-regression":"time-overshoot","CVode",
next<t?"CVODE returned a time earlier than the last accepted time.":
"CVODE advanced beyond the requested time boundary."); goto cleanup;
}
if (next==t) {
/* A successful internal step may be smaller than one time ULP.
* Retain CVODE's history/state and continue under the existing
* wall-clock timeout/cancellation checks. Never fabricate time,
* reinitialize, or evaluate zero-length dense/event intervals. */
r->same_time_returns++; r->same_time_streak++;
if (r->same_time_streak>r->max_same_time_streak) r->max_same_time_streak=r->same_time_streak;
if (!r->stagnating)
fprintf(stderr,"{\"event\":\"solver-time-stagnation\",\"time\":%.17g,\"returnCode\":%d}\n",t,flag);
r->stagnating=1;
continue;
}
if (r->stagnating)
fprintf(stderr,"{\"event\":\"solver-time-resumed\",\"time\":%.17g,\"sameTimeReturns\":%lu}\n",next,r->same_time_streak);
r->stagnating=0; r->same_time_streak=0;
if (!native_poll(r,t)) goto cleanup;
r->accepted++; r->max_accepted_step=fmax(r->max_accepted_step,next-t);
int impact=native_accept(r,t,next,old,N_VGetArrayPointer(y),cv_dense,&dense,&t,accepted);
if (impact<0) goto cleanup;
if (impact<0) {
native_fail(r,"sampling-event-failure","native_accept","Cannot evaluate an accepted step's samples or events.");
goto cleanup;
}
memcpy(N_VGetArrayPointer(y),accepted,sizeof(accepted));
if (impact) {
counters(r,solver);
if (CVodeReInit(solver,t,y)<0) goto cleanup;
CV_CHECK(CVodeReInit(solver,t,y));
r->starts++;
}
}
@@ -255,17 +323,23 @@ int native_bdf(NativeRun *r) {
memcpy(r->final_state,N_VGetArrayPointer(y),NSTATES*sizeof(double));
double sample=r->options.start+r->sample_index*r->options.sample_step;
if (r->options.record_samples && sample<=t && sample<=r->options.stop) {
if (!native_append(r,sample,r->final_state)) goto cleanup;
if (!native_append(r,sample,r->final_state)) {
native_fail(r,"sample-storage-failure","native_append","Cannot store a boundary sample."); goto cleanup;
}
r->sample_index++;
}
if (t<r->options.stop) {
counters(r,solver);
if (CVodeReInit(solver,t,y)<0) goto cleanup;
CV_CHECK(CVodeReInit(solver,t,y));
r->starts++;
}
}
success=1;
goto cleanup;
allocation_failure:
native_fail(r,"allocation-failure",allocation,"Cannot allocate native solver resources.");
cleanup:
if (initialized) cv_snapshot(r,solver);
if (solver) { counters(r,solver); CVodeFree(&solver); }
if (context.reference) SUNMatDestroy(context.reference);
if (context.weights) N_VDestroy(context.weights);
@@ -277,3 +351,4 @@ cleanup:
SUNContext_Free(&ctx);
return success;
}
#undef CV_CHECK