added README_changes.txt
[wrffire.git] / wrfv2_fire / chem / KPP / kpp / kpp-2.1 / int / oldies / ros2.c
blob88cc5116a33e0d9f63db506c040dc75c549290e4
2 #define MAX(a,b) ((a) >= (b)) ?(a):(b)
3 #define MIN(b,c) ((b) < (c)) ?(b):(c)
4 #define abs(x) ((x) >= 0 ) ?(x):(-x)
5 #define dabs(y) (double)abs(y)
6 #define DSQRT(d) (double)pow(d,0.5)
7 #define signum(x)((x) >= 0 ) ?(1):(-1)
11 void (*forfun)(int,KPP_REAL,KPP_REAL [],KPP_REAL []);
12 void (*forjac)(int,KPP_REAL,KPP_REAL [],KPP_REAL []);
17 void FUNC_CHEM(int N,KPP_REAL T,KPP_REAL Y[NVAR],KPP_REAL P[NVAR])
19 KPP_REAL Told;
20 Told = TIME;
21 TIME = T;
22 Update_SUN();
23 Update_RCONST();
24 Fun( Y, FIX, RCONST, P );
25 TIME = Told;
28 void JAC_CHEM(int N,KPP_REAL T,KPP_REAL Y[NVAR],KPP_REAL J[LU_NONZERO])
30 KPP_REAL Told;
31 Told = TIME;
32 TIME = T;
33 Update_SUN();
34 Update_RCONST();
35 Jac_SP( Y, FIX, RCONST, J );
36 TIME = Told;
43 INTEGRATE(KPP_REAL TIN,KPP_REAL TOUT )
46 /* TIN - Start Time */
47 /* TOUT - End Time */
50 int INFO[5];
51 forfun = &FUNC_CHEM;
52 forjac = &JAC_CHEM;
53 INFO[0] = Autonomous;
54 ROS2(NVAR,TIN,TOUT,STEPMIN,STEPMAX,STEPMIN,VAR,ATOL
55 ,RTOL,INFO,forfun,forjac);
60 int ROS2(int N,KPP_REAL T, KPP_REAL Tnext,KPP_REAL Hmin,KPP_REAL Hmax,
61 KPP_REAL Hstart,KPP_REAL y[NVAR],KPP_REAL AbsTol[NVAR],KPP_REAL RelTol[NVAR],
62 int INFO[5],void (*forfun)(int,KPP_REAL,KPP_REAL [],KPP_REAL []),
63 void (*forjac)(int,KPP_REAL,KPP_REAL [],KPP_REAL []) )
68 All the arguments aggree with the KPP syntax.
70 INPUT ARGUMENTS:
71 y = Vector of (NVAR) concentrations, contains the
72 initial values on input
73 [T, Tnext] = the integration interval
74 Hmin, Hmax = lower and upper bounds for the selected step-size.
75 Note that for Step = Hmin the current computed
76 solution is unconditionally accepted by the error
77 control mechanism.
78 AbsTol, RelTol = (NVAR) dimensional vectors of
79 componentwise absolute and relative tolerances.
80 FUNC_CHEM = name of routine of derivatives. KPP syntax.
81 See the header below.
82 JAC_CHEM = name of routine that computes the Jacobian, in
83 sparse format. KPP syntax. See the header below.
84 Info(1) = 1 for autonomous system
85 = 0 for nonautonomous system
87 OUTPUT ARGUMENTS:
88 y = the values of concentrations at Tend.
89 T = equals Tend on output.
90 Info(2) = # of FUNC_CHEM calls.
91 Info(3) = # of JAC_CHEM calls.
92 Info(4) = # of accepted steps.
93 Info(5) = # of rejected steps.
96 KPP_REAL K1[NVAR], K2[NVAR], K3[NVAR], K4[NVAR];
97 KPP_REAL F1[NVAR], JAC[LU_NONZERO];
98 KPP_REAL ghinv , uround , dround , c43 , tau;
99 KPP_REAL ynew[NVAR];
100 KPP_REAL H, Hold, Tplus;
101 KPP_REAL ERR, factor, facmax;
102 int n,nfcn,njac,Naccept,Nreject,i,j,ier;
103 char IsReject,Autonomous;
105 KPP_REAL gamma, m1, m2, alpha, beta, delta, theta, g[NVAR], x[NVAR];
107 /* Initialization of counters, etc. */
108 Autonomous = (INFO[0] == 1);
109 uround = (double)(1e-15);
111 dround = DSQRT(uround);
112 c43 = (double)(- 8.e0/3.e0);
113 H = MAX( (double)1.e-8, Hmin );
114 Tplus = T;
115 IsReject = 0;
116 Naccept = 0;
117 Nreject = 0;
118 nfcn = 0;
119 njac = 0;
120 gamma = (double)(1.e0 + 1.e0/DSQRT(2.e0));
122 /* === Starting the time loop === */
123 while(T < Tnext)
125 ten :
126 Tplus = T + H;
128 if ( Tplus > Tnext )
130 H = Tnext - T;
131 Tplus = Tnext;
134 (*forjac)(NVAR, T, y,JAC );
136 njac = njac+1;
137 ghinv = (double)(-1.0e0/(gamma*H));
141 for(j=0;j<NVAR;j++)
142 JAC[LU_DIAG[j]] = JAC[LU_DIAG[j]] + ghinv;
146 ier = KppDecomp (JAC);
148 if ( ier != 0)
150 if( H > Hmin )
152 H = (double)(5.0e-1*H);
153 goto ten;
155 else
156 printf("IER <> 0 , H = %d", H);
158 }/* main ier if ends*/
161 (*forfun)(NVAR , T, y, F1 ) ;
168 /* ====== NONAUTONOMOUS CASE =============== */
169 if(Autonomous == 0)
171 tau =( dround*MAX ((double)1.0e-6, dabs(T)) *signum(T) );
172 (*forfun)(NVAR, T+tau, y, K2);
173 nfcn=nfcn+1;
175 for(j = 0;j<NVAR;j++)
176 K3[j] = ( K2[j]-F1[j] )/tau;
179 /* ----- STAGE 1 (NON-AUTONOMOUS) ----- */
181 delta = (double)(gamma*H);
183 for(j = 0;j<NVAR;j++)
184 K1[j] = F1[j] + delta*K3[j];
186 KppSolve (JAC, K1);
189 /* ----- STAGE 2 (NON-AUTONOMOUS) ----- */
190 alpha = (double)(- 1.e0/gamma);
191 for(j = 0;j<NVAR;j++)
192 ynew[j] = y[j] + alpha*K1[j];
195 (*forfun)(NVAR, T+H, ynew, F1);
196 nfcn=nfcn+1;
197 beta = (double)(2.e0/(gamma*H));
198 delta = (double)(-gamma*H);
199 for(j = 0;j<NVAR;j++)
200 K2[j] = F1[j] + beta*K1[j] + delta*K3[j];
202 KppSolve (JAC, K2);
204 }/* if for non - autonomous case ends here */
206 /* ====== AUTONOMOUS CASE =============== */
207 else
210 /* ----- STAGE 1 (AUTONOMOUS) ----- */
211 for(j = 0;j<NVAR;j++)
212 K1[j] = F1[j];
214 KppSolve (JAC, K1);
216 /* ----- STAGE 2 (AUTONOMOUS) ----- */
217 alpha = (double)(- 1.e0/gamma);
219 for(j = 0;j<NVAR;j++)
220 ynew[j] = y[j] + alpha*K1[j];
222 (*forfun)(NVAR, T+H, ynew, F1);
224 nfcn=nfcn+1;
225 beta = (double)(2.e0/(gamma*H));
226 for(j = 0;j < NVAR;j++)
227 K2[j] = F1[j] + beta*K1[j];
229 KppSolve (JAC, K2);
231 }/* else autonomous case ends here */
235 /* ---- The Solution --- */
236 m1 = (double)(-3.e0/(2.e0*gamma));
237 m2 = (double)(-1.e0/(2.e0*gamma));
238 for(j = 0;j<NVAR;j++)
239 ynew[j] = y[j] + m1*K1[j] + m2*K2[j];
243 /* ====== Error estimation ======== */
245 ERR=(double)0.e0;
246 theta = (double)(1.e0/(2.e0*gamma));
248 for(i=0;i<NVAR;i++)
250 g[i] = AbsTol[i] + RelTol[i]*dabs(ynew[i]);
251 ERR = (double)( ERR + pow( ( theta*(K1[i]+K2[i])/g[i] ) , 2.0 ) );
253 ERR = MAX( uround, DSQRT( ERR/NVAR ) );
255 /* ======= Choose the stepsize ================== */
258 factor = (double)(0.9/pow( ERR,(1.e0/2.e0) ));
259 if (IsReject == 1)
260 facmax=(double)1.0;
262 else
263 facmax=(double)10.0;
266 factor =(double) MAX( 1.0e-1, MIN(factor,facmax) );
267 Hold = H;
268 H = (double)MIN( Hmax, MAX(Hmin,factor*H) );
270 /* ======= Rejected/Accepted Step ================== */
273 if( (ERR>1) && (Hold>Hmin) )
275 IsReject = 1;
276 Nreject = Nreject + 1;
278 else
280 IsReject = 0;
281 for(i=0;i<NVAR;i++)
283 y[i] = ynew[i];
285 T = Tplus;
286 Naccept = Naccept+1;
288 }/* else ends here */
294 /* ======= End of the time loop ================= */
296 } /* while loop (T < Tnext) ends here */
299 /* ======= Output Information ================ */
300 INFO[1] = nfcn;
301 INFO[2] = njac;
302 INFO[3] = Naccept;
303 INFO[4] = Nreject;
305 return 0;
307 } /* function ros2 ends here */