00001 *DECK SLSODE 00002 SUBROUTINE SLSODE (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK, 00003 1 ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF) 00004 EXTERNAL F, JAC 00005 INTEGER NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, MF 00006 REAL Y, T, TOUT, RTOL, ATOL, RWORK 00007 DIMENSION NEQ(*), Y(*), RTOL(*), ATOL(*), RWORK(LRW), IWORK(LIW) 00008 C***BEGIN PROLOGUE SLSODE 00009 C***PURPOSE Livermore Solver for Ordinary Differential Equations. 00010 C SLSODE solves the initial-value problem for stiff or 00011 C nonstiff systems of first-order ODE's, 00012 C dy/dt = f(t,y), or, in component form, 00013 C dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(N)), i=1,...,N. 00014 C***CATEGORY I1A 00015 C***TYPE SINGLE PRECISION (SLSODE-S, DLSODE-D) 00016 C***KEYWORDS ORDINARY DIFFERENTIAL EQUATIONS, INITIAL VALUE PROBLEM, 00017 C STIFF, NONSTIFF 00018 C***AUTHOR Hindmarsh, Alan C., (LLNL) 00019 C Center for Applied Scientific Computing, L-561 00020 C Lawrence Livermore National Laboratory 00021 C Livermore, CA 94551. 00022 C***DESCRIPTION 00023 C 00024 C NOTE: The "Usage" and "Arguments" sections treat only a subset of 00025 C available options, in condensed fashion. The options 00026 C covered and the information supplied will support most 00027 C standard uses of SLSODE. 00028 C 00029 C For more sophisticated uses, full details on all options are 00030 C given in the concluding section, headed "Long Description." 00031 C A synopsis of the SLSODE Long Description is provided at the 00032 C beginning of that section; general topics covered are: 00033 C - Elements of the call sequence; optional input and output 00034 C - Optional supplemental routines in the SLSODE package 00035 C - internal COMMON block 00036 C 00037 C *Usage: 00038 C Communication between the user and the SLSODE package, for normal 00039 C situations, is summarized here. This summary describes a subset 00040 C of the available options. See "Long Description" for complete 00041 C details, including optional communication, nonstandard options, 00042 C and instructions for special situations. 00043 C 00044 C A sample program is given in the "Examples" section. 00045 C 00046 C Refer to the argument descriptions for the definitions of the 00047 C quantities that appear in the following sample declarations. 00048 C 00049 C For MF = 10, 00050 C PARAMETER (LRW = 20 + 16*NEQ, LIW = 20) 00051 C For MF = 21 or 22, 00052 C PARAMETER (LRW = 22 + 9*NEQ + NEQ**2, LIW = 20 + NEQ) 00053 C For MF = 24 or 25, 00054 C PARAMETER (LRW = 22 + 10*NEQ + (2*ML+MU)*NEQ, 00055 C * LIW = 20 + NEQ) 00056 C 00057 C EXTERNAL F, JAC 00058 C INTEGER NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK(LIW), 00059 C * LIW, MF 00060 C REAL Y(NEQ), T, TOUT, RTOL, ATOL(ntol), RWORK(LRW) 00061 C 00062 C CALL SLSODE (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK, 00063 C * ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF) 00064 C 00065 C *Arguments: 00066 C F :EXT Name of subroutine for right-hand-side vector f. 00067 C This name must be declared EXTERNAL in calling 00068 C program. The form of F must be: 00069 C 00070 C SUBROUTINE F (NEQ, T, Y, YDOT) 00071 C INTEGER NEQ 00072 C REAL T, Y(*), YDOT(*) 00073 C 00074 C The inputs are NEQ, T, Y. F is to set 00075 C 00076 C YDOT(i) = f(i,T,Y(1),Y(2),...,Y(NEQ)), 00077 C i = 1, ..., NEQ . 00078 C 00079 C NEQ :IN Number of first-order ODE's. 00080 C 00081 C Y :INOUT Array of values of the y(t) vector, of length NEQ. 00082 C Input: For the first call, Y should contain the 00083 C values of y(t) at t = T. (Y is an input 00084 C variable only if ISTATE = 1.) 00085 C Output: On return, Y will contain the values at the 00086 C new t-value. 00087 C 00088 C T :INOUT Value of the independent variable. On return it 00089 C will be the current value of t (normally TOUT). 00090 C 00091 C TOUT :IN Next point where output is desired (.NE. T). 00092 C 00093 C ITOL :IN 1 or 2 according as ATOL (below) is a scalar or 00094 C an array. 00095 C 00096 C RTOL :IN Relative tolerance parameter (scalar). 00097 C 00098 C ATOL :IN Absolute tolerance parameter (scalar or array). 00099 C If ITOL = 1, ATOL need not be dimensioned. 00100 C If ITOL = 2, ATOL must be dimensioned at least NEQ. 00101 C 00102 C The estimated local error in Y(i) will be controlled 00103 C so as to be roughly less (in magnitude) than 00104 C 00105 C EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or 00106 C EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2. 00107 C 00108 C Thus the local error test passes if, in each 00109 C component, either the absolute error is less than 00110 C ATOL (or ATOL(i)), or the relative error is less 00111 C than RTOL. 00112 C 00113 C Use RTOL = 0.0 for pure absolute error control, and 00114 C use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative 00115 C error control. Caution: Actual (global) errors may 00116 C exceed these local tolerances, so choose them 00117 C conservatively. 00118 C 00119 C ITASK :IN Flag indicating the task SLSODE is to perform. 00120 C Use ITASK = 1 for normal computation of output 00121 C values of y at t = TOUT. 00122 C 00123 C ISTATE:INOUT Index used for input and output to specify the state 00124 C of the calculation. 00125 C Input: 00126 C 1 This is the first call for a problem. 00127 C 2 This is a subsequent call. 00128 C Output: 00129 C 1 Nothing was done, as TOUT was equal to T. 00130 C 2 SLSODE was successful (otherwise, negative). 00131 C Note that ISTATE need not be modified after a 00132 C successful return. 00133 C -1 Excess work done on this call (perhaps wrong 00134 C MF). 00135 C -2 Excess accuracy requested (tolerances too 00136 C small). 00137 C -3 Illegal input detected (see printed message). 00138 C -4 Repeated error test failures (check all 00139 C inputs). 00140 C -5 Repeated convergence failures (perhaps bad 00141 C Jacobian supplied or wrong choice of MF or 00142 C tolerances). 00143 C -6 Error weight became zero during problem 00144 C (solution component i vanished, and ATOL or 00145 C ATOL(i) = 0.). 00146 C 00147 C IOPT :IN Flag indicating whether optional inputs are used: 00148 C 0 No. 00149 C 1 Yes. (See "Optional inputs" under "Long 00150 C Description," Part 1.) 00151 C 00152 C RWORK :WORK Real work array of length at least: 00153 C 20 + 16*NEQ for MF = 10, 00154 C 22 + 9*NEQ + NEQ**2 for MF = 21 or 22, 00155 C 22 + 10*NEQ + (2*ML + MU)*NEQ for MF = 24 or 25. 00156 C 00157 C LRW :IN Declared length of RWORK (in user's DIMENSION 00158 C statement). 00159 C 00160 C IWORK :WORK Integer work array of length at least: 00161 C 20 for MF = 10, 00162 C 20 + NEQ for MF = 21, 22, 24, or 25. 00163 C 00164 C If MF = 24 or 25, input in IWORK(1),IWORK(2) the 00165 C lower and upper Jacobian half-bandwidths ML,MU. 00166 C 00167 C On return, IWORK contains information that may be 00168 C of interest to the user: 00169 C 00170 C Name Location Meaning 00171 C ----- --------- ----------------------------------------- 00172 C NST IWORK(11) Number of steps taken for the problem so 00173 C far. 00174 C NFE IWORK(12) Number of f evaluations for the problem 00175 C so far. 00176 C NJE IWORK(13) Number of Jacobian evaluations (and of 00177 C matrix LU decompositions) for the problem 00178 C so far. 00179 C NQU IWORK(14) Method order last used (successfully). 00180 C LENRW IWORK(17) Length of RWORK actually required. This 00181 C is defined on normal returns and on an 00182 C illegal input return for insufficient 00183 C storage. 00184 C LENIW IWORK(18) Length of IWORK actually required. This 00185 C is defined on normal returns and on an 00186 C illegal input return for insufficient 00187 C storage. 00188 C 00189 C LIW :IN Declared length of IWORK (in user's DIMENSION 00190 C statement). 00191 C 00192 C JAC :EXT Name of subroutine for Jacobian matrix (MF = 00193 C 21 or 24). If used, this name must be declared 00194 C EXTERNAL in calling program. If not used, pass a 00195 C dummy name. The form of JAC must be: 00196 C 00197 C SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD) 00198 C INTEGER NEQ, ML, MU, NROWPD 00199 C REAL T, Y(*), PD(NROWPD,*) 00200 C 00201 C See item c, under "Description" below for more 00202 C information about JAC. 00203 C 00204 C MF :IN Method flag. Standard values are: 00205 C 10 Nonstiff (Adams) method, no Jacobian used. 00206 C 21 Stiff (BDF) method, user-supplied full Jacobian. 00207 C 22 Stiff method, internally generated full 00208 C Jacobian. 00209 C 24 Stiff method, user-supplied banded Jacobian. 00210 C 25 Stiff method, internally generated banded 00211 C Jacobian. 00212 C 00213 C *Description: 00214 C SLSODE solves the initial value problem for stiff or nonstiff 00215 C systems of first-order ODE's, 00216 C 00217 C dy/dt = f(t,y) , 00218 C 00219 C or, in component form, 00220 C 00221 C dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ)) 00222 C (i = 1, ..., NEQ) . 00223 C 00224 C SLSODE is a package based on the GEAR and GEARB packages, and on 00225 C the October 23, 1978, version of the tentative ODEPACK user 00226 C interface standard, with minor modifications. 00227 C 00228 C The steps in solving such a problem are as follows. 00229 C 00230 C a. First write a subroutine of the form 00231 C 00232 C SUBROUTINE F (NEQ, T, Y, YDOT) 00233 C INTEGER NEQ 00234 C REAL T, Y(*), YDOT(*) 00235 C 00236 C which supplies the vector function f by loading YDOT(i) with 00237 C f(i). 00238 C 00239 C b. Next determine (or guess) whether or not the problem is stiff. 00240 C Stiffness occurs when the Jacobian matrix df/dy has an 00241 C eigenvalue whose real part is negative and large in magnitude 00242 C compared to the reciprocal of the t span of interest. If the 00243 C problem is nonstiff, use method flag MF = 10. If it is stiff, 00244 C there are four standard choices for MF, and SLSODE requires the 00245 C Jacobian matrix in some form. This matrix is regarded either 00246 C as full (MF = 21 or 22), or banded (MF = 24 or 25). In the 00247 C banded case, SLSODE requires two half-bandwidth parameters ML 00248 C and MU. These are, respectively, the widths of the lower and 00249 C upper parts of the band, excluding the main diagonal. Thus the 00250 C band consists of the locations (i,j) with 00251 C 00252 C i - ML <= j <= i + MU , 00253 C 00254 C and the full bandwidth is ML + MU + 1 . 00255 C 00256 C c. If the problem is stiff, you are encouraged to supply the 00257 C Jacobian directly (MF = 21 or 24), but if this is not feasible, 00258 C SLSODE will compute it internally by difference quotients (MF = 00259 C 22 or 25). If you are supplying the Jacobian, write a 00260 C subroutine of the form 00261 C 00262 C SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD) 00263 C INTEGER NEQ, ML, MU, NRWOPD 00264 C REAL T, Y(*), PD(NROWPD,*) 00265 C 00266 C which provides df/dy by loading PD as follows: 00267 C - For a full Jacobian (MF = 21), load PD(i,j) with df(i)/dy(j), 00268 C the partial derivative of f(i) with respect to y(j). (Ignore 00269 C the ML and MU arguments in this case.) 00270 C - For a banded Jacobian (MF = 24), load PD(i-j+MU+1,j) with 00271 C df(i)/dy(j); i.e., load the diagonal lines of df/dy into the 00272 C rows of PD from the top down. 00273 C - In either case, only nonzero elements need be loaded. 00274 C 00275 C d. Write a main program that calls subroutine SLSODE once for each 00276 C point at which answers are desired. This should also provide 00277 C for possible use of logical unit 6 for output of error messages 00278 C by SLSODE. 00279 C 00280 C Before the first call to SLSODE, set ISTATE = 1, set Y and T to 00281 C the initial values, and set TOUT to the first output point. To 00282 C continue the integration after a successful return, simply 00283 C reset TOUT and call SLSODE again. No other parameters need be 00284 C reset. 00285 C 00286 C *Examples: 00287 C The following is a simple example problem, with the coding needed 00288 C for its solution by SLSODE. The problem is from chemical kinetics, 00289 C and consists of the following three rate equations: 00290 C 00291 C dy1/dt = -.04*y1 + 1.E4*y2*y3 00292 C dy2/dt = .04*y1 - 1.E4*y2*y3 - 3.E7*y2**2 00293 C dy3/dt = 3.E7*y2**2 00294 C 00295 C on the interval from t = 0.0 to t = 4.E10, with initial conditions 00296 C y1 = 1.0, y2 = y3 = 0. The problem is stiff. 00297 C 00298 C The following coding solves this problem with SLSODE, using 00299 C MF = 21 and printing results at t = .4, 4., ..., 4.E10. It uses 00300 C ITOL = 2 and ATOL much smaller for y2 than for y1 or y3 because y2 00301 C has much smaller values. At the end of the run, statistical 00302 C quantities of interest are printed. 00303 C 00304 C EXTERNAL FEX, JEX 00305 C INTEGER IOPT, IOUT, ISTATE, ITASK, ITOL, IWORK(23), LIW, LRW, 00306 C * MF, NEQ 00307 C REAL ATOL(3), RTOL, RWORK(58), T, TOUT, Y(3) 00308 C NEQ = 3 00309 C Y(1) = 1. 00310 C Y(2) = 0. 00311 C Y(3) = 0. 00312 C T = 0. 00313 C TOUT = .4 00314 C ITOL = 2 00315 C RTOL = 1.E-4 00316 C ATOL(1) = 1.E-6 00317 C ATOL(2) = 1.E-10 00318 C ATOL(3) = 1.E-6 00319 C ITASK = 1 00320 C ISTATE = 1 00321 C IOPT = 0 00322 C LRW = 58 00323 C LIW = 23 00324 C MF = 21 00325 C DO 40 IOUT = 1,12 00326 C CALL SLSODE (FEX, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK, 00327 C * ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JEX, MF) 00328 C WRITE(6,20) T, Y(1), Y(2), Y(3) 00329 C 20 FORMAT(' At t =',E12.4,' y =',3E14.6) 00330 C IF (ISTATE .LT. 0) GO TO 80 00331 C 40 TOUT = TOUT*10. 00332 C WRITE(6,60) IWORK(11), IWORK(12), IWORK(13) 00333 C 60 FORMAT(/' No. steps =',i4,', No. f-s =',i4,', No. J-s =',i4) 00334 C STOP 00335 C 80 WRITE(6,90) ISTATE 00336 C 90 FORMAT(///' Error halt.. ISTATE =',I3) 00337 C STOP 00338 C END 00339 C 00340 C SUBROUTINE FEX (NEQ, T, Y, YDOT) 00341 C INTEGER NEQ 00342 C REAL T, Y(3), YDOT(3) 00343 C YDOT(1) = -.04*Y(1) + 1.E4*Y(2)*Y(3) 00344 C YDOT(3) = 3.E7*Y(2)*Y(2) 00345 C YDOT(2) = -YDOT(1) - YDOT(3) 00346 C RETURN 00347 C END 00348 C 00349 C SUBROUTINE JEX (NEQ, T, Y, ML, MU, PD, NRPD) 00350 C INTEGER NEQ, ML, MU, NRPD 00351 C REAL T, Y(3), PD(NRPD,3) 00352 C PD(1,1) = -.04 00353 C PD(1,2) = 1.E4*Y(3) 00354 C PD(1,3) = 1.E4*Y(2) 00355 C PD(2,1) = .04 00356 C PD(2,3) = -PD(1,3) 00357 C PD(3,2) = 6.E7*Y(2) 00358 C PD(2,2) = -PD(1,2) - PD(3,2) 00359 C RETURN 00360 C END 00361 C 00362 C The output from this program (on a Cray-1 in single precision) 00363 C is as follows. 00364 C 00365 C At t = 4.0000e-01 y = 9.851726e-01 3.386406e-05 1.479357e-02 00366 C At t = 4.0000e+00 y = 9.055142e-01 2.240418e-05 9.446344e-02 00367 C At t = 4.0000e+01 y = 7.158050e-01 9.184616e-06 2.841858e-01 00368 C At t = 4.0000e+02 y = 4.504846e-01 3.222434e-06 5.495122e-01 00369 C At t = 4.0000e+03 y = 1.831701e-01 8.940379e-07 8.168290e-01 00370 C At t = 4.0000e+04 y = 3.897016e-02 1.621193e-07 9.610297e-01 00371 C At t = 4.0000e+05 y = 4.935213e-03 1.983756e-08 9.950648e-01 00372 C At t = 4.0000e+06 y = 5.159269e-04 2.064759e-09 9.994841e-01 00373 C At t = 4.0000e+07 y = 5.306413e-05 2.122677e-10 9.999469e-01 00374 C At t = 4.0000e+08 y = 5.494530e-06 2.197825e-11 9.999945e-01 00375 C At t = 4.0000e+09 y = 5.129458e-07 2.051784e-12 9.999995e-01 00376 C At t = 4.0000e+10 y = -7.170603e-08 -2.868241e-13 1.000000e+00 00377 C 00378 C No. steps = 330, No. f-s = 405, No. J-s = 69 00379 C 00380 C *Accuracy: 00381 C The accuracy of the solution depends on the choice of tolerances 00382 C RTOL and ATOL. Actual (global) errors may exceed these local 00383 C tolerances, so choose them conservatively. 00384 C 00385 C *Cautions: 00386 C The work arrays should not be altered between calls to SLSODE for 00387 C the same problem, except possibly for the conditional and optional 00388 C inputs. 00389 C 00390 C *Portability: 00391 C Since NEQ is dimensioned inside SLSODE, some compilers may object 00392 C to a call to SLSODE with NEQ a scalar variable. In this event, 00393 C use DIMENSION NEQ(1). Similar remarks apply to RTOL and ATOL. 00394 C 00395 C Note to Cray users: 00396 C For maximum efficiency, use the CFT77 compiler. Appropriate 00397 C compiler optimization directives have been inserted for CFT77. 00398 C 00399 C *Reference: 00400 C Alan C. Hindmarsh, "ODEPACK, A Systematized Collection of ODE 00401 C Solvers," in Scientific Computing, R. S. Stepleman, et al., Eds. 00402 C (North-Holland, Amsterdam, 1983), pp. 55-64. 00403 C 00404 C *Long Description: 00405 C The following complete description of the user interface to 00406 C SLSODE consists of four parts: 00407 C 00408 C 1. The call sequence to subroutine SLSODE, which is a driver 00409 C routine for the solver. This includes descriptions of both 00410 C the call sequence arguments and user-supplied routines. 00411 C Following these descriptions is a description of optional 00412 C inputs available through the call sequence, and then a 00413 C description of optional outputs in the work arrays. 00414 C 00415 C 2. Descriptions of other routines in the SLSODE package that may 00416 C be (optionally) called by the user. These provide the ability 00417 C to alter error message handling, save and restore the internal 00418 C COMMON, and obtain specified derivatives of the solution y(t). 00419 C 00420 C 3. Descriptions of COMMON block to be declared in overlay or 00421 C similar environments, or to be saved when doing an interrupt 00422 C of the problem and continued solution later. 00423 C 00424 C 4. Description of two routines in the SLSODE package, either of 00425 C which the user may replace with his own version, if desired. 00426 C These relate to the measurement of errors. 00427 C 00428 C 00429 C Part 1. Call Sequence 00430 C ---------------------- 00431 C 00432 C Arguments 00433 C --------- 00434 C The call sequence parameters used for input only are 00435 C 00436 C F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC, MF, 00437 C 00438 C and those used for both input and output are 00439 C 00440 C Y, T, ISTATE. 00441 C 00442 C The work arrays RWORK and IWORK are also used for conditional and 00443 C optional inputs and optional outputs. (The term output here 00444 C refers to the return from subroutine SLSODE to the user's calling 00445 C program.) 00446 C 00447 C The legality of input parameters will be thoroughly checked on the 00448 C initial call for the problem, but not checked thereafter unless a 00449 C change in input parameters is flagged by ISTATE = 3 on input. 00450 C 00451 C The descriptions of the call arguments are as follows. 00452 C 00453 C F The name of the user-supplied subroutine defining the ODE 00454 C system. The system must be put in the first-order form 00455 C dy/dt = f(t,y), where f is a vector-valued function of 00456 C the scalar t and the vector y. Subroutine F is to compute 00457 C the function f. It is to have the form 00458 C 00459 C SUBROUTINE F (NEQ, T, Y, YDOT) 00460 C REAL T, Y(*), YDOT(*) 00461 C 00462 C where NEQ, T, and Y are input, and the array YDOT = 00463 C f(T,Y) is output. Y and YDOT are arrays of length NEQ. 00464 C Subroutine F should not alter Y(1),...,Y(NEQ). F must be 00465 C declared EXTERNAL in the calling program. 00466 C 00467 C Subroutine F may access user-defined quantities in 00468 C NEQ(2),... and/or in Y(NEQ(1)+1),..., if NEQ is an array 00469 C (dimensioned in F) and/or Y has length exceeding NEQ(1). 00470 C See the descriptions of NEQ and Y below. 00471 C 00472 C If quantities computed in the F routine are needed 00473 C externally to SLSODE, an extra call to F should be made 00474 C for this purpose, for consistent and accurate results. 00475 C If only the derivative dy/dt is needed, use SINTDY 00476 C instead. 00477 C 00478 C NEQ The size of the ODE system (number of first-order 00479 C ordinary differential equations). Used only for input. 00480 C NEQ may be decreased, but not increased, during the 00481 C problem. If NEQ is decreased (with ISTATE = 3 on input), 00482 C the remaining components of Y should be left undisturbed, 00483 C if these are to be accessed in F and/or JAC. 00484 C 00485 C Normally, NEQ is a scalar, and it is generally referred 00486 C to as a scalar in this user interface description. 00487 C However, NEQ may be an array, with NEQ(1) set to the 00488 C system size. (The SLSODE package accesses only NEQ(1).) 00489 C In either case, this parameter is passed as the NEQ 00490 C argument in all calls to F and JAC. Hence, if it is an 00491 C array, locations NEQ(2),... may be used to store other 00492 C integer data and pass it to F and/or JAC. Subroutines 00493 C F and/or JAC must include NEQ in a DIMENSION statement 00494 C in that case. 00495 C 00496 C Y A real array for the vector of dependent variables, of 00497 C length NEQ or more. Used for both input and output on 00498 C the first call (ISTATE = 1), and only for output on 00499 C other calls. On the first call, Y must contain the 00500 C vector of initial values. On output, Y contains the 00501 C computed solution vector, evaluated at T. If desired, 00502 C the Y array may be used for other purposes between 00503 C calls to the solver. 00504 C 00505 C This array is passed as the Y argument in all calls to F 00506 C and JAC. Hence its length may exceed NEQ, and locations 00507 C Y(NEQ+1),... may be used to store other real data and 00508 C pass it to F and/or JAC. (The SLSODE package accesses 00509 C only Y(1),...,Y(NEQ).) 00510 C 00511 C T The independent variable. On input, T is used only on 00512 C the first call, as the initial point of the integration. 00513 C On output, after each call, T is the value at which a 00514 C computed solution Y is evaluated (usually the same as 00515 C TOUT). On an error return, T is the farthest point 00516 C reached. 00517 C 00518 C TOUT The next value of T at which a computed solution is 00519 C desired. Used only for input. 00520 C 00521 C When starting the problem (ISTATE = 1), TOUT may be equal 00522 C to T for one call, then should not equal T for the next 00523 C call. For the initial T, an input value of TOUT .NE. T 00524 C is used in order to determine the direction of the 00525 C integration (i.e., the algebraic sign of the step sizes) 00526 C and the rough scale of the problem. Integration in 00527 C either direction (forward or backward in T) is permitted. 00528 C 00529 C If ITASK = 2 or 5 (one-step modes), TOUT is ignored 00530 C after the first call (i.e., the first call with 00531 C TOUT .NE. T). Otherwise, TOUT is required on every call. 00532 C 00533 C If ITASK = 1, 3, or 4, the values of TOUT need not be 00534 C monotone, but a value of TOUT which backs up is limited 00535 C to the current internal T interval, whose endpoints are 00536 C TCUR - HU and TCUR. (See "Optional Outputs" below for 00537 C TCUR and HU.) 00538 C 00539 C 00540 C ITOL An indicator for the type of error control. See 00541 C description below under ATOL. Used only for input. 00542 C 00543 C RTOL A relative error tolerance parameter, either a scalar or 00544 C an array of length NEQ. See description below under 00545 C ATOL. Input only. 00546 C 00547 C ATOL An absolute error tolerance parameter, either a scalar or 00548 C an array of length NEQ. Input only. 00549 C 00550 C The input parameters ITOL, RTOL, and ATOL determine the 00551 C error control performed by the solver. The solver will 00552 C control the vector e = (e(i)) of estimated local errors 00553 C in Y, according to an inequality of the form 00554 C 00555 C rms-norm of ( e(i)/EWT(i) ) <= 1, 00556 C 00557 C where 00558 C 00559 C EWT(i) = RTOL(i)*ABS(Y(i)) + ATOL(i), 00560 C 00561 C and the rms-norm (root-mean-square norm) here is 00562 C 00563 C rms-norm(v) = SQRT(sum v(i)**2 / NEQ). 00564 C 00565 C Here EWT = (EWT(i)) is a vector of weights which must 00566 C always be positive, and the values of RTOL and ATOL 00567 C should all be nonnegative. The following table gives the 00568 C types (scalar/array) of RTOL and ATOL, and the 00569 C corresponding form of EWT(i). 00570 C 00571 C ITOL RTOL ATOL EWT(i) 00572 C ---- ------ ------ ----------------------------- 00573 C 1 scalar scalar RTOL*ABS(Y(i)) + ATOL 00574 C 2 scalar array RTOL*ABS(Y(i)) + ATOL(i) 00575 C 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL 00576 C 4 array array RTOL(i)*ABS(Y(i)) + ATOL(i) 00577 C 00578 C When either of these parameters is a scalar, it need not 00579 C be dimensioned in the user's calling program. 00580 C 00581 C If none of the above choices (with ITOL, RTOL, and ATOL 00582 C fixed throughout the problem) is suitable, more general 00583 C error controls can be obtained by substituting 00584 C user-supplied routines for the setting of EWT and/or for 00585 C the norm calculation. See Part 4 below. 00586 C 00587 C If global errors are to be estimated by making a repeated 00588 C run on the same problem with smaller tolerances, then all 00589 C components of RTOL and ATOL (i.e., of EWT) should be 00590 C scaled down uniformly. 00591 C 00592 C ITASK An index specifying the task to be performed. Input 00593 C only. ITASK has the following values and meanings: 00594 C 1 Normal computation of output values of y(t) at 00595 C t = TOUT (by overshooting and interpolating). 00596 C 2 Take one step only and return. 00597 C 3 Stop at the first internal mesh point at or beyond 00598 C t = TOUT and return. 00599 C 4 Normal computation of output values of y(t) at 00600 C t = TOUT but without overshooting t = TCRIT. TCRIT 00601 C must be input as RWORK(1). TCRIT may be equal to or 00602 C beyond TOUT, but not behind it in the direction of 00603 C integration. This option is useful if the problem 00604 C has a singularity at or beyond t = TCRIT. 00605 C 5 Take one step, without passing TCRIT, and return. 00606 C TCRIT must be input as RWORK(1). 00607 C 00608 C Note: If ITASK = 4 or 5 and the solver reaches TCRIT 00609 C (within roundoff), it will return T = TCRIT (exactly) to 00610 C indicate this (unless ITASK = 4 and TOUT comes before 00611 C TCRIT, in which case answers at T = TOUT are returned 00612 C first). 00613 C 00614 C ISTATE An index used for input and output to specify the state 00615 C of the calculation. 00616 C 00617 C On input, the values of ISTATE are as follows: 00618 C 1 This is the first call for the problem 00619 C (initializations will be done). See "Note" below. 00620 C 2 This is not the first call, and the calculation is to 00621 C continue normally, with no change in any input 00622 C parameters except possibly TOUT and ITASK. (If ITOL, 00623 C RTOL, and/or ATOL are changed between calls with 00624 C ISTATE = 2, the new values will be used but not 00625 C tested for legality.) 00626 C 3 This is not the first call, and the calculation is to 00627 C continue normally, but with a change in input 00628 C parameters other than TOUT and ITASK. Changes are 00629 C allowed in NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF, 00630 C ML, MU, and any of the optional inputs except H0. 00631 C (See IWORK description for ML and MU.) 00632 C 00633 C Note: A preliminary call with TOUT = T is not counted as 00634 C a first call here, as no initialization or checking of 00635 C input is done. (Such a call is sometimes useful for the 00636 C purpose of outputting the initial conditions.) Thus the 00637 C first call for which TOUT .NE. T requires ISTATE = 1 on 00638 C input. 00639 C 00640 C On output, ISTATE has the following values and meanings: 00641 C 1 Nothing was done, as TOUT was equal to T with 00642 C ISTATE = 1 on input. 00643 C 2 The integration was performed successfully. 00644 C -1 An excessive amount of work (more than MXSTEP steps) 00645 C was done on this call, before completing the 00646 C requested task, but the integration was otherwise 00647 C successful as far as T. (MXSTEP is an optional input 00648 C and is normally 500.) To continue, the user may 00649 C simply reset ISTATE to a value >1 and call again (the 00650 C excess work step counter will be reset to 0). In 00651 C addition, the user may increase MXSTEP to avoid this 00652 C error return; see "Optional Inputs" below. 00653 C -2 Too much accuracy was requested for the precision of 00654 C the machine being used. This was detected before 00655 C completing the requested task, but the integration 00656 C was successful as far as T. To continue, the 00657 C tolerance parameters must be reset, and ISTATE must 00658 C be set to 3. The optional output TOLSF may be used 00659 C for this purpose. (Note: If this condition is 00660 C detected before taking any steps, then an illegal 00661 C input return (ISTATE = -3) occurs instead.) 00662 C -3 Illegal input was detected, before taking any 00663 C integration steps. See written message for details. 00664 C (Note: If the solver detects an infinite loop of 00665 C calls to the solver with illegal input, it will cause 00666 C the run to stop.) 00667 C -4 There were repeated error-test failures on one 00668 C attempted step, before completing the requested task, 00669 C but the integration was successful as far as T. The 00670 C problem may have a singularity, or the input may be 00671 C inappropriate. 00672 C -5 There were repeated convergence-test failures on one 00673 C attempted step, before completing the requested task, 00674 C but the integration was successful as far as T. This 00675 C may be caused by an inaccurate Jacobian matrix, if 00676 C one is being used. 00677 C -6 EWT(i) became zero for some i during the integration. 00678 C Pure relative error control (ATOL(i)=0.0) was 00679 C requested on a variable which has now vanished. The 00680 C integration was successful as far as T. 00681 C 00682 C Note: Since the normal output value of ISTATE is 2, it 00683 C does not need to be reset for normal continuation. Also, 00684 C since a negative input value of ISTATE will be regarded 00685 C as illegal, a negative output value requires the user to 00686 C change it, and possibly other inputs, before calling the 00687 C solver again. 00688 C 00689 C IOPT An integer flag to specify whether any optional inputs 00690 C are being used on this call. Input only. The optional 00691 C inputs are listed under a separate heading below. 00692 C 0 No optional inputs are being used. Default values 00693 C will be used in all cases. 00694 C 1 One or more optional inputs are being used. 00695 C 00696 C RWORK A real working array (single precision). The length of 00697 C RWORK must be at least 00698 C 00699 C 20 + NYH*(MAXORD + 1) + 3*NEQ + LWM 00700 C 00701 C where 00702 C NYH = the initial value of NEQ, 00703 C MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a 00704 C smaller value is given as an optional input), 00705 C LWM = 0 if MITER = 0, 00706 C LWM = NEQ**2 + 2 if MITER = 1 or 2, 00707 C LWM = NEQ + 2 if MITER = 3, and 00708 C LWM = (2*ML + MU + 1)*NEQ + 2 00709 C if MITER = 4 or 5. 00710 C (See the MF description below for METH and MITER.) 00711 C 00712 C Thus if MAXORD has its default value and NEQ is constant, 00713 C this length is: 00714 C 20 + 16*NEQ for MF = 10, 00715 C 22 + 16*NEQ + NEQ**2 for MF = 11 or 12, 00716 C 22 + 17*NEQ for MF = 13, 00717 C 22 + 17*NEQ + (2*ML + MU)*NEQ for MF = 14 or 15, 00718 C 20 + 9*NEQ for MF = 20, 00719 C 22 + 9*NEQ + NEQ**2 for MF = 21 or 22, 00720 C 22 + 10*NEQ for MF = 23, 00721 C 22 + 10*NEQ + (2*ML + MU)*NEQ for MF = 24 or 25. 00722 C 00723 C The first 20 words of RWORK are reserved for conditional 00724 C and optional inputs and optional outputs. 00725 C 00726 C The following word in RWORK is a conditional input: 00727 C RWORK(1) = TCRIT, the critical value of t which the 00728 C solver is not to overshoot. Required if ITASK 00729 C is 4 or 5, and ignored otherwise. See ITASK. 00730 C 00731 C LRW The length of the array RWORK, as declared by the user. 00732 C (This will be checked by the solver.) 00733 C 00734 C IWORK An integer work array. Its length must be at least 00735 C 20 if MITER = 0 or 3 (MF = 10, 13, 20, 23), or 00736 C 20 + NEQ otherwise (MF = 11, 12, 14, 15, 21, 22, 24, 25). 00737 C (See the MF description below for MITER.) The first few 00738 C words of IWORK are used for conditional and optional 00739 C inputs and optional outputs. 00740 C 00741 C The following two words in IWORK are conditional inputs: 00742 C IWORK(1) = ML These are the lower and upper half- 00743 C IWORK(2) = MU bandwidths, respectively, of the banded 00744 C Jacobian, excluding the main diagonal. 00745 C The band is defined by the matrix locations 00746 C (i,j) with i - ML <= j <= i + MU. ML and MU 00747 C must satisfy 0 <= ML,MU <= NEQ - 1. These are 00748 C required if MITER is 4 or 5, and ignored 00749 C otherwise. ML and MU may in fact be the band 00750 C parameters for a matrix to which df/dy is only 00751 C approximately equal. 00752 C 00753 C LIW The length of the array IWORK, as declared by the user. 00754 C (This will be checked by the solver.) 00755 C 00756 C Note: The work arrays must not be altered between calls to SLSODE 00757 C for the same problem, except possibly for the conditional and 00758 C optional inputs, and except for the last 3*NEQ words of RWORK. 00759 C The latter space is used for internal scratch space, and so is 00760 C available for use by the user outside SLSODE between calls, if 00761 C desired (but not for use by F or JAC). 00762 C 00763 C JAC The name of the user-supplied routine (MITER = 1 or 4) to 00764 C compute the Jacobian matrix, df/dy, as a function of the 00765 C scalar t and the vector y. (See the MF description below 00766 C for MITER.) It is to have the form 00767 C 00768 C SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD) 00769 C REAL T, Y(*), PD(NROWPD,*) 00770 C 00771 C where NEQ, T, Y, ML, MU, and NROWPD are input and the 00772 C array PD is to be loaded with partial derivatives 00773 C (elements of the Jacobian matrix) on output. PD must be 00774 C given a first dimension of NROWPD. T and Y have the same 00775 C meaning as in subroutine F. 00776 C 00777 C In the full matrix case (MITER = 1), ML and MU are 00778 C ignored, and the Jacobian is to be loaded into PD in 00779 C columnwise manner, with df(i)/dy(j) loaded into PD(i,j). 00780 C 00781 C In the band matrix case (MITER = 4), the elements within 00782 C the band are to be loaded into PD in columnwise manner, 00783 C with diagonal lines of df/dy loaded into the rows of PD. 00784 C Thus df(i)/dy(j) is to be loaded into PD(i-j+MU+1,j). ML 00785 C and MU are the half-bandwidth parameters (see IWORK). 00786 C The locations in PD in the two triangular areas which 00787 C correspond to nonexistent matrix elements can be ignored 00788 C or loaded arbitrarily, as they are overwritten by SLSODE. 00789 C 00790 C JAC need not provide df/dy exactly. A crude approximation 00791 C (possibly with a smaller bandwidth) will do. 00792 C 00793 C In either case, PD is preset to zero by the solver, so 00794 C that only the nonzero elements need be loaded by JAC. 00795 C Each call to JAC is preceded by a call to F with the same 00796 C arguments NEQ, T, and Y. Thus to gain some efficiency, 00797 C intermediate quantities shared by both calculations may 00798 C be saved in a user COMMON block by F and not recomputed 00799 C by JAC, if desired. Also, JAC may alter the Y array, if 00800 C desired. JAC must be declared EXTERNAL in the calling 00801 C program. 00802 C 00803 C Subroutine JAC may access user-defined quantities in 00804 C NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array 00805 C (dimensioned in JAC) and/or Y has length exceeding 00806 C NEQ(1). See the descriptions of NEQ and Y above. 00807 C 00808 C MF The method flag. Used only for input. The legal values 00809 C of MF are 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 00810 C and 25. MF has decimal digits METH and MITER: 00811 C MF = 10*METH + MITER . 00812 C 00813 C METH indicates the basic linear multistep method: 00814 C 1 Implicit Adams method. 00815 C 2 Method based on backward differentiation formulas 00816 C (BDF's). 00817 C 00818 C MITER indicates the corrector iteration method: 00819 C 0 Functional iteration (no Jacobian matrix is 00820 C involved). 00821 C 1 Chord iteration with a user-supplied full (NEQ by 00822 C NEQ) Jacobian. 00823 C 2 Chord iteration with an internally generated 00824 C (difference quotient) full Jacobian (using NEQ 00825 C extra calls to F per df/dy value). 00826 C 3 Chord iteration with an internally generated 00827 C diagonal Jacobian approximation (using one extra call 00828 C to F per df/dy evaluation). 00829 C 4 Chord iteration with a user-supplied banded Jacobian. 00830 C 5 Chord iteration with an internally generated banded 00831 C Jacobian (using ML + MU + 1 extra calls to F per 00832 C df/dy evaluation). 00833 C 00834 C If MITER = 1 or 4, the user must supply a subroutine JAC 00835 C (the name is arbitrary) as described above under JAC. 00836 C For other values of MITER, a dummy argument can be used. 00837 C 00838 C Optional Inputs 00839 C --------------- 00840 C The following is a list of the optional inputs provided for in the 00841 C call sequence. (See also Part 2.) For each such input variable, 00842 C this table lists its name as used in this documentation, its 00843 C location in the call sequence, its meaning, and the default value. 00844 C The use of any of these inputs requires IOPT = 1, and in that case 00845 C all of these inputs are examined. A value of zero for any of 00846 C these optional inputs will cause the default value to be used. 00847 C Thus to use a subset of the optional inputs, simply preload 00848 C locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, 00849 C and then set those of interest to nonzero values. 00850 C 00851 C Name Location Meaning and default value 00852 C ------ --------- ----------------------------------------------- 00853 C H0 RWORK(5) Step size to be attempted on the first step. 00854 C The default value is determined by the solver. 00855 C HMAX RWORK(6) Maximum absolute step size allowed. The 00856 C default value is infinite. 00857 C HMIN RWORK(7) Minimum absolute step size allowed. The 00858 C default value is 0. (This lower bound is not 00859 C enforced on the final step before reaching 00860 C TCRIT when ITASK = 4 or 5.) 00861 C MAXORD IWORK(5) Maximum order to be allowed. The default value 00862 C is 12 if METH = 1, and 5 if METH = 2. (See the 00863 C MF description above for METH.) If MAXORD 00864 C exceeds the default value, it will be reduced 00865 C to the default value. If MAXORD is changed 00866 C during the problem, it may cause the current 00867 C order to be reduced. 00868 C MXSTEP IWORK(6) Maximum number of (internally defined) steps 00869 C allowed during one call to the solver. The 00870 C default value is 500. 00871 C MXHNIL IWORK(7) Maximum number of messages printed (per 00872 C problem) warning that T + H = T on a step 00873 C (H = step size). This must be positive to 00874 C result in a nondefault value. The default 00875 C value is 10. 00876 C 00877 C Optional Outputs 00878 C ---------------- 00879 C As optional additional output from SLSODE, the variables listed 00880 C below are quantities related to the performance of SLSODE which 00881 C are available to the user. These are communicated by way of the 00882 C work arrays, but also have internal mnemonic names as shown. 00883 C Except where stated otherwise, all of these outputs are defined on 00884 C any successful return from SLSODE, and on any return with ISTATE = 00885 C -1, -2, -4, -5, or -6. On an illegal input return (ISTATE = -3), 00886 C they will be unchanged from their existing values (if any), except 00887 C possibly for TOLSF, LENRW, and LENIW. On any error return, 00888 C outputs relevant to the error will be defined, as noted below. 00889 C 00890 C Name Location Meaning 00891 C ----- --------- ------------------------------------------------ 00892 C HU RWORK(11) Step size in t last used (successfully). 00893 C HCUR RWORK(12) Step size to be attempted on the next step. 00894 C TCUR RWORK(13) Current value of the independent variable which 00895 C the solver has actually reached, i.e., the 00896 C current internal mesh point in t. On output, 00897 C TCUR will always be at least as far as the 00898 C argument T, but may be farther (if interpolation 00899 C was done). 00900 C TOLSF RWORK(14) Tolerance scale factor, greater than 1.0, 00901 C computed when a request for too much accuracy 00902 C was detected (ISTATE = -3 if detected at the 00903 C start of the problem, ISTATE = -2 otherwise). 00904 C If ITOL is left unaltered but RTOL and ATOL are 00905 C uniformly scaled up by a factor of TOLSF for the 00906 C next call, then the solver is deemed likely to 00907 C succeed. (The user may also ignore TOLSF and 00908 C alter the tolerance parameters in any other way 00909 C appropriate.) 00910 C NST IWORK(11) Number of steps taken for the problem so far. 00911 C NFE IWORK(12) Number of F evaluations for the problem so far. 00912 C NJE IWORK(13) Number of Jacobian evaluations (and of matrix LU 00913 C decompositions) for the problem so far. 00914 C NQU IWORK(14) Method order last used (successfully). 00915 C NQCUR IWORK(15) Order to be attempted on the next step. 00916 C IMXER IWORK(16) Index of the component of largest magnitude in 00917 C the weighted local error vector ( e(i)/EWT(i) ), 00918 C on an error return with ISTATE = -4 or -5. 00919 C LENRW IWORK(17) Length of RWORK actually required. This is 00920 C defined on normal returns and on an illegal 00921 C input return for insufficient storage. 00922 C LENIW IWORK(18) Length of IWORK actually required. This is 00923 C defined on normal returns and on an illegal 00924 C input return for insufficient storage. 00925 C 00926 C The following two arrays are segments of the RWORK array which may 00927 C also be of interest to the user as optional outputs. For each 00928 C array, the table below gives its internal name, its base address 00929 C in RWORK, and its description. 00930 C 00931 C Name Base address Description 00932 C ---- ------------ ---------------------------------------------- 00933 C YH 21 The Nordsieck history array, of size NYH by 00934 C (NQCUR + 1), where NYH is the initial value of 00935 C NEQ. For j = 0,1,...,NQCUR, column j + 1 of 00936 C YH contains HCUR**j/factorial(j) times the jth 00937 C derivative of the interpolating polynomial 00938 C currently representing the solution, evaluated 00939 C at t = TCUR. 00940 C ACOR LENRW-NEQ+1 Array of size NEQ used for the accumulated 00941 C corrections on each step, scaled on output to 00942 C represent the estimated local error in Y on 00943 C the last step. This is the vector e in the 00944 C description of the error control. It is 00945 C defined only on successful return from SLSODE. 00946 C 00947 C 00948 C Part 2. Other Callable Routines 00949 C -------------------------------- 00950 C 00951 C The following are optional calls which the user may make to gain 00952 C additional capabilities in conjunction with SLSODE. 00953 C 00954 C Form of call Function 00955 C ------------------------ ---------------------------------------- 00956 C CALL XSETUN(LUN) Set the logical unit number, LUN, for 00957 C output of messages from SLSODE, if the 00958 C default is not desired. The default 00959 C value of LUN is 6. This call may be made 00960 C at any time and will take effect 00961 C immediately. 00962 C CALL XSETF(MFLAG) Set a flag to control the printing of 00963 C messages by SLSODE. MFLAG = 0 means do 00964 C not print. (Danger: this risks losing 00965 C valuable information.) MFLAG = 1 means 00966 C print (the default). This call may be 00967 C made at any time and will take effect 00968 C immediately. 00969 C CALL SSRCOM(RSAV,ISAV,JOB) Saves and restores the contents of the 00970 C internal COMMON blocks used by SLSODE 00971 C (see Part 3 below). RSAV must be a 00972 C real array of length 218 or more, and 00973 C ISAV must be an integer array of length 00974 C 37 or more. JOB = 1 means save COMMON 00975 C into RSAV/ISAV. JOB = 2 means restore 00976 C COMMON from same. SSRCOM is useful if 00977 C one is interrupting a run and restarting 00978 C later, or alternating between two or 00979 C more problems solved with SLSODE. 00980 C CALL SINTDY(,,,,,) Provide derivatives of y, of various 00981 C (see below) orders, at a specified point t, if 00982 C desired. It may be called only after a 00983 C successful return from SLSODE. Detailed 00984 C instructions follow. 00985 C 00986 C Detailed instructions for using SINTDY 00987 C -------------------------------------- 00988 C The form of the CALL is: 00989 C 00990 C CALL SINTDY (T, K, RWORK(21), NYH, DKY, IFLAG) 00991 C 00992 C The input parameters are: 00993 C 00994 C T Value of independent variable where answers are 00995 C desired (normally the same as the T last returned by 00996 C SLSODE). For valid results, T must lie between 00997 C TCUR - HU and TCUR. (See "Optional Outputs" above 00998 C for TCUR and HU.) 00999 C K Integer order of the derivative desired. K must 01000 C satisfy 0 <= K <= NQCUR, where NQCUR is the current 01001 C order (see "Optional Outputs"). The capability 01002 C corresponding to K = 0, i.e., computing y(t), is 01003 C already provided by SLSODE directly. Since 01004 C NQCUR >= 1, the first derivative dy/dt is always 01005 C available with SINTDY. 01006 C RWORK(21) The base address of the history array YH. 01007 C NYH Column length of YH, equal to the initial value of NEQ. 01008 C 01009 C The output parameters are: 01010 C 01011 C DKY Real array of length NEQ containing the computed value 01012 C of the Kth derivative of y(t). 01013 C IFLAG Integer flag, returned as 0 if K and T were legal, 01014 C -1 if K was illegal, and -2 if T was illegal. 01015 C On an error return, a message is also written. 01016 C 01017 C 01018 C Part 3. Common Blocks 01019 C ---------------------- 01020 C 01021 C If SLSODE is to be used in an overlay situation, the user must 01022 C declare, in the primary overlay, the variables in: 01023 C (1) the call sequence to SLSODE, 01024 C (2) the internal COMMON block /SLS001/, of length 255 01025 C (218 single precision words followed by 37 integer words). 01026 C 01027 C If SLSODE is used on a system in which the contents of internal 01028 C COMMON blocks are not preserved between calls, the user should 01029 C declare the above COMMON block in his main program to insure that 01030 C its contents are preserved. 01031 C 01032 C If the solution of a given problem by SLSODE is to be interrupted 01033 C and then later continued, as when restarting an interrupted run or 01034 C alternating between two or more problems, the user should save, 01035 C following the return from the last SLSODE call prior to the 01036 C interruption, the contents of the call sequence variables and the 01037 C internal COMMON block, and later restore these values before the 01038 C next SLSODE call for that problem. In addition, if XSETUN and/or 01039 C XSETF was called for non-default handling of error messages, then 01040 C these calls must be repeated. To save and restore the COMMON 01041 C block, use subroutine SSRCOM (see Part 2 above). 01042 C 01043 C 01044 C Part 4. Optionally Replaceable Solver Routines 01045 C ----------------------------------------------- 01046 C 01047 C Below are descriptions of two routines in the SLSODE package which 01048 C relate to the measurement of errors. Either routine can be 01049 C replaced by a user-supplied version, if desired. However, since 01050 C such a replacement may have a major impact on performance, it 01051 C should be done only when absolutely necessary, and only with great 01052 C caution. (Note: The means by which the package version of a 01053 C routine is superseded by the user's version may be system- 01054 C dependent.) 01055 C 01056 C SEWSET 01057 C ------ 01058 C The following subroutine is called just before each internal 01059 C integration step, and sets the array of error weights, EWT, as 01060 C described under ITOL/RTOL/ATOL above: 01061 C 01062 C SUBROUTINE SEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT) 01063 C 01064 C where NEQ, ITOL, RTOL, and ATOL are as in the SLSODE call 01065 C sequence, YCUR contains the current dependent variable vector, 01066 C and EWT is the array of weights set by SEWSET. 01067 C 01068 C If the user supplies this subroutine, it must return in EWT(i) 01069 C (i = 1,...,NEQ) a positive quantity suitable for comparing errors 01070 C in Y(i) to. The EWT array returned by SEWSET is passed to the 01071 C SVNORM routine (see below), and also used by SLSODE in the 01072 C computation of the optional output IMXER, the diagonal Jacobian 01073 C approximation, and the increments for difference quotient 01074 C Jacobians. 01075 C 01076 C In the user-supplied version of SEWSET, it may be desirable to use 01077 C the current values of derivatives of y. Derivatives up to order NQ 01078 C are available from the history array YH, described above under 01079 C optional outputs. In SEWSET, YH is identical to the YCUR array, 01080 C extended to NQ + 1 columns with a column length of NYH and scale 01081 C factors of H**j/factorial(j). On the first call for the problem, 01082 C given by NST = 0, NQ is 1 and H is temporarily set to 1.0. 01083 C NYH is the initial value of NEQ. The quantities NQ, H, and NST 01084 C can be obtained by including in SEWSET the statements: 01085 C REAL RLS 01086 C COMMON /SLS001/ RLS(218),ILS(37) 01087 C NQ = ILS(33) 01088 C NST = ILS(34) 01089 C H = RLS(212) 01090 C Thus, for example, the current value of dy/dt can be obtained as 01091 C YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is unnecessary 01092 C when NST = 0). 01093 C 01094 C SVNORM 01095 C ------ 01096 C SVNORM is a real function routine which computes the weighted 01097 C root-mean-square norm of a vector v: 01098 C 01099 C d = SVNORM (n, v, w) 01100 C 01101 C where: 01102 C n = the length of the vector, 01103 C v = real array of length n containing the vector, 01104 C w = real array of length n containing weights, 01105 C d = SQRT( (1/n) * sum(v(i)*w(i))**2 ). 01106 C 01107 C SVNORM is called with n = NEQ and with w(i) = 1.0/EWT(i), where 01108 C EWT is as set by subroutine SEWSET. 01109 C 01110 C If the user supplies this function, it should return a nonnegative 01111 C value of SVNORM suitable for use in the error control in SLSODE. 01112 C None of the arguments should be altered by SVNORM. For example, a 01113 C user-supplied SVNORM routine might: 01114 C - Substitute a max-norm of (v(i)*w(i)) for the rms-norm, or 01115 C - Ignore some components of v in the norm, with the effect of 01116 C suppressing the error control on those components of Y. 01117 C --------------------------------------------------------------------- 01118 C***ROUTINES CALLED SEWSET, SINTDY, D1MACH, SSTODE, SVNORM, XERRWD 01119 C***COMMON BLOCKS SLS001 01120 C***REVISION HISTORY (YYYYMMDD) 01121 C 19791129 DATE WRITTEN 01122 C 19791213 Minor changes to declarations; DELP init. in STODE. 01123 C 19800118 Treat NEQ as array; integer declarations added throughout; 01124 C minor changes to prologue. 01125 C 19800306 Corrected TESCO(1,NQP1) setting in CFODE. 01126 C 19800519 Corrected access of YH on forced order reduction; 01127 C numerous corrections to prologues and other comments. 01128 C 19800617 In main driver, added loading of SQRT(UROUND) in RWORK; 01129 C minor corrections to main prologue. 01130 C 19800923 Added zero initialization of HU and NQU. 01131 C 19801218 Revised XERRWV routine; minor corrections to main prologue. 01132 C 19810401 Minor changes to comments and an error message. 01133 C 19810814 Numerous revisions: replaced EWT by 1/EWT; used flags 01134 C JCUR, ICF, IERPJ, IERSL between STODE and subordinates; 01135 C added tuning parameters CCMAX, MAXCOR, MSBP, MXNCF; 01136 C reorganized returns from STODE; reorganized type decls.; 01137 C fixed message length in XERRWV; changed default LUNIT to 6; 01138 C changed Common lengths; changed comments throughout. 01139 C 19870330 Major update by ACH: corrected comments throughout; 01140 C removed TRET from Common; rewrote EWSET with 4 loops; 01141 C fixed t test in INTDY; added Cray directives in STODE; 01142 C in STODE, fixed DELP init. and logic around PJAC call; 01143 C combined routines to save/restore Common; 01144 C passed LEVEL = 0 in error message calls (except run abort). 01145 C 19890426 Modified prologue to SLATEC/LDOC format. (FNF) 01146 C 19890501 Many improvements to prologue. (FNF) 01147 C 19890503 A few final corrections to prologue. (FNF) 01148 C 19890504 Minor cosmetic changes. (FNF) 01149 C 19890510 Corrected description of Y in Arguments section. (FNF) 01150 C 19890517 Minor corrections to prologue. (FNF) 01151 C 19920514 Updated with prologue edited 891025 by G. Shaw for manual. 01152 C 19920515 Converted source lines to upper case. (FNF) 01153 C 19920603 Revised XERRWV calls using mixed upper-lower case. (ACH) 01154 C 19920616 Revised prologue comment regarding CFT. (ACH) 01155 C 19921116 Revised prologue comments regarding Common. (ACH). 01156 C 19930326 Added comment about non-reentrancy. (FNF) 01157 C 19930723 Changed R1MACH to RUMACH. (FNF) 01158 C 19930801 Removed ILLIN and NTREP from Common (affects driver logic); 01159 C minor changes to prologue and internal comments; 01160 C changed Hollerith strings to quoted strings; 01161 C changed internal comments to mixed case; 01162 C replaced XERRWV with new version using character type; 01163 C changed dummy dimensions from 1 to *. (ACH) 01164 C 19930809 Changed to generic intrinsic names; changed names of 01165 C subprograms and Common blocks to SLSODE etc. (ACH) 01166 C 19930929 Eliminated use of REAL intrinsic; other minor changes. (ACH) 01167 C 20010412 Removed all 'own' variables from Common block /SLS001/ 01168 C (affects declarations in 6 routines). (ACH) 01169 C 20010509 Minor corrections to prologue. (ACH) 01170 C 20031105 Restored 'own' variables to Common block /SLS001/, to 01171 C enable interrupt/restart feature. (ACH) 01172 C 20031112 Added SAVE statements for data-loaded constants. 01173 C 01174 C*** END PROLOGUE SLSODE 01175 C 01176 C*Internal Notes: 01177 C 01178 C Other Routines in the SLSODE Package. 01179 C 01180 C In addition to Subroutine SLSODE, the SLSODE package includes the 01181 C following subroutines and function routines: 01182 C SINTDY computes an interpolated value of the y vector at t = TOUT. 01183 C SSTODE is the core integrator, which does one step of the 01184 C integration and the associated error control. 01185 C SCFODE sets all method coefficients and test constants. 01186 C SPREPJ computes and preprocesses the Jacobian matrix J = df/dy 01187 C and the Newton iteration matrix P = I - h*l0*J. 01188 C SSOLSY manages solution of linear system in chord iteration. 01189 C SEWSET sets the error weight vector EWT before each step. 01190 C SVNORM computes the weighted R.M.S. norm of a vector. 01191 C SSRCOM is a user-callable routine to save and restore 01192 C the contents of the internal Common block. 01193 C DGETRF AND DGETRS ARE ROUTINES FROM LAPACK FOR SOLVING FULL 01194 C SYSTEMS OF LINEAR ALGEBRAIC EQUATIONS. 01195 C DGBTRF AND DGBTRS ARE ROUTINES FROM LAPACK FOR SOLVING BANDED 01196 C LINEAR SYSTEMS. 01197 C D1MACH computes the unit roundoff in a machine-independent manner. 01198 C XERRWD, XSETUN, XSETF, IXSAV, IUMACH handle the printing of all 01199 C error messages and warnings. XERRWD is machine-dependent. 01200 C Note: SVNORM, D1MACH, IXSAV, and IUMACH are function routines. 01201 C All the others are subroutines. 01202 C 01203 C**End 01204 C 01205 C Declare externals. 01206 EXTERNAL SPREPJ, SSOLSY 01207 REAL D1MACH, SVNORM 01208 C 01209 C Declare all other variables. 01210 INTEGER INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS, 01211 1 ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, 01212 2 LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, 01213 3 MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU 01214 INTEGER I, I1, I2, IFLAG, IMXER, KGO, LF0, 01215 1 LENIW, LENRW, LENWM, ML, MORD, MU, MXHNL0, MXSTP0 01216 REAL ROWNS, 01217 1 CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND 01218 REAL ATOLI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RTOLI, 01219 1 TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0 01220 DIMENSION MORD(2) 01221 LOGICAL IHIT 01222 CHARACTER*80 MSG 01223 SAVE MORD, MXSTP0, MXHNL0 01224 C----------------------------------------------------------------------- 01225 C The following internal Common block contains 01226 C (a) variables which are local to any subroutine but whose values must 01227 C be preserved between calls to the routine ("own" variables), and 01228 C (b) variables which are communicated between subroutines. 01229 C The block SLS001 is declared in subroutines SLSODE, SINTDY, SSTODE, 01230 C SPREPJ, and SSOLSY. 01231 C Groups of variables are replaced by dummy arrays in the Common 01232 C declarations in routines where those variables are not used. 01233 C----------------------------------------------------------------------- 01234 COMMON /SLS001/ ROWNS(209), 01235 1 CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, 01236 2 INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6), 01237 3 ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, 01238 4 LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, 01239 5 MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU 01240 C 01241 DATA MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/ 01242 C----------------------------------------------------------------------- 01243 C Block A. 01244 C This code block is executed on every call. 01245 C It tests ISTATE and ITASK for legality and branches appropriately. 01246 C If ISTATE .GT. 1 but the flag INIT shows that initialization has 01247 C not yet been done, an error return occurs. 01248 C If ISTATE = 1 and TOUT = T, return immediately. 01249 C----------------------------------------------------------------------- 01250 C 01251 C***FIRST EXECUTABLE STATEMENT SLSODE 01252 IF (ISTATE .LT. 1 .OR. ISTATE .GT. 3) GO TO 601 01253 IF (ITASK .LT. 1 .OR. ITASK .GT. 5) GO TO 602 01254 IF (ISTATE .EQ. 1) GO TO 10 01255 IF (INIT .EQ. 0) GO TO 603 01256 IF (ISTATE .EQ. 2) GO TO 200 01257 GO TO 20 01258 10 INIT = 0 01259 IF (TOUT .EQ. T) RETURN 01260 C----------------------------------------------------------------------- 01261 C Block B. 01262 C The next code block is executed for the initial call (ISTATE = 1), 01263 C or for a continuation call with parameter changes (ISTATE = 3). 01264 C It contains checking of all inputs and various initializations. 01265 C 01266 C First check legality of the non-optional inputs NEQ, ITOL, IOPT, 01267 C MF, ML, and MU. 01268 C----------------------------------------------------------------------- 01269 20 IF (NEQ(1) .LE. 0) GO TO 604 01270 IF (ISTATE .EQ. 1) GO TO 25 01271 IF (NEQ(1) .GT. N) GO TO 605 01272 25 N = NEQ(1) 01273 IF (ITOL .LT. 1 .OR. ITOL .GT. 4) GO TO 606 01274 IF (IOPT .LT. 0 .OR. IOPT .GT. 1) GO TO 607 01275 METH = MF/10 01276 MITER = MF - 10*METH 01277 IF (METH .LT. 1 .OR. METH .GT. 2) GO TO 608 01278 IF (MITER .LT. 0 .OR. MITER .GT. 5) GO TO 608 01279 IF (MITER .LE. 3) GO TO 30 01280 ML = IWORK(1) 01281 MU = IWORK(2) 01282 IF (ML .LT. 0 .OR. ML .GE. N) GO TO 609 01283 IF (MU .LT. 0 .OR. MU .GE. N) GO TO 610 01284 30 CONTINUE 01285 C Next process and check the optional inputs. -------------------------- 01286 IF (IOPT .EQ. 1) GO TO 40 01287 MAXORD = MORD(METH) 01288 MXSTEP = MXSTP0 01289 MXHNIL = MXHNL0 01290 IF (ISTATE .EQ. 1) H0 = 0.0E0 01291 HMXI = 0.0E0 01292 HMIN = 0.0E0 01293 GO TO 60 01294 40 MAXORD = IWORK(5) 01295 IF (MAXORD .LT. 0) GO TO 611 01296 IF (MAXORD .EQ. 0) MAXORD = 100 01297 MAXORD = MIN(MAXORD,MORD(METH)) 01298 MXSTEP = IWORK(6) 01299 IF (MXSTEP .LT. 0) GO TO 612 01300 IF (MXSTEP .EQ. 0) MXSTEP = MXSTP0 01301 MXHNIL = IWORK(7) 01302 IF (MXHNIL .LT. 0) GO TO 613 01303 IF (MXHNIL .EQ. 0) MXHNIL = MXHNL0 01304 IF (ISTATE .NE. 1) GO TO 50 01305 H0 = RWORK(5) 01306 IF ((TOUT - T)*H0 .LT. 0.0E0) GO TO 614 01307 50 HMAX = RWORK(6) 01308 IF (HMAX .LT. 0.0E0) GO TO 615 01309 HMXI = 0.0E0 01310 IF (HMAX .GT. 0.0E0) HMXI = 1.0E0/HMAX 01311 HMIN = RWORK(7) 01312 IF (HMIN .LT. 0.0E0) GO TO 616 01313 C----------------------------------------------------------------------- 01314 C Set work array pointers and check lengths LRW and LIW. 01315 C Pointers to segments of RWORK and IWORK are named by prefixing L to 01316 C the name of the segment. E.g., the segment YH starts at RWORK(LYH). 01317 C Segments of RWORK (in order) are denoted YH, WM, EWT, SAVF, ACOR. 01318 C----------------------------------------------------------------------- 01319 60 LYH = 21 01320 IF (ISTATE .EQ. 1) NYH = N 01321 LWM = LYH + (MAXORD + 1)*NYH 01322 IF (MITER .EQ. 0) LENWM = 0 01323 IF (MITER .EQ. 1 .OR. MITER .EQ. 2) LENWM = N*N + 2 01324 IF (MITER .EQ. 3) LENWM = N + 2 01325 IF (MITER .GE. 4) LENWM = (2*ML + MU + 1)*N + 2 01326 LEWT = LWM + LENWM 01327 LSAVF = LEWT + N 01328 LACOR = LSAVF + N 01329 LENRW = LACOR + N - 1 01330 IWORK(17) = LENRW 01331 LIWM = 1 01332 LENIW = 20 + N 01333 IF (MITER .EQ. 0 .OR. MITER .EQ. 3) LENIW = 20 01334 IWORK(18) = LENIW 01335 IF (LENRW .GT. LRW) GO TO 617 01336 IF (LENIW .GT. LIW) GO TO 618 01337 C Check RTOL and ATOL for legality. ------------------------------------ 01338 RTOLI = RTOL(1) 01339 ATOLI = ATOL(1) 01340 DO 70 I = 1,N 01341 IF (ITOL .GE. 3) RTOLI = RTOL(I) 01342 IF (ITOL .EQ. 2 .OR. ITOL .EQ. 4) ATOLI = ATOL(I) 01343 IF (RTOLI .LT. 0.0E0) GO TO 619 01344 IF (ATOLI .LT. 0.0E0) GO TO 620 01345 70 CONTINUE 01346 IF (ISTATE .EQ. 1) GO TO 100 01347 C If ISTATE = 3, set flag to signal parameter changes to SSTODE. ------- 01348 JSTART = -1 01349 IF (NQ .LE. MAXORD) GO TO 90 01350 C MAXORD was reduced below NQ. Copy YH(*,MAXORD+2) into SAVF. --------- 01351 DO 80 I = 1,N 01352 80 RWORK(I+LSAVF-1) = RWORK(I+LWM-1) 01353 C Reload WM(1) = RWORK(LWM), since LWM may have changed. --------------- 01354 90 IF (MITER .GT. 0) RWORK(LWM) = SQRT(UROUND) 01355 IF (N .EQ. NYH) GO TO 200 01356 C NEQ was reduced. Zero part of YH to avoid undefined references. ----- 01357 I1 = LYH + L*NYH 01358 I2 = LYH + (MAXORD + 1)*NYH - 1 01359 IF (I1 .GT. I2) GO TO 200 01360 DO 95 I = I1,I2 01361 95 RWORK(I) = 0.0E0 01362 GO TO 200 01363 C----------------------------------------------------------------------- 01364 C Block C. 01365 C The next block is for the initial call only (ISTATE = 1). 01366 C It contains all remaining initializations, the initial call to F, 01367 C and the calculation of the initial step size. 01368 C The error weights in EWT are inverted after being loaded. 01369 C----------------------------------------------------------------------- 01370 100 UROUND = D1MACH(4) 01371 TN = T 01372 IF (ITASK .NE. 4 .AND. ITASK .NE. 5) GO TO 110 01373 TCRIT = RWORK(1) 01374 IF ((TCRIT - TOUT)*(TOUT - T) .LT. 0.0E0) GO TO 625 01375 IF (H0 .NE. 0.0E0 .AND. (T + H0 - TCRIT)*H0 .GT. 0.0E0) 01376 1 H0 = TCRIT - T 01377 110 JSTART = 0 01378 IF (MITER .GT. 0) RWORK(LWM) = SQRT(UROUND) 01379 NHNIL = 0 01380 NST = 0 01381 NJE = 0 01382 NSLAST = 0 01383 HU = 0.0E0 01384 NQU = 0 01385 CCMAX = 0.3E0 01386 MAXCOR = 3 01387 MSBP = 20 01388 MXNCF = 10 01389 C Initial call to F. (LF0 points to YH(*,2).) ------------------------- 01390 LF0 = LYH + NYH 01391 CALL F (NEQ, T, Y, RWORK(LF0)) 01392 NFE = 1 01393 C Load the initial value vector in YH. --------------------------------- 01394 DO 115 I = 1,N 01395 115 RWORK(I+LYH-1) = Y(I) 01396 C Load and invert the EWT array. (H is temporarily set to 1.0.) ------- 01397 NQ = 1 01398 H = 1.0E0 01399 CALL SEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT)) 01400 DO 120 I = 1,N 01401 IF (RWORK(I+LEWT-1) .LE. 0.0E0) GO TO 621 01402 120 RWORK(I+LEWT-1) = 1.0E0/RWORK(I+LEWT-1) 01403 C----------------------------------------------------------------------- 01404 C The coding below computes the step size, H0, to be attempted on the 01405 C first step, unless the user has supplied a value for this. 01406 C First check that TOUT - T differs significantly from zero. 01407 C A scalar tolerance quantity TOL is computed, as MAX(RTOL(I)) 01408 C if this is positive, or MAX(ATOL(I)/ABS(Y(I))) otherwise, adjusted 01409 C so as to be between 100*UROUND and 1.0E-3. 01410 C Then the computed value H0 is given by.. 01411 C NEQ 01412 C H0**2 = TOL / ( w0**-2 + (1/NEQ) * SUM ( f(i)/ywt(i) )**2 ) 01413 C 1 01414 C where w0 = MAX ( ABS(T), ABS(TOUT) ), 01415 C f(i) = i-th component of initial value of f, 01416 C ywt(i) = EWT(i)/TOL (a weight for y(i)). 01417 C The sign of H0 is inferred from the initial values of TOUT and T. 01418 C----------------------------------------------------------------------- 01419 IF (H0 .NE. 0.0E0) GO TO 180 01420 TDIST = ABS(TOUT - T) 01421 W0 = MAX(ABS(T),ABS(TOUT)) 01422 IF (TDIST .LT. 2.0E0*UROUND*W0) GO TO 622 01423 TOL = RTOL(1) 01424 IF (ITOL .LE. 2) GO TO 140 01425 DO 130 I = 1,N 01426 130 TOL = MAX(TOL,RTOL(I)) 01427 140 IF (TOL .GT. 0.0E0) GO TO 160 01428 ATOLI = ATOL(1) 01429 DO 150 I = 1,N 01430 IF (ITOL .EQ. 2 .OR. ITOL .EQ. 4) ATOLI = ATOL(I) 01431 AYI = ABS(Y(I)) 01432 IF (AYI .NE. 0.0E0) TOL = MAX(TOL,ATOLI/AYI) 01433 150 CONTINUE 01434 160 TOL = MAX(TOL,100.0E0*UROUND) 01435 TOL = MIN(TOL,0.001E0) 01436 SUM = SVNORM (N, RWORK(LF0), RWORK(LEWT)) 01437 SUM = 1.0E0/(TOL*W0*W0) + TOL*SUM**2 01438 H0 = 1.0E0/SQRT(SUM) 01439 H0 = MIN(H0,TDIST) 01440 H0 = SIGN(H0,TOUT-T) 01441 C Adjust H0 if necessary to meet HMAX bound. --------------------------- 01442 180 RH = ABS(H0)*HMXI 01443 IF (RH .GT. 1.0E0) H0 = H0/RH 01444 C Load H with H0 and scale YH(*,2) by H0. ------------------------------ 01445 H = H0 01446 DO 190 I = 1,N 01447 190 RWORK(I+LF0-1) = H0*RWORK(I+LF0-1) 01448 GO TO 270 01449 C----------------------------------------------------------------------- 01450 C Block D. 01451 C The next code block is for continuation calls only (ISTATE = 2 or 3) 01452 C and is to check stop conditions before taking a step. 01453 C----------------------------------------------------------------------- 01454 200 NSLAST = NST 01455 GO TO (210, 250, 220, 230, 240), ITASK 01456 210 IF ((TN - TOUT)*H .LT. 0.0E0) GO TO 250 01457 CALL SINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG) 01458 IF (IFLAG .NE. 0) GO TO 627 01459 T = TOUT 01460 GO TO 420 01461 220 TP = TN - HU*(1.0E0 + 100.0E0*UROUND) 01462 IF ((TP - TOUT)*H .GT. 0.0E0) GO TO 623 01463 IF ((TN - TOUT)*H .LT. 0.0E0) GO TO 250 01464 GO TO 400 01465 230 TCRIT = RWORK(1) 01466 IF ((TN - TCRIT)*H .GT. 0.0E0) GO TO 624 01467 IF ((TCRIT - TOUT)*H .LT. 0.0E0) GO TO 625 01468 IF ((TN - TOUT)*H .LT. 0.0E0) GO TO 245 01469 CALL SINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG) 01470 IF (IFLAG .NE. 0) GO TO 627 01471 T = TOUT 01472 GO TO 420 01473 240 TCRIT = RWORK(1) 01474 IF ((TN - TCRIT)*H .GT. 0.0E0) GO TO 624 01475 245 HMX = ABS(TN) + ABS(H) 01476 IHIT = ABS(TN - TCRIT) .LE. 100.0E0*UROUND*HMX 01477 IF (IHIT) GO TO 400 01478 TNEXT = TN + H*(1.0E0 + 4.0E0*UROUND) 01479 IF ((TNEXT - TCRIT)*H .LE. 0.0E0) GO TO 250 01480 H = (TCRIT - TN)*(1.0E0 - 4.0E0*UROUND) 01481 IF (ISTATE .EQ. 2) JSTART = -2 01482 C----------------------------------------------------------------------- 01483 C Block E. 01484 C The next block is normally executed for all calls and contains 01485 C the call to the one-step core integrator SSTODE. 01486 C 01487 C This is a looping point for the integration steps. 01488 C 01489 C First check for too many steps being taken, update EWT (if not at 01490 C start of problem), check for too much accuracy being requested, and 01491 C check for H below the roundoff level in T. 01492 C----------------------------------------------------------------------- 01493 250 CONTINUE 01494 IF ((NST-NSLAST) .GE. MXSTEP) GO TO 500 01495 CALL SEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT)) 01496 DO 260 I = 1,N 01497 IF (RWORK(I+LEWT-1) .LE. 0.0E0) GO TO 510 01498 260 RWORK(I+LEWT-1) = 1.0E0/RWORK(I+LEWT-1) 01499 270 TOLSF = UROUND*SVNORM (N, RWORK(LYH), RWORK(LEWT)) 01500 IF (TOLSF .LE. 1.0E0) GO TO 280 01501 TOLSF = TOLSF*2.0E0 01502 IF (NST .EQ. 0) GO TO 626 01503 GO TO 520 01504 280 IF ((TN + H) .NE. TN) GO TO 290 01505 NHNIL = NHNIL + 1 01506 IF (NHNIL .GT. MXHNIL) GO TO 290 01507 CALL XERRWD('SLSODE- Warning..internal T (=R1) and H (=R2) are', 01508 1 50, 101, 0, 0, 0, 0, 0, 0.0E0, 0.0E0) 01509 CALL XERRWD( 01510 1 ' such that in the machine, T + H = T on the next step ', 01511 1 60, 101, 0, 0, 0, 0, 0, 0.0E0, 0.0E0) 01512 CALL XERRWD(' (H = step size). Solver will continue anyway', 01513 1 50, 101, 0, 0, 0, 0, 2, TN, H) 01514 IF (NHNIL .LT. MXHNIL) GO TO 290 01515 CALL XERRWD('SLSODE- Above warning has been issued I1 times. ', 01516 1 50, 102, 0, 0, 0, 0, 0, 0.0E0, 0.0E0) 01517 CALL XERRWD(' It will not be issued again for this problem', 01518 1 50, 102, 0, 1, MXHNIL, 0, 0, 0.0E0, 0.0E0) 01519 290 CONTINUE 01520 C----------------------------------------------------------------------- 01521 C CALL SSTODE(NEQ,Y,YH,NYH,YH,EWT,SAVF,ACOR,WM,IWM,F,JAC,SPREPJ,SSOLSY) 01522 C----------------------------------------------------------------------- 01523 CALL SSTODE (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT), 01524 1 RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), IWORK(LIWM), 01525 2 F, JAC, SPREPJ, SSOLSY) 01526 KGO = 1 - KFLAG 01527 GO TO (300, 530, 540), KGO 01528 C----------------------------------------------------------------------- 01529 C Block F. 01530 C The following block handles the case of a successful return from the 01531 C core integrator (KFLAG = 0). Test for stop conditions. 01532 C----------------------------------------------------------------------- 01533 300 INIT = 1 01534 GO TO (310, 400, 330, 340, 350), ITASK 01535 C ITASK = 1. If TOUT has been reached, interpolate. ------------------- 01536 310 IF ((TN - TOUT)*H .LT. 0.0E0) GO TO 250 01537 CALL SINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG) 01538 T = TOUT 01539 GO TO 420 01540 C ITASK = 3. Jump to exit if TOUT was reached. ------------------------ 01541 330 IF ((TN - TOUT)*H .GE. 0.0E0) GO TO 400 01542 GO TO 250 01543 C ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary. 01544 340 IF ((TN - TOUT)*H .LT. 0.0E0) GO TO 345 01545 CALL SINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG) 01546 T = TOUT 01547 GO TO 420 01548 345 HMX = ABS(TN) + ABS(H) 01549 IHIT = ABS(TN - TCRIT) .LE. 100.0E0*UROUND*HMX 01550 IF (IHIT) GO TO 400 01551 TNEXT = TN + H*(1.0E0 + 4.0E0*UROUND) 01552 IF ((TNEXT - TCRIT)*H .LE. 0.0E0) GO TO 250 01553 H = (TCRIT - TN)*(1.0E0 - 4.0E0*UROUND) 01554 JSTART = -2 01555 GO TO 250 01556 C ITASK = 5. See if TCRIT was reached and jump to exit. --------------- 01557 350 HMX = ABS(TN) + ABS(H) 01558 IHIT = ABS(TN - TCRIT) .LE. 100.0E0*UROUND*HMX 01559 C----------------------------------------------------------------------- 01560 C Block G. 01561 C The following block handles all successful returns from SLSODE. 01562 C If ITASK .NE. 1, Y is loaded from YH and T is set accordingly. 01563 C ISTATE is set to 2, and the optional outputs are loaded into the 01564 C work arrays before returning. 01565 C----------------------------------------------------------------------- 01566 400 DO 410 I = 1,N 01567 410 Y(I) = RWORK(I+LYH-1) 01568 T = TN 01569 IF (ITASK .NE. 4 .AND. ITASK .NE. 5) GO TO 420 01570 IF (IHIT) T = TCRIT 01571 420 ISTATE = 2 01572 RWORK(11) = HU 01573 RWORK(12) = H 01574 RWORK(13) = TN 01575 IWORK(11) = NST 01576 IWORK(12) = NFE 01577 IWORK(13) = NJE 01578 IWORK(14) = NQU 01579 IWORK(15) = NQ 01580 RETURN 01581 C----------------------------------------------------------------------- 01582 C Block H. 01583 C The following block handles all unsuccessful returns other than 01584 C those for illegal input. First the error message routine is called. 01585 C If there was an error test or convergence test failure, IMXER is set. 01586 C Then Y is loaded from YH and T is set to TN. The optional outputs 01587 C are loaded into the work arrays before returning. 01588 C----------------------------------------------------------------------- 01589 C The maximum number of steps was taken before reaching TOUT. ---------- 01590 500 CALL XERRWD('SLSODE- At current T (=R1), MXSTEP (=I1) steps ', 01591 1 50, 201, 0, 0, 0, 0, 0, 0.0E0, 0.0E0) 01592 CALL XERRWD(' taken on this call before reaching TOUT ', 01593 1 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0E0) 01594 ISTATE = -1 01595 GO TO 580 01596 C EWT(I) .LE. 0.0 for some I (not at start of problem). ---------------- 01597 510 EWTI = RWORK(LEWT+I-1) 01598 CALL XERRWD('SLSODE- At T (=R1), EWT(I1) has become R2 .LE. 0.', 01599 1 50, 202, 0, 1, I, 0, 2, TN, EWTI) 01600 ISTATE = -6 01601 GO TO 580 01602 C Too much accuracy requested for machine precision. ------------------- 01603 520 CALL XERRWD('SLSODE- At T (=R1), too much accuracy requested ', 01604 1 50, 203, 0, 0, 0, 0, 0, 0.0E0, 0.0E0) 01605 CALL XERRWD(' for precision of machine.. see TOLSF (=R2) ', 01606 1 50, 203, 0, 0, 0, 0, 2, TN, TOLSF) 01607 RWORK(14) = TOLSF 01608 ISTATE = -2 01609 GO TO 580 01610 C KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. ----- 01611 530 CALL XERRWD('SLSODE- At T(=R1) and step size H(=R2), the error', 01612 1 50, 204, 0, 0, 0, 0, 0, 0.0E0, 0.0E0) 01613 CALL XERRWD(' test failed repeatedly or with ABS(H) = HMIN', 01614 1 50, 204, 0, 0, 0, 0, 2, TN, H) 01615 ISTATE = -4 01616 GO TO 560 01617 C KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ---- 01618 540 CALL XERRWD('SLSODE- At T (=R1) and step size H (=R2), the ', 01619 1 50, 205, 0, 0, 0, 0, 0, 0.0E0, 0.0E0) 01620 CALL XERRWD(' corrector convergence failed repeatedly ', 01621 1 50, 205, 0, 0, 0, 0, 0, 0.0E0, 0.0E0) 01622 CALL XERRWD(' or with ABS(H) = HMIN ', 01623 1 30, 205, 0, 0, 0, 0, 2, TN, H) 01624 ISTATE = -5 01625 C Compute IMXER if relevant. ------------------------------------------- 01626 560 BIG = 0.0E0 01627 IMXER = 1 01628 DO 570 I = 1,N 01629 SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1)) 01630 IF (BIG .GE. SIZE) GO TO 570 01631 BIG = SIZE 01632 IMXER = I 01633 570 CONTINUE 01634 IWORK(16) = IMXER 01635 C Set Y vector, T, and optional outputs. ------------------------------- 01636 580 DO 590 I = 1,N 01637 590 Y(I) = RWORK(I+LYH-1) 01638 T = TN 01639 RWORK(11) = HU 01640 RWORK(12) = H 01641 RWORK(13) = TN 01642 IWORK(11) = NST 01643 IWORK(12) = NFE 01644 IWORK(13) = NJE 01645 IWORK(14) = NQU 01646 IWORK(15) = NQ 01647 RETURN 01648 C----------------------------------------------------------------------- 01649 C Block I. 01650 C The following block handles all error returns due to illegal input 01651 C (ISTATE = -3), as detected before calling the core integrator. 01652 C First the error message routine is called. If the illegal input 01653 C is a negative ISTATE, the run is aborted (apparent infinite loop). 01654 C----------------------------------------------------------------------- 01655 601 CALL XERRWD('SLSODE- ISTATE (=I1) illegal ', 01656 1 30, 1, 0, 1, ISTATE, 0, 0, 0.0E0, 0.0E0) 01657 IF (ISTATE .LT. 0) GO TO 800 01658 GO TO 700 01659 602 CALL XERRWD('SLSODE- ITASK (=I1) illegal ', 01660 1 30, 2, 0, 1, ITASK, 0, 0, 0.0E0, 0.0E0) 01661 GO TO 700 01662 603 CALL XERRWD('SLSODE- ISTATE .GT. 1 but SLSODE not initialized ', 01663 1 50, 3, 0, 0, 0, 0, 0, 0.0E0, 0.0E0) 01664 GO TO 700 01665 604 CALL XERRWD('SLSODE- NEQ (=I1) .LT. 1 ', 01666 1 30, 4, 0, 1, NEQ(1), 0, 0, 0.0E0, 0.0E0) 01667 GO TO 700 01668 605 CALL XERRWD('SLSODE- ISTATE = 3 and NEQ increased (I1 to I2) ', 01669 1 50, 5, 0, 2, N, NEQ(1), 0, 0.0E0, 0.0E0) 01670 GO TO 700 01671 606 CALL XERRWD('SLSODE- ITOL (=I1) illegal ', 01672 1 30, 6, 0, 1, ITOL, 0, 0, 0.0E0, 0.0E0) 01673 GO TO 700 01674 607 CALL XERRWD('SLSODE- IOPT (=I1) illegal ', 01675 1 30, 7, 0, 1, IOPT, 0, 0, 0.0E0, 0.0E0) 01676 GO TO 700 01677 608 CALL XERRWD('SLSODE- MF (=I1) illegal ', 01678 1 30, 8, 0, 1, MF, 0, 0, 0.0E0, 0.0E0) 01679 GO TO 700 01680 609 CALL XERRWD('SLSODE- ML (=I1) illegal.. .LT.0 or .GE.NEQ (=I2)', 01681 1 50, 9, 0, 2, ML, NEQ(1), 0, 0.0E0, 0.0E0) 01682 GO TO 700 01683 610 CALL XERRWD('SLSODE- MU (=I1) illegal.. .LT.0 or .GE.NEQ (=I2)', 01684 1 50, 10, 0, 2, MU, NEQ(1), 0, 0.0E0, 0.0E0) 01685 GO TO 700 01686 611 CALL XERRWD('SLSODE- MAXORD (=I1) .LT. 0 ', 01687 1 30, 11, 0, 1, MAXORD, 0, 0, 0.0E0, 0.0E0) 01688 GO TO 700 01689 612 CALL XERRWD('SLSODE- MXSTEP (=I1) .LT. 0 ', 01690 1 30, 12, 0, 1, MXSTEP, 0, 0, 0.0E0, 0.0E0) 01691 GO TO 700 01692 613 CALL XERRWD('SLSODE- MXHNIL (=I1) .LT. 0 ', 01693 1 30, 13, 0, 1, MXHNIL, 0, 0, 0.0E0, 0.0E0) 01694 GO TO 700 01695 614 CALL XERRWD('SLSODE- TOUT (=R1) behind T (=R2) ', 01696 1 40, 14, 0, 0, 0, 0, 2, TOUT, T) 01697 CALL XERRWD(' Integration direction is given by H0 (=R1) ', 01698 1 50, 14, 0, 0, 0, 0, 1, H0, 0.0E0) 01699 GO TO 700 01700 615 CALL XERRWD('SLSODE- HMAX (=R1) .LT. 0.0 ', 01701 1 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0E0) 01702 GO TO 700 01703 616 CALL XERRWD('SLSODE- HMIN (=R1) .LT. 0.0 ', 01704 1 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0E0) 01705 GO TO 700 01706 617 CALL XERRWD( 01707 1 'SLSODE- RWORK length needed, LENRW (=I1), exceeds LRW (=I2)', 01708 1 60, 17, 0, 2, LENRW, LRW, 0, 0.0E0, 0.0E0) 01709 GO TO 700 01710 618 CALL XERRWD( 01711 1 'SLSODE- IWORK length needed, LENIW (=I1), exceeds LIW (=I2)', 01712 1 60, 18, 0, 2, LENIW, LIW, 0, 0.0E0, 0.0E0) 01713 GO TO 700 01714 619 CALL XERRWD('SLSODE- RTOL(I1) is R1 .LT. 0.0 ', 01715 1 40, 19, 0, 1, I, 0, 1, RTOLI, 0.0E0) 01716 GO TO 700 01717 620 CALL XERRWD('SLSODE- ATOL(I1) is R1 .LT. 0.0 ', 01718 1 40, 20, 0, 1, I, 0, 1, ATOLI, 0.0E0) 01719 GO TO 700 01720 621 EWTI = RWORK(LEWT+I-1) 01721 CALL XERRWD('SLSODE- EWT(I1) is R1 .LE. 0.0 ', 01722 1 40, 21, 0, 1, I, 0, 1, EWTI, 0.0E0) 01723 GO TO 700 01724 622 CALL XERRWD( 01725 1 'SLSODE- TOUT (=R1) too close to T(=R2) to start integration', 01726 1 60, 22, 0, 0, 0, 0, 2, TOUT, T) 01727 GO TO 700 01728 623 CALL XERRWD( 01729 1 'SLSODE- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) ', 01730 1 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP) 01731 GO TO 700 01732 624 CALL XERRWD( 01733 1 'SLSODE- ITASK = 4 OR 5 and TCRIT (=R1) behind TCUR (=R2) ', 01734 1 60, 24, 0, 0, 0, 0, 2, TCRIT, TN) 01735 GO TO 700 01736 625 CALL XERRWD( 01737 1 'SLSODE- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) ', 01738 1 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT) 01739 GO TO 700 01740 626 CALL XERRWD('SLSODE- At start of problem, too much accuracy ', 01741 1 50, 26, 0, 0, 0, 0, 0, 0.0E0, 0.0E0) 01742 CALL XERRWD( 01743 1 ' requested for precision of machine.. See TOLSF (=R1) ', 01744 1 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0E0) 01745 RWORK(14) = TOLSF 01746 GO TO 700 01747 627 CALL XERRWD('SLSODE- Trouble in SINTDY. ITASK = I1, TOUT = R1', 01748 1 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0E0) 01749 C 01750 700 ISTATE = -3 01751 RETURN 01752 C 01753 800 CALL XERRWD('SLSODE- Run aborted.. apparent infinite loop ', 01754 1 50, 303, 2, 0, 0, 0, 0, 0.0E0, 0.0E0) 01755 RETURN 01756 C----------------------- END OF SUBROUTINE SLSODE ---------------------- 01757 END