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)
8 void (*forfun
)(int,KPP_REAL
,KPP_REAL
[],KPP_REAL
[]);
9 void (*forjac
)(int,KPP_REAL
,KPP_REAL
[],KPP_REAL
[]);
12 void FUNC_CHEM(int N
,KPP_REAL T
,KPP_REAL Y
[NVAR
],KPP_REAL P
[NVAR
])
19 Fun( Y
, FIX
, RCONST
, P
);
21 } /* function fun ends here */
23 void JAC_CHEM(int N
,KPP_REAL T
,KPP_REAL Y
[NVAR
],KPP_REAL J
[LU_NONZERO
])
30 Jac_SP( Y
, FIX
, RCONST
, J
);
32 } /* function jac_sp ends here */
35 INTEGRATE( KPP_REAL TIN
, KPP_REAL TOUT
)
37 /* TIN - Start Time */
46 RODAS3( NVAR
,TIN
,TOUT
,STEPMIN
,STEPMAX
,STEPMIN
,VAR
,ATOL
,RTOL
,INFO
53 int RODAS3(int N
,KPP_REAL T
, KPP_REAL Tnext
,KPP_REAL Hmin
,KPP_REAL Hmax
,
54 KPP_REAL Hstart
,KPP_REAL y
[NVAR
],KPP_REAL AbsTol
[NVAR
],KPP_REAL RelTol
[NVAR
],
55 int INFO
[5],void (*forfun
)(int,KPP_REAL
,KPP_REAL
[],KPP_REAL
[]),
56 void (*forjac
)(int,KPP_REAL
,KPP_REAL
[],KPP_REAL
[]) )
59 Stiffly accurate Rosenbrock 3(2), with
60 stiffly accurate embedded formula for error control.
62 All the arguments aggree with the KPP syntax.
65 y = Vector of (NVAR) concentrations, contains the
66 initial values on input
67 [T, Tnext] = the integration interval
68 Hmin, Hmax = lower and upper bounds for the selected step-size.
69 Note that for Step = Hmin the current computed
70 solution is unconditionally accepted by the error
72 AbsTol, RelTol = (NVAR) dimensional vectors of
73 componentwise absolute and relative tolerances.
74 FUNC_CHEM = name of routine of derivatives. KPP syntax.
76 JAC_CHEM = name of routine that computes the Jacobian, in
77 sparse format. KPP syntax. See the header below.
78 Info(1) = 1 for autonomous system
79 = 0 for nonautonomous system
82 y = the values of concentrations at Tend.
83 T = equals Tend on output.
84 Info(2) = # of FUNC_CHEM calls.
85 Info(3) = # of JAC_CHEM calls.
86 Info(4) = # of accepted steps.
87 Info(5) = # of rejected steps.
89 Adrian Sandu, March 1996
90 The Center for Global and Regional Environmental Research
92 KPP_REAL K1
[NVAR
], K2
[NVAR
], K3
[NVAR
], K4
[NVAR
];
93 KPP_REAL F1
[NVAR
], JAC
[LU_NONZERO
];
94 KPP_REAL ghinv
,uround
,c43
,x1
,x2
,ytol
;
96 KPP_REAL H
, Hold
, Tplus
,tau
,tau1
,tau2
,tau3
;
97 KPP_REAL ERR
, factor
, facmax
;
98 int n
,nfcn
,njac
,Naccept
,Nreject
,i
,j
,ier
;
99 char IsReject
,Autonomous
;
103 /* Initialization of counters, etc. */
104 Autonomous
= (INFO
[0] == 1);
105 uround
= (double)1e-15;
106 c43
= (double)(-8.e0
/3.e0
);
107 H
= MAX( (double)1e-8, Hstart
);
108 Hmin
= MAX(Hmin
,uround
*(Tnext
-T
));
109 Hmax
= MIN(Hmax
,Tnext
-T
);
118 /* === Starting the time loop === */
131 (*forjac
)(NVAR
, T
, y
,JAC
);
134 ghinv
= (double)-2.0e0
/H
;
136 JAC
[LU_DIAG
[j
]] = JAC
[LU_DIAG
[j
]] + ghinv
;
139 ier
= KppDecomp (JAC
);
145 H
= (double)5.0e-1*H
;
149 printf("IER <> 0 , H = %d", H
);
150 }/* main ier if ends*/
153 (*forfun
)(NVAR
, T
, y
, F1
) ;
156 /* ====== NONAUTONOMOUS CASE =============== */
160 tau
= DSQRT( uround
*MAX( (double)1.0e-5, dabs(T
) ) );
161 (*forfun
)(NVAR
, T
+tau
, y
,K2
);
164 K3
[j
] = ( K2
[j
]-F1
[j
] )/tau
;
167 /* ----- STAGE 1 (NONAUTONOMOUS) ----- */
171 K1
[j
] = F1
[j
] + x1
*K3
[j
];
175 /* ----- STAGE 2 (NONAUTONOMOUS) ----- */
179 x2
= (double)1.5e0
*H
;
182 K2
[j
] = F1
[j
] - x1
*K1
[j
] + x2
*K3
[j
];
185 }/* if nonautonomous case ends here */
188 /* ====== AUTONOMOUS CASE =============== */
191 /* ----- STAGE 1 (AUTONOMOUS) ----- */
197 /* ----- STAGE 2 (AUTONOMOUS) ----- */
202 K2
[j
] = F1
[j
] - x1
*K1
[j
];
206 } /* else autonomous case ends here */
209 /* ----- STAGE 3 ----- */
212 ynew
[j
] = y
[j
] - 2.0e0
*K1
[j
];
215 (*forfun
)(NVAR
, T
+H
, ynew
,F1
);
220 K3
[j
] = F1
[j
] + ( -K1
[j
] + K2
[j
] )/H
;
226 /* ----- STAGE 4 ----- */
229 ynew
[j
] = y
[j
] - 2.0e0
*K1
[j
] - K3
[j
];
231 (*forfun
)(NVAR
, T
+H
, ynew
, F1
);
235 K4
[j
] = F1
[j
] + ( -K1
[j
] + K2
[j
] - c43
*K3
[j
] )/H
;
240 /* ---- The Solution --- */
242 ynew
[j
] = y
[j
] - (double)2.0e0
*K1
[j
] - K3
[j
] - K4
[j
];
246 /* ====== Error estimation ======== */
252 ytol
= AbsTol
[i
] + RelTol
[i
]*dabs(ynew
[i
]);
253 ERR
= (double)(ERR
+ pow( K4
[i
]/ytol
,2 ));
256 ERR
= MAX( uround
, DSQRT( ERR
/NVAR
) );
258 /* ======= Choose the stepsize =============================== */
260 factor
= (double)0.9/pow(ERR
,1.e0
/3.e0
);
263 facmax
= (double)1.0;
265 facmax
= (double)10.0;
267 factor
=(double) MAX( 1.0e-1, MIN(factor
,facmax
) );
270 H
= (double)MIN( Hmax
, MAX(Hmin
,factor
*H
) );
273 /* ======= Rejected/Accepted Step ============================ */
275 if( (ERR
>1) && (Hold
>Hmin
) )
278 Nreject
= Nreject
+ 1;
290 } /* else should end here */
293 /* ======= End of the time loop =============================== */
296 }/* while loop (T < Tnext) ends here */
300 /* ======= Output Information ================================= */
310 } /* function rodas ends here */