#define MAX(a,b) ((a) >= (b)) ?(a):(b) #define MIN(b,c) ((b) < (c)) ?(b):(c) #define abs(x) ((x) >= 0 ) ?(x):(-x) #define dabs(y) (double)abs(y) #define DSQRT(d) (double)pow(d,0.5) #define signum(x)((x) >= 0 ) ?(1):(-1) void (*forfun)(int,KPP_REAL,KPP_REAL [],KPP_REAL []); void (*forjac)(int,KPP_REAL,KPP_REAL [],KPP_REAL []); void FUNC_CHEM(int N,KPP_REAL T,KPP_REAL Y[NVAR],KPP_REAL P[NVAR]) { KPP_REAL Told; Told = TIME; TIME = T; Update_SUN(); Update_RCONST(); Fun( Y, FIX, RCONST, P ); TIME = Told; } void JAC_CHEM(int N,KPP_REAL T,KPP_REAL Y[NVAR],KPP_REAL J[LU_NONZERO]) { KPP_REAL Told; Told = TIME; TIME = T; Update_SUN(); Update_RCONST(); Jac_SP( Y, FIX, RCONST, J ); TIME = Told; } INTEGRATE(KPP_REAL TIN,KPP_REAL TOUT ) { /* TIN - Start Time */ /* TOUT - End Time */ int INFO[5]; forfun = &FUNC_CHEM; forjac = &JAC_CHEM; INFO[0] = Autonomous; ROS2(NVAR,TIN,TOUT,STEPMIN,STEPMAX,STEPMIN,VAR,ATOL ,RTOL,INFO,forfun,forjac); } int ROS2(int N,KPP_REAL T, KPP_REAL Tnext,KPP_REAL Hmin,KPP_REAL Hmax, KPP_REAL Hstart,KPP_REAL y[NVAR],KPP_REAL AbsTol[NVAR],KPP_REAL RelTol[NVAR], int INFO[5],void (*forfun)(int,KPP_REAL,KPP_REAL [],KPP_REAL []), void (*forjac)(int,KPP_REAL,KPP_REAL [],KPP_REAL []) ) { /* All the arguments aggree with the KPP syntax. INPUT ARGUMENTS: y = Vector of (NVAR) concentrations, contains the initial values on input [T, Tnext] = the integration interval Hmin, Hmax = lower and upper bounds for the selected step-size. Note that for Step = Hmin the current computed solution is unconditionally accepted by the error control mechanism. AbsTol, RelTol = (NVAR) dimensional vectors of componentwise absolute and relative tolerances. FUNC_CHEM = name of routine of derivatives. KPP syntax. See the header below. JAC_CHEM = name of routine that computes the Jacobian, in sparse format. KPP syntax. See the header below. Info(1) = 1 for autonomous system = 0 for nonautonomous system OUTPUT ARGUMENTS: y = the values of concentrations at Tend. T = equals Tend on output. Info(2) = # of FUNC_CHEM calls. Info(3) = # of JAC_CHEM calls. Info(4) = # of accepted steps. Info(5) = # of rejected steps. */ KPP_REAL K1[NVAR], K2[NVAR], K3[NVAR], K4[NVAR]; KPP_REAL F1[NVAR], JAC[LU_NONZERO]; KPP_REAL ghinv , uround , dround , c43 , tau; KPP_REAL ynew[NVAR]; KPP_REAL H, Hold, Tplus; KPP_REAL ERR, factor, facmax; int n,nfcn,njac,Naccept,Nreject,i,j,ier; char IsReject,Autonomous; KPP_REAL gamma, m1, m2, alpha, beta, delta, theta, g[NVAR], x[NVAR]; /* Initialization of counters, etc. */ Autonomous = (INFO[0] == 1); uround = (double)(1e-15); dround = DSQRT(uround); c43 = (double)(- 8.e0/3.e0); H = MAX( (double)1.e-8, Hmin ); Tplus = T; IsReject = 0; Naccept = 0; Nreject = 0; nfcn = 0; njac = 0; gamma = (double)(1.e0 + 1.e0/DSQRT(2.e0)); /* === Starting the time loop === */ while(T < Tnext) { ten : Tplus = T + H; if ( Tplus > Tnext ) { H = Tnext - T; Tplus = Tnext; } (*forjac)(NVAR, T, y,JAC ); njac = njac+1; ghinv = (double)(-1.0e0/(gamma*H)); for(j=0;j Hmin ) { H = (double)(5.0e-1*H); goto ten; } else printf("IER <> 0 , H = %d", H); }/* main ier if ends*/ (*forfun)(NVAR , T, y, F1 ) ; /* ====== NONAUTONOMOUS CASE =============== */ if(Autonomous == 0) { tau =( dround*MAX ((double)1.0e-6, dabs(T)) *signum(T) ); (*forfun)(NVAR, T+tau, y, K2); nfcn=nfcn+1; for(j = 0;j1) && (Hold>Hmin) ) { IsReject = 1; Nreject = Nreject + 1; } else { IsReject = 0; for(i=0;i