1 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
2 ! RADAU5 - Runge-Kutta method based on Radau-2A quadrature !
3 ! (2 stages, order 5) !
4 ! By default the code employs the KPP sparse linear algebra routines !
5 ! Compile with -DFULL_ALGEBRA to use full linear algebra (LAPACK) !
6 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!
8 MODULE KPP_ROOT_Integrator
10 USE KPP_ROOT_Precision
, ONLY
: dp
11 USE KPP_ROOT_Jacobian
, ONLY
: NVAR
, LU_NONZERO
, LU_DIAG
12 USE KPP_ROOT_LinearAlgebra
19 INTEGER :: Nfun
, Njac
, Nstp
, Nacc
, Nrej
, Ndec
, Nsol
, Nsng
22 KPP_REAL
:: Transf(3,3), TransfInv(3,3), &
23 rkA(3,3), rkB(3), rkC(3), rkE(3), &
24 rkGamma
, rkAlpha
, rkBeta
26 ! description of the error numbers IERR
27 CHARACTER(LEN
=50), PARAMETER, DIMENSION(-11:1) :: IERR_NAMES
= (/ &
28 'Matrix is repeatedly singular ', & ! -11
29 'Step size too small: T + 10*H = T or H < Roundoff ', & ! -10
30 'No of steps exceeds maximum bound ', & ! -9
31 'Tolerances are too small ', & ! -8
32 'Improper values for Qmin, Qmax ', & ! -7
33 'Newton stopping tolerance too small ', & ! -6
34 'Improper value for ThetaMin ', & ! -5
35 'Improper values for FacMin/FacMax/FacSafe/FacRej ', & ! -4
36 'Hmin/Hmax/Hstart must be positive ', & ! -3
37 'Improper value for maximal no of Newton iterations', & ! -2
38 'Improper value for maximal no of steps ', & ! -1
44 ! **************************************************************************
46 SUBROUTINE INTEGRATE( TIN
, TOUT
, &
47 ICNTRL_U
, RCNTRL_U
, ISTATUS_U
, RSTATUS_U
, IERR_U
)
49 USE KPP_ROOT_Parameters
, ONLY
: NVAR
50 USE KPP_ROOT_Global
, ONLY
: ATOL
,RTOL
,VAR
54 KPP_REAL
:: TIN
! TIN - Start Time
55 KPP_REAL
:: TOUT
! TOUT - End Time
56 INTEGER, INTENT(IN
), OPTIONAL
:: ICNTRL_U(20)
57 KPP_REAL
, INTENT(IN
), OPTIONAL
:: RCNTRL_U(20)
58 INTEGER, INTENT(OUT
), OPTIONAL
:: ISTATUS_U(20)
59 KPP_REAL
, INTENT(OUT
), OPTIONAL
:: RSTATUS_U(20)
60 INTEGER, INTENT(OUT
), OPTIONAL
:: IERR_U
65 KPP_REAL
:: RCNTRL(20), RSTATUS(20)
66 INTEGER :: ICNTRL(20), ISTATUS(20)
67 INTEGER, SAVE :: Ntotal
= 0
71 !~~~> fine-tune the integrator:
73 ICNTRL(2) = 0 ! 0=vector tolerances, 1=scalar tolerances
74 ICNTRL(5) = 8 ! Max no. of Newton iterations
75 ICNTRL(6) = 1 ! Starting values for Newton are interpolated (0) or zero (1)
76 ICNTRL(11) = 1 ! Gustaffson (1) or classic(2) controller
79 !~~~> if optional parameters are given, and if they are >0,
80 ! then use them to overwrite default settings
81 IF (PRESENT(ICNTRL_U
)) ICNTRL(1:20) = ICNTRL_U(1:20)
82 IF (PRESENT(RCNTRL_U
)) RCNTRL(1:20) = RCNTRL_U(1:20)
85 CALL RADAU5( NVAR
,TIN
,TOUT
,VAR
,H
, &
87 RCNTRL
,ICNTRL
,RSTATUS
,ISTATUS
,IERR
)
89 !!$ Ntotal = Ntotal + Nstp
90 !!$ PRINT*,'NSTEPS=',Nstp,' (',Ntotal,')'
92 Nfun
= Nfun
+ ISTATUS(1)
93 Njac
= Njac
+ ISTATUS(2)
94 Nstp
= Nstp
+ ISTATUS(3)
95 Nacc
= Nacc
+ ISTATUS(4)
96 Nrej
= Nrej
+ ISTATUS(5)
97 Ndec
= Ndec
+ ISTATUS(6)
98 Nsol
= Nsol
+ ISTATUS(7)
99 Nsng
= Nsng
+ ISTATUS(8)
101 ! if optional parameters are given for output
102 ! use them to store information in them
103 IF (PRESENT(ISTATUS_U
)) THEN
105 ISTATUS_U(1) = Nfun
! function calls
106 ISTATUS_U(2) = Njac
! jacobian calls
107 ISTATUS_U(3) = Nstp
! steps
108 ISTATUS_U(4) = Nacc
! accepted steps
109 ISTATUS_U(5) = Nrej
! rejected steps (except at the beginning)
110 ISTATUS_U(6) = Ndec
! LU decompositions
111 ISTATUS_U(7) = Nsol
! forward/backward substitutions
113 IF (PRESENT(RSTATUS_U
)) THEN
115 RSTATUS_U(1) = TOUT
! final time
117 IF (PRESENT(IERR_U
)) IERR_U
= IERR
119 ! mz_rs_20050716: IERR is returned to the user who then decides what to do
120 ! about it, i.e. either stop the run or ignore it.
121 !!$ IF (IERR < 0) THEN
122 !!$ PRINT *,'RADAU: Unsuccessful exit at T=', TIN,' (IERR=',IERR,')'
126 END SUBROUTINE INTEGRATE
128 SUBROUTINE RADAU5(N
,T
,Tend
,Y
,H
,RelTol
,AbsTol
, &
129 RCNTRL
,ICNTRL
,RSTATUS
,ISTATUS
,IDID
)
131 !~~~>-----------------------------------------------
132 ! NUMERICAL SOLUTION OF A STIFF (OR DIFFERENTIAL ALGEBRAIC)
133 ! SYSTEM OF FirstStep 0RDER ORDINARY DIFFERENTIAL EQUATIONS
135 ! THE SYSTEM CAN BE (LINEARLY) IMPLICIT (MASS-MATRIX M /= I)
137 ! THE METHOD USED IS AN IMPLICIT RUNGE-KUTTA METHOD (RADAU IIA)
138 ! OF ORDER 5 WITH STEP SIZE CONTROL AND CONTINUOUS OUTPUT.
141 ! AUTHORS: E. HAIRER AND G. WANNER
142 ! UNIVERSITE DE GENEVE, DEPT. DE MATHEMATIQUES
143 ! CH-1211 GENEVE 24, SWITZERLAND
144 ! E-MAIL: HAIRER@DIVSUN.UNIGE.CH, WANNER@DIVSUN.UNIGE.CH
146 ! THIS CODE IS PART OF THE BOOK:
147 ! E. HAIRER AND G. WANNER, SOLVING ORDINARY DIFFERENTIAL
148 ! EQUATIONS II. STIFF AND DIFFERENTIAL-ALGEBRAIC PROBLEMS.
149 ! SPRINGER SERIES IN COMPUTATIONAL MATHEMATICS 14,
150 ! SPRINGER-VERLAG (1991)
152 ! VERSION OF SEPTEMBER 30, 1995
156 ! N DIMENSION OF THE SYSTEM
158 ! FCN NAME (EXTERNAL) OF SUBROUTINE COMPUTING THE
160 ! SUBROUTINE FCN(N,T,Y,F)
161 ! KPP_REAL T,Y(N),F(N)
163 ! RPAR, IPAR (SEE BELOW)
165 ! T INITIAL TIME VALUE
167 ! Tend FINAL T-VALUE (Tend-T MAY BE POSITIVE OR NEGATIVE)
169 ! Y(N) INITIAL VALUES FOR Y
171 ! H INITIALL STEP SIZE GUESS;
172 ! FOR STIFF EQUATIONS WITH INITIALL TRANSIENT,
173 ! H=1.D0/(NORM OF F'), USUALLY 1.D-3 OR 1.D-5, IS GOOD.
174 ! THIS CHOICE IS NOT VERY IMPORTANT, THE STEP SIZE IS
175 ! QUICKLY ADAPTED. (IF H=0.D0, THE CODE PUTS H=1.D-6).
177 ! RelTol,AbsTol RELATIVE AND ABSOLUTE ERROR TOLERANCES.
178 ! for ICNTRL(2) = 0: AbsTol, RelTol are N-dimensional vectors
179 ! = 1: AbsTol, RelTol are scalars
181 ! ----- CONTINUOUS OUTPUT: -----
182 ! DURING CALLS TO "SOLOUT", A CONTINUOUS SOLUTION
183 ! FOR THE INTERVAL [Told,T] IS AVAILABLE THROUGH
185 ! >>> CONTR5(I,S,CONT,LRC) <<<
186 ! WHICH PROVIDES AN APPROXIMATION TO THE I-TH
187 ! COMPONENT OF THE SOLUTION AT THE POINT S. THE VALUE
188 ! S SHOULD LIE IN THE INTERVAL [Told,T].
189 ! DO NOT CHANGE THE ENTRIES OF CONT(LRC), IF THE
190 ! DENSE OUTPUT FUNCTION IS USED.
191 !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
193 !~~~> INPUT PARAMETERS:
195 ! Note: For input parameters equal to zero the default values of the
196 ! corresponding variables are used.
198 !~~~> Integer input parameters:
200 ! ICNTRL(1) = not used
202 ! ICNTRL(2) = 0: AbsTol, RelTol are NVAR-dimensional vectors
203 ! = 1: AbsTol, RelTol are scalars
205 ! ICNTRL(3) = not used
207 ! ICNTRL(4) -> maximum number of integration steps
208 ! For ICNTRL(4)=0 the default value of 10000 is used
210 ! ICNTRL(5) -> maximum number of Newton iterations
211 ! For ICNTRL(5)=0 the default value of 8 is used
213 ! ICNTRL(6) -> starting values of Newton iterations:
214 ! ICNTRL(6)=0 : starting values are obtained from
215 ! the extrapolated collocation solution
217 ! ICNTRL(6)=1 : starting values are zero
219 ! ICNTRL(11) -> switch for step size strategy
220 ! ICNTRL(8) == 1: mod. predictive controller (Gustafsson)
221 ! ICNTRL(8) == 2: classical step size control
222 ! the default value (for iwork(8)=0) is iwork(8)=1.
223 ! the choice iwork(8) == 1 seems to produce safer results;
224 ! for simple problems, the choice iwork(8) == 2 produces
225 ! often slightly faster runs
226 ! ( currently unused )
228 !~~~> Real input parameters:
230 ! RCNTRL(1) -> not used
232 ! RCNTRL(2) -> Hmax, upper bound for the integration step size
234 ! RCNTRL(3) -> not used
236 ! RCNTRL(4) -> FacMin, lower bound on step decrease factor (default=0.2)
238 ! RCNTRL(5) -> FacMax, upper bound on step increase factor (default=6)
240 ! RCNTRL(6) -> FacRej, step decrease factor after multiple rejections
243 ! RCNTRL(7) -> FacSafe, by which the new step is slightly smaller
244 ! than the predicted value (default=0.9)
246 ! RCNTRL(8) -> ThetaMin. If Newton convergence rate smaller
247 ! than ThetaMin the Jacobian is not recomputed;
250 ! RCNTRL(9) -> NewtonTol, stopping criterion for Newton's method
255 ! RCNTRL(11) -> Qmax. If Qmin < Hnew/Hold < Qmax, then the
256 ! step size is kept constant and the LU factorization
257 ! reused (default Qmin=1, Qmax=1.2)
258 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
263 ! T T-VALUE FOR WHICH THE SOLUTION HAS BEEN COMPUTED
264 ! (AFTER SUCCESSFUL RETURN T=Tend).
266 ! Y(N) NUMERICAL SOLUTION AT T
268 ! H PREDICTED STEP SIZE OF THE LastStep ACCEPTED STEP
270 ! IDID REPORTS ON SUCCESSFULNESS UPON RETURN:
272 ! ISTATUS(1) = No. of function calls
273 ! ISTATUS(2) = No. of jacobian calls
274 ! ISTATUS(3) = No. of steps
275 ! ISTATUS(4) = No. of accepted steps
276 ! ISTATUS(5) = No. of rejected steps (except at the beginning)
277 ! ISTATUS(6) = No. of LU decompositions
278 ! ISTATUS(7) = No. of forward/backward substitutions
279 ! ISTATUS(8) = No. of singular matrix decompositions
281 ! RSTATUS(1) -> Texit, the time corresponding to the
282 ! computed Y upon return
283 ! RSTATUS(2) -> Hexit, last accepted step before exit
284 ! For multiple restarts, use Hexit as Hstart
285 ! in the subsequent run
286 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
291 KPP_REAL
:: Y(N
),AbsTol(N
),RelTol(N
),RCNTRL(20),RSTATUS(20)
292 INTEGER :: ICNTRL(20), ISTATUS(20)
293 LOGICAL :: StartNewton
, Gustafsson
294 INTEGER :: IDID
, ITOL
297 !~~~> Control arguments
298 INTEGER :: Max_no_steps
, NewtonMaxit
299 KPP_REAL
:: Hstart
,Hmin
,Hmax
,Qmin
,Qmax
300 KPP_REAL
:: Roundoff
, ThetaMin
,TolNewton
301 KPP_REAL
:: FacSafe
,FacMin
,FacMax
,FacRej
302 !~~~> Local variables
304 KPP_REAL
, PARAMETER :: ZERO
= 0.0d0, ONE
= 1.0d0
306 !~~~> variables from the former COMMON block /CONRA5/
307 ! KPP_REAL :: Tsol, Hsol
309 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~
310 ! SETTING THE PARAMETERS
311 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~
321 !~~~> ICNTRL(1) - autonomous system - not used
322 !~~~> ITOL: 1 for vector and 0 for scalar AbsTol/RelTol
323 IF (ICNTRL(2) == 0) THEN
328 !~~~> ICNTRL(3) - method selection - not used
329 !~~~> Max_no_steps: the maximal number of time steps
330 IF (ICNTRL(4) == 0) THEN
333 Max_no_steps
=ICNTRL(4)
334 IF (Max_no_steps
<= 0) THEN
335 WRITE(6,*) 'ICNTRL(4)=',ICNTRL(4)
336 CALL RAD_ErrorMsg(-1,T
,ZERO
,IDID
)
339 !~~~> NewtonMaxit MAXIMAL NUMBER OF NEWTON ITERATIONS
340 IF (ICNTRL(5) == 0) THEN
343 NewtonMaxit
=ICNTRL(5)
344 IF (NewtonMaxit
<= 0) THEN
345 WRITE(6,*) 'ICNTRL(5)=',ICNTRL(5)
346 CALL RAD_ErrorMsg(-2,T
,ZERO
,IDID
)
349 !~~~> StartNewton: Use extrapolation for starting values of Newton iterations
350 IF (ICNTRL(6) == 0) THEN
353 StartNewton
= .FALSE
.
355 !~~~> Gustafsson: step size controller
356 IF(ICNTRL(11) == 0)THEN
363 !~~~> Roundoff SMALLEST NUMBER SATISFYING 1.0d0+Roundoff>1.0d0
364 Roundoff
=WLAMCH('E');
366 !~~~> RCNTRL(1) = Hmin - not used
368 !~~~> Hmax = maximal step size
369 IF (RCNTRL(2) == ZERO
) THEN
372 Hmax
=MAX(ABS(RCNTRL(7)),ABS(Tend
-T
))
374 !~~~> RCNTRL(3) = Hstart - not used
376 !~~~> FacMin: lower bound on step decrease factor
377 IF(RCNTRL(4) == ZERO
)THEN
382 !~~~> FacMax: upper bound on step increase factor
383 IF(RCNTRL(5) == ZERO
)THEN
388 !~~~> FacRej: step decrease factor after 2 consecutive rejections
389 IF(RCNTRL(6) == ZERO
)THEN
394 !~~~> FacSafe: by which the new step is slightly smaller
395 ! than the predicted value
396 IF (RCNTRL(7) == ZERO
) THEN
401 IF ( (FacMax
< ONE
) .OR
. (FacMin
> ONE
) .OR
. &
402 (FacSafe
<= 0.001D0
) .OR
. (FacSafe
>= 1.0d0) ) THEN
403 WRITE(6,*)'RCNTRL(4:7)=',RCNTRL(4:7)
404 CALL RAD_ErrorMsg(-4,T
,ZERO
,IDID
)
407 !~~~> ThetaMin: decides whether the Jacobian should be recomputed
408 IF (RCNTRL(8) == ZERO
) THEN
412 IF (ThetaMin
<= 0.0d0 .OR
. ThetaMin
>= 1.0d0) THEN
413 WRITE(6,*) 'RCNTRL(8)=', RCNTRL(8)
414 CALL RAD_ErrorMsg(-5,T
,ZERO
,IDID
)
417 !~~~> TolNewton: stopping crierion for Newton's method
418 IF (RCNTRL(9) == ZERO
) THEN
421 TolNewton
= RCNTRL(9)
422 IF (TolNewton
<= Roundoff
) THEN
423 WRITE(6,*) 'RCNTRL(9)=',RCNTRL(9)
424 CALL RAD_ErrorMsg(-6,T
,ZERO
,IDID
)
427 !~~~> Qmin AND Qmax: IF Qmin < Hnew/Hold < Qmax, STEP SIZE = CONST.
428 IF (RCNTRL(10) == ZERO
) THEN
433 IF (RCNTRL(11) == ZERO
) THEN
438 IF (Qmin
> ONE
.OR
. Qmax
< ONE
) THEN
439 WRITE(6,*) 'RCNTRL(10:11)=',Qmin
,Qmax
440 CALL RAD_ErrorMsg(-7,T
,ZERO
,IDID
)
442 !~~~> Check if tolerances are reasonable
444 IF (AbsTol(1) <= ZERO
.OR
.RelTol(1) <= 10.d0
*Roundoff
) THEN
445 WRITE (6,*) 'AbsTol/RelTol=',AbsTol
,RelTol
446 CALL RAD_ErrorMsg(-8,T
,ZERO
,IDID
)
450 IF (AbsTol(i
) <= ZERO
.OR
.RelTol(i
) <= 10.d0
*Roundoff
) THEN
451 WRITE (6,*) 'AbsTol/RelTol(',i
,')=',AbsTol(i
),RelTol(i
)
452 CALL RAD_ErrorMsg(-8,T
,ZERO
,IDID
)
457 !~~~> WHEN A FAIL HAS OCCURED, RETURN
461 !~~~> CALL TO CORE INTEGRATOR ------------
462 CALL RAD_Integrator( N
,T
,Y
,Tend
,Hmax
,H
,RelTol
,AbsTol
,ITOL
,IDID
, &
463 Max_no_steps
,Roundoff
,FacSafe
,ThetaMin
,TolNewton
,Qmin
,Qmax
, &
464 NewtonMaxit
,StartNewton
,Gustafsson
,FacMin
,FacMax
,FacRej
)
475 ! END SUBROUTINE RADAU5
476 CONTAINS ! INTERNAL PROCEDURES TO RADAU5
479 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
480 SUBROUTINE RAD_Integrator( N
,T
,Y
,Tend
,Hmax
,H
,RelTol
,AbsTol
,ITOL
,IDID
, &
481 Max_no_steps
,Roundoff
,FacSafe
,ThetaMin
,TolNewton
,Qmin
,Qmax
, &
482 NewtonMaxit
,StartNewton
,Gustafsson
,FacMin
,FacMax
,FacRej
)
483 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
484 ! CORE INTEGRATOR FOR RADAU5
485 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
489 KPP_REAL
Y(NVAR
),Z1(NVAR
),Z2(NVAR
),Z3(NVAR
),Y0(NVAR
),&
490 SCAL(NVAR
),F1(NVAR
),F2(NVAR
),F3(NVAR
), &
491 CONT(N
,4),AbsTol(NVAR
),RelTol(NVAR
)
494 KPP_REAL
:: FJAC(NVAR
,NVAR
), E1(NVAR
,NVAR
)
495 DOUBLE COMPLEX :: E2(NVAR
,NVAR
)
497 KPP_REAL
:: FJAC(LU_NONZERO
), E1(LU_NONZERO
)
498 DOUBLE COMPLEX :: E2(LU_NONZERO
)
501 !~~~> Local variables
502 KPP_REAL
:: TMP(NVAR
), T
, Tend
, Tdirection
, &
503 H
, Hmax
, HmaxN
, Hacc
, Hnew
, Hopt
, Hold
, &
504 Fac
, FacMin
, Facmax
, FacSafe
, FacRej
, FacGus
, FacConv
, &
505 Theta
, ThetaMin
, TolNewton
, ERR
, ERRACC
, &
506 Qmin
, Qmax
, DYNO
, Roundoff
, &
507 AK
, AK1
, AK2
, AK3
, C3Q
, &
508 Qnewton
, DYTH
, THQ
, THQOLD
, DYNOLD
, &
509 DENOM
, C1Q
, C2Q
, ALPHA
, BETA
, GAMMA
, CFAC
, ACONT3
, QT
510 INTEGER :: IP1(NVAR
),IP2(NVAR
), ITOL
, IDID
, Max_no_steps
, &
511 NewtonIter
, NewtonMaxit
, ISING
512 LOGICAL :: REJECT
, FirstStep
, FreshJac
, LastStep
, &
513 Gustafsson
, StartNewton
, NewtonDone
514 ! KPP_REAL, PARAMETER :: ONE = 1.0d0, ZERO = 0.0d0
516 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~
518 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~
520 CALL RAD_Coefficients
522 Tdirection
=SIGN(1.D0
,Tend
-T
)
523 HmaxN
=MIN(ABS(Hmax
),ABS(Tend
-T
))
524 H
=MIN(ABS(Hmin
),ABS(Hstart
))
526 IF (ABS(H
) <= 10.D0
*Roundoff
) H
=1.0D
-6
532 FreshJac
=.FALSE
.; Theta
=1.0d0
533 IF ((T
+H
*1.0001D0
-Tend
)*Tdirection
>= 0.D0
) THEN
538 CFAC
=FacSafe
*(1+2*NewtonMaxit
)
541 CALL RAD_ErrorScale(N
,ITOL
,AbsTol
,RelTol
,Y
,SCAL
)
542 CALL FUN_CHEM(T
,Y
,Y0
)
544 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
545 !~~~> Time loop begins
546 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
547 Tloop
: DO WHILE ( (Tend
-T
)*Tdirection
- Roundoff
> ZERO
)
549 !~~~> COMPUTE JACOBIAN MATRIX ANALYTICALLY
550 IF ( (.NOT
.FreshJac
) .AND
. (Theta
> ThetaMin
) ) THEN
551 CALL JAC_CHEM(T
,Y
,FJAC
)
555 !~~~> Compute the matrices E1 and E2 and their decompositions
559 CALL RAD_DecompReal(N
,FJAC
,GAMMA
,E1
,IP1
,ISING
)
563 CALL RAD_ErrorMsg(-12,T
,H
,IDID
); RETURN
565 H
=H
*0.5D0
; REJECT
=.TRUE
.; LastStep
=.FALSE
.
568 CALL RAD_DecompCmplx(N
,FJAC
,ALPHA
,BETA
,E2
,IP2
,ISING
)
572 CALL RAD_ErrorMsg(-12,T
,H
,IDID
); RETURN
574 H
=H
*0.5D0
; REJECT
=.TRUE
.; LastStep
=.FALSE
.
580 IF (Nstp
> Max_no_steps
) THEN
581 PRINT*,'Max number of time steps is ',Max_no_steps
582 CALL RAD_ErrorMsg(-9,T
,H
,IDID
); RETURN
584 IF (0.1D0
*ABS(H
) <= ABS(T
)*Roundoff
) THEN
585 CALL RAD_ErrorMsg(-10,T
,H
,IDID
); RETURN
588 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~
589 ! STARTING VALUES FOR NEWTON ITERATION
590 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~
591 IF ( FirstStep
.OR
. (.NOT
.StartNewton
) ) THEN
606 Z1(i
)=C1Q
*(AK1
+(C1Q
-rkC(2)+ONE
)*(AK2
+(C1Q
-rkC(1)+ONE
)*AK3
))
607 Z2(i
)=C2Q
*(AK1
+(C2Q
-rkC(2)+ONE
)*(AK2
+(C2Q
-rkC(1)+ONE
)*AK3
))
608 Z3(i
)=C3Q
*(AK1
+(C3Q
-rkC(2)+ONE
)*(AK2
+(C3Q
-rkC(1)+ONE
)*AK3
))
610 ! F(1,2,3) = TransfInv x Z(1,2,3)
611 CALL RAD_Transform(N
,TransfInv
,Z1
,Z2
,Z3
,F1
,F2
,F3
)
613 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~
614 ! LOOP FOR THE SIMPLIFIED NEWTON ITERATION
615 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~
617 FacConv
= MAX(FacConv
,Roundoff
)**0.8D0
620 NewtonLoop
:DO NewtonIter
= 1, NewtonMaxit
622 !~~~> The right-hand side
626 CALL FUN_CHEM(T
+rkC(1)*H
,TMP
,Z1
)
630 CALL FUN_CHEM(T
+rkC(2)*H
,TMP
,Z2
)
634 CALL FUN_CHEM(T
+rkC(3)*H
,TMP
,Z3
)
636 !~~~> Solve the linear systems
637 ! Z(1,2,3) = TransfInv x Z(1,2,3)
638 CALL RAD_Transform(N
,TransfInv
,Z1
,Z2
,Z3
,Z1
,Z2
,Z3
)
639 CALL RAD_Solve( N
,FJAC
,GAMMA
,ALPHA
,BETA
,E1
,E2
, &
640 Z1
,Z2
,Z3
,F1
,F2
,F3
,CONT
,IP1
,IP2
,ISING
)
646 DYNO
=DYNO
+(Z1(i
)/DENOM
)**2+(Z2(i
)/DENOM
)**2+(Z3(i
)/DENOM
)**2
648 DYNO
=SQRT(DYNO
/(3*N
))
650 !~~~> Bad convergence or number of iterations too large
651 IF ( (NewtonIter
> 1) .AND
. (NewtonIter
< NewtonMaxit
) ) THEN
653 IF (NewtonIter
== 2) THEN
656 Theta
=SQRT(THQ
*THQOLD
)
659 IF (Theta
< 0.99d0) THEN
660 FacConv
=Theta
/(1.0d0-Theta
)
661 DYTH
=FacConv
*DYNO
*Theta
**(NewtonMaxit
-1-NewtonIter
)/TolNewton
662 IF (DYTH
>= 1.0d0) THEN
663 Qnewton
=MAX(1.0D
-4,MIN(20.0d0,DYTH
))
664 FAC
=.8D0
*Qnewton
**(-1.0d0/(4.0d0+NewtonMaxit
-1-NewtonIter
))
670 ELSE ! Non-convergence of Newton
671 H
=H
*0.5D0
; REJECT
=.TRUE
.; LastStep
=.FALSE
.
675 DYNOLD
=MAX(DYNO
,Roundoff
)
676 CALL WAXPY(N
,ONE
,Z1
,1,F1
,1) ! F1 <- F1 + Z1
677 CALL WAXPY(N
,ONE
,Z2
,1,F2
,1) ! F2 <- F2 + Z2
678 CALL WAXPY(N
,ONE
,Z3
,1,F3
,1) ! F3 <- F3 + Z3
679 ! Z(1,2,3) = Transf x F(1,2,3)
680 CALL RAD_Transform(N
,Transf
,F1
,F2
,F3
,Z1
,Z2
,Z3
)
681 NewtonDone
= (FacConv
*DYNO
<= TolNewton
)
682 IF (NewtonDone
) EXIT NewtonLoop
686 IF (.NOT
.NewtonDone
) THEN
687 CALL RAD_ErrorMsg(-8,T
,H
,IDID
);
688 H
=H
*0.5D0
; REJECT
=.TRUE
.; LastStep
=.FALSE
.
693 !~~~> ERROR ESTIMATION
694 CALL RAD_ErrorEstimate(N
,FJAC
,H
,Y0
,Y
,T
, &
695 E1
,Z1
,Z2
,Z3
,IP1
,SCAL
,ERR
, &
696 FirstStep
,REJECT
,GAMMA
)
697 !~~~> COMPUTATION OF Hnew
698 Fac
= ERR
**(-0.25d0)* &
699 MIN(FacSafe
,(NewtonIter
+2*NewtonMaxit
)/CFAC
)
700 Fac
= MIN(FacMax
,MAX(FacMin
,Fac
))
703 !~~~> IS THE ERROR SMALL ENOUGH ?
704 accept:IF (ERR
< ONE
) THEN !~~~> STEP IS ACCEPTED
708 !~~~> Predictive controller of Gustafsson
709 !~~~> Currently not implemented
711 FacGus
=FacSafe
*(H
/Hacc
)*(ERR
**2/ERRACC
)**(-0.25d0)
712 FacGus
=MIN(FacMax
,MAX(FacMin
,FacGus
))
717 ERRACC
=MAX(1.0D
-2,ERR
)
724 CONT(i
,2)=(Z2(i
)-Z3(i
))/(rkC(2)-ONE
)
725 AK
=(Z1(i
)-Z2(i
))/(rkC(1)-rkC(2))
727 ACONT3
=(AK
-ACONT3
)/rkC(2)
728 CONT(i
,3)=(AK
-CONT(i
,2))/(rkC(1)-ONE
)
729 CONT(i
,4)=CONT(i
,3)-ACONT3
731 CALL RAD_ErrorScale(N
,ITOL
,AbsTol
,RelTol
,Y
,SCAL
)
738 CALL FUN_CHEM(T
,Y
,Y0
)
739 Hnew
=Tdirection
*MIN(ABS(Hnew
),HmaxN
)
742 IF (REJECT
) Hnew
=Tdirection
*MIN(ABS(Hnew
),ABS(H
))
744 IF ((T
+Hnew
/Qmin
-Tend
)*Tdirection
>= 0.D0
) THEN
749 IF ( (Theta
<=ThetaMin
) .AND
. (QT
>=Qmin
) &
750 .AND
. (QT
<=Qmax
) ) GOTO 30
754 ELSE accept !~~~> STEP IS REJECTED
762 IF (Nacc
>= 1) Nrej
=Nrej
+1
770 END SUBROUTINE RAD_Integrator
772 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
773 SUBROUTINE RAD_ErrorMsg(Code
,T
,H
,IERR
)
774 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
775 ! Handles all error messages
776 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
779 KPP_REAL
, INTENT(IN
) :: T
, H
780 INTEGER, INTENT(IN
) :: Code
781 INTEGER, INTENT(OUT
) :: IERR
785 'Forced exit from RADAU5 due to the following error:'
786 IF ((Code
>=-11).AND
.(Code
<=-1)) THEN
787 PRINT *, IERR_NAMES(Code
)
789 PRINT *, 'Unknown Error code: ', Code
792 PRINT *, "T=", T
, "and H=", H
794 END SUBROUTINE RAD_ErrorMsg
797 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
798 SUBROUTINE RAD_ErrorScale(N
,ITOL
,AbsTol
,RelTol
,Y
,SCAL
)
799 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
800 ! Handles all error messages
801 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
803 INTEGER, INTENT(IN
) :: N
, ITOL
804 KPP_REAL
, INTENT(IN
) :: AbsTol(*), RelTol(*), Y(N
)
805 KPP_REAL
, INTENT(OUT
) :: SCAL(N
)
810 SCAL(i
)=AbsTol(1)+RelTol(1)*ABS(Y(i
))
814 SCAL(i
)=AbsTol(i
)+RelTol(i
)*ABS(Y(i
))
818 END SUBROUTINE RAD_ErrorScale
820 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
821 SUBROUTINE RAD_Transform(N
,Tr
,Z1
,Z2
,Z3
,F1
,F2
,F3
)
823 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
826 KPP_REAL
:: Tr(3,3),Z1(N
),Z2(N
),Z3(N
),F1(N
),F2(N
),F3(N
)
827 KPP_REAL
:: x1
, x2
, x3
829 x1
= Z1(i
); x2
= Z2(i
); x3
= Z3(i
)
830 F1(i
) = Tr(1,1)*x1
+ Tr(1,2)*x2
+ Tr(1,3)*x3
831 F2(i
) = Tr(2,1)*x1
+ Tr(2,2)*x2
+ Tr(2,3)*x3
832 F3(i
) = Tr(3,1)*x1
+ Tr(3,2)*x2
+ Tr(3,3)*x3
834 END SUBROUTINE RAD_Transform
836 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
837 SUBROUTINE RAD_Coefficients
838 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
840 KPP_REAL
:: s2
,s3
,s6
,x1
,x2
,x3
,x4
,y1
,y2
,y3
,y4
,y5
845 x1
= 3.d0
**(1.d0
/3.d0
);
846 x2
= 3.d0
**(2.d0
/3.d0
);
847 x3
= 3.d0
**(1.d0
/6.d0
);
848 x4
= 3.d0
**(5.d0
/6.d0
);
850 rkA(1,1) = 11.d0
/45.d0
-7.d0
/360.d0
*s6
851 rkA(1,2) = 37.d0
/225.d0
-169.d0
/1800.d0
*s6
852 rkA(1,3) = -2.d0
/225.d0
+s6
/75
853 rkA(2,1) = 37.d0
/225.d0
+169.d0
/1800.d0
*s6
854 rkA(2,2) = 11.d0
/45.d0
+7.d0
/360.d0
*s6
855 rkA(2,3) = -2.d0
/225.d0
-s6
/75
856 rkA(3,1) = 4.d0
/9.d0
-s6
/36
857 rkA(3,2) = 4.d0
/9.d0
+s6
/36
860 rkB(1) = 4.d0
/9.d0
-s6
/36
861 rkB(2) = 4.d0
/9.d0
+s6
/36
864 rkC(1) = 2.d0
/5.d0
-s6
/10
865 rkC(2) = 2.d0
/5.d0
+s6
/10
869 rkE(1) = -(13.d0
+7.d0
*s6
)/3.d0
870 rkE(2) = (-13.d0
+7.d0
*s6
)/3.d0
873 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
874 !~~~> Diagonalize the RK matrix:
875 ! TransfInv * inv(rkA) * Transf =
877 ! | 0 rkAlpha -rkBeta |
878 ! | 0 rkBeta rkAlpha |
879 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
881 rkAlpha
= x1
/2-x2
/2+3
882 rkBeta
= -x4
/2-3.d0
/2.d0
*x3
885 y2
= 129.d0
/2500.d0
*x1
886 y3
= 111.d0
/2500.d0
*x3
*s2
887 Transf(1,1) = -31.d0
/1250.d0
*s6
*x1
+37.d0
/1250.d0
*s6
*x2
-y1
&
888 +129.d0
/1250.d0
*x1
-33.d0
/1250.d0
*x2
+49.d0
/625.d0
889 Transf(1,2) = -y1
-y2
-y3
&
890 +31.d0
/2500.d0
*x4
*s2
+33.d0
/2500.d0
*x2
+49.d0
/625.d0
891 Transf(1,3) = 3.d0
/2500.d0
*x3
*(-33-43*x2
+31*x3
*s2
+37*s3
*s2
)
892 Transf(2,1) = 31.d0
/1250.d0
*s6
*x1
-37.d0
/1250.d0
*s6
*x2
+y1
&
893 +129.d0
/1250.d0
*x1
-33.d0
/1250.d0
*x2
+49.d0
/625.d0
894 Transf(2,2) = y1
-y2
+y3
&
895 -31.d0
/2500.d0
*x4
*s2
+33.d0
/2500.d0
*x2
+49.d0
/625.d0
896 Transf(2,3) = -3.d0
/2500.d0
*x3
*(33+43*x2
+31*x3
*s2
+37*s3
*s2
)
901 y1
= 11.d0
/36.d0
*x3
*s2
+ 43.d0
/108.d0
*x4
*s2
902 y2
= 11.d0
/36.d0
*s2
*x2
- 43.d0
/36.d0
*s2
*x1
903 y3
= 31.d0
/54.d0
*x1
+ 37.d0
/54.d0
*x2
904 y4
= 31.d0
/54.d0
*x4
-37.d0
/18.d0
*x3
905 y5
= -x2
/27+5.d0
/27.d0
*x1
906 TransfInv(1,1) = y1
+ y3
907 TransfInv(1,2) = -y1
+ y3
908 TransfInv(1,3) = y5
+ 1.d0
/3.d0
909 TransfInv(2,1) = -y1
- y3
910 TransfInv(2,2) = y1
- y3
911 TransfInv(2,3) = -y5
+ 2.d0
/3.d0
912 TransfInv(3,1) = y4
- y2
913 TransfInv(3,2) = y4
+ y2
914 TransfInv(3,3) = x3
/9+5.d0
/27.d0
*x4
916 END SUBROUTINE RAD_Coefficients
919 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
920 SUBROUTINE RAD_DecompReal(N
,FJAC
,GAMMA
,E1
,IP1
,ISING
)
921 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
927 KPP_REAL
:: FJAC(NVAR
,NVAR
),E1(NVAR
,NVAR
)
929 KPP_REAL
:: FJAC(LU_NONZERO
),E1(LU_NONZERO
)
931 INTEGER :: IP1(N
), i
, j
938 E1(j
,j
)=E1(j
,j
)+GAMMA
940 CALL DGETRF(N
,N
,E1
,N
,IP1
,ISING
)
946 j
= LU_DIAG(i
); E1(j
)=E1(j
)+GAMMA
948 CALL KppDecomp(E1
,ISING
)
951 END SUBROUTINE RAD_DecompReal
954 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
955 SUBROUTINE RAD_DecompCmplx(N
,FJAC
,ALPHA
,BETA
,E2
,IP2
,ISING
)
956 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
960 KPP_REAL
:: FJAC(N
,N
)
961 DOUBLE COMPLEX :: E2(N
,N
)
963 KPP_REAL
:: FJAC(LU_NONZERO
)
964 DOUBLE COMPLEX :: E2(LU_NONZERO
)
966 KPP_REAL
:: ALPHA
, BETA
967 INTEGER :: IP2(N
), i
, j
972 E2(i
,j
) = DCMPLX( -FJAC(i
,j
), 0.0d0 )
974 E2(j
,j
) = E2(j
,j
) + DCMPLX( ALPHA
, BETA
)
976 CALL ZGETRF(N
,N
,E2
,N
,IP2
,ISING
)
979 E2(i
) = DCMPLX( -FJAC(i
), 0.0d0 )
982 j
= LU_DIAG(i
); E2(j
)=E2(j
)+DCMPLX( ALPHA
, BETA
)
984 CALL KppDecompCmplx(E2
,ISING
)
988 END SUBROUTINE RAD_DecompCmplx
991 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
992 SUBROUTINE RAD_Solve(N
,FJAC
,GAMMA
,ALPHA
,BETA
,E1
,E2
,&
993 Z1
,Z2
,Z3
,F1
,F2
,F3
,CONT
,IP1
,IP2
,ISING
)
994 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
996 INTEGER :: N
,IP1(NVAR
),IP2(NVAR
),ISING
998 KPP_REAL
:: FJAC(NVAR
,NVAR
), E1(NVAR
,NVAR
)
999 DOUBLE COMPLEX :: E2(NVAR
,NVAR
)
1001 KPP_REAL
:: FJAC(LU_NONZERO
), E1(LU_NONZERO
)
1002 DOUBLE COMPLEX :: E2(LU_NONZERO
)
1004 KPP_REAL
:: Z1(N
),Z2(N
),Z3(N
), &
1005 F1(N
),F2(N
),F3(N
),CONT(N
), &
1007 DOUBLE COMPLEX :: BC(N
)
1014 Z1(i
)=Z1(i
)-F1(i
)*GAMMA
1015 Z2(i
)=Z2(i
)+S2
*ALPHA
-S3
*BETA
1016 Z3(i
)=Z3(i
)+S3
*ALPHA
+S2
*BETA
1019 CALL DGETRS ('N',N
,1,E1
,N
,IP1
,Z1
,N
,0)
1021 CALL KppSolve (E1
,Z1
)
1025 BC(j
) = DCMPLX(Z2(j
),Z3(j
))
1028 CALL ZGETRS ('N',N
,1,E2
,N
,IP2
,BC
,N
,0)
1030 CALL KppSolveCmplx (E2
,BC
)
1033 Z2(j
) = DBLE( BC(j
) )
1034 Z3(j
) = AIMAG( BC(j
) )
1037 END SUBROUTINE RAD_Solve
1040 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1041 SUBROUTINE RAD_ErrorEstimate(N
,FJAC
,H
,Y0
,Y
,T
,&
1042 E1
,Z1
,Z2
,Z3
,IP1
,SCAL
,ERR
, &
1043 FirstStep
,REJECT
,GAMMA
)
1044 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1049 KPP_REAL
:: FJAC(NVAR
,NVAR
), E1(NVAR
,NVAR
)
1051 KPP_REAL
:: FJAC(LU_NONZERO
), E1(LU_NONZERO
)
1053 KPP_REAL
:: SCAL(N
),Z1(N
),Z2(N
),Z3(N
),F1(N
),F2(N
), &
1054 Y0(N
),Y(N
),TMP(N
),T
,H
,GAMMA
1055 INTEGER :: IP1(N
), i
1056 LOGICAL FirstStep
,REJECT
1057 KPP_REAL
:: HEE1
,HEE2
,HEE3
,ERR
1064 F2(i
)=HEE1
*Z1(i
)+HEE2
*Z2(i
)+HEE3
*Z3(i
)
1069 CALL DGETRS ('N',N
,1,E1
,N
,IP1
,TMP
,N
,0)
1071 CALL KppSolve (E1
, TMP
)
1076 ERR
=ERR
+(TMP(i
)/SCAL(i
))**2
1078 ERR
=MAX(SQRT(ERR
/N
),1.D
-10)
1080 IF (ERR
< 1.D0
) RETURN
1081 firej
:IF (FirstStep
.OR
.REJECT
) THEN
1085 CALL FUN_CHEM(T
,TMP
,F1
)
1091 CALL DGETRS ('N',N
,1,E1
,N
,IP1
,TMP
,N
,0)
1093 CALL KppSolve (E1
, TMP
)
1097 ERR
=ERR
+(TMP(i
)/SCAL(i
))**2
1099 ERR
=MAX(SQRT(ERR
/N
),1.0d-10)
1102 END SUBROUTINE RAD_ErrorEstimate
1104 !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1105 ! KPP_REAL FUNCTION CONTR5(I,N,T,CONT)
1106 !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1107 !! THIS FUNCTION CAN BE USED FOR CONTINUOUS OUTPUT. IT PROVIDES AN
1108 !! APPROXIMATION TO THE I-TH COMPONENT OF THE SOLUTION AT T.
1109 !! IT GIVES THE VALUE OF THE COLLOCATION POLYNOMIAL, DEFINED FOR
1110 !! THE STEP SUCCESSFULLY COMPUTED STEP (BY RADAU5).
1111 !!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1114 ! KPP_REAL :: T, CONT(N,4)
1116 ! KPP_REAL, PARAMETER :: ONE = 1.0d0
1118 ! CONTR5=CONT(i,1)+S* &
1119 ! (CONT(i,2)+(S-rkC(2)+ONE)*(CONT(i,3)+(S-rkC(1)+ONE)*CONT(i,4)))
1120 ! END FUNCTION CONTR5
1122 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1123 END SUBROUTINE RADAU5
! AND ALL ITS INTERNAL PROCEDURES
1124 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1126 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1127 SUBROUTINE FUN_CHEM(T
, V
, FCT
)
1128 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1130 USE KPP_ROOT_Parameters
1132 USE KPP_ROOT_Function
, ONLY
: Fun
1133 USE KPP_ROOT_Rates
, ONLY
: Update_SUN
, Update_RCONST
, Update_PHOTO
1137 KPP_REAL
:: V(NVAR
), FCT(NVAR
)
1143 !CALL Update_RCONST()
1144 !CALL Update_PHOTO()
1147 CALL Fun(V
, FIX
, RCONST
, FCT
)
1151 END SUBROUTINE FUN_CHEM
1153 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1154 SUBROUTINE JAC_CHEM (T
, V
, JF
)
1155 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1157 USE KPP_ROOT_Parameters
1159 USE KPP_ROOT_JacobianSP
1160 USE KPP_ROOT_Jacobian
, ONLY
: Jac_SP
1161 USE KPP_ROOT_Rates
, ONLY
: Update_SUN
, Update_RCONST
, Update_PHOTO
1165 KPP_REAL
:: V(NVAR
), T
, Told
1167 KPP_REAL
:: JV(LU_NONZERO
), JF(NVAR
,NVAR
)
1170 KPP_REAL
:: JF(LU_NONZERO
)
1176 !CALL Update_RCONST()
1177 !CALL Update_PHOTO()
1181 CALL Jac_SP(V
, FIX
, RCONST
, JV
)
1188 JF(LU_IROW(i
),LU_ICOL(i
)) = JV(i
)
1191 CALL Jac_SP(V
, FIX
, RCONST
, JF
)
1196 END SUBROUTINE JAC_CHEM
1198 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1200 END MODULE KPP_ROOT_Integrator