[2696] | 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 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~! |
---|
| 6 | |
---|
| 7 | MODULE KPP_ROOT_Integrator |
---|
| 8 | |
---|
| 9 | USE KPP_ROOT_Precision, ONLY: dp |
---|
| 10 | USE KPP_ROOT_Parameters, ONLY: NVAR, LU_NONZERO |
---|
| 11 | USE KPP_ROOT_Jacobian, ONLY: LU_DIAG |
---|
| 12 | USE KPP_ROOT_LinearAlgebra |
---|
| 13 | |
---|
| 14 | IMPLICIT NONE |
---|
| 15 | PUBLIC |
---|
| 16 | SAVE |
---|
| 17 | |
---|
| 18 | ! variables from the former COMMON block /CONRA5/ are now here: |
---|
| 19 | INTEGER :: NN, NN2, NN3, NN4 |
---|
| 20 | KPP_REAL :: TSOL, HSOL |
---|
| 21 | |
---|
| 22 | ! Statistics |
---|
| 23 | INTEGER :: Nfun,Njac,Nstp,Nacc,Nrej,Ndec,Nsol,Nsng |
---|
| 24 | |
---|
| 25 | ! Method parameters |
---|
| 26 | |
---|
| 27 | ! mz_rs_20050717: TODO: use strings of IERR_NAMES for error messages |
---|
| 28 | ! description of the error numbers IERR |
---|
| 29 | CHARACTER(LEN=50), PARAMETER, DIMENSION(-4:1) :: IERR_NAMES = (/ & |
---|
| 30 | 'Matrix is repeatedly singular ', & ! -4 |
---|
| 31 | 'Step size too small ', & ! -3 |
---|
| 32 | 'More than Max_no_steps steps are needed ', & ! -2 |
---|
| 33 | 'Insufficient storage for work or iwork ', & ! -1 |
---|
| 34 | ' ', & ! 0 (not used) |
---|
| 35 | 'Success ' /) ! 1 |
---|
| 36 | |
---|
| 37 | CONTAINS |
---|
| 38 | |
---|
| 39 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 40 | SUBROUTINE INTEGRATE( TIN, TOUT, & |
---|
| 41 | ICNTRL_U, RCNTRL_U, ISTATUS_U, RSTATUS_U, IERR_U ) |
---|
| 42 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 43 | |
---|
| 44 | USE KPP_ROOT_Parameters, ONLY: nvar |
---|
| 45 | USE KPP_ROOT_Global, ONLY: atol,rtol,var |
---|
| 46 | |
---|
| 47 | IMPLICIT NONE |
---|
| 48 | |
---|
| 49 | KPP_REAL :: TIN ! TIN - Start Time |
---|
| 50 | KPP_REAL :: TOUT ! TOUT - End Time |
---|
| 51 | INTEGER, INTENT(IN), OPTIONAL :: ICNTRL_U(20) |
---|
| 52 | KPP_REAL, INTENT(IN), OPTIONAL :: RCNTRL_U(20) |
---|
| 53 | INTEGER, INTENT(OUT), OPTIONAL :: ISTATUS_U(20) |
---|
| 54 | KPP_REAL, INTENT(OUT), OPTIONAL :: RSTATUS_U(20) |
---|
| 55 | INTEGER, INTENT(OUT), OPTIONAL :: IERR_U |
---|
| 56 | |
---|
| 57 | INTEGER :: Ncolumns, Ncolumns2, NRDENS |
---|
| 58 | PARAMETER (Ncolumns=12,Ncolumns2=2+Ncolumns*(Ncolumns+3)/2,NRDENS=NVAR) |
---|
| 59 | |
---|
| 60 | KPP_REAL :: RCNTRL(20), RSTATUS(20) |
---|
| 61 | INTEGER :: ICNTRL(20), ISTATUS(20) |
---|
| 62 | INTEGER :: IERR |
---|
| 63 | INTEGER, SAVE :: Ntotal = 0 |
---|
| 64 | KPP_REAL, SAVE :: H |
---|
| 65 | |
---|
| 66 | H = 0.0_dp |
---|
| 67 | |
---|
| 68 | ICNTRL(1:20) = 0 |
---|
| 69 | RCNTRL(1:20) = 0._dp |
---|
| 70 | ICNTRL(10)=0 !~~~> OUTPUT ROUTINE IS NOT USED DURING INTEGRATION |
---|
| 71 | |
---|
| 72 | ! if optional parameters are given, and if they are >0, |
---|
| 73 | ! they overwrite the default settings |
---|
| 74 | IF (PRESENT(ICNTRL_U)) ICNTRL(:) = ICNTRL_U(:) |
---|
| 75 | IF (PRESENT(RCNTRL_U)) RCNTRL(:) = RCNTRL_U(:) |
---|
| 76 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~----- |
---|
| 77 | |
---|
| 78 | |
---|
| 79 | CALL ATMSEULEX(NVAR,TIN,TOUT,VAR,H,RTOL,ATOL, & |
---|
| 80 | RCNTRL,ICNTRL,RSTATUS,ISTATUS,IERR ) |
---|
| 81 | Ntotal = Ntotal + Nstp |
---|
| 82 | !!$ PRINT*,'NSTEPS=',Nstp,' (',Ntotal,') T=',TIN |
---|
| 83 | |
---|
| 84 | |
---|
| 85 | Nfun = Nfun + ISTATUS(1) |
---|
| 86 | Njac = Njac + ISTATUS(2) |
---|
| 87 | Nstp = Nstp + ISTATUS(3) |
---|
| 88 | Nacc = Nacc + ISTATUS(4) |
---|
| 89 | Nrej = Nrej + ISTATUS(5) |
---|
| 90 | Ndec = Ndec + ISTATUS(6) |
---|
| 91 | Nsol = Nsol + ISTATUS(7) |
---|
| 92 | |
---|
| 93 | ! if optional parameters are given for output |
---|
| 94 | ! use them to store information in them |
---|
| 95 | IF (PRESENT(ISTATUS_U)) THEN |
---|
| 96 | ISTATUS_U(:) = 0 |
---|
| 97 | ISTATUS_U(1) = Nfun ! function calls |
---|
| 98 | ISTATUS_U(2) = Njac ! jacobian calls |
---|
| 99 | ISTATUS_U(3) = Nstp ! steps |
---|
| 100 | ISTATUS_U(4) = Nacc ! accepted steps |
---|
| 101 | ISTATUS_U(5) = Nrej ! rejected steps (except at the beginning) |
---|
| 102 | ISTATUS_U(6) = Ndec ! LU decompositions |
---|
| 103 | ISTATUS_U(7) = Nsol ! forward/backward substitutions |
---|
| 104 | ENDIF |
---|
| 105 | IF (PRESENT(RSTATUS_U)) THEN |
---|
| 106 | RSTATUS_U(:) = 0. |
---|
| 107 | RSTATUS_U(1) = TOUT ! final time |
---|
| 108 | ENDIF |
---|
| 109 | IF (PRESENT(IERR_U)) IERR_U = IERR |
---|
| 110 | |
---|
| 111 | ! mz_rs_20050716: IERR is returned to the user who then decides what to do |
---|
| 112 | ! about it, i.e. either stop the run or ignore it. |
---|
| 113 | !!$ IF (IERR < 0) THEN |
---|
| 114 | !!$ PRINT *,'SEULEX: Unsuccessful exit at T=', TIN,' (IERR=',IERR,')' |
---|
| 115 | !!$ STOP |
---|
| 116 | !!$ ENDIF |
---|
| 117 | |
---|
| 118 | END SUBROUTINE INTEGRATE |
---|
| 119 | |
---|
| 120 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 121 | SUBROUTINE ATMSEULEX( N,Tinitial,Tfinal,Y,H,RelTol,AbsTol, & |
---|
| 122 | RCNTRL,ICNTRL,RSTATUS,ISTATUS,IERR ) |
---|
| 123 | |
---|
| 124 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 125 | ! NUMERICAL SOLUTION OF A STIFF (OR DIFFERENTIAL ALGEBRAIC) |
---|
| 126 | ! SYSTEM OF FIRST 0RDER ORDINARY DIFFERENTIAL EQUATIONS MY'=F(T,Y). |
---|
| 127 | ! THIS IS AN EXTRAPOLATION-ALGORITHM, BASED ON THE |
---|
| 128 | ! LINEARLY IMPLICIT EULER METHOD (WITH STEP SIZE CONTROL |
---|
| 129 | ! AND ORDER SELECTION). |
---|
| 130 | ! |
---|
| 131 | ! AUTHORS: E. HAIRER AND G. WANNER |
---|
| 132 | ! UNIVERSITE DE GENEVE, DEPT. DE MATHEMATIQUES |
---|
| 133 | ! CH-1211 GENEVE 24, SWITZERLAND |
---|
| 134 | ! E-MAIL: HAIRER@DIVSUN.UNIGE.CH, WANNER@DIVSUN.UNIGE.CH |
---|
| 135 | ! INCLUSION OF DENSE OUTPUT BY E. HAIRER AND A. OSTERMANN |
---|
| 136 | ! |
---|
| 137 | ! THIS CODE IS PART OF THE BOOK: |
---|
| 138 | ! E. HAIRER AND G. WANNER, SOLVING ORDINARY DIFFERENTIAL |
---|
| 139 | ! EQUATIONS II. STIFF AND DIFFERENTIAL-ALGEBRAIC PROBLEMS. |
---|
| 140 | ! SPRINGER SERIES IN COMPUTATIONAL MATHEMATICS 14, |
---|
| 141 | ! SPRINGER-VERLAG (1991) |
---|
| 142 | ! |
---|
| 143 | ! VERSION OF SEPTEMBER 30, 1995 |
---|
| 144 | ! |
---|
| 145 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 146 | ! |
---|
| 147 | ! INPUT PARAMETERS |
---|
| 148 | ! ---------------- |
---|
| 149 | ! N DIMENSION OF THE SYSTEM |
---|
| 150 | ! |
---|
| 151 | ! T INITIAL T-VALUE |
---|
| 152 | ! |
---|
| 153 | ! Y(N) INITIAL VALUES FOR Y |
---|
| 154 | ! |
---|
| 155 | ! Tend FINAL T-VALUE (Tend-T MAY BE POSITIVE OR NEGATIVE) |
---|
| 156 | ! |
---|
| 157 | ! H INITIAL STEP SIZE GUESS; |
---|
| 158 | ! FOR STIFF EQUATIONS WITH INITIAL TRANSIENT, |
---|
| 159 | ! H=1.D0/(NORM OF F'), USUALLY 1.D-2 OR 1.D-3, IS GOOD. |
---|
| 160 | ! THIS CHOICE IS NOT VERY IMPORTANT, THE CODE QUICKLY |
---|
| 161 | ! ADAPTS ITS STEP SIZE (IF H=0.D0, THE CODE PUTS H=1.D-6 |
---|
| 162 | ! |
---|
| 163 | ! RelTol,AbsTol RELATIVE AND ABSOLUTE ERROR TOLERANCES. THEY |
---|
| 164 | ! CAN BE BOTH SCALARS OR ELSE BOTH VECTORS OF LENGTH N. |
---|
| 165 | ! |
---|
| 166 | ! JAC NAME (EXTERNAL) OF THE SUBROUTINE WHICH COMPUTES |
---|
| 167 | ! THE PARTIAL DERIVATIVES OF F(T,Y) WITH RESPECT TO Y |
---|
| 168 | ! |
---|
| 169 | ! SOLOUT NAME (EXTERNAL) OF SUBROUTINE PROVIDING THE |
---|
| 170 | ! NUMERICAL SOLUTION DURING INTEGRATION. |
---|
| 171 | ! IF IOUT>=1, IT IS CALLED AFTER EVERY SUCCESSFUL STEP. |
---|
| 172 | ! SUPPLY A DUMMY SUBROUTINE IF IOUT=0. |
---|
| 173 | ! IT MUST HAVE THE FORM |
---|
| 174 | ! SUBROUTINE SOLOUT (NR,TOLD,T,Y,RC,LRC,IC,LIC,N, |
---|
| 175 | ! RPAR,IPAR,IRTRN) |
---|
| 176 | ! KPP_REAL T,Y(N),RC(LRC),IC(LIC) |
---|
| 177 | ! .... |
---|
| 178 | ! SOLOUT FURNISHES THE SOLUTION "Y" AT THE NR-TH |
---|
| 179 | ! GRID-POINT "T" (THEREBY THE INITIAL VALUE IS |
---|
| 180 | ! THE FIRST GRID-POINT). |
---|
| 181 | ! "TOLD" IS THE PRECEEDING GRID-POINT. |
---|
| 182 | ! "IRTRN" SERVES TO INTERRUPT THE INTEGRATION. IF IRTRN |
---|
| 183 | ! IS SET <0, SEULEX RETURNS TO THE CALLING PROGRAM. |
---|
| 184 | ! DO NOT CHANGE THE ENTRIES OF RC(LRC),IC(LIC)! |
---|
| 185 | ! |
---|
| 186 | ! ----- CONTINUOUS OUTPUT (IF IOUT=2): ----- |
---|
| 187 | ! DURING CALLS TO "SOLOUT", A CONTINUOUS SOLUTION |
---|
| 188 | ! FOR THE INTERVAL [TOLD,T] IS AVAILABLE THROUGH |
---|
| 189 | ! THE KPP_REAL FUNCTION |
---|
| 190 | ! >>> CONTEX(I,S,RC,LRC,IC,LIC) <<< |
---|
| 191 | ! WHICH PROVIDES AN APPROXIMATION TO THE I-TH |
---|
| 192 | ! COMPONENT OF THE SOLUTION AT THE POINT S. THE VALUE |
---|
| 193 | ! S SHOULD LIE IN THE INTERVAL [TOLD,T]. |
---|
| 194 | ! |
---|
| 195 | ! IOUT GIVES INFORMATION ON THE SUBROUTINE SOLOUT: |
---|
| 196 | ! IOUT=0: SUBROUTINE IS NEVER CALLED |
---|
| 197 | ! IOUT=1: SUBROUTINE IS USED FOR OUTPUT |
---|
| 198 | ! IOUT=2: DENSE OUTPUT IS PERFORMED IN SOLOUT |
---|
| 199 | ! |
---|
| 200 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 201 | ! |
---|
| 202 | ! SOPHISTICATED SETTING OF PARAMETERS |
---|
| 203 | ! ----------------------------------- |
---|
| 204 | ! SEVERAL PARAMETERS OF THE CODE ARE TUNED TO MAKE IT CNTRL |
---|
| 205 | ! WELL. THEY MAY BE DEFINED BY SETTING CNTRL(1),..,CNTRL(13) |
---|
| 206 | ! AS WELL AS ICNTRL(1),..,ICNTRL(4) DIFFERENT FROM ZERO. |
---|
| 207 | ! FOR ZERO INPUT, THE CODE CHOOSES DEFAULT VALUES: |
---|
| 208 | ! |
---|
| 209 | ! |
---|
| 210 | !~~~> INPUT PARAMETERS: |
---|
| 211 | ! |
---|
| 212 | ! Note: For input parameters equal to zero the default values of the |
---|
| 213 | ! corresponding variables are used. |
---|
| 214 | !~~~> |
---|
| 215 | ! ICNTRL(1) = 1: F = F(y) Independent of T (autonomous) |
---|
| 216 | ! = 0: F = F(t,y) Depends on T (non-autonomous) |
---|
| 217 | ! |
---|
| 218 | ! ICNTRL(2) = 0: AbsTol, RelTol are NVAR-dimensional vectors |
---|
| 219 | ! = 1: AbsTol, RelTol are scalars |
---|
| 220 | ! |
---|
| 221 | ! ICNTRL(3) -> not used |
---|
| 222 | ! |
---|
| 223 | ! ICNTRL(4) -> maximum number of integration steps |
---|
| 224 | ! For ICNTRL(4)=0 the default value of 100000 is used |
---|
| 225 | ! |
---|
| 226 | ! ICNTRL(11) THE MAXIMUM NUMBER OF COLUMNS IN THE EXTRAPOLATION |
---|
| 227 | ! TABLE. THE DEFAULT VALUE (FOR ICNTRL(3)=0) IS 12. |
---|
| 228 | ! IF ICNTRL(3).NE.0 THEN ICNTRL(3) SHOULD BE >= 3. |
---|
| 229 | ! |
---|
| 230 | ! ICNTRL(12) SWITCH FOR THE STEP SIZE SEQUENCE |
---|
| 231 | ! IF ICNTRL(4) == 1 THEN 1,2,3,4,6,8,12,16,24,32,48,... |
---|
| 232 | ! IF ICNTRL(4) == 2 THEN 2,3,4,6,8,12,16,24,32,48,64,... |
---|
| 233 | ! IF ICNTRL(4) == 3 THEN 1,2,3,4,5,6,7,8,9,10,... |
---|
| 234 | ! IF ICNTRL(4) == 4 THEN 2,3,4,5,6,7,8,9,10,11,... |
---|
| 235 | ! THE DEFAULT VALUE (FOR ICNTRL(4)=0) IS ICNTRL(4)=2. |
---|
| 236 | ! |
---|
| 237 | ! ICNTRL(13) PARAMETER "LAMBDA" OF DENSE OUTPUT; POSSIBLE VALUES |
---|
| 238 | ! ARE 0 AND 1; DEFAULT ICNTRL(5)=0. |
---|
| 239 | ! |
---|
| 240 | ! ICNTRL(14) = NRDENS = NUMBER OF COMPONENTS, FOR WHICH DENSE OUTPUT |
---|
| 241 | ! IS REQUIRED |
---|
| 242 | ! |
---|
| 243 | ! ICNTRL(21),...,ICNTRL(NRDENS+20) INDICATE THE COMPONENTS, FOR WHICH |
---|
| 244 | ! DENSE OUTPUT IS REQUIRED |
---|
| 245 | ! |
---|
| 246 | !~~~> Real parameters |
---|
| 247 | ! |
---|
| 248 | ! RCNTRL(1) -> Hmin, lower bound for the integration step size |
---|
| 249 | ! It is strongly recommended to keep Hmin = ZERO |
---|
| 250 | ! RCNTRL(2) -> Hmax, upper bound for the integration step size |
---|
| 251 | ! RCNTRL(3) -> Hstart, starting value for the integration step size |
---|
| 252 | ! RCNTRL(4) -> FacMin, lower bound on step decrease factor (default=0.2) |
---|
| 253 | ! RCNTRL(5) -> FacMax, upper bound on step increase factor (default=6) |
---|
| 254 | ! RCNTRL(6) -> FacRej, step decrease factor after multiple rejections |
---|
| 255 | ! (default=0.1) |
---|
| 256 | ! RCNTRL(7) -> FacSafe, by which the new step is slightly smaller |
---|
| 257 | ! than the predicted value (default=0.9) |
---|
| 258 | ! RCNTRL(8) -> ThetaMin. If Newton convergence rate smaller |
---|
| 259 | ! than ThetaMin the Jacobian is not recomputed; |
---|
| 260 | ! (default=0.001). Increase cntrl(3), to 0.01 say, when |
---|
| 261 | ! Jacobian evaluations are costly. for small systems it |
---|
| 262 | ! should be smaller. |
---|
| 263 | ! RCNTRL(9) -> not used |
---|
| 264 | ! RCNTRL(10,11) -> FAC1,FAC2 (parameters for step size selection) |
---|
| 265 | ! RCNTRL(12,13) -> FAC3,FAC4 (parameters for order selection) |
---|
| 266 | ! RCNTRL(14,15) -> FacSafe1, FacSafe2 |
---|
| 267 | ! Safety factors for step size prediction |
---|
| 268 | ! HNEW=H*FacSafe2*(FacSafe1*TOL/ERR)**(1/(J-1)) |
---|
| 269 | ! RCNTRL(16:19) -> WorkFcn, WorkJac, WorkDec, WorkSol |
---|
| 270 | ! estimated computational work |
---|
| 271 | ! |
---|
| 272 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 273 | ! |
---|
| 274 | ! OUTPUT PARAMETERS |
---|
| 275 | ! ----------------- |
---|
| 276 | ! T T-VALUE WHERE THE SOLUTION IS COMPUTED |
---|
| 277 | ! (AFTER SUCCESSFUL RETURN T=Tend) |
---|
| 278 | ! |
---|
| 279 | ! Y(N) SOLUTION AT T |
---|
| 280 | ! |
---|
| 281 | ! H PREDICTED STEP SIZE OF THE LAST ACCEPTED STEP |
---|
| 282 | ! |
---|
| 283 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 284 | ! DECLARATIONS |
---|
| 285 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 286 | IMPLICIT NONE |
---|
| 287 | INTEGER :: N, IERR, ITOL, Max_no_steps, Ncolumns, Nsequence, Lambda, & |
---|
| 288 | NRDENS, i, Ncolumns2, NRD, IOUT |
---|
| 289 | KPP_REAL :: Y(NVAR),AbsTol(*),RelTol(*) |
---|
| 290 | KPP_REAL :: Tinitial, Tfinal, Roundoff, Hmin, Hmax, & |
---|
| 291 | FacMin, FacMax, FAC1, FAC2, FAC3, FAC4, FacSafe1, & |
---|
| 292 | FacSafe2, H, Hstart,WorkFcn,WorkJac, WorkDec, WorkSol,& |
---|
| 293 | WorkRow, FacRej, FacSafe, ThetaMin, T |
---|
| 294 | LOGICAL :: AUTNMS |
---|
| 295 | KPP_REAL :: RCNTRL(20), RSTATUS(20) |
---|
| 296 | INTEGER :: ICNTRL(20), ISTATUS(20) |
---|
| 297 | KPP_REAL, PARAMETER :: ZERO = 0.0d0 |
---|
| 298 | |
---|
| 299 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 300 | ! SETTING THE PARAMETERS |
---|
| 301 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 302 | Nfun=0 |
---|
| 303 | Njac=0 |
---|
| 304 | Nstp=0 |
---|
| 305 | Nacc=0 |
---|
| 306 | Nrej=0 |
---|
| 307 | Ndec=0 |
---|
| 308 | Nsol=0 |
---|
| 309 | |
---|
| 310 | IERR = 0 |
---|
| 311 | |
---|
| 312 | IF (ICNTRL(1) == 0) THEN |
---|
| 313 | AUTNMS = .FALSE. |
---|
| 314 | ELSE |
---|
| 315 | AUTNMS = .TRUE. |
---|
| 316 | END IF |
---|
| 317 | |
---|
| 318 | !~~~> For Scalar tolerances (ICNTRL(1)/=0) the code uses AbsTol(1) and RelTol(1) |
---|
| 319 | !~~~> For Vector tolerances (ICNTRL(1)==0) the code uses AbsTol(1:NVAR) and RelTol(1:NVAR) |
---|
| 320 | IF (ICNTRL(2) == 0) THEN |
---|
| 321 | ITOL = 1 |
---|
| 322 | ELSE |
---|
| 323 | ITOL = 0 |
---|
| 324 | END IF |
---|
| 325 | |
---|
| 326 | !~~~> Max_no_steps: the maximum number of time steps admitted |
---|
| 327 | IF (ICNTRL(4) == 0) THEN |
---|
| 328 | Max_no_steps = 100000 |
---|
| 329 | ELSEIF (ICNTRL(4) > 0) THEN |
---|
| 330 | Max_no_steps=ICNTRL(4) |
---|
| 331 | ELSE |
---|
| 332 | PRINT * ,'User-selected ICNTRL(4)=',ICNTRL(4) |
---|
| 333 | CALL SEULEX_ErrorMsg(-1,Tinitial,ZERO,IERR); |
---|
| 334 | END IF |
---|
| 335 | |
---|
| 336 | !~~~> IOUT = use (or not) the output routine |
---|
| 337 | IOUT = ICNTRL(10) |
---|
| 338 | IF ( IOUT<0 .OR. IOUT>2 ) THEN |
---|
| 339 | PRINT * ,'User-selected ICNTRL(10)=',ICNTRL(10) |
---|
| 340 | IOUT = 0 |
---|
| 341 | END IF |
---|
| 342 | |
---|
| 343 | !~~~> Ncolumns: maximum number of columns in the extrapolation |
---|
| 344 | IF (ICNTRL(11)==0) THEN |
---|
| 345 | Ncolumns=12 |
---|
| 346 | ELSEIF (ICNTRL(11) > 2) THEN |
---|
| 347 | Ncolumns=ICNTRL(11) |
---|
| 348 | ELSE |
---|
| 349 | PRINT * ,'User-selected ICNTRL(11)=',ICNTRL(11) |
---|
| 350 | CALL SEULEX_ErrorMsg(-2,Tinitial,ZERO,IERR); |
---|
| 351 | END IF |
---|
| 352 | |
---|
| 353 | !~~~> Nsequence: choice of step size sequence |
---|
| 354 | IF (ICNTRL(12)==0) THEN |
---|
| 355 | Nsequence = 2 |
---|
| 356 | ELSEIF ( (ICNTRL(12)>0).AND.(ICNTRL(12)<5) ) THEN |
---|
| 357 | Nsequence = ICNTRL(4) |
---|
| 358 | ELSE |
---|
| 359 | PRINT * ,'User-selected ICNTRL(12)=',ICNTRL(12) |
---|
| 360 | CALL SEULEX_ErrorMsg(-3,Tinitial,ZERO,IERR) |
---|
| 361 | END IF |
---|
| 362 | |
---|
| 363 | !~~~> LAMBDA: parameter for dense output |
---|
| 364 | LAMBDA = ICNTRL(13) |
---|
| 365 | IF ( LAMBDA < 0 .OR. LAMBDA >= 2 ) THEN |
---|
| 366 | PRINT * ,'User-selected ICNTRL(13)=',ICNTRL(13) |
---|
| 367 | CALL SEULEX_ErrorMsg(-4,Tinitial,ZERO,IERR) |
---|
| 368 | END IF |
---|
| 369 | |
---|
| 370 | !~~~>- NRDENS: number of dense output components |
---|
| 371 | NRDENS=ICNTRL(14) |
---|
| 372 | IF ( (NRDENS < 0) .OR. (NRDENS > N) ) THEN |
---|
| 373 | PRINT * ,'User-selected ICNTRL(14)=',ICNTRL(14) |
---|
| 374 | CALL SEULEX_ErrorMsg(-5,Tinitial,ZERO,IERR) |
---|
| 375 | END IF |
---|
| 376 | |
---|
| 377 | |
---|
| 378 | !~~~> Unit roundoff (1+Roundoff>1) |
---|
| 379 | Roundoff = WLAMCH('E') |
---|
| 380 | |
---|
| 381 | !~~~> Lower bound on the step size: (positive value) |
---|
| 382 | IF (RCNTRL(1) == ZERO) THEN |
---|
| 383 | Hmin = ZERO |
---|
| 384 | ELSEIF (RCNTRL(1) > ZERO) THEN |
---|
| 385 | Hmin = RCNTRL(1) |
---|
| 386 | ELSE |
---|
| 387 | PRINT * , 'User-selected RCNTRL(1)=', RCNTRL(1) |
---|
| 388 | CALL SEULEX_ErrorMsg(-7,Tinitial,ZERO,IERR) |
---|
| 389 | RETURN |
---|
| 390 | END IF |
---|
| 391 | |
---|
| 392 | !~~~> Upper bound on the step size: (positive value) |
---|
| 393 | IF (RCNTRL(2) == ZERO) THEN |
---|
| 394 | Hmax = ABS(Tfinal-Tinitial) |
---|
| 395 | ELSEIF (RCNTRL(2) > ZERO) THEN |
---|
| 396 | Hmax = MIN(ABS(RCNTRL(2)),ABS(Tfinal-Tinitial)) |
---|
| 397 | ELSE |
---|
| 398 | PRINT * , 'User-selected RCNTRL(2)=', RCNTRL(2) |
---|
| 399 | CALL SEULEX_ErrorMsg(-7,Tinitial,ZERO,IERR) |
---|
| 400 | RETURN |
---|
| 401 | END IF |
---|
| 402 | |
---|
| 403 | !~~~> Starting step size: (positive value) |
---|
| 404 | IF (RCNTRL(3) == ZERO) THEN |
---|
| 405 | Hstart = MAX(Hmin,Roundoff) |
---|
| 406 | ELSEIF (RCNTRL(3) > ZERO) THEN |
---|
| 407 | Hstart = MIN(ABS(RCNTRL(3)),ABS(Tfinal-Tinitial)) |
---|
| 408 | ELSE |
---|
| 409 | PRINT * , 'User-selected Hstart: RCNTRL(3)=', RCNTRL(3) |
---|
| 410 | CALL SEULEX_ErrorMsg(-7,Tinitial,ZERO,IERR) |
---|
| 411 | RETURN |
---|
| 412 | END IF |
---|
| 413 | |
---|
| 414 | |
---|
| 415 | !~~~> Step size can be changed s.t. FacMin < Hnew/Hexit < FacMax |
---|
| 416 | IF (RCNTRL(4) == ZERO) THEN |
---|
| 417 | FacMin = 0.2_dp |
---|
| 418 | ELSEIF (RCNTRL(4) > ZERO) THEN |
---|
| 419 | FacMin = RCNTRL(4) |
---|
| 420 | ELSE |
---|
| 421 | PRINT * , 'User-selected FacMin: RCNTRL(4)=', RCNTRL(4) |
---|
| 422 | CALL SEULEX_ErrorMsg(-8,Tinitial,ZERO,IERR) |
---|
| 423 | RETURN |
---|
| 424 | END IF |
---|
| 425 | IF (RCNTRL(5) == ZERO) THEN |
---|
| 426 | FacMax = 10.0_dp |
---|
| 427 | ELSEIF (RCNTRL(5) > ZERO) THEN |
---|
| 428 | FacMax = RCNTRL(5) |
---|
| 429 | ELSE |
---|
| 430 | PRINT * , 'User-selected FacMax: RCNTRL(5)=', RCNTRL(5) |
---|
| 431 | CALL SEULEX_ErrorMsg(-8,Tinitial,ZERO,IERR) |
---|
| 432 | RETURN |
---|
| 433 | END IF |
---|
| 434 | !~~~> FacRej: Factor to decrease step after 2 succesive rejections |
---|
| 435 | IF (RCNTRL(6) == ZERO) THEN |
---|
| 436 | FacRej = 0.1_dp |
---|
| 437 | ELSEIF (RCNTRL(6) > ZERO) THEN |
---|
| 438 | FacRej = RCNTRL(6) |
---|
| 439 | ELSE |
---|
| 440 | PRINT * , 'User-selected FacRej: RCNTRL(6)=', RCNTRL(6) |
---|
| 441 | CALL SEULEX_ErrorMsg(-8,Tinitial,ZERO,IERR) |
---|
| 442 | RETURN |
---|
| 443 | END IF |
---|
| 444 | !~~~> FacSafe: Safety Factor in the computation of new step size |
---|
| 445 | IF (RCNTRL(7) == ZERO) THEN |
---|
| 446 | FacSafe = 0.9_dp |
---|
| 447 | ELSEIF (RCNTRL(7) > ZERO) THEN |
---|
| 448 | FacSafe = RCNTRL(7) |
---|
| 449 | ELSE |
---|
| 450 | PRINT * , 'User-selected FacSafe: RCNTRL(7)=', RCNTRL(7) |
---|
| 451 | CALL SEULEX_ErrorMsg(-8,Tinitial,ZERO,IERR) |
---|
| 452 | RETURN |
---|
| 453 | END IF |
---|
| 454 | |
---|
| 455 | !~~~> ThetaMin: DECIDES WHETHER THE JACOBIAN SHOULD BE RECOMPUTED; |
---|
| 456 | ! INCREASE WORK(3), TO 0.01 SAY, WHEN JACOBIAN EVALUATIONS |
---|
| 457 | ! ARE COSTLY. FOR SMALL SYSTEMS WORK(3) SHOULD BE SMALLER. |
---|
| 458 | IF(RCNTRL(8) == 0.D0)THEN |
---|
| 459 | ThetaMin = 1.0d-3 |
---|
| 460 | ELSE |
---|
| 461 | ThetaMin = RCNTRL(8) |
---|
| 462 | END IF |
---|
| 463 | |
---|
| 464 | !~~~> FAC1,FAC2: PARAMETERS FOR STEP SIZE SELECTION |
---|
| 465 | ! THE NEW STEP SIZE FOR THE J-TH DIAGONAL ENTRY IS |
---|
| 466 | ! CHOSEN SUBJECT TO THE RESTRICTION |
---|
| 467 | ! FACMIN/WORK(5) <= HNEW(J)/HOLD <= 1/FACMIN |
---|
| 468 | ! WHERE FACMIN=WORK(4)**(1/(J-1)) |
---|
| 469 | IF(RCNTRL(10) == 0.D0)THEN |
---|
| 470 | FAC1=0.1D0 |
---|
| 471 | ELSE |
---|
| 472 | FAC1=RCNTRL(10) |
---|
| 473 | END IF |
---|
| 474 | IF(RCNTRL(11) == 0.D0)THEN |
---|
| 475 | FAC2=4.0D0 |
---|
| 476 | ELSE |
---|
| 477 | FAC2=RCNTRL(11) |
---|
| 478 | END IF |
---|
| 479 | !~~~> FAC3, FAC4: PARAMETERS FOR THE ORDER SELECTION |
---|
| 480 | ! ORDER IS DECREASED IF W(K-1) <= W(K)*WORK(6) |
---|
| 481 | ! ORDER IS INCREASED IF W(K) <= W(K-1)*WORK(7) |
---|
| 482 | IF(RCNTRL(12) == 0.D0)THEN |
---|
| 483 | FAC3=0.7D0 |
---|
| 484 | ELSE |
---|
| 485 | FAC3=RCNTRL(12) |
---|
| 486 | END IF |
---|
| 487 | IF(RCNTRL(13) == 0.D0)THEN |
---|
| 488 | FAC4=0.9D0 |
---|
| 489 | ELSE |
---|
| 490 | FAC4=RCNTRL(13) |
---|
| 491 | END IF |
---|
| 492 | !~~~>- FacSafe1, FacSafe2: safety factors for step size prediction |
---|
| 493 | ! HNEW=H*WORK(9)*(WORK(8)*TOL/ERR)**(1/(J-1)) |
---|
| 494 | IF(RCNTRL(14) == 0.D0)THEN |
---|
| 495 | FacSafe1=0.6D0 |
---|
| 496 | ELSE |
---|
| 497 | FacSafe1=RCNTRL(14) |
---|
| 498 | END IF |
---|
| 499 | IF(RCNTRL(15) == 0.D0)THEN |
---|
| 500 | FacSafe2=0.93D0 |
---|
| 501 | ELSE |
---|
| 502 | FacSafe2=RCNTRL(15) |
---|
| 503 | END IF |
---|
| 504 | |
---|
| 505 | !~~~> WorkFcn: estimated computational work for a calls to FCN |
---|
| 506 | IF(RCNTRL(16) == 0.D0)THEN |
---|
| 507 | WorkFcn=1.D0 |
---|
| 508 | ELSE |
---|
| 509 | WorkFcn=RCNTRL(16) |
---|
| 510 | END IF |
---|
| 511 | !~~~> WorkJac: estimated computational work for calls to JAC |
---|
| 512 | IF(RCNTRL(17) == 0.D0)THEN |
---|
| 513 | WorkJac=5.D0 |
---|
| 514 | ELSE |
---|
| 515 | WorkJac=RCNTRL(17) |
---|
| 516 | END IF |
---|
| 517 | !~~~> WorkDec: estimated computational work for calls to DEC |
---|
| 518 | IF(RCNTRL(18) == 0.D0)THEN |
---|
| 519 | WorkDec=1.D0 |
---|
| 520 | ELSE |
---|
| 521 | WorkDec=RCNTRL(18) |
---|
| 522 | END IF |
---|
| 523 | !~~~> WorkSol: estimated computational work for calls to SOL |
---|
| 524 | IF(RCNTRL(19) == 0.D0)THEN |
---|
| 525 | WorkSol=1.D0 |
---|
| 526 | ELSE |
---|
| 527 | WorkSol=RCNTRL(19) |
---|
| 528 | END IF |
---|
| 529 | WorkRow=WorkFcn+WorkSol |
---|
| 530 | |
---|
| 531 | !~~~> Check if tolerances are reasonable |
---|
| 532 | IF (ITOL == 0) THEN |
---|
| 533 | IF (AbsTol(1) <= 0.D0.OR.RelTol(1) <= 10.D0*Roundoff) THEN |
---|
| 534 | PRINT * , ' Scalar AbsTol = ',AbsTol(1) |
---|
| 535 | PRINT * , ' Scalar RelTol = ',RelTol(1) |
---|
| 536 | CALL SEULEX_ErrorMsg(-9,Tinitial,ZERO,IERR) |
---|
| 537 | END IF |
---|
| 538 | ELSE |
---|
| 539 | DO i=1,N |
---|
| 540 | IF (AbsTol(i) <= 0.D0.OR.RelTol(i) <= 10.D0*Roundoff) THEN |
---|
| 541 | PRINT * , ' AbsTol(',i,') = ',AbsTol(i) |
---|
| 542 | PRINT * , ' RelTol(',i,') = ',RelTol(i) |
---|
| 543 | CALL SEULEX_ErrorMsg(-9,Tinitial,ZERO,IERR) |
---|
| 544 | END IF |
---|
| 545 | END DO |
---|
| 546 | END IF |
---|
| 547 | |
---|
| 548 | IF (IERR < 0) RETURN |
---|
| 549 | |
---|
| 550 | !~~~>---- PREPARE THE ENTRY-POINTS FOR THE ARRAYS IN WORK ----- |
---|
| 551 | Ncolumns2=(Ncolumns*(Ncolumns+1))/2 |
---|
| 552 | NRD=MAX(1,NRDENS) |
---|
| 553 | |
---|
| 554 | T = Tinitial |
---|
| 555 | !~~~> CALL TO CORE INTEGRATOR |
---|
| 556 | CALL SEULEX_Integrator(N,T,Tfinal,Y,Hmax,H,Ncolumns,RelTol,AbsTol,ITOL, & |
---|
| 557 | IOUT,IERR,Max_no_steps,Roundoff,Nsequence,AUTNMS, & |
---|
| 558 | FAC1,FAC2,FAC3,FAC4,ThetaMin,FacSafe1,FacSafe2,WorkJac, & |
---|
| 559 | WorkDec,WorkRow,Ncolumns2,NRD,LAMBDA,Nstp) |
---|
| 560 | |
---|
| 561 | ISTATUS(1)=Nfun |
---|
| 562 | ISTATUS(2)=Njac |
---|
| 563 | ISTATUS(3)=Nstp |
---|
| 564 | ISTATUS(4)=Nacc |
---|
| 565 | ISTATUS(5)=Nrej |
---|
| 566 | ISTATUS(6)=Ndec |
---|
| 567 | ISTATUS(7)=Nsol |
---|
| 568 | |
---|
| 569 | END SUBROUTINE ATMSEULEX |
---|
| 570 | |
---|
| 571 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 572 | SUBROUTINE SEULEX_ErrorMsg(Code,T,H,IERR) |
---|
| 573 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 574 | ! Handles all error messages |
---|
| 575 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 576 | |
---|
| 577 | KPP_REAL, INTENT(IN) :: T, H |
---|
| 578 | INTEGER, INTENT(IN) :: Code |
---|
| 579 | INTEGER, INTENT(OUT) :: IERR |
---|
| 580 | |
---|
| 581 | IERR = Code |
---|
| 582 | PRINT * , & |
---|
| 583 | 'Forced exit from SEULEX due to the following error:' |
---|
| 584 | |
---|
| 585 | SELECT CASE (Code) |
---|
| 586 | CASE (-1) |
---|
| 587 | PRINT * , '--> Improper value for maximal no of steps' |
---|
| 588 | CASE (-2) |
---|
| 589 | PRINT * , '--> Improper value for maximum no of columns in extrapolation' |
---|
| 590 | CASE (-3) |
---|
| 591 | PRINT * , '--> Improper value for step size sequence' |
---|
| 592 | CASE (-4) |
---|
| 593 | PRINT * , '--> Improper value for Lambda (must be 0/1)' |
---|
| 594 | CASE (-5) |
---|
| 595 | PRINT * , '--> Improper number of dense output components' |
---|
| 596 | CASE (-6) |
---|
| 597 | PRINT * , '--> Improper parameters for second order equations' |
---|
| 598 | CASE (-7) |
---|
| 599 | PRINT * , '--> Hmin/Hmax/Hstart must be positive' |
---|
| 600 | CASE (-8) |
---|
| 601 | PRINT * , '--> FacMin/FacMax/FacRej must be positive' |
---|
| 602 | CASE (-9) |
---|
| 603 | PRINT * , '--> Improper tolerance values' |
---|
| 604 | CASE (-10) |
---|
| 605 | PRINT * , '--> No of steps exceeds maximum bound' |
---|
| 606 | CASE (-11) |
---|
| 607 | PRINT * , '--> Step size too small: T + 10*H = T', & |
---|
| 608 | ' or H < Roundoff' |
---|
| 609 | CASE (-12) |
---|
| 610 | PRINT * , '--> Matrix is repeatedly singular' |
---|
| 611 | CASE DEFAULT |
---|
| 612 | PRINT *, 'Unknown Error code: ', Code |
---|
| 613 | END SELECT |
---|
| 614 | |
---|
| 615 | PRINT *, "T=", T, "and H=", H |
---|
| 616 | |
---|
| 617 | END SUBROUTINE SEULEX_ErrorMsg |
---|
| 618 | |
---|
| 619 | |
---|
| 620 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 621 | SUBROUTINE SEULEX_Integrator(N,T,Tend,Y,Hmax,H,Ncolumns,RelTol,AbsTol,ITOL,& |
---|
| 622 | IOUT,IERR,Max_no_steps,Roundoff,Nsequence,AUTNMS, & |
---|
| 623 | FAC1,FAC2,FAC3,FAC4,ThetaMin,FacSafe1,FacSafe2,WorkJac, & |
---|
| 624 | WorkDec,WorkRow,Ncolumns2,NRD,LAMBDA,Nstp) |
---|
| 625 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 626 | ! CORE INTEGRATOR FOR SEULEX |
---|
| 627 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 628 | ! DECLARATIONS |
---|
| 629 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 630 | USE KPP_ROOT_Parameters |
---|
| 631 | USE KPP_ROOT_Jacobian |
---|
| 632 | IMPLICIT KPP_REAL (A-H,O-Z) |
---|
| 633 | IMPLICIT INTEGER (I-N) |
---|
| 634 | |
---|
| 635 | INTEGER :: N, Ncolumns, Ncolumns2, K, KC, KRIGHT, KLR, KK, KRN,& |
---|
| 636 | KOPT, NRD |
---|
| 637 | KPP_REAL :: Y(NVAR),DY(NVAR),FX(NVAR),YHH(NVAR) |
---|
| 638 | KPP_REAL :: DYH(NVAR), DEL(NVAR), WH(NVAR) |
---|
| 639 | KPP_REAL :: SCAL(NVAR), HH(Ncolumns), W(Ncolumns), A(Ncolumns) |
---|
| 640 | #ifdef FULL_ALGEBRA |
---|
| 641 | KPP_REAL :: FJAC(NVAR,NVAR) |
---|
| 642 | #else |
---|
| 643 | KPP_REAL :: FJAC(LU_NONZERO) |
---|
| 644 | #endif |
---|
| 645 | KPP_REAL Table(Ncolumns,N) |
---|
| 646 | INTEGER IP(N),NJ(Ncolumns),IPHES(N),ICOMP(NRD) |
---|
| 647 | KPP_REAL RelTol(*),AbsTol(*) |
---|
| 648 | KPP_REAL FSAFE(Ncolumns2,NRD),FACUL(Ncolumns),E(N,N),DENS((Ncolumns+2)*NRD) |
---|
| 649 | LOGICAL REJECT,LAST,ATOV,CALJAC,CALHES,AUTNMS |
---|
| 650 | |
---|
| 651 | KPP_REAL TOLDD,HHH,NNRD |
---|
| 652 | COMMON /COSEU/TOLDD,HHH,NNRD,KRIGHT |
---|
| 653 | |
---|
| 654 | !~~~> COMPUTE COEFFICIENTS FOR DENSE OUTPUT |
---|
| 655 | IF (IOUT == 2) THEN |
---|
| 656 | NNRD=NRD |
---|
| 657 | !~~~> COMPUTE THE FACTORIALS -------- |
---|
| 658 | FACUL(1)=1.D0 |
---|
| 659 | DO i=1,Ncolumns-1 |
---|
| 660 | FACUL(i+1)=i*FACUL(i) |
---|
| 661 | END DO |
---|
| 662 | END IF |
---|
| 663 | |
---|
| 664 | !~~~> DEFINE THE STEP SIZE SEQUENCE |
---|
| 665 | IF (Nsequence == 1) THEN |
---|
| 666 | NJ(1)=1 |
---|
| 667 | NJ(2)=2 |
---|
| 668 | NJ(3)=3 |
---|
| 669 | DO I=4,Ncolumns |
---|
| 670 | NJ(i)=2*NJ(I-2) |
---|
| 671 | END DO |
---|
| 672 | END IF |
---|
| 673 | IF (Nsequence == 2) THEN |
---|
| 674 | NJ(1)=2 |
---|
| 675 | NJ(2)=3 |
---|
| 676 | DO I=3,Ncolumns |
---|
| 677 | NJ(i)=2*NJ(I-2) |
---|
| 678 | END DO |
---|
| 679 | END IF |
---|
| 680 | DO i=1,Ncolumns |
---|
| 681 | IF (Nsequence == 3) NJ(i)=I |
---|
| 682 | IF (Nsequence == 4) NJ(i)=I+1 |
---|
| 683 | END DO |
---|
| 684 | A(1)=WorkJac+NJ(1)*WorkRow+WorkDec |
---|
| 685 | DO I=2,Ncolumns |
---|
| 686 | A(i)=A(i-1)+(NJ(i)-1)*WorkRow+WorkDec |
---|
| 687 | END DO |
---|
| 688 | K=MAX0(3,MIN0(Ncolumns-2,INT(-DLOG10(RelTol(1)+AbsTol(1))*.6D0+1.5D0))) |
---|
| 689 | |
---|
| 690 | ! T = Tinitial |
---|
| 691 | HmaxN = MIN(ABS(Hmax),ABS(Tend-T)) |
---|
| 692 | IF (ABS(H) <= 10.D0*Roundoff) H=1.0D-6 |
---|
| 693 | H=MIN(ABS(H),HmaxN) |
---|
| 694 | Theta=2*ABS(ThetaMin) |
---|
| 695 | ERR=0.D0 |
---|
| 696 | W(1)=1.D30 |
---|
| 697 | DO i=1,N |
---|
| 698 | IF (ITOL == 0) THEN |
---|
| 699 | SCAL(i)=AbsTol(1)+RelTol(1)*DABS(Y(i)) |
---|
| 700 | ELSE |
---|
| 701 | SCAL(i)=AbsTol(i)+RelTol(i)*DABS(Y(i)) |
---|
| 702 | END IF |
---|
| 703 | END DO |
---|
| 704 | CALJAC=.FALSE. |
---|
| 705 | REJECT=.FALSE. |
---|
| 706 | LAST=.FALSE. |
---|
| 707 | 10 CONTINUE |
---|
| 708 | IF (REJECT) Theta=2*ABS(ThetaMin) |
---|
| 709 | ATOV=.FALSE. |
---|
| 710 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 711 | !~~~> IS Tend REACHED IN THE NEXT STEP? |
---|
| 712 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 713 | H1=Tend-T |
---|
| 714 | IF (H1 <= Roundoff) GO TO 110 |
---|
| 715 | HOPT=H |
---|
| 716 | H=MIN(H,H1,HmaxN) |
---|
| 717 | IF (H >= H1-Roundoff) LAST=.TRUE. |
---|
| 718 | IF (AUTNMS) THEN |
---|
| 719 | CALL FUN_CHEM(T,Y,DY) |
---|
| 720 | END IF |
---|
| 721 | IF (Theta > ThetaMin.AND..NOT.CALJAC) THEN |
---|
| 722 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 723 | ! COMPUTATION OF THE JACOBIAN |
---|
| 724 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 725 | CALL JAC_CHEM(T,Y,FJAC) |
---|
| 726 | CALJAC=.TRUE. |
---|
| 727 | CALHES=.FALSE. |
---|
| 728 | END IF |
---|
| 729 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 730 | !~~~> THE FIRST AND LAST STEP |
---|
| 731 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 732 | IF (Nstp == 0.OR.LAST) THEN |
---|
| 733 | IPT=0 |
---|
| 734 | Nstp=Nstp+1 |
---|
| 735 | DO J=1,K |
---|
| 736 | KC=J |
---|
| 737 | CALL SEUL(J,N,T,Y,DY,FX,FJAC,LFJAC,E,LE,IP,H,Ncolumns, & |
---|
| 738 | HmaxN,Table,SCAL,NJ,HH,W,A,YHH,DYH,DEL,WH,ERR,FacSafe1,FAC, & |
---|
| 739 | FAC1,FAC2,FacSafe2,Theta,Nfun,Ndec,Nsol, & |
---|
| 740 | ERROLD,IPHES,ICOMP,AUTNMS,REJECT, & |
---|
| 741 | ATOV,FSAFE,Ncolumns2,NRD,IOUT,IPT,CALHES) |
---|
| 742 | IF (ATOV) GOTO 10 |
---|
| 743 | IF (J > 1 .AND. ERR <= 1.d0) GOTO 60 |
---|
| 744 | END DO |
---|
| 745 | GO TO 55 |
---|
| 746 | END IF |
---|
| 747 | !~~~> BASIC INTEGRATION STEP |
---|
| 748 | 30 CONTINUE |
---|
| 749 | IPT=0 |
---|
| 750 | Nstp=Nstp+1 |
---|
| 751 | IF (Nstp >= Max_no_steps) GOTO 120 |
---|
| 752 | KC=K-1 |
---|
| 753 | DO J=1,KC |
---|
| 754 | CALL SEUL(J,N,T,Y,DY,FX,FJAC,LFJAC,E,LE,IP,H,Ncolumns,& |
---|
| 755 | HmaxN,Table,SCAL,NJ,HH,W,A,YHH,DYH,DEL,WH,ERR,FacSafe1,& |
---|
| 756 | FAC,FAC1,FAC2,FacSafe2,Theta,Nfun,Ndec,Nsol,& |
---|
| 757 | ERROLD,IPHES,ICOMP,AUTNMS,REJECT,& |
---|
| 758 | ATOV,FSAFE,Ncolumns2,NRD,IOUT,IPT,CALHES) |
---|
| 759 | IF (ATOV) GOTO 10 |
---|
| 760 | END DO |
---|
| 761 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 762 | !~~~> CONVERGENCE MONITOR |
---|
| 763 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 764 | IF (K == 2.OR.REJECT) GO TO 50 |
---|
| 765 | IF (ERR <= 1.D0) GO TO 60 |
---|
| 766 | IF (ERR > DBLE(NJ(K+1)*NJ(K))*4.D0) GO TO 100 |
---|
| 767 | 50 CALL SEUL(K,N,T,Y,DY,FX,FJAC,LFJAC,E,LE,IP,H,Ncolumns,& |
---|
| 768 | HmaxN,Table,SCAL,NJ,HH,W,A,YHH,DYH,DEL,WH,ERR,FacSafe1,& |
---|
| 769 | FAC,FAC1,FAC2,FacSafe2,Theta,Nfun,Ndec,Nsol,& |
---|
| 770 | ERROLD,IPHES,ICOMP,AUTNMS,REJECT,& |
---|
| 771 | ATOV,FSAFE,Ncolumns2,NRD,IOUT,IPT,CALHES) |
---|
| 772 | IF (ATOV) GOTO 10 |
---|
| 773 | KC=K |
---|
| 774 | IF (ERR <= 1.D0) GO TO 60 |
---|
| 775 | !~~~> HOPE FOR CONVERGENCE IN LINE K+1 |
---|
| 776 | 55 IF (ERR > DBLE(NJ(K+1))*2.D0) GO TO 100 |
---|
| 777 | KC=K+1 |
---|
| 778 | CALL SEUL(KC,N,T,Y,DY,FX,FJAC,LFJAC,E,LE,IP,H,Ncolumns,& |
---|
| 779 | HmaxN,Table,SCAL,NJ,HH,W,A,YHH,DYH,DEL,WH,ERR,FacSafe1,& |
---|
| 780 | FAC,FAC1,FAC2,FacSafe2,Theta,Nfun,Ndec,Nsol,& |
---|
| 781 | ERROLD,IPHES,ICOMP,AUTNMS,REJECT,& |
---|
| 782 | ATOV,FSAFE,Ncolumns2,NRD,IOUT,IPT,CALHES) |
---|
| 783 | IF (ATOV) GOTO 10 |
---|
| 784 | IF (ERR > 1.D0) GO TO 100 |
---|
| 785 | !Adi IF ((ERR > 1.D0).and.(H.gt.Hmin)) GO TO 100 |
---|
| 786 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 787 | !~~~> STEP IS ACCEPTED |
---|
| 788 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 789 | 60 TOLD=T |
---|
| 790 | T=T+H |
---|
| 791 | IF (IOUT == 2) THEN |
---|
| 792 | KRIGHT=KC |
---|
| 793 | DO i=1,NRD |
---|
| 794 | DENS(i)=Y(ICOMP(i)) |
---|
| 795 | END DO |
---|
| 796 | END IF |
---|
| 797 | DO i=1,N |
---|
| 798 | T1I=Table(1,I) |
---|
| 799 | IF (ITOL == 0) THEN |
---|
| 800 | SCAL(i)=AbsTol(1)+RelTol(1)*DABS(T1I) |
---|
| 801 | ELSE |
---|
| 802 | SCAL(i)=AbsTol(i)+RelTol(i)*DABS(T1I) |
---|
| 803 | END IF |
---|
| 804 | Y(i)=T1I |
---|
| 805 | END DO |
---|
| 806 | Nacc=Nacc+1 |
---|
| 807 | CALJAC=.FALSE. |
---|
| 808 | IF (IOUT == 2) THEN |
---|
| 809 | TOLDD=TOLD |
---|
| 810 | HHH=H |
---|
| 811 | DO i=1,NRD |
---|
| 812 | DENS(NRD+I)=Y(ICOMP(i)) |
---|
| 813 | END DO |
---|
| 814 | DO KLR=1,KRIGHT-1 |
---|
| 815 | !~~~> COMPUTE DIFFERENCES |
---|
| 816 | IF (KLR >= 2) THEN |
---|
| 817 | DO KK=KLR,KC |
---|
| 818 | LBEG=((KK+1)*KK)/2 |
---|
| 819 | LEND=LBEG-KK+2 |
---|
| 820 | DO L=LBEG,LEND,-1 |
---|
| 821 | DO i=1,NRD |
---|
| 822 | FSAFE(L,I)=FSAFE(L,I)-FSAFE(L-1,I) |
---|
| 823 | END DO |
---|
| 824 | END DO |
---|
| 825 | END DO |
---|
| 826 | END IF |
---|
| 827 | !~~~> COMPUTE DERIVATIVES AT RIGHT END ---- |
---|
| 828 | DO KK=KLR+LAMBDA,KC |
---|
| 829 | FACNJ=NJ(KK) |
---|
| 830 | FACNJ=FACNJ**KLR/FACUL(KLR+1) |
---|
| 831 | IPT=((KK+1)*KK)/2 |
---|
| 832 | DO I=1,NRD |
---|
| 833 | KRN=(KK-LAMBDA+1)*NRD |
---|
| 834 | DENS(KRN+I)=FSAFE(IPT,I)*FACNJ |
---|
| 835 | END DO |
---|
| 836 | END DO |
---|
| 837 | DO J=KLR+LAMBDA+1,KC |
---|
| 838 | DBLENJ=NJ(J) |
---|
| 839 | DO L=J,KLR+LAMBDA+1,-1 |
---|
| 840 | FACTOR=DBLENJ/NJ(L-1)-1.D0 |
---|
| 841 | DO i=1,NRD |
---|
| 842 | KRN=(L-LAMBDA+1)*NRD+I |
---|
| 843 | DENS(KRN-NRD)=DENS(KRN)+(DENS(KRN)-DENS(KRN-NRD))/FACTOR |
---|
| 844 | END DO |
---|
| 845 | END DO |
---|
| 846 | END DO |
---|
| 847 | END DO |
---|
| 848 | !~~~> COMPUTE THE COEFFICIENTS OF THE INTERPOLATION POLYNOMIAL |
---|
| 849 | DO IN=1,NRD |
---|
| 850 | DO J=1,KRIGHT |
---|
| 851 | II=NRD*J+IN |
---|
| 852 | DENS(II)=DENS(II)-DENS(II-NRD) |
---|
| 853 | END DO |
---|
| 854 | END DO |
---|
| 855 | END IF |
---|
| 856 | !~~~> COMPUTE OPTIMAL ORDER |
---|
| 857 | IF (KC == 2) THEN |
---|
| 858 | KOPT=3 |
---|
| 859 | IF (REJECT) KOPT=2 |
---|
| 860 | GO TO 80 |
---|
| 861 | END IF |
---|
| 862 | IF (KC <= K) THEN |
---|
| 863 | KOPT=KC |
---|
| 864 | IF (W(KC-1) < W(KC)*FAC3) KOPT=KC-1 |
---|
| 865 | IF (W(KC) < W(KC-1)*FAC4) KOPT=MIN0(KC+1,Ncolumns-1) |
---|
| 866 | ELSE |
---|
| 867 | KOPT=KC-1 |
---|
| 868 | IF (KC > 3.AND.W(KC-2) < W(KC-1)*FAC3) KOPT=KC-2 |
---|
| 869 | IF (W(KC) < W(KOPT)*FAC4) KOPT=MIN0(KC,Ncolumns-1) |
---|
| 870 | END IF |
---|
| 871 | !~~~> AFTER A REJECTED STEP |
---|
| 872 | 80 IF (REJECT) THEN |
---|
| 873 | K=MIN0(KOPT,KC) |
---|
| 874 | H=MIN(H,HH(K)) |
---|
| 875 | REJECT=.FALSE. |
---|
| 876 | GO TO 10 |
---|
| 877 | END IF |
---|
| 878 | !~~~> COMPUTE STEP SIZE FOR NEXT STEP |
---|
| 879 | IF (KOPT <= KC) THEN |
---|
| 880 | H=HH(KOPT) |
---|
| 881 | ELSE |
---|
| 882 | IF (KC < K.AND.W(KC) < W(KC-1)*FAC4) THEN |
---|
| 883 | H=HH(KC)*A(KOPT+1)/A(KC) |
---|
| 884 | ELSE |
---|
| 885 | H=HH(KC)*A(KOPT)/A(KC) |
---|
| 886 | END IF |
---|
| 887 | END IF |
---|
| 888 | K=KOPT |
---|
| 889 | !Adi H = MAX(H, Hmin) |
---|
| 890 | GO TO 10 |
---|
| 891 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 892 | !~~~> STEP IS REJECTED |
---|
| 893 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 894 | 100 K=MIN0(K,KC) |
---|
| 895 | IF (K > 2.AND.W(K-1) < W(K)*FAC3) K=K-1 |
---|
| 896 | Nrej=Nrej+1 |
---|
| 897 | H=HH(K) |
---|
| 898 | LAST=.FALSE. |
---|
| 899 | REJECT=.TRUE. |
---|
| 900 | IF (CALJAC) GOTO 30 |
---|
| 901 | GO TO 10 |
---|
| 902 | !~~~> SOLUTION EXIT |
---|
| 903 | 110 CONTINUE |
---|
| 904 | H=HOPT |
---|
| 905 | IERR=1 |
---|
| 906 | RETURN |
---|
| 907 | !~~~> FAIL EXIT |
---|
| 908 | 120 WRITE (6,979) T,H |
---|
| 909 | 979 FORMAT(' EXIT OF SEULEX AT T=',D14.7,' H=',D14.7) |
---|
| 910 | IERR=-1 |
---|
| 911 | RETURN |
---|
| 912 | |
---|
| 913 | |
---|
| 914 | END SUBROUTINE SEULEX_Integrator |
---|
| 915 | |
---|
| 916 | |
---|
| 917 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 918 | SUBROUTINE SEUL(JJ,N,T,Y,DY,FX,FJAC,LFJAC,E,LE,IP,& |
---|
| 919 | H,Ncolumns,HmaxN,Table,SCAL,NJ,HH,W,A,YH,DYH,DEL,WH,ERR,FacSafe1, & |
---|
| 920 | FAC,FAC1,FAC2,FacSafe2,Theta,Nfun,Ndec,Nsol,& |
---|
| 921 | ERROLD,IPHES,ICOMP, & |
---|
| 922 | AUTNMS,REJECT,ATOV,FSAFE,Ncolumns2,NRD,IOUT, & |
---|
| 923 | IPT,CALHES) |
---|
| 924 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 925 | !~~~> THIS SUBROUTINE COMPUTES THE J-TH LINE OF THE |
---|
| 926 | !~~~> EXTRAPOLATION TABLE AND PROVIDES AN ESTIMATE |
---|
| 927 | !~~~> OF THE OPTIMAL STEP SIZE |
---|
| 928 | USE KPP_ROOT_Parameters |
---|
| 929 | USE KPP_ROOT_Jacobian |
---|
| 930 | IMPLICIT KPP_REAL (A-H,O-Z) |
---|
| 931 | IMPLICIT INTEGER (I-N) |
---|
| 932 | INTEGER :: Ncolumns, Ncolumns2, N, NRD |
---|
| 933 | KPP_REAL :: Y(NVAR),YH(NVAR),DY(NVAR),FX(NVAR),DYH(NVAR) |
---|
| 934 | KPP_REAL :: DEL(NVAR),WH(NVAR),SCAL(NVAR),HH(Ncolumns),W(Ncolumns),A(Ncolumns) |
---|
| 935 | #ifdef FULL_ALGEBRA |
---|
| 936 | KPP_REAL :: FJAC(NVAR,NVAR), E(NVAR,NVAR) |
---|
| 937 | #else |
---|
| 938 | KPP_REAL :: FJAC(LU_NONZERO), E(LU_NONZERO) |
---|
| 939 | #endif |
---|
| 940 | KPP_REAL :: Table(Ncolumns,NVAR) |
---|
| 941 | KPP_REAL :: FSAFE(Ncolumns2,NRD) |
---|
| 942 | INTEGER :: IP(N),NJ(Ncolumns),IPHES(N),ICOMP(NRD) |
---|
| 943 | LOGICAL ATOV,REJECT,AUTNMS,CALHES |
---|
| 944 | |
---|
| 945 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 946 | ! COMPUTE THE MATRIX E AND ITS DECOMPOSITION |
---|
| 947 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 948 | HJ=H/NJ(JJ) |
---|
| 949 | HJI=1.D0/HJ |
---|
| 950 | #ifdef FULL_ALGEBRA |
---|
| 951 | DO j=1,N |
---|
| 952 | DO i=1,N |
---|
| 953 | E(i,j)=-FJAC(i,j) |
---|
| 954 | END DO |
---|
| 955 | E(j,j)=E(j,j)+HJI |
---|
| 956 | END DO |
---|
| 957 | CALL DGETRF(N,N,E,N,IP,ISING) |
---|
| 958 | #else |
---|
| 959 | DO i=1,LU_NONZERO |
---|
| 960 | E(i)=-FJAC(i) |
---|
| 961 | END DO |
---|
| 962 | DO j=1,N |
---|
| 963 | E(LU_DIAG(j))=E(LU_DIAG(j))+HJI |
---|
| 964 | END DO |
---|
| 965 | CALL KppDecomp (E,ISING) |
---|
| 966 | #endif |
---|
| 967 | Ndec=Ndec+1 |
---|
| 968 | IF (ISING.NE.0) GOTO 79 |
---|
| 969 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 970 | !~~~> STARTING PROCEDURE |
---|
| 971 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 972 | IF (.NOT.AUTNMS) THEN |
---|
| 973 | CALL FUN_CHEM(T+HJ,Y,DY) |
---|
| 974 | END IF |
---|
| 975 | DO i=1,N |
---|
| 976 | YH(i)=Y(i) |
---|
| 977 | DEL(i)=DY(i) |
---|
| 978 | END DO |
---|
| 979 | #ifdef FULL_ALGEBRA |
---|
| 980 | CALL DGETRS ('N',N,1,E,N,IP,DEL,N,ISING) |
---|
| 981 | #else |
---|
| 982 | CALL KppSolve (E,DEL) |
---|
| 983 | #endif |
---|
| 984 | Nsol=Nsol+1 |
---|
| 985 | M=NJ(JJ) |
---|
| 986 | IF (IOUT == 2.AND.M == JJ) THEN |
---|
| 987 | IPT=IPT+1 |
---|
| 988 | DO i=1,NRD |
---|
| 989 | FSAFE(IPT,I)=DEL(ICOMP(i)) |
---|
| 990 | END DO |
---|
| 991 | END IF |
---|
| 992 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 993 | !~~~> SEMI-IMPLICIT EULER METHOD |
---|
| 994 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 995 | IF (M > 1) THEN |
---|
| 996 | DO MM=1,M-1 |
---|
| 997 | DO i=1,N |
---|
| 998 | YH(i)=YH(i)+DEL(i) |
---|
| 999 | END DO |
---|
| 1000 | IF (AUTNMS) THEN |
---|
| 1001 | CALL FUN_CHEM(T+HJ*MM,YH,DYH) |
---|
| 1002 | ELSE |
---|
| 1003 | CALL FUN_CHEM(T+HJ*(MM+1),YH,DYH) |
---|
| 1004 | END IF |
---|
| 1005 | |
---|
| 1006 | IF (MM == 1.AND.JJ <= 2) THEN |
---|
| 1007 | !~~~> STABILITY CHECK |
---|
| 1008 | DEL1=0.D0 |
---|
| 1009 | DO i=1,N |
---|
| 1010 | DEL1=DEL1+(DEL(i)/SCAL(i))**2 |
---|
| 1011 | END DO |
---|
| 1012 | DEL1=SQRT(DEL1) |
---|
| 1013 | IF (.NOT.AUTNMS) THEN |
---|
| 1014 | CALL FUN_CHEM(T+HJ,YH,WH) |
---|
| 1015 | |
---|
| 1016 | DO i=1,N |
---|
| 1017 | DEL(i)=WH(i)-DEL(i)*HJI |
---|
| 1018 | END DO |
---|
| 1019 | ELSE |
---|
| 1020 | DO i=1,N |
---|
| 1021 | DEL(i)=DYH(i)-DEL(i)*HJI |
---|
| 1022 | END DO |
---|
| 1023 | END IF |
---|
| 1024 | #ifdef FULL_ALGEBRA |
---|
| 1025 | CALL DGETRS ('N',N,1,E,N,IP,DEL,N,ISING) |
---|
| 1026 | #else |
---|
| 1027 | CALL KppSolve (E,DEL) |
---|
| 1028 | #endif |
---|
| 1029 | Nsol=Nsol+1 |
---|
| 1030 | DEL2=0.D0 |
---|
| 1031 | DO i=1,N |
---|
| 1032 | DEL2=DEL2+(DEL(i)/SCAL(i))**2 |
---|
| 1033 | END DO |
---|
| 1034 | DEL2=SQRT(DEL2) |
---|
| 1035 | Theta=DEL2/MAX(1.D0,DEL1) |
---|
| 1036 | IF (Theta > 1.D0) GOTO 79 |
---|
| 1037 | END IF |
---|
| 1038 | #ifdef FULL_ALGEBRA |
---|
| 1039 | CALL DGETRS ('N',N,1,E,N,IP,DYH,N,ISING) |
---|
| 1040 | #else |
---|
| 1041 | CALL KppSolve (E,DYH) |
---|
| 1042 | #endif |
---|
| 1043 | Nsol=Nsol+1 |
---|
| 1044 | DO i=1,N |
---|
| 1045 | DEL(i)=DYH(i) |
---|
| 1046 | END DO |
---|
| 1047 | IF (IOUT == 2.AND.MM >= M-JJ) THEN |
---|
| 1048 | IPT=IPT+1 |
---|
| 1049 | DO i=1,NRD |
---|
| 1050 | FSAFE(IPT,i)=DEL(ICOMP(i)) |
---|
| 1051 | END DO |
---|
| 1052 | END IF |
---|
| 1053 | END DO |
---|
| 1054 | END IF |
---|
| 1055 | DO i=1,N |
---|
| 1056 | Table(JJ,I)=YH(i)+DEL(i) |
---|
| 1057 | END DO |
---|
| 1058 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 1059 | !~~~> POLYNOMIAL EXTRAPOLATION |
---|
| 1060 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 1061 | IF (JJ == 1) RETURN |
---|
| 1062 | DO L=JJ,2,-1 |
---|
| 1063 | FAC=(DBLE(NJ(JJ))/DBLE(NJ(L-1)))-1.D0 |
---|
| 1064 | DO i=1,N |
---|
| 1065 | Table(L-1,I)=Table(L,I)+(Table(L,I)-Table(L-1,I))/FAC |
---|
| 1066 | END DO |
---|
| 1067 | END DO |
---|
| 1068 | ERR=0.D0 |
---|
| 1069 | DO i=1,N |
---|
| 1070 | ERR=ERR+MIN(ABS((Table(1,I)-Table(2,I)))/SCAL(i),1.D15)**2 |
---|
| 1071 | END DO |
---|
| 1072 | IF (ERR >= 1.D30) GOTO 79 |
---|
| 1073 | ERR=SQRT(ERR/DBLE(N)) |
---|
| 1074 | IF (JJ > 2.AND.ERR >= ERROLD) GOTO 79 |
---|
| 1075 | ERROLD=MAX(4*ERR,1.D0) |
---|
| 1076 | !~~~> COMPUTE OPTIMAL STEP SIZES |
---|
| 1077 | EXPO=1.D0/JJ |
---|
| 1078 | FACMIN=FAC1**EXPO |
---|
| 1079 | FAC=MIN(FAC2/FACMIN,MAX(FACMIN,(ERR/FacSafe1)**EXPO/FacSafe2)) |
---|
| 1080 | FAC=1.D0/FAC |
---|
| 1081 | HH(JJ)=MIN(H*FAC,HmaxN) |
---|
| 1082 | W(JJ)=A(JJ)/HH(JJ) |
---|
| 1083 | RETURN |
---|
| 1084 | 79 ATOV=.TRUE. |
---|
| 1085 | H=H*0.5D0 |
---|
| 1086 | REJECT=.TRUE. |
---|
| 1087 | RETURN |
---|
| 1088 | END SUBROUTINE SEUL |
---|
| 1089 | |
---|
| 1090 | |
---|
| 1091 | |
---|
| 1092 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 1093 | SUBROUTINE FUN_CHEM( T, V, FCT ) |
---|
| 1094 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 1095 | |
---|
| 1096 | USE KPP_ROOT_Parameters |
---|
| 1097 | USE KPP_ROOT_Global |
---|
| 1098 | USE KPP_ROOT_Function, ONLY: Fun |
---|
| 1099 | USE KPP_ROOT_Rates, ONLY: Update_SUN, Update_RCONST, Update_PHOTO |
---|
| 1100 | |
---|
| 1101 | IMPLICIT NONE |
---|
| 1102 | |
---|
| 1103 | KPP_REAL :: V(NVAR), FCT(NVAR) |
---|
| 1104 | KPP_REAL :: T, TOLD |
---|
| 1105 | |
---|
| 1106 | !TOLD = TIME |
---|
| 1107 | !TIME = T |
---|
| 1108 | !CALL Update_SUN() |
---|
| 1109 | !CALL Update_RCONST() |
---|
| 1110 | !CALL Update_PHOTO() |
---|
| 1111 | !TIME = TOLD |
---|
| 1112 | CALL Fun(V, FIX, RCONST, FCT) |
---|
| 1113 | Nfun=Nfun+1 |
---|
| 1114 | |
---|
| 1115 | END SUBROUTINE FUN_CHEM |
---|
| 1116 | |
---|
| 1117 | |
---|
| 1118 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 1119 | SUBROUTINE JAC_CHEM ( T, V, Jcb ) |
---|
| 1120 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 1121 | |
---|
| 1122 | USE KPP_ROOT_Parameters |
---|
| 1123 | USE KPP_ROOT_Global |
---|
| 1124 | USE KPP_ROOT_Jacobian, ONLY: Jac_SP |
---|
| 1125 | USE KPP_ROOT_Rates, ONLY: Update_SUN, Update_RCONST, Update_PHOTO |
---|
| 1126 | |
---|
| 1127 | IMPLICIT NONE |
---|
| 1128 | |
---|
| 1129 | KPP_REAL :: V(NVAR), T, TOLD |
---|
| 1130 | #ifdef FULL_ALGEBRA |
---|
| 1131 | KPP_REAL :: JV(LU_NONZERO), Jcb(NVAR,NVAR) |
---|
| 1132 | INTEGER :: i,j |
---|
| 1133 | #else |
---|
| 1134 | KPP_REAL :: Jcb(LU_NONZERO) |
---|
| 1135 | #endif |
---|
| 1136 | |
---|
| 1137 | !TOLD = TIME |
---|
| 1138 | !TIME = T |
---|
| 1139 | !CALL Update_SUN() |
---|
| 1140 | !CALL Update_RCONST() |
---|
| 1141 | !CALL Update_PHOTO() |
---|
| 1142 | !TIME = TOLD |
---|
| 1143 | |
---|
| 1144 | #ifdef FULL_ALGEBRA |
---|
| 1145 | CALL Jac_SP(V, FIX, RCONST, JV) |
---|
| 1146 | DO j=1,NVAR |
---|
| 1147 | DO i=1,NVAR |
---|
| 1148 | Jcb(i,j) = 0.0D0 |
---|
| 1149 | END DO |
---|
| 1150 | END DO |
---|
| 1151 | DO i=1,LU_NONZERO |
---|
| 1152 | Jcb(LU_IROW(i),LU_ICOL(i)) = JV(i) |
---|
| 1153 | END DO |
---|
| 1154 | #else |
---|
| 1155 | CALL Jac_SP(V, FIX, RCONST, Jcb) |
---|
| 1156 | #endif |
---|
| 1157 | Njac=Njac+1 |
---|
| 1158 | |
---|
| 1159 | END SUBROUTINE JAC_CHEM |
---|
| 1160 | |
---|
| 1161 | !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 1162 | |
---|
| 1163 | END MODULE KPP_ROOT_Integrator |
---|