1 SUBROUTINE INTEGRATE( TIN
, TOUT
)
12 EXTERNAL FUNC_CHEM
, JAC_CHEM
16 call ROS2(NVAR
,TIN
,TOUT
,STEPMIN
,STEPMAX
, &
17 STEPMIN
,VAR
,ATOL
,RTOL
, &
18 Info
,FUNC_CHEM
,JAC_CHEM
)
21 END SUBROUTINE INTEGRATE
26 SUBROUTINE ROS2(N
,T
,Tnext
,Hmin
,Hmax
,Hstart
, &
28 Info
,FUNC_CHEM
,JAC_CHEM
)
31 USE KPP_ROOT_Jacobian_sparsity
35 ! y = Vector of (NVAR) concentrations, contains the
36 ! initial values on input
37 ! [T, Tnext] = the integration interval
38 ! Hmin, Hmax = lower and upper bounds for the selected step-size.
39 ! Note that for Step = Hmin the current computed
40 ! solution is unconditionally accepted by the error
42 ! AbsTol, RelTol = (NVAR) dimensional vectors of
43 ! componentwise absolute and relative tolerances.
44 ! FUNC_CHEM = name of routine of derivatives. KPP syntax.
45 ! See the header below.
46 ! JAC_CHEM = name of routine that computes the Jacobian, in
47 ! sparse format. KPP syntax. See the header below.
48 ! Info(1) = 1 for autonomous system
49 ! = 0 for nonautonomous system
50 ! Info(2) = 1 for third order embedded formula
51 ! = 0 for first order embedded formula
53 ! Note: Stage 3 used to build strongly A-stable order 3 formula for error control
54 ! Embed3 = (Info(2).EQ.1)
55 ! if Embed3 = .true. then the third order embedded formula is used
56 ! .false. then a first order embedded formula is used
60 ! y = the values of concentrations at Tend.
61 ! T = equals Tend on output.
62 ! Info(2) = # of FUNC_CHEM calls.
63 ! Info(3) = # of JAC_CHEM calls.
64 ! Info(4) = # of accepted steps.
65 ! Info(5) = # of rejected steps.
67 KPP_REAL
K1(NVAR
), K2(NVAR
), K3(NVAR
)
68 KPP_REAL
F1(NVAR
), JAC(LU_NONZERO
)
70 KPP_REAL Hmin
,Hmax
,Hnew
,Hstart
,ghinv
,uround
71 KPP_REAL
y(NVAR
), ynew(NVAR
)
72 KPP_REAL
AbsTol(NVAR
), RelTol(NVAR
)
73 KPP_REAL T
, Tnext
, H
, Hold
, Tplus
74 KPP_REAL ERR
, factor
, facmax
75 KPP_REAL tau
, beta
, elo
, dround
, a21
, c31
, c32
76 KPP_REAL gamma3
, d1
, d2
, d3
, gam
77 INTEGER n
,nfcn
,njac
,Naccept
,Nreject
,i
,j
,ier
79 LOGICAL IsReject
, Autonomous
, Embed3
80 EXTERNAL FUNC_CHEM
, JAC_CHEM
82 KPP_REAL gamma
, m1
, m2
, alpha
, beta1
, beta2
, delta
, w
, e
84 ! Initialization of counters, etc.
85 Autonomous
= Info(1) .EQ
. 1
86 Embed3
= Info(2) .EQ
. 1
88 dround
= dsqrt(uround
)
89 H
= DMAX1(1.d
-8, Hmin
)
98 gamma
= 1.d0
+ 1.d0
/sqrt(2.d0
)
100 m1
= -3.d0
/(2.d0
*gamma
)
101 m2
= -1.d0
/(2.d0
*gamma
)
102 c31
= -1.0D0
/gamma
**2*(1.0D0
-7.0D0
*gamma
+9.0D0
*gamma
**2) &
103 /(-1.0D0
+2.0D0
*gamma
)
104 c32
= -1.0D0
/gamma
**2*(1.0D0
-6.0D0
*gamma
+6.0D0
*gamma
**2) &
105 /(-1.0D0
+2.0D0
*gamma
)/2
106 gamma3
= 0.5D0
- 2*gamma
107 d1
= ((-9.0D0
*gamma
+8.0D0
*gamma
**2+2.0D0
)/gamma
**2/ &
108 (-1.0D0
+2*gamma
))/6.0D0
109 d2
= ((-1.0D0
+3.0D0
*gamma
)/gamma
**2/(-1.0D0
+2.0D0
*gamma
))/6.0D0
110 d3
= -1.0D0
/(3.0D0
*gamma
)
112 ! === Starting the time loop ===
115 if ( Tplus
.gt
. Tnext
) then
120 call JAC_CHEM(NVAR
, T
, y
, JAC
)
123 ghinv
= -1.0d0/(gamma
*H
)
125 JAC(LU_DIAG(j
)) = JAC(LU_DIAG(j
)) + ghinv
127 CALL KppDecomp (JAC
, ier
)
134 print *,'IER <> 0, H=',H
139 call FUNC_CHEM(NVAR
, T
, y
, F1
)
141 ! ====== NONAUTONOMOUS CASE ===============
142 IF (.not
. Autonomous
) THEN
143 tau
= dsign(dround
*dmax1( 1.0d-6, dabs(T
) ), T
)
144 call FUNC_CHEM(NVAR
, T
+tau
, y
, K2
)
147 DFDT(j
) = ( K2(j
)-F1(j
) )/tau
149 END IF ! .NOT.Autonomous
151 ! ----- STAGE 1 -----
155 IF (.NOT
.Autonomous
) THEN
158 K1(j
) = K1(j
) + delta
*DFDT(j
)
160 END IF ! .NOT.Autonomous
161 call KppSolve (JAC
, K1
)
163 ! ----- STAGE 2 -----
165 ynew(j
) = y(j
) + a21
*K1(j
)
167 call FUNC_CHEM(NVAR
, T
+H
, ynew
, F1
)
169 beta
= 2.d0
/(gamma
*H
)
171 K2(j
) = F1(j
) + beta
*K1(j
)
173 IF (.NOT
. Autonomous
) THEN
176 K2(j
) = K2(j
) + delta
*DFDT(j
)
178 END IF ! .NOT.Autonomous
179 call KppSolve (JAC
, K2
)
181 ! ----- STAGE 3 -----
187 K3(j
) = F1(j
) + beta1
*K1(j
) + beta2
*K2(j
)
189 IF (.NOT
.Autonomous
) THEN
191 K3(j
) = K3(j
) + delta
*DFDT(j
)
193 END IF ! .NOT.Autonomous
194 CALL KppSolve (JAC
, K3
)
199 ! ---- The Solution ---
201 ynew(j
) = y(j
) + m1
*K1(j
) + m2
*K2(j
)
205 ! ====== Error estimation ========
209 w
= AbsTol(i
) + RelTol(i
)*DMAX1(DABS(y(i
)),DABS(ynew(i
)))
211 e
= d1
*K1(i
) + d2
*K2(i
) + d3
*K3(i
)
213 e
= 1.d0
/(2.d0
*gamma
)*(K1(i
)+K2(i
))
215 ERR
= ERR
+ ( e
/w
)**2
217 ERR
= DMAX1( uround
, DSQRT( ERR
/NVAR
) )
219 ! ======= Choose the stepsize ===============================
222 elo
= 3.0D0
! estimator local order
226 factor
= DMAX1(2.0D
-1,DMIN1(6.0D0
,ERR
**(1.0D0
/elo
)/.9D0
))
227 Hnew
= DMIN1(Hmax
,DMAX1(Hmin
, H
/factor
))
229 ! ======= Rejected/Accepted Step ============================
231 IF ( (ERR
.gt
.1).and
.(H
.gt
.Hmin
) ) THEN
240 IF (.NOT
. IsReject
) THEN
241 H
= Hnew
! Do not increase stepsize if previous step was rejected
248 ! ======= End of the time loop ===============================
249 IF ( T
.lt
. Tnext
) GO
TO 10
253 ! ======= Output Information =================================
263 SUBROUTINE FUNC_CHEM(N
, T
, Y
, P
)
267 KPP_REAL
Y(NVAR
), P(NVAR
)
272 CALL Fun( Y
, FIX
, RCONST
, P
)
274 END SUBROUTINE FUNC_CHEM
277 SUBROUTINE JAC_CHEM(N
, T
, Y
, J
)
281 KPP_REAL
Y(NVAR
), J(LU_NONZERO
)
286 CALL Jac_SP( Y
, FIX
, RCONST
, J
)
288 END SUBROUTINE JAC_CHEM