slsode.f

Go to the documentation of this file.
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
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines