1 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
2 ! SEULEX - Stiff extrapolation method based on linearly implicit Euler !
3 ! By default the code employs the KPP sparse linear algebra routines !
4 ! Compile with -DFULL_ALGEBRA to use full linear algebra (LAPACK) !
5 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
7 MODULE KPP_ROOT_Integrator
9 USE KPP_ROOT_Precision
, ONLY
: dp
10 USE KPP_ROOT_Jacobian
, ONLY
: NVAR
, LU_NONZERO
, LU_DIAG
11 USE KPP_ROOT_LinearAlgebra
17 ! variables from the former COMMON block /CONRA5/ are now here:
18 INTEGER :: NN
, NN2
, NN3
, NN4
19 KPP_REAL
:: TSOL
, HSOL
22 INTEGER :: Nfun
,Njac
,Nstp
,Nacc
,Nrej
,Ndec
,Nsol
,Nsng
26 ! mz_rs_20050717: TODO: use strings of IERR_NAMES for error messages
27 ! description of the error numbers IERR
28 CHARACTER(LEN
=50), PARAMETER, DIMENSION(-4:1) :: IERR_NAMES
= (/ &
29 'Matrix is repeatedly singular ', & ! -4
30 'Step size too small ', & ! -3
31 'More than Max_no_steps steps are needed ', & ! -2
32 'Insufficient storage for work or iwork ', & ! -1
38 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39 SUBROUTINE INTEGRATE( TIN
, TOUT
, &
40 ICNTRL_U
, RCNTRL_U
, ISTATUS_U
, RSTATUS_U
, IERR_U
)
41 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
43 USE KPP_ROOT_Parameters
, ONLY
: nvar
44 USE KPP_ROOT_Global
, ONLY
: atol
,rtol
,var
48 KPP_REAL
:: TIN
! TIN - Start Time
49 KPP_REAL
:: TOUT
! TOUT - End Time
50 INTEGER, INTENT(IN
), OPTIONAL
:: ICNTRL_U(20)
51 KPP_REAL
, INTENT(IN
), OPTIONAL
:: RCNTRL_U(20)
52 INTEGER, INTENT(OUT
), OPTIONAL
:: ISTATUS_U(20)
53 KPP_REAL
, INTENT(OUT
), OPTIONAL
:: RSTATUS_U(20)
54 INTEGER, INTENT(OUT
), OPTIONAL
:: IERR_U
56 INTEGER :: Ncolumns
, Ncolumns2
, NRDENS
57 PARAMETER (Ncolumns
=12,Ncolumns2
=2+Ncolumns
*(Ncolumns
+3)/2,NRDENS
=NVAR
)
59 KPP_REAL
:: RCNTRL(20), RSTATUS(20)
60 INTEGER :: ICNTRL(20), ISTATUS(20)
62 INTEGER, SAVE :: Ntotal
= 0
69 ICNTRL(10)=0 !~~~> OUTPUT ROUTINE IS NOT USED DURING INTEGRATION
71 ! if optional parameters are given, and if they are >0,
72 ! they overwrite the default settings
73 IF (PRESENT(ICNTRL_U
)) ICNTRL(:) = ICNTRL_U(:)
74 IF (PRESENT(RCNTRL_U
)) RCNTRL(:) = RCNTRL_U(:)
75 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-----
78 CALL ATMSEULEX(NVAR
,TIN
,TOUT
,VAR
,H
,RTOL
,ATOL
, &
79 RCNTRL
,ICNTRL
,RSTATUS
,ISTATUS
,IERR
)
80 Ntotal
= Ntotal
+ Nstp
81 !!$ PRINT*,'NSTEPS=',Nstp,' (',Ntotal,') T=',TIN
84 Nfun
= Nfun
+ ISTATUS(1)
85 Njac
= Njac
+ ISTATUS(2)
86 Nstp
= Nstp
+ ISTATUS(3)
87 Nacc
= Nacc
+ ISTATUS(4)
88 Nrej
= Nrej
+ ISTATUS(5)
89 Ndec
= Ndec
+ ISTATUS(6)
90 Nsol
= Nsol
+ ISTATUS(7)
92 ! if optional parameters are given for output
93 ! use them to store information in them
94 IF (PRESENT(ISTATUS_U
)) THEN
96 ISTATUS_U(1) = Nfun
! function calls
97 ISTATUS_U(2) = Njac
! jacobian calls
98 ISTATUS_U(3) = Nstp
! steps
99 ISTATUS_U(4) = Nacc
! accepted steps
100 ISTATUS_U(5) = Nrej
! rejected steps (except at the beginning)
101 ISTATUS_U(6) = Ndec
! LU decompositions
102 ISTATUS_U(7) = Nsol
! forward/backward substitutions
104 IF (PRESENT(RSTATUS_U
)) THEN
106 RSTATUS_U(1) = TOUT
! final time
108 IF (PRESENT(IERR_U
)) IERR_U
= IERR
110 ! mz_rs_20050716: IERR is returned to the user who then decides what to do
111 ! about it, i.e. either stop the run or ignore it.
112 !!$ IF (IERR < 0) THEN
113 !!$ PRINT *,'SEULEX: Unsuccessful exit at T=', TIN,' (IERR=',IERR,')'
117 END SUBROUTINE INTEGRATE
119 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120 SUBROUTINE ATMSEULEX( N
,Tinitial
,Tfinal
,Y
,H
,RelTol
,AbsTol
, &
121 RCNTRL
,ICNTRL
,RSTATUS
,ISTATUS
,IERR
)
123 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124 ! NUMERICAL SOLUTION OF A STIFF (OR DIFFERENTIAL ALGEBRAIC)
125 ! SYSTEM OF FIRST 0RDER ORDINARY DIFFERENTIAL EQUATIONS MY'=F(T,Y).
126 ! THIS IS AN EXTRAPOLATION-ALGORITHM, BASED ON THE
127 ! LINEARLY IMPLICIT EULER METHOD (WITH STEP SIZE CONTROL
128 ! AND ORDER SELECTION).
130 ! AUTHORS: E. HAIRER AND G. WANNER
131 ! UNIVERSITE DE GENEVE, DEPT. DE MATHEMATIQUES
132 ! CH-1211 GENEVE 24, SWITZERLAND
133 ! E-MAIL: HAIRER@DIVSUN.UNIGE.CH, WANNER@DIVSUN.UNIGE.CH
134 ! INCLUSION OF DENSE OUTPUT BY E. HAIRER AND A. OSTERMANN
136 ! THIS CODE IS PART OF THE BOOK:
137 ! E. HAIRER AND G. WANNER, SOLVING ORDINARY DIFFERENTIAL
138 ! EQUATIONS II. STIFF AND DIFFERENTIAL-ALGEBRAIC PROBLEMS.
139 ! SPRINGER SERIES IN COMPUTATIONAL MATHEMATICS 14,
140 ! SPRINGER-VERLAG (1991)
142 ! VERSION OF SEPTEMBER 30, 1995
144 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
148 ! N DIMENSION OF THE SYSTEM
152 ! Y(N) INITIAL VALUES FOR Y
154 ! Tend FINAL T-VALUE (Tend-T MAY BE POSITIVE OR NEGATIVE)
156 ! H INITIAL STEP SIZE GUESS;
157 ! FOR STIFF EQUATIONS WITH INITIAL TRANSIENT,
158 ! H=1.D0/(NORM OF F'), USUALLY 1.D-2 OR 1.D-3, IS GOOD.
159 ! THIS CHOICE IS NOT VERY IMPORTANT, THE CODE QUICKLY
160 ! ADAPTS ITS STEP SIZE (IF H=0.D0, THE CODE PUTS H=1.D-6
162 ! RelTol,AbsTol RELATIVE AND ABSOLUTE ERROR TOLERANCES. THEY
163 ! CAN BE BOTH SCALARS OR ELSE BOTH VECTORS OF LENGTH N.
165 ! JAC NAME (EXTERNAL) OF THE SUBROUTINE WHICH COMPUTES
166 ! THE PARTIAL DERIVATIVES OF F(T,Y) WITH RESPECT TO Y
168 ! SOLOUT NAME (EXTERNAL) OF SUBROUTINE PROVIDING THE
169 ! NUMERICAL SOLUTION DURING INTEGRATION.
170 ! IF IOUT>=1, IT IS CALLED AFTER EVERY SUCCESSFUL STEP.
171 ! SUPPLY A DUMMY SUBROUTINE IF IOUT=0.
172 ! IT MUST HAVE THE FORM
173 ! SUBROUTINE SOLOUT (NR,TOLD,T,Y,RC,LRC,IC,LIC,N,
175 ! KPP_REAL T,Y(N),RC(LRC),IC(LIC)
177 ! SOLOUT FURNISHES THE SOLUTION "Y" AT THE NR-TH
178 ! GRID-POINT "T" (THEREBY THE INITIAL VALUE IS
179 ! THE FIRST GRID-POINT).
180 ! "TOLD" IS THE PRECEEDING GRID-POINT.
181 ! "IRTRN" SERVES TO INTERRUPT THE INTEGRATION. IF IRTRN
182 ! IS SET <0, SEULEX RETURNS TO THE CALLING PROGRAM.
183 ! DO NOT CHANGE THE ENTRIES OF RC(LRC),IC(LIC)!
185 ! ----- CONTINUOUS OUTPUT (IF IOUT=2): -----
186 ! DURING CALLS TO "SOLOUT", A CONTINUOUS SOLUTION
187 ! FOR THE INTERVAL [TOLD,T] IS AVAILABLE THROUGH
188 ! THE KPP_REAL FUNCTION
189 ! >>> CONTEX(I,S,RC,LRC,IC,LIC) <<<
190 ! WHICH PROVIDES AN APPROXIMATION TO THE I-TH
191 ! COMPONENT OF THE SOLUTION AT THE POINT S. THE VALUE
192 ! S SHOULD LIE IN THE INTERVAL [TOLD,T].
194 ! IOUT GIVES INFORMATION ON THE SUBROUTINE SOLOUT:
195 ! IOUT=0: SUBROUTINE IS NEVER CALLED
196 ! IOUT=1: SUBROUTINE IS USED FOR OUTPUT
197 ! IOUT=2: DENSE OUTPUT IS PERFORMED IN SOLOUT
199 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
201 ! SOPHISTICATED SETTING OF PARAMETERS
202 ! -----------------------------------
203 ! SEVERAL PARAMETERS OF THE CODE ARE TUNED TO MAKE IT CNTRL
204 ! WELL. THEY MAY BE DEFINED BY SETTING CNTRL(1),..,CNTRL(13)
205 ! AS WELL AS ICNTRL(1),..,ICNTRL(4) DIFFERENT FROM ZERO.
206 ! FOR ZERO INPUT, THE CODE CHOOSES DEFAULT VALUES:
209 !~~~> INPUT PARAMETERS:
211 ! Note: For input parameters equal to zero the default values of the
212 ! corresponding variables are used.
214 ! ICNTRL(1) = 1: F = F(y) Independent of T (autonomous)
215 ! = 0: F = F(t,y) Depends on T (non-autonomous)
217 ! ICNTRL(2) = 0: AbsTol, RelTol are NVAR-dimensional vectors
218 ! = 1: AbsTol, RelTol are scalars
220 ! ICNTRL(3) -> not used
222 ! ICNTRL(4) -> maximum number of integration steps
223 ! For ICNTRL(4)=0 the default value of 100000 is used
225 ! ICNTRL(11) THE MAXIMUM NUMBER OF COLUMNS IN THE EXTRAPOLATION
226 ! TABLE. THE DEFAULT VALUE (FOR ICNTRL(3)=0) IS 12.
227 ! IF ICNTRL(3).NE.0 THEN ICNTRL(3) SHOULD BE >= 3.
229 ! ICNTRL(12) SWITCH FOR THE STEP SIZE SEQUENCE
230 ! IF ICNTRL(4) == 1 THEN 1,2,3,4,6,8,12,16,24,32,48,...
231 ! IF ICNTRL(4) == 2 THEN 2,3,4,6,8,12,16,24,32,48,64,...
232 ! IF ICNTRL(4) == 3 THEN 1,2,3,4,5,6,7,8,9,10,...
233 ! IF ICNTRL(4) == 4 THEN 2,3,4,5,6,7,8,9,10,11,...
234 ! THE DEFAULT VALUE (FOR ICNTRL(4)=0) IS ICNTRL(4)=2.
236 ! ICNTRL(13) PARAMETER "LAMBDA" OF DENSE OUTPUT; POSSIBLE VALUES
237 ! ARE 0 AND 1; DEFAULT ICNTRL(5)=0.
239 ! ICNTRL(14) = NRDENS = NUMBER OF COMPONENTS, FOR WHICH DENSE OUTPUT
242 ! ICNTRL(21),...,ICNTRL(NRDENS+20) INDICATE THE COMPONENTS, FOR WHICH
243 ! DENSE OUTPUT IS REQUIRED
245 !~~~> Real parameters
247 ! RCNTRL(1) -> Hmin, lower bound for the integration step size
248 ! It is strongly recommended to keep Hmin = ZERO
249 ! RCNTRL(2) -> Hmax, upper bound for the integration step size
250 ! RCNTRL(3) -> Hstart, starting value for the integration step size
251 ! RCNTRL(4) -> FacMin, lower bound on step decrease factor (default=0.2)
252 ! RCNTRL(5) -> FacMax, upper bound on step increase factor (default=6)
253 ! RCNTRL(6) -> FacRej, step decrease factor after multiple rejections
255 ! RCNTRL(7) -> FacSafe, by which the new step is slightly smaller
256 ! than the predicted value (default=0.9)
257 ! RCNTRL(8) -> ThetaMin. If Newton convergence rate smaller
258 ! than ThetaMin the Jacobian is not recomputed;
259 ! (default=0.001). Increase cntrl(3), to 0.01 say, when
260 ! Jacobian evaluations are costly. for small systems it
262 ! RCNTRL(9) -> not used
263 ! RCNTRL(10,11) -> FAC1,FAC2 (parameters for step size selection)
264 ! RCNTRL(12,13) -> FAC3,FAC4 (parameters for order selection)
265 ! RCNTRL(14,15) -> FacSafe1, FacSafe2
266 ! Safety factors for step size prediction
267 ! HNEW=H*FacSafe2*(FacSafe1*TOL/ERR)**(1/(J-1))
268 ! RCNTRL(16:19) -> WorkFcn, WorkJac, WorkDec, WorkSol
269 ! estimated computational work
271 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
275 ! T T-VALUE WHERE THE SOLUTION IS COMPUTED
276 ! (AFTER SUCCESSFUL RETURN T=Tend)
280 ! H PREDICTED STEP SIZE OF THE LAST ACCEPTED STEP
282 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
284 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
286 INTEGER :: N
, IERR
, ITOL
, Max_no_steps
, Ncolumns
, Nsequence
, Lambda
, &
287 NRDENS
, i
, Ncolumns2
, NRD
, IOUT
288 KPP_REAL
:: Y(NVAR
),AbsTol(*),RelTol(*)
289 KPP_REAL
:: Tinitial
, Tfinal
, Roundoff
, Hmin
, Hmax
, &
290 FacMin
, FacMax
, FAC1
, FAC2
, FAC3
, FAC4
, FacSafe1
, &
291 FacSafe2
, H
, Hstart
,WorkFcn
,WorkJac
, WorkDec
, WorkSol
,&
292 WorkRow
, FacRej
, FacSafe
, ThetaMin
, T
294 KPP_REAL
:: RCNTRL(20), RSTATUS(20)
295 INTEGER :: ICNTRL(20), ISTATUS(20)
296 KPP_REAL
, PARAMETER :: ZERO
= 0.0d0
298 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
299 ! SETTING THE PARAMETERS
300 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311 IF (ICNTRL(1) == 0) THEN
317 !~~~> For Scalar tolerances (ICNTRL(1)/=0) the code uses AbsTol(1) and RelTol(1)
318 !~~~> For Vector tolerances (ICNTRL(1)==0) the code uses AbsTol(1:NVAR) and RelTol(1:NVAR)
319 IF (ICNTRL(2) == 0) THEN
325 !~~~> Max_no_steps: the maximum number of time steps admitted
326 IF (ICNTRL(4) == 0) THEN
327 Max_no_steps
= 100000
328 ELSEIF (ICNTRL(4) > 0) THEN
329 Max_no_steps
=ICNTRL(4)
331 PRINT * ,'User-selected ICNTRL(4)=',ICNTRL(4)
332 CALL SEULEX_ErrorMsg(-1,Tinitial
,ZERO
,IERR
);
335 !~~~> IOUT = use (or not) the output routine
337 IF ( IOUT
<0 .OR
. IOUT
>2 ) THEN
338 PRINT * ,'User-selected ICNTRL(10)=',ICNTRL(10)
342 !~~~> Ncolumns: maximum number of columns in the extrapolation
343 IF (ICNTRL(11)==0) THEN
345 ELSEIF (ICNTRL(11) > 2) THEN
348 PRINT * ,'User-selected ICNTRL(11)=',ICNTRL(11)
349 CALL SEULEX_ErrorMsg(-2,Tinitial
,ZERO
,IERR
);
352 !~~~> Nsequence: choice of step size sequence
353 IF (ICNTRL(12)==0) THEN
355 ELSEIF ( (ICNTRL(12)>0).AND
.(ICNTRL(12)<5) ) THEN
356 Nsequence
= ICNTRL(4)
358 PRINT * ,'User-selected ICNTRL(12)=',ICNTRL(12)
359 CALL SEULEX_ErrorMsg(-3,Tinitial
,ZERO
,IERR
)
362 !~~~> LAMBDA: parameter for dense output
364 IF ( LAMBDA
< 0 .OR
. LAMBDA
>= 2 ) THEN
365 PRINT * ,'User-selected ICNTRL(13)=',ICNTRL(13)
366 CALL SEULEX_ErrorMsg(-4,Tinitial
,ZERO
,IERR
)
369 !~~~>- NRDENS: number of dense output components
371 IF ( (NRDENS
< 0) .OR
. (NRDENS
> N
) ) THEN
372 PRINT * ,'User-selected ICNTRL(14)=',ICNTRL(14)
373 CALL SEULEX_ErrorMsg(-5,Tinitial
,ZERO
,IERR
)
377 !~~~> Unit roundoff (1+Roundoff>1)
378 Roundoff
= WLAMCH('E')
380 !~~~> Lower bound on the step size: (positive value)
381 IF (RCNTRL(1) == ZERO
) THEN
383 ELSEIF (RCNTRL(1) > ZERO
) THEN
386 PRINT * , 'User-selected RCNTRL(1)=', RCNTRL(1)
387 CALL SEULEX_ErrorMsg(-7,Tinitial
,ZERO
,IERR
)
391 !~~~> Upper bound on the step size: (positive value)
392 IF (RCNTRL(2) == ZERO
) THEN
393 Hmax
= ABS(Tfinal
-Tinitial
)
394 ELSEIF (RCNTRL(2) > ZERO
) THEN
395 Hmax
= MIN(ABS(RCNTRL(2)),ABS(Tfinal
-Tinitial
))
397 PRINT * , 'User-selected RCNTRL(2)=', RCNTRL(2)
398 CALL SEULEX_ErrorMsg(-7,Tinitial
,ZERO
,IERR
)
402 !~~~> Starting step size: (positive value)
403 IF (RCNTRL(3) == ZERO
) THEN
404 Hstart
= MAX(Hmin
,Roundoff
)
405 ELSEIF (RCNTRL(3) > ZERO
) THEN
406 Hstart
= MIN(ABS(RCNTRL(3)),ABS(Tfinal
-Tinitial
))
408 PRINT * , 'User-selected Hstart: RCNTRL(3)=', RCNTRL(3)
409 CALL SEULEX_ErrorMsg(-7,Tinitial
,ZERO
,IERR
)
414 !~~~> Step size can be changed s.t. FacMin < Hnew/Hexit < FacMax
415 IF (RCNTRL(4) == ZERO
) THEN
417 ELSEIF (RCNTRL(4) > ZERO
) THEN
420 PRINT * , 'User-selected FacMin: RCNTRL(4)=', RCNTRL(4)
421 CALL SEULEX_ErrorMsg(-8,Tinitial
,ZERO
,IERR
)
424 IF (RCNTRL(5) == ZERO
) THEN
426 ELSEIF (RCNTRL(5) > ZERO
) THEN
429 PRINT * , 'User-selected FacMax: RCNTRL(5)=', RCNTRL(5)
430 CALL SEULEX_ErrorMsg(-8,Tinitial
,ZERO
,IERR
)
433 !~~~> FacRej: Factor to decrease step after 2 succesive rejections
434 IF (RCNTRL(6) == ZERO
) THEN
436 ELSEIF (RCNTRL(6) > ZERO
) THEN
439 PRINT * , 'User-selected FacRej: RCNTRL(6)=', RCNTRL(6)
440 CALL SEULEX_ErrorMsg(-8,Tinitial
,ZERO
,IERR
)
443 !~~~> FacSafe: Safety Factor in the computation of new step size
444 IF (RCNTRL(7) == ZERO
) THEN
446 ELSEIF (RCNTRL(7) > ZERO
) THEN
449 PRINT * , 'User-selected FacSafe: RCNTRL(7)=', RCNTRL(7)
450 CALL SEULEX_ErrorMsg(-8,Tinitial
,ZERO
,IERR
)
454 !~~~> ThetaMin: DECIDES WHETHER THE JACOBIAN SHOULD BE RECOMPUTED;
455 ! INCREASE WORK(3), TO 0.01 SAY, WHEN JACOBIAN EVALUATIONS
456 ! ARE COSTLY. FOR SMALL SYSTEMS WORK(3) SHOULD BE SMALLER.
457 IF(RCNTRL(8) == 0.D0
)THEN
463 !~~~> FAC1,FAC2: PARAMETERS FOR STEP SIZE SELECTION
464 ! THE NEW STEP SIZE FOR THE J-TH DIAGONAL ENTRY IS
465 ! CHOSEN SUBJECT TO THE RESTRICTION
466 ! FACMIN/WORK(5) <= HNEW(J)/HOLD <= 1/FACMIN
467 ! WHERE FACMIN=WORK(4)**(1/(J-1))
468 IF(RCNTRL(10) == 0.D0
)THEN
473 IF(RCNTRL(11) == 0.D0
)THEN
478 !~~~> FAC3, FAC4: PARAMETERS FOR THE ORDER SELECTION
479 ! ORDER IS DECREASED IF W(K-1) <= W(K)*WORK(6)
480 ! ORDER IS INCREASED IF W(K) <= W(K-1)*WORK(7)
481 IF(RCNTRL(12) == 0.D0
)THEN
486 IF(RCNTRL(13) == 0.D0
)THEN
491 !~~~>- FacSafe1, FacSafe2: safety factors for step size prediction
492 ! HNEW=H*WORK(9)*(WORK(8)*TOL/ERR)**(1/(J-1))
493 IF(RCNTRL(14) == 0.D0
)THEN
498 IF(RCNTRL(15) == 0.D0
)THEN
504 !~~~> WorkFcn: estimated computational work for a calls to FCN
505 IF(RCNTRL(16) == 0.D0
)THEN
510 !~~~> WorkJac: estimated computational work for calls to JAC
511 IF(RCNTRL(17) == 0.D0
)THEN
516 !~~~> WorkDec: estimated computational work for calls to DEC
517 IF(RCNTRL(18) == 0.D0
)THEN
522 !~~~> WorkSol: estimated computational work for calls to SOL
523 IF(RCNTRL(19) == 0.D0
)THEN
528 WorkRow
=WorkFcn
+WorkSol
530 !~~~> Check if tolerances are reasonable
532 IF (AbsTol(1) <= 0.D0
.OR
.RelTol(1) <= 10.D0
*Roundoff
) THEN
533 PRINT * , ' Scalar AbsTol = ',AbsTol(1)
534 PRINT * , ' Scalar RelTol = ',RelTol(1)
535 CALL SEULEX_ErrorMsg(-9,Tinitial
,ZERO
,IERR
)
539 IF (AbsTol(i
) <= 0.D0
.OR
.RelTol(i
) <= 10.D0
*Roundoff
) THEN
540 PRINT * , ' AbsTol(',i
,') = ',AbsTol(i
)
541 PRINT * , ' RelTol(',i
,') = ',RelTol(i
)
542 CALL SEULEX_ErrorMsg(-9,Tinitial
,ZERO
,IERR
)
549 !~~~>---- PREPARE THE ENTRY-POINTS FOR THE ARRAYS IN WORK -----
550 Ncolumns2
=(Ncolumns
*(Ncolumns
+1))/2
554 !~~~> CALL TO CORE INTEGRATOR
555 CALL SEULEX_Integrator(N
,T
,Tfinal
,Y
,Hmax
,H
,Ncolumns
,RelTol
,AbsTol
,ITOL
, &
556 IOUT
,IERR
,Max_no_steps
,Roundoff
,Nsequence
,AUTNMS
, &
557 FAC1
,FAC2
,FAC3
,FAC4
,ThetaMin
,FacSafe1
,FacSafe2
,WorkJac
, &
558 WorkDec
,WorkRow
,Ncolumns2
,NRD
,LAMBDA
,Nstp
)
568 END SUBROUTINE ATMSEULEX
570 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
571 SUBROUTINE SEULEX_ErrorMsg(Code
,T
,H
,IERR
)
572 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
573 ! Handles all error messages
574 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
576 KPP_REAL
, INTENT(IN
) :: T
, H
577 INTEGER, INTENT(IN
) :: Code
578 INTEGER, INTENT(OUT
) :: IERR
582 'Forced exit from SEULEX due to the following error:'
586 PRINT * , '--> Improper value for maximal no of steps'
588 PRINT * , '--> Improper value for maximum no of columns in extrapolation'
590 PRINT * , '--> Improper value for step size sequence'
592 PRINT * , '--> Improper value for Lambda (must be 0/1)'
594 PRINT * , '--> Improper number of dense output components'
596 PRINT * , '--> Improper parameters for second order equations'
598 PRINT * , '--> Hmin/Hmax/Hstart must be positive'
600 PRINT * , '--> FacMin/FacMax/FacRej must be positive'
602 PRINT * , '--> Improper tolerance values'
604 PRINT * , '--> No of steps exceeds maximum bound'
606 PRINT * , '--> Step size too small: T + 10*H = T', &
609 PRINT * , '--> Matrix is repeatedly singular'
611 PRINT *, 'Unknown Error code: ', Code
614 PRINT *, "T=", T
, "and H=", H
616 END SUBROUTINE SEULEX_ErrorMsg
619 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
620 SUBROUTINE SEULEX_Integrator(N
,T
,Tend
,Y
,Hmax
,H
,Ncolumns
,RelTol
,AbsTol
,ITOL
,&
621 IOUT
,IERR
,Max_no_steps
,Roundoff
,Nsequence
,AUTNMS
, &
622 FAC1
,FAC2
,FAC3
,FAC4
,ThetaMin
,FacSafe1
,FacSafe2
,WorkJac
, &
623 WorkDec
,WorkRow
,Ncolumns2
,NRD
,LAMBDA
,Nstp
)
624 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
625 ! CORE INTEGRATOR FOR SEULEX
626 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
628 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
629 USE KPP_ROOT_Parameters
630 USE KPP_ROOT_Jacobian
631 IMPLICIT KPP_REAL (A
-H
,O
-Z
)
632 IMPLICIT INTEGER (I
-N
)
634 INTEGER :: N
, Ncolumns
, Ncolumns2
, K
, KC
, KRIGHT
, KLR
, KK
, KRN
,&
636 KPP_REAL
:: Y(NVAR
),DY(NVAR
),FX(NVAR
),YHH(NVAR
)
637 KPP_REAL
:: DYH(NVAR
), DEL(NVAR
), WH(NVAR
)
638 KPP_REAL
:: SCAL(NVAR
), HH(Ncolumns
), W(Ncolumns
), A(Ncolumns
)
640 KPP_REAL
:: FJAC(NVAR
,NVAR
)
642 KPP_REAL
:: FJAC(LU_NONZERO
)
644 KPP_REAL
Table(Ncolumns
,N
)
645 INTEGER IP(N
),NJ(Ncolumns
),IPHES(N
),ICOMP(NRD
)
646 KPP_REAL
RelTol(*),AbsTol(*)
647 KPP_REAL
FSAFE(Ncolumns2
,NRD
),FACUL(Ncolumns
),E(N
,N
),DENS((Ncolumns
+2)*NRD
)
648 LOGICAL REJECT
,LAST
,ATOV
,CALJAC
,CALHES
,AUTNMS
650 KPP_REAL TOLDD
,HHH
,NNRD
651 COMMON /COSEU
/TOLDD
,HHH
,NNRD
,KRIGHT
653 !~~~> COMPUTE COEFFICIENTS FOR DENSE OUTPUT
656 !~~~> COMPUTE THE FACTORIALS --------
659 FACUL(i
+1)=i
*FACUL(i
)
663 !~~~> DEFINE THE STEP SIZE SEQUENCE
664 IF (Nsequence
== 1) THEN
672 IF (Nsequence
== 2) THEN
680 IF (Nsequence
== 3) NJ(i
)=I
681 IF (Nsequence
== 4) NJ(i
)=I
+1
683 A(1)=WorkJac
+NJ(1)*WorkRow
+WorkDec
685 A(i
)=A(i
-1)+(NJ(i
)-1)*WorkRow
+WorkDec
687 K
=MAX0(3,MIN0(Ncolumns
-2,INT(-DLOG10(RelTol(1)+AbsTol(1))*.6D0
+1.5D0
)))
690 HmaxN
= MIN(ABS(Hmax
),ABS(Tend
-T
))
691 IF (ABS(H
) <= 10.D0
*Roundoff
) H
=1.0D
-6
693 Theta
=2*ABS(ThetaMin
)
698 SCAL(i
)=AbsTol(1)+RelTol(1)*DABS(Y(i
))
700 SCAL(i
)=AbsTol(i
)+RelTol(i
)*DABS(Y(i
))
707 IF (REJECT
) Theta
=2*ABS(ThetaMin
)
709 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
710 !~~~> IS Tend REACHED IN THE NEXT STEP?
711 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
713 IF (H1
<= Roundoff
) GO
TO 110
716 IF (H
>= H1
-Roundoff
) LAST
=.TRUE
.
718 CALL FUN_CHEM(T
,Y
,DY
)
720 IF (Theta
> ThetaMin
.AND
..NOT
.CALJAC
) THEN
721 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
722 ! COMPUTATION OF THE JACOBIAN
723 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
724 CALL JAC_CHEM(T
,Y
,FJAC
)
728 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
729 !~~~> THE FIRST AND LAST STEP
730 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
731 IF (Nstp
== 0.OR
.LAST
) THEN
736 CALL SEUL(J
,N
,T
,Y
,DY
,FX
,FJAC
,LFJAC
,E
,LE
,IP
,H
,Ncolumns
, &
737 HmaxN
,Table
,SCAL
,NJ
,HH
,W
,A
,YHH
,DYH
,DEL
,WH
,ERR
,FacSafe1
,FAC
, &
738 FAC1
,FAC2
,FacSafe2
,Theta
,Nfun
,Ndec
,Nsol
, &
739 ERROLD
,IPHES
,ICOMP
,AUTNMS
,REJECT
, &
740 ATOV
,FSAFE
,Ncolumns2
,NRD
,IOUT
,IPT
,CALHES
)
742 IF (J
> 1 .AND
. ERR
<= 1.d0
) GOTO 60
746 !~~~> BASIC INTEGRATION STEP
750 IF (Nstp
>= Max_no_steps
) GOTO 120
753 CALL SEUL(J
,N
,T
,Y
,DY
,FX
,FJAC
,LFJAC
,E
,LE
,IP
,H
,Ncolumns
,&
754 HmaxN
,Table
,SCAL
,NJ
,HH
,W
,A
,YHH
,DYH
,DEL
,WH
,ERR
,FacSafe1
,&
755 FAC
,FAC1
,FAC2
,FacSafe2
,Theta
,Nfun
,Ndec
,Nsol
,&
756 ERROLD
,IPHES
,ICOMP
,AUTNMS
,REJECT
,&
757 ATOV
,FSAFE
,Ncolumns2
,NRD
,IOUT
,IPT
,CALHES
)
760 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
761 !~~~> CONVERGENCE MONITOR
762 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
763 IF (K
== 2.OR
.REJECT
) GO
TO 50
764 IF (ERR
<= 1.D0
) GO
TO 60
765 IF (ERR
> DBLE(NJ(K
+1)*NJ(K
))*4.D0
) GO
TO 100
766 50 CALL SEUL(K
,N
,T
,Y
,DY
,FX
,FJAC
,LFJAC
,E
,LE
,IP
,H
,Ncolumns
,&
767 HmaxN
,Table
,SCAL
,NJ
,HH
,W
,A
,YHH
,DYH
,DEL
,WH
,ERR
,FacSafe1
,&
768 FAC
,FAC1
,FAC2
,FacSafe2
,Theta
,Nfun
,Ndec
,Nsol
,&
769 ERROLD
,IPHES
,ICOMP
,AUTNMS
,REJECT
,&
770 ATOV
,FSAFE
,Ncolumns2
,NRD
,IOUT
,IPT
,CALHES
)
773 IF (ERR
<= 1.D0
) GO
TO 60
774 !~~~> HOPE FOR CONVERGENCE IN LINE K+1
775 55 IF (ERR
> DBLE(NJ(K
+1))*2.D0
) GO
TO 100
777 CALL SEUL(KC
,N
,T
,Y
,DY
,FX
,FJAC
,LFJAC
,E
,LE
,IP
,H
,Ncolumns
,&
778 HmaxN
,Table
,SCAL
,NJ
,HH
,W
,A
,YHH
,DYH
,DEL
,WH
,ERR
,FacSafe1
,&
779 FAC
,FAC1
,FAC2
,FacSafe2
,Theta
,Nfun
,Ndec
,Nsol
,&
780 ERROLD
,IPHES
,ICOMP
,AUTNMS
,REJECT
,&
781 ATOV
,FSAFE
,Ncolumns2
,NRD
,IOUT
,IPT
,CALHES
)
783 IF (ERR
> 1.D0
) GO
TO 100
784 !Adi IF ((ERR > 1.D0).and.(H.gt.Hmin)) GO TO 100
785 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
786 !~~~> STEP IS ACCEPTED
787 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
799 SCAL(i
)=AbsTol(1)+RelTol(1)*DABS(T1I
)
801 SCAL(i
)=AbsTol(i
)+RelTol(i
)*DABS(T1I
)
811 DENS(NRD
+I
)=Y(ICOMP(i
))
814 !~~~> COMPUTE DIFFERENCES
821 FSAFE(L
,I
)=FSAFE(L
,I
)-FSAFE(L
-1,I
)
826 !~~~> COMPUTE DERIVATIVES AT RIGHT END ----
829 FACNJ
=FACNJ
**KLR
/FACUL(KLR
+1)
832 KRN
=(KK
-LAMBDA
+1)*NRD
833 DENS(KRN
+I
)=FSAFE(IPT
,I
)*FACNJ
838 DO L
=J
,KLR
+LAMBDA
+1,-1
839 FACTOR
=DBLENJ
/NJ(L
-1)-1.D0
841 KRN
=(L
-LAMBDA
+1)*NRD
+I
842 DENS(KRN
-NRD
)=DENS(KRN
)+(DENS(KRN
)-DENS(KRN
-NRD
))/FACTOR
847 !~~~> COMPUTE THE COEFFICIENTS OF THE INTERPOLATION POLYNOMIAL
851 DENS(II
)=DENS(II
)-DENS(II
-NRD
)
855 !~~~> COMPUTE OPTIMAL ORDER
863 IF (W(KC
-1) < W(KC
)*FAC3
) KOPT
=KC
-1
864 IF (W(KC
) < W(KC
-1)*FAC4
) KOPT
=MIN0(KC
+1,Ncolumns
-1)
867 IF (KC
> 3.AND
.W(KC
-2) < W(KC
-1)*FAC3
) KOPT
=KC
-2
868 IF (W(KC
) < W(KOPT
)*FAC4
) KOPT
=MIN0(KC
,Ncolumns
-1)
870 !~~~> AFTER A REJECTED STEP
877 !~~~> COMPUTE STEP SIZE FOR NEXT STEP
881 IF (KC
< K
.AND
.W(KC
) < W(KC
-1)*FAC4
) THEN
882 H
=HH(KC
)*A(KOPT
+1)/A(KC
)
884 H
=HH(KC
)*A(KOPT
)/A(KC
)
888 !Adi H = MAX(H, Hmin)
890 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
891 !~~~> STEP IS REJECTED
892 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
894 IF (K
> 2.AND
.W(K
-1) < W(K
)*FAC3
) K
=K
-1
907 120 WRITE (6,979) T
,H
908 979 FORMAT(' EXIT OF SEULEX AT T=',D14
.7
,' H=',D14
.7
)
913 END SUBROUTINE SEULEX_Integrator
916 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
917 SUBROUTINE SEUL(JJ
,N
,T
,Y
,DY
,FX
,FJAC
,LFJAC
,E
,LE
,IP
,&
918 H
,Ncolumns
,HmaxN
,Table
,SCAL
,NJ
,HH
,W
,A
,YH
,DYH
,DEL
,WH
,ERR
,FacSafe1
, &
919 FAC
,FAC1
,FAC2
,FacSafe2
,Theta
,Nfun
,Ndec
,Nsol
,&
920 ERROLD
,IPHES
,ICOMP
, &
921 AUTNMS
,REJECT
,ATOV
,FSAFE
,Ncolumns2
,NRD
,IOUT
, &
923 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
924 !~~~> THIS SUBROUTINE COMPUTES THE J-TH LINE OF THE
925 !~~~> EXTRAPOLATION TABLE AND PROVIDES AN ESTIMATE
926 !~~~> OF THE OPTIMAL STEP SIZE
927 USE KPP_ROOT_Parameters
928 USE KPP_ROOT_Jacobian
929 IMPLICIT KPP_REAL (A
-H
,O
-Z
)
930 IMPLICIT INTEGER (I
-N
)
931 INTEGER :: Ncolumns
, Ncolumns2
, N
, NRD
932 KPP_REAL
:: Y(NVAR
),YH(NVAR
),DY(NVAR
),FX(NVAR
),DYH(NVAR
)
933 KPP_REAL
:: DEL(NVAR
),WH(NVAR
),SCAL(NVAR
),HH(Ncolumns
),W(Ncolumns
),A(Ncolumns
)
935 KPP_REAL
:: FJAC(NVAR
,NVAR
), E(NVAR
,NVAR
)
937 KPP_REAL
:: FJAC(LU_NONZERO
), E(LU_NONZERO
)
939 KPP_REAL
:: Table(Ncolumns
,NVAR
)
940 KPP_REAL
:: FSAFE(Ncolumns2
,NRD
)
941 INTEGER :: IP(N
),NJ(Ncolumns
),IPHES(N
),ICOMP(NRD
)
942 LOGICAL ATOV
,REJECT
,AUTNMS
,CALHES
944 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
945 ! COMPUTE THE MATRIX E AND ITS DECOMPOSITION
946 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
956 CALL DGETRF(N
,N
,E
,N
,IP
,ISING
)
962 E(LU_DIAG(j
))=E(LU_DIAG(j
))+HJI
964 CALL KppDecomp (E
,ISING
)
967 IF (ISING
.NE
.0) GOTO 79
968 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
969 !~~~> STARTING PROCEDURE
970 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
971 IF (.NOT
.AUTNMS
) THEN
972 CALL FUN_CHEM(T
+HJ
,Y
,DY
)
979 CALL DGETRS ('N',N
,1,E
,N
,IP
,DEL
,N
,ISING
)
981 CALL KppSolve (E
,DEL
)
985 IF (IOUT
== 2.AND
.M
== JJ
) THEN
988 FSAFE(IPT
,I
)=DEL(ICOMP(i
))
991 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
992 !~~~> SEMI-IMPLICIT EULER METHOD
993 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1000 CALL FUN_CHEM(T
+HJ
*MM
,YH
,DYH
)
1002 CALL FUN_CHEM(T
+HJ
*(MM
+1),YH
,DYH
)
1005 IF (MM
== 1.AND
.JJ
<= 2) THEN
1006 !~~~> STABILITY CHECK
1009 DEL1
=DEL1
+(DEL(i
)/SCAL(i
))**2
1012 IF (.NOT
.AUTNMS
) THEN
1013 CALL FUN_CHEM(T
+HJ
,YH
,WH
)
1016 DEL(i
)=WH(i
)-DEL(i
)*HJI
1020 DEL(i
)=DYH(i
)-DEL(i
)*HJI
1024 CALL DGETRS ('N',N
,1,E
,N
,IP
,DEL
,N
,ISING
)
1026 CALL KppSolve (E
,DEL
)
1031 DEL2
=DEL2
+(DEL(i
)/SCAL(i
))**2
1034 Theta
=DEL2
/MAX(1.D0
,DEL1
)
1035 IF (Theta
> 1.D0
) GOTO 79
1038 CALL DGETRS ('N',N
,1,E
,N
,IP
,DYH
,N
,ISING
)
1040 CALL KppSolve (E
,DYH
)
1046 IF (IOUT
== 2.AND
.MM
>= M
-JJ
) THEN
1049 FSAFE(IPT
,i
)=DEL(ICOMP(i
))
1055 Table(JJ
,I
)=YH(i
)+DEL(i
)
1057 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1058 !~~~> POLYNOMIAL EXTRAPOLATION
1059 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1062 FAC
=(DBLE(NJ(JJ
))/DBLE(NJ(L
-1)))-1.D0
1064 Table(L
-1,I
)=Table(L
,I
)+(Table(L
,I
)-Table(L
-1,I
))/FAC
1069 ERR
=ERR
+MIN(ABS((Table(1,I
)-Table(2,I
)))/SCAL(i
),1.D15
)**2
1071 IF (ERR
>= 1.D30
) GOTO 79
1072 ERR
=SQRT(ERR
/DBLE(N
))
1073 IF (JJ
> 2.AND
.ERR
>= ERROLD
) GOTO 79
1074 ERROLD
=MAX(4*ERR
,1.D0
)
1075 !~~~> COMPUTE OPTIMAL STEP SIZES
1078 FAC
=MIN(FAC2
/FACMIN
,MAX(FACMIN
,(ERR
/FacSafe1
)**EXPO
/FacSafe2
))
1080 HH(JJ
)=MIN(H
*FAC
,HmaxN
)
1091 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1092 SUBROUTINE FUN_CHEM( T
, V
, FCT
)
1093 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1095 USE KPP_ROOT_Parameters
1097 USE KPP_ROOT_Function
, ONLY
: Fun
1098 USE KPP_ROOT_Rates
, ONLY
: Update_SUN
, Update_RCONST
, Update_PHOTO
1102 KPP_REAL
:: V(NVAR
), FCT(NVAR
)
1108 !CALL Update_RCONST()
1109 !CALL Update_PHOTO()
1111 CALL Fun(V
, FIX
, RCONST
, FCT
)
1114 END SUBROUTINE FUN_CHEM
1117 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1118 SUBROUTINE JAC_CHEM ( T
, V
, Jcb
)
1119 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1121 USE KPP_ROOT_Parameters
1123 USE KPP_ROOT_Jacobian
, ONLY
: Jac_SP
1124 USE KPP_ROOT_Rates
, ONLY
: Update_SUN
, Update_RCONST
, Update_PHOTO
1128 KPP_REAL
:: V(NVAR
), T
, TOLD
1130 KPP_REAL
:: JV(LU_NONZERO
), Jcb(NVAR
,NVAR
)
1133 KPP_REAL
:: Jcb(LU_NONZERO
)
1139 !CALL Update_RCONST()
1140 !CALL Update_PHOTO()
1144 CALL Jac_SP(V
, FIX
, RCONST
, JV
)
1151 Jcb(LU_IROW(i
),LU_ICOL(i
)) = JV(i
)
1154 CALL Jac_SP(V
, FIX
, RCONST
, Jcb
)
1158 END SUBROUTINE JAC_CHEM
1160 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1162 END MODULE KPP_ROOT_Integrator