#include "runtime.h" #include #include #include #include #include static void json_string(FILE *f, const char *value) { fputc('"',f); for (const unsigned char *p=(const unsigned char *)value; *p; p++) { if (*p=='"' || *p=='\\') { fputc('\\',f); fputc(*p,f); } else if (*p<32) fprintf(f,"\\u%04x",*p); else fputc(*p,f); } fputc('"',f); } static void vector(FILE *f, const double *value, int count) { fputc('[',f); for (int i=0;ifinal_time,r->final_state,dy,final); size_t length=r->count*NOUTPUTS; if (length>268435456u/sizeof(double)) return 0; double *values=length?malloc(length*sizeof(double)):NULL; if (length && !values) return 0; for (size_t i=0;icount;i++) { if (!model_eval(r->times[i],r->states+i*NSTATES,dy,values+i*NOUTPUTS)) { free(values); return 0; } } FILE *f=fopen(path,"wb"); if (!f) { free(values); return 0; } fprintf(f,"{\"success\":%s,\"status\":",!r->status?"true":"false"); json_string(f,r->status==0?"completed":r->status==1?"cancelled":"failed"); fprintf(f,",\"message\":"); json_string(f,r->message); fprintf(f,",\"backend\":\"native-c\",\"method\":\"%s\",\"solver\":\"%s\",\"sundialsVersion\":\"%s\"," "\"simulatedUntil\":%.17g,\"solveSeconds\":%.17g,\"solveCpuSeconds\":%.17g," "\"nfev\":%lu,\"acceptedSteps\":%lu,\"rejectedSteps\":%lu,\"stateTransitions\":%lu," "\"solverStarts\":%lu,\"njev\":%lu,\"nlu\":%lu,\"maxAcceptedStep\":%.17g,\"series\":{", r->options.bdf?"BDF":"RK45",r->options.bdf?"CVODE":"Dormand-Prince 5(4)",SUNDIALS_VERSION, r->final_time,r->solve_seconds,r->solve_cpu_seconds,r->nfev,r->accepted,r->rejected, r->events,r->starts,r->njev,r->nlu,r->max_accepted_step); if (r->count) { fprintf(f,"\"time\":["); for (size_t i=0;icount;i++) fprintf(f,"%s%.17g",i?",":"",r->times[i]); fputc(']',f); for (int j=0;jcount;i++) fprintf(f,"%s%.17g",i?",":"",values[i*NOUTPUTS+j]); fputc(']',f); } } fprintf(f,"},\"final\":{"); if (final_ok) for (int j=0;jfinal_state,NSTATES); fprintf(f,"}\n"); int ok=!ferror(f); if (fclose(f)) ok=0; free(values); return ok; } int main(int argc, char **argv) { NativeRun r={0}; r.options=(NativeOptions){0,10,.02,.001,1e-6,300,0,1,NULL}; const char *output="result.json"; for (int i=1;ir.options.start && r.options.sample_step>0 && r.options.max_step>0 && r.options.rtol>0 && r.options.timeout>0) || r.options.start+r.options.sample_step==r.options.start || r.options.start+r.options.max_step==r.options.start || !isfinite(r.options.stop-r.options.start)) return 64; if (r.options.record_samples && ((r.options.stop-r.options.start)/r.options.sample_step>1000000 || ((r.options.stop-r.options.start)/r.options.sample_step+1024)*(NSTATES+NOUTPUTS)*sizeof(double)>268435456)) return 64; native_solve(&r); int saved=write_result(&r,output); int code=saved?(r.status==2?2:0):3; native_run_free(&r); return code; }