Merge remote-tracking branch 'origin/release-v4.6.1'
[WRF.git] / chem / KPP / kpp / kpp-2.1 / int / kpp_seulex.f90
blobff8e46fe23bf0c4be8b06789b2820fcbc278dd91
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
13 IMPLICIT NONE
14 PUBLIC
15 SAVE
17 ! variables from the former COMMON block /CONRA5/ are now here:
18 INTEGER :: NN, NN2, NN3, NN4
19 KPP_REAL :: TSOL, HSOL
21 ! Statistics
22 INTEGER :: Nfun,Njac,Nstp,Nacc,Nrej,Ndec,Nsol,Nsng
24 ! Method parameters
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
33 ' ', & ! 0 (not used)
34 'Success ' /) ! 1
36 CONTAINS
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
46 IMPLICIT NONE
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)
61 INTEGER :: IERR
62 INTEGER, SAVE :: Ntotal = 0
63 KPP_REAL, SAVE :: H
65 H = 0.0_dp
67 ICNTRL(1:20) = 0
68 RCNTRL(1:20) = 0._dp
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
95 ISTATUS_U(:) = 0
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
103 ENDIF
104 IF (PRESENT(RSTATUS_U)) THEN
105 RSTATUS_U(:) = 0.
106 RSTATUS_U(1) = TOUT ! final time
107 ENDIF
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,')'
114 !!$ STOP
115 !!$ ENDIF
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 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
146 ! INPUT PARAMETERS
147 ! ----------------
148 ! N DIMENSION OF THE SYSTEM
150 ! T INITIAL T-VALUE
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,
174 ! RPAR,IPAR,IRTRN)
175 ! KPP_REAL T,Y(N),RC(LRC),IC(LIC)
176 ! ....
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.
213 !~~~>
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
240 ! IS REQUIRED
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
254 ! (default=0.1)
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
261 ! should be smaller.
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 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
273 ! OUTPUT PARAMETERS
274 ! -----------------
275 ! T T-VALUE WHERE THE SOLUTION IS COMPUTED
276 ! (AFTER SUCCESSFUL RETURN T=Tend)
278 ! Y(N) SOLUTION AT T
280 ! H PREDICTED STEP SIZE OF THE LAST ACCEPTED STEP
282 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
283 ! DECLARATIONS
284 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
285 IMPLICIT NONE
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
293 LOGICAL :: AUTNMS
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 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
301 Nfun=0
302 Njac=0
303 Nstp=0
304 Nacc=0
305 Nrej=0
306 Ndec=0
307 Nsol=0
309 IERR = 0
311 IF (ICNTRL(1) == 0) THEN
312 AUTNMS = .FALSE.
313 ELSE
314 AUTNMS = .TRUE.
315 END IF
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
320 ITOL = 1
321 ELSE
322 ITOL = 0
323 END IF
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)
330 ELSE
331 PRINT * ,'User-selected ICNTRL(4)=',ICNTRL(4)
332 CALL SEULEX_ErrorMsg(-1,Tinitial,ZERO,IERR);
333 END IF
335 !~~~> IOUT = use (or not) the output routine
336 IOUT = ICNTRL(10)
337 IF ( IOUT<0 .OR. IOUT>2 ) THEN
338 PRINT * ,'User-selected ICNTRL(10)=',ICNTRL(10)
339 IOUT = 0
340 END IF
342 !~~~> Ncolumns: maximum number of columns in the extrapolation
343 IF (ICNTRL(11)==0) THEN
344 Ncolumns=12
345 ELSEIF (ICNTRL(11) > 2) THEN
346 Ncolumns=ICNTRL(11)
347 ELSE
348 PRINT * ,'User-selected ICNTRL(11)=',ICNTRL(11)
349 CALL SEULEX_ErrorMsg(-2,Tinitial,ZERO,IERR);
350 END IF
352 !~~~> Nsequence: choice of step size sequence
353 IF (ICNTRL(12)==0) THEN
354 Nsequence = 2
355 ELSEIF ( (ICNTRL(12)>0).AND.(ICNTRL(12)<5) ) THEN
356 Nsequence = ICNTRL(4)
357 ELSE
358 PRINT * ,'User-selected ICNTRL(12)=',ICNTRL(12)
359 CALL SEULEX_ErrorMsg(-3,Tinitial,ZERO,IERR)
360 END IF
362 !~~~> LAMBDA: parameter for dense output
363 LAMBDA = ICNTRL(13)
364 IF ( LAMBDA < 0 .OR. LAMBDA >= 2 ) THEN
365 PRINT * ,'User-selected ICNTRL(13)=',ICNTRL(13)
366 CALL SEULEX_ErrorMsg(-4,Tinitial,ZERO,IERR)
367 END IF
369 !~~~>- NRDENS: number of dense output components
370 NRDENS=ICNTRL(14)
371 IF ( (NRDENS < 0) .OR. (NRDENS > N) ) THEN
372 PRINT * ,'User-selected ICNTRL(14)=',ICNTRL(14)
373 CALL SEULEX_ErrorMsg(-5,Tinitial,ZERO,IERR)
374 END IF
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
382 Hmin = ZERO
383 ELSEIF (RCNTRL(1) > ZERO) THEN
384 Hmin = RCNTRL(1)
385 ELSE
386 PRINT * , 'User-selected RCNTRL(1)=', RCNTRL(1)
387 CALL SEULEX_ErrorMsg(-7,Tinitial,ZERO,IERR)
388 RETURN
389 END IF
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))
396 ELSE
397 PRINT * , 'User-selected RCNTRL(2)=', RCNTRL(2)
398 CALL SEULEX_ErrorMsg(-7,Tinitial,ZERO,IERR)
399 RETURN
400 END IF
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))
407 ELSE
408 PRINT * , 'User-selected Hstart: RCNTRL(3)=', RCNTRL(3)
409 CALL SEULEX_ErrorMsg(-7,Tinitial,ZERO,IERR)
410 RETURN
411 END IF
414 !~~~> Step size can be changed s.t. FacMin < Hnew/Hexit < FacMax
415 IF (RCNTRL(4) == ZERO) THEN
416 FacMin = 0.2_dp
417 ELSEIF (RCNTRL(4) > ZERO) THEN
418 FacMin = RCNTRL(4)
419 ELSE
420 PRINT * , 'User-selected FacMin: RCNTRL(4)=', RCNTRL(4)
421 CALL SEULEX_ErrorMsg(-8,Tinitial,ZERO,IERR)
422 RETURN
423 END IF
424 IF (RCNTRL(5) == ZERO) THEN
425 FacMax = 10.0_dp
426 ELSEIF (RCNTRL(5) > ZERO) THEN
427 FacMax = RCNTRL(5)
428 ELSE
429 PRINT * , 'User-selected FacMax: RCNTRL(5)=', RCNTRL(5)
430 CALL SEULEX_ErrorMsg(-8,Tinitial,ZERO,IERR)
431 RETURN
432 END IF
433 !~~~> FacRej: Factor to decrease step after 2 succesive rejections
434 IF (RCNTRL(6) == ZERO) THEN
435 FacRej = 0.1_dp
436 ELSEIF (RCNTRL(6) > ZERO) THEN
437 FacRej = RCNTRL(6)
438 ELSE
439 PRINT * , 'User-selected FacRej: RCNTRL(6)=', RCNTRL(6)
440 CALL SEULEX_ErrorMsg(-8,Tinitial,ZERO,IERR)
441 RETURN
442 END IF
443 !~~~> FacSafe: Safety Factor in the computation of new step size
444 IF (RCNTRL(7) == ZERO) THEN
445 FacSafe = 0.9_dp
446 ELSEIF (RCNTRL(7) > ZERO) THEN
447 FacSafe = RCNTRL(7)
448 ELSE
449 PRINT * , 'User-selected FacSafe: RCNTRL(7)=', RCNTRL(7)
450 CALL SEULEX_ErrorMsg(-8,Tinitial,ZERO,IERR)
451 RETURN
452 END IF
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
458 ThetaMin = 1.0d-3
459 ELSE
460 ThetaMin = RCNTRL(8)
461 END IF
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
469 FAC1=0.1D0
470 ELSE
471 FAC1=RCNTRL(10)
472 END IF
473 IF(RCNTRL(11) == 0.D0)THEN
474 FAC2=4.0D0
475 ELSE
476 FAC2=RCNTRL(11)
477 END IF
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
482 FAC3=0.7D0
483 ELSE
484 FAC3=RCNTRL(12)
485 END IF
486 IF(RCNTRL(13) == 0.D0)THEN
487 FAC4=0.9D0
488 ELSE
489 FAC4=RCNTRL(13)
490 END IF
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
494 FacSafe1=0.6D0
495 ELSE
496 FacSafe1=RCNTRL(14)
497 END IF
498 IF(RCNTRL(15) == 0.D0)THEN
499 FacSafe2=0.93D0
500 ELSE
501 FacSafe2=RCNTRL(15)
502 END IF
504 !~~~> WorkFcn: estimated computational work for a calls to FCN
505 IF(RCNTRL(16) == 0.D0)THEN
506 WorkFcn=1.D0
507 ELSE
508 WorkFcn=RCNTRL(16)
509 END IF
510 !~~~> WorkJac: estimated computational work for calls to JAC
511 IF(RCNTRL(17) == 0.D0)THEN
512 WorkJac=5.D0
513 ELSE
514 WorkJac=RCNTRL(17)
515 END IF
516 !~~~> WorkDec: estimated computational work for calls to DEC
517 IF(RCNTRL(18) == 0.D0)THEN
518 WorkDec=1.D0
519 ELSE
520 WorkDec=RCNTRL(18)
521 END IF
522 !~~~> WorkSol: estimated computational work for calls to SOL
523 IF(RCNTRL(19) == 0.D0)THEN
524 WorkSol=1.D0
525 ELSE
526 WorkSol=RCNTRL(19)
527 END IF
528 WorkRow=WorkFcn+WorkSol
530 !~~~> Check if tolerances are reasonable
531 IF (ITOL == 0) THEN
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)
536 END IF
537 ELSE
538 DO i=1,N
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)
543 END IF
544 END DO
545 END IF
547 IF (IERR < 0) RETURN
549 !~~~>---- PREPARE THE ENTRY-POINTS FOR THE ARRAYS IN WORK -----
550 Ncolumns2=(Ncolumns*(Ncolumns+1))/2
551 NRD=MAX(1,NRDENS)
553 T = Tinitial
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)
560 ISTATUS(1)=Nfun
561 ISTATUS(2)=Njac
562 ISTATUS(3)=Nstp
563 ISTATUS(4)=Nacc
564 ISTATUS(5)=Nrej
565 ISTATUS(6)=Ndec
566 ISTATUS(7)=Nsol
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
580 IERR = Code
581 PRINT * , &
582 'Forced exit from SEULEX due to the following error:'
584 SELECT CASE (Code)
585 CASE (-1)
586 PRINT * , '--> Improper value for maximal no of steps'
587 CASE (-2)
588 PRINT * , '--> Improper value for maximum no of columns in extrapolation'
589 CASE (-3)
590 PRINT * , '--> Improper value for step size sequence'
591 CASE (-4)
592 PRINT * , '--> Improper value for Lambda (must be 0/1)'
593 CASE (-5)
594 PRINT * , '--> Improper number of dense output components'
595 CASE (-6)
596 PRINT * , '--> Improper parameters for second order equations'
597 CASE (-7)
598 PRINT * , '--> Hmin/Hmax/Hstart must be positive'
599 CASE (-8)
600 PRINT * , '--> FacMin/FacMax/FacRej must be positive'
601 CASE (-9)
602 PRINT * , '--> Improper tolerance values'
603 CASE (-10)
604 PRINT * , '--> No of steps exceeds maximum bound'
605 CASE (-11)
606 PRINT * , '--> Step size too small: T + 10*H = T', &
607 ' or H < Roundoff'
608 CASE (-12)
609 PRINT * , '--> Matrix is repeatedly singular'
610 CASE DEFAULT
611 PRINT *, 'Unknown Error code: ', Code
612 END SELECT
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 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
627 ! DECLARATIONS
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,&
635 KOPT, NRD
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)
639 #ifdef FULL_ALGEBRA
640 KPP_REAL :: FJAC(NVAR,NVAR)
641 #else
642 KPP_REAL :: FJAC(LU_NONZERO)
643 #endif
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
654 IF (IOUT == 2) THEN
655 NNRD=NRD
656 !~~~> COMPUTE THE FACTORIALS --------
657 FACUL(1)=1.D0
658 DO i=1,Ncolumns-1
659 FACUL(i+1)=i*FACUL(i)
660 END DO
661 END IF
663 !~~~> DEFINE THE STEP SIZE SEQUENCE
664 IF (Nsequence == 1) THEN
665 NJ(1)=1
666 NJ(2)=2
667 NJ(3)=3
668 DO I=4,Ncolumns
669 NJ(i)=2*NJ(I-2)
670 END DO
671 END IF
672 IF (Nsequence == 2) THEN
673 NJ(1)=2
674 NJ(2)=3
675 DO I=3,Ncolumns
676 NJ(i)=2*NJ(I-2)
677 END DO
678 END IF
679 DO i=1,Ncolumns
680 IF (Nsequence == 3) NJ(i)=I
681 IF (Nsequence == 4) NJ(i)=I+1
682 END DO
683 A(1)=WorkJac+NJ(1)*WorkRow+WorkDec
684 DO I=2,Ncolumns
685 A(i)=A(i-1)+(NJ(i)-1)*WorkRow+WorkDec
686 END DO
687 K=MAX0(3,MIN0(Ncolumns-2,INT(-DLOG10(RelTol(1)+AbsTol(1))*.6D0+1.5D0)))
689 ! T = Tinitial
690 HmaxN = MIN(ABS(Hmax),ABS(Tend-T))
691 IF (ABS(H) <= 10.D0*Roundoff) H=1.0D-6
692 H=MIN(ABS(H),HmaxN)
693 Theta=2*ABS(ThetaMin)
694 ERR=0.D0
695 W(1)=1.D30
696 DO i=1,N
697 IF (ITOL == 0) THEN
698 SCAL(i)=AbsTol(1)+RelTol(1)*DABS(Y(i))
699 ELSE
700 SCAL(i)=AbsTol(i)+RelTol(i)*DABS(Y(i))
701 END IF
702 END DO
703 CALJAC=.FALSE.
704 REJECT=.FALSE.
705 LAST=.FALSE.
706 10 CONTINUE
707 IF (REJECT) Theta=2*ABS(ThetaMin)
708 ATOV=.FALSE.
709 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
710 !~~~> IS Tend REACHED IN THE NEXT STEP?
711 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
712 H1=Tend-T
713 IF (H1 <= Roundoff) GO TO 110
714 HOPT=H
715 H=MIN(H,H1,HmaxN)
716 IF (H >= H1-Roundoff) LAST=.TRUE.
717 IF (AUTNMS) THEN
718 CALL FUN_CHEM(T,Y,DY)
719 END IF
720 IF (Theta > ThetaMin.AND..NOT.CALJAC) THEN
721 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
722 ! COMPUTATION OF THE JACOBIAN
723 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
724 CALL JAC_CHEM(T,Y,FJAC)
725 CALJAC=.TRUE.
726 CALHES=.FALSE.
727 END IF
728 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
729 !~~~> THE FIRST AND LAST STEP
730 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
731 IF (Nstp == 0.OR.LAST) THEN
732 IPT=0
733 Nstp=Nstp+1
734 DO J=1,K
735 KC=J
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)
741 IF (ATOV) GOTO 10
742 IF (J > 1 .AND. ERR <= 1.d0) GOTO 60
743 END DO
744 GO TO 55
745 END IF
746 !~~~> BASIC INTEGRATION STEP
747 30 CONTINUE
748 IPT=0
749 Nstp=Nstp+1
750 IF (Nstp >= Max_no_steps) GOTO 120
751 KC=K-1
752 DO J=1,KC
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)
758 IF (ATOV) GOTO 10
759 END DO
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)
771 IF (ATOV) GOTO 10
772 KC=K
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
776 KC=K+1
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)
782 IF (ATOV) GOTO 10
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 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
788 60 TOLD=T
789 T=T+H
790 IF (IOUT == 2) THEN
791 KRIGHT=KC
792 DO i=1,NRD
793 DENS(i)=Y(ICOMP(i))
794 END DO
795 END IF
796 DO i=1,N
797 T1I=Table(1,I)
798 IF (ITOL == 0) THEN
799 SCAL(i)=AbsTol(1)+RelTol(1)*DABS(T1I)
800 ELSE
801 SCAL(i)=AbsTol(i)+RelTol(i)*DABS(T1I)
802 END IF
803 Y(i)=T1I
804 END DO
805 Nacc=Nacc+1
806 CALJAC=.FALSE.
807 IF (IOUT == 2) THEN
808 TOLDD=TOLD
809 HHH=H
810 DO i=1,NRD
811 DENS(NRD+I)=Y(ICOMP(i))
812 END DO
813 DO KLR=1,KRIGHT-1
814 !~~~> COMPUTE DIFFERENCES
815 IF (KLR >= 2) THEN
816 DO KK=KLR,KC
817 LBEG=((KK+1)*KK)/2
818 LEND=LBEG-KK+2
819 DO L=LBEG,LEND,-1
820 DO i=1,NRD
821 FSAFE(L,I)=FSAFE(L,I)-FSAFE(L-1,I)
822 END DO
823 END DO
824 END DO
825 END IF
826 !~~~> COMPUTE DERIVATIVES AT RIGHT END ----
827 DO KK=KLR+LAMBDA,KC
828 FACNJ=NJ(KK)
829 FACNJ=FACNJ**KLR/FACUL(KLR+1)
830 IPT=((KK+1)*KK)/2
831 DO I=1,NRD
832 KRN=(KK-LAMBDA+1)*NRD
833 DENS(KRN+I)=FSAFE(IPT,I)*FACNJ
834 END DO
835 END DO
836 DO J=KLR+LAMBDA+1,KC
837 DBLENJ=NJ(J)
838 DO L=J,KLR+LAMBDA+1,-1
839 FACTOR=DBLENJ/NJ(L-1)-1.D0
840 DO i=1,NRD
841 KRN=(L-LAMBDA+1)*NRD+I
842 DENS(KRN-NRD)=DENS(KRN)+(DENS(KRN)-DENS(KRN-NRD))/FACTOR
843 END DO
844 END DO
845 END DO
846 END DO
847 !~~~> COMPUTE THE COEFFICIENTS OF THE INTERPOLATION POLYNOMIAL
848 DO IN=1,NRD
849 DO J=1,KRIGHT
850 II=NRD*J+IN
851 DENS(II)=DENS(II)-DENS(II-NRD)
852 END DO
853 END DO
854 END IF
855 !~~~> COMPUTE OPTIMAL ORDER
856 IF (KC == 2) THEN
857 KOPT=3
858 IF (REJECT) KOPT=2
859 GO TO 80
860 END IF
861 IF (KC <= K) THEN
862 KOPT=KC
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)
865 ELSE
866 KOPT=KC-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)
869 END IF
870 !~~~> AFTER A REJECTED STEP
871 80 IF (REJECT) THEN
872 K=MIN0(KOPT,KC)
873 H=MIN(H,HH(K))
874 REJECT=.FALSE.
875 GO TO 10
876 END IF
877 !~~~> COMPUTE STEP SIZE FOR NEXT STEP
878 IF (KOPT <= KC) THEN
879 H=HH(KOPT)
880 ELSE
881 IF (KC < K.AND.W(KC) < W(KC-1)*FAC4) THEN
882 H=HH(KC)*A(KOPT+1)/A(KC)
883 ELSE
884 H=HH(KC)*A(KOPT)/A(KC)
885 END IF
886 END IF
887 K=KOPT
888 !Adi H = MAX(H, Hmin)
889 GO TO 10
890 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
891 !~~~> STEP IS REJECTED
892 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
893 100 K=MIN0(K,KC)
894 IF (K > 2.AND.W(K-1) < W(K)*FAC3) K=K-1
895 Nrej=Nrej+1
896 H=HH(K)
897 LAST=.FALSE.
898 REJECT=.TRUE.
899 IF (CALJAC) GOTO 30
900 GO TO 10
901 !~~~> SOLUTION EXIT
902 110 CONTINUE
903 H=HOPT
904 IERR=1
905 RETURN
906 !~~~> FAIL EXIT
907 120 WRITE (6,979) T,H
908 979 FORMAT(' EXIT OF SEULEX AT T=',D14.7,' H=',D14.7)
909 IERR=-1
910 RETURN
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, &
922 IPT,CALHES)
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)
934 #ifdef FULL_ALGEBRA
935 KPP_REAL :: FJAC(NVAR,NVAR), E(NVAR,NVAR)
936 #else
937 KPP_REAL :: FJAC(LU_NONZERO), E(LU_NONZERO)
938 #endif
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 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
947 HJ=H/NJ(JJ)
948 HJI=1.D0/HJ
949 #ifdef FULL_ALGEBRA
950 DO j=1,N
951 DO i=1,N
952 E(i,j)=-FJAC(i,j)
953 END DO
954 E(j,j)=E(j,j)+HJI
955 END DO
956 CALL DGETRF(N,N,E,N,IP,ISING)
957 #else
958 DO i=1,LU_NONZERO
959 E(i)=-FJAC(i)
960 END DO
961 DO j=1,N
962 E(LU_DIAG(j))=E(LU_DIAG(j))+HJI
963 END DO
964 CALL KppDecomp (E,ISING)
965 #endif
966 Ndec=Ndec+1
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)
973 END IF
974 DO i=1,N
975 YH(i)=Y(i)
976 DEL(i)=DY(i)
977 END DO
978 #ifdef FULL_ALGEBRA
979 CALL DGETRS ('N',N,1,E,N,IP,DEL,N,ISING)
980 #else
981 CALL KppSolve (E,DEL)
982 #endif
983 Nsol=Nsol+1
984 M=NJ(JJ)
985 IF (IOUT == 2.AND.M == JJ) THEN
986 IPT=IPT+1
987 DO i=1,NRD
988 FSAFE(IPT,I)=DEL(ICOMP(i))
989 END DO
990 END IF
991 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
992 !~~~> SEMI-IMPLICIT EULER METHOD
993 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
994 IF (M > 1) THEN
995 DO MM=1,M-1
996 DO i=1,N
997 YH(i)=YH(i)+DEL(i)
998 END DO
999 IF (AUTNMS) THEN
1000 CALL FUN_CHEM(T+HJ*MM,YH,DYH)
1001 ELSE
1002 CALL FUN_CHEM(T+HJ*(MM+1),YH,DYH)
1003 END IF
1005 IF (MM == 1.AND.JJ <= 2) THEN
1006 !~~~> STABILITY CHECK
1007 DEL1=0.D0
1008 DO i=1,N
1009 DEL1=DEL1+(DEL(i)/SCAL(i))**2
1010 END DO
1011 DEL1=SQRT(DEL1)
1012 IF (.NOT.AUTNMS) THEN
1013 CALL FUN_CHEM(T+HJ,YH,WH)
1015 DO i=1,N
1016 DEL(i)=WH(i)-DEL(i)*HJI
1017 END DO
1018 ELSE
1019 DO i=1,N
1020 DEL(i)=DYH(i)-DEL(i)*HJI
1021 END DO
1022 END IF
1023 #ifdef FULL_ALGEBRA
1024 CALL DGETRS ('N',N,1,E,N,IP,DEL,N,ISING)
1025 #else
1026 CALL KppSolve (E,DEL)
1027 #endif
1028 Nsol=Nsol+1
1029 DEL2=0.D0
1030 DO i=1,N
1031 DEL2=DEL2+(DEL(i)/SCAL(i))**2
1032 END DO
1033 DEL2=SQRT(DEL2)
1034 Theta=DEL2/MAX(1.D0,DEL1)
1035 IF (Theta > 1.D0) GOTO 79
1036 END IF
1037 #ifdef FULL_ALGEBRA
1038 CALL DGETRS ('N',N,1,E,N,IP,DYH,N,ISING)
1039 #else
1040 CALL KppSolve (E,DYH)
1041 #endif
1042 Nsol=Nsol+1
1043 DO i=1,N
1044 DEL(i)=DYH(i)
1045 END DO
1046 IF (IOUT == 2.AND.MM >= M-JJ) THEN
1047 IPT=IPT+1
1048 DO i=1,NRD
1049 FSAFE(IPT,i)=DEL(ICOMP(i))
1050 END DO
1051 END IF
1052 END DO
1053 END IF
1054 DO i=1,N
1055 Table(JJ,I)=YH(i)+DEL(i)
1056 END DO
1057 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1058 !~~~> POLYNOMIAL EXTRAPOLATION
1059 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1060 IF (JJ == 1) RETURN
1061 DO L=JJ,2,-1
1062 FAC=(DBLE(NJ(JJ))/DBLE(NJ(L-1)))-1.D0
1063 DO i=1,N
1064 Table(L-1,I)=Table(L,I)+(Table(L,I)-Table(L-1,I))/FAC
1065 END DO
1066 END DO
1067 ERR=0.D0
1068 DO i=1,N
1069 ERR=ERR+MIN(ABS((Table(1,I)-Table(2,I)))/SCAL(i),1.D15)**2
1070 END DO
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
1076 EXPO=1.D0/JJ
1077 FACMIN=FAC1**EXPO
1078 FAC=MIN(FAC2/FACMIN,MAX(FACMIN,(ERR/FacSafe1)**EXPO/FacSafe2))
1079 FAC=1.D0/FAC
1080 HH(JJ)=MIN(H*FAC,HmaxN)
1081 W(JJ)=A(JJ)/HH(JJ)
1082 RETURN
1083 79 ATOV=.TRUE.
1084 H=H*0.5D0
1085 REJECT=.TRUE.
1086 RETURN
1087 END SUBROUTINE SEUL
1091 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1092 SUBROUTINE FUN_CHEM( T, V, FCT )
1093 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1095 USE KPP_ROOT_Parameters
1096 USE KPP_ROOT_Global
1097 USE KPP_ROOT_Function, ONLY: Fun
1098 USE KPP_ROOT_Rates, ONLY: Update_SUN, Update_RCONST, Update_PHOTO
1100 IMPLICIT NONE
1102 KPP_REAL :: V(NVAR), FCT(NVAR)
1103 KPP_REAL :: T, TOLD
1105 !TOLD = TIME
1106 !TIME = T
1107 !CALL Update_SUN()
1108 !CALL Update_RCONST()
1109 !CALL Update_PHOTO()
1110 !TIME = TOLD
1111 CALL Fun(V, FIX, RCONST, FCT)
1112 Nfun=Nfun+1
1114 END SUBROUTINE FUN_CHEM
1117 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1118 SUBROUTINE JAC_CHEM ( T, V, Jcb )
1119 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1121 USE KPP_ROOT_Parameters
1122 USE KPP_ROOT_Global
1123 USE KPP_ROOT_Jacobian, ONLY: Jac_SP
1124 USE KPP_ROOT_Rates, ONLY: Update_SUN, Update_RCONST, Update_PHOTO
1126 IMPLICIT NONE
1128 KPP_REAL :: V(NVAR), T, TOLD
1129 #ifdef FULL_ALGEBRA
1130 KPP_REAL :: JV(LU_NONZERO), Jcb(NVAR,NVAR)
1131 INTEGER :: i,j
1132 #else
1133 KPP_REAL :: Jcb(LU_NONZERO)
1134 #endif
1136 !TOLD = TIME
1137 !TIME = T
1138 !CALL Update_SUN()
1139 !CALL Update_RCONST()
1140 !CALL Update_PHOTO()
1141 !TIME = TOLD
1143 #ifdef FULL_ALGEBRA
1144 CALL Jac_SP(V, FIX, RCONST, JV)
1145 DO j=1,NVAR
1146 DO i=1,NVAR
1147 Jcb(i,j) = 0.0D0
1148 END DO
1149 END DO
1150 DO i=1,LU_NONZERO
1151 Jcb(LU_IROW(i),LU_ICOL(i)) = JV(i)
1152 END DO
1153 #else
1154 CALL Jac_SP(V, FIX, RCONST, Jcb)
1155 #endif
1156 Njac=Njac+1
1158 END SUBROUTINE JAC_CHEM
1160 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1162 END MODULE KPP_ROOT_Integrator