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
])
24 Fun( Y
, FIX
, RCONST
, P
);
28 void JAC_CHEM(int N
,KPP_REAL T
,KPP_REAL Y
[NVAR
],KPP_REAL J
[LU_NONZERO
])
35 Jac_SP( Y
, FIX
, RCONST
, J
);
43 INTEGRATE(KPP_REAL TIN
,KPP_REAL TOUT
)
46 /* TIN - Start Time */
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.
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
78 AbsTol, RelTol = (NVAR) dimensional vectors of
79 componentwise absolute and relative tolerances.
80 FUNC_CHEM = name of routine of derivatives. KPP syntax.
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
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
;
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
);
120 gamma
= (double)(1.e0
+ 1.e0
/DSQRT(2.e0
));
122 /* === Starting the time loop === */
134 (*forjac
)(NVAR
, T
, y
,JAC
);
137 ghinv
= (double)(-1.0e0
/(gamma
*H
));
142 JAC
[LU_DIAG
[j
]] = JAC
[LU_DIAG
[j
]] + ghinv
;
146 ier
= KppDecomp (JAC
);
152 H
= (double)(5.0e-1*H
);
156 printf("IER <> 0 , H = %d", H
);
158 }/* main ier if ends*/
161 (*forfun
)(NVAR
, T
, y
, F1
) ;
168 /* ====== NONAUTONOMOUS CASE =============== */
171 tau
=( dround
*MAX ((double)1.0e-6, dabs(T
)) *signum(T
) );
172 (*forfun
)(NVAR
, T
+tau
, y
, K2
);
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
];
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
);
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
];
204 }/* if for non - autonomous case ends here */
206 /* ====== AUTONOMOUS CASE =============== */
210 /* ----- STAGE 1 (AUTONOMOUS) ----- */
211 for(j
= 0;j
<NVAR
;j
++)
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
);
225 beta
= (double)(2.e0
/(gamma
*H
));
226 for(j
= 0;j
< NVAR
;j
++)
227 K2
[j
] = F1
[j
] + beta
*K1
[j
];
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 ======== */
246 theta
= (double)(1.e0
/(2.e0
*gamma
));
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
) ));
266 factor
=(double) MAX( 1.0e-1, MIN(factor
,facmax
) );
268 H
= (double)MIN( Hmax
, MAX(Hmin
,factor
*H
) );
270 /* ======= Rejected/Accepted Step ================== */
273 if( (ERR
>1) && (Hold
>Hmin
) )
276 Nreject
= Nreject
+ 1;
288 }/* else ends here */
294 /* ======= End of the time loop ================= */
296 } /* while loop (T < Tnext) ends here */
299 /* ======= Output Information ================ */
307 } /* function ros2 ends here */