f2kodepack  Reference documentation for version 0.0
02_odepack_main.f90
Go to the documentation of this file.
1 ! ECK DLSODE
2 ! SUBROUTINE DLSODE (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK, &
3 ! ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF)
4 ! EXTERNAL F, JAC
5 ! INTEGER :: NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, MF
6 ! DOUBLE PRECISION :: Y, T, TOUT, RTOL, ATOL, RWORK
7 ! DIMENSION NEQ(*), Y(*), RTOL(*), ATOL(*), RWORK(LRW), IWORK(LIW)
8 !***BEGIN PROLOGUE DLSODE
9 !***PURPOSE Livermore Solver for Ordinary Differential Equations.
10 ! DLSODE solves the initial-value problem for stiff or
11 ! nonstiff systems of first-order ODE's,
12 ! dy/dt = f(t,y), or, in component form,
13 ! dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(N)), i=1,...,N.
14 !***CATEGORY I1A
15 !***TYPE DOUBLE PRECISION (SLSODE-S, DLSODE-D)
16 !***KEYWORDS ORDINARY DIFFERENTIAL EQUATIONS, INITIAL VALUE PROBLEM,
17 ! STIFF, NONSTIFF
18 !***AUTHOR Hindmarsh, Alan C., (LLNL)
19 ! Center for Applied Scientific Computing, L-561
20 ! Lawrence Livermore National Laboratory
21 ! Livermore, CA 94551.
22 !***DESCRIPTION
23 ! NOTE: The "Usage" and "Arguments" sections treat only a subset of
24 ! available options, in condensed fashion. The options
25 ! covered and the information supplied will support most
26 ! standard uses of DLSODE.
27 ! For more sophisticated uses, full details on all options are
28 ! given in the concluding section, headed "Long Description."
29 ! A synopsis of the DLSODE Long Description is provided at the
30 ! beginning of that section; general topics covered are:
31 ! - Elements of the call sequence; optional input and output
32 ! - Optional supplemental routines in the DLSODE package
33 ! - internal COMMON block
34 ! *Usage:
35 ! Communication between the user and the DLSODE package, for normal
36 ! situations, is summarized here. This summary describes a subset
37 ! of the available options. See "Long Description" for complete
38 ! details, including optional communication, nonstandard options,
39 ! and instructions for special situations.
40 ! A sample program is given in the "Examples" section.
41 ! Refer to the argument descriptions for the definitions of the
42 ! quantities that appear in the following sample declarations.
43 ! For MF = 10,
44 ! PARAMETER (LRW = 20 + 16*NEQ, LIW = 20)
45 ! For MF = 21 or 22,
46 ! PARAMETER (LRW = 22 + 9*NEQ + NEQ**2, LIW = 20 + NEQ)
47 ! For MF = 24 or 25,
48 ! PARAMETER (LRW = 22 + 10*NEQ + (2*ML+MU)*NEQ,
49 ! * LIW = 20 + NEQ)
50 ! EXTERNAL F, JAC
51 ! INTEGER NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK(LIW),
52 ! * LIW, MF
53 ! DOUBLE PRECISION Y(NEQ), T, TOUT, RTOL, ATOL(ntol), RWORK(LRW)
54 ! CALL DLSODE (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK,
55 ! * ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF)
56 ! *Arguments:
57 ! F :EXT Name of subroutine for right-hand-side vector f.
58 ! This name must be declared EXTERNAL in calling
59 ! program. The form of F must be:
60 ! SUBROUTINE F (NEQ, T, Y, YDOT)
61 ! INTEGER NEQ
62 ! DOUBLE PRECISION T, Y(*), YDOT(*)
63 ! The inputs are NEQ, T, Y. F is to set
64 ! YDOT(i) = f(i,T,Y(1),Y(2),...,Y(NEQ)),
65 ! i = 1, ..., NEQ .
66 ! NEQ :IN Number of first-order ODE's.
67 ! Y :INOUT Array of values of the y(t) vector, of length NEQ.
68 ! Input: For the first call, Y should contain the
69 ! values of y(t) at t = T. (Y is an input
70 ! variable only if ISTATE = 1.)
71 ! Output: On return, Y will contain the values at the
72 ! new t-value.
73 ! T :INOUT Value of the independent variable. On return it
74 ! will be the current value of t (normally TOUT).
75 ! TOUT :IN Next point where output is desired (.NE. T).
76 ! ITOL :IN 1 or 2 according as ATOL (below) is a scalar or
77 ! an array.
78 ! RTOL :IN Relative tolerance parameter (scalar).
79 ! ATOL :IN Absolute tolerance parameter (scalar or array).
80 ! If ITOL = 1, ATOL need not be dimensioned.
81 ! If ITOL = 2, ATOL must be dimensioned at least NEQ.
82 ! The estimated local error in Y(i) will be controlled
83 ! so as to be roughly less (in magnitude) than
84 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or
85 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2.
86 ! Thus the local error test passes if, in each
87 ! component, either the absolute error is less than
88 ! ATOL (or ATOL(i)), or the relative error is less
89 ! than RTOL.
90 ! Use RTOL = 0.0 for pure absolute error control, and
91 ! use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative
92 ! error control. Caution: Actual (global) errors may
93 ! exceed these local tolerances, so choose them
94 ! conservatively.
95 ! ITASK :IN Flag indicating the task DLSODE is to perform.
96 ! Use ITASK = 1 for normal computation of output
97 ! values of y at t = TOUT.
98 ! ISTATE:INOUT Index used for input and output to specify the state
99 ! of the calculation.
100 ! Input:
101 ! 1 This is the first call for a problem.
102 ! 2 This is a subsequent call.
103 ! Output:
104 ! 1 Nothing was done, because TOUT was equal to T.
105 ! 2 DLSODE was successful (otherwise, negative).
106 ! Note that ISTATE need not be modified after a
107 ! successful return.
108 ! -1 Excess work done on this call (perhaps wrong
109 ! MF).
110 ! -2 Excess accuracy requested (tolerances too
111 ! small).
112 ! -3 Illegal input detected (see printed message).
113 ! -4 Repeated error test failures (check all
114 ! inputs).
115 ! -5 Repeated convergence failures (perhaps bad
116 ! Jacobian supplied or wrong choice of MF or
117 ! tolerances).
118 ! -6 Error weight became zero during problem
119 ! (solution component i vanished, and ATOL or
120 ! ATOL(i) = 0.).
121 ! IOPT :IN Flag indicating whether optional inputs are used:
122 ! 0 No.
123 ! 1 Yes. (See "Optional inputs" under "Long
124 ! Description," Part 1.)
125 ! RWORK :WORK Real work array of length at least:
126 ! 20 + 16*NEQ for MF = 10,
127 ! 22 + 9*NEQ + NEQ**2 for MF = 21 or 22,
128 ! 22 + 10*NEQ + (2*ML + MU)*NEQ for MF = 24 or 25.
129 ! LRW :IN Declared length of RWORK (in user's DIMENSION
130 ! statement).
131 ! IWORK :WORK Integer work array of length at least:
132 ! 20 for MF = 10,
133 ! 20 + NEQ for MF = 21, 22, 24, or 25.
134 ! If MF = 24 or 25, input in IWORK(1),IWORK(2) the
135 ! lower and upper Jacobian half-bandwidths ML,MU.
136 ! On return, IWORK contains information that may be
137 ! of interest to the user:
138 ! Name Location Meaning
139 ! ----- --------- -----------------------------------------
140 ! NST IWORK(11) Number of steps taken for the problem so
141 ! far.
142 ! NFE IWORK(12) Number of f evaluations for the problem
143 ! so far.
144 ! NJE IWORK(13) Number of Jacobian evaluations (and of
145 ! matrix LU decompositions) for the problem
146 ! so far.
147 ! NQU IWORK(14) Method order last used (successfully).
148 ! LENRW IWORK(17) Length of RWORK actually required. This
149 ! is defined on normal returns and on an
150 ! illegal input return for insufficient
151 ! storage.
152 ! LENIW IWORK(18) Length of IWORK actually required. This
153 ! is defined on normal returns and on an
154 ! illegal input return for insufficient
155 ! storage.
156 ! LIW :IN Declared length of IWORK (in user's DIMENSION
157 ! statement).
158 ! JAC :EXT Name of subroutine for Jacobian matrix (MF =
159 ! 21 or 24). If used, this name must be declared
160 ! EXTERNAL in calling program. If not used, pass a
161 ! dummy name. The form of JAC must be:
162 ! SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
163 ! INTEGER NEQ, ML, MU, NROWPD
164 ! DOUBLE PRECISION T, Y(*), PD(NROWPD,*)
165 ! See item c, under "Description" below for more
166 ! information about JAC.
167 ! MF :IN Method flag. Standard values are:
168 ! 10 Nonstiff (Adams) method, no Jacobian used.
169 ! 21 Stiff (BDF) method, user-supplied full Jacobian.
170 ! 22 Stiff method, internally generated full
171 ! Jacobian.
172 ! 24 Stiff method, user-supplied banded Jacobian.
173 ! 25 Stiff method, internally generated banded
174 ! Jacobian.
175 ! *Description:
176 ! DLSODE solves the initial value problem for stiff or nonstiff
177 ! systems of first-order ODE's,
178 ! dy/dt = f(t,y) ,
179 ! or, in component form,
180 ! dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ))
181 ! (i = 1, ..., NEQ) .
182 ! DLSODE is a package based on the GEAR and GEARB packages, and on
183 ! the October 23, 1978, version of the tentative ODEPACK user
184 ! interface standard, with minor modifications.
185 ! The steps in solving such a problem are as follows.
186 ! a. First write a subroutine of the form
187 ! SUBROUTINE F (NEQ, T, Y, YDOT)
188 ! INTEGER NEQ
189 ! DOUBLE PRECISION T, Y(*), YDOT(*)
190 ! which supplies the vector function f by loading YDOT(i) with
191 ! f(i).
192 ! b. Next determine (or guess) whether or not the problem is stiff.
193 ! Stiffness occurs when the Jacobian matrix df/dy has an
194 ! eigenvalue whose real part is negative and large in magnitude
195 ! compared to the reciprocal of the t span of interest. If the
196 ! problem is nonstiff, use method flag MF = 10. If it is stiff,
197 ! there are four standard choices for MF, and DLSODE requires the
198 ! Jacobian matrix in some form. This matrix is regarded either
199 ! as full (MF = 21 or 22), or banded (MF = 24 or 25). In the
200 ! banded case, DLSODE requires two half-bandwidth parameters ML
201 ! and MU. These are, respectively, the widths of the lower and
202 ! upper parts of the band, excluding the main diagonal. Thus the
203 ! band consists of the locations (i,j) with
204 ! i - ML <= j <= i + MU ,
205 ! and the full bandwidth is ML + MU + 1 .
206 ! c. If the problem is stiff, you are encouraged to supply the
207 ! Jacobian directly (MF = 21 or 24), but if this is not feasible,
208 ! DLSODE will compute it internally by difference quotients (MF =
209 ! 22 or 25). If you are supplying the Jacobian, write a
210 ! subroutine of the form
211 ! SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
212 ! INTEGER NEQ, ML, MU, NRWOPD
213 ! DOUBLE PRECISION T, Y(*), PD(NROWPD,*)
214 ! which provides df/dy by loading PD as follows:
215 ! - For a full Jacobian (MF = 21), load PD(i,j) with df(i)/dy(j),
216 ! the partial derivative of f(i) with respect to y(j). (Ignore
217 ! the ML and MU arguments in this case.)
218 ! - For a banded Jacobian (MF = 24), load PD(i-j+MU+1,j) with
219 ! df(i)/dy(j); i.e., load the diagonal lines of df/dy into the
220 ! rows of PD from the top down.
221 ! - In either case, only nonzero elements need be loaded.
222 ! d. Write a main program that calls subroutine DLSODE once for each
223 ! point at which answers are desired. This should also provide
224 ! for possible use of logical unit 6 for output of error messages
225 ! by DLSODE.
226 ! Before the first call to DLSODE, set ISTATE = 1, set Y and T to
227 ! the initial values, and set TOUT to the first output point. To
228 ! continue the integration after a successful return, simply
229 ! reset TOUT and call DLSODE again. No other parameters need be
230 ! reset.
231 ! *Examples:
232 ! The following is a simple example problem, with the coding needed
233 ! for its solution by DLSODE. The problem is from chemical kinetics,
234 ! and consists of the following three rate equations:
235 ! dy1/dt = -.04*y1 + 1.E4*y2*y3
236 ! dy2/dt = .04*y1 - 1.E4*y2*y3 - 3.E7*y2**2
237 ! dy3/dt = 3.E7*y2**2
238 ! on the interval from t = 0.0 to t = 4.E10, with initial conditions
239 ! y1 = 1.0, y2 = y3 = 0. The problem is stiff.
240 ! The following coding solves this problem with DLSODE, using
241 ! MF = 21 and printing results at t = .4, 4., ..., 4.E10. It uses
242 ! ITOL = 2 and ATOL much smaller for y2 than for y1 or y3 because y2
243 ! has much smaller values. At the end of the run, statistical
244 ! quantities of interest are printed.
245 ! EXTERNAL FEX, JEX
246 ! INTEGER IOPT, IOUT, ISTATE, ITASK, ITOL, IWORK(23), LIW, LRW,
247 ! * MF, NEQ
248 ! DOUBLE PRECISION ATOL(3), RTOL, RWORK(58), T, TOUT, Y(3)
249 ! NEQ = 3
250 ! Y(1) = 1.D0
251 ! Y(2) = 0.D0
252 ! Y(3) = 0.D0
253 ! T = 0.D0
254 ! TOUT = .4D0
255 ! ITOL = 2
256 ! RTOL = 1.D-4
257 ! ATOL(1) = 1.D-6
258 ! ATOL(2) = 1.D-10
259 ! ATOL(3) = 1.D-6
260 ! ITASK = 1
261 ! ISTATE = 1
262 ! IOPT = 0
263 ! LRW = 58
264 ! LIW = 23
265 ! MF = 21
266 ! DO 40 IOUT = 1,12
267 ! CALL DLSODE (FEX, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK,
268 ! * ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JEX, MF)
269 ! WRITE(6,20) T, Y(1), Y(2), Y(3)
270 ! 20 FORMAT(' At t =',D12.4,' y =',3D14.6)
271 ! IF (ISTATE .LT. 0) GO TO 80
272 ! 40 TOUT = TOUT*10.D0
273 ! WRITE(6,60) IWORK(11), IWORK(12), IWORK(13)
274 ! 60 FORMAT(/' No. steps =',i4,', No. f-s =',i4,', No. J-s =',i4)
275 ! STOP
276 ! 80 WRITE(6,90) ISTATE
277 ! 90 FORMAT(///' Error halt.. ISTATE =',I3)
278 ! STOP
279 ! END
280 ! SUBROUTINE FEX (NEQ, T, Y, YDOT)
281 ! INTEGER NEQ
282 ! DOUBLE PRECISION T, Y(3), YDOT(3)
283 ! YDOT(1) = -.04D0*Y(1) + 1.D4*Y(2)*Y(3)
284 ! YDOT(3) = 3.D7*Y(2)*Y(2)
285 ! YDOT(2) = -YDOT(1) - YDOT(3)
286 ! RETURN
287 ! END
288 ! SUBROUTINE JEX (NEQ, T, Y, ML, MU, PD, NRPD)
289 ! INTEGER NEQ, ML, MU, NRPD
290 ! DOUBLE PRECISION T, Y(3), PD(NRPD,3)
291 ! PD(1,1) = -.04D0
292 ! PD(1,2) = 1.D4*Y(3)
293 ! PD(1,3) = 1.D4*Y(2)
294 ! PD(2,1) = .04D0
295 ! PD(2,3) = -PD(1,3)
296 ! PD(3,2) = 6.D7*Y(2)
297 ! PD(2,2) = -PD(1,2) - PD(3,2)
298 ! RETURN
299 ! END
300 ! The output from this program (on a Cray-1 in single precision)
301 ! is as follows.
302 ! At t = 4.0000e-01 y = 9.851726e-01 3.386406e-05 1.479357e-02
303 ! At t = 4.0000e+00 y = 9.055142e-01 2.240418e-05 9.446344e-02
304 ! At t = 4.0000e+01 y = 7.158050e-01 9.184616e-06 2.841858e-01
305 ! At t = 4.0000e+02 y = 4.504846e-01 3.222434e-06 5.495122e-01
306 ! At t = 4.0000e+03 y = 1.831701e-01 8.940379e-07 8.168290e-01
307 ! At t = 4.0000e+04 y = 3.897016e-02 1.621193e-07 9.610297e-01
308 ! At t = 4.0000e+05 y = 4.935213e-03 1.983756e-08 9.950648e-01
309 ! At t = 4.0000e+06 y = 5.159269e-04 2.064759e-09 9.994841e-01
310 ! At t = 4.0000e+07 y = 5.306413e-05 2.122677e-10 9.999469e-01
311 ! At t = 4.0000e+08 y = 5.494530e-06 2.197825e-11 9.999945e-01
312 ! At t = 4.0000e+09 y = 5.129458e-07 2.051784e-12 9.999995e-01
313 ! At t = 4.0000e+10 y = -7.170603e-08 -2.868241e-13 1.000000e+00
314 ! No. steps = 330, No. f-s = 405, No. J-s = 69
315 ! *Accuracy:
316 ! The accuracy of the solution depends on the choice of tolerances
317 ! RTOL and ATOL. Actual (global) errors may exceed these local
318 ! tolerances, so choose them conservatively.
319 ! *Cautions:
320 ! The work arrays should not be altered between calls to DLSODE for
321 ! the same problem, except possibly for the conditional and optional
322 ! inputs.
323 ! *Portability:
324 ! Since NEQ is dimensioned inside DLSODE, some compilers may object
325 ! to a call to DLSODE with NEQ a scalar variable. In this event,
326 ! use DIMENSION NEQ(1). Similar remarks apply to RTOL and ATOL.
327 ! Note to Cray users:
328 ! For maximum efficiency, use the CFT77 compiler. Appropriate
329 ! compiler optimization directives have been inserted for CFT77.
330 ! *Reference:
331 ! Alan C. Hindmarsh, "ODEPACK, A Systematized Collection of ODE
332 ! Solvers," in Scientific Computing, R. S. Stepleman, et al., Eds.
333 ! (North-Holland, Amsterdam, 1983), pp. 55-64.
334 ! *Long Description:
335 ! The following complete description of the user interface to
336 ! DLSODE consists of four parts:
337 ! 1. The call sequence to subroutine DLSODE, which is a driver
338 ! routine for the solver. This includes descriptions of both
339 ! the call sequence arguments and user-supplied routines.
340 ! Following these descriptions is a description of optional
341 ! inputs available through the call sequence, and then a
342 ! description of optional outputs in the work arrays.
343 ! 2. Descriptions of other routines in the DLSODE package that may
344 ! be (optionally) called by the user. These provide the ability
345 ! to alter error message handling, save and restore the internal
346 ! COMMON, and obtain specified derivatives of the solution y(t).
347 ! 3. Descriptions of COMMON block to be declared in overlay or
348 ! similar environments, or to be saved when doing an interrupt
349 ! of the problem and continued solution later.
350 ! 4. Description of two routines in the DLSODE package, either of
351 ! which the user may replace with his own version, if desired.
352 ! These relate to the measurement of errors.
353 ! Part 1. Call Sequence
354 ! ----------------------
355 ! Arguments
356 ! ---------
357 ! The call sequence parameters used for input only are
358 ! F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC, MF,
359 ! and those used for both input and output are
360 ! Y, T, ISTATE.
361 ! The work arrays RWORK and IWORK are also used for conditional and
362 ! optional inputs and optional outputs. (The term output here
363 ! refers to the return from subroutine DLSODE to the user's calling
364 ! program.)
365 ! The legality of input parameters will be thoroughly checked on the
366 ! initial call for the problem, but not checked thereafter unless a
367 ! change in input parameters is flagged by ISTATE = 3 on input.
368 ! The descriptions of the call arguments are as follows.
369 ! F The name of the user-supplied subroutine defining the ODE
370 ! system. The system must be put in the first-order form
371 ! dy/dt = f(t,y), where f is a vector-valued function of
372 ! the scalar t and the vector y. Subroutine F is to compute
373 ! the function f. It is to have the form
374 ! SUBROUTINE F (NEQ, T, Y, YDOT)
375 ! DOUBLE PRECISION T, Y(*), YDOT(*)
376 ! where NEQ, T, and Y are input, and the array YDOT =
377 ! f(T,Y) is output. Y and YDOT are arrays of length NEQ.
378 ! Subroutine F should not alter Y(1),...,Y(NEQ). F must be
379 ! declared EXTERNAL in the calling program.
380 ! Subroutine F may access user-defined quantities in
381 ! NEQ(2),... and/or in Y(NEQ(1)+1),..., if NEQ is an array
382 ! (dimensioned in F) and/or Y has length exceeding NEQ(1).
383 ! See the descriptions of NEQ and Y below.
384 ! If quantities computed in the F routine are needed
385 ! externally to DLSODE, an extra call to F should be made
386 ! for this purpose, for consistent and accurate results.
387 ! If only the derivative dy/dt is needed, use DINTDY
388 ! instead.
389 ! NEQ The size of the ODE system (number of first-order
390 ! ordinary differential equations). Used only for input.
391 ! NEQ may be decreased, but not increased, during the
392 ! problem. If NEQ is decreased (with ISTATE = 3 on input),
393 ! the remaining components of Y should be left undisturbed,
394 ! if these are to be accessed in F and/or JAC.
395 ! Normally, NEQ is a scalar, and it is generally referred
396 ! to as a scalar in this user interface description.
397 ! However, NEQ may be an array, with NEQ(1) set to the
398 ! system size. (The DLSODE package accesses only NEQ(1).)
399 ! In either case, this parameter is passed as the NEQ
400 ! argument in all calls to F and JAC. Hence, if it is an
401 ! array, locations NEQ(2),... may be used to store other
402 ! integer data and pass it to F and/or JAC. Subroutines
403 ! F and/or JAC must include NEQ in a DIMENSION statement
404 ! in that case.
405 ! Y A real array for the vector of dependent variables, of
406 ! length NEQ or more. Used for both input and output on
407 ! the first call (ISTATE = 1), and only for output on
408 ! other calls. On the first call, Y must contain the
409 ! vector of initial values. On output, Y contains the
410 ! computed solution vector, evaluated at T. If desired,
411 ! the Y array may be used for other purposes between
412 ! calls to the solver.
413 ! This array is passed as the Y argument in all calls to F
414 ! and JAC. Hence its length may exceed NEQ, and locations
415 ! Y(NEQ+1),... may be used to store other real data and
416 ! pass it to F and/or JAC. (The DLSODE package accesses
417 ! only Y(1),...,Y(NEQ).)
418 ! T The independent variable. On input, T is used only on
419 ! the first call, as the initial point of the integration.
420 ! On output, after each call, T is the value at which a
421 ! computed solution Y is evaluated (usually the same as
422 ! TOUT). On an error return, T is the farthest point
423 ! reached.
424 ! TOUT The next value of T at which a computed solution is
425 ! desired. Used only for input.
426 ! When starting the problem (ISTATE = 1), TOUT may be equal
427 ! to T for one call, then should not equal T for the next
428 ! call. For the initial T, an input value of TOUT .NE. T
429 ! is used in order to determine the direction of the
430 ! integration (i.e., the algebraic sign of the step sizes)
431 ! and the rough scale of the problem. Integration in
432 ! either direction (forward or backward in T) is permitted.
433 ! If ITASK = 2 or 5 (one-step modes), TOUT is ignored
434 ! after the first call (i.e., the first call with
435 ! TOUT .NE. T). Otherwise, TOUT is required on every call.
436 ! If ITASK = 1, 3, or 4, the values of TOUT need not be
437 ! monotone, but a value of TOUT which backs up is limited
438 ! to the current internal T interval, whose endpoints are
439 ! TCUR - HU and TCUR. (See "Optional Outputs" below for
440 ! TCUR and HU.)
441 ! ITOL An indicator for the type of error control. See
442 ! description below under ATOL. Used only for input.
443 ! RTOL A relative error tolerance parameter, either a scalar or
444 ! an array of length NEQ. See description below under
445 ! ATOL. Input only.
446 ! ATOL An absolute error tolerance parameter, either a scalar or
447 ! an array of length NEQ. Input only.
448 ! The input parameters ITOL, RTOL, and ATOL determine the
449 ! error control performed by the solver. The solver will
450 ! control the vector e = (e(i)) of estimated local errors
451 ! in Y, according to an inequality of the form
452 ! rms-norm of ( e(i)/EWT(i) ) <= 1,
453 ! where
454 ! EWT(i) = RTOL(i)*ABS(Y(i)) + ATOL(i),
455 ! and the rms-norm (root-mean-square norm) here is
456 ! rms-norm(v) = SQRT(sum v(i)**2 / NEQ).
457 ! Here EWT = (EWT(i)) is a vector of weights which must
458 ! always be positive, and the values of RTOL and ATOL
459 ! should all be nonnegative. The following table gives the
460 ! types (scalar/array) of RTOL and ATOL, and the
461 ! corresponding form of EWT(i).
462 ! ITOL RTOL ATOL EWT(i)
463 ! ---- ------ ------ -----------------------------
464 ! 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
465 ! 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
466 ! 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
467 ! 4 array array RTOL(i)*ABS(Y(i)) + ATOL(i)
468 ! When either of these parameters is a scalar, it need not
469 ! be dimensioned in the user's calling program.
470 ! If none of the above choices (with ITOL, RTOL, and ATOL
471 ! fixed throughout the problem) is suitable, more general
472 ! error controls can be obtained by substituting
473 ! user-supplied routines for the setting of EWT and/or for
474 ! the norm calculation. See Part 4 below.
475 ! If global errors are to be estimated by making a repeated
476 ! run on the same problem with smaller tolerances, then all
477 ! components of RTOL and ATOL (i.e., of EWT) should be
478 ! scaled down uniformly.
479 ! ITASK An index specifying the task to be performed. Input
480 ! only. ITASK has the following values and meanings:
481 ! 1 Normal computation of output values of y(t) at
482 ! t = TOUT (by overshooting and interpolating).
483 ! 2 Take one step only and return.
484 ! 3 Stop at the first internal mesh point at or beyond
485 ! t = TOUT and return.
486 ! 4 Normal computation of output values of y(t) at
487 ! t = TOUT but without overshooting t = TCRIT. TCRIT
488 ! must be input as RWORK(1). TCRIT may be equal to or
489 ! beyond TOUT, but not behind it in the direction of
490 ! integration. This option is useful if the problem
491 ! has a singularity at or beyond t = TCRIT.
492 ! 5 Take one step, without passing TCRIT, and return.
493 ! TCRIT must be input as RWORK(1).
494 ! Note: If ITASK = 4 or 5 and the solver reaches TCRIT
495 ! (within roundoff), it will return T = TCRIT (exactly) to
496 ! indicate this (unless ITASK = 4 and TOUT comes before
497 ! TCRIT, in which case answers at T = TOUT are returned
498 ! first).
499 ! ISTATE An index used for input and output to specify the state
500 ! of the calculation.
501 ! On input, the values of ISTATE are as follows:
502 ! 1 This is the first call for the problem
503 ! (initializations will be done). See "Note" below.
504 ! 2 This is not the first call, and the calculation is to
505 ! continue normally, with no change in any input
506 ! parameters except possibly TOUT and ITASK. (If ITOL,
507 ! RTOL, and/or ATOL are changed between calls with
508 ! ISTATE = 2, the new values will be used but not
509 ! tested for legality.)
510 ! 3 This is not the first call, and the calculation is to
511 ! continue normally, but with a change in input
512 ! parameters other than TOUT and ITASK. Changes are
513 ! allowed in NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF,
514 ! ML, MU, and any of the optional inputs except H0.
515 ! (See IWORK description for ML and MU.)
516 ! Note: A preliminary call with TOUT = T is not counted as
517 ! a first call here, as no initialization or checking of
518 ! input is done. (Such a call is sometimes useful for the
519 ! purpose of outputting the initial conditions.) Thus the
520 ! first call for which TOUT .NE. T requires ISTATE = 1 on
521 ! input.
522 ! On output, ISTATE has the following values and meanings:
523 ! 1 Nothing was done, as TOUT was equal to T with
524 ! ISTATE = 1 on input.
525 ! 2 The integration was performed successfully.
526 ! -1 An excessive amount of work (more than MXSTEP steps)
527 ! was done on this call, before completing the
528 ! requested task, but the integration was otherwise
529 ! successful as far as T. (MXSTEP is an optional input
530 ! and is normally 500.) To continue, the user may
531 ! simply reset ISTATE to a value >1 and call again (the
532 ! excess work step counter will be reset to 0). In
533 ! addition, the user may increase MXSTEP to avoid this
534 ! error return; see "Optional Inputs" below.
535 ! -2 Too much accuracy was requested for the precision of
536 ! the machine being used. This was detected before
537 ! completing the requested task, but the integration
538 ! was successful as far as T. To continue, the
539 ! tolerance parameters must be reset, and ISTATE must
540 ! be set to 3. The optional output TOLSF may be used
541 ! for this purpose. (Note: If this condition is
542 ! detected before taking any steps, then an illegal
543 ! input return (ISTATE = -3) occurs instead.)
544 ! -3 Illegal input was detected, before taking any
545 ! integration steps. See written message for details.
546 ! (Note: If the solver detects an infinite loop of
547 ! calls to the solver with illegal input, it will cause
548 ! the run to stop.)
549 ! -4 There were repeated error-test failures on one
550 ! attempted step, before completing the requested task,
551 ! but the integration was successful as far as T. The
552 ! problem may have a singularity, or the input may be
553 ! inappropriate.
554 ! -5 There were repeated convergence-test failures on one
555 ! attempted step, before completing the requested task,
556 ! but the integration was successful as far as T. This
557 ! may be caused by an inaccurate Jacobian matrix, if
558 ! one is being used.
559 ! -6 EWT(i) became zero for some i during the integration.
560 ! Pure relative error control (ATOL(i)=0.0) was
561 ! requested on a variable which has now vanished. The
562 ! integration was successful as far as T.
563 ! Note: Since the normal output value of ISTATE is 2, it
564 ! does not need to be reset for normal continuation. Also,
565 ! since a negative input value of ISTATE will be regarded
566 ! as illegal, a negative output value requires the user to
567 ! change it, and possibly other inputs, before calling the
568 ! solver again.
569 ! IOPT An integer flag to specify whether any optional inputs
570 ! are being used on this call. Input only. The optional
571 ! inputs are listed under a separate heading below.
572 ! 0 No optional inputs are being used. Default values
573 ! will be used in all cases.
574 ! 1 One or more optional inputs are being used.
575 ! RWORK A real working array (double precision). The length of
576 ! RWORK must be at least
577 ! 20 + NYH*(MAXORD + 1) + 3*NEQ + LWM
578 ! where
579 ! NYH = the initial value of NEQ,
580 ! MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a
581 ! smaller value is given as an optional input),
582 ! LWM = 0 if MITER = 0,
583 ! LWM = NEQ**2 + 2 if MITER = 1 or 2,
584 ! LWM = NEQ + 2 if MITER = 3, and
585 ! LWM = (2*ML + MU + 1)*NEQ + 2
586 ! if MITER = 4 or 5.
587 ! (See the MF description below for METH and MITER.)
588 ! Thus if MAXORD has its default value and NEQ is constant,
589 ! this length is:
590 ! 20 + 16*NEQ for MF = 10,
591 ! 22 + 16*NEQ + NEQ**2 for MF = 11 or 12,
592 ! 22 + 17*NEQ for MF = 13,
593 ! 22 + 17*NEQ + (2*ML + MU)*NEQ for MF = 14 or 15,
594 ! 20 + 9*NEQ for MF = 20,
595 ! 22 + 9*NEQ + NEQ**2 for MF = 21 or 22,
596 ! 22 + 10*NEQ for MF = 23,
597 ! 22 + 10*NEQ + (2*ML + MU)*NEQ for MF = 24 or 25.
598 ! The first 20 words of RWORK are reserved for conditional
599 ! and optional inputs and optional outputs.
600 ! The following word in RWORK is a conditional input:
601 ! RWORK(1) = TCRIT, the critical value of t which the
602 ! solver is not to overshoot. Required if ITASK
603 ! is 4 or 5, and ignored otherwise. See ITASK.
604 ! LRW The length of the array RWORK, as declared by the user.
605 ! (This will be checked by the solver.)
606 ! IWORK An integer work array. Its length must be at least
607 ! 20 if MITER = 0 or 3 (MF = 10, 13, 20, 23), or
608 ! 20 + NEQ otherwise (MF = 11, 12, 14, 15, 21, 22, 24, 25).
609 ! (See the MF description below for MITER.) The first few
610 ! words of IWORK are used for conditional and optional
611 ! inputs and optional outputs.
612 ! The following two words in IWORK are conditional inputs:
613 ! IWORK(1) = ML These are the lower and upper half-
614 ! IWORK(2) = MU bandwidths, respectively, of the banded
615 ! Jacobian, excluding the main diagonal.
616 ! The band is defined by the matrix locations
617 ! (i,j) with i - ML <= j <= i + MU. ML and MU
618 ! must satisfy 0 <= ML,MU <= NEQ - 1. These are
619 ! required if MITER is 4 or 5, and ignored
620 ! otherwise. ML and MU may in fact be the band
621 ! parameters for a matrix to which df/dy is only
622 ! approximately equal.
623 ! LIW The length of the array IWORK, as declared by the user.
624 ! (This will be checked by the solver.)
625 ! Note: The work arrays must not be altered between calls to DLSODE
626 ! for the same problem, except possibly for the conditional and
627 ! optional inputs, and except for the last 3*NEQ words of RWORK.
628 ! The latter space is used for internal scratch space, and so is
629 ! available for use by the user outside DLSODE between calls, if
630 ! desired (but not for use by F or JAC).
631 ! JAC The name of the user-supplied routine (MITER = 1 or 4) to
632 ! compute the Jacobian matrix, df/dy, as a function of the
633 ! scalar t and the vector y. (See the MF description below
634 ! for MITER.) It is to have the form
635 ! SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
636 ! DOUBLE PRECISION T, Y(*), PD(NROWPD,*)
637 ! where NEQ, T, Y, ML, MU, and NROWPD are input and the
638 ! array PD is to be loaded with partial derivatives
639 ! (elements of the Jacobian matrix) on output. PD must be
640 ! given a first dimension of NROWPD. T and Y have the same
641 ! meaning as in subroutine F.
642 ! In the full matrix case (MITER = 1), ML and MU are
643 ! ignored, and the Jacobian is to be loaded into PD in
644 ! columnwise manner, with df(i)/dy(j) loaded into PD(i,j).
645 ! In the band matrix case (MITER = 4), the elements within
646 ! the band are to be loaded into PD in columnwise manner,
647 ! with diagonal lines of df/dy loaded into the rows of PD.
648 ! Thus df(i)/dy(j) is to be loaded into PD(i-j+MU+1,j). ML
649 ! and MU are the half-bandwidth parameters (see IWORK).
650 ! The locations in PD in the two triangular areas which
651 ! correspond to nonexistent matrix elements can be ignored
652 ! or loaded arbitrarily, as they are overwritten by DLSODE.
653 ! JAC need not provide df/dy exactly. A crude approximation
654 ! (possibly with a smaller bandwidth) will do.
655 ! In either case, PD is preset to zero by the solver, so
656 ! that only the nonzero elements need be loaded by JAC.
657 ! Each call to JAC is preceded by a call to F with the same
658 ! arguments NEQ, T, and Y. Thus to gain some efficiency,
659 ! intermediate quantities shared by both calculations may
660 ! be saved in a user COMMON block by F and not recomputed
661 ! by JAC, if desired. Also, JAC may alter the Y array, if
662 ! desired. JAC must be declared EXTERNAL in the calling
663 ! program.
664 ! Subroutine JAC may access user-defined quantities in
665 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
666 ! (dimensioned in JAC) and/or Y has length exceeding
667 ! NEQ(1). See the descriptions of NEQ and Y above.
668 ! MF The method flag. Used only for input. The legal values
669 ! of MF are 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24,
670 ! and 25. MF has decimal digits METH and MITER:
671 ! MF = 10*METH + MITER .
672 ! METH indicates the basic linear multistep method:
673 ! 1 Implicit Adams method.
674 ! 2 Method based on backward differentiation formulas
675 ! (BDF's).
676 ! MITER indicates the corrector iteration method:
677 ! 0 Functional iteration (no Jacobian matrix is
678 ! involved).
679 ! 1 Chord iteration with a user-supplied full (NEQ by
680 ! NEQ) Jacobian.
681 ! 2 Chord iteration with an internally generated
682 ! (difference quotient) full Jacobian (using NEQ
683 ! extra calls to F per df/dy value).
684 ! 3 Chord iteration with an internally generated
685 ! diagonal Jacobian approximation (using one extra call
686 ! to F per df/dy evaluation).
687 ! 4 Chord iteration with a user-supplied banded Jacobian.
688 ! 5 Chord iteration with an internally generated banded
689 ! Jacobian (using ML + MU + 1 extra calls to F per
690 ! df/dy evaluation).
691 ! If MITER = 1 or 4, the user must supply a subroutine JAC
692 ! (the name is arbitrary) as described above under JAC.
693 ! For other values of MITER, a dummy argument can be used.
694 ! Optional Inputs
695 ! ---------------
696 ! The following is a list of the optional inputs provided for in the
697 ! call sequence. (See also Part 2.) For each such input variable,
698 ! this table lists its name as used in this documentation, its
699 ! location in the call sequence, its meaning, and the default value.
700 ! The use of any of these inputs requires IOPT = 1, and in that case
701 ! all of these inputs are examined. A value of zero for any of
702 ! these optional inputs will cause the default value to be used.
703 ! Thus to use a subset of the optional inputs, simply preload
704 ! locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively,
705 ! and then set those of interest to nonzero values.
706 ! Name Location Meaning and default value
707 ! ------ --------- -----------------------------------------------
708 ! H0 RWORK(5) Step size to be attempted on the first step.
709 ! The default value is determined by the solver.
710 ! HMAX RWORK(6) Maximum absolute step size allowed. The
711 ! default value is infinite.
712 ! HMIN RWORK(7) Minimum absolute step size allowed. The
713 ! default value is 0. (This lower bound is not
714 ! enforced on the final step before reaching
715 ! TCRIT when ITASK = 4 or 5.)
716 ! MAXORD IWORK(5) Maximum order to be allowed. The default value
717 ! is 12 if METH = 1, and 5 if METH = 2. (See the
718 ! MF description above for METH.) If MAXORD
719 ! exceeds the default value, it will be reduced
720 ! to the default value. If MAXORD is changed
721 ! during the problem, it may cause the current
722 ! order to be reduced.
723 ! MXSTEP IWORK(6) Maximum number of (internally defined) steps
724 ! allowed during one call to the solver. The
725 ! default value is 500.
726 ! MXHNIL IWORK(7) Maximum number of messages printed (per
727 ! problem) warning that T + H = T on a step
728 ! (H = step size). This must be positive to
729 ! result in a nondefault value. The default
730 ! value is 10.
731 ! Optional Outputs
732 ! ----------------
733 ! As optional additional output from DLSODE, the variables listed
734 ! below are quantities related to the performance of DLSODE which
735 ! are available to the user. These are communicated by way of the
736 ! work arrays, but also have internal mnemonic names as shown.
737 ! Except where stated otherwise, all of these outputs are defined on
738 ! any successful return from DLSODE, and on any return with ISTATE =
739 ! -1, -2, -4, -5, or -6. On an illegal input return (ISTATE = -3),
740 ! they will be unchanged from their existing values (if any), except
741 ! possibly for TOLSF, LENRW, and LENIW. On any error return,
742 ! outputs relevant to the error will be defined, as noted below.
743 ! Name Location Meaning
744 ! ----- --------- ------------------------------------------------
745 ! HU RWORK(11) Step size in t last used (successfully).
746 ! HCUR RWORK(12) Step size to be attempted on the next step.
747 ! TCUR RWORK(13) Current value of the independent variable which
748 ! the solver has actually reached, i.e., the
749 ! current internal mesh point in t. On output,
750 ! TCUR will always be at least as far as the
751 ! argument T, but may be farther (if interpolation
752 ! was done).
753 ! TOLSF RWORK(14) Tolerance scale factor, greater than 1.0,
754 ! computed when a request for too much accuracy
755 ! was detected (ISTATE = -3 if detected at the
756 ! start of the problem, ISTATE = -2 otherwise).
757 ! If ITOL is left unaltered but RTOL and ATOL are
758 ! uniformly scaled up by a factor of TOLSF for the
759 ! next call, then the solver is deemed likely to
760 ! succeed. (The user may also ignore TOLSF and
761 ! alter the tolerance parameters in any other way
762 ! appropriate.)
763 ! NST IWORK(11) Number of steps taken for the problem so far.
764 ! NFE IWORK(12) Number of F evaluations for the problem so far.
765 ! NJE IWORK(13) Number of Jacobian evaluations (and of matrix LU
766 ! decompositions) for the problem so far.
767 ! NQU IWORK(14) Method order last used (successfully).
768 ! NQCUR IWORK(15) Order to be attempted on the next step.
769 ! IMXER IWORK(16) Index of the component of largest magnitude in
770 ! the weighted local error vector ( e(i)/EWT(i) ),
771 ! on an error return with ISTATE = -4 or -5.
772 ! LENRW IWORK(17) Length of RWORK actually required. This is
773 ! defined on normal returns and on an illegal
774 ! input return for insufficient storage.
775 ! LENIW IWORK(18) Length of IWORK actually required. This is
776 ! defined on normal returns and on an illegal
777 ! input return for insufficient storage.
778 ! The following two arrays are segments of the RWORK array which may
779 ! also be of interest to the user as optional outputs. For each
780 ! array, the table below gives its internal name, its base address
781 ! in RWORK, and its description.
782 ! Name Base address Description
783 ! ---- ------------ ----------------------------------------------
784 ! YH 21 The Nordsieck history array, of size NYH by
785 ! (NQCUR + 1), where NYH is the initial value of
786 ! NEQ. For j = 0,1,...,NQCUR, column j + 1 of
787 ! YH contains HCUR**j/factorial(j) times the jth
788 ! derivative of the interpolating polynomial
789 ! currently representing the solution, evaluated
790 ! at t = TCUR.
791 ! ACOR LENRW-NEQ+1 Array of size NEQ used for the accumulated
792 ! corrections on each step, scaled on output to
793 ! represent the estimated local error in Y on
794 ! the last step. This is the vector e in the
795 ! description of the error control. It is
796 ! defined only on successful return from DLSODE.
797 ! Part 2. Other Callable Routines
798 ! --------------------------------
799 ! The following are optional calls which the user may make to gain
800 ! additional capabilities in conjunction with DLSODE.
801 ! Form of call Function
802 ! ------------------------ ----------------------------------------
803 ! CALL XSETUN(LUN) Set the logical unit number, LUN, for
804 ! output of messages from DLSODE, if the
805 ! default is not desired. The default
806 ! value of LUN is 6. This call may be made
807 ! at any time and will take effect
808 ! immediately.
809 ! CALL XSETF(MFLAG) Set a flag to control the printing of
810 ! messages by DLSODE. MFLAG = 0 means do
811 ! not print. (Danger: this risks losing
812 ! valuable information.) MFLAG = 1 means
813 ! print (the default). This call may be
814 ! made at any time and will take effect
815 ! immediately.
816 ! CALL DSRCOM(RSAV,ISAV,JOB) Saves and restores the contents of the
817 ! internal COMMON blocks used by DLSODE
818 ! (see Part 3 below). RSAV must be a
819 ! real array of length 218 or more, and
820 ! ISAV must be an integer array of length
821 ! 37 or more. JOB = 1 means save COMMON
822 ! into RSAV/ISAV. JOB = 2 means restore
823 ! COMMON from same. DSRCOM is useful if
824 ! one is interrupting a run and restarting
825 ! later, or alternating between two or
826 ! more problems solved with DLSODE.
827 ! CALL DINTDY(,,,,,) Provide derivatives of y, of various
828 ! (see below) orders, at a specified point t, if
829 ! desired. It may be called only after a
830 ! successful return from DLSODE. Detailed
831 ! instructions follow.
832 ! Detailed instructions for using DINTDY
833 ! --------------------------------------
834 ! The form of the CALL is:
835 ! CALL DINTDY (T, K, RWORK(21), NYH, DKY, IFLAG)
836 ! The input parameters are:
837 ! T Value of independent variable where answers are
838 ! desired (normally the same as the T last returned by
839 ! DLSODE). For valid results, T must lie between
840 ! TCUR - HU and TCUR. (See "Optional Outputs" above
841 ! for TCUR and HU.)
842 ! K Integer order of the derivative desired. K must
843 ! satisfy 0 <= K <= NQCUR, where NQCUR is the current
844 ! order (see "Optional Outputs"). The capability
845 ! corresponding to K = 0, i.e., computing y(t), is
846 ! already provided by DLSODE directly. Since
847 ! NQCUR >= 1, the first derivative dy/dt is always
848 ! available with DINTDY.
849 ! RWORK(21) The base address of the history array YH.
850 ! NYH Column length of YH, equal to the initial value of NEQ.
851 ! The output parameters are:
852 ! DKY Real array of length NEQ containing the computed value
853 ! of the Kth derivative of y(t).
854 ! IFLAG Integer flag, returned as 0 if K and T were legal,
855 ! -1 if K was illegal, and -2 if T was illegal.
856 ! On an error return, a message is also written.
857 ! Part 3. Common Blocks
858 ! ----------------------
859 ! If DLSODE is to be used in an overlay situation, the user must
860 ! declare, in the primary overlay, the variables in:
861 ! (1) the call sequence to DLSODE,
862 ! (2) the internal COMMON block /DLS001/, of length 255
863 ! (218 double precision words followed by 37 integer words).
864 ! If DLSODE is used on a system in which the contents of internal
865 ! COMMON blocks are not preserved between calls, the user should
866 ! declare the above COMMON block in his main program to insure that
867 ! its contents are preserved.
868 ! If the solution of a given problem by DLSODE is to be interrupted
869 ! and then later continued, as when restarting an interrupted run or
870 ! alternating between two or more problems, the user should save,
871 ! following the return from the last DLSODE call prior to the
872 ! interruption, the contents of the call sequence variables and the
873 ! internal COMMON block, and later restore these values before the
874 ! next DLSODE call for that problem. In addition, if XSETUN and/or
875 ! XSETF was called for non-default handling of error messages, then
876 ! these calls must be repeated. To save and restore the COMMON
877 ! block, use subroutine DSRCOM (see Part 2 above).
878 ! Part 4. Optionally Replaceable Solver Routines
879 ! -----------------------------------------------
880 ! Below are descriptions of two routines in the DLSODE package which
881 ! relate to the measurement of errors. Either routine can be
882 ! replaced by a user-supplied version, if desired. However, since
883 ! such a replacement may have a major impact on performance, it
884 ! should be done only when absolutely necessary, and only with great
885 ! caution. (Note: The means by which the package version of a
886 ! routine is superseded by the user's version may be system-
887 ! dependent.)
888 ! DEWSET
889 ! ------
890 ! The following subroutine is called just before each internal
891 ! integration step, and sets the array of error weights, EWT, as
892 ! described under ITOL/RTOL/ATOL above:
893 ! SUBROUTINE DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
894 ! where NEQ, ITOL, RTOL, and ATOL are as in the DLSODE call
895 ! sequence, YCUR contains the current dependent variable vector,
896 ! and EWT is the array of weights set by DEWSET.
897 ! If the user supplies this subroutine, it must return in EWT(i)
898 ! (i = 1,...,NEQ) a positive quantity suitable for comparing errors
899 ! in Y(i) to. The EWT array returned by DEWSET is passed to the
900 ! DVNORM routine (see below), and also used by DLSODE in the
901 ! computation of the optional output IMXER, the diagonal Jacobian
902 ! approximation, and the increments for difference quotient
903 ! Jacobians.
904 ! In the user-supplied version of DEWSET, it may be desirable to use
905 ! the current values of derivatives of y. Derivatives up to order NQ
906 ! are available from the history array YH, described above under
907 ! optional outputs. In DEWSET, YH is identical to the YCUR array,
908 ! extended to NQ + 1 columns with a column length of NYH and scale
909 ! factors of H**j/factorial(j). On the first call for the problem,
910 ! given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
911 ! NYH is the initial value of NEQ. The quantities NQ, H, and NST
912 ! can be obtained by including in SEWSET the statements:
913 ! DOUBLE PRECISION RLS
914 ! COMMON /DLS001/ RLS(218),ILS(37)
915 ! NQ = ILS(33)
916 ! NST = ILS(34)
917 ! H = RLS(212)
918 ! Thus, for example, the current value of dy/dt can be obtained as
919 ! YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is unnecessary
920 ! when NST = 0).
921 ! DVNORM
922 ! ------
923 ! DVNORM is a real function routine which computes the weighted
924 ! root-mean-square norm of a vector v:
925 ! d = DVNORM (n, v, w)
926 ! where:
927 ! n = the length of the vector,
928 ! v = real array of length n containing the vector,
929 ! w = real array of length n containing weights,
930 ! d = SQRT( (1/n) * sum(v(i)*w(i))**2 ).
931 ! DVNORM is called with n = NEQ and with w(i) = 1.0/EWT(i), where
932 ! EWT is as set by subroutine DEWSET.
933 ! If the user supplies this function, it should return a nonnegative
934 ! value of DVNORM suitable for use in the error control in DLSODE.
935 ! None of the arguments should be altered by DVNORM. For example, a
936 ! user-supplied DVNORM routine might:
937 ! - Substitute a max-norm of (v(i)*w(i)) for the rms-norm, or
938 ! - Ignore some components of v in the norm, with the effect of
939 ! suppressing the error control on those components of Y.
940 ! ---------------------------------------------------------------------
941 !***ROUTINES CALLED DEWSET, DINTDY, DUMACH, DSTODE, DVNORM, XERRWD
942 !***COMMON BLOCKS DLS001
943 !***REVISION HISTORY (YYYYMMDD)
944 ! 19791129 DATE WRITTEN
945 ! 19791213 Minor changes to declarations; DELP init. in STODE.
946 ! 19800118 Treat NEQ as array; integer declarations added throughout;
947 ! minor changes to prologue.
948 ! 19800306 Corrected TESCO(1,NQP1) setting in CFODE.
949 ! 19800519 Corrected access of YH on forced order reduction;
950 ! numerous corrections to prologues and other comments.
951 ! 19800617 In main driver, added loading of SQRT(UROUND) in RWORK;
952 ! minor corrections to main prologue.
953 ! 19800923 Added zero initialization of HU and NQU.
954 ! 19801218 Revised XERRWD routine; minor corrections to main prologue.
955 ! 19810401 Minor changes to comments and an error message.
956 ! 19810814 Numerous revisions: replaced EWT by 1/EWT; used flags
957 ! JCUR, ICF, IERPJ, IERSL between STODE and subordinates;
958 ! added tuning parameters CCMAX, MAXCOR, MSBP, MXNCF;
959 ! reorganized returns from STODE; reorganized type decls.;
960 ! fixed message length in XERRWD; changed default LUNIT to 6;
961 ! changed Common lengths; changed comments throughout.
962 ! 19870330 Major update by ACH: corrected comments throughout;
963 ! removed TRET from Common; rewrote EWSET with 4 loops;
964 ! fixed t test in INTDY; added Cray directives in STODE;
965 ! in STODE, fixed DELP init. and logic around PJAC call;
966 ! combined routines to save/restore Common;
967 ! passed LEVEL = 0 in error message calls (except run abort).
968 ! 19890426 Modified prologue to SLATEC/LDOC format. (FNF)
969 ! 19890501 Many improvements to prologue. (FNF)
970 ! 19890503 A few final corrections to prologue. (FNF)
971 ! 19890504 Minor cosmetic changes. (FNF)
972 ! 19890510 Corrected description of Y in Arguments section. (FNF)
973 ! 19890517 Minor corrections to prologue. (FNF)
974 ! 19920514 Updated with prologue edited 891025 by G. Shaw for manual.
975 ! 19920515 Converted source lines to upper case. (FNF)
976 ! 19920603 Revised XERRWD calls using mixed upper-lower case. (ACH)
977 ! 19920616 Revised prologue comment regarding CFT. (ACH)
978 ! 19921116 Revised prologue comments regarding Common. (ACH).
979 ! 19930326 Added comment about non-reentrancy. (FNF)
980 ! 19930723 Changed D1MACH to DUMACH. (FNF)
981 ! 19930801 Removed ILLIN and NTREP from Common (affects driver logic);
982 ! minor changes to prologue and internal comments;
983 ! changed Hollerith strings to quoted strings;
984 ! changed internal comments to mixed case;
985 ! replaced XERRWD with new version using character type;
986 ! changed dummy dimensions from 1 to *. (ACH)
987 ! 19930809 Changed to generic intrinsic names; changed names of
988 ! subprograms and Common blocks to DLSODE etc. (ACH)
989 ! 19930929 Eliminated use of REAL intrinsic; other minor changes. (ACH)
990 ! 20010412 Removed all 'own' variables from Common block /DLS001/
991 ! (affects declarations in 6 routines). (ACH)
992 ! 20010509 Minor corrections to prologue. (ACH)
993 ! 20031105 Restored 'own' variables to Common block /DLS001/, to
994 ! enable interrupt/restart feature. (ACH)
995 ! 20031112 Added SAVE statements for data-loaded constants.
996 !***END PROLOGUE DLSODE
997 ! Internal Notes:
998 ! Other Routines in the DLSODE Package.
999 ! In addition to Subroutine DLSODE, the DLSODE package includes the
1000 ! following subroutines and function routines:
1001 ! DINTDY computes an interpolated value of the y vector at t = TOUT.
1002 ! DSTODE is the core integrator, which does one step of the
1003 ! integration and the associated error control.
1004 ! DCFODE sets all method coefficients and test constants.
1005 ! DPREPJ computes and preprocesses the Jacobian matrix J = df/dy
1006 ! and the Newton iteration matrix P = I - h*l0*J.
1007 ! DSOLSY manages solution of linear system in chord iteration.
1008 ! DEWSET sets the error weight vector EWT before each step.
1009 ! DVNORM computes the weighted R.M.S. norm of a vector.
1010 ! DSRCOM is a user-callable routine to save and restore
1011 ! the contents of the internal Common block.
1012 ! DGEFA and DGESL are routines from LINPACK for solving full
1013 ! systems of linear algebraic equations.
1014 ! DGBFA and DGBSL are routines from LINPACK for solving banded
1015 ! linear systems.
1016 ! DUMACH computes the unit roundoff in a machine-independent manner.
1017 ! XERRWD, XSETUN, XSETF, IXSAV, IUMACH handle the printing of all
1018 ! error messages and warnings. XERRWD is machine-dependent.
1019 ! Note: DVNORM, DUMACH, IXSAV, and IUMACH are function routines.
1020 ! All the others are subroutines.
1021 !**End
1022 ! Declare externals.
1023 ! EXTERNAL DPREPJ, DSOLSY
1024 ! DOUBLE PRECISION :: DUMACH, DVNORM
1025 ! Declare all other variables.
1026 ! INTEGER :: INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS, &
1027 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
1028 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
1029 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
1030 ! INTEGER :: I, I1, I2, IFLAG, IMXER, KGO, LF0, &
1031 ! LENIW, LENRW, LENWM, ML, MORD, MU, MXHNL0, MXSTP0
1032 ! DOUBLE PRECISION :: ROWNS, &
1033 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
1034 ! DOUBLE PRECISION :: ATOLI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RTOLI, &
1035 ! TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0
1036 ! DIMENSION MORD(2)
1037 ! LOGICAL :: IHIT
1038 ! CHARACTER(80) :: MSG
1039 ! SAVE MORD, MXSTP0, MXHNL0
1040 !-----------------------------------------------------------------------
1041 ! The following internal Common block contains
1042 ! (a) variables which are local to any subroutine but whose values must
1043 ! be preserved between calls to the routine ("own" variables), and
1044 ! (b) variables which are communicated between subroutines.
1045 ! The block DLS001 is declared in subroutines DLSODE, DINTDY, DSTODE,
1046 ! DPREPJ, and DSOLSY.
1047 ! Groups of variables are replaced by dummy arrays in the Common
1048 ! declarations in routines where those variables are not used.
1049 !-----------------------------------------------------------------------
1050 ! COMMON /DLS001/ ROWNS(209), &
1051 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
1052 ! INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6), &
1053 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
1054 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
1055 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
1056 ! DATA MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
1057 !-----------------------------------------------------------------------
1058 ! Block A.
1059 ! This code block is executed on every call.
1060 ! It tests ISTATE and ITASK for legality and branches appropriately.
1061 ! If ISTATE .GT. 1 but the flag INIT shows that initialization has
1062 ! not yet been done, an error return occurs.
1063 ! If ISTATE = 1 and TOUT = T, return immediately.
1064 !-----------------------------------------------------------------------
1065 !***FIRST EXECUTABLE STATEMENT DLSODE
1066 ! IF (ISTATE < 1 .OR. ISTATE > 3) GO TO 601
1067 ! IF (ITASK < 1 .OR. ITASK > 5) GO TO 602
1068 ! IF (ISTATE == 1) GO TO 10
1069 ! IF (INIT == 0) GO TO 603
1070 ! IF (ISTATE == 2) GO TO 200
1071 ! GO TO 20
1072 ! 10 INIT = 0
1073 ! IF (TOUT == T) RETURN
1074 !-----------------------------------------------------------------------
1075 ! Block B.
1076 ! The next code block is executed for the initial call (ISTATE = 1),
1077 ! or for a continuation call with parameter changes (ISTATE = 3).
1078 ! It contains checking of all inputs and various initializations.
1079 ! First check legality of the non-optional inputs NEQ, ITOL, IOPT,
1080 ! MF, ML, and MU.
1081 !-----------------------------------------------------------------------
1082 ! 20 IF (NEQ(1) <= 0) GO TO 604
1083 ! IF (ISTATE == 1) GO TO 25
1084 ! IF (NEQ(1) > N) GO TO 605
1085 ! 25 N = NEQ(1)
1086 ! IF (ITOL < 1 .OR. ITOL > 4) GO TO 606
1087 ! IF (IOPT < 0 .OR. IOPT > 1) GO TO 607
1088 ! METH = MF/10
1089 ! MITER = MF - 10*METH
1090 ! IF (METH < 1 .OR. METH > 2) GO TO 608
1091 ! IF (MITER < 0 .OR. MITER > 5) GO TO 608
1092 ! IF (MITER <= 3) GO TO 30
1093 ! ML = IWORK(1)
1094 ! MU = IWORK(2)
1095 ! IF (ML < 0 .OR. ML >= N) GO TO 609
1096 ! IF (MU < 0 .OR. MU >= N) GO TO 610
1097 ! 30 CONTINUE
1098 ! Next process and check the optional inputs. --------------------------
1099 ! IF (IOPT == 1) GO TO 40
1100 ! MAXORD = MORD(METH)
1101 ! MXSTEP = MXSTP0
1102 ! MXHNIL = MXHNL0
1103 ! IF (ISTATE == 1) H0 = 0.0D0
1104 ! HMXI = 0.0D0
1105 ! HMIN = 0.0D0
1106 ! GO TO 60
1107 ! 40 MAXORD = IWORK(5)
1108 ! IF (MAXORD < 0) GO TO 611
1109 ! IF (MAXORD == 0) MAXORD = 100
1110 ! MAXORD = MIN(MAXORD,MORD(METH))
1111 ! MXSTEP = IWORK(6)
1112 ! IF (MXSTEP < 0) GO TO 612
1113 ! IF (MXSTEP == 0) MXSTEP = MXSTP0
1114 ! MXHNIL = IWORK(7)
1115 ! IF (MXHNIL < 0) GO TO 613
1116 ! IF (MXHNIL == 0) MXHNIL = MXHNL0
1117 ! IF (ISTATE /= 1) GO TO 50
1118 ! H0 = RWORK(5)
1119 ! IF ((TOUT - T)*H0 < 0.0D0) GO TO 614
1120 ! 50 HMAX = RWORK(6)
1121 ! IF (HMAX < 0.0D0) GO TO 615
1122 ! HMXI = 0.0D0
1123 ! IF (HMAX > 0.0D0) HMXI = 1.0D0/HMAX
1124 ! HMIN = RWORK(7)
1125 ! IF (HMIN < 0.0D0) GO TO 616
1126 !-----------------------------------------------------------------------
1127 ! Set work array pointers and check lengths LRW and LIW.
1128 ! Pointers to segments of RWORK and IWORK are named by prefixing L to
1129 ! the name of the segment. E.g., the segment YH starts at RWORK(LYH).
1130 ! Segments of RWORK (in order) are denoted YH, WM, EWT, SAVF, ACOR.
1131 !-----------------------------------------------------------------------
1132 ! 60 LYH = 21
1133 ! IF (ISTATE == 1) NYH = N
1134 ! LWM = LYH + (MAXORD + 1)*NYH
1135 ! IF (MITER == 0) LENWM = 0
1136 ! IF (MITER == 1 .OR. MITER == 2) LENWM = N*N + 2
1137 ! IF (MITER == 3) LENWM = N + 2
1138 ! IF (MITER >= 4) LENWM = (2*ML + MU + 1)*N + 2
1139 ! LEWT = LWM + LENWM
1140 ! LSAVF = LEWT + N
1141 ! LACOR = LSAVF + N
1142 ! LENRW = LACOR + N - 1
1143 ! IWORK(17) = LENRW
1144 ! LIWM = 1
1145 ! LENIW = 20 + N
1146 ! IF (MITER == 0 .OR. MITER == 3) LENIW = 20
1147 ! IWORK(18) = LENIW
1148 ! IF (LENRW > LRW) GO TO 617
1149 ! IF (LENIW > LIW) GO TO 618
1150 ! Check RTOL and ATOL for legality. ------------------------------------
1151 ! RTOLI = RTOL(1)
1152 ! ATOLI = ATOL(1)
1153 ! DO 70 I = 1,N
1154 ! IF (ITOL >= 3) RTOLI = RTOL(I)
1155 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
1156 ! IF (RTOLI < 0.0D0) GO TO 619
1157 ! IF (ATOLI < 0.0D0) GO TO 620
1158 ! 70 END DO
1159 ! IF (ISTATE == 1) GO TO 100
1160 ! If ISTATE = 3, set flag to signal parameter changes to DSTODE. -------
1161 ! JSTART = -1
1162 ! IF (NQ <= MAXORD) GO TO 90
1163 ! MAXORD was reduced below NQ. Copy YH(*,MAXORD+2) into SAVF. ---------
1164 ! DO 80 I = 1,N
1165 ! RWORK(I+LSAVF-1) = RWORK(I+LWM-1)
1166 ! 80 END DO
1167 ! Reload WM(1) = RWORK(LWM), since LWM may have changed. ---------------
1168 ! 90 IF (MITER > 0) RWORK(LWM) = SQRT(UROUND)
1169 ! IF (N == NYH) GO TO 200
1170 ! NEQ was reduced. Zero part of YH to avoid undefined references. -----
1171 ! I1 = LYH + L*NYH
1172 ! I2 = LYH + (MAXORD + 1)*NYH - 1
1173 ! IF (I1 > I2) GO TO 200
1174 ! DO 95 I = I1,I2
1175 ! RWORK(I) = 0.0D0
1176 ! 95 END DO
1177 ! GO TO 200
1178 !-----------------------------------------------------------------------
1179 ! Block C.
1180 ! The next block is for the initial call only (ISTATE = 1).
1181 ! It contains all remaining initializations, the initial call to F,
1182 ! and the calculation of the initial step size.
1183 ! The error weights in EWT are inverted after being loaded.
1184 !-----------------------------------------------------------------------
1185 ! 100 UROUND = DUMACH()
1186 ! TN = T
1187 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 110
1188 ! TCRIT = RWORK(1)
1189 ! IF ((TCRIT - TOUT)*(TOUT - T) < 0.0D0) GO TO 625
1190 ! IF (H0 /= 0.0D0 .AND. (T + H0 - TCRIT)*H0 > 0.0D0) &
1191 ! H0 = TCRIT - T
1192 ! 110 JSTART = 0
1193 ! IF (MITER > 0) RWORK(LWM) = SQRT(UROUND)
1194 ! NHNIL = 0
1195 ! NST = 0
1196 ! NJE = 0
1197 ! NSLAST = 0
1198 ! HU = 0.0D0
1199 ! NQU = 0
1200 ! CCMAX = 0.3D0
1201 ! MAXCOR = 3
1202 ! MSBP = 20
1203 ! MXNCF = 10
1204 ! Initial call to F. (LF0 points to YH(*,2).) -------------------------
1205 ! LF0 = LYH + NYH
1206 ! CALL F (NEQ, T, Y, RWORK(LF0))
1207 ! NFE = 1
1208 ! Load the initial value vector in YH. ---------------------------------
1209 ! DO 115 I = 1,N
1210 ! RWORK(I+LYH-1) = Y(I)
1211 ! 115 END DO
1212 ! Load and invert the EWT array. (H is temporarily set to 1.0.) -------
1213 ! NQ = 1
1214 ! H = 1.0D0
1215 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
1216 ! DO 120 I = 1,N
1217 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
1218 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
1219 ! 120 END DO
1220 !-----------------------------------------------------------------------
1221 ! The coding below computes the step size, H0, to be attempted on the
1222 ! first step, unless the user has supplied a value for this.
1223 ! First check that TOUT - T differs significantly from zero.
1224 ! A scalar tolerance quantity TOL is computed, as MAX(RTOL(I))
1225 ! if this is positive, or MAX(ATOL(I)/ABS(Y(I))) otherwise, adjusted
1226 ! so as to be between 100*UROUND and 1.0E-3.
1227 ! Then the computed value H0 is given by..
1228 ! NEQ
1229 ! H0**2 = TOL / ( w0**-2 + (1/NEQ) * SUM ( f(i)/ywt(i) )**2 )
1230 ! 1
1231 ! where w0 = MAX ( ABS(T), ABS(TOUT) ),
1232 ! f(i) = i-th component of initial value of f,
1233 ! ywt(i) = EWT(i)/TOL (a weight for y(i)).
1234 ! The sign of H0 is inferred from the initial values of TOUT and T.
1235 !-----------------------------------------------------------------------
1236 ! IF (H0 /= 0.0D0) GO TO 180
1237 ! TDIST = ABS(TOUT - T)
1238 ! W0 = MAX(ABS(T),ABS(TOUT))
1239 ! IF (TDIST < 2.0D0*UROUND*W0) GO TO 622
1240 ! TOL = RTOL(1)
1241 ! IF (ITOL <= 2) GO TO 140
1242 ! DO 130 I = 1,N
1243 ! TOL = MAX(TOL,RTOL(I))
1244 ! 130 END DO
1245 ! 140 IF (TOL > 0.0D0) GO TO 160
1246 ! ATOLI = ATOL(1)
1247 ! DO 150 I = 1,N
1248 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
1249 ! AYI = ABS(Y(I))
1250 ! IF (AYI /= 0.0D0) TOL = MAX(TOL,ATOLI/AYI)
1251 ! 150 END DO
1252 ! 160 TOL = MAX(TOL,100.0D0*UROUND)
1253 ! TOL = MIN(TOL,0.001D0)
1254 ! SUM = DVNORM (N, RWORK(LF0), RWORK(LEWT))
1255 ! SUM = 1.0D0/(TOL*W0*W0) + TOL*SUM**2
1256 ! H0 = 1.0D0/SQRT(SUM)
1257 ! H0 = MIN(H0,TDIST)
1258 ! H0 = SIGN(H0,TOUT-T)
1259 ! Adjust H0 if necessary to meet HMAX bound. ---------------------------
1260 ! 180 RH = ABS(H0)*HMXI
1261 ! IF (RH > 1.0D0) H0 = H0/RH
1262 ! Load H with H0 and scale YH(*,2) by H0. ------------------------------
1263 ! H = H0
1264 ! DO 190 I = 1,N
1265 ! RWORK(I+LF0-1) = H0*RWORK(I+LF0-1)
1266 ! 190 END DO
1267 ! GO TO 270
1268 !-----------------------------------------------------------------------
1269 ! Block D.
1270 ! The next code block is for continuation calls only (ISTATE = 2 or 3)
1271 ! and is to check stop conditions before taking a step.
1272 !-----------------------------------------------------------------------
1273 ! 200 NSLAST = NST
1274 ! GO TO (210, 250, 220, 230, 240), ITASK
1275 ! 210 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
1276 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
1277 ! IF (IFLAG /= 0) GO TO 627
1278 ! T = TOUT
1279 ! GO TO 420
1280 ! 220 TP = TN - HU*(1.0D0 + 100.0D0*UROUND)
1281 ! IF ((TP - TOUT)*H > 0.0D0) GO TO 623
1282 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 250
1283 ! GO TO 400
1284 ! 230 TCRIT = RWORK(1)
1285 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
1286 ! IF ((TCRIT - TOUT)*H < 0.0D0) GO TO 625
1287 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 245
1288 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
1289 ! IF (IFLAG /= 0) GO TO 627
1290 ! T = TOUT
1291 ! GO TO 420
1292 ! 240 TCRIT = RWORK(1)
1293 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
1294 ! 245 HMX = ABS(TN) + ABS(H)
1295 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
1296 ! IF (IHIT) GO TO 400
1297 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
1298 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
1299 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
1300 ! IF (ISTATE == 2) JSTART = -2
1301 !-----------------------------------------------------------------------
1302 ! Block E.
1303 ! The next block is normally executed for all calls and contains
1304 ! the call to the one-step core integrator DSTODE.
1305 ! This is a looping point for the integration steps.
1306 ! First check for too many steps being taken, update EWT (if not at
1307 ! start of problem), check for too much accuracy being requested, and
1308 ! check for H below the roundoff level in T.
1309 !-----------------------------------------------------------------------
1310 ! 250 CONTINUE
1311 ! IF ((NST-NSLAST) >= MXSTEP) GO TO 500
1312 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
1313 ! DO 260 I = 1,N
1314 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 510
1315 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
1316 ! 260 END DO
1317 ! 270 TOLSF = UROUND*DVNORM (N, RWORK(LYH), RWORK(LEWT))
1318 ! IF (TOLSF <= 1.0D0) GO TO 280
1319 ! TOLSF = TOLSF*2.0D0
1320 ! IF (NST == 0) GO TO 626
1321 ! GO TO 520
1322 ! 280 IF ((TN + H) /= TN) GO TO 290
1323 ! NHNIL = NHNIL + 1
1324 ! IF (NHNIL > MXHNIL) GO TO 290
1325 ! MSG = 'DLSODE- Warning..internal T (=R1) and H (=R2) are'
1326 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
1327 ! MSG=' such that in the machine, T + H = T on the next step '
1328 ! CALL XERRWD (MSG, 60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
1329 ! MSG = ' (H = step size). Solver will continue anyway'
1330 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 2, TN, H)
1331 ! IF (NHNIL < MXHNIL) GO TO 290
1332 ! MSG = 'DLSODE- Above warning has been issued I1 times. '
1333 ! CALL XERRWD (MSG, 50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
1334 ! MSG = ' It will not be issued again for this problem'
1335 ! CALL XERRWD (MSG, 50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
1336 ! 290 CONTINUE
1337 !-----------------------------------------------------------------------
1338 ! CALL DSTODE(NEQ,Y,YH,NYH,YH,EWT,SAVF,ACOR,WM,IWM,F,JAC,DPREPJ,DSOLSY)
1339 !-----------------------------------------------------------------------
1340 ! CALL DSTODE (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT), &
1341 ! RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), IWORK(LIWM), &
1342 ! F, JAC, DPREPJ, DSOLSY)
1343 ! KGO = 1 - KFLAG
1344 ! GO TO (300, 530, 540), KGO
1345 !-----------------------------------------------------------------------
1346 ! Block F.
1347 ! The following block handles the case of a successful return from the
1348 ! core integrator (KFLAG = 0). Test for stop conditions.
1349 !-----------------------------------------------------------------------
1350 ! 300 INIT = 1
1351 ! GO TO (310, 400, 330, 340, 350), ITASK
1352 ! ITASK = 1. If TOUT has been reached, interpolate. -------------------
1353 ! 310 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
1354 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
1355 ! T = TOUT
1356 ! GO TO 420
1357 ! ITASK = 3. Jump to exit if TOUT was reached. ------------------------
1358 ! 330 IF ((TN - TOUT)*H >= 0.0D0) GO TO 400
1359 ! GO TO 250
1360 ! ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary.
1361 ! 340 IF ((TN - TOUT)*H < 0.0D0) GO TO 345
1362 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
1363 ! T = TOUT
1364 ! GO TO 420
1365 ! 345 HMX = ABS(TN) + ABS(H)
1366 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
1367 ! IF (IHIT) GO TO 400
1368 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
1369 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
1370 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
1371 ! JSTART = -2
1372 ! GO TO 250
1373 ! ITASK = 5. See if TCRIT was reached and jump to exit. ---------------
1374 ! 350 HMX = ABS(TN) + ABS(H)
1375 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
1376 !-----------------------------------------------------------------------
1377 ! Block G.
1378 ! The following block handles all successful returns from DLSODE.
1379 ! If ITASK .NE. 1, Y is loaded from YH and T is set accordingly.
1380 ! ISTATE is set to 2, and the optional outputs are loaded into the
1381 ! work arrays before returning.
1382 !-----------------------------------------------------------------------
1383 ! 400 DO 410 I = 1,N
1384 ! Y(I) = RWORK(I+LYH-1)
1385 ! 410 END DO
1386 ! T = TN
1387 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 420
1388 ! IF (IHIT) T = TCRIT
1389 ! 420 ISTATE = 2
1390 ! RWORK(11) = HU
1391 ! RWORK(12) = H
1392 ! RWORK(13) = TN
1393 ! IWORK(11) = NST
1394 ! IWORK(12) = NFE
1395 ! IWORK(13) = NJE
1396 ! IWORK(14) = NQU
1397 ! IWORK(15) = NQ
1398 ! RETURN
1399 !-----------------------------------------------------------------------
1400 ! Block H.
1401 ! The following block handles all unsuccessful returns other than
1402 ! those for illegal input. First the error message routine is called.
1403 ! If there was an error test or convergence test failure, IMXER is set.
1404 ! Then Y is loaded from YH and T is set to TN. The optional outputs
1405 ! are loaded into the work arrays before returning.
1406 !-----------------------------------------------------------------------
1407 ! The maximum number of steps was taken before reaching TOUT. ----------
1408 ! 500 MSG = 'DLSODE- At current T (=R1), MXSTEP (=I1) steps '
1409 ! CALL XERRWD (MSG, 50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
1410 ! MSG = ' taken on this call before reaching TOUT '
1411 ! CALL XERRWD (MSG, 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0)
1412 ! ISTATE = -1
1413 ! GO TO 580
1414 ! EWT(I) .LE. 0.0 for some I (not at start of problem). ----------------
1415 ! 510 EWTI = RWORK(LEWT+I-1)
1416 ! MSG = 'DLSODE- At T (=R1), EWT(I1) has become R2 <= 0.'
1417 ! CALL XERRWD (MSG, 50, 202, 0, 1, I, 0, 2, TN, EWTI)
1418 ! ISTATE = -6
1419 ! GO TO 580
1420 ! Too much accuracy requested for machine precision. -------------------
1421 ! 520 MSG = 'DLSODE- At T (=R1), too much accuracy requested '
1422 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
1423 ! MSG = ' for precision of machine.. see TOLSF (=R2) '
1424 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
1425 ! RWORK(14) = TOLSF
1426 ! ISTATE = -2
1427 ! GO TO 580
1428 ! KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
1429 ! 530 MSG = 'DLSODE- At T(=R1) and step size H(=R2), the error'
1430 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
1431 ! MSG = ' test failed repeatedly or with ABS(H) = HMIN'
1432 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 2, TN, H)
1433 ! ISTATE = -4
1434 ! GO TO 560
1435 ! KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
1436 ! 540 MSG = 'DLSODE- At T (=R1) and step size H (=R2), the '
1437 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
1438 ! MSG = ' corrector convergence failed repeatedly '
1439 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
1440 ! MSG = ' or with ABS(H) = HMIN '
1441 ! CALL XERRWD (MSG, 30, 205, 0, 0, 0, 0, 2, TN, H)
1442 ! ISTATE = -5
1443 ! Compute IMXER if relevant. -------------------------------------------
1444 ! 560 BIG = 0.0D0
1445 ! IMXER = 1
1446 ! DO 570 I = 1,N
1447 ! SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
1448 ! IF (BIG >= SIZE) GO TO 570
1449 ! BIG = SIZE
1450 ! IMXER = I
1451 ! 570 END DO
1452 ! IWORK(16) = IMXER
1453 ! Set Y vector, T, and optional outputs. -------------------------------
1454 ! 580 DO 590 I = 1,N
1455 ! Y(I) = RWORK(I+LYH-1)
1456 ! 590 END DO
1457 ! T = TN
1458 ! RWORK(11) = HU
1459 ! RWORK(12) = H
1460 ! RWORK(13) = TN
1461 ! IWORK(11) = NST
1462 ! IWORK(12) = NFE
1463 ! IWORK(13) = NJE
1464 ! IWORK(14) = NQU
1465 ! IWORK(15) = NQ
1466 ! RETURN
1467 !-----------------------------------------------------------------------
1468 ! Block I.
1469 ! The following block handles all error returns due to illegal input
1470 ! (ISTATE = -3), as detected before calling the core integrator.
1471 ! First the error message routine is called. If the illegal input
1472 ! is a negative ISTATE, the run is aborted (apparent infinite loop).
1473 !-----------------------------------------------------------------------
1474 ! 601 MSG = 'DLSODE- ISTATE (=I1) illegal '
1475 ! CALL XERRWD (MSG, 30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0)
1476 ! IF (ISTATE < 0) GO TO 800
1477 ! GO TO 700
1478 ! 602 MSG = 'DLSODE- ITASK (=I1) illegal '
1479 ! CALL XERRWD (MSG, 30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0)
1480 ! GO TO 700
1481 ! 603 MSG = 'DLSODE- ISTATE > 1 but DLSODE not initialized '
1482 ! CALL XERRWD (MSG, 50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
1483 ! GO TO 700
1484 ! 604 MSG = 'DLSODE- NEQ (=I1) < 1 '
1485 ! CALL XERRWD (MSG, 30, 4, 0, 1, NEQ(1), 0, 0, 0.0D0, 0.0D0)
1486 ! GO TO 700
1487 ! 605 MSG = 'DLSODE- ISTATE = 3 and NEQ increased (I1 to I2) '
1488 ! CALL XERRWD (MSG, 50, 5, 0, 2, N, NEQ(1), 0, 0.0D0, 0.0D0)
1489 ! GO TO 700
1490 ! 606 MSG = 'DLSODE- ITOL (=I1) illegal '
1491 ! CALL XERRWD (MSG, 30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0)
1492 ! GO TO 700
1493 ! 607 MSG = 'DLSODE- IOPT (=I1) illegal '
1494 ! CALL XERRWD (MSG, 30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0)
1495 ! GO TO 700
1496 ! 608 MSG = 'DLSODE- MF (=I1) illegal '
1497 ! CALL XERRWD (MSG, 30, 8, 0, 1, MF, 0, 0, 0.0D0, 0.0D0)
1498 ! GO TO 700
1499 ! 609 MSG = 'DLSODE- ML (=I1) illegal.. < 0 or >= NEQ (=I2)'
1500 ! CALL XERRWD (MSG, 50, 9, 0, 2, ML, NEQ(1), 0, 0.0D0, 0.0D0)
1501 ! GO TO 700
1502 ! 610 MSG = 'DLSODE- MU (=I1) illegal.. < 0 or >= NEQ (=I2)'
1503 ! CALL XERRWD (MSG, 50, 10, 0, 2, MU, NEQ(1), 0, 0.0D0, 0.0D0)
1504 ! GO TO 700
1505 ! 611 MSG = 'DLSODE- MAXORD (=I1) < 0 '
1506 ! CALL XERRWD (MSG, 30, 11, 0, 1, MAXORD, 0, 0, 0.0D0, 0.0D0)
1507 ! GO TO 700
1508 ! 612 MSG = 'DLSODE- MXSTEP (=I1) < 0 '
1509 ! CALL XERRWD (MSG, 30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0)
1510 ! GO TO 700
1511 ! 613 MSG = 'DLSODE- MXHNIL (=I1) < 0 '
1512 ! CALL XERRWD (MSG, 30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
1513 ! GO TO 700
1514 ! 614 MSG = 'DLSODE- TOUT (=R1) behind T (=R2) '
1515 ! CALL XERRWD (MSG, 40, 14, 0, 0, 0, 0, 2, TOUT, T)
1516 ! MSG = ' Integration direction is given by H0 (=R1) '
1517 ! CALL XERRWD (MSG, 50, 14, 0, 0, 0, 0, 1, H0, 0.0D0)
1518 ! GO TO 700
1519 ! 615 MSG = 'DLSODE- HMAX (=R1) < 0.0 '
1520 ! CALL XERRWD (MSG, 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0)
1521 ! GO TO 700
1522 ! 616 MSG = 'DLSODE- HMIN (=R1) < 0.0 '
1523 ! CALL XERRWD (MSG, 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0)
1524 ! GO TO 700
1525 ! 617 CONTINUE
1526 ! MSG='DLSODE- RWORK length needed, LENRW (=I1), exceeds LRW (=I2)'
1527 ! CALL XERRWD (MSG, 60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
1528 ! GO TO 700
1529 ! 618 CONTINUE
1530 ! MSG='DLSODE- IWORK length needed, LENIW (=I1), exceeds LIW (=I2)'
1531 ! CALL XERRWD (MSG, 60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
1532 ! GO TO 700
1533 ! 619 MSG = 'DLSODE- RTOL(I1) is R1 < 0.0 '
1534 ! CALL XERRWD (MSG, 40, 19, 0, 1, I, 0, 1, RTOLI, 0.0D0)
1535 ! GO TO 700
1536 ! 620 MSG = 'DLSODE- ATOL(I1) is R1 < 0.0 '
1537 ! CALL XERRWD (MSG, 40, 20, 0, 1, I, 0, 1, ATOLI, 0.0D0)
1538 ! GO TO 700
1539 ! 621 EWTI = RWORK(LEWT+I-1)
1540 ! MSG = 'DLSODE- EWT(I1) is R1 <= 0.0 '
1541 ! CALL XERRWD (MSG, 40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0)
1542 ! GO TO 700
1543 ! 622 CONTINUE
1544 ! MSG='DLSODE- TOUT (=R1) too close to T(=R2) to start integration'
1545 ! CALL XERRWD (MSG, 60, 22, 0, 0, 0, 0, 2, TOUT, T)
1546 ! GO TO 700
1547 ! 623 CONTINUE
1548 ! MSG='DLSODE- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
1549 ! CALL XERRWD (MSG, 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
1550 ! GO TO 700
1551 ! 624 CONTINUE
1552 ! MSG='DLSODE- ITASK = 4 OR 5 and TCRIT (=R1) behind TCUR (=R2) '
1553 ! CALL XERRWD (MSG, 60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
1554 ! GO TO 700
1555 ! 625 CONTINUE
1556 ! MSG='DLSODE- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
1557 ! CALL XERRWD (MSG, 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
1558 ! GO TO 700
1559 ! 626 MSG = 'DLSODE- At start of problem, too much accuracy '
1560 ! CALL XERRWD (MSG, 50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
1561 ! MSG=' requested for precision of machine.. See TOLSF (=R1) '
1562 ! CALL XERRWD (MSG, 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0)
1563 ! RWORK(14) = TOLSF
1564 ! GO TO 700
1565 ! 627 MSG = 'DLSODE- Trouble in DINTDY. ITASK = I1, TOUT = R1'
1566 ! CALL XERRWD (MSG, 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0)
1567 ! 700 ISTATE = -3
1568 ! RETURN
1569 ! 800 MSG = 'DLSODE- Run aborted.. apparent infinite loop '
1570 ! CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0)
1571 ! RETURN
1572 !----------------------- END OF SUBROUTINE DLSODE ----------------------
1573 ! END SUBROUTINE DLSODE
1574 ! ECK DLSODES
1575 ! SUBROUTINE DLSODES (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK, &
1576 ! ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF)
1577 ! EXTERNAL F, JAC
1578 ! INTEGER :: NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, MF
1579 ! DOUBLE PRECISION :: Y, T, TOUT, RTOL, ATOL, RWORK
1580 ! DIMENSION NEQ(*), Y(*), RTOL(*), ATOL(*), RWORK(LRW), IWORK(LIW)
1581 !-----------------------------------------------------------------------
1582 ! This is the 12 November 2003 version of
1583 ! DLSODES: Livermore Solver for Ordinary Differential Equations
1584 ! with general Sparse Jacobian matrix.
1585 ! This version is in double precision.
1586 ! DLSODES solves the initial value problem for stiff or nonstiff
1587 ! systems of first order ODEs,
1588 ! dy/dt = f(t,y) , or, in component form,
1589 ! dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ)) (i = 1,...,NEQ).
1590 ! DLSODES is a variant of the DLSODE package, and is intended for
1591 ! problems in which the Jacobian matrix df/dy has an arbitrary
1592 ! sparse structure (when the problem is stiff).
1593 ! Authors: Alan C. Hindmarsh
1594 ! Center for Applied Scientific Computing, L-561
1595 ! Lawrence Livermore National Laboratory
1596 ! Livermore, CA 94551
1597 ! and
1598 ! Andrew H. Sherman
1599 ! J. S. Nolen and Associates
1600 ! Houston, TX 77084
1601 !-----------------------------------------------------------------------
1602 ! References:
1603 ! 1. Alan C. Hindmarsh, ODEPACK, A Systematized Collection of ODE
1604 ! Solvers, in Scientific Computing, R. S. Stepleman et al. (Eds.),
1605 ! North-Holland, Amsterdam, 1983, pp. 55-64.
1606 ! 2. S. C. Eisenstat, M. C. Gursky, M. H. Schultz, and A. H. Sherman,
1607 ! Yale Sparse Matrix Package: I. The Symmetric Codes,
1608 ! Int. J. Num. Meth. Eng., 18 (1982), pp. 1145-1151.
1609 ! 3. S. C. Eisenstat, M. C. Gursky, M. H. Schultz, and A. H. Sherman,
1610 ! Yale Sparse Matrix Package: II. The Nonsymmetric Codes,
1611 ! Research Report No. 114, Dept. of Computer Sciences, Yale
1612 ! University, 1977.
1613 !-----------------------------------------------------------------------
1614 ! Summary of Usage.
1615 ! Communication between the user and the DLSODES package, for normal
1616 ! situations, is summarized here. This summary describes only a subset
1617 ! of the full set of options available. See the full description for
1618 ! details, including optional communication, nonstandard options,
1619 ! and instructions for special situations. See also the example
1620 ! problem (with program and output) following this summary.
1621 ! A. First provide a subroutine of the form:
1622 ! SUBROUTINE F (NEQ, T, Y, YDOT)
1623 ! DOUBLE PRECISION T, Y(*), YDOT(*)
1624 ! which supplies the vector function f by loading YDOT(i) with f(i).
1625 ! B. Next determine (or guess) whether or not the problem is stiff.
1626 ! Stiffness occurs when the Jacobian matrix df/dy has an eigenvalue
1627 ! whose real part is negative and large in magnitude, compared to the
1628 ! reciprocal of the t span of interest. If the problem is nonstiff,
1629 ! use a method flag MF = 10. If it is stiff, there are two standard
1630 ! choices for the method flag, MF = 121 and MF = 222. In both cases,
1631 ! DLSODES requires the Jacobian matrix in some form, and it treats this
1632 ! matrix in general sparse form, with sparsity structure determined
1633 ! internally. (For options where the user supplies the sparsity
1634 ! structure, see the full description of MF below.)
1635 ! C. If the problem is stiff, you are encouraged to supply the Jacobian
1636 ! directly (MF = 121), but if this is not feasible, DLSODES will
1637 ! compute it internally by difference quotients (MF = 222).
1638 ! If you are supplying the Jacobian, provide a subroutine of the form:
1639 ! SUBROUTINE JAC (NEQ, T, Y, J, IAN, JAN, PDJ)
1640 ! DOUBLE PRECISION T, Y(*), IAN(*), JAN(*), PDJ(*)
1641 ! Here NEQ, T, Y, and J are input arguments, and the JAC routine is to
1642 ! load the array PDJ (of length NEQ) with the J-th column of df/dy.
1643 ! I.e., load PDJ(i) with df(i)/dy(J) for all relevant values of i.
1644 ! The arguments IAN and JAN should be ignored for normal situations.
1645 ! DLSODES will call the JAC routine with J = 1,2,...,NEQ.
1646 ! Only nonzero elements need be loaded. Usually, a crude approximation
1647 ! to df/dy, possibly with fewer nonzero elements, will suffice.
1648 ! D. Write a main program which calls Subroutine DLSODES once for
1649 ! each point at which answers are desired. This should also provide
1650 ! for possible use of logical unit 6 for output of error messages by
1651 ! DLSODES. On the first call to DLSODES, supply arguments as follows:
1652 ! F = name of subroutine for right-hand side vector f.
1653 ! This name must be declared External in calling program.
1654 ! NEQ = number of first order ODEs.
1655 ! Y = array of initial values, of length NEQ.
1656 ! T = the initial value of the independent variable t.
1657 ! TOUT = first point where output is desired (.ne. T).
1658 ! ITOL = 1 or 2 according as ATOL (below) is a scalar or array.
1659 ! RTOL = relative tolerance parameter (scalar).
1660 ! ATOL = absolute tolerance parameter (scalar or array).
1661 ! The estimated local error in Y(i) will be controlled so as
1662 ! to be roughly less (in magnitude) than
1663 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or
1664 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2.
1665 ! Thus the local error test passes if, in each component,
1666 ! either the absolute error is less than ATOL (or ATOL(i)),
1667 ! or the relative error is less than RTOL.
1668 ! Use RTOL = 0.0 for pure absolute error control, and
1669 ! use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative error
1670 ! control. Caution: actual (global) errors may exceed these
1671 ! local tolerances, so choose them conservatively.
1672 ! ITASK = 1 for normal computation of output values of Y at t = TOUT.
1673 ! ISTATE = integer flag (input and output). Set ISTATE = 1.
1674 ! IOPT = 0 to indicate no optional inputs used.
1675 ! RWORK = real work array of length at least:
1676 ! 20 + 16*NEQ for MF = 10,
1677 ! 20 + (2 + 1./LENRAT)*NNZ + (11 + 9./LENRAT)*NEQ
1678 ! for MF = 121 or 222,
1679 ! where:
1680 ! NNZ = the number of nonzero elements in the sparse
1681 ! Jacobian (if this is unknown, use an estimate), and
1682 ! LENRAT = the real to integer wordlength ratio (usually 1 in
1683 ! single precision and 2 in double precision).
1684 ! In any case, the required size of RWORK cannot generally
1685 ! be predicted in advance if MF = 121 or 222, and the value
1686 ! above is a rough estimate of a crude lower bound. Some
1687 ! experimentation with this size may be necessary.
1688 ! (When known, the correct required length is an optional
1689 ! output, available in IWORK(17).)
1690 ! LRW = declared length of RWORK (in user dimension).
1691 ! IWORK = integer work array of length at least 30.
1692 ! LIW = declared length of IWORK (in user dimension).
1693 ! JAC = name of subroutine for Jacobian matrix (MF = 121).
1694 ! If used, this name must be declared External in calling
1695 ! program. If not used, pass a dummy name.
1696 ! MF = method flag. Standard values are:
1697 ! 10 for nonstiff (Adams) method, no Jacobian used
1698 ! 121 for stiff (BDF) method, user-supplied sparse Jacobian
1699 ! 222 for stiff method, internally generated sparse Jacobian
1700 ! Note that the main program must declare arrays Y, RWORK, IWORK,
1701 ! and possibly ATOL.
1702 ! E. The output from the first call (or any call) is:
1703 ! Y = array of computed values of y(t) vector.
1704 ! T = corresponding value of independent variable (normally TOUT).
1705 ! ISTATE = 2 if DLSODES was successful, negative otherwise.
1706 ! -1 means excess work done on this call (perhaps wrong MF).
1707 ! -2 means excess accuracy requested (tolerances too small).
1708 ! -3 means illegal input detected (see printed message).
1709 ! -4 means repeated error test failures (check all inputs).
1710 ! -5 means repeated convergence failures (perhaps bad Jacobian
1711 ! supplied or wrong choice of MF or tolerances).
1712 ! -6 means error weight became zero during problem. (Solution
1713 ! component i vanished, and ATOL or ATOL(i) = 0.)
1714 ! -7 means a fatal error return flag came from sparse solver
1715 ! CDRV by way of DPRJS or DSOLSS. Should never happen.
1716 ! A return with ISTATE = -1, -4, or -5 may result from using
1717 ! an inappropriate sparsity structure, one that is quite
1718 ! different from the initial structure. Consider calling
1719 ! DLSODES again with ISTATE = 3 to force the structure to be
1720 ! reevaluated. See the full description of ISTATE below.
1721 ! F. To continue the integration after a successful return, simply
1722 ! reset TOUT and call DLSODES again. No other parameters need be reset.
1723 !-----------------------------------------------------------------------
1724 ! Example Problem.
1725 ! The following is a simple example problem, with the coding
1726 ! needed for its solution by DLSODES. The problem is from chemical
1727 ! kinetics, and consists of the following 12 rate equations:
1728 ! dy1/dt = -rk1*y1
1729 ! dy2/dt = rk1*y1 + rk11*rk14*y4 + rk19*rk14*y5
1730 ! - rk3*y2*y3 - rk15*y2*y12 - rk2*y2
1731 ! dy3/dt = rk2*y2 - rk5*y3 - rk3*y2*y3 - rk7*y10*y3
1732 ! + rk11*rk14*y4 + rk12*rk14*y6
1733 ! dy4/dt = rk3*y2*y3 - rk11*rk14*y4 - rk4*y4
1734 ! dy5/dt = rk15*y2*y12 - rk19*rk14*y5 - rk16*y5
1735 ! dy6/dt = rk7*y10*y3 - rk12*rk14*y6 - rk8*y6
1736 ! dy7/dt = rk17*y10*y12 - rk20*rk14*y7 - rk18*y7
1737 ! dy8/dt = rk9*y10 - rk13*rk14*y8 - rk10*y8
1738 ! dy9/dt = rk4*y4 + rk16*y5 + rk8*y6 + rk18*y7
1739 ! dy10/dt = rk5*y3 + rk12*rk14*y6 + rk20*rk14*y7
1740 ! + rk13*rk14*y8 - rk7*y10*y3 - rk17*y10*y12
1741 ! - rk6*y10 - rk9*y10
1742 ! dy11/dt = rk10*y8
1743 ! dy12/dt = rk6*y10 + rk19*rk14*y5 + rk20*rk14*y7
1744 ! - rk15*y2*y12 - rk17*y10*y12
1745 ! with rk1 = rk5 = 0.1, rk4 = rk8 = rk16 = rk18 = 2.5,
1746 ! rk10 = 5.0, rk2 = rk6 = 10.0, rk14 = 30.0,
1747 ! rk3 = rk7 = rk9 = rk11 = rk12 = rk13 = rk19 = rk20 = 50.0,
1748 ! rk15 = rk17 = 100.0.
1749 ! The t interval is from 0 to 1000, and the initial conditions
1750 ! are y1 = 1, y2 = y3 = ... = y12 = 0. The problem is stiff.
1751 ! The following coding solves this problem with DLSODES, using MF = 121
1752 ! and printing results at t = .1, 1., 10., 100., 1000. It uses
1753 ! ITOL = 1 and mixed relative/absolute tolerance controls.
1754 ! During the run and at the end, statistical quantities of interest
1755 ! are printed (see optional outputs in the full description below).
1756 ! EXTERNAL FEX, JEX
1757 ! DOUBLE PRECISION ATOL, RTOL, RWORK, T, TOUT, Y
1758 ! DIMENSION Y(12), RWORK(500), IWORK(30)
1759 ! DATA LRW/500/, LIW/30/
1760 ! NEQ = 12
1761 ! DO 10 I = 1,NEQ
1762 ! 10 Y(I) = 0.0D0
1763 ! Y(1) = 1.0D0
1764 ! T = 0.0D0
1765 ! TOUT = 0.1D0
1766 ! ITOL = 1
1767 ! RTOL = 1.0D-4
1768 ! ATOL = 1.0D-6
1769 ! ITASK = 1
1770 ! ISTATE = 1
1771 ! IOPT = 0
1772 ! MF = 121
1773 ! DO 40 IOUT = 1,5
1774 ! CALL DLSODES (FEX, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL,
1775 ! 1 ITASK, ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JEX, MF)
1776 ! WRITE(6,30)T,IWORK(11),RWORK(11),(Y(I),I=1,NEQ)
1777 ! 30 FORMAT(//' At t =',D11.3,4X,
1778 ! 1 ' No. steps =',I5,4X,' Last step =',D11.3/
1779 ! 2 ' Y array = ',4D14.5/13X,4D14.5/13X,4D14.5)
1780 ! IF (ISTATE .LT. 0) GO TO 80
1781 ! TOUT = TOUT*10.0D0
1782 ! 40 CONTINUE
1783 ! LENRW = IWORK(17)
1784 ! LENIW = IWORK(18)
1785 ! NST = IWORK(11)
1786 ! NFE = IWORK(12)
1787 ! NJE = IWORK(13)
1788 ! NLU = IWORK(21)
1789 ! NNZ = IWORK(19)
1790 ! NNZLU = IWORK(25) + IWORK(26) + NEQ
1791 ! WRITE (6,70) LENRW,LENIW,NST,NFE,NJE,NLU,NNZ,NNZLU
1792 ! 70 FORMAT(//' Required RWORK size =',I4,' IWORK size =',I4/
1793 ! 1 ' No. steps =',I4,' No. f-s =',I4,' No. J-s =',I4,
1794 ! 2 ' No. LU-s =',I4/' No. of nonzeros in J =',I5,
1795 ! 3 ' No. of nonzeros in LU =',I5)
1796 ! STOP
1797 ! 80 WRITE(6,90)ISTATE
1798 ! 90 FORMAT(///' Error halt.. ISTATE =',I3)
1799 ! STOP
1800 ! END
1801 ! SUBROUTINE FEX (NEQ, T, Y, YDOT)
1802 ! DOUBLE PRECISION T, Y, YDOT
1803 ! DOUBLE PRECISION RK1, RK2, RK3, RK4, RK5, RK6, RK7, RK8, RK9,
1804 ! 1 RK10, RK11, RK12, RK13, RK14, RK15, RK16, RK17
1805 ! DIMENSION Y(12), YDOT(12)
1806 ! DATA RK1/0.1D0/, RK2/10.0D0/, RK3/50.0D0/, RK4/2.5D0/, RK5/0.1D0/,
1807 ! 1 RK6/10.0D0/, RK7/50.0D0/, RK8/2.5D0/, RK9/50.0D0/, RK10/5.0D0/,
1808 ! 2 RK11/50.0D0/, RK12/50.0D0/, RK13/50.0D0/, RK14/30.0D0/,
1809 ! 3 RK15/100.0D0/, RK16/2.5D0/, RK17/100.0D0/, RK18/2.5D0/,
1810 ! 4 RK19/50.0D0/, RK20/50.0D0/
1811 ! YDOT(1) = -RK1*Y(1)
1812 ! YDOT(2) = RK1*Y(1) + RK11*RK14*Y(4) + RK19*RK14*Y(5)
1813 ! 1 - RK3*Y(2)*Y(3) - RK15*Y(2)*Y(12) - RK2*Y(2)
1814 ! YDOT(3) = RK2*Y(2) - RK5*Y(3) - RK3*Y(2)*Y(3) - RK7*Y(10)*Y(3)
1815 ! 1 + RK11*RK14*Y(4) + RK12*RK14*Y(6)
1816 ! YDOT(4) = RK3*Y(2)*Y(3) - RK11*RK14*Y(4) - RK4*Y(4)
1817 ! YDOT(5) = RK15*Y(2)*Y(12) - RK19*RK14*Y(5) - RK16*Y(5)
1818 ! YDOT(6) = RK7*Y(10)*Y(3) - RK12*RK14*Y(6) - RK8*Y(6)
1819 ! YDOT(7) = RK17*Y(10)*Y(12) - RK20*RK14*Y(7) - RK18*Y(7)
1820 ! YDOT(8) = RK9*Y(10) - RK13*RK14*Y(8) - RK10*Y(8)
1821 ! YDOT(9) = RK4*Y(4) + RK16*Y(5) + RK8*Y(6) + RK18*Y(7)
1822 ! YDOT(10) = RK5*Y(3) + RK12*RK14*Y(6) + RK20*RK14*Y(7)
1823 ! 1 + RK13*RK14*Y(8) - RK7*Y(10)*Y(3) - RK17*Y(10)*Y(12)
1824 ! 2 - RK6*Y(10) - RK9*Y(10)
1825 ! YDOT(11) = RK10*Y(8)
1826 ! YDOT(12) = RK6*Y(10) + RK19*RK14*Y(5) + RK20*RK14*Y(7)
1827 ! 1 - RK15*Y(2)*Y(12) - RK17*Y(10)*Y(12)
1828 ! RETURN
1829 ! END
1830 ! SUBROUTINE JEX (NEQ, T, Y, J, IA, JA, PDJ)
1831 ! DOUBLE PRECISION T, Y, PDJ
1832 ! DOUBLE PRECISION RK1, RK2, RK3, RK4, RK5, RK6, RK7, RK8, RK9,
1833 ! 1 RK10, RK11, RK12, RK13, RK14, RK15, RK16, RK17
1834 ! DIMENSION Y(12), IA(*), JA(*), PDJ(12)
1835 ! DATA RK1/0.1D0/, RK2/10.0D0/, RK3/50.0D0/, RK4/2.5D0/, RK5/0.1D0/,
1836 ! 1 RK6/10.0D0/, RK7/50.0D0/, RK8/2.5D0/, RK9/50.0D0/, RK10/5.0D0/,
1837 ! 2 RK11/50.0D0/, RK12/50.0D0/, RK13/50.0D0/, RK14/30.0D0/,
1838 ! 3 RK15/100.0D0/, RK16/2.5D0/, RK17/100.0D0/, RK18/2.5D0/,
1839 ! 4 RK19/50.0D0/, RK20/50.0D0/
1840 ! GO TO (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), J
1841 ! 1 PDJ(1) = -RK1
1842 ! PDJ(2) = RK1
1843 ! RETURN
1844 ! 2 PDJ(2) = -RK3*Y(3) - RK15*Y(12) - RK2
1845 ! PDJ(3) = RK2 - RK3*Y(3)
1846 ! PDJ(4) = RK3*Y(3)
1847 ! PDJ(5) = RK15*Y(12)
1848 ! PDJ(12) = -RK15*Y(12)
1849 ! RETURN
1850 ! 3 PDJ(2) = -RK3*Y(2)
1851 ! PDJ(3) = -RK5 - RK3*Y(2) - RK7*Y(10)
1852 ! PDJ(4) = RK3*Y(2)
1853 ! PDJ(6) = RK7*Y(10)
1854 ! PDJ(10) = RK5 - RK7*Y(10)
1855 ! RETURN
1856 ! 4 PDJ(2) = RK11*RK14
1857 ! PDJ(3) = RK11*RK14
1858 ! PDJ(4) = -RK11*RK14 - RK4
1859 ! PDJ(9) = RK4
1860 ! RETURN
1861 ! 5 PDJ(2) = RK19*RK14
1862 ! PDJ(5) = -RK19*RK14 - RK16
1863 ! PDJ(9) = RK16
1864 ! PDJ(12) = RK19*RK14
1865 ! RETURN
1866 ! 6 PDJ(3) = RK12*RK14
1867 ! PDJ(6) = -RK12*RK14 - RK8
1868 ! PDJ(9) = RK8
1869 ! PDJ(10) = RK12*RK14
1870 ! RETURN
1871 ! 7 PDJ(7) = -RK20*RK14 - RK18
1872 ! PDJ(9) = RK18
1873 ! PDJ(10) = RK20*RK14
1874 ! PDJ(12) = RK20*RK14
1875 ! RETURN
1876 ! 8 PDJ(8) = -RK13*RK14 - RK10
1877 ! PDJ(10) = RK13*RK14
1878 ! PDJ(11) = RK10
1879 ! 9 RETURN
1880 ! 10 PDJ(3) = -RK7*Y(3)
1881 ! PDJ(6) = RK7*Y(3)
1882 ! PDJ(7) = RK17*Y(12)
1883 ! PDJ(8) = RK9
1884 ! PDJ(10) = -RK7*Y(3) - RK17*Y(12) - RK6 - RK9
1885 ! PDJ(12) = RK6 - RK17*Y(12)
1886 ! 11 RETURN
1887 ! 12 PDJ(2) = -RK15*Y(2)
1888 ! PDJ(5) = RK15*Y(2)
1889 ! PDJ(7) = RK17*Y(10)
1890 ! PDJ(10) = -RK17*Y(10)
1891 ! PDJ(12) = -RK15*Y(2) - RK17*Y(10)
1892 ! RETURN
1893 ! END
1894 ! The output of this program (on a Cray-1 in single precision)
1895 ! is as follows:
1896 ! At t = 1.000e-01 No. steps = 12 Last step = 1.515e-02
1897 ! Y array = 9.90050e-01 6.28228e-03 3.65313e-03 7.51934e-07
1898 ! 1.12167e-09 1.18458e-09 1.77291e-12 3.26476e-07
1899 ! 5.46720e-08 9.99500e-06 4.48483e-08 2.76398e-06
1900 ! At t = 1.000e+00 No. steps = 33 Last step = 7.880e-02
1901 ! Y array = 9.04837e-01 9.13105e-03 8.20622e-02 2.49177e-05
1902 ! 1.85055e-06 1.96797e-06 1.46157e-07 2.39557e-05
1903 ! 3.26306e-05 7.21621e-04 5.06433e-05 3.05010e-03
1904 ! At t = 1.000e+01 No. steps = 48 Last step = 1.239e+00
1905 ! Y array = 3.67876e-01 3.68958e-03 3.65133e-01 4.48325e-05
1906 ! 6.10798e-05 4.33148e-05 5.90211e-05 1.18449e-04
1907 ! 3.15235e-03 3.56531e-03 4.15520e-03 2.48741e-01
1908 ! At t = 1.000e+02 No. steps = 91 Last step = 3.764e+00
1909 ! Y array = 4.44981e-05 4.42666e-07 4.47273e-04 -3.53257e-11
1910 ! 2.81577e-08 -9.67741e-11 2.77615e-07 1.45322e-07
1911 ! 1.56230e-02 4.37394e-06 1.60104e-02 9.52246e-01
1912 ! At t = 1.000e+03 No. steps = 111 Last step = 4.156e+02
1913 ! Y array = -2.65492e-13 2.60539e-14 -8.59563e-12 6.29355e-14
1914 ! -1.78066e-13 5.71471e-13 -1.47561e-12 4.58078e-15
1915 ! 1.56314e-02 1.37878e-13 1.60184e-02 9.52719e-01
1916 ! Required RWORK size = 442 IWORK size = 30
1917 ! No. steps = 111 No. f-s = 142 No. J-s = 2 No. LU-s = 20
1918 ! No. of nonzeros in J = 44 No. of nonzeros in LU = 50
1919 !-----------------------------------------------------------------------
1920 ! Full Description of User Interface to DLSODES.
1921 ! The user interface to DLSODES consists of the following parts.
1922 ! 1. The call sequence to Subroutine DLSODES, which is a driver
1923 ! routine for the solver. This includes descriptions of both
1924 ! the call sequence arguments and of user-supplied routines.
1925 ! Following these descriptions is a description of
1926 ! optional inputs available through the call sequence, and then
1927 ! a description of optional outputs (in the work arrays).
1928 ! 2. Descriptions of other routines in the DLSODES package that may be
1929 ! (optionally) called by the user. These provide the ability to
1930 ! alter error message handling, save and restore the internal
1931 ! Common, and obtain specified derivatives of the solution y(t).
1932 ! 3. Descriptions of Common blocks to be declared in overlay
1933 ! or similar environments, or to be saved when doing an interrupt
1934 ! of the problem and continued solution later.
1935 ! 4. Description of two routines in the DLSODES package, either of
1936 ! which the user may replace with his/her own version, if desired.
1937 ! These relate to the measurement of errors.
1938 !-----------------------------------------------------------------------
1939 ! Part 1. Call Sequence.
1940 ! The call sequence parameters used for input only are
1941 ! F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC, MF,
1942 ! and those used for both input and output are
1943 ! Y, T, ISTATE.
1944 ! The work arrays RWORK and IWORK are also used for conditional and
1945 ! optional inputs and optional outputs. (The term output here refers
1946 ! to the return from Subroutine DLSODES to the user's calling program.)
1947 ! The legality of input parameters will be thoroughly checked on the
1948 ! initial call for the problem, but not checked thereafter unless a
1949 ! change in input parameters is flagged by ISTATE = 3 on input.
1950 ! The descriptions of the call arguments are as follows.
1951 ! F = the name of the user-supplied subroutine defining the
1952 ! ODE system. The system must be put in the first-order
1953 ! form dy/dt = f(t,y), where f is a vector-valued function
1954 ! of the scalar t and the vector y. Subroutine F is to
1955 ! compute the function f. It is to have the form
1956 ! SUBROUTINE F (NEQ, T, Y, YDOT)
1957 ! DOUBLE PRECISION T, Y(*), YDOT(*)
1958 ! where NEQ, T, and Y are input, and the array YDOT = f(t,y)
1959 ! is output. Y and YDOT are arrays of length NEQ.
1960 ! Subroutine F should not alter y(1),...,y(NEQ).
1961 ! F must be declared External in the calling program.
1962 ! Subroutine F may access user-defined quantities in
1963 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
1964 ! (dimensioned in F) and/or Y has length exceeding NEQ(1).
1965 ! See the descriptions of NEQ and Y below.
1966 ! If quantities computed in the F routine are needed
1967 ! externally to DLSODES, an extra call to F should be made
1968 ! for this purpose, for consistent and accurate results.
1969 ! If only the derivative dy/dt is needed, use DINTDY instead.
1970 ! NEQ = the size of the ODE system (number of first order
1971 ! ordinary differential equations). Used only for input.
1972 ! NEQ may be decreased, but not increased, during the problem.
1973 ! If NEQ is decreased (with ISTATE = 3 on input), the
1974 ! remaining components of Y should be left undisturbed, if
1975 ! these are to be accessed in F and/or JAC.
1976 ! Normally, NEQ is a scalar, and it is generally referred to
1977 ! as a scalar in this user interface description. However,
1978 ! NEQ may be an array, with NEQ(1) set to the system size.
1979 ! (The DLSODES package accesses only NEQ(1).) In either case,
1980 ! this parameter is passed as the NEQ argument in all calls
1981 ! to F and JAC. Hence, if it is an array, locations
1982 ! NEQ(2),... may be used to store other integer data and pass
1983 ! it to F and/or JAC. Subroutines F and/or JAC must include
1984 ! NEQ in a Dimension statement in that case.
1985 ! Y = a real array for the vector of dependent variables, of
1986 ! length NEQ or more. Used for both input and output on the
1987 ! first call (ISTATE = 1), and only for output on other calls.
1988 ! on the first call, Y must contain the vector of initial
1989 ! values. On output, Y contains the computed solution vector,
1990 ! evaluated at T. If desired, the Y array may be used
1991 ! for other purposes between calls to the solver.
1992 ! This array is passed as the Y argument in all calls to
1993 ! F and JAC. Hence its length may exceed NEQ, and locations
1994 ! Y(NEQ+1),... may be used to store other real data and
1995 ! pass it to F and/or JAC. (The DLSODES package accesses only
1996 ! Y(1),...,Y(NEQ).)
1997 ! T = the independent variable. On input, T is used only on the
1998 ! first call, as the initial point of the integration.
1999 ! on output, after each call, T is the value at which a
2000 ! computed solution Y is evaluated (usually the same as TOUT).
2001 ! On an error return, T is the farthest point reached.
2002 ! TOUT = the next value of t at which a computed solution is desired.
2003 ! Used only for input.
2004 ! When starting the problem (ISTATE = 1), TOUT may be equal
2005 ! to T for one call, then should .ne. T for the next call.
2006 ! For the initial T, an input value of TOUT .ne. T is used
2007 ! in order to determine the direction of the integration
2008 ! (i.e. the algebraic sign of the step sizes) and the rough
2009 ! scale of the problem. Integration in either direction
2010 ! (forward or backward in t) is permitted.
2011 ! If ITASK = 2 or 5 (one-step modes), TOUT is ignored after
2012 ! the first call (i.e. the first call with TOUT .ne. T).
2013 ! Otherwise, TOUT is required on every call.
2014 ! If ITASK = 1, 3, or 4, the values of TOUT need not be
2015 ! monotone, but a value of TOUT which backs up is limited
2016 ! to the current internal T interval, whose endpoints are
2017 ! TCUR - HU and TCUR (see optional outputs, below, for
2018 ! TCUR and HU).
2019 ! ITOL = an indicator for the type of error control. See
2020 ! description below under ATOL. Used only for input.
2021 ! RTOL = a relative error tolerance parameter, either a scalar or
2022 ! an array of length NEQ. See description below under ATOL.
2023 ! Input only.
2024 ! ATOL = an absolute error tolerance parameter, either a scalar or
2025 ! an array of length NEQ. Input only.
2026 ! The input parameters ITOL, RTOL, and ATOL determine
2027 ! the error control performed by the solver. The solver will
2028 ! control the vector E = (E(i)) of estimated local errors
2029 ! in y, according to an inequality of the form
2030 ! RMS-norm of ( E(i)/EWT(i) ) .le. 1,
2031 ! where EWT(i) = RTOL(i)*ABS(Y(i)) + ATOL(i),
2032 ! and the RMS-norm (root-mean-square norm) here is
2033 ! RMS-norm(v) = SQRT(sum v(i)**2 / NEQ). Here EWT = (EWT(i))
2034 ! is a vector of weights which must always be positive, and
2035 ! the values of RTOL and ATOL should all be non-negative.
2036 ! The following table gives the types (scalar/array) of
2037 ! RTOL and ATOL, and the corresponding form of EWT(i).
2038 ! ITOL RTOL ATOL EWT(i)
2039 ! 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
2040 ! 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
2041 ! 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
2042 ! 4 array array RTOL(i)*ABS(Y(i)) + ATOL(i)
2043 ! When either of these parameters is a scalar, it need not
2044 ! be dimensioned in the user's calling program.
2045 ! If none of the above choices (with ITOL, RTOL, and ATOL
2046 ! fixed throughout the problem) is suitable, more general
2047 ! error controls can be obtained by substituting
2048 ! user-supplied routines for the setting of EWT and/or for
2049 ! the norm calculation. See Part 4 below.
2050 ! If global errors are to be estimated by making a repeated
2051 ! run on the same problem with smaller tolerances, then all
2052 ! components of RTOL and ATOL (i.e. of EWT) should be scaled
2053 ! down uniformly.
2054 ! ITASK = an index specifying the task to be performed.
2055 ! Input only. ITASK has the following values and meanings.
2056 ! 1 means normal computation of output values of y(t) at
2057 ! t = TOUT (by overshooting and interpolating).
2058 ! 2 means take one step only and return.
2059 ! 3 means stop at the first internal mesh point at or
2060 ! beyond t = TOUT and return.
2061 ! 4 means normal computation of output values of y(t) at
2062 ! t = TOUT but without overshooting t = TCRIT.
2063 ! TCRIT must be input as RWORK(1). TCRIT may be equal to
2064 ! or beyond TOUT, but not behind it in the direction of
2065 ! integration. This option is useful if the problem
2066 ! has a singularity at or beyond t = TCRIT.
2067 ! 5 means take one step, without passing TCRIT, and return.
2068 ! TCRIT must be input as RWORK(1).
2069 ! Note: If ITASK = 4 or 5 and the solver reaches TCRIT
2070 ! (within roundoff), it will return T = TCRIT (exactly) to
2071 ! indicate this (unless ITASK = 4 and TOUT comes before TCRIT,
2072 ! in which case answers at t = TOUT are returned first).
2073 ! ISTATE = an index used for input and output to specify the
2074 ! the state of the calculation.
2075 ! On input, the values of ISTATE are as follows.
2076 ! 1 means this is the first call for the problem
2077 ! (initializations will be done). See note below.
2078 ! 2 means this is not the first call, and the calculation
2079 ! is to continue normally, with no change in any input
2080 ! parameters except possibly TOUT and ITASK.
2081 ! (If ITOL, RTOL, and/or ATOL are changed between calls
2082 ! with ISTATE = 2, the new values will be used but not
2083 ! tested for legality.)
2084 ! 3 means this is not the first call, and the
2085 ! calculation is to continue normally, but with
2086 ! a change in input parameters other than
2087 ! TOUT and ITASK. Changes are allowed in
2088 ! NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF,
2089 ! the conditional inputs IA and JA,
2090 ! and any of the optional inputs except H0.
2091 ! In particular, if MITER = 1 or 2, a call with ISTATE = 3
2092 ! will cause the sparsity structure of the problem to be
2093 ! recomputed (or reread from IA and JA if MOSS = 0).
2094 ! Note: a preliminary call with TOUT = T is not counted
2095 ! as a first call here, as no initialization or checking of
2096 ! input is done. (Such a call is sometimes useful for the
2097 ! purpose of outputting the initial conditions.)
2098 ! Thus the first call for which TOUT .ne. T requires
2099 ! ISTATE = 1 on input.
2100 ! On output, ISTATE has the following values and meanings.
2101 ! 1 means nothing was done; TOUT = T and ISTATE = 1 on input.
2102 ! 2 means the integration was performed successfully.
2103 ! -1 means an excessive amount of work (more than MXSTEP
2104 ! steps) was done on this call, before completing the
2105 ! requested task, but the integration was otherwise
2106 ! successful as far as T. (MXSTEP is an optional input
2107 ! and is normally 500.) To continue, the user may
2108 ! simply reset ISTATE to a value .gt. 1 and call again
2109 ! (the excess work step counter will be reset to 0).
2110 ! In addition, the user may increase MXSTEP to avoid
2111 ! this error return (see below on optional inputs).
2112 ! -2 means too much accuracy was requested for the precision
2113 ! of the machine being used. This was detected before
2114 ! completing the requested task, but the integration
2115 ! was successful as far as T. To continue, the tolerance
2116 ! parameters must be reset, and ISTATE must be set
2117 ! to 3. The optional output TOLSF may be used for this
2118 ! purpose. (Note: If this condition is detected before
2119 ! taking any steps, then an illegal input return
2120 ! (ISTATE = -3) occurs instead.)
2121 ! -3 means illegal input was detected, before taking any
2122 ! integration steps. See written message for details.
2123 ! Note: If the solver detects an infinite loop of calls
2124 ! to the solver with illegal input, it will cause
2125 ! the run to stop.
2126 ! -4 means there were repeated error test failures on
2127 ! one attempted step, before completing the requested
2128 ! task, but the integration was successful as far as T.
2129 ! The problem may have a singularity, or the input
2130 ! may be inappropriate.
2131 ! -5 means there were repeated convergence test failures on
2132 ! one attempted step, before completing the requested
2133 ! task, but the integration was successful as far as T.
2134 ! This may be caused by an inaccurate Jacobian matrix,
2135 ! if one is being used.
2136 ! -6 means EWT(i) became zero for some i during the
2137 ! integration. Pure relative error control (ATOL(i)=0.0)
2138 ! was requested on a variable which has now vanished.
2139 ! The integration was successful as far as T.
2140 ! -7 means a fatal error return flag came from the sparse
2141 ! solver CDRV by way of DPRJS or DSOLSS (numerical
2142 ! factorization or backsolve). This should never happen.
2143 ! The integration was successful as far as T.
2144 ! Note: an error return with ISTATE = -1, -4, or -5 and with
2145 ! MITER = 1 or 2 may mean that the sparsity structure of the
2146 ! problem has changed significantly since it was last
2147 ! determined (or input). In that case, one can attempt to
2148 ! complete the integration by setting ISTATE = 3 on the next
2149 ! call, so that a new structure determination is done.
2150 ! Note: since the normal output value of ISTATE is 2,
2151 ! it does not need to be reset for normal continuation.
2152 ! Also, since a negative input value of ISTATE will be
2153 ! regarded as illegal, a negative output value requires the
2154 ! user to change it, and possibly other inputs, before
2155 ! calling the solver again.
2156 ! IOPT = an integer flag to specify whether or not any optional
2157 ! inputs are being used on this call. Input only.
2158 ! The optional inputs are listed separately below.
2159 ! IOPT = 0 means no optional inputs are being used.
2160 ! Default values will be used in all cases.
2161 ! IOPT = 1 means one or more optional inputs are being used.
2162 ! RWORK = a work array used for a mixture of real (double precision)
2163 ! and integer work space.
2164 ! The length of RWORK (in real words) must be at least
2165 ! 20 + NYH*(MAXORD + 1) + 3*NEQ + LWM where
2166 ! NYH = the initial value of NEQ,
2167 ! MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a
2168 ! smaller value is given as an optional input),
2169 ! LWM = 0 if MITER = 0,
2170 ! LWM = 2*NNZ + 2*NEQ + (NNZ+9*NEQ)/LENRAT if MITER = 1,
2171 ! LWM = 2*NNZ + 2*NEQ + (NNZ+10*NEQ)/LENRAT if MITER = 2,
2172 ! LWM = NEQ + 2 if MITER = 3.
2173 ! In the above formulas,
2174 ! NNZ = number of nonzero elements in the Jacobian matrix.
2175 ! LENRAT = the real to integer wordlength ratio (usually 1 in
2176 ! single precision and 2 in double precision).
2177 ! (See the MF description for METH and MITER.)
2178 ! Thus if MAXORD has its default value and NEQ is constant,
2179 ! the minimum length of RWORK is:
2180 ! 20 + 16*NEQ for MF = 10,
2181 ! 20 + 16*NEQ + LWM for MF = 11, 111, 211, 12, 112, 212,
2182 ! 22 + 17*NEQ for MF = 13,
2183 ! 20 + 9*NEQ for MF = 20,
2184 ! 20 + 9*NEQ + LWM for MF = 21, 121, 221, 22, 122, 222,
2185 ! 22 + 10*NEQ for MF = 23.
2186 ! If MITER = 1 or 2, the above formula for LWM is only a
2187 ! crude lower bound. The required length of RWORK cannot
2188 ! be readily predicted in general, as it depends on the
2189 ! sparsity structure of the problem. Some experimentation
2190 ! may be necessary.
2191 ! The first 20 words of RWORK are reserved for conditional
2192 ! and optional inputs and optional outputs.
2193 ! The following word in RWORK is a conditional input:
2194 ! RWORK(1) = TCRIT = critical value of t which the solver
2195 ! is not to overshoot. Required if ITASK is
2196 ! 4 or 5, and ignored otherwise. (See ITASK.)
2197 ! LRW = the length of the array RWORK, as declared by the user.
2198 ! (This will be checked by the solver.)
2199 ! IWORK = an integer work array. The length of IWORK must be at least
2200 ! 31 + NEQ + NNZ if MOSS = 0 and MITER = 1 or 2, or
2201 ! 30 otherwise.
2202 ! (NNZ is the number of nonzero elements in df/dy.)
2203 ! In DLSODES, IWORK is used only for conditional and
2204 ! optional inputs and optional outputs.
2205 ! The following two blocks of words in IWORK are conditional
2206 ! inputs, required if MOSS = 0 and MITER = 1 or 2, but not
2207 ! otherwise (see the description of MF for MOSS).
2208 ! IWORK(30+j) = IA(j) (j=1,...,NEQ+1)
2209 ! IWORK(31+NEQ+k) = JA(k) (k=1,...,NNZ)
2210 ! The two arrays IA and JA describe the sparsity structure
2211 ! to be assumed for the Jacobian matrix. JA contains the row
2212 ! indices where nonzero elements occur, reading in columnwise
2213 ! order, and IA contains the starting locations in JA of the
2214 ! descriptions of columns 1,...,NEQ, in that order, with
2215 ! IA(1) = 1. Thus, for each column index j = 1,...,NEQ, the
2216 ! values of the row index i in column j where a nonzero
2217 ! element may occur are given by
2218 ! i = JA(k), where IA(j) .le. k .lt. IA(j+1).
2219 ! If NNZ is the total number of nonzero locations assumed,
2220 ! then the length of the JA array is NNZ, and IA(NEQ+1) must
2221 ! be NNZ + 1. Duplicate entries are not allowed.
2222 ! LIW = the length of the array IWORK, as declared by the user.
2223 ! (This will be checked by the solver.)
2224 ! Note: The work arrays must not be altered between calls to DLSODES
2225 ! for the same problem, except possibly for the conditional and
2226 ! optional inputs, and except for the last 3*NEQ words of RWORK.
2227 ! The latter space is used for internal scratch space, and so is
2228 ! available for use by the user outside DLSODES between calls, if
2229 ! desired (but not for use by F or JAC).
2230 ! JAC = name of user-supplied routine (MITER = 1 or MOSS = 1) to
2231 ! compute the Jacobian matrix, df/dy, as a function of
2232 ! the scalar t and the vector y. It is to have the form
2233 ! SUBROUTINE JAC (NEQ, T, Y, J, IAN, JAN, PDJ)
2234 ! DOUBLE PRECISION T, Y(*), IAN(*), JAN(*), PDJ(*)
2235 ! where NEQ, T, Y, J, IAN, and JAN are input, and the array
2236 ! PDJ, of length NEQ, is to be loaded with column J
2237 ! of the Jacobian on output. Thus df(i)/dy(J) is to be
2238 ! loaded into PDJ(i) for all relevant values of i.
2239 ! Here T and Y have the same meaning as in Subroutine F,
2240 ! and J is a column index (1 to NEQ). IAN and JAN are
2241 ! undefined in calls to JAC for structure determination
2242 ! (MOSS = 1). otherwise, IAN and JAN are structure
2243 ! descriptors, as defined under optional outputs below, and
2244 ! so can be used to determine the relevant row indices i, if
2245 ! desired.
2246 ! JAC need not provide df/dy exactly. A crude
2247 ! approximation (possibly with greater sparsity) will do.
2248 ! In any case, PDJ is preset to zero by the solver,
2249 ! so that only the nonzero elements need be loaded by JAC.
2250 ! Calls to JAC are made with J = 1,...,NEQ, in that order, and
2251 ! each such set of calls is preceded by a call to F with the
2252 ! same arguments NEQ, T, and Y. Thus to gain some efficiency,
2253 ! intermediate quantities shared by both calculations may be
2254 ! saved in a user Common block by F and not recomputed by JAC,
2255 ! if desired. JAC must not alter its input arguments.
2256 ! JAC must be declared External in the calling program.
2257 ! Subroutine JAC may access user-defined quantities in
2258 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
2259 ! (dimensioned in JAC) and/or Y has length exceeding NEQ(1).
2260 ! See the descriptions of NEQ and Y above.
2261 ! MF = the method flag. Used only for input.
2262 ! MF has three decimal digits-- MOSS, METH, MITER--
2263 ! MF = 100*MOSS + 10*METH + MITER.
2264 ! MOSS indicates the method to be used to obtain the sparsity
2265 ! structure of the Jacobian matrix if MITER = 1 or 2:
2266 ! MOSS = 0 means the user has supplied IA and JA
2267 ! (see descriptions under IWORK above).
2268 ! MOSS = 1 means the user has supplied JAC (see below)
2269 ! and the structure will be obtained from NEQ
2270 ! initial calls to JAC.
2271 ! MOSS = 2 means the structure will be obtained from NEQ+1
2272 ! initial calls to F.
2273 ! METH indicates the basic linear multistep method:
2274 ! METH = 1 means the implicit Adams method.
2275 ! METH = 2 means the method based on Backward
2276 ! Differentiation Formulas (BDFs).
2277 ! MITER indicates the corrector iteration method:
2278 ! MITER = 0 means functional iteration (no Jacobian matrix
2279 ! is involved).
2280 ! MITER = 1 means chord iteration with a user-supplied
2281 ! sparse Jacobian, given by Subroutine JAC.
2282 ! MITER = 2 means chord iteration with an internally
2283 ! generated (difference quotient) sparse Jacobian
2284 ! (using NGP extra calls to F per df/dy value,
2285 ! where NGP is an optional output described below.)
2286 ! MITER = 3 means chord iteration with an internally
2287 ! generated diagonal Jacobian approximation
2288 ! (using 1 extra call to F per df/dy evaluation).
2289 ! If MITER = 1 or MOSS = 1, the user must supply a Subroutine
2290 ! JAC (the name is arbitrary) as described above under JAC.
2291 ! Otherwise, a dummy argument can be used.
2292 ! The standard choices for MF are:
2293 ! MF = 10 for a nonstiff problem,
2294 ! MF = 21 or 22 for a stiff problem with IA/JA supplied
2295 ! (21 if JAC is supplied, 22 if not),
2296 ! MF = 121 for a stiff problem with JAC supplied,
2297 ! but not IA/JA,
2298 ! MF = 222 for a stiff problem with neither IA/JA nor
2299 ! JAC supplied.
2300 ! The sparseness structure can be changed during the
2301 ! problem by making a call to DLSODES with ISTATE = 3.
2302 !-----------------------------------------------------------------------
2303 ! Optional Inputs.
2304 ! The following is a list of the optional inputs provided for in the
2305 ! call sequence. (See also Part 2.) For each such input variable,
2306 ! this table lists its name as used in this documentation, its
2307 ! location in the call sequence, its meaning, and the default value.
2308 ! The use of any of these inputs requires IOPT = 1, and in that
2309 ! case all of these inputs are examined. A value of zero for any
2310 ! of these optional inputs will cause the default value to be used.
2311 ! Thus to use a subset of the optional inputs, simply preload
2312 ! locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, and
2313 ! then set those of interest to nonzero values.
2314 ! Name Location Meaning and Default Value
2315 ! H0 RWORK(5) the step size to be attempted on the first step.
2316 ! The default value is determined by the solver.
2317 ! HMAX RWORK(6) the maximum absolute step size allowed.
2318 ! The default value is infinite.
2319 ! HMIN RWORK(7) the minimum absolute step size allowed.
2320 ! The default value is 0. (This lower bound is not
2321 ! enforced on the final step before reaching TCRIT
2322 ! when ITASK = 4 or 5.)
2323 ! SETH RWORK(8) the element threshhold for sparsity determination
2324 ! when MOSS = 1 or 2. If the absolute value of
2325 ! an estimated Jacobian element is .le. SETH, it
2326 ! will be assumed to be absent in the structure.
2327 ! The default value of SETH is 0.
2328 ! MAXORD IWORK(5) the maximum order to be allowed. The default
2329 ! value is 12 if METH = 1, and 5 if METH = 2.
2330 ! If MAXORD exceeds the default value, it will
2331 ! be reduced to the default value.
2332 ! If MAXORD is changed during the problem, it may
2333 ! cause the current order to be reduced.
2334 ! MXSTEP IWORK(6) maximum number of (internally defined) steps
2335 ! allowed during one call to the solver.
2336 ! The default value is 500.
2337 ! MXHNIL IWORK(7) maximum number of messages printed (per problem)
2338 ! warning that T + H = T on a step (H = step size).
2339 ! This must be positive to result in a non-default
2340 ! value. The default value is 10.
2341 !-----------------------------------------------------------------------
2342 ! Optional Outputs.
2343 ! As optional additional output from DLSODES, the variables listed
2344 ! below are quantities related to the performance of DLSODES
2345 ! which are available to the user. These are communicated by way of
2346 ! the work arrays, but also have internal mnemonic names as shown.
2347 ! Except where stated otherwise, all of these outputs are defined
2348 ! on any successful return from DLSODES, and on any return with
2349 ! ISTATE = -1, -2, -4, -5, or -6. On an illegal input return
2350 ! (ISTATE = -3), they will be unchanged from their existing values
2351 ! (if any), except possibly for TOLSF, LENRW, and LENIW.
2352 ! On any error return, outputs relevant to the error will be defined,
2353 ! as noted below.
2354 ! Name Location Meaning
2355 ! HU RWORK(11) the step size in t last used (successfully).
2356 ! HCUR RWORK(12) the step size to be attempted on the next step.
2357 ! TCUR RWORK(13) the current value of the independent variable
2358 ! which the solver has actually reached, i.e. the
2359 ! current internal mesh point in t. On output, TCUR
2360 ! will always be at least as far as the argument
2361 ! T, but may be farther (if interpolation was done).
2362 ! TOLSF RWORK(14) a tolerance scale factor, greater than 1.0,
2363 ! computed when a request for too much accuracy was
2364 ! detected (ISTATE = -3 if detected at the start of
2365 ! the problem, ISTATE = -2 otherwise). If ITOL is
2366 ! left unaltered but RTOL and ATOL are uniformly
2367 ! scaled up by a factor of TOLSF for the next call,
2368 ! then the solver is deemed likely to succeed.
2369 ! (The user may also ignore TOLSF and alter the
2370 ! tolerance parameters in any other way appropriate.)
2371 ! NST IWORK(11) the number of steps taken for the problem so far.
2372 ! NFE IWORK(12) the number of f evaluations for the problem so far,
2373 ! excluding those for structure determination
2374 ! (MOSS = 2).
2375 ! NJE IWORK(13) the number of Jacobian evaluations for the problem
2376 ! so far, excluding those for structure determination
2377 ! (MOSS = 1).
2378 ! NQU IWORK(14) the method order last used (successfully).
2379 ! NQCUR IWORK(15) the order to be attempted on the next step.
2380 ! IMXER IWORK(16) the index of the component of largest magnitude in
2381 ! the weighted local error vector ( E(i)/EWT(i) ),
2382 ! on an error return with ISTATE = -4 or -5.
2383 ! LENRW IWORK(17) the length of RWORK actually required.
2384 ! This is defined on normal returns and on an illegal
2385 ! input return for insufficient storage.
2386 ! LENIW IWORK(18) the length of IWORK actually required.
2387 ! This is defined on normal returns and on an illegal
2388 ! input return for insufficient storage.
2389 ! NNZ IWORK(19) the number of nonzero elements in the Jacobian
2390 ! matrix, including the diagonal (MITER = 1 or 2).
2391 ! (This may differ from that given by IA(NEQ+1)-1
2392 ! if MOSS = 0, because of added diagonal entries.)
2393 ! NGP IWORK(20) the number of groups of column indices, used in
2394 ! difference quotient Jacobian aproximations if
2395 ! MITER = 2. This is also the number of extra f
2396 ! evaluations needed for each Jacobian evaluation.
2397 ! NLU IWORK(21) the number of sparse LU decompositions for the
2398 ! problem so far.
2399 ! LYH IWORK(22) the base address in RWORK of the history array YH,
2400 ! described below in this list.
2401 ! IPIAN IWORK(23) the base address of the structure descriptor array
2402 ! IAN, described below in this list.
2403 ! IPJAN IWORK(24) the base address of the structure descriptor array
2404 ! JAN, described below in this list.
2405 ! NZL IWORK(25) the number of nonzero elements in the strict lower
2406 ! triangle of the LU factorization used in the chord
2407 ! iteration (MITER = 1 or 2).
2408 ! NZU IWORK(26) the number of nonzero elements in the strict upper
2409 ! triangle of the LU factorization used in the chord
2410 ! iteration (MITER = 1 or 2).
2411 ! The total number of nonzeros in the factorization
2412 ! is therefore NZL + NZU + NEQ.
2413 ! The following four arrays are segments of the RWORK array which
2414 ! may also be of interest to the user as optional outputs.
2415 ! For each array, the table below gives its internal name,
2416 ! its base address, and its description.
2417 ! For YH and ACOR, the base addresses are in RWORK (a real array).
2418 ! The integer arrays IAN and JAN are to be obtained by declaring an
2419 ! integer array IWK and identifying IWK(1) with RWORK(21), using either
2420 ! an equivalence statement or a subroutine call. Then the base
2421 ! addresses IPIAN (of IAN) and IPJAN (of JAN) in IWK are to be obtained
2422 ! as optional outputs IWORK(23) and IWORK(24), respectively.
2423 ! Thus IAN(1) is IWK(IPIAN), etc.
2424 ! Name Base Address Description
2425 ! IAN IPIAN (in IWK) structure descriptor array of size NEQ + 1.
2426 ! JAN IPJAN (in IWK) structure descriptor array of size NNZ.
2427 ! (see above) IAN and JAN together describe the sparsity
2428 ! structure of the Jacobian matrix, as used by
2429 ! DLSODES when MITER = 1 or 2.
2430 ! JAN contains the row indices of the nonzero
2431 ! locations, reading in columnwise order, and
2432 ! IAN contains the starting locations in JAN of
2433 ! the descriptions of columns 1,...,NEQ, in
2434 ! that order, with IAN(1) = 1. Thus for each
2435 ! j = 1,...,NEQ, the row indices i of the
2436 ! nonzero locations in column j are
2437 ! i = JAN(k), IAN(j) .le. k .lt. IAN(j+1).
2438 ! Note that IAN(NEQ+1) = NNZ + 1.
2439 ! (If MOSS = 0, IAN/JAN may differ from the
2440 ! input IA/JA because of a different ordering
2441 ! in each column, and added diagonal entries.)
2442 ! YH LYH the Nordsieck history array, of size NYH by
2443 ! (optional (NQCUR + 1), where NYH is the initial value
2444 ! output) of NEQ. For j = 0,1,...,NQCUR, column j+1
2445 ! of YH contains HCUR**j/factorial(j) times
2446 ! the j-th derivative of the interpolating
2447 ! polynomial currently representing the solution,
2448 ! evaluated at t = TCUR. The base address LYH
2449 ! is another optional output, listed above.
2450 ! ACOR LENRW-NEQ+1 array of size NEQ used for the accumulated
2451 ! corrections on each step, scaled on output
2452 ! to represent the estimated local error in y
2453 ! on the last step. This is the vector E in
2454 ! the description of the error control. It is
2455 ! defined only on a successful return from
2456 ! DLSODES.
2457 !-----------------------------------------------------------------------
2458 ! Part 2. Other Routines Callable.
2459 ! The following are optional calls which the user may make to
2460 ! gain additional capabilities in conjunction with DLSODES.
2461 ! (The routines XSETUN and XSETF are designed to conform to the
2462 ! SLATEC error handling package.)
2463 ! Form of Call Function
2464 ! CALL XSETUN(LUN) Set the logical unit number, LUN, for
2465 ! output of messages from DLSODES, if
2466 ! the default is not desired.
2467 ! The default value of LUN is 6.
2468 ! CALL XSETF(MFLAG) Set a flag to control the printing of
2469 ! messages by DLSODES.
2470 ! MFLAG = 0 means do not print. (Danger:
2471 ! This risks losing valuable information.)
2472 ! MFLAG = 1 means print (the default).
2473 ! Either of the above calls may be made at
2474 ! any time and will take effect immediately.
2475 ! CALL DSRCMS(RSAV,ISAV,JOB) saves and restores the contents of
2476 ! the internal Common blocks used by
2477 ! DLSODES (see Part 3 below).
2478 ! RSAV must be a real array of length 224
2479 ! or more, and ISAV must be an integer
2480 ! array of length 71 or more.
2481 ! JOB=1 means save Common into RSAV/ISAV.
2482 ! JOB=2 means restore Common from RSAV/ISAV.
2483 ! DSRCMS is useful if one is
2484 ! interrupting a run and restarting
2485 ! later, or alternating between two or
2486 ! more problems solved with DLSODES.
2487 ! CALL DINTDY(,,,,,) Provide derivatives of y, of various
2488 ! (see below) orders, at a specified point t, if
2489 ! desired. It may be called only after
2490 ! a successful return from DLSODES.
2491 ! The detailed instructions for using DINTDY are as follows.
2492 ! The form of the call is:
2493 ! LYH = IWORK(22)
2494 ! CALL DINTDY (T, K, RWORK(LYH), NYH, DKY, IFLAG)
2495 ! The input parameters are:
2496 ! T = value of independent variable where answers are desired
2497 ! (normally the same as the T last returned by DLSODES).
2498 ! For valid results, T must lie between TCUR - HU and TCUR.
2499 ! (See optional outputs for TCUR and HU.)
2500 ! K = integer order of the derivative desired. K must satisfy
2501 ! 0 .le. K .le. NQCUR, where NQCUR is the current order
2502 ! (See optional outputs). The capability corresponding
2503 ! to K = 0, i.e. computing y(T), is already provided
2504 ! by DLSODES directly. Since NQCUR .ge. 1, the first
2505 ! derivative dy/dt is always available with DINTDY.
2506 ! LYH = the base address of the history array YH, obtained
2507 ! as an optional output as shown above.
2508 ! NYH = column length of YH, equal to the initial value of NEQ.
2509 ! The output parameters are:
2510 ! DKY = a real array of length NEQ containing the computed value
2511 ! of the K-th derivative of y(t).
2512 ! IFLAG = integer flag, returned as 0 if K and T were legal,
2513 ! -1 if K was illegal, and -2 if T was illegal.
2514 ! On an error return, a message is also written.
2515 !-----------------------------------------------------------------------
2516 ! Part 3. Common Blocks.
2517 ! If DLSODES is to be used in an overlay situation, the user
2518 ! must declare, in the primary overlay, the variables in:
2519 ! (1) the call sequence to DLSODES, and
2520 ! (2) the two internal Common blocks
2521 ! /DLS001/ of length 255 (218 double precision words
2522 ! followed by 37 integer words),
2523 ! /DLSS01/ of length 40 (6 double precision words
2524 ! followed by 34 integer words),
2525 ! If DLSODES is used on a system in which the contents of internal
2526 ! Common blocks are not preserved between calls, the user should
2527 ! declare the above Common blocks in the calling program to insure
2528 ! that their contents are preserved.
2529 ! If the solution of a given problem by DLSODES is to be interrupted
2530 ! and then later continued, such as when restarting an interrupted run
2531 ! or alternating between two or more problems, the user should save,
2532 ! following the return from the last DLSODES call prior to the
2533 ! interruption, the contents of the call sequence variables and the
2534 ! internal Common blocks, and later restore these values before the
2535 ! next DLSODES call for that problem. To save and restore the Common
2536 ! blocks, use Subroutine DSRCMS (see Part 2 above).
2537 !-----------------------------------------------------------------------
2538 ! Part 4. Optionally Replaceable Solver Routines.
2539 ! Below are descriptions of two routines in the DLSODES package which
2540 ! relate to the measurement of errors. Either routine can be
2541 ! replaced by a user-supplied version, if desired. However, since such
2542 ! a replacement may have a major impact on performance, it should be
2543 ! done only when absolutely necessary, and only with great caution.
2544 ! (Note: The means by which the package version of a routine is
2545 ! superseded by the user's version may be system-dependent.)
2546 ! (a) DEWSET.
2547 ! The following subroutine is called just before each internal
2548 ! integration step, and sets the array of error weights, EWT, as
2549 ! described under ITOL/RTOL/ATOL above:
2550 ! Subroutine DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
2551 ! where NEQ, ITOL, RTOL, and ATOL are as in the DLSODES call sequence,
2552 ! YCUR contains the current dependent variable vector, and
2553 ! EWT is the array of weights set by DEWSET.
2554 ! If the user supplies this subroutine, it must return in EWT(i)
2555 ! (i = 1,...,NEQ) a positive quantity suitable for comparing errors
2556 ! in y(i) to. The EWT array returned by DEWSET is passed to the DVNORM
2557 ! routine (see below), and also used by DLSODES in the computation
2558 ! of the optional output IMXER, the diagonal Jacobian approximation,
2559 ! and the increments for difference quotient Jacobians.
2560 ! In the user-supplied version of DEWSET, it may be desirable to use
2561 ! the current values of derivatives of y. Derivatives up to order NQ
2562 ! are available from the history array YH, described above under
2563 ! optional outputs. In DEWSET, YH is identical to the YCUR array,
2564 ! extended to NQ + 1 columns with a column length of NYH and scale
2565 ! factors of H**j/factorial(j). On the first call for the problem,
2566 ! given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
2567 ! NYH is the initial value of NEQ. The quantities NQ, H, and NST
2568 ! can be obtained by including in DEWSET the statements:
2569 ! DOUBLE PRECISION RLS
2570 ! COMMON /DLS001/ RLS(218),ILS(37)
2571 ! NQ = ILS(33)
2572 ! NST = ILS(34)
2573 ! H = RLS(212)
2574 ! Thus, for example, the current value of dy/dt can be obtained as
2575 ! YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is
2576 ! unnecessary when NST = 0).
2577 ! (b) DVNORM.
2578 ! The following is a real function routine which computes the weighted
2579 ! root-mean-square norm of a vector v:
2580 ! D = DVNORM (N, V, W)
2581 ! where
2582 ! N = the length of the vector,
2583 ! V = real array of length N containing the vector,
2584 ! W = real array of length N containing weights,
2585 ! D = SQRT( (1/N) * sum(V(i)*W(i))**2 ).
2586 ! DVNORM is called with N = NEQ and with W(i) = 1.0/EWT(i), where
2587 ! EWT is as set by Subroutine DEWSET.
2588 ! If the user supplies this function, it should return a non-negative
2589 ! value of DVNORM suitable for use in the error control in DLSODES.
2590 ! None of the arguments should be altered by DVNORM.
2591 ! For example, a user-supplied DVNORM routine might:
2592 ! -substitute a max-norm of (V(i)*W(i)) for the RMS-norm, or
2593 ! -ignore some components of V in the norm, with the effect of
2594 ! suppressing the error control on those components of y.
2595 !-----------------------------------------------------------------------
2596 !***REVISION HISTORY (YYYYMMDD)
2597 ! 19810120 DATE WRITTEN
2598 ! 19820315 Upgraded MDI in ODRV package: operates on M + M-transpose.
2599 ! 19820426 Numerous revisions in use of work arrays;
2600 ! use wordlength ratio LENRAT; added IPISP & LRAT to Common;
2601 ! added optional outputs IPIAN/IPJAN;
2602 ! numerous corrections to comments.
2603 ! 19830503 Added routine CNTNZU; added NZL and NZU to /LSS001/;
2604 ! changed ADJLR call logic; added optional outputs NZL & NZU;
2605 ! revised counter initializations; revised PREP stmt. numbers;
2606 ! corrections to comments throughout.
2607 ! 19870320 Corrected jump on test of umax in CDRV routine;
2608 ! added ISTATE = -7 return.
2609 ! 19870330 Major update: corrected comments throughout;
2610 ! removed TRET from Common; rewrote EWSET with 4 loops;
2611 ! fixed t test in INTDY; added Cray directives in STODE;
2612 ! in STODE, fixed DELP init. and logic around PJAC call;
2613 ! combined routines to save/restore Common;
2614 ! passed LEVEL = 0 in error message calls (except run abort).
2615 ! 20010425 Major update: convert source lines to upper case;
2616 ! added *DECK lines; changed from 1 to * in dummy dimensions;
2617 ! changed names R1MACH/D1MACH to RUMACH/DUMACH;
2618 ! renamed routines for uniqueness across single/double prec.;
2619 ! converted intrinsic names to generic form;
2620 ! removed ILLIN and NTREP (data loaded) from Common;
2621 ! removed all 'own' variables from Common;
2622 ! changed error messages to quoted strings;
2623 ! replaced XERRWV/XERRWD with 1993 revised version;
2624 ! converted prologues, comments, error messages to mixed case;
2625 ! converted arithmetic IF statements to logical IF statements;
2626 ! numerous corrections to prologues and internal comments.
2627 ! 20010507 Converted single precision source to double precision.
2628 ! 20020502 Corrected declarations in descriptions of user routines.
2629 ! 20031105 Restored 'own' variables to Common blocks, to enable
2630 ! interrupt/restart feature.
2631 ! 20031112 Added SAVE statements for data-loaded constants.
2632 !-----------------------------------------------------------------------
2633 ! Other routines in the DLSODES package.
2634 ! In addition to Subroutine DLSODES, the DLSODES package includes the
2635 ! following subroutines and function routines:
2636 ! DIPREP acts as an iterface between DLSODES and DPREP, and also does
2637 ! adjusting of work space pointers and work arrays.
2638 ! DPREP is called by DIPREP to compute sparsity and do sparse matrix
2639 ! preprocessing if MITER = 1 or 2.
2640 ! JGROUP is called by DPREP to compute groups of Jacobian column
2641 ! indices for use when MITER = 2.
2642 ! ADJLR adjusts the length of required sparse matrix work space.
2643 ! It is called by DPREP.
2644 ! CNTNZU is called by DPREP and counts the nonzero elements in the
2645 ! strict upper triangle of J + J-transpose, where J = df/dy.
2646 ! DINTDY computes an interpolated value of the y vector at t = TOUT.
2647 ! DSTODE is the core integrator, which does one step of the
2648 ! integration and the associated error control.
2649 ! DCFODE sets all method coefficients and test constants.
2650 ! DPRJS computes and preprocesses the Jacobian matrix J = df/dy
2651 ! and the Newton iteration matrix P = I - h*l0*J.
2652 ! DSOLSS manages solution of linear system in chord iteration.
2653 ! DEWSET sets the error weight vector EWT before each step.
2654 ! DVNORM computes the weighted RMS-norm of a vector.
2655 ! DSRCMS is a user-callable routine to save and restore
2656 ! the contents of the internal Common blocks.
2657 ! ODRV constructs a reordering of the rows and columns of
2658 ! a matrix by the minimum degree algorithm. ODRV is a
2659 ! driver routine which calls Subroutines MD, MDI, MDM,
2660 ! MDP, MDU, and SRO. See Ref. 2 for details. (The ODRV
2661 ! module has been modified since Ref. 2, however.)
2662 ! CDRV performs reordering, symbolic factorization, numerical
2663 ! factorization, or linear system solution operations,
2664 ! depending on a path argument ipath. CDRV is a
2665 ! driver routine which calls Subroutines NROC, NSFC,
2666 ! NNFC, NNSC, and NNTC. See Ref. 3 for details.
2667 ! DLSODES uses CDRV to solve linear systems in which the
2668 ! coefficient matrix is P = I - con*J, where I is the
2669 ! identity, con is a scalar, and J is an approximation to
2670 ! the Jacobian df/dy. Because CDRV deals with rowwise
2671 ! sparsity descriptions, CDRV works with P-transpose, not P.
2672 ! DUMACH computes the unit roundoff in a machine-independent manner.
2673 ! XERRWD, XSETUN, XSETF, IXSAV, and IUMACH handle the printing of all
2674 ! error messages and warnings. XERRWD is machine-dependent.
2675 ! Note: DVNORM, DUMACH, IXSAV, and IUMACH are function routines.
2676 ! All the others are subroutines.
2677 !-----------------------------------------------------------------------
2678 ! EXTERNAL DPRJS, DSOLSS
2679 ! DOUBLE PRECISION :: DUMACH, DVNORM
2680 ! INTEGER :: INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS, &
2681 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
2682 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
2683 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
2684 ! INTEGER :: IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
2685 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
2686 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
2687 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
2688 ! INTEGER :: I, I1, I2, IFLAG, IMAX, IMUL, IMXER, IPFLAG, IPGO, IREM, &
2689 ! J, KGO, LENRAT, LENYHT, LENIW, LENRW, LF0, LIA, LJA, &
2690 ! LRTEM, LWTEM, LYHD, LYHN, MF1, MORD, MXHNL0, MXSTP0, NCOLM
2691 ! DOUBLE PRECISION :: ROWNS, &
2692 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
2693 ! DOUBLE PRECISION :: CON0, CONMIN, CCMXJ, PSMALL, RBIG, SETH
2694 ! DOUBLE PRECISION :: ATOLI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RTOLI, &
2695 ! TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0
2696 ! DIMENSION MORD(2)
2697 ! LOGICAL :: IHIT
2698 ! CHARACTER(60) :: MSG
2699 ! SAVE LENRAT, MORD, MXSTP0, MXHNL0
2700 !-----------------------------------------------------------------------
2701 ! The following two internal Common blocks contain
2702 ! (a) variables which are local to any subroutine but whose values must
2703 ! be preserved between calls to the routine ("own" variables), and
2704 ! (b) variables which are communicated between subroutines.
2705 ! The block DLS001 is declared in subroutines DLSODES, DIPREP, DPREP,
2706 ! DINTDY, DSTODE, DPRJS, and DSOLSS.
2707 ! The block DLSS01 is declared in subroutines DLSODES, DIPREP, DPREP,
2708 ! DPRJS, and DSOLSS.
2709 ! Groups of variables are replaced by dummy arrays in the Common
2710 ! declarations in routines where those variables are not used.
2711 !-----------------------------------------------------------------------
2712 ! COMMON /DLS001/ ROWNS(209), &
2713 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
2714 ! INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6), &
2715 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
2716 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
2717 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
2718 ! COMMON /DLSS01/ CON0, CONMIN, CCMXJ, PSMALL, RBIG, SETH, &
2719 ! IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
2720 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
2721 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
2722 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
2723 ! DATA MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
2724 !-----------------------------------------------------------------------
2725 ! In the Data statement below, set LENRAT equal to the ratio of
2726 ! the wordlength for a real number to that for an integer. Usually,
2727 ! LENRAT = 1 for single precision and 2 for double precision. If the
2728 ! true ratio is not an integer, use the next smaller integer (.ge. 1).
2729 !-----------------------------------------------------------------------
2730 ! DATA LENRAT/2/
2731 !-----------------------------------------------------------------------
2732 ! Block A.
2733 ! This code block is executed on every call.
2734 ! It tests ISTATE and ITASK for legality and branches appropriately.
2735 ! If ISTATE .gt. 1 but the flag INIT shows that initialization has
2736 ! not yet been done, an error return occurs.
2737 ! If ISTATE = 1 and TOUT = T, return immediately.
2738 !-----------------------------------------------------------------------
2739 ! IF (ISTATE < 1 .OR. ISTATE > 3) GO TO 601
2740 ! IF (ITASK < 1 .OR. ITASK > 5) GO TO 602
2741 ! IF (ISTATE == 1) GO TO 10
2742 ! IF (INIT == 0) GO TO 603
2743 ! IF (ISTATE == 2) GO TO 200
2744 ! GO TO 20
2745 ! 10 INIT = 0
2746 ! IF (TOUT == T) RETURN
2747 !-----------------------------------------------------------------------
2748 ! Block B.
2749 ! The next code block is executed for the initial call (ISTATE = 1),
2750 ! or for a continuation call with parameter changes (ISTATE = 3).
2751 ! It contains checking of all inputs and various initializations.
2752 ! If ISTATE = 1, the final setting of work space pointers, the matrix
2753 ! preprocessing, and other initializations are done in Block C.
2754 ! First check legality of the non-optional inputs NEQ, ITOL, IOPT,
2755 ! MF, ML, and MU.
2756 !-----------------------------------------------------------------------
2757 ! 20 IF (NEQ(1) <= 0) GO TO 604
2758 ! IF (ISTATE == 1) GO TO 25
2759 ! IF (NEQ(1) > N) GO TO 605
2760 ! 25 N = NEQ(1)
2761 ! IF (ITOL < 1 .OR. ITOL > 4) GO TO 606
2762 ! IF (IOPT < 0 .OR. IOPT > 1) GO TO 607
2763 ! MOSS = MF/100
2764 ! MF1 = MF - 100*MOSS
2765 ! METH = MF1/10
2766 ! MITER = MF1 - 10*METH
2767 ! IF (MOSS < 0 .OR. MOSS > 2) GO TO 608
2768 ! IF (METH < 1 .OR. METH > 2) GO TO 608
2769 ! IF (MITER < 0 .OR. MITER > 3) GO TO 608
2770 ! IF (MITER == 0 .OR. MITER == 3) MOSS = 0
2771 ! Next process and check the optional inputs. --------------------------
2772 ! IF (IOPT == 1) GO TO 40
2773 ! MAXORD = MORD(METH)
2774 ! MXSTEP = MXSTP0
2775 ! MXHNIL = MXHNL0
2776 ! IF (ISTATE == 1) H0 = 0.0D0
2777 ! HMXI = 0.0D0
2778 ! HMIN = 0.0D0
2779 ! SETH = 0.0D0
2780 ! GO TO 60
2781 ! 40 MAXORD = IWORK(5)
2782 ! IF (MAXORD < 0) GO TO 611
2783 ! IF (MAXORD == 0) MAXORD = 100
2784 ! MAXORD = MIN(MAXORD,MORD(METH))
2785 ! MXSTEP = IWORK(6)
2786 ! IF (MXSTEP < 0) GO TO 612
2787 ! IF (MXSTEP == 0) MXSTEP = MXSTP0
2788 ! MXHNIL = IWORK(7)
2789 ! IF (MXHNIL < 0) GO TO 613
2790 ! IF (MXHNIL == 0) MXHNIL = MXHNL0
2791 ! IF (ISTATE /= 1) GO TO 50
2792 ! H0 = RWORK(5)
2793 ! IF ((TOUT - T)*H0 < 0.0D0) GO TO 614
2794 ! 50 HMAX = RWORK(6)
2795 ! IF (HMAX < 0.0D0) GO TO 615
2796 ! HMXI = 0.0D0
2797 ! IF (HMAX > 0.0D0) HMXI = 1.0D0/HMAX
2798 ! HMIN = RWORK(7)
2799 ! IF (HMIN < 0.0D0) GO TO 616
2800 ! SETH = RWORK(8)
2801 ! IF (SETH < 0.0D0) GO TO 609
2802 ! Check RTOL and ATOL for legality. ------------------------------------
2803 ! 60 RTOLI = RTOL(1)
2804 ! ATOLI = ATOL(1)
2805 ! DO 65 I = 1,N
2806 ! IF (ITOL >= 3) RTOLI = RTOL(I)
2807 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
2808 ! IF (RTOLI < 0.0D0) GO TO 619
2809 ! IF (ATOLI < 0.0D0) GO TO 620
2810 ! 65 END DO
2811 !-----------------------------------------------------------------------
2812 ! Compute required work array lengths, as far as possible, and test
2813 ! these against LRW and LIW. Then set tentative pointers for work
2814 ! arrays. Pointers to RWORK/IWORK segments are named by prefixing L to
2815 ! the name of the segment. E.g., the segment YH starts at RWORK(LYH).
2816 ! Segments of RWORK (in order) are denoted WM, YH, SAVF, EWT, ACOR.
2817 ! If MITER = 1 or 2, the required length of the matrix work space WM
2818 ! is not yet known, and so a crude minimum value is used for the
2819 ! initial tests of LRW and LIW, and YH is temporarily stored as far
2820 ! to the right in RWORK as possible, to leave the maximum amount
2821 ! of space for WM for matrix preprocessing. Thus if MITER = 1 or 2
2822 ! and MOSS .ne. 2, some of the segments of RWORK are temporarily
2823 ! omitted, as they are not needed in the preprocessing. These
2824 ! omitted segments are: ACOR if ISTATE = 1, EWT and ACOR if ISTATE = 3
2825 ! and MOSS = 1, and SAVF, EWT, and ACOR if ISTATE = 3 and MOSS = 0.
2826 !-----------------------------------------------------------------------
2827 ! LRAT = LENRAT
2828 ! IF (ISTATE == 1) NYH = N
2829 ! LWMIN = 0
2830 ! IF (MITER == 1) LWMIN = 4*N + 10*N/LRAT
2831 ! IF (MITER == 2) LWMIN = 4*N + 11*N/LRAT
2832 ! IF (MITER == 3) LWMIN = N + 2
2833 ! LENYH = (MAXORD+1)*NYH
2834 ! LREST = LENYH + 3*N
2835 ! LENRW = 20 + LWMIN + LREST
2836 ! IWORK(17) = LENRW
2837 ! LENIW = 30
2838 ! IF (MOSS == 0 .AND. MITER /= 0 .AND. MITER /= 3) &
2839 ! LENIW = LENIW + N + 1
2840 ! IWORK(18) = LENIW
2841 ! IF (LENRW > LRW) GO TO 617
2842 ! IF (LENIW > LIW) GO TO 618
2843 ! LIA = 31
2844 ! IF (MOSS == 0 .AND. MITER /= 0 .AND. MITER /= 3) &
2845 ! LENIW = LENIW + IWORK(LIA+N) - 1
2846 ! IWORK(18) = LENIW
2847 ! IF (LENIW > LIW) GO TO 618
2848 ! LJA = LIA + N + 1
2849 ! LIA = MIN(LIA,LIW)
2850 ! LJA = MIN(LJA,LIW)
2851 ! LWM = 21
2852 ! IF (ISTATE == 1) NQ = 1
2853 ! NCOLM = MIN(NQ+1,MAXORD+2)
2854 ! LENYHM = NCOLM*NYH
2855 ! LENYHT = LENYH
2856 ! IF (MITER == 1 .OR. MITER == 2) LENYHT = LENYHM
2857 ! IMUL = 2
2858 ! IF (ISTATE == 3) IMUL = MOSS
2859 ! IF (MOSS == 2) IMUL = 3
2860 ! LRTEM = LENYHT + IMUL*N
2861 ! LWTEM = LWMIN
2862 ! IF (MITER == 1 .OR. MITER == 2) LWTEM = LRW - 20 - LRTEM
2863 ! LENWK = LWTEM
2864 ! LYHN = LWM + LWTEM
2865 ! LSAVF = LYHN + LENYHT
2866 ! LEWT = LSAVF + N
2867 ! LACOR = LEWT + N
2868 ! ISTATC = ISTATE
2869 ! IF (ISTATE == 1) GO TO 100
2870 !-----------------------------------------------------------------------
2871 ! ISTATE = 3. Move YH to its new location.
2872 ! Note that only the part of YH needed for the next step, namely
2873 ! MIN(NQ+1,MAXORD+2) columns, is actually moved.
2874 ! A temporary error weight array EWT is loaded if MOSS = 2.
2875 ! Sparse matrix processing is done in DIPREP/DPREP if MITER = 1 or 2.
2876 ! If MAXORD was reduced below NQ, then the pointers are finally set
2877 ! so that SAVF is identical to YH(*,MAXORD+2).
2878 !-----------------------------------------------------------------------
2879 ! LYHD = LYH - LYHN
2880 ! IMAX = LYHN - 1 + LENYHM
2881 ! Move YH. Move right if LYHD < 0; move left if LYHD > 0. -------------
2882 ! IF (LYHD < 0) THEN
2883 ! DO 72 I = LYHN,IMAX
2884 ! J = IMAX + LYHN - I
2885 ! RWORK(J) = RWORK(J+LYHD)
2886 ! 72 END DO
2887 ! ENDIF
2888 ! IF (LYHD > 0) THEN
2889 ! DO 76 I = LYHN,IMAX
2890 ! RWORK(I) = RWORK(I+LYHD)
2891 ! 76 END DO
2892 ! ENDIF
2893 ! 80 LYH = LYHN
2894 ! IWORK(22) = LYH
2895 ! IF (MITER == 0 .OR. MITER == 3) GO TO 92
2896 ! IF (MOSS /= 2) GO TO 85
2897 ! Temporarily load EWT if MITER = 1 or 2 and MOSS = 2. -----------------
2898 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
2899 ! DO 82 I = 1,N
2900 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
2901 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
2902 ! 82 END DO
2903 ! 85 CONTINUE
2904 ! DIPREP and DPREP do sparse matrix preprocessing if MITER = 1 or 2. ---
2905 ! LSAVF = MIN(LSAVF,LRW)
2906 ! LEWT = MIN(LEWT,LRW)
2907 ! LACOR = MIN(LACOR,LRW)
2908 ! CALL DIPREP (NEQ, Y, RWORK, IWORK(LIA),IWORK(LJA), IPFLAG, F, JAC)
2909 ! LENRW = LWM - 1 + LENWK + LREST
2910 ! IWORK(17) = LENRW
2911 ! IF (IPFLAG /= -1) IWORK(23) = IPIAN
2912 ! IF (IPFLAG /= -1) IWORK(24) = IPJAN
2913 ! IPGO = -IPFLAG + 1
2914 ! GO TO (90, 628, 629, 630, 631, 632, 633), IPGO
2915 ! 90 IWORK(22) = LYH
2916 ! IF (LENRW > LRW) GO TO 617
2917 ! Set flag to signal parameter changes to DSTODE. ----------------------
2918 ! 92 JSTART = -1
2919 ! IF (N == NYH) GO TO 200
2920 ! NEQ was reduced. Zero part of YH to avoid undefined references. -----
2921 ! I1 = LYH + L*NYH
2922 ! I2 = LYH + (MAXORD + 1)*NYH - 1
2923 ! IF (I1 > I2) GO TO 200
2924 ! DO 95 I = I1,I2
2925 ! RWORK(I) = 0.0D0
2926 ! 95 END DO
2927 ! GO TO 200
2928 !-----------------------------------------------------------------------
2929 ! Block C.
2930 ! The next block is for the initial call only (ISTATE = 1).
2931 ! It contains all remaining initializations, the initial call to F,
2932 ! the sparse matrix preprocessing (MITER = 1 or 2), and the
2933 ! calculation of the initial step size.
2934 ! The error weights in EWT are inverted after being loaded.
2935 !-----------------------------------------------------------------------
2936 ! 100 CONTINUE
2937 ! LYH = LYHN
2938 ! IWORK(22) = LYH
2939 ! TN = T
2940 ! NST = 0
2941 ! H = 1.0D0
2942 ! NNZ = 0
2943 ! NGP = 0
2944 ! NZL = 0
2945 ! NZU = 0
2946 ! Load the initial value vector in YH. ---------------------------------
2947 ! DO 105 I = 1,N
2948 ! RWORK(I+LYH-1) = Y(I)
2949 ! 105 END DO
2950 ! Initial call to F. (LF0 points to YH(*,2).) -------------------------
2951 ! LF0 = LYH + NYH
2952 ! CALL F (NEQ, T, Y, RWORK(LF0))
2953 ! NFE = 1
2954 ! Load and invert the EWT array. (H is temporarily set to 1.0.) -------
2955 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
2956 ! DO 110 I = 1,N
2957 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
2958 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
2959 ! 110 END DO
2960 ! IF (MITER == 0 .OR. MITER == 3) GO TO 120
2961 ! DIPREP and DPREP do sparse matrix preprocessing if MITER = 1 or 2. ---
2962 ! LACOR = MIN(LACOR,LRW)
2963 ! CALL DIPREP (NEQ, Y, RWORK, IWORK(LIA),IWORK(LJA), IPFLAG, F, JAC)
2964 ! LENRW = LWM - 1 + LENWK + LREST
2965 ! IWORK(17) = LENRW
2966 ! IF (IPFLAG /= -1) IWORK(23) = IPIAN
2967 ! IF (IPFLAG /= -1) IWORK(24) = IPJAN
2968 ! IPGO = -IPFLAG + 1
2969 ! GO TO (115, 628, 629, 630, 631, 632, 633), IPGO
2970 ! 115 IWORK(22) = LYH
2971 ! IF (LENRW > LRW) GO TO 617
2972 ! Check TCRIT for legality (ITASK = 4 or 5). ---------------------------
2973 ! 120 CONTINUE
2974 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 125
2975 ! TCRIT = RWORK(1)
2976 ! IF ((TCRIT - TOUT)*(TOUT - T) < 0.0D0) GO TO 625
2977 ! IF (H0 /= 0.0D0 .AND. (T + H0 - TCRIT)*H0 > 0.0D0) &
2978 ! H0 = TCRIT - T
2979 ! Initialize all remaining parameters. ---------------------------------
2980 ! 125 UROUND = DUMACH()
2981 ! JSTART = 0
2982 ! IF (MITER /= 0) RWORK(LWM) = SQRT(UROUND)
2983 ! MSBJ = 50
2984 ! NSLJ = 0
2985 ! CCMXJ = 0.2D0
2986 ! PSMALL = 1000.0D0*UROUND
2987 ! RBIG = 0.01D0/PSMALL
2988 ! NHNIL = 0
2989 ! NJE = 0
2990 ! NLU = 0
2991 ! NSLAST = 0
2992 ! HU = 0.0D0
2993 ! NQU = 0
2994 ! CCMAX = 0.3D0
2995 ! MAXCOR = 3
2996 ! MSBP = 20
2997 ! MXNCF = 10
2998 !-----------------------------------------------------------------------
2999 ! The coding below computes the step size, H0, to be attempted on the
3000 ! first step, unless the user has supplied a value for this.
3001 ! First check that TOUT - T differs significantly from zero.
3002 ! A scalar tolerance quantity TOL is computed, as MAX(RTOL(i))
3003 ! if this is positive, or MAX(ATOL(i)/ABS(Y(i))) otherwise, adjusted
3004 ! so as to be between 100*UROUND and 1.0E-3.
3005 ! Then the computed value H0 is given by..
3006 ! NEQ
3007 ! H0**2 = TOL / ( w0**-2 + (1/NEQ) * Sum ( f(i)/ywt(i) )**2 )
3008 ! 1
3009 ! where w0 = MAX ( ABS(T), ABS(TOUT) ),
3010 ! f(i) = i-th component of initial value of f,
3011 ! ywt(i) = EWT(i)/TOL (a weight for y(i)).
3012 ! The sign of H0 is inferred from the initial values of TOUT and T.
3013 ! ABS(H0) is made .le. ABS(TOUT-T) in any case.
3014 !-----------------------------------------------------------------------
3015 ! LF0 = LYH + NYH
3016 ! IF (H0 /= 0.0D0) GO TO 180
3017 ! TDIST = ABS(TOUT - T)
3018 ! W0 = MAX(ABS(T),ABS(TOUT))
3019 ! IF (TDIST < 2.0D0*UROUND*W0) GO TO 622
3020 ! TOL = RTOL(1)
3021 ! IF (ITOL <= 2) GO TO 140
3022 ! DO 130 I = 1,N
3023 ! TOL = MAX(TOL,RTOL(I))
3024 ! 130 END DO
3025 ! 140 IF (TOL > 0.0D0) GO TO 160
3026 ! ATOLI = ATOL(1)
3027 ! DO 150 I = 1,N
3028 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
3029 ! AYI = ABS(Y(I))
3030 ! IF (AYI /= 0.0D0) TOL = MAX(TOL,ATOLI/AYI)
3031 ! 150 END DO
3032 ! 160 TOL = MAX(TOL,100.0D0*UROUND)
3033 ! TOL = MIN(TOL,0.001D0)
3034 ! SUM = DVNORM (N, RWORK(LF0), RWORK(LEWT))
3035 ! SUM = 1.0D0/(TOL*W0*W0) + TOL*SUM**2
3036 ! H0 = 1.0D0/SQRT(SUM)
3037 ! H0 = MIN(H0,TDIST)
3038 ! H0 = SIGN(H0,TOUT-T)
3039 ! Adjust H0 if necessary to meet HMAX bound. ---------------------------
3040 ! 180 RH = ABS(H0)*HMXI
3041 ! IF (RH > 1.0D0) H0 = H0/RH
3042 ! Load H with H0 and scale YH(*,2) by H0. ------------------------------
3043 ! H = H0
3044 ! DO 190 I = 1,N
3045 ! RWORK(I+LF0-1) = H0*RWORK(I+LF0-1)
3046 ! 190 END DO
3047 ! GO TO 270
3048 !-----------------------------------------------------------------------
3049 ! Block D.
3050 ! The next code block is for continuation calls only (ISTATE = 2 or 3)
3051 ! and is to check stop conditions before taking a step.
3052 !-----------------------------------------------------------------------
3053 ! 200 NSLAST = NST
3054 ! GO TO (210, 250, 220, 230, 240), ITASK
3055 ! 210 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
3056 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
3057 ! IF (IFLAG /= 0) GO TO 627
3058 ! T = TOUT
3059 ! GO TO 420
3060 ! 220 TP = TN - HU*(1.0D0 + 100.0D0*UROUND)
3061 ! IF ((TP - TOUT)*H > 0.0D0) GO TO 623
3062 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 250
3063 ! GO TO 400
3064 ! 230 TCRIT = RWORK(1)
3065 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
3066 ! IF ((TCRIT - TOUT)*H < 0.0D0) GO TO 625
3067 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 245
3068 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
3069 ! IF (IFLAG /= 0) GO TO 627
3070 ! T = TOUT
3071 ! GO TO 420
3072 ! 240 TCRIT = RWORK(1)
3073 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
3074 ! 245 HMX = ABS(TN) + ABS(H)
3075 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
3076 ! IF (IHIT) GO TO 400
3077 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
3078 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
3079 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
3080 ! IF (ISTATE == 2) JSTART = -2
3081 !-----------------------------------------------------------------------
3082 ! Block E.
3083 ! The next block is normally executed for all calls and contains
3084 ! the call to the one-step core integrator DSTODE.
3085 ! This is a looping point for the integration steps.
3086 ! First check for too many steps being taken, update EWT (if not at
3087 ! start of problem), check for too much accuracy being requested, and
3088 ! check for H below the roundoff level in T.
3089 !-----------------------------------------------------------------------
3090 ! 250 CONTINUE
3091 ! IF ((NST-NSLAST) >= MXSTEP) GO TO 500
3092 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
3093 ! DO 260 I = 1,N
3094 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 510
3095 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
3096 ! 260 END DO
3097 ! 270 TOLSF = UROUND*DVNORM (N, RWORK(LYH), RWORK(LEWT))
3098 ! IF (TOLSF <= 1.0D0) GO TO 280
3099 ! TOLSF = TOLSF*2.0D0
3100 ! IF (NST == 0) GO TO 626
3101 ! GO TO 520
3102 ! 280 IF ((TN + H) /= TN) GO TO 290
3103 ! NHNIL = NHNIL + 1
3104 ! IF (NHNIL > MXHNIL) GO TO 290
3105 ! MSG = 'DLSODES- Warning..Internal T (=R1) and H (=R2) are'
3106 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3107 ! MSG=' such that in the machine, T + H = T on the next step '
3108 ! CALL XERRWD (MSG, 60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3109 ! MSG = ' (H = step size). Solver will continue anyway.'
3110 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 2, TN, H)
3111 ! IF (NHNIL < MXHNIL) GO TO 290
3112 ! MSG = 'DLSODES- Above warning has been issued I1 times. '
3113 ! CALL XERRWD (MSG, 50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3114 ! MSG = ' It will not be issued again for this problem.'
3115 ! CALL XERRWD (MSG, 50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
3116 ! 290 CONTINUE
3117 !-----------------------------------------------------------------------
3118 ! CALL DSTODE(NEQ,Y,YH,NYH,YH,EWT,SAVF,ACOR,WM,WM,F,JAC,DPRJS,DSOLSS)
3119 !-----------------------------------------------------------------------
3120 ! CALL DSTODE (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT), &
3121 ! RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), RWORK(LWM), &
3122 ! F, JAC, DPRJS, DSOLSS)
3123 ! KGO = 1 - KFLAG
3124 ! GO TO (300, 530, 540, 550), KGO
3125 !-----------------------------------------------------------------------
3126 ! Block F.
3127 ! The following block handles the case of a successful return from the
3128 ! core integrator (KFLAG = 0). Test for stop conditions.
3129 !-----------------------------------------------------------------------
3130 ! 300 INIT = 1
3131 ! GO TO (310, 400, 330, 340, 350), ITASK
3132 ! ITASK = 1. if TOUT has been reached, interpolate. -------------------
3133 ! 310 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
3134 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
3135 ! T = TOUT
3136 ! GO TO 420
3137 ! ITASK = 3. Jump to exit if TOUT was reached. ------------------------
3138 ! 330 IF ((TN - TOUT)*H >= 0.0D0) GO TO 400
3139 ! GO TO 250
3140 ! ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary.
3141 ! 340 IF ((TN - TOUT)*H < 0.0D0) GO TO 345
3142 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
3143 ! T = TOUT
3144 ! GO TO 420
3145 ! 345 HMX = ABS(TN) + ABS(H)
3146 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
3147 ! IF (IHIT) GO TO 400
3148 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
3149 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
3150 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
3151 ! JSTART = -2
3152 ! GO TO 250
3153 ! ITASK = 5. See if TCRIT was reached and jump to exit. ---------------
3154 ! 350 HMX = ABS(TN) + ABS(H)
3155 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
3156 !-----------------------------------------------------------------------
3157 ! Block G.
3158 ! The following block handles all successful returns from DLSODES.
3159 ! If ITASK .ne. 1, Y is loaded from YH and T is set accordingly.
3160 ! ISTATE is set to 2, and the optional outputs are loaded into the
3161 ! work arrays before returning.
3162 !-----------------------------------------------------------------------
3163 ! 400 DO 410 I = 1,N
3164 ! Y(I) = RWORK(I+LYH-1)
3165 ! 410 END DO
3166 ! T = TN
3167 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 420
3168 ! IF (IHIT) T = TCRIT
3169 ! 420 ISTATE = 2
3170 ! RWORK(11) = HU
3171 ! RWORK(12) = H
3172 ! RWORK(13) = TN
3173 ! IWORK(11) = NST
3174 ! IWORK(12) = NFE
3175 ! IWORK(13) = NJE
3176 ! IWORK(14) = NQU
3177 ! IWORK(15) = NQ
3178 ! IWORK(19) = NNZ
3179 ! IWORK(20) = NGP
3180 ! IWORK(21) = NLU
3181 ! IWORK(25) = NZL
3182 ! IWORK(26) = NZU
3183 ! RETURN
3184 !-----------------------------------------------------------------------
3185 ! Block H.
3186 ! The following block handles all unsuccessful returns other than
3187 ! those for illegal input. First the error message routine is called.
3188 ! If there was an error test or convergence test failure, IMXER is set.
3189 ! Then Y is loaded from YH and T is set to TN.
3190 ! The optional outputs are loaded into the work arrays before returning.
3191 !-----------------------------------------------------------------------
3192 ! The maximum number of steps was taken before reaching TOUT. ----------
3193 ! 500 MSG = 'DLSODES- At current T (=R1), MXSTEP (=I1) steps '
3194 ! CALL XERRWD (MSG, 50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3195 ! MSG = ' taken on this call before reaching TOUT '
3196 ! CALL XERRWD (MSG, 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0)
3197 ! ISTATE = -1
3198 ! GO TO 580
3199 ! EWT(i) .le. 0.0 for some i (not at start of problem). ----------------
3200 ! 510 EWTI = RWORK(LEWT+I-1)
3201 ! MSG = 'DLSODES- At T (=R1), EWT(I1) has become R2 <= 0.'
3202 ! CALL XERRWD (MSG, 50, 202, 0, 1, I, 0, 2, TN, EWTI)
3203 ! ISTATE = -6
3204 ! GO TO 580
3205 ! Too much accuracy requested for machine precision. -------------------
3206 ! 520 MSG = 'DLSODES- At T (=R1), too much accuracy requested '
3207 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3208 ! MSG = ' for precision of machine.. See TOLSF (=R2) '
3209 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
3210 ! RWORK(14) = TOLSF
3211 ! ISTATE = -2
3212 ! GO TO 580
3213 ! KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
3214 ! 530 MSG = 'DLSODES- At T(=R1) and step size H(=R2), the error'
3215 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3216 ! MSG = ' test failed repeatedly or with ABS(H) = HMIN'
3217 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 2, TN, H)
3218 ! ISTATE = -4
3219 ! GO TO 560
3220 ! KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
3221 ! 540 MSG = 'DLSODES- At T (=R1) and step size H (=R2), the '
3222 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3223 ! MSG = ' corrector convergence failed repeatedly '
3224 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3225 ! MSG = ' or with ABS(H) = HMIN '
3226 ! CALL XERRWD (MSG, 30, 205, 0, 0, 0, 0, 2, TN, H)
3227 ! ISTATE = -5
3228 ! GO TO 560
3229 ! KFLAG = -3. Fatal error flag returned by DPRJS or DSOLSS (CDRV). ----
3230 ! 550 MSG = 'DLSODES- At T (=R1) and step size H (=R2), a fatal'
3231 ! CALL XERRWD (MSG, 50, 207, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3232 ! MSG = ' error flag was returned by CDRV (by way of '
3233 ! CALL XERRWD (MSG, 50, 207, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3234 ! MSG = ' Subroutine DPRJS or DSOLSS) '
3235 ! CALL XERRWD (MSG, 40, 207, 0, 0, 0, 0, 2, TN, H)
3236 ! ISTATE = -7
3237 ! GO TO 580
3238 ! Compute IMXER if relevant. -------------------------------------------
3239 ! 560 BIG = 0.0D0
3240 ! IMXER = 1
3241 ! DO 570 I = 1,N
3242 ! SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
3243 ! IF (BIG >= SIZE) GO TO 570
3244 ! BIG = SIZE
3245 ! IMXER = I
3246 ! 570 END DO
3247 ! IWORK(16) = IMXER
3248 ! Set Y vector, T, and optional outputs. -------------------------------
3249 ! 580 DO 590 I = 1,N
3250 ! Y(I) = RWORK(I+LYH-1)
3251 ! 590 END DO
3252 ! T = TN
3253 ! RWORK(11) = HU
3254 ! RWORK(12) = H
3255 ! RWORK(13) = TN
3256 ! IWORK(11) = NST
3257 ! IWORK(12) = NFE
3258 ! IWORK(13) = NJE
3259 ! IWORK(14) = NQU
3260 ! IWORK(15) = NQ
3261 ! IWORK(19) = NNZ
3262 ! IWORK(20) = NGP
3263 ! IWORK(21) = NLU
3264 ! IWORK(25) = NZL
3265 ! IWORK(26) = NZU
3266 ! RETURN
3267 !-----------------------------------------------------------------------
3268 ! Block I.
3269 ! The following block handles all error returns due to illegal input
3270 ! (ISTATE = -3), as detected before calling the core integrator.
3271 ! First the error message routine is called. If the illegal input
3272 ! is a negative ISTATE, the run is aborted (apparent infinite loop).
3273 !-----------------------------------------------------------------------
3274 ! 601 MSG = 'DLSODES- ISTATE (=I1) illegal.'
3275 ! CALL XERRWD (MSG, 30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0)
3276 ! IF (ISTATE < 0) GO TO 800
3277 ! GO TO 700
3278 ! 602 MSG = 'DLSODES- ITASK (=I1) illegal. '
3279 ! CALL XERRWD (MSG, 30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0)
3280 ! GO TO 700
3281 ! 603 MSG = 'DLSODES- ISTATE > 1 but DLSODES not initialized. '
3282 ! CALL XERRWD (MSG, 50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3283 ! GO TO 700
3284 ! 604 MSG = 'DLSODES- NEQ (=I1) < 1 '
3285 ! CALL XERRWD (MSG, 30, 4, 0, 1, NEQ(1), 0, 0, 0.0D0, 0.0D0)
3286 ! GO TO 700
3287 ! 605 MSG = 'DLSODES- ISTATE = 3 and NEQ increased (I1 to I2). '
3288 ! CALL XERRWD (MSG, 50, 5, 0, 2, N, NEQ(1), 0, 0.0D0, 0.0D0)
3289 ! GO TO 700
3290 ! 606 MSG = 'DLSODES- ITOL (=I1) illegal. '
3291 ! CALL XERRWD (MSG, 30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0)
3292 ! GO TO 700
3293 ! 607 MSG = 'DLSODES- IOPT (=I1) illegal. '
3294 ! CALL XERRWD (MSG, 30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0)
3295 ! GO TO 700
3296 ! 608 MSG = 'DLSODES- MF (=I1) illegal. '
3297 ! CALL XERRWD (MSG, 30, 8, 0, 1, MF, 0, 0, 0.0D0, 0.0D0)
3298 ! GO TO 700
3299 ! 609 MSG = 'DLSODES- SETH (=R1) < 0.0 '
3300 ! CALL XERRWD (MSG, 30, 9, 0, 0, 0, 0, 1, SETH, 0.0D0)
3301 ! GO TO 700
3302 ! 611 MSG = 'DLSODES- MAXORD (=I1) < 0 '
3303 ! CALL XERRWD (MSG, 30, 11, 0, 1, MAXORD, 0, 0, 0.0D0, 0.0D0)
3304 ! GO TO 700
3305 ! 612 MSG = 'DLSODES- MXSTEP (=I1) < 0 '
3306 ! CALL XERRWD (MSG, 30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0)
3307 ! GO TO 700
3308 ! 613 MSG = 'DLSODES- MXHNIL (=I1) < 0 '
3309 ! CALL XERRWD (MSG, 30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
3310 ! GO TO 700
3311 ! 614 MSG = 'DLSODES- TOUT (=R1) behind T (=R2) '
3312 ! CALL XERRWD (MSG, 40, 14, 0, 0, 0, 0, 2, TOUT, T)
3313 ! MSG = ' Integration direction is given by H0 (=R1) '
3314 ! CALL XERRWD (MSG, 50, 14, 0, 0, 0, 0, 1, H0, 0.0D0)
3315 ! GO TO 700
3316 ! 615 MSG = 'DLSODES- HMAX (=R1) < 0.0 '
3317 ! CALL XERRWD (MSG, 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0)
3318 ! GO TO 700
3319 ! 616 MSG = 'DLSODES- HMIN (=R1) < 0.0 '
3320 ! CALL XERRWD (MSG, 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0)
3321 ! GO TO 700
3322 ! 617 MSG = 'DLSODES- RWORK length is insufficient to proceed. '
3323 ! CALL XERRWD (MSG, 50, 17, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3324 ! MSG=' Length needed is >= LENRW (=I1), exceeds LRW (=I2)'
3325 ! CALL XERRWD (MSG, 60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
3326 ! GO TO 700
3327 ! 618 MSG = 'DLSODES- IWORK length is insufficient to proceed. '
3328 ! CALL XERRWD (MSG, 50, 18, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3329 ! MSG=' Length needed is >= LENIW (=I1), exceeds LIW (=I2)'
3330 ! CALL XERRWD (MSG, 60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
3331 ! GO TO 700
3332 ! 619 MSG = 'DLSODES- RTOL(I1) is R1 < 0.0 '
3333 ! CALL XERRWD (MSG, 40, 19, 0, 1, I, 0, 1, RTOLI, 0.0D0)
3334 ! GO TO 700
3335 ! 620 MSG = 'DLSODES- ATOL(I1) is R1 < 0.0 '
3336 ! CALL XERRWD (MSG, 40, 20, 0, 1, I, 0, 1, ATOLI, 0.0D0)
3337 ! GO TO 700
3338 ! 621 EWTI = RWORK(LEWT+I-1)
3339 ! MSG = 'DLSODES- EWT(I1) is R1 <= 0.0 '
3340 ! CALL XERRWD (MSG, 40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0)
3341 ! GO TO 700
3342 ! 622 MSG='DLSODES- TOUT(=R1) too close to T(=R2) to start integration.'
3343 ! CALL XERRWD (MSG, 60, 22, 0, 0, 0, 0, 2, TOUT, T)
3344 ! GO TO 700
3345 ! 623 MSG='DLSODES- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
3346 ! CALL XERRWD (MSG, 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
3347 ! GO TO 700
3348 ! 624 MSG='DLSODES- ITASK = 4 or 5 and TCRIT (=R1) behind TCUR (=R2) '
3349 ! CALL XERRWD (MSG, 60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
3350 ! GO TO 700
3351 ! 625 MSG='DLSODES- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
3352 ! CALL XERRWD (MSG, 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
3353 ! GO TO 700
3354 ! 626 MSG = 'DLSODES- At start of problem, too much accuracy '
3355 ! CALL XERRWD (MSG, 50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3356 ! MSG=' requested for precision of machine.. See TOLSF (=R1) '
3357 ! CALL XERRWD (MSG, 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0)
3358 ! RWORK(14) = TOLSF
3359 ! GO TO 700
3360 ! 627 MSG = 'DLSODES- Trouble in DINTDY. ITASK = I1, TOUT = R1'
3361 ! CALL XERRWD (MSG, 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0)
3362 ! GO TO 700
3363 ! 628 MSG='DLSODES- RWORK length insufficient (for Subroutine DPREP). '
3364 ! CALL XERRWD (MSG, 60, 28, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3365 ! MSG=' Length needed is >= LENRW (=I1), exceeds LRW (=I2)'
3366 ! CALL XERRWD (MSG, 60, 28, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
3367 ! GO TO 700
3368 ! 629 MSG='DLSODES- RWORK length insufficient (for Subroutine JGROUP). '
3369 ! CALL XERRWD (MSG, 60, 29, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3370 ! MSG=' Length needed is >= LENRW (=I1), exceeds LRW (=I2)'
3371 ! CALL XERRWD (MSG, 60, 29, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
3372 ! GO TO 700
3373 ! 630 MSG='DLSODES- RWORK length insufficient (for Subroutine ODRV). '
3374 ! CALL XERRWD (MSG, 60, 30, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3375 ! MSG=' Length needed is >= LENRW (=I1), exceeds LRW (=I2)'
3376 ! CALL XERRWD (MSG, 60, 30, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
3377 ! GO TO 700
3378 ! 631 MSG='DLSODES- Error from ODRV in Yale Sparse Matrix Package. '
3379 ! CALL XERRWD (MSG, 60, 31, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3380 ! IMUL = (IYS - 1)/N
3381 ! IREM = IYS - IMUL*N
3382 ! MSG=' At T (=R1), ODRV returned error flag = I1*NEQ + I2. '
3383 ! CALL XERRWD (MSG, 60, 31, 0, 2, IMUL, IREM, 1, TN, 0.0D0)
3384 ! GO TO 700
3385 ! 632 MSG='DLSODES- RWORK length insufficient (for Subroutine CDRV). '
3386 ! CALL XERRWD (MSG, 60, 32, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3387 ! MSG=' Length needed is >= LENRW (=I1), exceeds LRW (=I2)'
3388 ! CALL XERRWD (MSG, 60, 32, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
3389 ! GO TO 700
3390 ! 633 MSG='DLSODES- Error from CDRV in Yale Sparse Matrix Package. '
3391 ! CALL XERRWD (MSG, 60, 33, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3392 ! IMUL = (IYS - 1)/N
3393 ! IREM = IYS - IMUL*N
3394 ! MSG=' At T (=R1), CDRV returned error flag = I1*NEQ + I2. '
3395 ! CALL XERRWD (MSG, 60, 33, 0, 2, IMUL, IREM, 1, TN, 0.0D0)
3396 ! IF (IMUL == 2) THEN
3397 ! MSG=' Duplicate entry in sparsity structure descriptors. '
3398 ! CALL XERRWD (MSG, 60, 33, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3399 ! ENDIF
3400 ! IF (IMUL == 3 .OR. IMUL == 6) THEN
3401 ! MSG=' Insufficient storage for NSFC (called by CDRV). '
3402 ! CALL XERRWD (MSG, 60, 33, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
3403 ! ENDIF
3404 ! 700 ISTATE = -3
3405 ! RETURN
3406 ! 800 MSG = 'DLSODES- Run aborted.. apparent infinite loop. '
3407 ! CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0)
3408 ! RETURN
3409 !----------------------- End of Subroutine DLSODES ---------------------
3410 ! END SUBROUTINE DLSODES
3411 ! ECK DLSODA
3412 ! SUBROUTINE DLSODA (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK, &
3413 ! ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, JT)
3414 ! EXTERNAL F, JAC
3415 ! INTEGER :: NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, JT
3416 ! DOUBLE PRECISION :: Y, T, TOUT, RTOL, ATOL, RWORK
3417 ! DIMENSION NEQ(*), Y(*), RTOL(*), ATOL(*), RWORK(LRW), IWORK(LIW)
3418 !-----------------------------------------------------------------------
3419 ! This is the 12 November 2003 version of
3420 ! DLSODA: Livermore Solver for Ordinary Differential Equations, with
3421 ! Automatic method switching for stiff and nonstiff problems.
3422 ! This version is in double precision.
3423 ! DLSODA solves the initial value problem for stiff or nonstiff
3424 ! systems of first order ODEs,
3425 ! dy/dt = f(t,y) , or, in component form,
3426 ! dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ)) (i = 1,...,NEQ).
3427 ! This a variant version of the DLSODE package.
3428 ! It switches automatically between stiff and nonstiff methods.
3429 ! This means that the user does not have to determine whether the
3430 ! problem is stiff or not, and the solver will automatically choose the
3431 ! appropriate method. It always starts with the nonstiff method.
3432 ! Authors: Alan C. Hindmarsh
3433 ! Center for Applied Scientific Computing, L-561
3434 ! Lawrence Livermore National Laboratory
3435 ! Livermore, CA 94551
3436 ! and
3437 ! Linda R. Petzold
3438 ! Univ. of California at Santa Barbara
3439 ! Dept. of Computer Science
3440 ! Santa Barbara, CA 93106
3441 ! References:
3442 ! 1. Alan C. Hindmarsh, ODEPACK, A Systematized Collection of ODE
3443 ! Solvers, in Scientific Computing, R. S. Stepleman et al. (Eds.),
3444 ! North-Holland, Amsterdam, 1983, pp. 55-64.
3445 ! 2. Linda R. Petzold, Automatic Selection of Methods for Solving
3446 ! Stiff and Nonstiff Systems of Ordinary Differential Equations,
3447 ! Siam J. Sci. Stat. Comput. 4 (1983), pp. 136-148.
3448 !-----------------------------------------------------------------------
3449 ! Summary of Usage.
3450 ! Communication between the user and the DLSODA package, for normal
3451 ! situations, is summarized here. This summary describes only a subset
3452 ! of the full set of options available. See the full description for
3453 ! details, including alternative treatment of the Jacobian matrix,
3454 ! optional inputs and outputs, nonstandard options, and
3455 ! instructions for special situations. See also the example
3456 ! problem (with program and output) following this summary.
3457 ! A. First provide a subroutine of the form:
3458 ! SUBROUTINE F (NEQ, T, Y, YDOT)
3459 ! DOUBLE PRECISION T, Y(*), YDOT(*)
3460 ! which supplies the vector function f by loading YDOT(i) with f(i).
3461 ! B. Write a main program which calls Subroutine DLSODA once for
3462 ! each point at which answers are desired. This should also provide
3463 ! for possible use of logical unit 6 for output of error messages
3464 ! by DLSODA. On the first call to DLSODA, supply arguments as follows:
3465 ! F = name of subroutine for right-hand side vector f.
3466 ! This name must be declared External in calling program.
3467 ! NEQ = number of first order ODEs.
3468 ! Y = array of initial values, of length NEQ.
3469 ! T = the initial value of the independent variable.
3470 ! TOUT = first point where output is desired (.ne. T).
3471 ! ITOL = 1 or 2 according as ATOL (below) is a scalar or array.
3472 ! RTOL = relative tolerance parameter (scalar).
3473 ! ATOL = absolute tolerance parameter (scalar or array).
3474 ! the estimated local error in y(i) will be controlled so as
3475 ! to be less than
3476 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or
3477 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2.
3478 ! Thus the local error test passes if, in each component,
3479 ! either the absolute error is less than ATOL (or ATOL(i)),
3480 ! or the relative error is less than RTOL.
3481 ! Use RTOL = 0.0 for pure absolute error control, and
3482 ! use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative error
3483 ! control. Caution: actual (global) errors may exceed these
3484 ! local tolerances, so choose them conservatively.
3485 ! ITASK = 1 for normal computation of output values of y at t = TOUT.
3486 ! ISTATE = integer flag (input and output). Set ISTATE = 1.
3487 ! IOPT = 0 to indicate no optional inputs used.
3488 ! RWORK = real work array of length at least:
3489 ! 22 + NEQ * MAX(16, NEQ + 9).
3490 ! See also Paragraph E below.
3491 ! LRW = declared length of RWORK (in user's dimension).
3492 ! IWORK = integer work array of length at least 20 + NEQ.
3493 ! LIW = declared length of IWORK (in user's dimension).
3494 ! JAC = name of subroutine for Jacobian matrix.
3495 ! Use a dummy name. See also Paragraph E below.
3496 ! JT = Jacobian type indicator. Set JT = 2.
3497 ! See also Paragraph E below.
3498 ! Note that the main program must declare arrays Y, RWORK, IWORK,
3499 ! and possibly ATOL.
3500 ! C. The output from the first call (or any call) is:
3501 ! Y = array of computed values of y(t) vector.
3502 ! T = corresponding value of independent variable (normally TOUT).
3503 ! ISTATE = 2 if DLSODA was successful, negative otherwise.
3504 ! -1 means excess work done on this call (perhaps wrong JT).
3505 ! -2 means excess accuracy requested (tolerances too small).
3506 ! -3 means illegal input detected (see printed message).
3507 ! -4 means repeated error test failures (check all inputs).
3508 ! -5 means repeated convergence failures (perhaps bad Jacobian
3509 ! supplied or wrong choice of JT or tolerances).
3510 ! -6 means error weight became zero during problem. (Solution
3511 ! component i vanished, and ATOL or ATOL(i) = 0.)
3512 ! -7 means work space insufficient to finish (see messages).
3513 ! D. To continue the integration after a successful return, simply
3514 ! reset TOUT and call DLSODA again. No other parameters need be reset.
3515 ! E. Note: If and when DLSODA regards the problem as stiff, and
3516 ! switches methods accordingly, it must make use of the NEQ by NEQ
3517 ! Jacobian matrix, J = df/dy. For the sake of simplicity, the
3518 ! inputs to DLSODA recommended in Paragraph B above cause DLSODA to
3519 ! treat J as a full matrix, and to approximate it internally by
3520 ! difference quotients. Alternatively, J can be treated as a band
3521 ! matrix (with great potential reduction in the size of the RWORK
3522 ! array). Also, in either the full or banded case, the user can supply
3523 ! J in closed form, with a routine whose name is passed as the JAC
3524 ! argument. These alternatives are described in the paragraphs on
3525 ! RWORK, JAC, and JT in the full description of the call sequence below.
3526 !-----------------------------------------------------------------------
3527 ! Example Problem.
3528 ! The following is a simple example problem, with the coding
3529 ! needed for its solution by DLSODA. The problem is from chemical
3530 ! kinetics, and consists of the following three rate equations:
3531 ! dy1/dt = -.04*y1 + 1.e4*y2*y3
3532 ! dy2/dt = .04*y1 - 1.e4*y2*y3 - 3.e7*y2**2
3533 ! dy3/dt = 3.e7*y2**2
3534 ! on the interval from t = 0.0 to t = 4.e10, with initial conditions
3535 ! y1 = 1.0, y2 = y3 = 0. The problem is stiff.
3536 ! The following coding solves this problem with DLSODA,
3537 ! printing results at t = .4, 4., ..., 4.e10. It uses
3538 ! ITOL = 2 and ATOL much smaller for y2 than y1 or y3 because
3539 ! y2 has much smaller values.
3540 ! At the end of the run, statistical quantities of interest are
3541 ! printed (see optional outputs in the full description below).
3542 ! EXTERNAL FEX
3543 ! DOUBLE PRECISION ATOL, RTOL, RWORK, T, TOUT, Y
3544 ! DIMENSION Y(3), ATOL(3), RWORK(70), IWORK(23)
3545 ! NEQ = 3
3546 ! Y(1) = 1.
3547 ! Y(2) = 0.
3548 ! Y(3) = 0.
3549 ! T = 0.
3550 ! TOUT = .4
3551 ! ITOL = 2
3552 ! RTOL = 1.D-4
3553 ! ATOL(1) = 1.D-6
3554 ! ATOL(2) = 1.D-10
3555 ! ATOL(3) = 1.D-6
3556 ! ITASK = 1
3557 ! ISTATE = 1
3558 ! IOPT = 0
3559 ! LRW = 70
3560 ! LIW = 23
3561 ! JT = 2
3562 ! DO 40 IOUT = 1,12
3563 ! CALL DLSODA(FEX,NEQ,Y,T,TOUT,ITOL,RTOL,ATOL,ITASK,ISTATE,
3564 ! 1 IOPT,RWORK,LRW,IWORK,LIW,JDUM,JT)
3565 ! WRITE(6,20)T,Y(1),Y(2),Y(3)
3566 ! 20 FORMAT(' At t =',D12.4,' Y =',3D14.6)
3567 ! IF (ISTATE .LT. 0) GO TO 80
3568 ! 40 TOUT = TOUT*10.
3569 ! WRITE(6,60)IWORK(11),IWORK(12),IWORK(13),IWORK(19),RWORK(15)
3570 ! 60 FORMAT(/' No. steps =',I4,' No. f-s =',I4,' No. J-s =',I4/
3571 ! 1 ' Method last used =',I2,' Last switch was at t =',D12.4)
3572 ! STOP
3573 ! 80 WRITE(6,90)ISTATE
3574 ! 90 FORMAT(///' Error halt.. ISTATE =',I3)
3575 ! STOP
3576 ! END
3577 ! SUBROUTINE FEX (NEQ, T, Y, YDOT)
3578 ! DOUBLE PRECISION T, Y, YDOT
3579 ! DIMENSION Y(3), YDOT(3)
3580 ! YDOT(1) = -.04*Y(1) + 1.D4*Y(2)*Y(3)
3581 ! YDOT(3) = 3.D7*Y(2)*Y(2)
3582 ! YDOT(2) = -YDOT(1) - YDOT(3)
3583 ! RETURN
3584 ! END
3585 ! The output of this program (on a CDC-7600 in single precision)
3586 ! is as follows:
3587 ! At t = 4.0000e-01 y = 9.851712e-01 3.386380e-05 1.479493e-02
3588 ! At t = 4.0000e+00 Y = 9.055333e-01 2.240655e-05 9.444430e-02
3589 ! At t = 4.0000e+01 Y = 7.158403e-01 9.186334e-06 2.841505e-01
3590 ! At t = 4.0000e+02 Y = 4.505250e-01 3.222964e-06 5.494717e-01
3591 ! At t = 4.0000e+03 Y = 1.831975e-01 8.941774e-07 8.168016e-01
3592 ! At t = 4.0000e+04 Y = 3.898730e-02 1.621940e-07 9.610125e-01
3593 ! At t = 4.0000e+05 Y = 4.936363e-03 1.984221e-08 9.950636e-01
3594 ! At t = 4.0000e+06 Y = 5.161831e-04 2.065786e-09 9.994838e-01
3595 ! At t = 4.0000e+07 Y = 5.179817e-05 2.072032e-10 9.999482e-01
3596 ! At t = 4.0000e+08 Y = 5.283401e-06 2.113371e-11 9.999947e-01
3597 ! At t = 4.0000e+09 Y = 4.659031e-07 1.863613e-12 9.999995e-01
3598 ! At t = 4.0000e+10 Y = 1.404280e-08 5.617126e-14 1.000000e+00
3599 ! No. steps = 361 No. f-s = 693 No. J-s = 64
3600 ! Method last used = 2 Last switch was at t = 6.0092e-03
3601 !-----------------------------------------------------------------------
3602 ! Full description of user interface to DLSODA.
3603 ! The user interface to DLSODA consists of the following parts.
3604 ! 1. The call sequence to Subroutine DLSODA, which is a driver
3605 ! routine for the solver. This includes descriptions of both
3606 ! the call sequence arguments and of user-supplied routines.
3607 ! following these descriptions is a description of
3608 ! optional inputs available through the call sequence, and then
3609 ! a description of optional outputs (in the work arrays).
3610 ! 2. Descriptions of other routines in the DLSODA package that may be
3611 ! (optionally) called by the user. These provide the ability to
3612 ! alter error message handling, save and restore the internal
3613 ! Common, and obtain specified derivatives of the solution y(t).
3614 ! 3. Descriptions of Common blocks to be declared in overlay
3615 ! or similar environments, or to be saved when doing an interrupt
3616 ! of the problem and continued solution later.
3617 ! 4. Description of a subroutine in the DLSODA package,
3618 ! which the user may replace with his/her own version, if desired.
3619 ! this relates to the measurement of errors.
3620 !-----------------------------------------------------------------------
3621 ! Part 1. Call Sequence.
3622 ! The call sequence parameters used for input only are
3623 ! F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC, JT,
3624 ! and those used for both input and output are
3625 ! Y, T, ISTATE.
3626 ! The work arrays RWORK and IWORK are also used for conditional and
3627 ! optional inputs and optional outputs. (The term output here refers
3628 ! to the return from Subroutine DLSODA to the user's calling program.)
3629 ! The legality of input parameters will be thoroughly checked on the
3630 ! initial call for the problem, but not checked thereafter unless a
3631 ! change in input parameters is flagged by ISTATE = 3 on input.
3632 ! The descriptions of the call arguments are as follows.
3633 ! F = the name of the user-supplied subroutine defining the
3634 ! ODE system. The system must be put in the first-order
3635 ! form dy/dt = f(t,y), where f is a vector-valued function
3636 ! of the scalar t and the vector y. Subroutine F is to
3637 ! compute the function f. It is to have the form
3638 ! SUBROUTINE F (NEQ, T, Y, YDOT)
3639 ! DOUBLE PRECISION T, Y(*), YDOT(*)
3640 ! where NEQ, T, and Y are input, and the array YDOT = f(t,y)
3641 ! is output. Y and YDOT are arrays of length NEQ.
3642 ! Subroutine F should not alter Y(1),...,Y(NEQ).
3643 ! F must be declared External in the calling program.
3644 ! Subroutine F may access user-defined quantities in
3645 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
3646 ! (dimensioned in F) and/or Y has length exceeding NEQ(1).
3647 ! See the descriptions of NEQ and Y below.
3648 ! If quantities computed in the F routine are needed
3649 ! externally to DLSODA, an extra call to F should be made
3650 ! for this purpose, for consistent and accurate results.
3651 ! If only the derivative dy/dt is needed, use DINTDY instead.
3652 ! NEQ = the size of the ODE system (number of first order
3653 ! ordinary differential equations). Used only for input.
3654 ! NEQ may be decreased, but not increased, during the problem.
3655 ! If NEQ is decreased (with ISTATE = 3 on input), the
3656 ! remaining components of Y should be left undisturbed, if
3657 ! these are to be accessed in F and/or JAC.
3658 ! Normally, NEQ is a scalar, and it is generally referred to
3659 ! as a scalar in this user interface description. However,
3660 ! NEQ may be an array, with NEQ(1) set to the system size.
3661 ! (The DLSODA package accesses only NEQ(1).) In either case,
3662 ! this parameter is passed as the NEQ argument in all calls
3663 ! to F and JAC. Hence, if it is an array, locations
3664 ! NEQ(2),... may be used to store other integer data and pass
3665 ! it to F and/or JAC. Subroutines F and/or JAC must include
3666 ! NEQ in a Dimension statement in that case.
3667 ! Y = a real array for the vector of dependent variables, of
3668 ! length NEQ or more. Used for both input and output on the
3669 ! first call (ISTATE = 1), and only for output on other calls.
3670 ! On the first call, Y must contain the vector of initial
3671 ! values. On output, Y contains the computed solution vector,
3672 ! evaluated at T. If desired, the Y array may be used
3673 ! for other purposes between calls to the solver.
3674 ! This array is passed as the Y argument in all calls to
3675 ! F and JAC. Hence its length may exceed NEQ, and locations
3676 ! Y(NEQ+1),... may be used to store other real data and
3677 ! pass it to F and/or JAC. (The DLSODA package accesses only
3678 ! Y(1),...,Y(NEQ).)
3679 ! T = the independent variable. On input, T is used only on the
3680 ! first call, as the initial point of the integration.
3681 ! on output, after each call, T is the value at which a
3682 ! computed solution Y is evaluated (usually the same as TOUT).
3683 ! on an error return, T is the farthest point reached.
3684 ! TOUT = the next value of t at which a computed solution is desired.
3685 ! Used only for input.
3686 ! When starting the problem (ISTATE = 1), TOUT may be equal
3687 ! to T for one call, then should .ne. T for the next call.
3688 ! For the initial t, an input value of TOUT .ne. T is used
3689 ! in order to determine the direction of the integration
3690 ! (i.e. the algebraic sign of the step sizes) and the rough
3691 ! scale of the problem. Integration in either direction
3692 ! (forward or backward in t) is permitted.
3693 ! If ITASK = 2 or 5 (one-step modes), TOUT is ignored after
3694 ! the first call (i.e. the first call with TOUT .ne. T).
3695 ! Otherwise, TOUT is required on every call.
3696 ! If ITASK = 1, 3, or 4, the values of TOUT need not be
3697 ! monotone, but a value of TOUT which backs up is limited
3698 ! to the current internal T interval, whose endpoints are
3699 ! TCUR - HU and TCUR (see optional outputs, below, for
3700 ! TCUR and HU).
3701 ! ITOL = an indicator for the type of error control. See
3702 ! description below under ATOL. Used only for input.
3703 ! RTOL = a relative error tolerance parameter, either a scalar or
3704 ! an array of length NEQ. See description below under ATOL.
3705 ! Input only.
3706 ! ATOL = an absolute error tolerance parameter, either a scalar or
3707 ! an array of length NEQ. Input only.
3708 ! The input parameters ITOL, RTOL, and ATOL determine
3709 ! the error control performed by the solver. The solver will
3710 ! control the vector E = (E(i)) of estimated local errors
3711 ! in y, according to an inequality of the form
3712 ! max-norm of ( E(i)/EWT(i) ) .le. 1,
3713 ! where EWT = (EWT(i)) is a vector of positive error weights.
3714 ! The values of RTOL and ATOL should all be non-negative.
3715 ! The following table gives the types (scalar/array) of
3716 ! RTOL and ATOL, and the corresponding form of EWT(i).
3717 ! ITOL RTOL ATOL EWT(i)
3718 ! 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
3719 ! 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
3720 ! 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
3721 ! 4 array array RTOL(i)*ABS(Y(i)) + ATOL(i)
3722 ! When either of these parameters is a scalar, it need not
3723 ! be dimensioned in the user's calling program.
3724 ! If none of the above choices (with ITOL, RTOL, and ATOL
3725 ! fixed throughout the problem) is suitable, more general
3726 ! error controls can be obtained by substituting a
3727 ! user-supplied routine for the setting of EWT.
3728 ! See Part 4 below.
3729 ! If global errors are to be estimated by making a repeated
3730 ! run on the same problem with smaller tolerances, then all
3731 ! components of RTOL and ATOL (i.e. of EWT) should be scaled
3732 ! down uniformly.
3733 ! ITASK = an index specifying the task to be performed.
3734 ! Input only. ITASK has the following values and meanings.
3735 ! 1 means normal computation of output values of y(t) at
3736 ! t = TOUT (by overshooting and interpolating).
3737 ! 2 means take one step only and return.
3738 ! 3 means stop at the first internal mesh point at or
3739 ! beyond t = TOUT and return.
3740 ! 4 means normal computation of output values of y(t) at
3741 ! t = TOUT but without overshooting t = TCRIT.
3742 ! TCRIT must be input as RWORK(1). TCRIT may be equal to
3743 ! or beyond TOUT, but not behind it in the direction of
3744 ! integration. This option is useful if the problem
3745 ! has a singularity at or beyond t = TCRIT.
3746 ! 5 means take one step, without passing TCRIT, and return.
3747 ! TCRIT must be input as RWORK(1).
3748 ! Note: If ITASK = 4 or 5 and the solver reaches TCRIT
3749 ! (within roundoff), it will return T = TCRIT (exactly) to
3750 ! indicate this (unless ITASK = 4 and TOUT comes before TCRIT,
3751 ! in which case answers at t = TOUT are returned first).
3752 ! ISTATE = an index used for input and output to specify the
3753 ! the state of the calculation.
3754 ! On input, the values of ISTATE are as follows.
3755 ! 1 means this is the first call for the problem
3756 ! (initializations will be done). See note below.
3757 ! 2 means this is not the first call, and the calculation
3758 ! is to continue normally, with no change in any input
3759 ! parameters except possibly TOUT and ITASK.
3760 ! (If ITOL, RTOL, and/or ATOL are changed between calls
3761 ! with ISTATE = 2, the new values will be used but not
3762 ! tested for legality.)
3763 ! 3 means this is not the first call, and the
3764 ! calculation is to continue normally, but with
3765 ! a change in input parameters other than
3766 ! TOUT and ITASK. Changes are allowed in
3767 ! NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, JT, ML, MU,
3768 ! and any optional inputs except H0, MXORDN, and MXORDS.
3769 ! (See IWORK description for ML and MU.)
3770 ! Note: A preliminary call with TOUT = T is not counted
3771 ! as a first call here, as no initialization or checking of
3772 ! input is done. (Such a call is sometimes useful for the
3773 ! purpose of outputting the initial conditions.)
3774 ! Thus the first call for which TOUT .ne. T requires
3775 ! ISTATE = 1 on input.
3776 ! On output, ISTATE has the following values and meanings.
3777 ! 1 means nothing was done; TOUT = T and ISTATE = 1 on input.
3778 ! 2 means the integration was performed successfully.
3779 ! -1 means an excessive amount of work (more than MXSTEP
3780 ! steps) was done on this call, before completing the
3781 ! requested task, but the integration was otherwise
3782 ! successful as far as T. (MXSTEP is an optional input
3783 ! and is normally 500.) To continue, the user may
3784 ! simply reset ISTATE to a value .gt. 1 and call again
3785 ! (the excess work step counter will be reset to 0).
3786 ! In addition, the user may increase MXSTEP to avoid
3787 ! this error return (see below on optional inputs).
3788 ! -2 means too much accuracy was requested for the precision
3789 ! of the machine being used. This was detected before
3790 ! completing the requested task, but the integration
3791 ! was successful as far as T. To continue, the tolerance
3792 ! parameters must be reset, and ISTATE must be set
3793 ! to 3. The optional output TOLSF may be used for this
3794 ! purpose. (Note: If this condition is detected before
3795 ! taking any steps, then an illegal input return
3796 ! (ISTATE = -3) occurs instead.)
3797 ! -3 means illegal input was detected, before taking any
3798 ! integration steps. See written message for details.
3799 ! Note: If the solver detects an infinite loop of calls
3800 ! to the solver with illegal input, it will cause
3801 ! the run to stop.
3802 ! -4 means there were repeated error test failures on
3803 ! one attempted step, before completing the requested
3804 ! task, but the integration was successful as far as T.
3805 ! The problem may have a singularity, or the input
3806 ! may be inappropriate.
3807 ! -5 means there were repeated convergence test failures on
3808 ! one attempted step, before completing the requested
3809 ! task, but the integration was successful as far as T.
3810 ! This may be caused by an inaccurate Jacobian matrix,
3811 ! if one is being used.
3812 ! -6 means EWT(i) became zero for some i during the
3813 ! integration. Pure relative error control (ATOL(i)=0.0)
3814 ! was requested on a variable which has now vanished.
3815 ! The integration was successful as far as T.
3816 ! -7 means the length of RWORK and/or IWORK was too small to
3817 ! proceed, but the integration was successful as far as T.
3818 ! This happens when DLSODA chooses to switch methods
3819 ! but LRW and/or LIW is too small for the new method.
3820 ! Note: Since the normal output value of ISTATE is 2,
3821 ! it does not need to be reset for normal continuation.
3822 ! Also, since a negative input value of ISTATE will be
3823 ! regarded as illegal, a negative output value requires the
3824 ! user to change it, and possibly other inputs, before
3825 ! calling the solver again.
3826 ! IOPT = an integer flag to specify whether or not any optional
3827 ! inputs are being used on this call. Input only.
3828 ! The optional inputs are listed separately below.
3829 ! IOPT = 0 means no optional inputs are being used.
3830 ! default values will be used in all cases.
3831 ! IOPT = 1 means one or more optional inputs are being used.
3832 ! RWORK = a real array (double precision) for work space, and (in the
3833 ! first 20 words) for conditional and optional inputs and
3834 ! optional outputs.
3835 ! As DLSODA switches automatically between stiff and nonstiff
3836 ! methods, the required length of RWORK can change during the
3837 ! problem. Thus the RWORK array passed to DLSODA can either
3838 ! have a static (fixed) length large enough for both methods,
3839 ! or have a dynamic (changing) length altered by the calling
3840 ! program in response to output from DLSODA.
3841 ! --- Fixed Length Case ---
3842 ! If the RWORK length is to be fixed, it should be at least
3843 ! MAX (LRN, LRS),
3844 ! where LRN and LRS are the RWORK lengths required when the
3845 ! current method is nonstiff or stiff, respectively.
3846 ! The separate RWORK length requirements LRN and LRS are
3847 ! as follows:
3848 ! IF NEQ is constant and the maximum method orders have
3849 ! their default values, then
3850 ! LRN = 20 + 16*NEQ,
3851 ! LRS = 22 + 9*NEQ + NEQ**2 if JT = 1 or 2,
3852 ! LRS = 22 + 10*NEQ + (2*ML+MU)*NEQ if JT = 4 or 5.
3853 ! Under any other conditions, LRN and LRS are given by:
3854 ! LRN = 20 + NYH*(MXORDN+1) + 3*NEQ,
3855 ! LRS = 20 + NYH*(MXORDS+1) + 3*NEQ + LMAT,
3856 ! where
3857 ! NYH = the initial value of NEQ,
3858 ! MXORDN = 12, unless a smaller value is given as an
3859 ! optional input,
3860 ! MXORDS = 5, unless a smaller value is given as an
3861 ! optional input,
3862 ! LMAT = length of matrix work space:
3863 ! LMAT = NEQ**2 + 2 if JT = 1 or 2,
3864 ! LMAT = (2*ML + MU + 1)*NEQ + 2 if JT = 4 or 5.
3865 ! --- Dynamic Length Case ---
3866 ! If the length of RWORK is to be dynamic, then it should
3867 ! be at least LRN or LRS, as defined above, depending on the
3868 ! current method. Initially, it must be at least LRN (since
3869 ! DLSODA starts with the nonstiff method). On any return
3870 ! from DLSODA, the optional output MCUR indicates the current
3871 ! method. If MCUR differs from the value it had on the
3872 ! previous return, or if there has only been one call to
3873 ! DLSODA and MCUR is now 2, then DLSODA has switched
3874 ! methods during the last call, and the length of RWORK
3875 ! should be reset (to LRN if MCUR = 1, or to LRS if
3876 ! MCUR = 2). (An increase in the RWORK length is required
3877 ! if DLSODA returned ISTATE = -7, but not otherwise.)
3878 ! After resetting the length, call DLSODA with ISTATE = 3
3879 ! to signal that change.
3880 ! LRW = the length of the array RWORK, as declared by the user.
3881 ! (This will be checked by the solver.)
3882 ! IWORK = an integer array for work space.
3883 ! As DLSODA switches automatically between stiff and nonstiff
3884 ! methods, the required length of IWORK can change during
3885 ! problem, between
3886 ! LIS = 20 + NEQ and LIN = 20,
3887 ! respectively. Thus the IWORK array passed to DLSODA can
3888 ! either have a fixed length of at least 20 + NEQ, or have a
3889 ! dynamic length of at least LIN or LIS, depending on the
3890 ! current method. The comments on dynamic length under
3891 ! RWORK above apply here. Initially, this length need
3892 ! only be at least LIN = 20.
3893 ! The first few words of IWORK are used for conditional and
3894 ! optional inputs and optional outputs.
3895 ! The following 2 words in IWORK are conditional inputs:
3896 ! IWORK(1) = ML these are the lower and upper
3897 ! IWORK(2) = MU half-bandwidths, respectively, of the
3898 ! banded Jacobian, excluding the main diagonal.
3899 ! The band is defined by the matrix locations
3900 ! (i,j) with i-ML .le. j .le. i+MU. ML and MU
3901 ! must satisfy 0 .le. ML,MU .le. NEQ-1.
3902 ! These are required if JT is 4 or 5, and
3903 ! ignored otherwise. ML and MU may in fact be
3904 ! the band parameters for a matrix to which
3905 ! df/dy is only approximately equal.
3906 ! LIW = the length of the array IWORK, as declared by the user.
3907 ! (This will be checked by the solver.)
3908 ! Note: The base addresses of the work arrays must not be
3909 ! altered between calls to DLSODA for the same problem.
3910 ! The contents of the work arrays must not be altered
3911 ! between calls, except possibly for the conditional and
3912 ! optional inputs, and except for the last 3*NEQ words of RWORK.
3913 ! The latter space is used for internal scratch space, and so is
3914 ! available for use by the user outside DLSODA between calls, if
3915 ! desired (but not for use by F or JAC).
3916 ! JAC = the name of the user-supplied routine to compute the
3917 ! Jacobian matrix, df/dy, if JT = 1 or 4. The JAC routine
3918 ! is optional, but if the problem is expected to be stiff much
3919 ! of the time, you are encouraged to supply JAC, for the sake
3920 ! of efficiency. (Alternatively, set JT = 2 or 5 to have
3921 ! DLSODA compute df/dy internally by difference quotients.)
3922 ! If and when DLSODA uses df/dy, it treats this NEQ by NEQ
3923 ! matrix either as full (JT = 1 or 2), or as banded (JT =
3924 ! 4 or 5) with half-bandwidths ML and MU (discussed under
3925 ! IWORK above). In either case, if JT = 1 or 4, the JAC
3926 ! routine must compute df/dy as a function of the scalar t
3927 ! and the vector y. It is to have the form
3928 ! SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
3929 ! DOUBLE PRECISION T, Y(*), PD(NROWPD,*)
3930 ! where NEQ, T, Y, ML, MU, and NROWPD are input and the array
3931 ! PD is to be loaded with partial derivatives (elements of
3932 ! the Jacobian matrix) on output. PD must be given a first
3933 ! dimension of NROWPD. T and Y have the same meaning as in
3934 ! Subroutine F.
3935 ! In the full matrix case (JT = 1), ML and MU are
3936 ! ignored, and the Jacobian is to be loaded into PD in
3937 ! columnwise manner, with df(i)/dy(j) loaded into PD(i,j).
3938 ! In the band matrix case (JT = 4), the elements
3939 ! within the band are to be loaded into PD in columnwise
3940 ! manner, with diagonal lines of df/dy loaded into the rows
3941 ! of PD. Thus df(i)/dy(j) is to be loaded into PD(i-j+MU+1,j).
3942 ! ML and MU are the half-bandwidth parameters (see IWORK).
3943 ! The locations in PD in the two triangular areas which
3944 ! correspond to nonexistent matrix elements can be ignored
3945 ! or loaded arbitrarily, as they are overwritten by DLSODA.
3946 ! JAC need not provide df/dy exactly. A crude
3947 ! approximation (possibly with a smaller bandwidth) will do.
3948 ! In either case, PD is preset to zero by the solver,
3949 ! so that only the nonzero elements need be loaded by JAC.
3950 ! Each call to JAC is preceded by a call to F with the same
3951 ! arguments NEQ, T, and Y. Thus to gain some efficiency,
3952 ! intermediate quantities shared by both calculations may be
3953 ! saved in a user Common block by F and not recomputed by JAC,
3954 ! if desired. Also, JAC may alter the Y array, if desired.
3955 ! JAC must be declared External in the calling program.
3956 ! Subroutine JAC may access user-defined quantities in
3957 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
3958 ! (dimensioned in JAC) and/or Y has length exceeding NEQ(1).
3959 ! See the descriptions of NEQ and Y above.
3960 ! JT = Jacobian type indicator. Used only for input.
3961 ! JT specifies how the Jacobian matrix df/dy will be
3962 ! treated, if and when DLSODA requires this matrix.
3963 ! JT has the following values and meanings:
3964 ! 1 means a user-supplied full (NEQ by NEQ) Jacobian.
3965 ! 2 means an internally generated (difference quotient) full
3966 ! Jacobian (using NEQ extra calls to F per df/dy value).
3967 ! 4 means a user-supplied banded Jacobian.
3968 ! 5 means an internally generated banded Jacobian (using
3969 ! ML+MU+1 extra calls to F per df/dy evaluation).
3970 ! If JT = 1 or 4, the user must supply a Subroutine JAC
3971 ! (the name is arbitrary) as described above under JAC.
3972 ! If JT = 2 or 5, a dummy argument can be used.
3973 !-----------------------------------------------------------------------
3974 ! Optional Inputs.
3975 ! The following is a list of the optional inputs provided for in the
3976 ! call sequence. (See also Part 2.) For each such input variable,
3977 ! this table lists its name as used in this documentation, its
3978 ! location in the call sequence, its meaning, and the default value.
3979 ! The use of any of these inputs requires IOPT = 1, and in that
3980 ! case all of these inputs are examined. A value of zero for any
3981 ! of these optional inputs will cause the default value to be used.
3982 ! Thus to use a subset of the optional inputs, simply preload
3983 ! locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, and
3984 ! then set those of interest to nonzero values.
3985 ! Name Location Meaning and Default Value
3986 ! H0 RWORK(5) the step size to be attempted on the first step.
3987 ! The default value is determined by the solver.
3988 ! HMAX RWORK(6) the maximum absolute step size allowed.
3989 ! The default value is infinite.
3990 ! HMIN RWORK(7) the minimum absolute step size allowed.
3991 ! The default value is 0. (This lower bound is not
3992 ! enforced on the final step before reaching TCRIT
3993 ! when ITASK = 4 or 5.)
3994 ! IXPR IWORK(5) flag to generate extra printing at method switches.
3995 ! IXPR = 0 means no extra printing (the default).
3996 ! IXPR = 1 means print data on each switch.
3997 ! T, H, and NST will be printed on the same logical
3998 ! unit as used for error messages.
3999 ! MXSTEP IWORK(6) maximum number of (internally defined) steps
4000 ! allowed during one call to the solver.
4001 ! The default value is 500.
4002 ! MXHNIL IWORK(7) maximum number of messages printed (per problem)
4003 ! warning that T + H = T on a step (H = step size).
4004 ! This must be positive to result in a non-default
4005 ! value. The default value is 10.
4006 ! MXORDN IWORK(8) the maximum order to be allowed for the nonstiff
4007 ! (Adams) method. the default value is 12.
4008 ! if MXORDN exceeds the default value, it will
4009 ! be reduced to the default value.
4010 ! MXORDN is held constant during the problem.
4011 ! MXORDS IWORK(9) the maximum order to be allowed for the stiff
4012 ! (BDF) method. The default value is 5.
4013 ! If MXORDS exceeds the default value, it will
4014 ! be reduced to the default value.
4015 ! MXORDS is held constant during the problem.
4016 !-----------------------------------------------------------------------
4017 ! Optional Outputs.
4018 ! As optional additional output from DLSODA, the variables listed
4019 ! below are quantities related to the performance of DLSODA
4020 ! which are available to the user. These are communicated by way of
4021 ! the work arrays, but also have internal mnemonic names as shown.
4022 ! except where stated otherwise, all of these outputs are defined
4023 ! on any successful return from DLSODA, and on any return with
4024 ! ISTATE = -1, -2, -4, -5, or -6. On an illegal input return
4025 ! (ISTATE = -3), they will be unchanged from their existing values
4026 ! (if any), except possibly for TOLSF, LENRW, and LENIW.
4027 ! On any error return, outputs relevant to the error will be defined,
4028 ! as noted below.
4029 ! Name Location Meaning
4030 ! HU RWORK(11) the step size in t last used (successfully).
4031 ! HCUR RWORK(12) the step size to be attempted on the next step.
4032 ! TCUR RWORK(13) the current value of the independent variable
4033 ! which the solver has actually reached, i.e. the
4034 ! current internal mesh point in t. On output, TCUR
4035 ! will always be at least as far as the argument
4036 ! T, but may be farther (if interpolation was done).
4037 ! TOLSF RWORK(14) a tolerance scale factor, greater than 1.0,
4038 ! computed when a request for too much accuracy was
4039 ! detected (ISTATE = -3 if detected at the start of
4040 ! the problem, ISTATE = -2 otherwise). If ITOL is
4041 ! left unaltered but RTOL and ATOL are uniformly
4042 ! scaled up by a factor of TOLSF for the next call,
4043 ! then the solver is deemed likely to succeed.
4044 ! (The user may also ignore TOLSF and alter the
4045 ! tolerance parameters in any other way appropriate.)
4046 ! TSW RWORK(15) the value of t at the time of the last method
4047 ! switch, if any.
4048 ! NST IWORK(11) the number of steps taken for the problem so far.
4049 ! NFE IWORK(12) the number of f evaluations for the problem so far.
4050 ! NJE IWORK(13) the number of Jacobian evaluations (and of matrix
4051 ! LU decompositions) for the problem so far.
4052 ! NQU IWORK(14) the method order last used (successfully).
4053 ! NQCUR IWORK(15) the order to be attempted on the next step.
4054 ! IMXER IWORK(16) the index of the component of largest magnitude in
4055 ! the weighted local error vector ( E(i)/EWT(i) ),
4056 ! on an error return with ISTATE = -4 or -5.
4057 ! LENRW IWORK(17) the length of RWORK actually required, assuming
4058 ! that the length of RWORK is to be fixed for the
4059 ! rest of the problem, and that switching may occur.
4060 ! This is defined on normal returns and on an illegal
4061 ! input return for insufficient storage.
4062 ! LENIW IWORK(18) the length of IWORK actually required, assuming
4063 ! that the length of IWORK is to be fixed for the
4064 ! rest of the problem, and that switching may occur.
4065 ! This is defined on normal returns and on an illegal
4066 ! input return for insufficient storage.
4067 ! MUSED IWORK(19) the method indicator for the last successful step:
4068 ! 1 means Adams (nonstiff), 2 means BDF (stiff).
4069 ! MCUR IWORK(20) the current method indicator:
4070 ! 1 means Adams (nonstiff), 2 means BDF (stiff).
4071 ! This is the method to be attempted
4072 ! on the next step. Thus it differs from MUSED
4073 ! only if a method switch has just been made.
4074 ! The following two arrays are segments of the RWORK array which
4075 ! may also be of interest to the user as optional outputs.
4076 ! For each array, the table below gives its internal name,
4077 ! its base address in RWORK, and its description.
4078 ! Name Base Address Description
4079 ! YH 21 the Nordsieck history array, of size NYH by
4080 ! (NQCUR + 1), where NYH is the initial value
4081 ! of NEQ. For j = 0,1,...,NQCUR, column j+1
4082 ! of YH contains HCUR**j/factorial(j) times
4083 ! the j-th derivative of the interpolating
4084 ! polynomial currently representing the solution,
4085 ! evaluated at T = TCUR.
4086 ! ACOR LACOR array of size NEQ used for the accumulated
4087 ! (from Common corrections on each step, scaled on output
4088 ! as noted) to represent the estimated local error in y
4089 ! on the last step. This is the vector E in
4090 ! the description of the error control. It is
4091 ! defined only on a successful return from
4092 ! DLSODA. The base address LACOR is obtained by
4093 ! including in the user's program the
4094 ! following 2 lines:
4095 ! COMMON /DLS001/ RLS(218), ILS(37)
4096 ! LACOR = ILS(22)
4097 !-----------------------------------------------------------------------
4098 ! Part 2. Other Routines Callable.
4099 ! The following are optional calls which the user may make to
4100 ! gain additional capabilities in conjunction with DLSODA.
4101 ! (The routines XSETUN and XSETF are designed to conform to the
4102 ! SLATEC error handling package.)
4103 ! Form of Call Function
4104 ! CALL XSETUN(LUN) set the logical unit number, LUN, for
4105 ! output of messages from DLSODA, if
4106 ! the default is not desired.
4107 ! The default value of LUN is 6.
4108 ! CALL XSETF(MFLAG) set a flag to control the printing of
4109 ! messages by DLSODA.
4110 ! MFLAG = 0 means do not print. (Danger:
4111 ! This risks losing valuable information.)
4112 ! MFLAG = 1 means print (the default).
4113 ! Either of the above calls may be made at
4114 ! any time and will take effect immediately.
4115 ! CALL DSRCMA(RSAV,ISAV,JOB) saves and restores the contents of
4116 ! the internal Common blocks used by
4117 ! DLSODA (see Part 3 below).
4118 ! RSAV must be a real array of length 240
4119 ! or more, and ISAV must be an integer
4120 ! array of length 46 or more.
4121 ! JOB=1 means save Common into RSAV/ISAV.
4122 ! JOB=2 means restore Common from RSAV/ISAV.
4123 ! DSRCMA is useful if one is
4124 ! interrupting a run and restarting
4125 ! later, or alternating between two or
4126 ! more problems solved with DLSODA.
4127 ! CALL DINTDY(,,,,,) provide derivatives of y, of various
4128 ! (see below) orders, at a specified point t, if
4129 ! desired. It may be called only after
4130 ! a successful return from DLSODA.
4131 ! The detailed instructions for using DINTDY are as follows.
4132 ! The form of the call is:
4133 ! CALL DINTDY (T, K, RWORK(21), NYH, DKY, IFLAG)
4134 ! The input parameters are:
4135 ! T = value of independent variable where answers are desired
4136 ! (normally the same as the T last returned by DLSODA).
4137 ! For valid results, T must lie between TCUR - HU and TCUR.
4138 ! (See optional outputs for TCUR and HU.)
4139 ! K = integer order of the derivative desired. K must satisfy
4140 ! 0 .le. K .le. NQCUR, where NQCUR is the current order
4141 ! (see optional outputs). The capability corresponding
4142 ! to K = 0, i.e. computing y(T), is already provided
4143 ! by DLSODA directly. Since NQCUR .ge. 1, the first
4144 ! derivative dy/dt is always available with DINTDY.
4145 ! RWORK(21) = the base address of the history array YH.
4146 ! NYH = column length of YH, equal to the initial value of NEQ.
4147 ! The output parameters are:
4148 ! DKY = a real array of length NEQ containing the computed value
4149 ! of the K-th derivative of y(t).
4150 ! IFLAG = integer flag, returned as 0 if K and T were legal,
4151 ! -1 if K was illegal, and -2 if T was illegal.
4152 ! On an error return, a message is also written.
4153 !-----------------------------------------------------------------------
4154 ! Part 3. Common Blocks.
4155 ! If DLSODA is to be used in an overlay situation, the user
4156 ! must declare, in the primary overlay, the variables in:
4157 ! (1) the call sequence to DLSODA, and
4158 ! (2) the two internal Common blocks
4159 ! /DLS001/ of length 255 (218 double precision words
4160 ! followed by 37 integer words),
4161 ! /DLSA01/ of length 31 (22 double precision words
4162 ! followed by 9 integer words).
4163 ! If DLSODA is used on a system in which the contents of internal
4164 ! Common blocks are not preserved between calls, the user should
4165 ! declare the above Common blocks in the calling program to insure
4166 ! that their contents are preserved.
4167 ! If the solution of a given problem by DLSODA is to be interrupted
4168 ! and then later continued, such as when restarting an interrupted run
4169 ! or alternating between two or more problems, the user should save,
4170 ! following the return from the last DLSODA call prior to the
4171 ! interruption, the contents of the call sequence variables and the
4172 ! internal Common blocks, and later restore these values before the
4173 ! next DLSODA call for that problem. To save and restore the Common
4174 ! blocks, use Subroutine DSRCMA (see Part 2 above).
4175 !-----------------------------------------------------------------------
4176 ! Part 4. Optionally Replaceable Solver Routines.
4177 ! Below is a description of a routine in the DLSODA package which
4178 ! relates to the measurement of errors, and can be
4179 ! replaced by a user-supplied version, if desired. However, since such
4180 ! a replacement may have a major impact on performance, it should be
4181 ! done only when absolutely necessary, and only with great caution.
4182 ! (Note: The means by which the package version of a routine is
4183 ! superseded by the user's version may be system-dependent.)
4184 ! (a) DEWSET.
4185 ! The following subroutine is called just before each internal
4186 ! integration step, and sets the array of error weights, EWT, as
4187 ! described under ITOL/RTOL/ATOL above:
4188 ! Subroutine DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
4189 ! where NEQ, ITOL, RTOL, and ATOL are as in the DLSODA call sequence,
4190 ! YCUR contains the current dependent variable vector, and
4191 ! EWT is the array of weights set by DEWSET.
4192 ! If the user supplies this subroutine, it must return in EWT(i)
4193 ! (i = 1,...,NEQ) a positive quantity suitable for comparing errors
4194 ! in y(i) to. The EWT array returned by DEWSET is passed to the
4195 ! DMNORM routine, and also used by DLSODA in the computation
4196 ! of the optional output IMXER, and the increments for difference
4197 ! quotient Jacobians.
4198 ! In the user-supplied version of DEWSET, it may be desirable to use
4199 ! the current values of derivatives of y. Derivatives up to order NQ
4200 ! are available from the history array YH, described above under
4201 ! optional outputs. In DEWSET, YH is identical to the YCUR array,
4202 ! extended to NQ + 1 columns with a column length of NYH and scale
4203 ! factors of H**j/factorial(j). On the first call for the problem,
4204 ! given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
4205 ! NYH is the initial value of NEQ. The quantities NQ, H, and NST
4206 ! can be obtained by including in DEWSET the statements:
4207 ! DOUBLE PRECISION RLS
4208 ! COMMON /DLS001/ RLS(218),ILS(37)
4209 ! NQ = ILS(33)
4210 ! NST = ILS(34)
4211 ! H = RLS(212)
4212 ! Thus, for example, the current value of dy/dt can be obtained as
4213 ! YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is
4214 ! unnecessary when NST = 0).
4215 !-----------------------------------------------------------------------
4216 !***REVISION HISTORY (YYYYMMDD)
4217 ! 19811102 DATE WRITTEN
4218 ! 19820126 Fixed bug in tests of work space lengths;
4219 ! minor corrections in main prologue and comments.
4220 ! 19870330 Major update: corrected comments throughout;
4221 ! removed TRET from Common; rewrote EWSET with 4 loops;
4222 ! fixed t test in INTDY; added Cray directives in STODA;
4223 ! in STODA, fixed DELP init. and logic around PJAC call;
4224 ! combined routines to save/restore Common;
4225 ! passed LEVEL = 0 in error message calls (except run abort).
4226 ! 19970225 Fixed lines setting JSTART = -2 in Subroutine LSODA.
4227 ! 20010425 Major update: convert source lines to upper case;
4228 ! added *DECK lines; changed from 1 to * in dummy dimensions;
4229 ! changed names R1MACH/D1MACH to RUMACH/DUMACH;
4230 ! renamed routines for uniqueness across single/double prec.;
4231 ! converted intrinsic names to generic form;
4232 ! removed ILLIN and NTREP (data loaded) from Common;
4233 ! removed all 'own' variables from Common;
4234 ! changed error messages to quoted strings;
4235 ! replaced XERRWV/XERRWD with 1993 revised version;
4236 ! converted prologues, comments, error messages to mixed case;
4237 ! numerous corrections to prologues and internal comments.
4238 ! 20010507 Converted single precision source to double precision.
4239 ! 20010613 Revised excess accuracy test (to match rest of ODEPACK).
4240 ! 20010808 Fixed bug in DPRJA (matrix in DBNORM call).
4241 ! 20020502 Corrected declarations in descriptions of user routines.
4242 ! 20031105 Restored 'own' variables to Common blocks, to enable
4243 ! interrupt/restart feature.
4244 ! 20031112 Added SAVE statements for data-loaded constants.
4245 !-----------------------------------------------------------------------
4246 ! Other routines in the DLSODA package.
4247 ! In addition to Subroutine DLSODA, the DLSODA package includes the
4248 ! following subroutines and function routines:
4249 ! DINTDY computes an interpolated value of the y vector at t = TOUT.
4250 ! DSTODA is the core integrator, which does one step of the
4251 ! integration and the associated error control.
4252 ! DCFODE sets all method coefficients and test constants.
4253 ! DPRJA computes and preprocesses the Jacobian matrix J = df/dy
4254 ! and the Newton iteration matrix P = I - h*l0*J.
4255 ! DSOLSY manages solution of linear system in chord iteration.
4256 ! DEWSET sets the error weight vector EWT before each step.
4257 ! DMNORM computes the weighted max-norm of a vector.
4258 ! DFNORM computes the norm of a full matrix consistent with the
4259 ! weighted max-norm on vectors.
4260 ! DBNORM computes the norm of a band matrix consistent with the
4261 ! weighted max-norm on vectors.
4262 ! DSRCMA is a user-callable routine to save and restore
4263 ! the contents of the internal Common blocks.
4264 ! DGEFA and DGESL are routines from LINPACK for solving full
4265 ! systems of linear algebraic equations.
4266 ! DGBFA and DGBSL are routines from LINPACK for solving banded
4267 ! linear systems.
4268 ! DUMACH computes the unit roundoff in a machine-independent manner.
4269 ! XERRWD, XSETUN, XSETF, IXSAV, and IUMACH handle the printing of all
4270 ! error messages and warnings. XERRWD is machine-dependent.
4271 ! Note: DMNORM, DFNORM, DBNORM, DUMACH, IXSAV, and IUMACH are
4272 ! function routines. All the others are subroutines.
4273 !-----------------------------------------------------------------------
4274 ! EXTERNAL DPRJA, DSOLSY
4275 ! DOUBLE PRECISION :: DUMACH, DMNORM
4276 ! INTEGER :: INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS, &
4277 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
4278 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
4279 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
4280 ! INTEGER :: INSUFR, INSUFI, IXPR, IOWNS2, JTYP, MUSED, MXORDN, MXORDS
4281 ! INTEGER :: I, I1, I2, IFLAG, IMXER, KGO, LF0, &
4282 ! LENIW, LENRW, LENWM, ML, MORD, MU, MXHNL0, MXSTP0
4283 ! INTEGER :: LEN1, LEN1C, LEN1N, LEN1S, LEN2, LENIWC, LENRWC
4284 ! DOUBLE PRECISION :: ROWNS, &
4285 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
4286 ! DOUBLE PRECISION :: TSW, ROWNS2, PDNORM
4287 ! DOUBLE PRECISION :: ATOLI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RTOLI, &
4288 ! TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0
4289 ! DIMENSION MORD(2)
4290 ! LOGICAL :: IHIT
4291 ! CHARACTER(60) :: MSG
4292 ! SAVE MORD, MXSTP0, MXHNL0
4293 !-----------------------------------------------------------------------
4294 ! The following two internal Common blocks contain
4295 ! (a) variables which are local to any subroutine but whose values must
4296 ! be preserved between calls to the routine ("own" variables), and
4297 ! (b) variables which are communicated between subroutines.
4298 ! The block DLS001 is declared in subroutines DLSODA, DINTDY, DSTODA,
4299 ! DPRJA, and DSOLSY.
4300 ! The block DLSA01 is declared in subroutines DLSODA, DSTODA, and DPRJA.
4301 ! Groups of variables are replaced by dummy arrays in the Common
4302 ! declarations in routines where those variables are not used.
4303 !-----------------------------------------------------------------------
4304 ! COMMON /DLS001/ ROWNS(209), &
4305 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
4306 ! INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6), &
4307 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
4308 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
4309 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
4310 ! COMMON /DLSA01/ TSW, ROWNS2(20), PDNORM, &
4311 ! INSUFR, INSUFI, IXPR, IOWNS2(2), JTYP, MUSED, MXORDN, MXORDS
4312 ! DATA MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
4313 !-----------------------------------------------------------------------
4314 ! Block A.
4315 ! This code block is executed on every call.
4316 ! It tests ISTATE and ITASK for legality and branches appropriately.
4317 ! If ISTATE .gt. 1 but the flag INIT shows that initialization has
4318 ! not yet been done, an error return occurs.
4319 ! If ISTATE = 1 and TOUT = T, return immediately.
4320 !-----------------------------------------------------------------------
4321 ! IF (ISTATE < 1 .OR. ISTATE > 3) GO TO 601
4322 ! IF (ITASK < 1 .OR. ITASK > 5) GO TO 602
4323 ! IF (ISTATE == 1) GO TO 10
4324 ! IF (INIT == 0) GO TO 603
4325 ! IF (ISTATE == 2) GO TO 200
4326 ! GO TO 20
4327 ! 10 INIT = 0
4328 ! IF (TOUT == T) RETURN
4329 !-----------------------------------------------------------------------
4330 ! Block B.
4331 ! The next code block is executed for the initial call (ISTATE = 1),
4332 ! or for a continuation call with parameter changes (ISTATE = 3).
4333 ! It contains checking of all inputs and various initializations.
4334 ! First check legality of the non-optional inputs NEQ, ITOL, IOPT,
4335 ! JT, ML, and MU.
4336 !-----------------------------------------------------------------------
4337 ! 20 IF (NEQ(1) <= 0) GO TO 604
4338 ! IF (ISTATE == 1) GO TO 25
4339 ! IF (NEQ(1) > N) GO TO 605
4340 ! 25 N = NEQ(1)
4341 ! IF (ITOL < 1 .OR. ITOL > 4) GO TO 606
4342 ! IF (IOPT < 0 .OR. IOPT > 1) GO TO 607
4343 ! IF (JT == 3 .OR. JT < 1 .OR. JT > 5) GO TO 608
4344 ! JTYP = JT
4345 ! IF (JT <= 2) GO TO 30
4346 ! ML = IWORK(1)
4347 ! MU = IWORK(2)
4348 ! IF (ML < 0 .OR. ML >= N) GO TO 609
4349 ! IF (MU < 0 .OR. MU >= N) GO TO 610
4350 ! 30 CONTINUE
4351 ! Next process and check the optional inputs. --------------------------
4352 ! IF (IOPT == 1) GO TO 40
4353 ! IXPR = 0
4354 ! MXSTEP = MXSTP0
4355 ! MXHNIL = MXHNL0
4356 ! HMXI = 0.0D0
4357 ! HMIN = 0.0D0
4358 ! IF (ISTATE /= 1) GO TO 60
4359 ! H0 = 0.0D0
4360 ! MXORDN = MORD(1)
4361 ! MXORDS = MORD(2)
4362 ! GO TO 60
4363 ! 40 IXPR = IWORK(5)
4364 ! IF (IXPR < 0 .OR. IXPR > 1) GO TO 611
4365 ! MXSTEP = IWORK(6)
4366 ! IF (MXSTEP < 0) GO TO 612
4367 ! IF (MXSTEP == 0) MXSTEP = MXSTP0
4368 ! MXHNIL = IWORK(7)
4369 ! IF (MXHNIL < 0) GO TO 613
4370 ! IF (MXHNIL == 0) MXHNIL = MXHNL0
4371 ! IF (ISTATE /= 1) GO TO 50
4372 ! H0 = RWORK(5)
4373 ! MXORDN = IWORK(8)
4374 ! IF (MXORDN < 0) GO TO 628
4375 ! IF (MXORDN == 0) MXORDN = 100
4376 ! MXORDN = MIN(MXORDN,MORD(1))
4377 ! MXORDS = IWORK(9)
4378 ! IF (MXORDS < 0) GO TO 629
4379 ! IF (MXORDS == 0) MXORDS = 100
4380 ! MXORDS = MIN(MXORDS,MORD(2))
4381 ! IF ((TOUT - T)*H0 < 0.0D0) GO TO 614
4382 ! 50 HMAX = RWORK(6)
4383 ! IF (HMAX < 0.0D0) GO TO 615
4384 ! HMXI = 0.0D0
4385 ! IF (HMAX > 0.0D0) HMXI = 1.0D0/HMAX
4386 ! HMIN = RWORK(7)
4387 ! IF (HMIN < 0.0D0) GO TO 616
4388 !-----------------------------------------------------------------------
4389 ! Set work array pointers and check lengths LRW and LIW.
4390 ! If ISTATE = 1, METH is initialized to 1 here to facilitate the
4391 ! checking of work space lengths.
4392 ! Pointers to segments of RWORK and IWORK are named by prefixing L to
4393 ! the name of the segment. E.g., the segment YH starts at RWORK(LYH).
4394 ! Segments of RWORK (in order) are denoted YH, WM, EWT, SAVF, ACOR.
4395 ! If the lengths provided are insufficient for the current method,
4396 ! an error return occurs. This is treated as illegal input on the
4397 ! first call, but as a problem interruption with ISTATE = -7 on a
4398 ! continuation call. If the lengths are sufficient for the current
4399 ! method but not for both methods, a warning message is sent.
4400 !-----------------------------------------------------------------------
4401 ! 60 IF (ISTATE == 1) METH = 1
4402 ! IF (ISTATE == 1) NYH = N
4403 ! LYH = 21
4404 ! LEN1N = 20 + (MXORDN + 1)*NYH
4405 ! LEN1S = 20 + (MXORDS + 1)*NYH
4406 ! LWM = LEN1S + 1
4407 ! IF (JT <= 2) LENWM = N*N + 2
4408 ! IF (JT >= 4) LENWM = (2*ML + MU + 1)*N + 2
4409 ! LEN1S = LEN1S + LENWM
4410 ! LEN1C = LEN1N
4411 ! IF (METH == 2) LEN1C = LEN1S
4412 ! LEN1 = MAX(LEN1N,LEN1S)
4413 ! LEN2 = 3*N
4414 ! LENRW = LEN1 + LEN2
4415 ! LENRWC = LEN1C + LEN2
4416 ! IWORK(17) = LENRW
4417 ! LIWM = 1
4418 ! LENIW = 20 + N
4419 ! LENIWC = 20
4420 ! IF (METH == 2) LENIWC = LENIW
4421 ! IWORK(18) = LENIW
4422 ! IF (ISTATE == 1 .AND. LRW < LENRWC) GO TO 617
4423 ! IF (ISTATE == 1 .AND. LIW < LENIWC) GO TO 618
4424 ! IF (ISTATE == 3 .AND. LRW < LENRWC) GO TO 550
4425 ! IF (ISTATE == 3 .AND. LIW < LENIWC) GO TO 555
4426 ! LEWT = LEN1 + 1
4427 ! INSUFR = 0
4428 ! IF (LRW >= LENRW) GO TO 65
4429 ! INSUFR = 2
4430 ! LEWT = LEN1C + 1
4431 ! MSG='DLSODA- Warning.. RWORK length is sufficient for now, but '
4432 ! CALL XERRWD (MSG, 60, 103, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4433 ! MSG=' may not be later. Integration will proceed anyway. '
4434 ! CALL XERRWD (MSG, 60, 103, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4435 ! MSG = ' Length needed is LENRW = I1, while LRW = I2.'
4436 ! CALL XERRWD (MSG, 50, 103, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
4437 ! 65 LSAVF = LEWT + N
4438 ! LACOR = LSAVF + N
4439 ! INSUFI = 0
4440 ! IF (LIW >= LENIW) GO TO 70
4441 ! INSUFI = 2
4442 ! MSG='DLSODA- Warning.. IWORK length is sufficient for now, but '
4443 ! CALL XERRWD (MSG, 60, 104, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4444 ! MSG=' may not be later. Integration will proceed anyway. '
4445 ! CALL XERRWD (MSG, 60, 104, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4446 ! MSG = ' Length needed is LENIW = I1, while LIW = I2.'
4447 ! CALL XERRWD (MSG, 50, 104, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
4448 ! 70 CONTINUE
4449 ! Check RTOL and ATOL for legality. ------------------------------------
4450 ! RTOLI = RTOL(1)
4451 ! ATOLI = ATOL(1)
4452 ! DO 75 I = 1,N
4453 ! IF (ITOL >= 3) RTOLI = RTOL(I)
4454 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
4455 ! IF (RTOLI < 0.0D0) GO TO 619
4456 ! IF (ATOLI < 0.0D0) GO TO 620
4457 ! 75 END DO
4458 ! IF (ISTATE == 1) GO TO 100
4459 ! If ISTATE = 3, set flag to signal parameter changes to DSTODA. -------
4460 ! JSTART = -1
4461 ! IF (N == NYH) GO TO 200
4462 ! NEQ was reduced. Zero part of YH to avoid undefined references. -----
4463 ! I1 = LYH + L*NYH
4464 ! I2 = LYH + (MAXORD + 1)*NYH - 1
4465 ! IF (I1 > I2) GO TO 200
4466 ! DO 95 I = I1,I2
4467 ! RWORK(I) = 0.0D0
4468 ! 95 END DO
4469 ! GO TO 200
4470 !-----------------------------------------------------------------------
4471 ! Block C.
4472 ! The next block is for the initial call only (ISTATE = 1).
4473 ! It contains all remaining initializations, the initial call to F,
4474 ! and the calculation of the initial step size.
4475 ! The error weights in EWT are inverted after being loaded.
4476 !-----------------------------------------------------------------------
4477 ! 100 UROUND = DUMACH()
4478 ! TN = T
4479 ! TSW = T
4480 ! MAXORD = MXORDN
4481 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 110
4482 ! TCRIT = RWORK(1)
4483 ! IF ((TCRIT - TOUT)*(TOUT - T) < 0.0D0) GO TO 625
4484 ! IF (H0 /= 0.0D0 .AND. (T + H0 - TCRIT)*H0 > 0.0D0) &
4485 ! H0 = TCRIT - T
4486 ! 110 JSTART = 0
4487 ! NHNIL = 0
4488 ! NST = 0
4489 ! NJE = 0
4490 ! NSLAST = 0
4491 ! HU = 0.0D0
4492 ! NQU = 0
4493 ! MUSED = 0
4494 ! MITER = 0
4495 ! CCMAX = 0.3D0
4496 ! MAXCOR = 3
4497 ! MSBP = 20
4498 ! MXNCF = 10
4499 ! Initial call to F. (LF0 points to YH(*,2).) -------------------------
4500 ! LF0 = LYH + NYH
4501 ! CALL F (NEQ, T, Y, RWORK(LF0))
4502 ! NFE = 1
4503 ! Load the initial value vector in YH. ---------------------------------
4504 ! DO 115 I = 1,N
4505 ! RWORK(I+LYH-1) = Y(I)
4506 ! 115 END DO
4507 ! Load and invert the EWT array. (H is temporarily set to 1.0.) -------
4508 ! NQ = 1
4509 ! H = 1.0D0
4510 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
4511 ! DO 120 I = 1,N
4512 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
4513 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
4514 ! 120 END DO
4515 !-----------------------------------------------------------------------
4516 ! The coding below computes the step size, H0, to be attempted on the
4517 ! first step, unless the user has supplied a value for this.
4518 ! First check that TOUT - T differs significantly from zero.
4519 ! A scalar tolerance quantity TOL is computed, as MAX(RTOL(i))
4520 ! if this is positive, or MAX(ATOL(i)/ABS(Y(i))) otherwise, adjusted
4521 ! so as to be between 100*UROUND and 1.0E-3.
4522 ! Then the computed value H0 is given by:
4523 ! H0**(-2) = 1./(TOL * w0**2) + TOL * (norm(F))**2
4524 ! where w0 = MAX ( ABS(T), ABS(TOUT) ),
4525 ! F = the initial value of the vector f(t,y), and
4526 ! norm() = the weighted vector norm used throughout, given by
4527 ! the DMNORM function routine, and weighted by the
4528 ! tolerances initially loaded into the EWT array.
4529 ! The sign of H0 is inferred from the initial values of TOUT and T.
4530 ! ABS(H0) is made .le. ABS(TOUT-T) in any case.
4531 !-----------------------------------------------------------------------
4532 ! IF (H0 /= 0.0D0) GO TO 180
4533 ! TDIST = ABS(TOUT - T)
4534 ! W0 = MAX(ABS(T),ABS(TOUT))
4535 ! IF (TDIST < 2.0D0*UROUND*W0) GO TO 622
4536 ! TOL = RTOL(1)
4537 ! IF (ITOL <= 2) GO TO 140
4538 ! DO 130 I = 1,N
4539 ! TOL = MAX(TOL,RTOL(I))
4540 ! 130 END DO
4541 ! 140 IF (TOL > 0.0D0) GO TO 160
4542 ! ATOLI = ATOL(1)
4543 ! DO 150 I = 1,N
4544 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
4545 ! AYI = ABS(Y(I))
4546 ! IF (AYI /= 0.0D0) TOL = MAX(TOL,ATOLI/AYI)
4547 ! 150 END DO
4548 ! 160 TOL = MAX(TOL,100.0D0*UROUND)
4549 ! TOL = MIN(TOL,0.001D0)
4550 ! SUM = DMNORM (N, RWORK(LF0), RWORK(LEWT))
4551 ! SUM = 1.0D0/(TOL*W0*W0) + TOL*SUM**2
4552 ! H0 = 1.0D0/SQRT(SUM)
4553 ! H0 = MIN(H0,TDIST)
4554 ! H0 = SIGN(H0,TOUT-T)
4555 ! Adjust H0 if necessary to meet HMAX bound. ---------------------------
4556 ! 180 RH = ABS(H0)*HMXI
4557 ! IF (RH > 1.0D0) H0 = H0/RH
4558 ! Load H with H0 and scale YH(*,2) by H0. ------------------------------
4559 ! H = H0
4560 ! DO 190 I = 1,N
4561 ! RWORK(I+LF0-1) = H0*RWORK(I+LF0-1)
4562 ! 190 END DO
4563 ! GO TO 270
4564 !-----------------------------------------------------------------------
4565 ! Block D.
4566 ! The next code block is for continuation calls only (ISTATE = 2 or 3)
4567 ! and is to check stop conditions before taking a step.
4568 !-----------------------------------------------------------------------
4569 ! 200 NSLAST = NST
4570 ! GO TO (210, 250, 220, 230, 240), ITASK
4571 ! 210 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
4572 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
4573 ! IF (IFLAG /= 0) GO TO 627
4574 ! T = TOUT
4575 ! GO TO 420
4576 ! 220 TP = TN - HU*(1.0D0 + 100.0D0*UROUND)
4577 ! IF ((TP - TOUT)*H > 0.0D0) GO TO 623
4578 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 250
4579 ! T = TN
4580 ! GO TO 400
4581 ! 230 TCRIT = RWORK(1)
4582 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
4583 ! IF ((TCRIT - TOUT)*H < 0.0D0) GO TO 625
4584 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 245
4585 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
4586 ! IF (IFLAG /= 0) GO TO 627
4587 ! T = TOUT
4588 ! GO TO 420
4589 ! 240 TCRIT = RWORK(1)
4590 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
4591 ! 245 HMX = ABS(TN) + ABS(H)
4592 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
4593 ! IF (IHIT) T = TCRIT
4594 ! IF (IHIT) GO TO 400
4595 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
4596 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
4597 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
4598 ! IF (ISTATE == 2 .AND. JSTART >= 0) JSTART = -2
4599 !-----------------------------------------------------------------------
4600 ! Block E.
4601 ! The next block is normally executed for all calls and contains
4602 ! the call to the one-step core integrator DSTODA.
4603 ! This is a looping point for the integration steps.
4604 ! First check for too many steps being taken, update EWT (if not at
4605 ! start of problem), check for too much accuracy being requested, and
4606 ! check for H below the roundoff level in T.
4607 !-----------------------------------------------------------------------
4608 ! 250 CONTINUE
4609 ! IF (METH == MUSED) GO TO 255
4610 ! IF (INSUFR == 1) GO TO 550
4611 ! IF (INSUFI == 1) GO TO 555
4612 ! 255 IF ((NST-NSLAST) >= MXSTEP) GO TO 500
4613 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
4614 ! DO 260 I = 1,N
4615 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 510
4616 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
4617 ! 260 END DO
4618 ! 270 TOLSF = UROUND*DMNORM (N, RWORK(LYH), RWORK(LEWT))
4619 ! IF (TOLSF <= 1.0D0) GO TO 280
4620 ! TOLSF = TOLSF*2.0D0
4621 ! IF (NST == 0) GO TO 626
4622 ! GO TO 520
4623 ! 280 IF ((TN + H) /= TN) GO TO 290
4624 ! NHNIL = NHNIL + 1
4625 ! IF (NHNIL > MXHNIL) GO TO 290
4626 ! MSG = 'DLSODA- Warning..Internal T (=R1) and H (=R2) are'
4627 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4628 ! MSG=' such that in the machine, T + H = T on the next step '
4629 ! CALL XERRWD (MSG, 60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4630 ! MSG = ' (H = step size). Solver will continue anyway.'
4631 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 2, TN, H)
4632 ! IF (NHNIL < MXHNIL) GO TO 290
4633 ! MSG = 'DLSODA- Above warning has been issued I1 times. '
4634 ! CALL XERRWD (MSG, 50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4635 ! MSG = ' It will not be issued again for this problem.'
4636 ! CALL XERRWD (MSG, 50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
4637 ! 290 CONTINUE
4638 !-----------------------------------------------------------------------
4639 ! CALL DSTODA(NEQ,Y,YH,NYH,YH,EWT,SAVF,ACOR,WM,IWM,F,JAC,DPRJA,DSOLSY)
4640 !-----------------------------------------------------------------------
4641 ! CALL DSTODA (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT), &
4642 ! RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), IWORK(LIWM), &
4643 ! F, JAC, DPRJA, DSOLSY)
4644 ! KGO = 1 - KFLAG
4645 ! GO TO (300, 530, 540), KGO
4646 !-----------------------------------------------------------------------
4647 ! Block F.
4648 ! The following block handles the case of a successful return from the
4649 ! core integrator (KFLAG = 0).
4650 ! If a method switch was just made, record TSW, reset MAXORD,
4651 ! set JSTART to -1 to signal DSTODA to complete the switch,
4652 ! and do extra printing of data if IXPR = 1.
4653 ! Then, in any case, check for stop conditions.
4654 !-----------------------------------------------------------------------
4655 ! 300 INIT = 1
4656 ! IF (METH == MUSED) GO TO 310
4657 ! TSW = TN
4658 ! MAXORD = MXORDN
4659 ! IF (METH == 2) MAXORD = MXORDS
4660 ! IF (METH == 2) RWORK(LWM) = SQRT(UROUND)
4661 ! INSUFR = MIN(INSUFR,1)
4662 ! INSUFI = MIN(INSUFI,1)
4663 ! JSTART = -1
4664 ! IF (IXPR == 0) GO TO 310
4665 ! IF (METH == 2) THEN
4666 ! MSG='DLSODA- A switch to the BDF (stiff) method has occurred '
4667 ! CALL XERRWD (MSG, 60, 105, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4668 ! ENDIF
4669 ! IF (METH == 1) THEN
4670 ! MSG='DLSODA- A switch to the Adams (nonstiff) method has occurred'
4671 ! CALL XERRWD (MSG, 60, 106, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4672 ! ENDIF
4673 ! MSG=' at T = R1, tentative step size H = R2, step NST = I1 '
4674 ! CALL XERRWD (MSG, 60, 107, 0, 1, NST, 0, 2, TN, H)
4675 ! 310 GO TO (320, 400, 330, 340, 350), ITASK
4676 ! ITASK = 1. If TOUT has been reached, interpolate. -------------------
4677 ! 320 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
4678 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
4679 ! T = TOUT
4680 ! GO TO 420
4681 ! ITASK = 3. Jump to exit if TOUT was reached. ------------------------
4682 ! 330 IF ((TN - TOUT)*H >= 0.0D0) GO TO 400
4683 ! GO TO 250
4684 ! ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary.
4685 ! 340 IF ((TN - TOUT)*H < 0.0D0) GO TO 345
4686 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
4687 ! T = TOUT
4688 ! GO TO 420
4689 ! 345 HMX = ABS(TN) + ABS(H)
4690 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
4691 ! IF (IHIT) GO TO 400
4692 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
4693 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
4694 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
4695 ! IF (JSTART >= 0) JSTART = -2
4696 ! GO TO 250
4697 ! ITASK = 5. See if TCRIT was reached and jump to exit. ---------------
4698 ! 350 HMX = ABS(TN) + ABS(H)
4699 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
4700 !-----------------------------------------------------------------------
4701 ! Block G.
4702 ! The following block handles all successful returns from DLSODA.
4703 ! If ITASK .ne. 1, Y is loaded from YH and T is set accordingly.
4704 ! ISTATE is set to 2, and the optional outputs are loaded into the
4705 ! work arrays before returning.
4706 !-----------------------------------------------------------------------
4707 ! 400 DO 410 I = 1,N
4708 ! Y(I) = RWORK(I+LYH-1)
4709 ! 410 END DO
4710 ! T = TN
4711 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 420
4712 ! IF (IHIT) T = TCRIT
4713 ! 420 ISTATE = 2
4714 ! RWORK(11) = HU
4715 ! RWORK(12) = H
4716 ! RWORK(13) = TN
4717 ! RWORK(15) = TSW
4718 ! IWORK(11) = NST
4719 ! IWORK(12) = NFE
4720 ! IWORK(13) = NJE
4721 ! IWORK(14) = NQU
4722 ! IWORK(15) = NQ
4723 ! IWORK(19) = MUSED
4724 ! IWORK(20) = METH
4725 ! RETURN
4726 !-----------------------------------------------------------------------
4727 ! Block H.
4728 ! The following block handles all unsuccessful returns other than
4729 ! those for illegal input. First the error message routine is called.
4730 ! If there was an error test or convergence test failure, IMXER is set.
4731 ! Then Y is loaded from YH and T is set to TN.
4732 ! The optional outputs are loaded into the work arrays before returning.
4733 !-----------------------------------------------------------------------
4734 ! The maximum number of steps was taken before reaching TOUT. ----------
4735 ! 500 MSG = 'DLSODA- At current T (=R1), MXSTEP (=I1) steps '
4736 ! CALL XERRWD (MSG, 50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4737 ! MSG = ' taken on this call before reaching TOUT '
4738 ! CALL XERRWD (MSG, 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0)
4739 ! ISTATE = -1
4740 ! GO TO 580
4741 ! EWT(i) .le. 0.0 for some i (not at start of problem). ----------------
4742 ! 510 EWTI = RWORK(LEWT+I-1)
4743 ! MSG = 'DLSODA- At T (=R1), EWT(I1) has become R2 <= 0.'
4744 ! CALL XERRWD (MSG, 50, 202, 0, 1, I, 0, 2, TN, EWTI)
4745 ! ISTATE = -6
4746 ! GO TO 580
4747 ! Too much accuracy requested for machine precision. -------------------
4748 ! 520 MSG = 'DLSODA- At T (=R1), too much accuracy requested '
4749 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4750 ! MSG = ' for precision of machine.. See TOLSF (=R2) '
4751 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
4752 ! RWORK(14) = TOLSF
4753 ! ISTATE = -2
4754 ! GO TO 580
4755 ! KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
4756 ! 530 MSG = 'DLSODA- At T(=R1) and step size H(=R2), the error'
4757 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4758 ! MSG = ' test failed repeatedly or with ABS(H) = HMIN'
4759 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 2, TN, H)
4760 ! ISTATE = -4
4761 ! GO TO 560
4762 ! KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
4763 ! 540 MSG = 'DLSODA- At T (=R1) and step size H (=R2), the '
4764 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4765 ! MSG = ' corrector convergence failed repeatedly '
4766 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4767 ! MSG = ' or with ABS(H) = HMIN '
4768 ! CALL XERRWD (MSG, 30, 205, 0, 0, 0, 0, 2, TN, H)
4769 ! ISTATE = -5
4770 ! GO TO 560
4771 ! RWORK length too small to proceed. -----------------------------------
4772 ! 550 MSG = 'DLSODA- At current T(=R1), RWORK length too small'
4773 ! CALL XERRWD (MSG, 50, 206, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4774 ! MSG=' to proceed. The integration was otherwise successful.'
4775 ! CALL XERRWD (MSG, 60, 206, 0, 0, 0, 0, 1, TN, 0.0D0)
4776 ! ISTATE = -7
4777 ! GO TO 580
4778 ! IWORK length too small to proceed. -----------------------------------
4779 ! 555 MSG = 'DLSODA- At current T(=R1), IWORK length too small'
4780 ! CALL XERRWD (MSG, 50, 207, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4781 ! MSG=' to proceed. The integration was otherwise successful.'
4782 ! CALL XERRWD (MSG, 60, 207, 0, 0, 0, 0, 1, TN, 0.0D0)
4783 ! ISTATE = -7
4784 ! GO TO 580
4785 ! Compute IMXER if relevant. -------------------------------------------
4786 ! 560 BIG = 0.0D0
4787 ! IMXER = 1
4788 ! DO 570 I = 1,N
4789 ! SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
4790 ! IF (BIG >= SIZE) GO TO 570
4791 ! BIG = SIZE
4792 ! IMXER = I
4793 ! 570 END DO
4794 ! IWORK(16) = IMXER
4795 ! Set Y vector, T, and optional outputs. -------------------------------
4796 ! 580 DO 590 I = 1,N
4797 ! Y(I) = RWORK(I+LYH-1)
4798 ! 590 END DO
4799 ! T = TN
4800 ! RWORK(11) = HU
4801 ! RWORK(12) = H
4802 ! RWORK(13) = TN
4803 ! RWORK(15) = TSW
4804 ! IWORK(11) = NST
4805 ! IWORK(12) = NFE
4806 ! IWORK(13) = NJE
4807 ! IWORK(14) = NQU
4808 ! IWORK(15) = NQ
4809 ! IWORK(19) = MUSED
4810 ! IWORK(20) = METH
4811 ! RETURN
4812 !-----------------------------------------------------------------------
4813 ! Block I.
4814 ! The following block handles all error returns due to illegal input
4815 ! (ISTATE = -3), as detected before calling the core integrator.
4816 ! First the error message routine is called. If the illegal input
4817 ! is a negative ISTATE, the run is aborted (apparent infinite loop).
4818 !-----------------------------------------------------------------------
4819 ! 601 MSG = 'DLSODA- ISTATE (=I1) illegal.'
4820 ! CALL XERRWD (MSG, 30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0)
4821 ! IF (ISTATE < 0) GO TO 800
4822 ! GO TO 700
4823 ! 602 MSG = 'DLSODA- ITASK (=I1) illegal. '
4824 ! CALL XERRWD (MSG, 30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0)
4825 ! GO TO 700
4826 ! 603 MSG = 'DLSODA- ISTATE > 1 but DLSODA not initialized.'
4827 ! CALL XERRWD (MSG, 50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4828 ! GO TO 700
4829 ! 604 MSG = 'DLSODA- NEQ (=I1) < 1 '
4830 ! CALL XERRWD (MSG, 30, 4, 0, 1, NEQ(1), 0, 0, 0.0D0, 0.0D0)
4831 ! GO TO 700
4832 ! 605 MSG = 'DLSODA- ISTATE = 3 and NEQ increased (I1 to I2). '
4833 ! CALL XERRWD (MSG, 50, 5, 0, 2, N, NEQ(1), 0, 0.0D0, 0.0D0)
4834 ! GO TO 700
4835 ! 606 MSG = 'DLSODA- ITOL (=I1) illegal. '
4836 ! CALL XERRWD (MSG, 30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0)
4837 ! GO TO 700
4838 ! 607 MSG = 'DLSODA- IOPT (=I1) illegal. '
4839 ! CALL XERRWD (MSG, 30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0)
4840 ! GO TO 700
4841 ! 608 MSG = 'DLSODA- JT (=I1) illegal. '
4842 ! CALL XERRWD (MSG, 30, 8, 0, 1, JT, 0, 0, 0.0D0, 0.0D0)
4843 ! GO TO 700
4844 ! 609 MSG = 'DLSODA- ML (=I1) illegal: < 0 or >= NEQ (=I2) '
4845 ! CALL XERRWD (MSG, 50, 9, 0, 2, ML, NEQ(1), 0, 0.0D0, 0.0D0)
4846 ! GO TO 700
4847 ! 610 MSG = 'DLSODA- MU (=I1) illegal: < 0 or >= NEQ (=I2) '
4848 ! CALL XERRWD (MSG, 50, 10, 0, 2, MU, NEQ(1), 0, 0.0D0, 0.0D0)
4849 ! GO TO 700
4850 ! 611 MSG = 'DLSODA- IXPR (=I1) illegal. '
4851 ! CALL XERRWD (MSG, 30, 11, 0, 1, IXPR, 0, 0, 0.0D0, 0.0D0)
4852 ! GO TO 700
4853 ! 612 MSG = 'DLSODA- MXSTEP (=I1) < 0 '
4854 ! CALL XERRWD (MSG, 30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0)
4855 ! GO TO 700
4856 ! 613 MSG = 'DLSODA- MXHNIL (=I1) < 0 '
4857 ! CALL XERRWD (MSG, 30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
4858 ! GO TO 700
4859 ! 614 MSG = 'DLSODA- TOUT (=R1) behind T (=R2) '
4860 ! CALL XERRWD (MSG, 40, 14, 0, 0, 0, 0, 2, TOUT, T)
4861 ! MSG = ' Integration direction is given by H0 (=R1) '
4862 ! CALL XERRWD (MSG, 50, 14, 0, 0, 0, 0, 1, H0, 0.0D0)
4863 ! GO TO 700
4864 ! 615 MSG = 'DLSODA- HMAX (=R1) < 0.0 '
4865 ! CALL XERRWD (MSG, 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0)
4866 ! GO TO 700
4867 ! 616 MSG = 'DLSODA- HMIN (=R1) < 0.0 '
4868 ! CALL XERRWD (MSG, 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0)
4869 ! GO TO 700
4870 ! 617 MSG='DLSODA- RWORK length needed, LENRW (=I1), exceeds LRW (=I2)'
4871 ! CALL XERRWD (MSG, 60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
4872 ! GO TO 700
4873 ! 618 MSG='DLSODA- IWORK length needed, LENIW (=I1), exceeds LIW (=I2)'
4874 ! CALL XERRWD (MSG, 60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
4875 ! GO TO 700
4876 ! 619 MSG = 'DLSODA- RTOL(I1) is R1 < 0.0 '
4877 ! CALL XERRWD (MSG, 40, 19, 0, 1, I, 0, 1, RTOLI, 0.0D0)
4878 ! GO TO 700
4879 ! 620 MSG = 'DLSODA- ATOL(I1) is R1 < 0.0 '
4880 ! CALL XERRWD (MSG, 40, 20, 0, 1, I, 0, 1, ATOLI, 0.0D0)
4881 ! GO TO 700
4882 ! 621 EWTI = RWORK(LEWT+I-1)
4883 ! MSG = 'DLSODA- EWT(I1) is R1 <= 0.0 '
4884 ! CALL XERRWD (MSG, 40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0)
4885 ! GO TO 700
4886 ! 622 MSG='DLSODA- TOUT(=R1) too close to T(=R2) to start integration.'
4887 ! CALL XERRWD (MSG, 60, 22, 0, 0, 0, 0, 2, TOUT, T)
4888 ! GO TO 700
4889 ! 623 MSG='DLSODA- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
4890 ! CALL XERRWD (MSG, 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
4891 ! GO TO 700
4892 ! 624 MSG='DLSODA- ITASK = 4 or 5 and TCRIT (=R1) behind TCUR (=R2) '
4893 ! CALL XERRWD (MSG, 60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
4894 ! GO TO 700
4895 ! 625 MSG='DLSODA- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
4896 ! CALL XERRWD (MSG, 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
4897 ! GO TO 700
4898 ! 626 MSG = 'DLSODA- At start of problem, too much accuracy '
4899 ! CALL XERRWD (MSG, 50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
4900 ! MSG=' requested for precision of machine.. See TOLSF (=R1) '
4901 ! CALL XERRWD (MSG, 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0)
4902 ! RWORK(14) = TOLSF
4903 ! GO TO 700
4904 ! 627 MSG = 'DLSODA- Trouble in DINTDY. ITASK = I1, TOUT = R1'
4905 ! CALL XERRWD (MSG, 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0)
4906 ! GO TO 700
4907 ! 628 MSG = 'DLSODA- MXORDN (=I1) < 0 '
4908 ! CALL XERRWD (MSG, 30, 28, 0, 1, MXORDN, 0, 0, 0.0D0, 0.0D0)
4909 ! GO TO 700
4910 ! 629 MSG = 'DLSODA- MXORDS (=I1) < 0 '
4911 ! CALL XERRWD (MSG, 30, 29, 0, 1, MXORDS, 0, 0, 0.0D0, 0.0D0)
4912 ! 700 ISTATE = -3
4913 ! RETURN
4914 ! 800 MSG = 'DLSODA- Run aborted.. apparent infinite loop. '
4915 ! CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0)
4916 ! RETURN
4917 !----------------------- End of Subroutine DLSODA ----------------------
4918 ! END SUBROUTINE DLSODA
4919 ! ECK DLSODAR
4920 ! SUBROUTINE DLSODAR (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK, &
4921 ! ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, JT, &
4922 ! G, NG, JROOT)
4923 ! EXTERNAL F, JAC, G
4924 ! INTEGER :: NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, JT, &
4925 ! NG, JROOT
4926 ! DOUBLE PRECISION :: Y, T, TOUT, RTOL, ATOL, RWORK
4927 ! DIMENSION NEQ(*), Y(*), RTOL(*), ATOL(*), RWORK(LRW), IWORK(LIW), &
4928 ! JROOT(NG)
4929 !-----------------------------------------------------------------------
4930 ! This is the 12 November 2003 version of
4931 ! DLSODAR: Livermore Solver for Ordinary Differential Equations, with
4932 ! Automatic method switching for stiff and nonstiff problems,
4933 ! and with Root-finding.
4934 ! This version is in double precision.
4935 ! DLSODAR solves the initial value problem for stiff or nonstiff
4936 ! systems of first order ODEs,
4937 ! dy/dt = f(t,y) , or, in component form,
4938 ! dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ)) (i = 1,...,NEQ).
4939 ! At the same time, it locates the roots of any of a set of functions
4940 ! g(i) = g(i,t,y(1),...,y(NEQ)) (i = 1,...,ng).
4941 ! This a variant version of the DLSODE package. It differs from it
4942 ! in two ways:
4943 ! (a) It switches automatically between stiff and nonstiff methods.
4944 ! This means that the user does not have to determine whether the
4945 ! problem is stiff or not, and the solver will automatically choose the
4946 ! appropriate method. It always starts with the nonstiff method.
4947 ! (b) It finds the root of at least one of a set of constraint
4948 ! functions g(i) of the independent and dependent variables.
4949 ! It finds only those roots for which some g(i), as a function
4950 ! of t, changes sign in the interval of integration.
4951 ! It then returns the solution at the root, if that occurs
4952 ! sooner than the specified stop condition, and otherwise returns
4953 ! the solution according the specified stop condition.
4954 ! Authors: Alan C. Hindmarsh,
4955 ! Center for Applied Scientific Computing, L-561
4956 ! Lawrence Livermore National Laboratory
4957 ! Livermore, CA 94551
4958 ! and
4959 ! Linda R. Petzold
4960 ! Univ. of California at Santa Barbara
4961 ! Dept. of Computer Science
4962 ! Santa Barbara, CA 93106
4963 ! References:
4964 ! 1. Alan C. Hindmarsh, ODEPACK, A Systematized Collection of ODE
4965 ! Solvers, in Scientific Computing, R. S. Stepleman et al. (Eds.),
4966 ! North-Holland, Amsterdam, 1983, pp. 55-64.
4967 ! 2. Linda R. Petzold, Automatic Selection of Methods for Solving
4968 ! Stiff and Nonstiff Systems of Ordinary Differential Equations,
4969 ! Siam J. Sci. Stat. Comput. 4 (1983), pp. 136-148.
4970 ! 3. Kathie L. Hiebert and Lawrence F. Shampine, Implicitly Defined
4971 ! Output Points for Solutions of ODEs, Sandia Report SAND80-0180,
4972 ! February 1980.
4973 !-----------------------------------------------------------------------
4974 ! Summary of Usage.
4975 ! Communication between the user and the DLSODAR package, for normal
4976 ! situations, is summarized here. This summary describes only a subset
4977 ! of the full set of options available. See the full description for
4978 ! details, including alternative treatment of the Jacobian matrix,
4979 ! optional inputs and outputs, nonstandard options, and
4980 ! instructions for special situations. See also the example
4981 ! problem (with program and output) following this summary.
4982 ! A. First provide a subroutine of the form:
4983 ! SUBROUTINE F (NEQ, T, Y, YDOT)
4984 ! DOUBLE PRECISION T, Y(*), YDOT(*)
4985 ! which supplies the vector function f by loading YDOT(i) with f(i).
4986 ! B. Provide a subroutine of the form:
4987 ! SUBROUTINE G (NEQ, T, Y, NG, GOUT)
4988 ! DOUBLE PRECISION T, Y(*), GOUT(NG)
4989 ! which supplies the vector function g by loading GOUT(i) with
4990 ! g(i), the i-th constraint function whose root is sought.
4991 ! C. Write a main program which calls Subroutine DLSODAR once for
4992 ! each point at which answers are desired. This should also provide
4993 ! for possible use of logical unit 6 for output of error messages by
4994 ! DLSODAR. On the first call to DLSODAR, supply arguments as follows:
4995 ! F = name of subroutine for right-hand side vector f.
4996 ! This name must be declared External in calling program.
4997 ! NEQ = number of first order ODEs.
4998 ! Y = array of initial values, of length NEQ.
4999 ! T = the initial value of the independent variable.
5000 ! TOUT = first point where output is desired (.ne. T).
5001 ! ITOL = 1 or 2 according as ATOL (below) is a scalar or array.
5002 ! RTOL = relative tolerance parameter (scalar).
5003 ! ATOL = absolute tolerance parameter (scalar or array).
5004 ! the estimated local error in y(i) will be controlled so as
5005 ! to be less than
5006 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or
5007 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2.
5008 ! Thus the local error test passes if, in each component,
5009 ! either the absolute error is less than ATOL (or ATOL(i)),
5010 ! or the relative error is less than RTOL.
5011 ! Use RTOL = 0.0 for pure absolute error control, and
5012 ! use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative error
5013 ! control. Caution: actual (global) errors may exceed these
5014 ! local tolerances, so choose them conservatively.
5015 ! ITASK = 1 for normal computation of output values of y at t = TOUT.
5016 ! ISTATE = integer flag (input and output). Set ISTATE = 1.
5017 ! IOPT = 0 to indicate no optional inputs used.
5018 ! RWORK = real work array of length at least:
5019 ! 22 + NEQ * MAX(16, NEQ + 9) + 3*NG.
5020 ! See also Paragraph F below.
5021 ! LRW = declared length of RWORK (in user's dimension).
5022 ! IWORK = integer work array of length at least 20 + NEQ.
5023 ! LIW = declared length of IWORK (in user's dimension).
5024 ! JAC = name of subroutine for Jacobian matrix.
5025 ! Use a dummy name. See also Paragraph F below.
5026 ! JT = Jacobian type indicator. Set JT = 2.
5027 ! See also Paragraph F below.
5028 ! G = name of subroutine for constraint functions, whose
5029 ! roots are desired during the integration.
5030 ! This name must be declared External in calling program.
5031 ! NG = number of constraint functions g(i). If there are none,
5032 ! set NG = 0, and pass a dummy name for G.
5033 ! JROOT = integer array of length NG for output of root information.
5034 ! See next paragraph.
5035 ! Note that the main program must declare arrays Y, RWORK, IWORK,
5036 ! JROOT, and possibly ATOL.
5037 ! D. The output from the first call (or any call) is:
5038 ! Y = array of computed values of y(t) vector.
5039 ! T = corresponding value of independent variable. This is
5040 ! TOUT if ISTATE = 2, or the root location if ISTATE = 3,
5041 ! or the farthest point reached if DLSODAR was unsuccessful.
5042 ! ISTATE = 2 or 3 if DLSODAR was successful, negative otherwise.
5043 ! 2 means no root was found, and TOUT was reached as desired.
5044 ! 3 means a root was found prior to reaching TOUT.
5045 ! -1 means excess work done on this call (perhaps wrong JT).
5046 ! -2 means excess accuracy requested (tolerances too small).
5047 ! -3 means illegal input detected (see printed message).
5048 ! -4 means repeated error test failures (check all inputs).
5049 ! -5 means repeated convergence failures (perhaps bad Jacobian
5050 ! supplied or wrong choice of JT or tolerances).
5051 ! -6 means error weight became zero during problem. (Solution
5052 ! component i vanished, and ATOL or ATOL(i) = 0.)
5053 ! -7 means work space insufficient to finish (see messages).
5054 ! JROOT = array showing roots found if ISTATE = 3 on return.
5055 ! JROOT(i) = 1 if g(i) has a root at t, or 0 otherwise.
5056 ! E. To continue the integration after a successful return, proceed
5057 ! as follows:
5058 ! (a) If ISTATE = 2 on return, reset TOUT and call DLSODAR again.
5059 ! (b) If ISTATE = 3 on return, reset ISTATE to 2, call DLSODAR again.
5060 ! In either case, no other parameters need be reset.
5061 ! F. Note: If and when DLSODAR regards the problem as stiff, and
5062 ! switches methods accordingly, it must make use of the NEQ by NEQ
5063 ! Jacobian matrix, J = df/dy. For the sake of simplicity, the
5064 ! inputs to DLSODAR recommended in Paragraph C above cause DLSODAR to
5065 ! treat J as a full matrix, and to approximate it internally by
5066 ! difference quotients. Alternatively, J can be treated as a band
5067 ! matrix (with great potential reduction in the size of the RWORK
5068 ! array). Also, in either the full or banded case, the user can supply
5069 ! J in closed form, with a routine whose name is passed as the JAC
5070 ! argument. These alternatives are described in the paragraphs on
5071 ! RWORK, JAC, and JT in the full description of the call sequence below.
5072 !-----------------------------------------------------------------------
5073 ! Example Problem.
5074 ! The following is a simple example problem, with the coding
5075 ! needed for its solution by DLSODAR. The problem is from chemical
5076 ! kinetics, and consists of the following three rate equations:
5077 ! dy1/dt = -.04*y1 + 1.e4*y2*y3
5078 ! dy2/dt = .04*y1 - 1.e4*y2*y3 - 3.e7*y2**2
5079 ! dy3/dt = 3.e7*y2**2
5080 ! on the interval from t = 0.0 to t = 4.e10, with initial conditions
5081 ! y1 = 1.0, y2 = y3 = 0. The problem is stiff.
5082 ! In addition, we want to find the values of t, y1, y2, and y3 at which
5083 ! (1) y1 reaches the value 1.e-4, and
5084 ! (2) y3 reaches the value 1.e-2.
5085 ! The following coding solves this problem with DLSODAR,
5086 ! printing results at t = .4, 4., ..., 4.e10, and at the computed
5087 ! roots. It uses ITOL = 2 and ATOL much smaller for y2 than y1 or y3
5088 ! because y2 has much smaller values.
5089 ! At the end of the run, statistical quantities of interest are
5090 ! printed (see optional outputs in the full description below).
5091 ! EXTERNAL FEX, GEX
5092 ! DOUBLE PRECISION ATOL, RTOL, RWORK, T, TOUT, Y
5093 ! DIMENSION Y(3), ATOL(3), RWORK(76), IWORK(23), JROOT(2)
5094 ! NEQ = 3
5095 ! Y(1) = 1.
5096 ! Y(2) = 0.
5097 ! Y(3) = 0.
5098 ! T = 0.
5099 ! TOUT = .4
5100 ! ITOL = 2
5101 ! RTOL = 1.D-4
5102 ! ATOL(1) = 1.D-6
5103 ! ATOL(2) = 1.D-10
5104 ! ATOL(3) = 1.D-6
5105 ! ITASK = 1
5106 ! ISTATE = 1
5107 ! IOPT = 0
5108 ! LRW = 76
5109 ! LIW = 23
5110 ! JT = 2
5111 ! NG = 2
5112 ! DO 40 IOUT = 1,12
5113 ! 10 CALL DLSODAR(FEX,NEQ,Y,T,TOUT,ITOL,RTOL,ATOL,ITASK,ISTATE,
5114 ! 1 IOPT,RWORK,LRW,IWORK,LIW,JDUM,JT,GEX,NG,JROOT)
5115 ! WRITE(6,20)T,Y(1),Y(2),Y(3)
5116 ! 20 FORMAT(' At t =',D12.4,' Y =',3D14.6)
5117 ! IF (ISTATE .LT. 0) GO TO 80
5118 ! IF (ISTATE .EQ. 2) GO TO 40
5119 ! WRITE(6,30)JROOT(1),JROOT(2)
5120 ! 30 FORMAT(5X,' The above line is a root, JROOT =',2I5)
5121 ! ISTATE = 2
5122 ! GO TO 10
5123 ! 40 TOUT = TOUT*10.
5124 ! WRITE(6,60)IWORK(11),IWORK(12),IWORK(13),IWORK(10),
5125 ! 1 IWORK(19),RWORK(15)
5126 ! 60 FORMAT(/' No. steps =',I4,' No. f-s =',I4,' No. J-s =',I4,
5127 ! 1 ' No. g-s =',I4/
5128 ! 2 ' Method last used =',I2,' Last switch was at t =',D12.4)
5129 ! STOP
5130 ! 80 WRITE(6,90)ISTATE
5131 ! 90 FORMAT(///' Error halt.. ISTATE =',I3)
5132 ! STOP
5133 ! END
5134 ! SUBROUTINE FEX (NEQ, T, Y, YDOT)
5135 ! DOUBLE PRECISION T, Y, YDOT
5136 ! DIMENSION Y(3), YDOT(3)
5137 ! YDOT(1) = -.04*Y(1) + 1.D4*Y(2)*Y(3)
5138 ! YDOT(3) = 3.D7*Y(2)*Y(2)
5139 ! YDOT(2) = -YDOT(1) - YDOT(3)
5140 ! RETURN
5141 ! END
5142 ! SUBROUTINE GEX (NEQ, T, Y, NG, GOUT)
5143 ! DOUBLE PRECISION T, Y, GOUT
5144 ! DIMENSION Y(3), GOUT(2)
5145 ! GOUT(1) = Y(1) - 1.D-4
5146 ! GOUT(2) = Y(3) - 1.D-2
5147 ! RETURN
5148 ! END
5149 ! The output of this program (on a CDC-7600 in single precision)
5150 ! is as follows:
5151 ! At t = 2.6400e-01 y = 9.899653e-01 3.470563e-05 1.000000e-02
5152 ! The above line is a root, JROOT = 0 1
5153 ! At t = 4.0000e-01 Y = 9.851712e-01 3.386380e-05 1.479493e-02
5154 ! At t = 4.0000e+00 Y = 9.055333e-01 2.240655e-05 9.444430e-02
5155 ! At t = 4.0000e+01 Y = 7.158403e-01 9.186334e-06 2.841505e-01
5156 ! At t = 4.0000e+02 Y = 4.505250e-01 3.222964e-06 5.494717e-01
5157 ! At t = 4.0000e+03 Y = 1.831975e-01 8.941774e-07 8.168016e-01
5158 ! At t = 4.0000e+04 Y = 3.898730e-02 1.621940e-07 9.610125e-01
5159 ! At t = 4.0000e+05 Y = 4.936363e-03 1.984221e-08 9.950636e-01
5160 ! At t = 4.0000e+06 Y = 5.161831e-04 2.065786e-09 9.994838e-01
5161 ! At t = 2.0745e+07 Y = 1.000000e-04 4.000395e-10 9.999000e-01
5162 ! The above line is a root, JROOT = 1 0
5163 ! At t = 4.0000e+07 Y = 5.179817e-05 2.072032e-10 9.999482e-01
5164 ! At t = 4.0000e+08 Y = 5.283401e-06 2.113371e-11 9.999947e-01
5165 ! At t = 4.0000e+09 Y = 4.659031e-07 1.863613e-12 9.999995e-01
5166 ! At t = 4.0000e+10 Y = 1.404280e-08 5.617126e-14 1.000000e+00
5167 ! No. steps = 361 No. f-s = 693 No. J-s = 64 No. g-s = 390
5168 ! Method last used = 2 Last switch was at t = 6.0092e-03
5169 !-----------------------------------------------------------------------
5170 ! Full Description of User Interface to DLSODAR.
5171 ! The user interface to DLSODAR consists of the following parts.
5172 ! 1. The call sequence to Subroutine DLSODAR, which is a driver
5173 ! routine for the solver. This includes descriptions of both
5174 ! the call sequence arguments and of user-supplied routines.
5175 ! Following these descriptions is a description of
5176 ! optional inputs available through the call sequence, and then
5177 ! a description of optional outputs (in the work arrays).
5178 ! 2. Descriptions of other routines in the DLSODAR package that may be
5179 ! (optionally) called by the user. These provide the ability to
5180 ! alter error message handling, save and restore the internal
5181 ! Common, and obtain specified derivatives of the solution y(t).
5182 ! 3. Descriptions of Common blocks to be declared in overlay
5183 ! or similar environments, or to be saved when doing an interrupt
5184 ! of the problem and continued solution later.
5185 ! 4. Description of a subroutine in the DLSODAR package,
5186 ! which the user may replace with his/her own version, if desired.
5187 ! this relates to the measurement of errors.
5188 !-----------------------------------------------------------------------
5189 ! Part 1. Call Sequence.
5190 ! The call sequence parameters used for input only are
5191 ! F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC,
5192 ! JT, G, and NG,
5193 ! that used only for output is JROOT,
5194 ! and those used for both input and output are
5195 ! Y, T, ISTATE.
5196 ! The work arrays RWORK and IWORK are also used for conditional and
5197 ! optional inputs and optional outputs. (The term output here refers
5198 ! to the return from Subroutine DLSODAR to the user's calling program.)
5199 ! The legality of input parameters will be thoroughly checked on the
5200 ! initial call for the problem, but not checked thereafter unless a
5201 ! change in input parameters is flagged by ISTATE = 3 on input.
5202 ! The descriptions of the call arguments are as follows.
5203 ! F = the name of the user-supplied subroutine defining the
5204 ! ODE system. The system must be put in the first-order
5205 ! form dy/dt = f(t,y), where f is a vector-valued function
5206 ! of the scalar t and the vector y. Subroutine F is to
5207 ! compute the function f. It is to have the form
5208 ! SUBROUTINE F (NEQ, T, Y, YDOT)
5209 ! DOUBLE PRECISION T, Y(*), YDOT(*)
5210 ! where NEQ, T, and Y are input, and the array YDOT = f(t,y)
5211 ! is output. Y and YDOT are arrays of length NEQ.
5212 ! Subroutine F should not alter Y(1),...,Y(NEQ).
5213 ! F must be declared External in the calling program.
5214 ! Subroutine F may access user-defined quantities in
5215 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
5216 ! (dimensioned in F) and/or Y has length exceeding NEQ(1).
5217 ! See the descriptions of NEQ and Y below.
5218 ! If quantities computed in the F routine are needed
5219 ! externally to DLSODAR, an extra call to F should be made
5220 ! for this purpose, for consistent and accurate results.
5221 ! If only the derivative dy/dt is needed, use DINTDY instead.
5222 ! NEQ = the size of the ODE system (number of first order
5223 ! ordinary differential equations). Used only for input.
5224 ! NEQ may be decreased, but not increased, during the problem.
5225 ! If NEQ is decreased (with ISTATE = 3 on input), the
5226 ! remaining components of Y should be left undisturbed, if
5227 ! these are to be accessed in F and/or JAC.
5228 ! Normally, NEQ is a scalar, and it is generally referred to
5229 ! as a scalar in this user interface description. However,
5230 ! NEQ may be an array, with NEQ(1) set to the system size.
5231 ! (The DLSODAR package accesses only NEQ(1).) In either case,
5232 ! this parameter is passed as the NEQ argument in all calls
5233 ! to F, JAC, and G. Hence, if it is an array, locations
5234 ! NEQ(2),... may be used to store other integer data and pass
5235 ! it to F, JAC, and G. Each such subroutine must include
5236 ! NEQ in a Dimension statement in that case.
5237 ! Y = a real array for the vector of dependent variables, of
5238 ! length NEQ or more. Used for both input and output on the
5239 ! first call (ISTATE = 1), and only for output on other calls.
5240 ! On the first call, Y must contain the vector of initial
5241 ! values. On output, Y contains the computed solution vector,
5242 ! evaluated at T. If desired, the Y array may be used
5243 ! for other purposes between calls to the solver.
5244 ! This array is passed as the Y argument in all calls to F,
5245 ! JAC, and G. Hence its length may exceed NEQ, and locations
5246 ! Y(NEQ+1),... may be used to store other real data and
5247 ! pass it to F, JAC, and G. (The DLSODAR package accesses only
5248 ! Y(1),...,Y(NEQ).)
5249 ! T = the independent variable. On input, T is used only on the
5250 ! first call, as the initial point of the integration.
5251 ! On output, after each call, T is the value at which a
5252 ! computed solution y is evaluated (usually the same as TOUT).
5253 ! If a root was found, T is the computed location of the
5254 ! root reached first, on output.
5255 ! On an error return, T is the farthest point reached.
5256 ! TOUT = the next value of t at which a computed solution is desired.
5257 ! Used only for input.
5258 ! When starting the problem (ISTATE = 1), TOUT may be equal
5259 ! to T for one call, then should .ne. T for the next call.
5260 ! For the initial T, an input value of TOUT .ne. T is used
5261 ! in order to determine the direction of the integration
5262 ! (i.e. the algebraic sign of the step sizes) and the rough
5263 ! scale of the problem. Integration in either direction
5264 ! (forward or backward in t) is permitted.
5265 ! If ITASK = 2 or 5 (one-step modes), TOUT is ignored after
5266 ! the first call (i.e. the first call with TOUT .ne. T).
5267 ! Otherwise, TOUT is required on every call.
5268 ! If ITASK = 1, 3, or 4, the values of TOUT need not be
5269 ! monotone, but a value of TOUT which backs up is limited
5270 ! to the current internal T interval, whose endpoints are
5271 ! TCUR - HU and TCUR (see optional outputs, below, for
5272 ! TCUR and HU).
5273 ! ITOL = an indicator for the type of error control. See
5274 ! description below under ATOL. Used only for input.
5275 ! RTOL = a relative error tolerance parameter, either a scalar or
5276 ! an array of length NEQ. See description below under ATOL.
5277 ! Input only.
5278 ! ATOL = an absolute error tolerance parameter, either a scalar or
5279 ! an array of length NEQ. Input only.
5280 ! The input parameters ITOL, RTOL, and ATOL determine
5281 ! the error control performed by the solver. The solver will
5282 ! control the vector E = (E(i)) of estimated local errors
5283 ! in y, according to an inequality of the form
5284 ! max-norm of ( E(i)/EWT(i) ) .le. 1,
5285 ! where EWT = (EWT(i)) is a vector of positive error weights.
5286 ! The values of RTOL and ATOL should all be non-negative.
5287 ! The following table gives the types (scalar/array) of
5288 ! RTOL and ATOL, and the corresponding form of EWT(i).
5289 ! ITOL RTOL ATOL EWT(i)
5290 ! 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
5291 ! 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
5292 ! 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
5293 ! 4 array array RTOL(i)*ABS(Y(i)) + ATOL(i)
5294 ! When either of these parameters is a scalar, it need not
5295 ! be dimensioned in the user's calling program.
5296 ! If none of the above choices (with ITOL, RTOL, and ATOL
5297 ! fixed throughout the problem) is suitable, more general
5298 ! error controls can be obtained by substituting a
5299 ! user-supplied routine for the setting of EWT.
5300 ! See Part 4 below.
5301 ! If global errors are to be estimated by making a repeated
5302 ! run on the same problem with smaller tolerances, then all
5303 ! components of RTOL and ATOL (i.e. of EWT) should be scaled
5304 ! down uniformly.
5305 ! ITASK = an index specifying the task to be performed.
5306 ! input only. ITASK has the following values and meanings.
5307 ! 1 means normal computation of output values of y(t) at
5308 ! t = TOUT (by overshooting and interpolating).
5309 ! 2 means take one step only and return.
5310 ! 3 means stop at the first internal mesh point at or
5311 ! beyond t = TOUT and return.
5312 ! 4 means normal computation of output values of y(t) at
5313 ! t = TOUT but without overshooting t = TCRIT.
5314 ! TCRIT must be input as RWORK(1). TCRIT may be equal to
5315 ! or beyond TOUT, but not behind it in the direction of
5316 ! integration. This option is useful if the problem
5317 ! has a singularity at or beyond t = TCRIT.
5318 ! 5 means take one step, without passing TCRIT, and return.
5319 ! TCRIT must be input as RWORK(1).
5320 ! Note: If ITASK = 4 or 5 and the solver reaches TCRIT
5321 ! (within roundoff), it will return T = TCRIT (exactly) to
5322 ! indicate this (unless ITASK = 4 and TOUT comes before TCRIT,
5323 ! in which case answers at t = TOUT are returned first).
5324 ! ISTATE = an index used for input and output to specify the
5325 ! the state of the calculation.
5326 ! On input, the values of ISTATE are as follows.
5327 ! 1 means this is the first call for the problem
5328 ! (initializations will be done). See note below.
5329 ! 2 means this is not the first call, and the calculation
5330 ! is to continue normally, with no change in any input
5331 ! parameters except possibly TOUT and ITASK.
5332 ! (If ITOL, RTOL, and/or ATOL are changed between calls
5333 ! with ISTATE = 2, the new values will be used but not
5334 ! tested for legality.)
5335 ! 3 means this is not the first call, and the
5336 ! calculation is to continue normally, but with
5337 ! a change in input parameters other than
5338 ! TOUT and ITASK. Changes are allowed in
5339 ! NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, JT, ML, MU,
5340 ! and any optional inputs except H0, MXORDN, and MXORDS.
5341 ! (See IWORK description for ML and MU.)
5342 ! In addition, immediately following a return with
5343 ! ISTATE = 3 (root found), NG and G may be changed.
5344 ! (But changing NG from 0 to .gt. 0 is not allowed.)
5345 ! Note: A preliminary call with TOUT = T is not counted
5346 ! as a first call here, as no initialization or checking of
5347 ! input is done. (Such a call is sometimes useful for the
5348 ! purpose of outputting the initial conditions.)
5349 ! Thus the first call for which TOUT .ne. T requires
5350 ! ISTATE = 1 on input.
5351 ! On output, ISTATE has the following values and meanings.
5352 ! 1 means nothing was done; TOUT = t and ISTATE = 1 on input.
5353 ! 2 means the integration was performed successfully, and
5354 ! no roots were found.
5355 ! 3 means the integration was successful, and one or more
5356 ! roots were found before satisfying the stop condition
5357 ! specified by ITASK. See JROOT.
5358 ! -1 means an excessive amount of work (more than MXSTEP
5359 ! steps) was done on this call, before completing the
5360 ! requested task, but the integration was otherwise
5361 ! successful as far as T. (MXSTEP is an optional input
5362 ! and is normally 500.) To continue, the user may
5363 ! simply reset ISTATE to a value .gt. 1 and call again
5364 ! (the excess work step counter will be reset to 0).
5365 ! In addition, the user may increase MXSTEP to avoid
5366 ! this error return (see below on optional inputs).
5367 ! -2 means too much accuracy was requested for the precision
5368 ! of the machine being used. This was detected before
5369 ! completing the requested task, but the integration
5370 ! was successful as far as T. To continue, the tolerance
5371 ! parameters must be reset, and ISTATE must be set
5372 ! to 3. The optional output TOLSF may be used for this
5373 ! purpose. (Note: If this condition is detected before
5374 ! taking any steps, then an illegal input return
5375 ! (ISTATE = -3) occurs instead.)
5376 ! -3 means illegal input was detected, before taking any
5377 ! integration steps. See written message for details.
5378 ! Note: If the solver detects an infinite loop of calls
5379 ! to the solver with illegal input, it will cause
5380 ! the run to stop.
5381 ! -4 means there were repeated error test failures on
5382 ! one attempted step, before completing the requested
5383 ! task, but the integration was successful as far as T.
5384 ! The problem may have a singularity, or the input
5385 ! may be inappropriate.
5386 ! -5 means there were repeated convergence test failures on
5387 ! one attempted step, before completing the requested
5388 ! task, but the integration was successful as far as T.
5389 ! This may be caused by an inaccurate Jacobian matrix,
5390 ! if one is being used.
5391 ! -6 means EWT(i) became zero for some i during the
5392 ! integration. Pure relative error control (ATOL(i)=0.0)
5393 ! was requested on a variable which has now vanished.
5394 ! The integration was successful as far as T.
5395 ! -7 means the length of RWORK and/or IWORK was too small to
5396 ! proceed, but the integration was successful as far as T.
5397 ! This happens when DLSODAR chooses to switch methods
5398 ! but LRW and/or LIW is too small for the new method.
5399 ! Note: Since the normal output value of ISTATE is 2,
5400 ! it does not need to be reset for normal continuation.
5401 ! Also, since a negative input value of ISTATE will be
5402 ! regarded as illegal, a negative output value requires the
5403 ! user to change it, and possibly other inputs, before
5404 ! calling the solver again.
5405 ! IOPT = an integer flag to specify whether or not any optional
5406 ! inputs are being used on this call. Input only.
5407 ! The optional inputs are listed separately below.
5408 ! IOPT = 0 means no optional inputs are being used.
5409 ! Default values will be used in all cases.
5410 ! IOPT = 1 means one or more optional inputs are being used.
5411 ! RWORK = a real array (double precision) for work space, and (in the
5412 ! first 20 words) for conditional and optional inputs and
5413 ! optional outputs.
5414 ! As DLSODAR switches automatically between stiff and nonstiff
5415 ! methods, the required length of RWORK can change during the
5416 ! problem. Thus the RWORK array passed to DLSODAR can either
5417 ! have a static (fixed) length large enough for both methods,
5418 ! or have a dynamic (changing) length altered by the calling
5419 ! program in response to output from DLSODAR.
5420 ! --- Fixed Length Case ---
5421 ! If the RWORK length is to be fixed, it should be at least
5422 ! max (LRN, LRS),
5423 ! where LRN and LRS are the RWORK lengths required when the
5424 ! current method is nonstiff or stiff, respectively.
5425 ! The separate RWORK length requirements LRN and LRS are
5426 ! as follows:
5427 ! If NEQ is constant and the maximum method orders have
5428 ! their default values, then
5429 ! LRN = 20 + 16*NEQ + 3*NG,
5430 ! LRS = 22 + 9*NEQ + NEQ**2 + 3*NG (JT = 1 or 2),
5431 ! LRS = 22 + 10*NEQ + (2*ML+MU)*NEQ + 3*NG (JT = 4 or 5).
5432 ! Under any other conditions, LRN and LRS are given by:
5433 ! LRN = 20 + NYH*(MXORDN+1) + 3*NEQ + 3*NG,
5434 ! LRS = 20 + NYH*(MXORDS+1) + 3*NEQ + LMAT + 3*NG,
5435 ! where
5436 ! NYH = the initial value of NEQ,
5437 ! MXORDN = 12, unless a smaller value is given as an
5438 ! optional input,
5439 ! MXORDS = 5, unless a smaller value is given as an
5440 ! optional input,
5441 ! LMAT = length of matrix work space:
5442 ! LMAT = NEQ**2 + 2 if JT = 1 or 2,
5443 ! LMAT = (2*ML + MU + 1)*NEQ + 2 if JT = 4 or 5.
5444 ! --- Dynamic Length Case ---
5445 ! If the length of RWORK is to be dynamic, then it should
5446 ! be at least LRN or LRS, as defined above, depending on the
5447 ! current method. Initially, it must be at least LRN (since
5448 ! DLSODAR starts with the nonstiff method). On any return
5449 ! from DLSODAR, the optional output MCUR indicates the current
5450 ! method. If MCUR differs from the value it had on the
5451 ! previous return, or if there has only been one call to
5452 ! DLSODAR and MCUR is now 2, then DLSODAR has switched
5453 ! methods during the last call, and the length of RWORK
5454 ! should be reset (to LRN if MCUR = 1, or to LRS if
5455 ! MCUR = 2). (An increase in the RWORK length is required
5456 ! if DLSODAR returned ISTATE = -7, but not otherwise.)
5457 ! After resetting the length, call DLSODAR with ISTATE = 3
5458 ! to signal that change.
5459 ! LRW = the length of the array RWORK, as declared by the user.
5460 ! (This will be checked by the solver.)
5461 ! IWORK = an integer array for work space.
5462 ! As DLSODAR switches automatically between stiff and nonstiff
5463 ! methods, the required length of IWORK can change during
5464 ! problem, between
5465 ! LIS = 20 + NEQ and LIN = 20,
5466 ! respectively. Thus the IWORK array passed to DLSODAR can
5467 ! either have a fixed length of at least 20 + NEQ, or have a
5468 ! dynamic length of at least LIN or LIS, depending on the
5469 ! current method. The comments on dynamic length under
5470 ! RWORK above apply here. Initially, this length need
5471 ! only be at least LIN = 20.
5472 ! The first few words of IWORK are used for conditional and
5473 ! optional inputs and optional outputs.
5474 ! The following 2 words in IWORK are conditional inputs:
5475 ! IWORK(1) = ML These are the lower and upper
5476 ! IWORK(2) = MU half-bandwidths, respectively, of the
5477 ! banded Jacobian, excluding the main diagonal.
5478 ! The band is defined by the matrix locations
5479 ! (i,j) with i-ML .le. j .le. i+MU. ML and MU
5480 ! must satisfy 0 .le. ML,MU .le. NEQ-1.
5481 ! These are required if JT is 4 or 5, and
5482 ! ignored otherwise. ML and MU may in fact be
5483 ! the band parameters for a matrix to which
5484 ! df/dy is only approximately equal.
5485 ! LIW = the length of the array IWORK, as declared by the user.
5486 ! (This will be checked by the solver.)
5487 ! Note: The base addresses of the work arrays must not be
5488 ! altered between calls to DLSODAR for the same problem.
5489 ! The contents of the work arrays must not be altered
5490 ! between calls, except possibly for the conditional and
5491 ! optional inputs, and except for the last 3*NEQ words of RWORK.
5492 ! The latter space is used for internal scratch space, and so is
5493 ! available for use by the user outside DLSODAR between calls, if
5494 ! desired (but not for use by F, JAC, or G).
5495 ! JAC = the name of the user-supplied routine to compute the
5496 ! Jacobian matrix, df/dy, if JT = 1 or 4. The JAC routine
5497 ! is optional, but if the problem is expected to be stiff much
5498 ! of the time, you are encouraged to supply JAC, for the sake
5499 ! of efficiency. (Alternatively, set JT = 2 or 5 to have
5500 ! DLSODAR compute df/dy internally by difference quotients.)
5501 ! If and when DLSODAR uses df/dy, it treats this NEQ by NEQ
5502 ! matrix either as full (JT = 1 or 2), or as banded (JT =
5503 ! 4 or 5) with half-bandwidths ML and MU (discussed under
5504 ! IWORK above). In either case, if JT = 1 or 4, the JAC
5505 ! routine must compute df/dy as a function of the scalar t
5506 ! and the vector y. It is to have the form
5507 ! SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
5508 ! DOUBLE PRECISION T, Y(*), PD(NROWPD,*)
5509 ! where NEQ, T, Y, ML, MU, and NROWPD are input and the array
5510 ! PD is to be loaded with partial derivatives (elements of
5511 ! the Jacobian matrix) on output. PD must be given a first
5512 ! dimension of NROWPD. T and Y have the same meaning as in
5513 ! Subroutine F.
5514 ! In the full matrix case (JT = 1), ML and MU are
5515 ! ignored, and the Jacobian is to be loaded into PD in
5516 ! columnwise manner, with df(i)/dy(j) loaded into pd(i,j).
5517 ! In the band matrix case (JT = 4), the elements
5518 ! within the band are to be loaded into PD in columnwise
5519 ! manner, with diagonal lines of df/dy loaded into the rows
5520 ! of PD. Thus df(i)/dy(j) is to be loaded into PD(i-j+MU+1,j).
5521 ! ML and MU are the half-bandwidth parameters (see IWORK).
5522 ! The locations in PD in the two triangular areas which
5523 ! correspond to nonexistent matrix elements can be ignored
5524 ! or loaded arbitrarily, as they are overwritten by DLSODAR.
5525 ! JAC need not provide df/dy exactly. A crude
5526 ! approximation (possibly with a smaller bandwidth) will do.
5527 ! In either case, PD is preset to zero by the solver,
5528 ! so that only the nonzero elements need be loaded by JAC.
5529 ! Each call to JAC is preceded by a call to F with the same
5530 ! arguments NEQ, T, and Y. Thus to gain some efficiency,
5531 ! intermediate quantities shared by both calculations may be
5532 ! saved in a user Common block by F and not recomputed by JAC,
5533 ! if desired. Also, JAC may alter the Y array, if desired.
5534 ! JAC must be declared External in the calling program.
5535 ! Subroutine JAC may access user-defined quantities in
5536 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
5537 ! (dimensioned in JAC) and/or Y has length exceeding NEQ(1).
5538 ! See the descriptions of NEQ and Y above.
5539 ! JT = Jacobian type indicator. Used only for input.
5540 ! JT specifies how the Jacobian matrix df/dy will be
5541 ! treated, if and when DLSODAR requires this matrix.
5542 ! JT has the following values and meanings:
5543 ! 1 means a user-supplied full (NEQ by NEQ) Jacobian.
5544 ! 2 means an internally generated (difference quotient) full
5545 ! Jacobian (using NEQ extra calls to F per df/dy value).
5546 ! 4 means a user-supplied banded Jacobian.
5547 ! 5 means an internally generated banded Jacobian (using
5548 ! ML+MU+1 extra calls to F per df/dy evaluation).
5549 ! If JT = 1 or 4, the user must supply a Subroutine JAC
5550 ! (the name is arbitrary) as described above under JAC.
5551 ! If JT = 2 or 5, a dummy argument can be used.
5552 ! G = the name of subroutine for constraint functions, whose
5553 ! roots are desired during the integration. It is to have
5554 ! the form
5555 ! SUBROUTINE G (NEQ, T, Y, NG, GOUT)
5556 ! DOUBLE PRECISION T, Y(*), GOUT(NG)
5557 ! where NEQ, T, Y, and NG are input, and the array GOUT
5558 ! is output. NEQ, T, and Y have the same meaning as in
5559 ! the F routine, and GOUT is an array of length NG.
5560 ! For i = 1,...,NG, this routine is to load into GOUT(i)
5561 ! the value at (T,Y) of the i-th constraint function g(i).
5562 ! DLSODAR will find roots of the g(i) of odd multiplicity
5563 ! (i.e. sign changes) as they occur during the integration.
5564 ! G must be declared External in the calling program.
5565 ! Caution: Because of numerical errors in the functions
5566 ! g(i) due to roundoff and integration error, DLSODAR may
5567 ! return false roots, or return the same root at two or more
5568 ! nearly equal values of t. If such false roots are
5569 ! suspected, the user should consider smaller error tolerances
5570 ! and/or higher precision in the evaluation of the g(i).
5571 ! If a root of some g(i) defines the end of the problem,
5572 ! the input to DLSODAR should nevertheless allow integration
5573 ! to a point slightly past that root, so that DLSODAR can
5574 ! locate the root by interpolation.
5575 ! Subroutine G may access user-defined quantities in
5576 ! NEQ(2),... and Y(NEQ(1)+1),... if NEQ is an array
5577 ! (dimensioned in G) and/or Y has length exceeding NEQ(1).
5578 ! See the descriptions of NEQ and Y above.
5579 ! NG = number of constraint functions g(i). If there are none,
5580 ! set NG = 0, and pass a dummy name for G.
5581 ! JROOT = integer array of length NG. Used only for output.
5582 ! On a return with ISTATE = 3 (one or more roots found),
5583 ! JROOT(i) = 1 if g(i) has a root at T, or JROOT(i) = 0 if not.
5584 !-----------------------------------------------------------------------
5585 ! Optional Inputs.
5586 ! The following is a list of the optional inputs provided for in the
5587 ! call sequence. (See also Part 2.) For each such input variable,
5588 ! this table lists its name as used in this documentation, its
5589 ! location in the call sequence, its meaning, and the default value.
5590 ! The use of any of these inputs requires IOPT = 1, and in that
5591 ! case all of these inputs are examined. A value of zero for any
5592 ! of these optional inputs will cause the default value to be used.
5593 ! Thus to use a subset of the optional inputs, simply preload
5594 ! locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, and
5595 ! then set those of interest to nonzero values.
5596 ! Name Location Meaning and Default Value
5597 ! H0 RWORK(5) the step size to be attempted on the first step.
5598 ! The default value is determined by the solver.
5599 ! HMAX RWORK(6) the maximum absolute step size allowed.
5600 ! The default value is infinite.
5601 ! HMIN RWORK(7) the minimum absolute step size allowed.
5602 ! The default value is 0. (This lower bound is not
5603 ! enforced on the final step before reaching TCRIT
5604 ! when ITASK = 4 or 5.)
5605 ! IXPR IWORK(5) flag to generate extra printing at method switches.
5606 ! IXPR = 0 means no extra printing (the default).
5607 ! IXPR = 1 means print data on each switch.
5608 ! T, H, and NST will be printed on the same logical
5609 ! unit as used for error messages.
5610 ! MXSTEP IWORK(6) maximum number of (internally defined) steps
5611 ! allowed during one call to the solver.
5612 ! The default value is 500.
5613 ! MXHNIL IWORK(7) maximum number of messages printed (per problem)
5614 ! warning that T + H = T on a step (H = step size).
5615 ! This must be positive to result in a non-default
5616 ! value. The default value is 10.
5617 ! MXORDN IWORK(8) the maximum order to be allowed for the nonstiff
5618 ! (Adams) method. The default value is 12.
5619 ! If MXORDN exceeds the default value, it will
5620 ! be reduced to the default value.
5621 ! MXORDN is held constant during the problem.
5622 ! MXORDS IWORK(9) the maximum order to be allowed for the stiff
5623 ! (BDF) method. The default value is 5.
5624 ! If MXORDS exceeds the default value, it will
5625 ! be reduced to the default value.
5626 ! MXORDS is held constant during the problem.
5627 !-----------------------------------------------------------------------
5628 ! Optional Outputs.
5629 ! As optional additional output from DLSODAR, the variables listed
5630 ! below are quantities related to the performance of DLSODAR
5631 ! which are available to the user. These are communicated by way of
5632 ! the work arrays, but also have internal mnemonic names as shown.
5633 ! Except where stated otherwise, all of these outputs are defined
5634 ! on any successful return from DLSODAR, and on any return with
5635 ! ISTATE = -1, -2, -4, -5, or -6. On an illegal input return
5636 ! (ISTATE = -3), they will be unchanged from their existing values
5637 ! (if any), except possibly for TOLSF, LENRW, and LENIW.
5638 ! On any error return, outputs relevant to the error will be defined,
5639 ! as noted below.
5640 ! Name Location Meaning
5641 ! HU RWORK(11) the step size in t last used (successfully).
5642 ! HCUR RWORK(12) the step size to be attempted on the next step.
5643 ! TCUR RWORK(13) the current value of the independent variable
5644 ! which the solver has actually reached, i.e. the
5645 ! current internal mesh point in t. On output, TCUR
5646 ! will always be at least as far as the argument
5647 ! T, but may be farther (if interpolation was done).
5648 ! TOLSF RWORK(14) a tolerance scale factor, greater than 1.0,
5649 ! computed when a request for too much accuracy was
5650 ! detected (ISTATE = -3 if detected at the start of
5651 ! the problem, ISTATE = -2 otherwise). If ITOL is
5652 ! left unaltered but RTOL and ATOL are uniformly
5653 ! scaled up by a factor of TOLSF for the next call,
5654 ! then the solver is deemed likely to succeed.
5655 ! (The user may also ignore TOLSF and alter the
5656 ! tolerance parameters in any other way appropriate.)
5657 ! TSW RWORK(15) the value of t at the time of the last method
5658 ! switch, if any.
5659 ! NGE IWORK(10) the number of g evaluations for the problem so far.
5660 ! NST IWORK(11) the number of steps taken for the problem so far.
5661 ! NFE IWORK(12) the number of f evaluations for the problem so far.
5662 ! NJE IWORK(13) the number of Jacobian evaluations (and of matrix
5663 ! LU decompositions) for the problem so far.
5664 ! NQU IWORK(14) the method order last used (successfully).
5665 ! NQCUR IWORK(15) the order to be attempted on the next step.
5666 ! IMXER IWORK(16) the index of the component of largest magnitude in
5667 ! the weighted local error vector ( E(i)/EWT(i) ),
5668 ! on an error return with ISTATE = -4 or -5.
5669 ! LENRW IWORK(17) the length of RWORK actually required, assuming
5670 ! that the length of RWORK is to be fixed for the
5671 ! rest of the problem, and that switching may occur.
5672 ! This is defined on normal returns and on an illegal
5673 ! input return for insufficient storage.
5674 ! LENIW IWORK(18) the length of IWORK actually required, assuming
5675 ! that the length of IWORK is to be fixed for the
5676 ! rest of the problem, and that switching may occur.
5677 ! This is defined on normal returns and on an illegal
5678 ! input return for insufficient storage.
5679 ! MUSED IWORK(19) the method indicator for the last successful step:
5680 ! 1 means Adams (nonstiff), 2 means BDF (stiff).
5681 ! MCUR IWORK(20) the current method indicator:
5682 ! 1 means Adams (nonstiff), 2 means BDF (stiff).
5683 ! This is the method to be attempted
5684 ! on the next step. Thus it differs from MUSED
5685 ! only if a method switch has just been made.
5686 ! The following two arrays are segments of the RWORK array which
5687 ! may also be of interest to the user as optional outputs.
5688 ! For each array, the table below gives its internal name,
5689 ! its base address in RWORK, and its description.
5690 ! Name Base Address Description
5691 ! YH 21 + 3*NG the Nordsieck history array, of size NYH by
5692 ! (NQCUR + 1), where NYH is the initial value
5693 ! of NEQ. For j = 0,1,...,NQCUR, column j+1
5694 ! of YH contains HCUR**j/factorial(j) times
5695 ! the j-th derivative of the interpolating
5696 ! polynomial currently representing the solution,
5697 ! evaluated at t = TCUR.
5698 ! ACOR LACOR array of size NEQ used for the accumulated
5699 ! (from Common corrections on each step, scaled on output
5700 ! as noted) to represent the estimated local error in y
5701 ! on the last step. This is the vector E in
5702 ! the description of the error control. It is
5703 ! defined only on a successful return from
5704 ! DLSODAR. The base address LACOR is obtained by
5705 ! including in the user's program the
5706 ! following 2 lines:
5707 ! COMMON /DLS001/ RLS(218), ILS(37)
5708 ! LACOR = ILS(22)
5709 !-----------------------------------------------------------------------
5710 ! Part 2. Other Routines Callable.
5711 ! The following are optional calls which the user may make to
5712 ! gain additional capabilities in conjunction with DLSODAR.
5713 ! (The routines XSETUN and XSETF are designed to conform to the
5714 ! SLATEC error handling package.)
5715 ! Form of Call Function
5716 ! CALL XSETUN(LUN) Set the logical unit number, LUN, for
5717 ! output of messages from DLSODAR, if
5718 ! the default is not desired.
5719 ! The default value of LUN is 6.
5720 ! CALL XSETF(MFLAG) Set a flag to control the printing of
5721 ! messages by DLSODAR.
5722 ! MFLAG = 0 means do not print. (Danger:
5723 ! This risks losing valuable information.)
5724 ! MFLAG = 1 means print (the default).
5725 ! Either of the above calls may be made at
5726 ! any time and will take effect immediately.
5727 ! CALL DSRCAR(RSAV,ISAV,JOB) saves and restores the contents of
5728 ! the internal Common blocks used by
5729 ! DLSODAR (see Part 3 below).
5730 ! RSAV must be a real array of length 245
5731 ! or more, and ISAV must be an integer
5732 ! array of length 55 or more.
5733 ! JOB=1 means save Common into RSAV/ISAV.
5734 ! JOB=2 means restore Common from RSAV/ISAV.
5735 ! DSRCAR is useful if one is
5736 ! interrupting a run and restarting
5737 ! later, or alternating between two or
5738 ! more problems solved with DLSODAR.
5739 ! CALL DINTDY(,,,,,) Provide derivatives of y, of various
5740 ! (see below) orders, at a specified point t, if
5741 ! desired. It may be called only after
5742 ! a successful return from DLSODAR.
5743 ! The detailed instructions for using DINTDY are as follows.
5744 ! The form of the call is:
5745 ! LYH = 21 + 3*NG
5746 ! CALL DINTDY (T, K, RWORK(LYH), NYH, DKY, IFLAG)
5747 ! The input parameters are:
5748 ! T = value of independent variable where answers are desired
5749 ! (normally the same as the T last returned by DLSODAR).
5750 ! For valid results, T must lie between TCUR - HU and TCUR.
5751 ! (See optional outputs for TCUR and HU.)
5752 ! K = integer order of the derivative desired. K must satisfy
5753 ! 0 .le. K .le. NQCUR, where NQCUR is the current order
5754 ! (see optional outputs). The capability corresponding
5755 ! to K = 0, i.e. computing y(t), is already provided
5756 ! by DLSODAR directly. Since NQCUR .ge. 1, the first
5757 ! derivative dy/dt is always available with DINTDY.
5758 ! LYH = 21 + 3*NG = base address in RWORK of the history array YH.
5759 ! NYH = column length of YH, equal to the initial value of NEQ.
5760 ! The output parameters are:
5761 ! DKY = a real array of length NEQ containing the computed value
5762 ! of the K-th derivative of y(t).
5763 ! IFLAG = integer flag, returned as 0 if K and T were legal,
5764 ! -1 if K was illegal, and -2 if T was illegal.
5765 ! On an error return, a message is also written.
5766 !-----------------------------------------------------------------------
5767 ! Part 3. Common Blocks.
5768 ! If DLSODAR is to be used in an overlay situation, the user
5769 ! must declare, in the primary overlay, the variables in:
5770 ! (1) the call sequence to DLSODAR, and
5771 ! (2) the three internal Common blocks
5772 ! /DLS001/ of length 255 (218 double precision words
5773 ! followed by 37 integer words),
5774 ! /DLSA01/ of length 31 (22 double precision words
5775 ! followed by 9 integer words).
5776 ! /DLSR01/ of length 7 (3 double precision words
5777 ! followed by 4 integer words).
5778 ! If DLSODAR is used on a system in which the contents of internal
5779 ! Common blocks are not preserved between calls, the user should
5780 ! declare the above Common blocks in the calling program to insure
5781 ! that their contents are preserved.
5782 ! If the solution of a given problem by DLSODAR is to be interrupted
5783 ! and then later continued, such as when restarting an interrupted run
5784 ! or alternating between two or more problems, the user should save,
5785 ! following the return from the last DLSODAR call prior to the
5786 ! interruption, the contents of the call sequence variables and the
5787 ! internal Common blocks, and later restore these values before the
5788 ! next DLSODAR call for that problem. To save and restore the Common
5789 ! blocks, use Subroutine DSRCAR (see Part 2 above).
5790 !-----------------------------------------------------------------------
5791 ! Part 4. Optionally Replaceable Solver Routines.
5792 ! Below is a description of a routine in the DLSODAR package which
5793 ! relates to the measurement of errors, and can be
5794 ! replaced by a user-supplied version, if desired. However, since such
5795 ! a replacement may have a major impact on performance, it should be
5796 ! done only when absolutely necessary, and only with great caution.
5797 ! (Note: The means by which the package version of a routine is
5798 ! superseded by the user's version may be system-dependent.)
5799 ! (a) DEWSET.
5800 ! The following subroutine is called just before each internal
5801 ! integration step, and sets the array of error weights, EWT, as
5802 ! described under ITOL/RTOL/ATOL above:
5803 ! Subroutine DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
5804 ! where NEQ, ITOL, RTOL, and ATOL are as in the DLSODAR call sequence,
5805 ! YCUR contains the current dependent variable vector, and
5806 ! EWT is the array of weights set by DEWSET.
5807 ! If the user supplies this subroutine, it must return in EWT(i)
5808 ! (i = 1,...,NEQ) a positive quantity suitable for comparing errors
5809 ! in y(i) to. The EWT array returned by DEWSET is passed to the
5810 ! DMNORM routine, and also used by DLSODAR in the computation
5811 ! of the optional output IMXER, and the increments for difference
5812 ! quotient Jacobians.
5813 ! In the user-supplied version of DEWSET, it may be desirable to use
5814 ! the current values of derivatives of y. Derivatives up to order NQ
5815 ! are available from the history array YH, described above under
5816 ! optional outputs. In DEWSET, YH is identical to the YCUR array,
5817 ! extended to NQ + 1 columns with a column length of NYH and scale
5818 ! factors of H**j/factorial(j). On the first call for the problem,
5819 ! given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
5820 ! NYH is the initial value of NEQ. The quantities NQ, H, and NST
5821 ! can be obtained by including in DEWSET the statements:
5822 ! DOUBLE PRECISION RLS
5823 ! COMMON /DLS001/ RLS(218),ILS(37)
5824 ! NQ = ILS(33)
5825 ! NST = ILS(34)
5826 ! H = RLS(212)
5827 ! Thus, for example, the current value of dy/dt can be obtained as
5828 ! YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is
5829 ! unnecessary when NST = 0).
5830 !-----------------------------------------------------------------------
5831 !***REVISION HISTORY (YYYYMMDD)
5832 ! 19811102 DATE WRITTEN
5833 ! 19820126 Fixed bug in tests of work space lengths;
5834 ! minor corrections in main prologue and comments.
5835 ! 19820507 Fixed bug in RCHEK in setting HMING.
5836 ! 19870330 Major update: corrected comments throughout;
5837 ! removed TRET from Common; rewrote EWSET with 4 loops;
5838 ! fixed t test in INTDY; added Cray directives in STODA;
5839 ! in STODA, fixed DELP init. and logic around PJAC call;
5840 ! combined routines to save/restore Common;
5841 ! passed LEVEL = 0 in error message calls (except run abort).
5842 ! 19970225 Fixed lines setting JSTART = -2 in Subroutine LSODAR.
5843 ! 20010425 Major update: convert source lines to upper case;
5844 ! added *DECK lines; changed from 1 to * in dummy dimensions;
5845 ! changed names R1MACH/D1MACH to RUMACH/DUMACH;
5846 ! renamed routines for uniqueness across single/double prec.;
5847 ! converted intrinsic names to generic form;
5848 ! removed ILLIN and NTREP (data loaded) from Common;
5849 ! removed all 'own' variables from Common;
5850 ! changed error messages to quoted strings;
5851 ! replaced XERRWV/XERRWD with 1993 revised version;
5852 ! converted prologues, comments, error messages to mixed case;
5853 ! numerous corrections to prologues and internal comments.
5854 ! 20010507 Converted single precision source to double precision.
5855 ! 20010613 Revised excess accuracy test (to match rest of ODEPACK).
5856 ! 20010808 Fixed bug in DPRJA (matrix in DBNORM call).
5857 ! 20020502 Corrected declarations in descriptions of user routines.
5858 ! 20031105 Restored 'own' variables to Common blocks, to enable
5859 ! interrupt/restart feature.
5860 ! 20031112 Added SAVE statements for data-loaded constants.
5861 !-----------------------------------------------------------------------
5862 ! Other routines in the DLSODAR package.
5863 ! In addition to Subroutine DLSODAR, the DLSODAR package includes the
5864 ! following subroutines and function routines:
5865 ! DRCHEK does preliminary checking for roots, and serves as an
5866 ! interface between Subroutine DLSODAR and Subroutine DROOTS.
5867 ! DROOTS finds the leftmost root of a set of functions.
5868 ! DINTDY computes an interpolated value of the y vector at t = TOUT.
5869 ! DSTODA is the core integrator, which does one step of the
5870 ! integration and the associated error control.
5871 ! DCFODE sets all method coefficients and test constants.
5872 ! DPRJA computes and preprocesses the Jacobian matrix J = df/dy
5873 ! and the Newton iteration matrix P = I - h*l0*J.
5874 ! DSOLSY manages solution of linear system in chord iteration.
5875 ! DEWSET sets the error weight vector EWT before each step.
5876 ! DMNORM computes the weighted max-norm of a vector.
5877 ! DFNORM computes the norm of a full matrix consistent with the
5878 ! weighted max-norm on vectors.
5879 ! DBNORM computes the norm of a band matrix consistent with the
5880 ! weighted max-norm on vectors.
5881 ! DSRCAR is a user-callable routine to save and restore
5882 ! the contents of the internal Common blocks.
5883 ! DGEFA and DGESL are routines from LINPACK for solving full
5884 ! systems of linear algebraic equations.
5885 ! DGBFA and DGBSL are routines from LINPACK for solving banded
5886 ! linear systems.
5887 ! DCOPY is one of the basic linear algebra modules (BLAS).
5888 ! DUMACH computes the unit roundoff in a machine-independent manner.
5889 ! XERRWD, XSETUN, XSETF, IXSAV, and IUMACH handle the printing of all
5890 ! error messages and warnings. XERRWD is machine-dependent.
5891 ! Note: DMNORM, DFNORM, DBNORM, DUMACH, IXSAV, and IUMACH are
5892 ! function routines. All the others are subroutines.
5893 !-----------------------------------------------------------------------
5894 ! EXTERNAL DPRJA, DSOLSY
5895 ! DOUBLE PRECISION :: DUMACH, DMNORM
5896 ! INTEGER :: INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS, &
5897 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
5898 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
5899 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
5900 ! INTEGER :: INSUFR, INSUFI, IXPR, IOWNS2, JTYP, MUSED, MXORDN, MXORDS
5901 ! INTEGER :: LG0, LG1, LGX, IOWNR3, IRFND, ITASKC, NGC, NGE
5902 ! INTEGER :: I, I1, I2, IFLAG, IMXER, KGO, LENIW, &
5903 ! LENRW, LENWM, LF0, ML, MORD, MU, MXHNL0, MXSTP0
5904 ! INTEGER :: LEN1, LEN1C, LEN1N, LEN1S, LEN2, LENIWC, LENRWC
5905 ! INTEGER :: IRFP, IRT, LENYH, LYHNEW
5906 ! DOUBLE PRECISION :: ROWNS, &
5907 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
5908 ! DOUBLE PRECISION :: TSW, ROWNS2, PDNORM
5909 ! DOUBLE PRECISION :: ROWNR3, T0, TLAST, TOUTC
5910 ! DOUBLE PRECISION :: ATOLI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RTOLI, &
5911 ! TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0
5912 ! DIMENSION MORD(2)
5913 ! LOGICAL :: IHIT
5914 ! CHARACTER(60) :: MSG
5915 ! SAVE MORD, MXSTP0, MXHNL0
5916 !-----------------------------------------------------------------------
5917 ! The following three internal Common blocks contain
5918 ! (a) variables which are local to any subroutine but whose values must
5919 ! be preserved between calls to the routine ("own" variables), and
5920 ! (b) variables which are communicated between subroutines.
5921 ! The block DLS001 is declared in subroutines DLSODAR, DINTDY, DSTODA,
5922 ! DPRJA, and DSOLSY.
5923 ! The block DLSA01 is declared in subroutines DLSODAR, DSTODA, DPRJA.
5924 ! The block DLSR01 is declared in subroutines DLSODAR, DRCHEK, DROOTS.
5925 ! Groups of variables are replaced by dummy arrays in the Common
5926 ! declarations in routines where those variables are not used.
5927 !-----------------------------------------------------------------------
5928 ! COMMON /DLS001/ ROWNS(209), &
5929 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
5930 ! INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6), &
5931 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
5932 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
5933 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
5934 ! COMMON /DLSA01/ TSW, ROWNS2(20), PDNORM, &
5935 ! INSUFR, INSUFI, IXPR, IOWNS2(2), JTYP, MUSED, MXORDN, MXORDS
5936 ! COMMON /DLSR01/ ROWNR3(2), T0, TLAST, TOUTC, &
5937 ! LG0, LG1, LGX, IOWNR3(2), IRFND, ITASKC, NGC, NGE
5938 ! DATA MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
5939 !-----------------------------------------------------------------------
5940 ! Block A.
5941 ! This code block is executed on every call.
5942 ! It tests ISTATE and ITASK for legality and branches appropriately.
5943 ! If ISTATE .gt. 1 but the flag INIT shows that initialization has
5944 ! not yet been done, an error return occurs.
5945 ! If ISTATE = 1 and TOUT = T, return immediately.
5946 !-----------------------------------------------------------------------
5947 ! IF (ISTATE < 1 .OR. ISTATE > 3) GO TO 601
5948 ! IF (ITASK < 1 .OR. ITASK > 5) GO TO 602
5949 ! ITASKC = ITASK
5950 ! IF (ISTATE == 1) GO TO 10
5951 ! IF (INIT == 0) GO TO 603
5952 ! IF (ISTATE == 2) GO TO 200
5953 ! GO TO 20
5954 ! 10 INIT = 0
5955 ! IF (TOUT == T) RETURN
5956 !-----------------------------------------------------------------------
5957 ! Block B.
5958 ! The next code block is executed for the initial call (ISTATE = 1),
5959 ! or for a continuation call with parameter changes (ISTATE = 3).
5960 ! It contains checking of all inputs and various initializations.
5961 ! First check legality of the non-optional inputs NEQ, ITOL, IOPT,
5962 ! JT, ML, MU, and NG.
5963 !-----------------------------------------------------------------------
5964 ! 20 IF (NEQ(1) <= 0) GO TO 604
5965 ! IF (ISTATE == 1) GO TO 25
5966 ! IF (NEQ(1) > N) GO TO 605
5967 ! 25 N = NEQ(1)
5968 ! IF (ITOL < 1 .OR. ITOL > 4) GO TO 606
5969 ! IF (IOPT < 0 .OR. IOPT > 1) GO TO 607
5970 ! IF (JT == 3 .OR. JT < 1 .OR. JT > 5) GO TO 608
5971 ! JTYP = JT
5972 ! IF (JT <= 2) GO TO 30
5973 ! ML = IWORK(1)
5974 ! MU = IWORK(2)
5975 ! IF (ML < 0 .OR. ML >= N) GO TO 609
5976 ! IF (MU < 0 .OR. MU >= N) GO TO 610
5977 ! 30 CONTINUE
5978 ! IF (NG < 0) GO TO 630
5979 ! IF (ISTATE == 1) GO TO 35
5980 ! IF (IRFND == 0 .AND. NG /= NGC) GO TO 631
5981 ! 35 NGC = NG
5982 ! Next process and check the optional inputs. --------------------------
5983 ! IF (IOPT == 1) GO TO 40
5984 ! IXPR = 0
5985 ! MXSTEP = MXSTP0
5986 ! MXHNIL = MXHNL0
5987 ! HMXI = 0.0D0
5988 ! HMIN = 0.0D0
5989 ! IF (ISTATE /= 1) GO TO 60
5990 ! H0 = 0.0D0
5991 ! MXORDN = MORD(1)
5992 ! MXORDS = MORD(2)
5993 ! GO TO 60
5994 ! 40 IXPR = IWORK(5)
5995 ! IF (IXPR < 0 .OR. IXPR > 1) GO TO 611
5996 ! MXSTEP = IWORK(6)
5997 ! IF (MXSTEP < 0) GO TO 612
5998 ! IF (MXSTEP == 0) MXSTEP = MXSTP0
5999 ! MXHNIL = IWORK(7)
6000 ! IF (MXHNIL < 0) GO TO 613
6001 ! IF (MXHNIL == 0) MXHNIL = MXHNL0
6002 ! IF (ISTATE /= 1) GO TO 50
6003 ! H0 = RWORK(5)
6004 ! MXORDN = IWORK(8)
6005 ! IF (MXORDN < 0) GO TO 628
6006 ! IF (MXORDN == 0) MXORDN = 100
6007 ! MXORDN = MIN(MXORDN,MORD(1))
6008 ! MXORDS = IWORK(9)
6009 ! IF (MXORDS < 0) GO TO 629
6010 ! IF (MXORDS == 0) MXORDS = 100
6011 ! MXORDS = MIN(MXORDS,MORD(2))
6012 ! IF ((TOUT - T)*H0 < 0.0D0) GO TO 614
6013 ! 50 HMAX = RWORK(6)
6014 ! IF (HMAX < 0.0D0) GO TO 615
6015 ! HMXI = 0.0D0
6016 ! IF (HMAX > 0.0D0) HMXI = 1.0D0/HMAX
6017 ! HMIN = RWORK(7)
6018 ! IF (HMIN < 0.0D0) GO TO 616
6019 !-----------------------------------------------------------------------
6020 ! Set work array pointers and check lengths LRW and LIW.
6021 ! If ISTATE = 1, METH is initialized to 1 here to facilitate the
6022 ! checking of work space lengths.
6023 ! Pointers to segments of RWORK and IWORK are named by prefixing L to
6024 ! the name of the segment. E.g., the segment YH starts at RWORK(LYH).
6025 ! Segments of RWORK (in order) are denoted G0, G1, GX, YH, WM,
6026 ! EWT, SAVF, ACOR.
6027 ! If the lengths provided are insufficient for the current method,
6028 ! an error return occurs. This is treated as illegal input on the
6029 ! first call, but as a problem interruption with ISTATE = -7 on a
6030 ! continuation call. If the lengths are sufficient for the current
6031 ! method but not for both methods, a warning message is sent.
6032 !-----------------------------------------------------------------------
6033 ! 60 IF (ISTATE == 1) METH = 1
6034 ! IF (ISTATE == 1) NYH = N
6035 ! LG0 = 21
6036 ! LG1 = LG0 + NG
6037 ! LGX = LG1 + NG
6038 ! LYHNEW = LGX + NG
6039 ! IF (ISTATE == 1) LYH = LYHNEW
6040 ! IF (LYHNEW == LYH) GO TO 62
6041 ! If ISTATE = 3 and NG was changed, shift YH to its new location. ------
6042 ! LENYH = L*NYH
6043 ! IF (LRW < LYHNEW-1+LENYH) GO TO 62
6044 ! I1 = 1
6045 ! IF (LYHNEW > LYH) I1 = -1
6046 ! CALL DCOPY (LENYH, RWORK(LYH), I1, RWORK(LYHNEW), I1)
6047 ! LYH = LYHNEW
6048 ! 62 CONTINUE
6049 ! LEN1N = LYHNEW - 1 + (MXORDN + 1)*NYH
6050 ! LEN1S = LYHNEW - 1 + (MXORDS + 1)*NYH
6051 ! LWM = LEN1S + 1
6052 ! IF (JT <= 2) LENWM = N*N + 2
6053 ! IF (JT >= 4) LENWM = (2*ML + MU + 1)*N + 2
6054 ! LEN1S = LEN1S + LENWM
6055 ! LEN1C = LEN1N
6056 ! IF (METH == 2) LEN1C = LEN1S
6057 ! LEN1 = MAX(LEN1N,LEN1S)
6058 ! LEN2 = 3*N
6059 ! LENRW = LEN1 + LEN2
6060 ! LENRWC = LEN1C + LEN2
6061 ! IWORK(17) = LENRW
6062 ! LIWM = 1
6063 ! LENIW = 20 + N
6064 ! LENIWC = 20
6065 ! IF (METH == 2) LENIWC = LENIW
6066 ! IWORK(18) = LENIW
6067 ! IF (ISTATE == 1 .AND. LRW < LENRWC) GO TO 617
6068 ! IF (ISTATE == 1 .AND. LIW < LENIWC) GO TO 618
6069 ! IF (ISTATE == 3 .AND. LRW < LENRWC) GO TO 550
6070 ! IF (ISTATE == 3 .AND. LIW < LENIWC) GO TO 555
6071 ! LEWT = LEN1 + 1
6072 ! INSUFR = 0
6073 ! IF (LRW >= LENRW) GO TO 65
6074 ! INSUFR = 2
6075 ! LEWT = LEN1C + 1
6076 ! MSG='DLSODAR- Warning.. RWORK length is sufficient for now, but '
6077 ! CALL XERRWD (MSG, 60, 103, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6078 ! MSG=' may not be later. Integration will proceed anyway. '
6079 ! CALL XERRWD (MSG, 60, 103, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6080 ! MSG = ' Length needed is LENRW = I1, while LRW = I2.'
6081 ! CALL XERRWD (MSG, 50, 103, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
6082 ! 65 LSAVF = LEWT + N
6083 ! LACOR = LSAVF + N
6084 ! INSUFI = 0
6085 ! IF (LIW >= LENIW) GO TO 70
6086 ! INSUFI = 2
6087 ! MSG='DLSODAR- Warning.. IWORK length is sufficient for now, but '
6088 ! CALL XERRWD (MSG, 60, 104, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6089 ! MSG=' may not be later. Integration will proceed anyway. '
6090 ! CALL XERRWD (MSG, 60, 104, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6091 ! MSG = ' Length needed is LENIW = I1, while LIW = I2.'
6092 ! CALL XERRWD (MSG, 50, 104, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
6093 ! 70 CONTINUE
6094 ! Check RTOL and ATOL for legality. ------------------------------------
6095 ! RTOLI = RTOL(1)
6096 ! ATOLI = ATOL(1)
6097 ! DO 75 I = 1,N
6098 ! IF (ITOL >= 3) RTOLI = RTOL(I)
6099 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
6100 ! IF (RTOLI < 0.0D0) GO TO 619
6101 ! IF (ATOLI < 0.0D0) GO TO 620
6102 ! 75 END DO
6103 ! IF (ISTATE == 1) GO TO 100
6104 ! if ISTATE = 3, set flag to signal parameter changes to DSTODA. -------
6105 ! JSTART = -1
6106 ! IF (N == NYH) GO TO 200
6107 ! NEQ was reduced. zero part of yh to avoid undefined references. -----
6108 ! I1 = LYH + L*NYH
6109 ! I2 = LYH + (MAXORD + 1)*NYH - 1
6110 ! IF (I1 > I2) GO TO 200
6111 ! DO 95 I = I1,I2
6112 ! RWORK(I) = 0.0D0
6113 ! 95 END DO
6114 ! GO TO 200
6115 !-----------------------------------------------------------------------
6116 ! Block C.
6117 ! The next block is for the initial call only (ISTATE = 1).
6118 ! It contains all remaining initializations, the initial call to F,
6119 ! and the calculation of the initial step size.
6120 ! The error weights in EWT are inverted after being loaded.
6121 !-----------------------------------------------------------------------
6122 ! 100 UROUND = DUMACH()
6123 ! TN = T
6124 ! TSW = T
6125 ! MAXORD = MXORDN
6126 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 110
6127 ! TCRIT = RWORK(1)
6128 ! IF ((TCRIT - TOUT)*(TOUT - T) < 0.0D0) GO TO 625
6129 ! IF (H0 /= 0.0D0 .AND. (T + H0 - TCRIT)*H0 > 0.0D0) &
6130 ! H0 = TCRIT - T
6131 ! 110 JSTART = 0
6132 ! NHNIL = 0
6133 ! NST = 0
6134 ! NJE = 0
6135 ! NSLAST = 0
6136 ! HU = 0.0D0
6137 ! NQU = 0
6138 ! MUSED = 0
6139 ! MITER = 0
6140 ! CCMAX = 0.3D0
6141 ! MAXCOR = 3
6142 ! MSBP = 20
6143 ! MXNCF = 10
6144 ! Initial call to F. (LF0 points to YH(*,2).) -------------------------
6145 ! LF0 = LYH + NYH
6146 ! CALL F (NEQ, T, Y, RWORK(LF0))
6147 ! NFE = 1
6148 ! Load the initial value vector in YH. ---------------------------------
6149 ! DO 115 I = 1,N
6150 ! RWORK(I+LYH-1) = Y(I)
6151 ! 115 END DO
6152 ! Load and invert the EWT array. (H is temporarily set to 1.0.) -------
6153 ! NQ = 1
6154 ! H = 1.0D0
6155 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
6156 ! DO 120 I = 1,N
6157 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
6158 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
6159 ! 120 END DO
6160 !-----------------------------------------------------------------------
6161 ! The coding below computes the step size, H0, to be attempted on the
6162 ! first step, unless the user has supplied a value for this.
6163 ! First check that TOUT - T differs significantly from zero.
6164 ! A scalar tolerance quantity TOL is computed, as MAX(RTOL(i))
6165 ! if this is positive, or MAX(ATOL(i)/ABS(Y(i))) otherwise, adjusted
6166 ! so as to be between 100*UROUND and 1.0E-3.
6167 ! Then the computed value H0 is given by:
6168 ! H0**(-2) = 1./(TOL * w0**2) + TOL * (norm(F))**2
6169 ! where w0 = MAX ( ABS(T), ABS(TOUT) ),
6170 ! F = the initial value of the vector f(t,y), and
6171 ! norm() = the weighted vector norm used throughout, given by
6172 ! the DMNORM function routine, and weighted by the
6173 ! tolerances initially loaded into the EWT array.
6174 ! The sign of H0 is inferred from the initial values of TOUT and T.
6175 ! ABS(H0) is made .le. ABS(TOUT-T) in any case.
6176 !-----------------------------------------------------------------------
6177 ! IF (H0 /= 0.0D0) GO TO 180
6178 ! TDIST = ABS(TOUT - T)
6179 ! W0 = MAX(ABS(T),ABS(TOUT))
6180 ! IF (TDIST < 2.0D0*UROUND*W0) GO TO 622
6181 ! TOL = RTOL(1)
6182 ! IF (ITOL <= 2) GO TO 140
6183 ! DO 130 I = 1,N
6184 ! TOL = MAX(TOL,RTOL(I))
6185 ! 130 END DO
6186 ! 140 IF (TOL > 0.0D0) GO TO 160
6187 ! ATOLI = ATOL(1)
6188 ! DO 150 I = 1,N
6189 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
6190 ! AYI = ABS(Y(I))
6191 ! IF (AYI /= 0.0D0) TOL = MAX(TOL,ATOLI/AYI)
6192 ! 150 END DO
6193 ! 160 TOL = MAX(TOL,100.0D0*UROUND)
6194 ! TOL = MIN(TOL,0.001D0)
6195 ! SUM = DMNORM (N, RWORK(LF0), RWORK(LEWT))
6196 ! SUM = 1.0D0/(TOL*W0*W0) + TOL*SUM**2
6197 ! H0 = 1.0D0/SQRT(SUM)
6198 ! H0 = MIN(H0,TDIST)
6199 ! H0 = SIGN(H0,TOUT-T)
6200 ! Adjust H0 if necessary to meet HMAX bound. ---------------------------
6201 ! 180 RH = ABS(H0)*HMXI
6202 ! IF (RH > 1.0D0) H0 = H0/RH
6203 ! Load H with H0 and scale YH(*,2) by H0. ------------------------------
6204 ! H = H0
6205 ! DO 190 I = 1,N
6206 ! RWORK(I+LF0-1) = H0*RWORK(I+LF0-1)
6207 ! 190 END DO
6208 ! Check for a zero of g at T. ------------------------------------------
6209 ! IRFND = 0
6210 ! TOUTC = TOUT
6211 ! IF (NGC == 0) GO TO 270
6212 ! CALL DRCHEK (1, G, NEQ, Y, RWORK(LYH), NYH, &
6213 ! RWORK(LG0), RWORK(LG1), RWORK(LGX), JROOT, IRT)
6214 ! IF (IRT == 0) GO TO 270
6215 ! GO TO 632
6216 !-----------------------------------------------------------------------
6217 ! Block D.
6218 ! The next code block is for continuation calls only (ISTATE = 2 or 3)
6219 ! and is to check stop conditions before taking a step.
6220 ! First, DRCHEK is called to check for a root within the last step
6221 ! taken, other than the last root found there, if any.
6222 ! If ITASK = 2 or 5, and y(TN) has not yet been returned to the user
6223 ! because of an intervening root, return through Block G.
6224 !-----------------------------------------------------------------------
6225 ! 200 NSLAST = NST
6226 ! IRFP = IRFND
6227 ! IF (NGC == 0) GO TO 205
6228 ! IF (ITASK == 1 .OR. ITASK == 4) TOUTC = TOUT
6229 ! CALL DRCHEK (2, G, NEQ, Y, RWORK(LYH), NYH, &
6230 ! RWORK(LG0), RWORK(LG1), RWORK(LGX), JROOT, IRT)
6231 ! IF (IRT /= 1) GO TO 205
6232 ! IRFND = 1
6233 ! ISTATE = 3
6234 ! T = T0
6235 ! GO TO 425
6236 ! 205 CONTINUE
6237 ! IRFND = 0
6238 ! IF (IRFP == 1 .AND. TLAST /= TN .AND. ITASK == 2) GO TO 400
6239 ! GO TO (210, 250, 220, 230, 240), ITASK
6240 ! 210 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
6241 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
6242 ! IF (IFLAG /= 0) GO TO 627
6243 ! T = TOUT
6244 ! GO TO 420
6245 ! 220 TP = TN - HU*(1.0D0 + 100.0D0*UROUND)
6246 ! IF ((TP - TOUT)*H > 0.0D0) GO TO 623
6247 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 250
6248 ! T = TN
6249 ! GO TO 400
6250 ! 230 TCRIT = RWORK(1)
6251 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
6252 ! IF ((TCRIT - TOUT)*H < 0.0D0) GO TO 625
6253 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 245
6254 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
6255 ! IF (IFLAG /= 0) GO TO 627
6256 ! T = TOUT
6257 ! GO TO 420
6258 ! 240 TCRIT = RWORK(1)
6259 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
6260 ! 245 HMX = ABS(TN) + ABS(H)
6261 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
6262 ! IF (IHIT) T = TCRIT
6263 ! IF (IRFP == 1 .AND. TLAST /= TN .AND. ITASK == 5) GO TO 400
6264 ! IF (IHIT) GO TO 400
6265 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
6266 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
6267 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
6268 ! IF (ISTATE == 2 .AND. JSTART >= 0) JSTART = -2
6269 !-----------------------------------------------------------------------
6270 ! Block E.
6271 ! The next block is normally executed for all calls and contains
6272 ! the call to the one-step core integrator DSTODA.
6273 ! This is a looping point for the integration steps.
6274 ! First check for too many steps being taken, update EWT (if not at
6275 ! start of problem), check for too much accuracy being requested, and
6276 ! check for H below the roundoff level in T.
6277 !-----------------------------------------------------------------------
6278 ! 250 CONTINUE
6279 ! IF (METH == MUSED) GO TO 255
6280 ! IF (INSUFR == 1) GO TO 550
6281 ! IF (INSUFI == 1) GO TO 555
6282 ! 255 IF ((NST-NSLAST) >= MXSTEP) GO TO 500
6283 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
6284 ! DO 260 I = 1,N
6285 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 510
6286 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
6287 ! 260 END DO
6288 ! 270 TOLSF = UROUND*DMNORM (N, RWORK(LYH), RWORK(LEWT))
6289 ! IF (TOLSF <= 1.0D0) GO TO 280
6290 ! TOLSF = TOLSF*2.0D0
6291 ! IF (NST == 0) GO TO 626
6292 ! GO TO 520
6293 ! 280 IF ((TN + H) /= TN) GO TO 290
6294 ! NHNIL = NHNIL + 1
6295 ! IF (NHNIL > MXHNIL) GO TO 290
6296 ! MSG = 'DLSODAR- Warning..Internal T(=R1) and H(=R2) are '
6297 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6298 ! MSG=' such that in the machine, T + H = T on the next step '
6299 ! CALL XERRWD (MSG, 60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6300 ! MSG = ' (H = step size). Solver will continue anyway.'
6301 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 2, TN, H)
6302 ! IF (NHNIL < MXHNIL) GO TO 290
6303 ! MSG = 'DLSODAR- Above warning has been issued I1 times. '
6304 ! CALL XERRWD (MSG, 50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6305 ! MSG = ' It will not be issued again for this problem.'
6306 ! CALL XERRWD (MSG, 50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
6307 ! 290 CONTINUE
6308 !-----------------------------------------------------------------------
6309 ! CALL DSTODA(NEQ,Y,YH,NYH,YH,EWT,SAVF,ACOR,WM,IWM,F,JAC,DPRJA,DSOLSY)
6310 !-----------------------------------------------------------------------
6311 ! CALL DSTODA (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT), &
6312 ! RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), IWORK(LIWM), &
6313 ! F, JAC, DPRJA, DSOLSY)
6314 ! KGO = 1 - KFLAG
6315 ! GO TO (300, 530, 540), KGO
6316 !-----------------------------------------------------------------------
6317 ! Block F.
6318 ! The following block handles the case of a successful return from the
6319 ! core integrator (KFLAG = 0).
6320 ! If a method switch was just made, record TSW, reset MAXORD,
6321 ! set JSTART to -1 to signal DSTODA to complete the switch,
6322 ! and do extra printing of data if IXPR = 1.
6323 ! Then call DRCHEK to check for a root within the last step.
6324 ! Then, if no root was found, check for stop conditions.
6325 !-----------------------------------------------------------------------
6326 ! 300 INIT = 1
6327 ! IF (METH == MUSED) GO TO 310
6328 ! TSW = TN
6329 ! MAXORD = MXORDN
6330 ! IF (METH == 2) MAXORD = MXORDS
6331 ! IF (METH == 2) RWORK(LWM) = SQRT(UROUND)
6332 ! INSUFR = MIN(INSUFR,1)
6333 ! INSUFI = MIN(INSUFI,1)
6334 ! JSTART = -1
6335 ! IF (IXPR == 0) GO TO 310
6336 ! IF (METH == 2) THEN
6337 ! MSG='DLSODAR- A switch to the BDF (stiff) method has occurred '
6338 ! CALL XERRWD (MSG, 60, 105, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6339 ! ENDIF
6340 ! IF (METH == 1) THEN
6341 ! MSG='DLSODAR- A switch to the Adams (nonstiff) method occurred '
6342 ! CALL XERRWD (MSG, 60, 106, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6343 ! ENDIF
6344 ! MSG=' at T = R1, tentative step size H = R2, step NST = I1 '
6345 ! CALL XERRWD (MSG, 60, 107, 0, 1, NST, 0, 2, TN, H)
6346 ! 310 CONTINUE
6347 ! IF (NGC == 0) GO TO 315
6348 ! CALL DRCHEK (3, G, NEQ, Y, RWORK(LYH), NYH, &
6349 ! RWORK(LG0), RWORK(LG1), RWORK(LGX), JROOT, IRT)
6350 ! IF (IRT /= 1) GO TO 315
6351 ! IRFND = 1
6352 ! ISTATE = 3
6353 ! T = T0
6354 ! GO TO 425
6355 ! 315 CONTINUE
6356 ! GO TO (320, 400, 330, 340, 350), ITASK
6357 ! ITASK = 1. If TOUT has been reached, interpolate. -------------------
6358 ! 320 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
6359 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
6360 ! T = TOUT
6361 ! GO TO 420
6362 ! ITASK = 3. Jump to exit if TOUT was reached. ------------------------
6363 ! 330 IF ((TN - TOUT)*H >= 0.0D0) GO TO 400
6364 ! GO TO 250
6365 ! ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary.
6366 ! 340 IF ((TN - TOUT)*H < 0.0D0) GO TO 345
6367 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
6368 ! T = TOUT
6369 ! GO TO 420
6370 ! 345 HMX = ABS(TN) + ABS(H)
6371 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
6372 ! IF (IHIT) GO TO 400
6373 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
6374 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
6375 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
6376 ! IF (JSTART >= 0) JSTART = -2
6377 ! GO TO 250
6378 ! ITASK = 5. See if TCRIT was reached and jump to exit. ---------------
6379 ! 350 HMX = ABS(TN) + ABS(H)
6380 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
6381 !-----------------------------------------------------------------------
6382 ! Block G.
6383 ! The following block handles all successful returns from DLSODAR.
6384 ! If ITASK .ne. 1, Y is loaded from YH and T is set accordingly.
6385 ! ISTATE is set to 2, and the optional outputs are loaded into the
6386 ! work arrays before returning.
6387 !-----------------------------------------------------------------------
6388 ! 400 DO 410 I = 1,N
6389 ! Y(I) = RWORK(I+LYH-1)
6390 ! 410 END DO
6391 ! T = TN
6392 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 420
6393 ! IF (IHIT) T = TCRIT
6394 ! 420 ISTATE = 2
6395 ! 425 CONTINUE
6396 ! RWORK(11) = HU
6397 ! RWORK(12) = H
6398 ! RWORK(13) = TN
6399 ! RWORK(15) = TSW
6400 ! IWORK(11) = NST
6401 ! IWORK(12) = NFE
6402 ! IWORK(13) = NJE
6403 ! IWORK(14) = NQU
6404 ! IWORK(15) = NQ
6405 ! IWORK(19) = MUSED
6406 ! IWORK(20) = METH
6407 ! IWORK(10) = NGE
6408 ! TLAST = T
6409 ! RETURN
6410 !-----------------------------------------------------------------------
6411 ! Block H.
6412 ! The following block handles all unsuccessful returns other than
6413 ! those for illegal input. First the error message routine is called.
6414 ! If there was an error test or convergence test failure, IMXER is set.
6415 ! Then Y is loaded from YH and T is set to TN.
6416 ! The optional outputs are loaded into the work arrays before returning.
6417 !-----------------------------------------------------------------------
6418 ! The maximum number of steps was taken before reaching TOUT. ----------
6419 ! 500 MSG = 'DLSODAR- At current T (=R1), MXSTEP (=I1) steps '
6420 ! CALL XERRWD (MSG, 50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6421 ! MSG = ' taken on this call before reaching TOUT '
6422 ! CALL XERRWD (MSG, 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0)
6423 ! ISTATE = -1
6424 ! GO TO 580
6425 ! EWT(i) .le. 0.0 for some i (not at start of problem). ----------------
6426 ! 510 EWTI = RWORK(LEWT+I-1)
6427 ! MSG = 'DLSODAR- At T(=R1), EWT(I1) has become R2 <= 0.'
6428 ! CALL XERRWD (MSG, 50, 202, 0, 1, I, 0, 2, TN, EWTI)
6429 ! ISTATE = -6
6430 ! GO TO 580
6431 ! Too much accuracy requested for machine precision. -------------------
6432 ! 520 MSG = 'DLSODAR- At T (=R1), too much accuracy requested '
6433 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6434 ! MSG = ' for precision of machine.. See TOLSF (=R2) '
6435 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
6436 ! RWORK(14) = TOLSF
6437 ! ISTATE = -2
6438 ! GO TO 580
6439 ! KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
6440 ! 530 MSG = 'DLSODAR- At T(=R1), step size H(=R2), the error '
6441 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6442 ! MSG = ' test failed repeatedly or with ABS(H) = HMIN'
6443 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 2, TN, H)
6444 ! ISTATE = -4
6445 ! GO TO 560
6446 ! KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
6447 ! 540 MSG = 'DLSODAR- At T (=R1) and step size H (=R2), the '
6448 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6449 ! MSG = ' corrector convergence failed repeatedly '
6450 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6451 ! MSG = ' or with ABS(H) = HMIN '
6452 ! CALL XERRWD (MSG, 30, 205, 0, 0, 0, 0, 2, TN, H)
6453 ! ISTATE = -5
6454 ! GO TO 560
6455 ! RWORK length too small to proceed. -----------------------------------
6456 ! 550 MSG = 'DLSODAR- At current T(=R1), RWORK length too small'
6457 ! CALL XERRWD (MSG, 50, 206, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6458 ! MSG=' to proceed. The integration was otherwise successful.'
6459 ! CALL XERRWD (MSG, 60, 206, 0, 0, 0, 0, 1, TN, 0.0D0)
6460 ! ISTATE = -7
6461 ! GO TO 580
6462 ! IWORK length too small to proceed. -----------------------------------
6463 ! 555 MSG = 'DLSODAR- At current T(=R1), IWORK length too small'
6464 ! CALL XERRWD (MSG, 50, 207, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6465 ! MSG=' to proceed. The integration was otherwise successful.'
6466 ! CALL XERRWD (MSG, 60, 207, 0, 0, 0, 0, 1, TN, 0.0D0)
6467 ! ISTATE = -7
6468 ! GO TO 580
6469 ! Compute IMXER if relevant. -------------------------------------------
6470 ! 560 BIG = 0.0D0
6471 ! IMXER = 1
6472 ! DO 570 I = 1,N
6473 ! SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
6474 ! IF (BIG >= SIZE) GO TO 570
6475 ! BIG = SIZE
6476 ! IMXER = I
6477 ! 570 END DO
6478 ! IWORK(16) = IMXER
6479 ! Set Y vector, T, and optional outputs. -------------------------------
6480 ! 580 DO 590 I = 1,N
6481 ! Y(I) = RWORK(I+LYH-1)
6482 ! 590 END DO
6483 ! T = TN
6484 ! RWORK(11) = HU
6485 ! RWORK(12) = H
6486 ! RWORK(13) = TN
6487 ! RWORK(15) = TSW
6488 ! IWORK(11) = NST
6489 ! IWORK(12) = NFE
6490 ! IWORK(13) = NJE
6491 ! IWORK(14) = NQU
6492 ! IWORK(15) = NQ
6493 ! IWORK(19) = MUSED
6494 ! IWORK(20) = METH
6495 ! IWORK(10) = NGE
6496 ! TLAST = T
6497 ! RETURN
6498 !-----------------------------------------------------------------------
6499 ! Block I.
6500 ! The following block handles all error returns due to illegal input
6501 ! (ISTATE = -3), as detected before calling the core integrator.
6502 ! First the error message routine is called. If the illegal input
6503 ! is a negative ISTATE, the run is aborted (apparent infinite loop).
6504 !-----------------------------------------------------------------------
6505 ! 601 MSG = 'DLSODAR- ISTATE(=I1) illegal.'
6506 ! CALL XERRWD (MSG, 30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0)
6507 ! IF (ISTATE < 0) GO TO 800
6508 ! GO TO 700
6509 ! 602 MSG = 'DLSODAR- ITASK (=I1) illegal.'
6510 ! CALL XERRWD (MSG, 30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0)
6511 ! GO TO 700
6512 ! 603 MSG = 'DLSODAR- ISTATE > 1 but DLSODAR not initialized.'
6513 ! CALL XERRWD (MSG, 50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6514 ! GO TO 700
6515 ! 604 MSG = 'DLSODAR- NEQ (=I1) < 1 '
6516 ! CALL XERRWD (MSG, 30, 4, 0, 1, NEQ(1), 0, 0, 0.0D0, 0.0D0)
6517 ! GO TO 700
6518 ! 605 MSG = 'DLSODAR- ISTATE = 3 and NEQ increased (I1 to I2).'
6519 ! CALL XERRWD (MSG, 50, 5, 0, 2, N, NEQ(1), 0, 0.0D0, 0.0D0)
6520 ! GO TO 700
6521 ! 606 MSG = 'DLSODAR- ITOL (=I1) illegal. '
6522 ! CALL XERRWD (MSG, 30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0)
6523 ! GO TO 700
6524 ! 607 MSG = 'DLSODAR- IOPT (=I1) illegal. '
6525 ! CALL XERRWD (MSG, 30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0)
6526 ! GO TO 700
6527 ! 608 MSG = 'DLSODAR- JT (=I1) illegal. '
6528 ! CALL XERRWD (MSG, 30, 8, 0, 1, JT, 0, 0, 0.0D0, 0.0D0)
6529 ! GO TO 700
6530 ! 609 MSG = 'DLSODAR- ML (=I1) illegal: < 0 or >= NEQ (=I2)'
6531 ! CALL XERRWD (MSG, 50, 9, 0, 2, ML, NEQ(1), 0, 0.0D0, 0.0D0)
6532 ! GO TO 700
6533 ! 610 MSG = 'DLSODAR- MU (=I1) illegal: < 0 or >= NEQ (=I2)'
6534 ! CALL XERRWD (MSG, 50, 10, 0, 2, MU, NEQ(1), 0, 0.0D0, 0.0D0)
6535 ! GO TO 700
6536 ! 611 MSG = 'DLSODAR- IXPR (=I1) illegal. '
6537 ! CALL XERRWD (MSG, 30, 11, 0, 1, IXPR, 0, 0, 0.0D0, 0.0D0)
6538 ! GO TO 700
6539 ! 612 MSG = 'DLSODAR- MXSTEP (=I1) < 0 '
6540 ! CALL XERRWD (MSG, 30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0)
6541 ! GO TO 700
6542 ! 613 MSG = 'DLSODAR- MXHNIL (=I1) < 0 '
6543 ! CALL XERRWD (MSG, 30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
6544 ! GO TO 700
6545 ! 614 MSG = 'DLSODAR- TOUT (=R1) behind T (=R2) '
6546 ! CALL XERRWD (MSG, 40, 14, 0, 0, 0, 0, 2, TOUT, T)
6547 ! MSG = ' Integration direction is given by H0 (=R1) '
6548 ! CALL XERRWD (MSG, 50, 14, 0, 0, 0, 0, 1, H0, 0.0D0)
6549 ! GO TO 700
6550 ! 615 MSG = 'DLSODAR- HMAX (=R1) < 0.0 '
6551 ! CALL XERRWD (MSG, 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0)
6552 ! GO TO 700
6553 ! 616 MSG = 'DLSODAR- HMIN (=R1) < 0.0 '
6554 ! CALL XERRWD (MSG, 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0)
6555 ! GO TO 700
6556 ! 617 MSG='DLSODAR- RWORK length needed, LENRW(=I1), exceeds LRW(=I2) '
6557 ! CALL XERRWD (MSG, 60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
6558 ! GO TO 700
6559 ! 618 MSG='DLSODAR- IWORK length needed, LENIW(=I1), exceeds LIW(=I2) '
6560 ! CALL XERRWD (MSG, 60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
6561 ! GO TO 700
6562 ! 619 MSG = 'DLSODAR- RTOL(I1) is R1 < 0.0 '
6563 ! CALL XERRWD (MSG, 40, 19, 0, 1, I, 0, 1, RTOLI, 0.0D0)
6564 ! GO TO 700
6565 ! 620 MSG = 'DLSODAR- ATOL(I1) is R1 < 0.0 '
6566 ! CALL XERRWD (MSG, 40, 20, 0, 1, I, 0, 1, ATOLI, 0.0D0)
6567 ! GO TO 700
6568 ! 621 EWTI = RWORK(LEWT+I-1)
6569 ! MSG = 'DLSODAR- EWT(I1) is R1 <= 0.0 '
6570 ! CALL XERRWD (MSG, 40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0)
6571 ! GO TO 700
6572 ! 622 MSG='DLSODAR- TOUT(=R1) too close to T(=R2) to start integration.'
6573 ! CALL XERRWD (MSG, 60, 22, 0, 0, 0, 0, 2, TOUT, T)
6574 ! GO TO 700
6575 ! 623 MSG='DLSODAR- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
6576 ! CALL XERRWD (MSG, 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
6577 ! GO TO 700
6578 ! 624 MSG='DLSODAR- ITASK = 4 or 5 and TCRIT (=R1) behind TCUR (=R2) '
6579 ! CALL XERRWD (MSG, 60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
6580 ! GO TO 700
6581 ! 625 MSG='DLSODAR- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
6582 ! CALL XERRWD (MSG, 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
6583 ! GO TO 700
6584 ! 626 MSG = 'DLSODAR- At start of problem, too much accuracy '
6585 ! CALL XERRWD (MSG, 50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6586 ! MSG=' requested for precision of machine.. See TOLSF (=R1) '
6587 ! CALL XERRWD (MSG, 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0)
6588 ! RWORK(14) = TOLSF
6589 ! GO TO 700
6590 ! 627 MSG = 'DLSODAR- Trouble in DINTDY. ITASK = I1, TOUT = R1'
6591 ! CALL XERRWD (MSG, 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0)
6592 ! GO TO 700
6593 ! 628 MSG = 'DLSODAR- MXORDN (=I1) < 0 '
6594 ! CALL XERRWD (MSG, 30, 28, 0, 1, MXORDN, 0, 0, 0.0D0, 0.0D0)
6595 ! GO TO 700
6596 ! 629 MSG = 'DLSODAR- MXORDS (=I1) < 0 '
6597 ! CALL XERRWD (MSG, 30, 29, 0, 1, MXORDS, 0, 0, 0.0D0, 0.0D0)
6598 ! GO TO 700
6599 ! 630 MSG = 'DLSODAR- NG (=I1) < 0 '
6600 ! CALL XERRWD (MSG, 30, 30, 0, 1, NG, 0, 0, 0.0D0, 0.0D0)
6601 ! GO TO 700
6602 ! 631 MSG = 'DLSODAR- NG changed (from I1 to I2) illegally, '
6603 ! CALL XERRWD (MSG, 50, 31, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6604 ! MSG = ' i.e. not immediately after a root was found.'
6605 ! CALL XERRWD (MSG, 50, 31, 0, 2, NGC, NG, 0, 0.0D0, 0.0D0)
6606 ! GO TO 700
6607 ! 632 MSG = 'DLSODAR- One or more components of g has a root '
6608 ! CALL XERRWD (MSG, 50, 32, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6609 ! MSG = ' too near to the initial point. '
6610 ! CALL XERRWD (MSG, 40, 32, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
6611 ! 700 ISTATE = -3
6612 ! RETURN
6613 ! 800 MSG = 'DLSODAR- Run aborted.. apparent infinite loop. '
6614 ! CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0)
6615 ! RETURN
6616 !----------------------- End of Subroutine DLSODAR ---------------------
6617 ! END SUBROUTINE DLSODAR
6618 ! ECK DLSODPK
6619 ! SUBROUTINE DLSODPK (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK, &
6620 ! ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, PSOL, MF)
6621 ! EXTERNAL F, JAC, PSOL
6622 ! INTEGER :: NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, MF
6623 ! DOUBLE PRECISION :: Y, T, TOUT, RTOL, ATOL, RWORK
6624 ! DIMENSION NEQ(*), Y(*), RTOL(*), ATOL(*), RWORK(LRW), IWORK(LIW)
6625 !-----------------------------------------------------------------------
6626 ! This is the 18 November 2003 version of
6627 ! DLSODPK: Livermore Solver for Ordinary Differential equations,
6628 ! with Preconditioned Krylov iteration methods for the
6629 ! Newton correction linear systems.
6630 ! This version is in double precision.
6631 ! DLSODPK solves the initial value problem for stiff or nonstiff
6632 ! systems of first order ODEs,
6633 ! dy/dt = f(t,y) , or, in component form,
6634 ! dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ)) (i = 1,...,NEQ).
6635 !-----------------------------------------------------------------------
6636 ! Introduction.
6637 ! This is a modification of the DLSODE package which incorporates
6638 ! various preconditioned Krylov subspace iteration methods for the
6639 ! linear algebraic systems that arise in the case of stiff systems.
6640 ! The linear systems that must be solved have the form
6641 ! A * x = b , where A = identity - hl0 * (df/dy) .
6642 ! Here hl0 is a scalar, and df/dy is the Jacobian matrix of partial
6643 ! derivatives of f (NEQ by NEQ).
6644 ! The particular Krylov method is chosen by setting the second digit,
6645 ! MITER, in the method flag MF.
6646 ! Currently, the values of MITER have the following meanings:
6647 ! MITER = 1 means the preconditioned Scaled Incomplete
6648 ! Orthogonalization Method (SPIOM).
6649 ! 2 means an incomplete version of the Preconditioned Scaled
6650 ! Generalized Minimal Residual method (SPIGMR).
6651 ! This is the best choice in general.
6652 ! 3 means the Preconditioned Conjugate Gradient method (PCG).
6653 ! Recommended only when df/dy is symmetric or nearly so.
6654 ! 4 means the scaled Preconditioned Conjugate Gradient method
6655 ! (PCGS). Recommended only when D-inverse * df/dy * D is
6656 ! symmetric or nearly so, where D is the diagonal scaling
6657 ! matrix with elements 1/EWT(i) (see RTOL/ATOL description).
6658 ! 9 means that only a user-supplied matrix P (approximating A)
6659 ! will be used, with no Krylov iteration done. This option
6660 ! allows the user to provide the complete linear system
6661 ! solution algorithm, if desired.
6662 ! The user can apply preconditioning to the linear system A*x = b,
6663 ! by means of arbitrary matrices (the preconditioners).
6664 ! In the case of SPIOM and SPIGMR, one can apply left and right
6665 ! preconditioners P1 and P2, and the basic iterative method is then
6666 ! applied to the matrix (P1-inverse)*A*(P2-inverse) instead of to the
6667 ! matrix A. The product P1*P2 should be an approximation to matrix A
6668 ! such that linear systems with P1 or P2 are easier to solve than with
6669 ! A. Preconditioning from the left only or right only means using
6670 ! P2 = identity or P1 = identity, respectively.
6671 ! In the case of the PCG and PCGS methods, there is only one
6672 ! preconditioner matrix P (but it can be the product of more than one).
6673 ! It should approximate the matrix A but allow for relatively
6674 ! easy solution of linear systems with coefficient matrix P.
6675 ! For PCG, P should be positive definite symmetric, or nearly so,
6676 ! and for PCGS, the scaled preconditioner D-inverse * P * D
6677 ! should be symmetric or nearly so.
6678 ! If the Jacobian J = df/dy splits in a natural way into a sum
6679 ! J = J1 + J2, then one possible choice of preconditioners is
6680 ! P1 = identity - hl0 * J1 and P2 = identity - hl0 * J2
6681 ! provided each of these is easy to solve (or approximately solve).
6682 !-----------------------------------------------------------------------
6683 ! References:
6684 ! 1. Peter N. Brown and Alan C. Hindmarsh, Reduced Storage Matrix
6685 ! Methods in Stiff ODE Systems, J. Appl. Math. & Comp., 31 (1989),
6686 ! pp. 40-91; also L.L.N.L. Report UCRL-95088, Rev. 1, June 1987.
6687 ! 2. Alan C. Hindmarsh, ODEPACK, A Systematized Collection of ODE
6688 ! Solvers, in Scientific Computing, R. S. Stepleman et al. (Eds.),
6689 ! North-Holland, Amsterdam, 1983, pp. 55-64.
6690 !-----------------------------------------------------------------------
6691 ! Authors: Alan C. Hindmarsh and Peter N. Brown
6692 ! Center for Applied Scientific Computing, L-561
6693 ! Lawrence Livermore National Laboratory
6694 ! Livermore, CA 94551
6695 !-----------------------------------------------------------------------
6696 ! Summary of Usage.
6697 ! Communication between the user and the DLSODPK package, for normal
6698 ! situations, is summarized here. This summary describes only a subset
6699 ! of the full set of options available. See the full description for
6700 ! details, including optional communication, nonstandard options,
6701 ! and instructions for special situations. See also the demonstration
6702 ! program distributed with this solver.
6703 ! A. First provide a subroutine of the form:
6704 ! SUBROUTINE F (NEQ, T, Y, YDOT)
6705 ! DOUBLE PRECISION T, Y(*), YDOT(*)
6706 ! which supplies the vector function f by loading YDOT(i) with f(i).
6707 ! B. Next determine (or guess) whether or not the problem is stiff.
6708 ! Stiffness occurs when the Jacobian matrix df/dy has an eigenvalue
6709 ! whose real part is negative and large in magnitude, compared to the
6710 ! reciprocal of the t span of interest. If the problem is nonstiff,
6711 ! use a method flag MF = 10. If it is stiff, MF should be between 21
6712 ! and 24, or possibly 29. MF = 22 is generally the best choice.
6713 ! Use 23 or 24 only if symmetry is present. Use MF = 29 if the
6714 ! complete linear system solution is to be provided by the user.
6715 ! The following four parameters must also be set.
6716 ! IWORK(1) = LWP = length of real array WP for preconditioning.
6717 ! IWORK(2) = LIWP = length of integer array IWP for preconditioning.
6718 ! IWORK(3) = JPRE = preconditioner type flag:
6719 ! = 0 for no preconditioning (P1 = P2 = P = identity)
6720 ! = 1 for left-only preconditioning (P2 = identity)
6721 ! = 2 for right-only preconditioning (P1 = identity)
6722 ! = 3 for two-sided preconditioning (and PCG or PCGS)
6723 ! IWORK(4) = JACFLG = flag for whether JAC is called.
6724 ! = 0 if JAC is not to be called,
6725 ! = 1 if JAC is to be called.
6726 ! Use JACFLG = 1 if JAC computes any nonconstant data for use in
6727 ! preconditioning, such as Jacobian elements.
6728 ! The arrays WP and IWP are work arrays under the user's control,
6729 ! for use in the routines that perform preconditioning operations.
6730 ! C. If the problem is stiff, you must supply two routines that deal
6731 ! with the preconditioning of the linear systems to be solved.
6732 ! These are as follows:
6733 ! SUBROUTINE JAC (F, NEQ, T, Y, YSV, REWT, FTY, V, HL0, WP,IWP, IER)
6734 ! DOUBLE PRECISION T, Y(*),YSV(*), REWT(*), FTY(*), V(*), HL0, WP(*)
6735 ! INTEGER IWP(*)
6736 ! This routine must evaluate and preprocess any parts of the
6737 ! Jacobian matrix df/dy involved in the preconditioners P1, P2, P.
6738 ! The Y and FTY arrays contain the current values of y and f(t,y),
6739 ! respectively, and YSV also contains the current value of y.
6740 ! The array V is work space of length NEQ.
6741 ! JAC must multiply all computed Jacobian elements by the scalar
6742 ! -HL0, add the identity matrix, and do any factorization
6743 ! operations called for, in preparation for solving linear systems
6744 ! with a coefficient matrix of P1, P2, or P. The matrix P1*P2 or P
6745 ! should be an approximation to identity - HL0 * (df/dy).
6746 ! JAC should return IER = 0 if successful, and IER .ne. 0 if not.
6747 ! (If IER .ne. 0, a smaller time step will be tried.)
6748 ! SUBROUTINE PSOL (NEQ, T, Y, FTY, WK, HL0, WP, IWP, B, LR, IER)
6749 ! DOUBLE PRECISION T, Y(*), FTY(*), WK(*), HL0, WP(*), B(*)
6750 ! INTEGER IWP(*)
6751 ! This routine must solve a linear system with B as right-hand
6752 ! side and one of the preconditioning matrices, P1, P2, or P, as
6753 ! coefficient matrix, and return the solution vector in B.
6754 ! LR is a flag concerning left vs right preconditioning, input
6755 ! to PSOL. PSOL is to use P1 if LR = 1 and P2 if LR = 2.
6756 ! In the case of the PCG or PCGS method, LR will be 3, and PSOL
6757 ! should solve the system P*x = B with the preconditioner matrix P.
6758 ! In the case MF = 29 (no Krylov iteration), LR will be 0,
6759 ! and PSOL is to return in B the desired approximate solution
6760 ! to A * x = B, where A = identity - HL0 * (df/dy).
6761 ! PSOL can use data generated in the JAC routine and stored in
6762 ! WP and IWP. WK is a work array of length NEQ.
6763 ! The argument HL0 is the current value of the scalar appearing
6764 ! in the linear system. If the old value, at the time of the last
6765 ! JAC call, is needed, it must have been saved by JAC in WP.
6766 ! On return, PSOL should set the error flag IER as follows:
6767 ! IER = 0 if PSOL was successful,
6768 ! IER .gt. 0 if a recoverable error occurred, meaning that the
6769 ! time step will be retried,
6770 ! IER .lt. 0 if an unrecoverable error occurred, meaning that the
6771 ! solver is to stop immediately.
6772 ! D. Write a main program which calls Subroutine DLSODPK once for
6773 ! each point at which answers are desired. This should also provide
6774 ! for possible use of logical unit 6 for output of error messages by
6775 ! DLSODPK. On the first call to DLSODPK, supply arguments as follows:
6776 ! F = name of subroutine for right-hand side vector f.
6777 ! This name must be declared External in calling program.
6778 ! NEQ = number of first order ODEs.
6779 ! Y = array of initial values, of length NEQ.
6780 ! T = the initial value of the independent variable.
6781 ! TOUT = first point where output is desired (.ne. T).
6782 ! ITOL = 1 or 2 according as ATOL (below) is a scalar or array.
6783 ! RTOL = relative tolerance parameter (scalar).
6784 ! ATOL = absolute tolerance parameter (scalar or array).
6785 ! the estimated local error in y(i) will be controlled so as
6786 ! to be roughly less (in magnitude) than
6787 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or
6788 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2.
6789 ! Thus the local error test passes if, in each component,
6790 ! either the absolute error is less than ATOL (or ATOL(i)),
6791 ! or the relative error is less than RTOL.
6792 ! Use RTOL = 0.0 for pure absolute error control, and
6793 ! use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative error
6794 ! control. Caution: Actual (global) errors may exceed these
6795 ! local tolerances, so choose them conservatively.
6796 ! ITASK = 1 for normal computation of output values of y at t = TOUT.
6797 ! ISTATE = integer flag (input and output). Set ISTATE = 1.
6798 ! IOPT = 0 to indicate no optional inputs used.
6799 ! RWORK = real work array of length at least:
6800 ! 20 + 16*NEQ for MF = 10,
6801 ! 45 + 17*NEQ + LWP for MF = 21,
6802 ! 61 + 17*NEQ + LWP for MF = 22,
6803 ! 20 + 15*NEQ + LWP for MF = 23 or 24,
6804 ! 20 + 12*NEQ + LWP for MF = 29.
6805 ! LRW = declared length of RWORK (in user's dimension).
6806 ! IWORK = integer work array of length at least:
6807 ! 30 for MF = 10,
6808 ! 35 + LIWP for MF = 21,
6809 ! 30 + LIWP for MF = 22, 23, 24, or 29.
6810 ! LIW = declared length of IWORK (in user's dimension).
6811 ! JAC,PSOL = names of subroutines for preconditioning.
6812 ! These names must be declared External in the calling program.
6813 ! MF = method flag. Standard values are:
6814 ! 10 for nonstiff (Adams) method.
6815 ! 21 for stiff (BDF) method, with preconditioned SIOM.
6816 ! 22 for stiff method, with preconditioned GMRES method.
6817 ! 23 for stiff method, with preconditioned CG method.
6818 ! 24 for stiff method, with scaled preconditioned CG method.
6819 ! 29 for stiff method, with user's PSOL routine only.
6820 ! Note that the main program must declare arrays Y, RWORK, IWORK,
6821 ! and possibly ATOL.
6822 ! E. The output from the first call (or any call) is:
6823 ! Y = array of computed values of y(t) vector.
6824 ! T = corresponding value of independent variable (normally TOUT).
6825 ! ISTATE = 2 if DLSODPK was successful, negative otherwise.
6826 ! -1 means excess work done on this call (perhaps wrong MF).
6827 ! -2 means excess accuracy requested (tolerances too small).
6828 ! -3 means illegal input detected (see printed message).
6829 ! -4 means repeated error test failures (check all inputs).
6830 ! -5 means repeated convergence failures (perhaps bad JAC
6831 ! or PSOL routine supplied or wrong choice of MF or
6832 ! tolerances, or this solver is inappropriate).
6833 ! -6 means error weight became zero during problem. (Solution
6834 ! component i vanished, and ATOL or ATOL(i) = 0.)
6835 ! -7 means an unrecoverable error occurred in PSOL.
6836 ! F. To continue the integration after a successful return, simply
6837 ! reset TOUT and call DLSODPK again. No other parameters need be reset.
6838 !-----------------------------------------------------------------------
6839 !-----------------------------------------------------------------------
6840 ! Full Description of User Interface to DLSODPK.
6841 ! The user interface to DLSODPK consists of the following parts.
6842 ! 1. The call sequence to Subroutine DLSODPK, which is a driver
6843 ! routine for the solver. This includes descriptions of both
6844 ! the call sequence arguments and of user-supplied routines.
6845 ! Following these descriptions is a description of
6846 ! optional inputs available through the call sequence, and then
6847 ! a description of optional outputs (in the work arrays).
6848 ! 2. Descriptions of other routines in the DLSODPK package that may be
6849 ! (optionally) called by the user. These provide the ability to
6850 ! alter error message handling, save and restore the internal
6851 ! Common, and obtain specified derivatives of the solution y(t).
6852 ! 3. Descriptions of Common blocks to be declared in overlay
6853 ! or similar environments, or to be saved when doing an interrupt
6854 ! of the problem and continued solution later.
6855 ! 4. Description of two routines in the DLSODPK package, either of
6856 ! which the user may replace with his/her own version, if desired.
6857 ! These relate to the measurement of errors.
6858 !-----------------------------------------------------------------------
6859 ! Part 1. Call Sequence.
6860 ! The call sequence parameters used for input only are
6861 ! F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC, PSOL, MF,
6862 ! and those used for both input and output are
6863 ! Y, T, ISTATE.
6864 ! The work arrays RWORK and IWORK are also used for conditional and
6865 ! optional inputs and optional outputs. (The term output here refers
6866 ! to the return from Subroutine DLSODPK to the user's calling program.)
6867 ! The legality of input parameters will be thoroughly checked on the
6868 ! initial call for the problem, but not checked thereafter unless a
6869 ! change in input parameters is flagged by ISTATE = 3 on input.
6870 ! The descriptions of the call arguments are as follows.
6871 ! F = the name of the user-supplied subroutine defining the
6872 ! ODE system. The system must be put in the first-order
6873 ! form dy/dt = f(t,y), where f is a vector-valued function
6874 ! of the scalar t and the vector y. Subroutine F is to
6875 ! compute the function f. It is to have the form
6876 ! SUBROUTINE F (NEQ, T, Y, YDOT)
6877 ! DOUBLE PRECISION T, Y(*), YDOT(*)
6878 ! where NEQ, T, and Y are input, and the array YDOT = f(t,y)
6879 ! is output. Y and YDOT are arrays of length NEQ.
6880 ! Subroutine F should not alter Y(1),...,Y(NEQ).
6881 ! F must be declared External in the calling program.
6882 ! Subroutine F may access user-defined quantities in
6883 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
6884 ! (dimensioned in F) and/or Y has length exceeding NEQ(1).
6885 ! See the descriptions of NEQ and Y below.
6886 ! If quantities computed in the F routine are needed
6887 ! externally to DLSODPK, an extra call to F should be made
6888 ! for this purpose, for consistent and accurate results.
6889 ! If only the derivative dy/dt is needed, use DINTDY instead.
6890 ! NEQ = the size of the ODE system (number of first order
6891 ! ordinary differential equations). Used only for input.
6892 ! NEQ may be decreased, but not increased, during the problem.
6893 ! If NEQ is decreased (with ISTATE = 3 on input), the
6894 ! remaining components of Y should be left undisturbed, if
6895 ! these are to be accessed in the user-supplied subroutines.
6896 ! Normally, NEQ is a scalar, and it is generally referred to
6897 ! as a scalar in this user interface description. However,
6898 ! NEQ may be an array, with NEQ(1) set to the system size.
6899 ! (The DLSODPK package accesses only NEQ(1).) In either case,
6900 ! this parameter is passed as the NEQ argument in all calls
6901 ! to F, JAC, and PSOL. Hence, if it is an array, locations
6902 ! NEQ(2),... may be used to store other integer data and pass
6903 ! it to the user-supplied subroutines. Each such routine must
6904 ! include NEQ in a Dimension statement in that case.
6905 ! Y = a real array for the vector of dependent variables, of
6906 ! length NEQ or more. Used for both input and output on the
6907 ! first call (ISTATE = 1), and only for output on other calls.
6908 ! On the first call, Y must contain the vector of initial
6909 ! values. On output, Y contains the computed solution vector,
6910 ! evaluated at T. If desired, the Y array may be used
6911 ! for other purposes between calls to the solver.
6912 ! This array is passed as the Y argument in all calls to F,
6913 ! JAC, and PSOL. Hence its length may exceed NEQ, and locations
6914 ! Y(NEQ+1),... may be used to store other real data and
6915 ! pass it to the user-supplied subroutines. (The DLSODPK
6916 ! package accesses only Y(1),...,Y(NEQ).)
6917 ! T = the independent variable. On input, T is used only on the
6918 ! first call, as the initial point of the integration.
6919 ! On output, after each call, T is the value at which a
6920 ! computed solution y is evaluated (usually the same as TOUT).
6921 ! On an error return, T is the farthest point reached.
6922 ! TOUT = the next value of t at which a computed solution is desired.
6923 ! Used only for input.
6924 ! When starting the problem (ISTATE = 1), TOUT may be equal
6925 ! to T for one call, then should .ne. T for the next call.
6926 ! For the initial T, an input value of TOUT .ne. T is used
6927 ! in order to determine the direction of the integration
6928 ! (i.e. the algebraic sign of the step sizes) and the rough
6929 ! scale of the problem. Integration in either direction
6930 ! (forward or backward in t) is permitted.
6931 ! If ITASK = 2 or 5 (one-step modes), TOUT is ignored after
6932 ! the first call (i.e. the first call with TOUT .ne. T).
6933 ! Otherwise, TOUT is required on every call.
6934 ! If ITASK = 1, 3, or 4, the values of TOUT need not be
6935 ! monotone, but a value of TOUT which backs up is limited
6936 ! to the current internal T interval, whose endpoints are
6937 ! TCUR - HU and TCUR (see optional outputs, below, for
6938 ! TCUR and HU).
6939 ! ITOL = an indicator for the type of error control. See
6940 ! description below under ATOL. Used only for input.
6941 ! RTOL = a relative error tolerance parameter, either a scalar or
6942 ! an array of length NEQ. See description below under ATOL.
6943 ! Input only.
6944 ! ATOL = an absolute error tolerance parameter, either a scalar or
6945 ! an array of length NEQ. Input only.
6946 ! The input parameters ITOL, RTOL, and ATOL determine
6947 ! the error control performed by the solver. The solver will
6948 ! control the vector E = (E(i)) of estimated local errors
6949 ! in y, according to an inequality of the form
6950 ! RMS-norm of ( E(i)/EWT(i) ) .le. 1,
6951 ! where EWT(i) = RTOL(i)*ABS(Y(i)) + ATOL(i),
6952 ! and the RMS-norm (root-mean-square norm) here is
6953 ! RMS-norm(v) = SQRT(sum v(i)**2 / NEQ). Here EWT = (EWT(i))
6954 ! is a vector of weights which must always be positive, and
6955 ! the values of RTOL and ATOL should all be non-negative.
6956 ! the following table gives the types (scalar/array) of
6957 ! RTOL and ATOL, and the corresponding form of EWT(i).
6958 ! ITOL RTOL ATOL EWT(i)
6959 ! 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
6960 ! 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
6961 ! 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
6962 ! 4 array array RTOL(i)*ABS(Y(i)) + ATOL(i)
6963 ! When either of these parameters is a scalar, it need not
6964 ! be dimensioned in the user's calling program.
6965 ! If none of the above choices (with ITOL, RTOL, and ATOL
6966 ! fixed throughout the problem) is suitable, more general
6967 ! error controls can be obtained by substituting
6968 ! user-supplied routines for the setting of EWT and/or for
6969 ! the norm calculation. See Part 4 below.
6970 ! If global errors are to be estimated by making a repeated
6971 ! run on the same problem with smaller tolerances, then all
6972 ! components of RTOL and ATOL (i.e. of EWT) should be scaled
6973 ! down uniformly.
6974 ! ITASK = an index specifying the task to be performed.
6975 ! Input only. ITASK has the following values and meanings.
6976 ! 1 means normal computation of output values of y(t) at
6977 ! t = TOUT (by overshooting and interpolating).
6978 ! 2 means take one step only and return.
6979 ! 3 means stop at the first internal mesh point at or
6980 ! beyond t = TOUT and return.
6981 ! 4 means normal computation of output values of y(t) at
6982 ! t = TOUT but without overshooting t = TCRIT.
6983 ! TCRIT must be input as RWORK(1). TCRIT may be equal to
6984 ! or beyond TOUT, but not behind it in the direction of
6985 ! integration. This option is useful if the problem
6986 ! has a singularity at or beyond t = TCRIT.
6987 ! 5 means take one step, without passing TCRIT, and return.
6988 ! TCRIT must be input as RWORK(1).
6989 ! Note: If ITASK = 4 or 5 and the solver reaches TCRIT
6990 ! (within roundoff), it will return T = TCRIT (exactly) to
6991 ! indicate this (unless ITASK = 4 and TOUT comes before TCRIT,
6992 ! in which case answers at t = TOUT are returned first).
6993 ! ISTATE = an index used for input and output to specify the
6994 ! the state of the calculation.
6995 ! On input, the values of ISTATE are as follows.
6996 ! 1 means this is the first call for the problem
6997 ! (initializations will be done). See note below.
6998 ! 2 means this is not the first call, and the calculation
6999 ! is to continue normally, with no change in any input
7000 ! parameters except possibly TOUT and ITASK.
7001 ! (If ITOL, RTOL, and/or ATOL are changed between calls
7002 ! with ISTATE = 2, the new values will be used but not
7003 ! tested for legality.)
7004 ! 3 means this is not the first call, and the
7005 ! calculation is to continue normally, but with
7006 ! a change in input parameters other than
7007 ! TOUT and ITASK. Changes are allowed in
7008 ! NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF,
7009 ! and any of the optional inputs except H0.
7010 ! Note: A preliminary call with TOUT = T is not counted
7011 ! as a first call here, as no initialization or checking of
7012 ! input is done. (Such a call is sometimes useful for the
7013 ! purpose of outputting the initial conditions.)
7014 ! Thus the first call for which TOUT .ne. T requires
7015 ! ISTATE = 1 on input.
7016 ! On output, ISTATE has the following values and meanings.
7017 ! 1 means nothing was done; TOUT = T and ISTATE = 1 on input.
7018 ! 2 means the integration was performed successfully.
7019 ! -1 means an excessive amount of work (more than MXSTEP
7020 ! steps) was done on this call, before completing the
7021 ! requested task, but the integration was otherwise
7022 ! successful as far as T. (MXSTEP is an optional input
7023 ! and is normally 500.) To continue, the user may
7024 ! simply reset ISTATE to a value .gt. 1 and call again
7025 ! (the excess work step counter will be reset to 0).
7026 ! In addition, the user may increase MXSTEP to avoid
7027 ! this error return (see below on optional inputs).
7028 ! -2 means too much accuracy was requested for the precision
7029 ! of the machine being used. This was detected before
7030 ! completing the requested task, but the integration
7031 ! was successful as far as T. To continue, the tolerance
7032 ! parameters must be reset, and ISTATE must be set
7033 ! to 3. The optional output TOLSF may be used for this
7034 ! purpose. (Note: If this condition is detected before
7035 ! taking any steps, then an illegal input return
7036 ! (ISTATE = -3) occurs instead.)
7037 ! -3 means illegal input was detected, before taking any
7038 ! integration steps. See written message for details.
7039 ! Note: If the solver detects an infinite loop of calls
7040 ! to the solver with illegal input, it will cause
7041 ! the run to stop.
7042 ! -4 means there were repeated error test failures on
7043 ! one attempted step, before completing the requested
7044 ! task, but the integration was successful as far as T.
7045 ! The problem may have a singularity, or the input
7046 ! may be inappropriate.
7047 ! -5 means there were repeated convergence test failures on
7048 ! one attempted step, before completing the requested
7049 ! task, but the integration was successful as far as T.
7050 ! -6 means EWT(i) became zero for some i during the
7051 ! integration. Pure relative error control (ATOL(i)=0.0)
7052 ! was requested on a variable which has now vanished.
7053 ! The integration was successful as far as T.
7054 ! -7 means the PSOL routine returned an unrecoverable error
7055 ! flag (IER .lt. 0). The integration was successful as
7056 ! far as T.
7057 ! Note: since the normal output value of ISTATE is 2,
7058 ! it does not need to be reset for normal continuation.
7059 ! Also, since a negative input value of ISTATE will be
7060 ! regarded as illegal, a negative output value requires the
7061 ! user to change it, and possibly other inputs, before
7062 ! calling the solver again.
7063 ! IOPT = an integer flag to specify whether or not any optional
7064 ! inputs are being used on this call. Input only.
7065 ! The optional inputs are listed separately below.
7066 ! IOPT = 0 means no optional inputs are being used.
7067 ! Default values will be used in all cases.
7068 ! IOPT = 1 means one or more optional inputs are being used.
7069 ! RWORK = a real working array (double precision).
7070 ! The length of RWORK must be at least
7071 ! 20 + NYH*(MAXORD + 1) + 3*NEQ + LENLS + LWP where
7072 ! NYH = the initial value of NEQ,
7073 ! MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a
7074 ! smaller value is given as an optional input),
7075 ! LENLS = length of work space for linear system (Krylov)
7076 ! method, excluding preconditioning:
7077 ! LENLS = 0 if MITER = 0,
7078 ! LENLS = NEQ*(MAXL+3) + MAXL**2 if MITER = 1,
7079 ! LENLS = NEQ*(MAXL+3+MIN(1,MAXL-KMP))
7080 ! + (MAXL+3)*MAXL + 1 if MITER = 2,
7081 ! LENLS = 6*NEQ if MITER = 3 or 4,
7082 ! LENLS = 3*NEQ if MITER = 9.
7083 ! (See the MF description for METH and MITER, and the
7084 ! list of optional inputs for MAXL and KMP.)
7085 ! LWP = length of real user work space for preconditioning
7086 ! (see JAC/PSOL).
7087 ! Thus if default values are used and NEQ is constant,
7088 ! this length is:
7089 ! 20 + 16*NEQ for MF = 10,
7090 ! 45 + 24*NEQ + LWP FOR MF = 11,
7091 ! 61 + 24*NEQ + LWP FOR MF = 12,
7092 ! 20 + 22*NEQ + LWP FOR MF = 13 OR 14,
7093 ! 20 + 19*NEQ + LWP FOR MF = 19,
7094 ! 20 + 9*NEQ FOR MF = 20,
7095 ! 45 + 17*NEQ + LWP FOR MF = 21,
7096 ! 61 + 17*NEQ + LWP FOR MF = 22,
7097 ! 20 + 15*NEQ + LWP FOR MF = 23 OR 24,
7098 ! 20 + 12*NEQ + LWP for MF = 29.
7099 ! The first 20 words of RWORK are reserved for conditional
7100 ! and optional inputs and optional outputs.
7101 ! The following word in RWORK is a conditional input:
7102 ! RWORK(1) = TCRIT = critical value of t which the solver
7103 ! is not to overshoot. Required if ITASK is
7104 ! 4 or 5, and ignored otherwise. (See ITASK.)
7105 ! LRW = the length of the array RWORK, as declared by the user.
7106 ! (This will be checked by the solver.)
7107 ! IWORK = an integer work array. The length of IWORK must be at least
7108 ! 30 if MITER = 0 (MF = 10 or 20),
7109 ! 30 + MAXL + LIWP if MITER = 1 (MF = 11, 21),
7110 ! 30 + LIWP if MITER = 2, 3, 4, or 9.
7111 ! MAXL = 5 unless a different optional input value is given.
7112 ! LIWP = length of integer user work space for preconditioning
7113 ! (see conditional input list following).
7114 ! The first few words of IWORK are used for conditional and
7115 ! optional inputs and optional outputs.
7116 ! The following 4 words in IWORK are conditional inputs,
7117 ! required if MITER .ge. 1:
7118 ! IWORK(1) = LWP = length of real array WP for use in
7119 ! preconditioning (part of RWORK array).
7120 ! IWORK(2) = LIWP = length of integer array IWP for use in
7121 ! preconditioning (part of IWORK array).
7122 ! The arrays WP and IWP are work arrays under the
7123 ! user's control, for use in the routines that
7124 ! perform preconditioning operations (JAC and PSOL).
7125 ! IWORK(3) = JPRE = preconditioner type flag:
7126 ! = 0 for no preconditioning (P1 = P2 = P = identity)
7127 ! = 1 for left-only preconditioning (P2 = identity)
7128 ! = 2 for right-only preconditioning (P1 = identity)
7129 ! = 3 for two-sided preconditioning (and PCG or PCGS)
7130 ! IWORK(4) = JACFLG = flag for whether JAC is called.
7131 ! = 0 if JAC is not to be called,
7132 ! = 1 if JAC is to be called.
7133 ! Use JACFLG = 1 if JAC computes any nonconstant
7134 ! data needed in preconditioning operations,
7135 ! such as some of the Jacobian elements.
7136 ! LIW = the length of the array IWORK, as declared by the user.
7137 ! (This will be checked by the solver.)
7138 ! Note: The work arrays must not be altered between calls to DLSODPK
7139 ! for the same problem, except possibly for the conditional and
7140 ! optional inputs, and except for the last 3*NEQ words of RWORK.
7141 ! The latter space is used for internal scratch space, and so is
7142 ! available for use by the user outside DLSODPK between calls, if
7143 ! desired (but not for use by any of the user-supplied subroutines).
7144 ! JAC = the name of the user-supplied routine to compute any
7145 ! Jacobian elements (or approximations) involved in the
7146 ! matrix preconditioning operations (MITER .ge. 1).
7147 ! It is to have the form
7148 ! SUBROUTINE JAC (F, NEQ, T, Y, YSV, REWT, FTY, V,
7149 ! 1 HL0, WP, IWP, IER)
7150 ! DOUBLE PRECISION T, Y(*),YSV(*), REWT(*), FTY(*), V(*),
7151 ! 1 HL0, WP(*)
7152 ! INTEGER IWP(*)
7153 ! This routine must evaluate and preprocess any parts of the
7154 ! Jacobian matrix df/dy used in the preconditioners P1, P2, P.
7155 ! the Y and FTY arrays contain the current values of y and
7156 ! f(t,y), respectively, and YSV also contains the current
7157 ! value of y. The array V is work space of length
7158 ! NEQ for use by JAC. REWT is the array of reciprocal error
7159 ! weights (1/EWT). JAC must multiply all computed Jacobian
7160 ! elements by the scalar -HL0, add the identity matrix, and do
7161 ! any factorization operations called for, in preparation
7162 ! for solving linear systems with a coefficient matrix of
7163 ! P1, P2, or P. The matrix P1*P2 or P should be an
7164 ! approximation to identity - HL0 * (df/dy). JAC should
7165 ! return IER = 0 if successful, and IER .ne. 0 if not.
7166 ! (If IER .ne. 0, a smaller time step will be tried.)
7167 ! The arrays WP (of length LWP) and IWP (of length LIWP)
7168 ! are for use by JAC and PSOL for work space and for storage
7169 ! of data needed for the solution of the preconditioner
7170 ! linear systems. Their lengths and contents are under the
7171 ! user's control.
7172 ! The JAC routine may save relevant Jacobian elements (or
7173 ! approximations) used in the preconditioners, along with the
7174 ! value of HL0, and use these to reconstruct preconditioner
7175 ! matrices later without reevaluationg those elements.
7176 ! This may be cost-effective if JAC is called with HL0
7177 ! considerably different from its earlier value, indicating
7178 ! that a corrector convergence failure has occurred because
7179 ! of the change in HL0, not because of changes in the
7180 ! value of the Jacobian. In doing this, use the saved and
7181 ! current values of HL0 to decide whether to use saved
7182 ! or reevaluated elements.
7183 ! JAC may alter V, but may not alter Y, YSV, REWT, FTY, or HL0.
7184 ! JAC must be declared External in the calling program.
7185 ! Subroutine JAC may access user-defined quantities in
7186 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
7187 ! (dimensioned in JAC) and/or Y has length exceeding NEQ(1).
7188 ! See the descriptions of NEQ and Y above.
7189 ! PSOL = the name of the user-supplied routine for the
7190 ! solution of preconditioner linear systems.
7191 ! It is to have the form
7192 ! SUBROUTINE PSOL (NEQ, T, Y, FTY, WK,HL0, WP,IWP, B, LR,IER)
7193 ! DOUBLE PRECISION T, Y(*), FTY(*), WK(*), HL0, WP(*), B(*)
7194 ! INTEGER IWP(*)
7195 ! This routine must solve a linear system with B as right-hand
7196 ! side and one of the preconditioning matrices, P1, P2, or P,
7197 ! as coefficient matrix, and return the solution vector in B.
7198 ! LR is a flag concerning left vs right preconditioning, input
7199 ! to PSOL. PSOL is to use P1 if LR = 1 and P2 if LR = 2.
7200 ! In the case of the PCG or PCGS method, LR will be 3, and PSOL
7201 ! should solve the system P*x = B with the preconditioner P.
7202 ! In the case MITER = 9 (no Krylov iteration), LR will be 0,
7203 ! and PSOL is to return in B the desired approximate solution
7204 ! to A * x = B, where A = identity - HL0 * (df/dy).
7205 ! PSOL can use data generated in the JAC routine and stored in
7206 ! WP and IWP.
7207 ! The Y and FTY arrays contain the current values of y and
7208 ! f(t,y), respectively. The array WK is work space of length
7209 ! NEQ for use by PSOL.
7210 ! The argument HL0 is the current value of the scalar appearing
7211 ! in the linear system. If the old value, as of the last
7212 ! JAC call, is needed, it must have been saved by JAC in WP.
7213 ! On return, PSOL should set the error flag IER as follows:
7214 ! IER = 0 if PSOL was successful,
7215 ! IER .gt. 0 on a recoverable error, meaning that the
7216 ! time step will be retried,
7217 ! IER .lt. 0 on an unrecoverable error, meaning that the
7218 ! solver is to stop immediately.
7219 ! PSOL may not alter Y, FTY, or HL0.
7220 ! PSOL must be declared External in the calling program.
7221 ! Subroutine PSOL may access user-defined quantities in
7222 ! NEQ(2),... and Y(NEQ(1)+1),... if NEQ is an array
7223 ! (dimensioned in PSOL) and/or Y has length exceeding NEQ(1).
7224 ! See the descriptions of NEQ and Y above.
7225 ! MF = the method flag. Used only for input. The legal values of
7226 ! MF are 10, 11, 12, 13, 14, 19, 20, 21, 22, 23, 24, and 29.
7227 ! MF has decimal digits METH and MITER: MF = 10*METH + MITER.
7228 ! METH indicates the basic linear multistep method:
7229 ! METH = 1 means the implicit Adams method.
7230 ! METH = 2 means the method based on Backward
7231 ! Differentiation Formulas (BDFs).
7232 ! MITER indicates the corrector iteration method:
7233 ! MITER = 0 means functional iteration (no linear system
7234 ! is involved).
7235 ! MITER = 1 means Newton iteration with Scaled Preconditioned
7236 ! Incomplete Orthogonalization Method (SPIOM)
7237 ! for the linear systems.
7238 ! MITER = 2 means Newton iteration with Scaled Preconditioned
7239 ! Generalized Minimal Residual method (SPIGMR)
7240 ! for the linear systems.
7241 ! MITER = 3 means Newton iteration with Preconditioned
7242 ! Conjugate Gradient method (PCG)
7243 ! for the linear systems.
7244 ! MITER = 4 means Newton iteration with scaled Preconditioned
7245 ! Conjugate Gradient method (PCGS)
7246 ! for the linear systems.
7247 ! MITER = 9 means Newton iteration with only the
7248 ! user-supplied PSOL routine called (no Krylov
7249 ! iteration) for the linear systems.
7250 ! JPRE is ignored, and PSOL is called with LR = 0.
7251 ! See comments in the introduction about the choice of MITER.
7252 ! If MITER .ge. 1, the user must supply routines JAC and PSOL
7253 ! (the names are arbitrary) as described above.
7254 ! For MITER = 0, dummy arguments can be used.
7255 !-----------------------------------------------------------------------
7256 ! Optional Inputs.
7257 ! The following is a list of the optional inputs provided for in the
7258 ! call sequence. (See also Part 2.) For each such input variable,
7259 ! this table lists its name as used in this documentation, its
7260 ! location in the call sequence, its meaning, and the default value.
7261 ! The use of any of these inputs requires IOPT = 1, and in that
7262 ! case all of these inputs are examined. A value of zero for any
7263 ! of these optional inputs will cause the default value to be used.
7264 ! Thus to use a subset of the optional inputs, simply preload
7265 ! locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, and
7266 ! then set those of interest to nonzero values.
7267 ! Name Location Meaning and Default Value
7268 ! H0 RWORK(5) the step size to be attempted on the first step.
7269 ! The default value is determined by the solver.
7270 ! HMAX RWORK(6) the maximum absolute step size allowed.
7271 ! The default value is infinite.
7272 ! HMIN RWORK(7) the minimum absolute step size allowed.
7273 ! The default value is 0. (This lower bound is not
7274 ! enforced on the final step before reaching TCRIT
7275 ! when ITASK = 4 or 5.)
7276 ! DELT RWORK(8) convergence test constant in Krylov iteration
7277 ! algorithm. The default is .05.
7278 ! MAXORD IWORK(5) the maximum order to be allowed. The default
7279 ! value is 12 if METH = 1, and 5 if METH = 2.
7280 ! If MAXORD exceeds the default value, it will
7281 ! be reduced to the default value.
7282 ! If MAXORD is changed during the problem, it may
7283 ! cause the current order to be reduced.
7284 ! MXSTEP IWORK(6) maximum number of (internally defined) steps
7285 ! allowed during one call to the solver.
7286 ! The default value is 500.
7287 ! MXHNIL IWORK(7) maximum number of messages printed (per problem)
7288 ! warning that T + H = T on a step (H = step size).
7289 ! This must be positive to result in a non-default
7290 ! value. The default value is 10.
7291 ! MAXL IWORK(8) maximum number of iterations in the SPIOM, SPIGMR,
7292 ! PCG, or PCGS algorithm (.le. NEQ).
7293 ! The default is MAXL = MIN(5,NEQ).
7294 ! KMP IWORK(9) number of vectors on which orthogonalization
7295 ! is done in SPIOM or SPIGMR algorithm (.le. MAXL).
7296 ! The default is KMP = MAXL.
7297 ! Note: When KMP .lt. MAXL and MF = 22, the length
7298 ! of RWORK must be defined accordingly. See
7299 ! the definition of RWORK above.
7300 !-----------------------------------------------------------------------
7301 ! Optional Outputs.
7302 ! As optional additional output from DLSODPK, the variables listed
7303 ! below are quantities related to the performance of DLSODPK
7304 ! which are available to the user. These are communicated by way of
7305 ! the work arrays, but also have internal mnemonic names as shown.
7306 ! Except where stated otherwise, all of these outputs are defined
7307 ! on any successful return from DLSODPK, and on any return with
7308 ! ISTATE = -1, -2, -4, -5, -6, or -7. On an illegal input return
7309 ! (ISTATE = -3), they will be unchanged from their existing values
7310 ! (if any), except possibly for TOLSF, LENRW, and LENIW.
7311 ! On any error return, outputs relevant to the error will be defined,
7312 ! as noted below.
7313 ! Name Location Meaning
7314 ! HU RWORK(11) the step size in t last used (successfully).
7315 ! HCUR RWORK(12) the step size to be attempted on the next step.
7316 ! TCUR RWORK(13) the current value of the independent variable
7317 ! which the solver has actually reached, i.e. the
7318 ! current internal mesh point in t. On output, TCUR
7319 ! will always be at least as far as the argument
7320 ! T, but may be farther (if interpolation was done).
7321 ! TOLSF RWORK(14) a tolerance scale factor, greater than 1.0,
7322 ! computed when a request for too much accuracy was
7323 ! detected (ISTATE = -3 if detected at the start of
7324 ! the problem, ISTATE = -2 otherwise). If ITOL is
7325 ! left unaltered but RTOL and ATOL are uniformly
7326 ! scaled up by a factor of TOLSF for the next call,
7327 ! then the solver is deemed likely to succeed.
7328 ! (The user may also ignore TOLSF and alter the
7329 ! tolerance parameters in any other way appropriate.)
7330 ! NST IWORK(11) the number of steps taken for the problem so far.
7331 ! NFE IWORK(12) the number of f evaluations for the problem so far.
7332 ! NPE IWORK(13) the number of calls to JAC so far (for Jacobian
7333 ! evaluation associated with preconditioning).
7334 ! NQU IWORK(14) the method order last used (successfully).
7335 ! NQCUR IWORK(15) the order to be attempted on the next step.
7336 ! IMXER IWORK(16) the index of the component of largest magnitude in
7337 ! the weighted local error vector ( E(i)/EWT(i) ),
7338 ! on an error return with ISTATE = -4 or -5.
7339 ! LENRW IWORK(17) the length of RWORK actually required.
7340 ! This is defined on normal returns and on an illegal
7341 ! input return for insufficient storage.
7342 ! LENIW IWORK(18) the length of IWORK actually required.
7343 ! This is defined on normal returns and on an illegal
7344 ! input return for insufficient storage.
7345 ! NNI IWORK(19) number of nonlinear iterations so far (each of
7346 ! which calls an iterative linear solver).
7347 ! NLI IWORK(20) number of linear iterations so far.
7348 ! Note: A measure of the success of algorithm is
7349 ! the average number of linear iterations per
7350 ! nonlinear iteration, given by NLI/NNI.
7351 ! If this is close to MAXL, MAXL may be too small.
7352 ! NPS IWORK(21) number of preconditioning solve operations
7353 ! (PSOL calls) so far.
7354 ! NCFN IWORK(22) number of convergence failures of the nonlinear
7355 ! (Newton) iteration so far.
7356 ! Note: A measure of success is the overall
7357 ! rate of nonlinear convergence failures, NCFN/NST.
7358 ! NCFL IWORK(23) number of convergence failures of the linear
7359 ! iteration so far.
7360 ! Note: A measure of success is the overall
7361 ! rate of linear convergence failures, NCFL/NNI.
7362 ! The following two arrays are segments of the RWORK array which
7363 ! may also be of interest to the user as optional outputs.
7364 ! For each array, the table below gives its internal name,
7365 ! its base address in RWORK, and its description.
7366 ! Name Base Address Description
7367 ! YH 21 the Nordsieck history array, of size NYH by
7368 ! (NQCUR + 1), where NYH is the initial value
7369 ! of NEQ. For j = 0,1,...,NQCUR, column j+1
7370 ! of YH contains HCUR**j/factorial(j) times
7371 ! the j-th derivative of the interpolating
7372 ! polynomial currently representing the solution,
7373 ! evaluated at t = TCUR.
7374 ! ACOR LENRW-NEQ+1 array of size NEQ used for the accumulated
7375 ! corrections on each step, scaled on output
7376 ! to represent the estimated local error in y
7377 ! on the last step. This is the vector E in
7378 ! the description of the error control. It is
7379 ! defined only on a successful return from
7380 ! DLSODPK.
7381 !-----------------------------------------------------------------------
7382 ! Part 2. Other Routines Callable.
7383 ! The following are optional calls which the user may make to
7384 ! gain additional capabilities in conjunction with DLSODPK.
7385 ! (The routines XSETUN and XSETF are designed to conform to the
7386 ! SLATEC error handling package.)
7387 ! Form of Call Function
7388 ! CALL XSETUN(LUN) Set the logical unit number, LUN, for
7389 ! output of messages from DLSODPK, if
7390 ! the default is not desired.
7391 ! The default value of lun is 6.
7392 ! CALL XSETF(MFLAG) Set a flag to control the printing of
7393 ! messages by DLSODPK.
7394 ! MFLAG = 0 means do not print. (Danger:
7395 ! This risks losing valuable information.)
7396 ! MFLAG = 1 means print (the default).
7397 ! Either of the above calls may be made at
7398 ! any time and will take effect immediately.
7399 ! CALL DSRCPK(RSAV,ISAV,JOB) saves and restores the contents of
7400 ! the internal Common blocks used by
7401 ! DLSODPK (see Part 3 below).
7402 ! RSAV must be a real array of length 222
7403 ! or more, and ISAV must be an integer
7404 ! array of length 50 or more.
7405 ! JOB=1 means save Common into RSAV/ISAV.
7406 ! JOB=2 means restore Common from RSAV/ISAV.
7407 ! DSRCPK is useful if one is
7408 ! interrupting a run and restarting
7409 ! later, or alternating between two or
7410 ! more problems solved with DLSODPK.
7411 ! CALL DINTDY(,,,,,) Provide derivatives of y, of various
7412 ! (See below) orders, at a specified point t, if
7413 ! desired. It may be called only after
7414 ! a successful return from DLSODPK.
7415 ! The detailed instructions for using DINTDY are as follows.
7416 ! The form of the call is:
7417 ! CALL DINTDY (T, K, RWORK(21), NYH, DKY, IFLAG)
7418 ! The input parameters are:
7419 ! T = value of independent variable where answers are desired
7420 ! (normally the same as the T last returned by DLSODPK).
7421 ! for valid results, T must lie between TCUR - HU and TCUR.
7422 ! (See optional outputs for TCUR and HU.)
7423 ! K = integer order of the derivative desired. K must satisfy
7424 ! 0 .le. K .le. NQCUR, where NQCUR is the current order
7425 ! (see optional outputs). The capability corresponding
7426 ! to K = 0, i.e. computing y(T), is already provided
7427 ! by DLSODPK directly. Since NQCUR .ge. 1, the first
7428 ! derivative dy/dt is always available with DINTDY.
7429 ! RWORK(21) = the base address of the history array YH.
7430 ! NYH = column length of YH, equal to the initial value of NEQ.
7431 ! The output parameters are:
7432 ! DKY = a real array of length NEQ containing the computed value
7433 ! of the K-th derivative of y(t).
7434 ! IFLAG = integer flag, returned as 0 if K and T were legal,
7435 ! -1 if K was illegal, and -2 if T was illegal.
7436 ! On an error return, a message is also written.
7437 !-----------------------------------------------------------------------
7438 ! Part 3. Common Blocks.
7439 ! If DLSODPK is to be used in an overlay situation, the user
7440 ! must declare, in the primary overlay, the variables in:
7441 ! (1) the call sequence to DLSODPK, and
7442 ! (2) the two internal Common blocks
7443 ! /DLS001/ of length 255 (218 double precision words
7444 ! followed by 37 integer words),
7445 ! /DLPK01/ of length 17 (4 double precision words
7446 ! followed by 13 integer words).
7447 ! If DLSODPK is used on a system in which the contents of internal
7448 ! Common blocks are not preserved between calls, the user should
7449 ! declare the above Common blocks in the calling program to insure
7450 ! that their contents are preserved.
7451 ! If the solution of a given problem by DLSODPK is to be interrupted
7452 ! and then later continued, such as when restarting an interrupted run
7453 ! or alternating between two or more problems, the user should save,
7454 ! following the return from the last DLSODPK call prior to the
7455 ! interruption, the contents of the call sequence variables and the
7456 ! internal Common blocks, and later restore these values before the
7457 ! next DLSODPK call for that problem. To save and restore the Common
7458 ! blocks, use Subroutine DSRCPK (see Part 2 above).
7459 !-----------------------------------------------------------------------
7460 ! Part 4. Optionally Replaceable Solver Routines.
7461 ! below are descriptions of two routines in the DLSODPK package which
7462 ! relate to the measurement of errors. Either routine can be
7463 ! replaced by a user-supplied version, if desired. However, since such
7464 ! a replacement may have a major impact on performance, it should be
7465 ! done only when absolutely necessary, and only with great caution.
7466 ! (Note: The means by which the package version of a routine is
7467 ! superseded by the user's version may be system-dependent.)
7468 ! (a) DEWSET.
7469 ! The following subroutine is called just before each internal
7470 ! integration step, and sets the array of error weights, EWT, as
7471 ! described under ITOL/RTOL/ATOL above:
7472 ! SUBROUTINE DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
7473 ! where NEQ, ITOL, RTOL, and ATOL are as in the DLSODPK call sequence,
7474 ! YCUR contains the current dependent variable vector, and
7475 ! EWT is the array of weights set by DEWSET.
7476 ! If the user supplies this subroutine, it must return in EWT(i)
7477 ! (i = 1,...,NEQ) a positive quantity suitable for comparing errors
7478 ! in y(i) to. The EWT array returned by DEWSET is passed to the DVNORM
7479 ! routine (see below), and also used by DLSODPK in the computation
7480 ! of the optional output IMXER, the diagonal Jacobian approximation,
7481 ! and the increments for difference quotient Jacobians.
7482 ! In the user-supplied version of DEWSET, it may be desirable to use
7483 ! the current values of derivatives of y. Derivatives up to order NQ
7484 ! are available from the history array YH, described above under
7485 ! optional outputs. In DEWSET, YH is identical to the YCUR array,
7486 ! extended to NQ + 1 columns with a column length of NYH and scale
7487 ! factors of H**j/factorial(j). On the first call for the problem,
7488 ! given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
7489 ! NYH is the initial value of NEQ. The quantities NQ, H, and NST
7490 ! can be obtained by including in DEWSET the statements:
7491 ! DOUBLE PRECISION RLS
7492 ! COMMON /DLS001/ RLS(218),ILS(37)
7493 ! NQ = ILS(33)
7494 ! NST = ILS(34)
7495 ! H = RLS(212)
7496 ! Thus, for example, the current value of dy/dt can be obtained as
7497 ! YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is
7498 ! unnecessary when NST = 0).
7499 ! (b) DVNORM.
7500 ! The following is a real function routine which computes the weighted
7501 ! root-mean-square norm of a vector v:
7502 ! D = DVNORM (N, V, W)
7503 ! where:
7504 ! N = the length of the vector,
7505 ! V = real array of length N containing the vector,
7506 ! W = real array of length N containing weights,
7507 ! D = SQRT( (1/N) * sum(V(i)*W(i))**2 ).
7508 ! DVNORM is called with N = NEQ and with W(i) = 1.0/EWT(i), where
7509 ! EWT is as set by Subroutine DEWSET.
7510 ! If the user supplies this function, it should return a non-negative
7511 ! value of DVNORM suitable for use in the error control in DLSODPK.
7512 ! None of the arguments should be altered by DVNORM.
7513 ! For example, a user-supplied DVNORM routine might:
7514 ! -substitute a max-norm of (V(i)*W(i)) for the RMS-norm, or
7515 ! -ignore some components of V in the norm, with the effect of
7516 ! suppressing the error control on those components of y.
7517 !-----------------------------------------------------------------------
7518 !***REVISION HISTORY (YYYYMMDD)
7519 ! 19860901 DATE WRITTEN
7520 ! 19861010 Numerous minor revisions to SPIOM and SPGMR routines;
7521 ! minor corrections to prologues and comments.
7522 ! 19870114 Changed name SPGMR to SPIGMR; revised residual norm
7523 ! calculation in SPIGMR (for incomplete case);
7524 ! revised error return logic in SPIGMR;
7525 ! 19870330 Major update: corrected comments throughout;
7526 ! removed TRET from Common; rewrote EWSET with 4 loops;
7527 ! fixed t test in INTDY; added Cray directives in STODPK;
7528 ! in STODPK, fixed DELP init. and logic around PJAC call;
7529 ! combined routines to save/restore Common;
7530 ! passed LEVEL = 0 in error message calls (except run abort).
7531 ! 19871130 Added option MITER = 9; shortened WM array by 2;
7532 ! revised early return from SPIOM and SPIGMR;
7533 ! replaced copy loops with SCOPY/DCOPY calls;
7534 ! minor corrections/revisions to SOLPK, SPIGMR, ATV, ATP;
7535 ! corrections to main prologue and internal comments.
7536 ! 19880304 Corrections to type declarations in SOLPK, SPIOM, USOL.
7537 ! 19891025 Added ISTATE = -7 return; minor revisions to USOL;
7538 ! added initialization of JACFLG in main driver;
7539 ! removed YH and NYH from PKSET call list;
7540 ! minor revisions to SPIOM and SPIGMR;
7541 ! corrections to main prologue and internal comments.
7542 ! 19900803 Added YSV to JAC call list; minor comment corrections.
7543 ! 20010425 Major update: convert source lines to upper case;
7544 ! added *DECK lines; changed from 1 to * in dummy dimensions;
7545 ! changed names R1MACH/D1MACH to RUMACH/DUMACH;
7546 ! renamed routines for uniqueness across single/double prec.;
7547 ! converted intrinsic names to generic form;
7548 ! removed ILLIN and NTREP (data loaded) from Common;
7549 ! removed all 'own' variables from Common;
7550 ! changed error messages to quoted strings;
7551 ! replaced XERRWV/XERRWD with 1993 revised version;
7552 ! converted prologues, comments, error messages to mixed case;
7553 ! numerous corrections to prologues and internal comments.
7554 ! 20010507 Converted single precision source to double precision.
7555 ! 20020502 Corrected declarations in descriptions of user routines.
7556 ! 20030603 Corrected duplicate type declaration for DUMACH.
7557 ! 20031105 Restored 'own' variables to Common blocks, to enable
7558 ! interrupt/restart feature.
7559 ! 20031112 Added SAVE statements for data-loaded constants.
7560 ! 20031117 Changed internal name NPE to NJE.
7561 !-----------------------------------------------------------------------
7562 ! Other routines in the DLSODPK package.
7563 ! In addition to Subroutine DLSODPK, the DLSODPK package includes the
7564 ! following subroutines and function routines:
7565 ! DINTDY computes an interpolated value of the y vector at t = TOUT.
7566 ! DEWSET sets the error weight vector EWT before each step.
7567 ! DVNORM computes the weighted RMS-norm of a vector.
7568 ! DSTODPK is the core integrator, which does one step of the
7569 ! integration and the associated error control.
7570 ! DCFODE sets all method coefficients and test constants.
7571 ! DPKSET interfaces between DSTODPK and the JAC routine.
7572 ! DSOLPK manages solution of linear system in Newton iteration.
7573 ! DSPIOM performs the SPIOM algorithm.
7574 ! DATV computes a scaled, preconditioned product (I-hl0*J)*v.
7575 ! DORTHOG orthogonalizes a vector against previous basis vectors.
7576 ! DHEFA generates an LU factorization of a Hessenberg matrix.
7577 ! DHESL solves a Hessenberg square linear system.
7578 ! DSPIGMR performs the SPIGMR algorithm.
7579 ! DHEQR generates a QR factorization of a Hessenberg matrix.
7580 ! DHELS finds the least squares solution of a Hessenberg system.
7581 ! DPCG performs Preconditioned Conjugate Gradient algorithm (PCG).
7582 ! DPCGS performs the PCGS algorithm.
7583 ! DATP computes the product A*p, where A = I - hl0*df/dy.
7584 ! DUSOL interfaces to the user's PSOL routine (MITER = 9).
7585 ! DSRCPK is a user-callable routine to save and restore
7586 ! the contents of the internal Common blocks.
7587 ! DAXPY, DCOPY, DDOT, DNRM2, and DSCAL are basic linear
7588 ! algebra modules (from the BLAS collection).
7589 ! DUMACH computes the unit roundoff in a machine-independent manner.
7590 ! XERRWD, XSETUN, XSETF, IXSAV, and IUMACH handle the printing of all
7591 ! error messages and warnings. XERRWD is machine-dependent.
7592 ! Note: DVNORM, DDOT, DNRM2, DUMACH, IXSAV, and IUMACH are function
7593 ! routines. All the others are subroutines.
7594 !-----------------------------------------------------------------------
7595 ! DOUBLE PRECISION :: DUMACH, DVNORM
7596 ! INTEGER :: INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS, &
7597 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
7598 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
7599 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
7600 ! INTEGER :: JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
7601 ! NNI, NLI, NPS, NCFN, NCFL
7602 ! INTEGER :: I, I1, I2, IFLAG, IMXER, KGO, LF0, LENIW, &
7603 ! LENIWK, LENRW, LENWM, LENWK, LIWP, LWP, MORD, MXHNL0, MXSTP0, &
7604 ! NCFN0, NCFL0, NLI0, NNI0, NNID, NSTD, NWARN
7605 ! DOUBLE PRECISION :: ROWNS, &
7606 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
7607 ! DOUBLE PRECISION :: DELT, EPCON, SQRTN, RSQRTN
7608 ! DOUBLE PRECISION :: ATOLI, AVDIM, AYI, BIG, EWTI, H0, HMAX, HMX, &
7609 ! RCFL, RCFN, RH, RTOLI, TCRIT, &
7610 ! TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0
7611 ! DIMENSION MORD(2)
7612 ! LOGICAL :: IHIT, LAVD, LCFN, LCFL, LWARN
7613 ! CHARACTER(60) :: MSG
7614 ! SAVE MORD, MXSTP0, MXHNL0
7615 !-----------------------------------------------------------------------
7616 ! The following two internal Common blocks contain
7617 ! (a) variables which are local to any subroutine but whose values must
7618 ! be preserved between calls to the routine ("own" variables), and
7619 ! (b) variables which are communicated between subroutines.
7620 ! The block DLS001 is declared in subroutines DLSODPK, DINTDY, DSTODPK,
7621 ! DSOLPK, and DATV.
7622 ! The block DLPK01 is declared in subroutines DLSODPK, DSTODPK, DPKSET,
7623 ! and DSOLPK.
7624 ! Groups of variables are replaced by dummy arrays in the Common
7625 ! declarations in routines where those variables are not used.
7626 !-----------------------------------------------------------------------
7627 ! COMMON /DLS001/ ROWNS(209), &
7628 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
7629 ! INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6), &
7630 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
7631 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
7632 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
7633 ! COMMON /DLPK01/ DELT, EPCON, SQRTN, RSQRTN, &
7634 ! JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
7635 ! NNI, NLI, NPS, NCFN, NCFL
7636 ! DATA MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
7637 !-----------------------------------------------------------------------
7638 ! Block A.
7639 ! This code block is executed on every call.
7640 ! It tests ISTATE and ITASK for legality and branches appropriately.
7641 ! If ISTATE .gt. 1 but the flag INIT shows that initialization has
7642 ! not yet been done, an error return occurs.
7643 ! If ISTATE = 1 and TOUT = T, return immediately.
7644 !-----------------------------------------------------------------------
7645 ! IF (ISTATE < 1 .OR. ISTATE > 3) GO TO 601
7646 ! IF (ITASK < 1 .OR. ITASK > 5) GO TO 602
7647 ! IF (ISTATE == 1) GO TO 10
7648 ! IF (INIT == 0) GO TO 603
7649 ! IF (ISTATE == 2) GO TO 200
7650 ! GO TO 20
7651 ! 10 INIT = 0
7652 ! IF (TOUT == T) RETURN
7653 !-----------------------------------------------------------------------
7654 ! Block B.
7655 ! The next code block is executed for the initial call (ISTATE = 1),
7656 ! or for a continuation call with parameter changes (ISTATE = 3).
7657 ! It contains checking of all inputs and various initializations.
7658 ! First check legality of the non-optional inputs NEQ, ITOL, IOPT, MF.
7659 !-----------------------------------------------------------------------
7660 ! 20 IF (NEQ(1) <= 0) GO TO 604
7661 ! IF (ISTATE == 1) GO TO 25
7662 ! IF (NEQ(1) > N) GO TO 605
7663 ! 25 N = NEQ(1)
7664 ! IF (ITOL < 1 .OR. ITOL > 4) GO TO 606
7665 ! IF (IOPT < 0 .OR. IOPT > 1) GO TO 607
7666 ! METH = MF/10
7667 ! MITER = MF - 10*METH
7668 ! IF (METH < 1 .OR. METH > 2) GO TO 608
7669 ! IF (MITER < 0) GO TO 608
7670 ! IF (MITER > 4 .AND. MITER < 9) GO TO 608
7671 ! IF (MITER >= 1) JPRE = IWORK(3)
7672 ! JACFLG = 0
7673 ! IF (MITER >= 1) JACFLG = IWORK(4)
7674 ! Next process and check the optional inputs. --------------------------
7675 ! IF (IOPT == 1) GO TO 40
7676 ! MAXORD = MORD(METH)
7677 ! MXSTEP = MXSTP0
7678 ! MXHNIL = MXHNL0
7679 ! IF (ISTATE == 1) H0 = 0.0D0
7680 ! HMXI = 0.0D0
7681 ! HMIN = 0.0D0
7682 ! MAXL = MIN(5,N)
7683 ! KMP = MAXL
7684 ! DELT = 0.05D0
7685 ! GO TO 60
7686 ! 40 MAXORD = IWORK(5)
7687 ! IF (MAXORD < 0) GO TO 611
7688 ! IF (MAXORD == 0) MAXORD = 100
7689 ! MAXORD = MIN(MAXORD,MORD(METH))
7690 ! MXSTEP = IWORK(6)
7691 ! IF (MXSTEP < 0) GO TO 612
7692 ! IF (MXSTEP == 0) MXSTEP = MXSTP0
7693 ! MXHNIL = IWORK(7)
7694 ! IF (MXHNIL < 0) GO TO 613
7695 ! IF (MXHNIL == 0) MXHNIL = MXHNL0
7696 ! IF (ISTATE /= 1) GO TO 50
7697 ! H0 = RWORK(5)
7698 ! IF ((TOUT - T)*H0 < 0.0D0) GO TO 614
7699 ! 50 HMAX = RWORK(6)
7700 ! IF (HMAX < 0.0D0) GO TO 615
7701 ! HMXI = 0.0D0
7702 ! IF (HMAX > 0.0D0) HMXI = 1.0D0/HMAX
7703 ! HMIN = RWORK(7)
7704 ! IF (HMIN < 0.0D0) GO TO 616
7705 ! MAXL = IWORK(8)
7706 ! IF (MAXL == 0) MAXL = 5
7707 ! MAXL = MIN(MAXL,N)
7708 ! KMP = IWORK(9)
7709 ! IF (KMP == 0 .OR. KMP > MAXL) KMP = MAXL
7710 ! DELT = RWORK(8)
7711 ! IF (DELT == 0.0D0) DELT = 0.05D0
7712 !-----------------------------------------------------------------------
7713 ! Set work array pointers and check lengths LRW and LIW.
7714 ! Pointers to segments of RWORK and IWORK are named by prefixing L to
7715 ! the name of the segment. E.g., the segment YH starts at RWORK(LYH).
7716 ! RWORK segments (in order) are denoted YH, WM, EWT, SAVF, SAVX, ACOR.
7717 !-----------------------------------------------------------------------
7718 ! 60 LYH = 21
7719 ! IF (ISTATE == 1) NYH = N
7720 ! LWM = LYH + (MAXORD + 1)*NYH
7721 ! IF (MITER == 0) LENWK = 0
7722 ! IF (MITER == 1) LENWK = N*(MAXL+2) + MAXL*MAXL
7723 ! IF (MITER == 2) &
7724 ! LENWK = N*(MAXL+2+MIN(1,MAXL-KMP)) + (MAXL+3)*MAXL + 1
7725 ! IF (MITER == 3 .OR. MITER == 4) LENWK = 5*N
7726 ! IF (MITER == 9) LENWK = 2*N
7727 ! LWP = 0
7728 ! IF (MITER >= 1) LWP = IWORK(1)
7729 ! LENWM = LENWK + LWP
7730 ! LOCWP = LENWK + 1
7731 ! LEWT = LWM + LENWM
7732 ! LSAVF = LEWT + N
7733 ! LSAVX = LSAVF + N
7734 ! LACOR = LSAVX + N
7735 ! IF (MITER == 0) LACOR = LSAVF + N
7736 ! LENRW = LACOR + N - 1
7737 ! IWORK(17) = LENRW
7738 ! LIWM = 31
7739 ! LENIWK = 0
7740 ! IF (MITER == 1) LENIWK = MAXL
7741 ! LIWP = 0
7742 ! IF (MITER >= 1) LIWP = IWORK(2)
7743 ! LENIW = 30 + LENIWK + LIWP
7744 ! LOCIWP = LENIWK + 1
7745 ! IWORK(18) = LENIW
7746 ! IF (LENRW > LRW) GO TO 617
7747 ! IF (LENIW > LIW) GO TO 618
7748 ! Check RTOL and ATOL for legality. ------------------------------------
7749 ! RTOLI = RTOL(1)
7750 ! ATOLI = ATOL(1)
7751 ! DO 70 I = 1,N
7752 ! IF (ITOL >= 3) RTOLI = RTOL(I)
7753 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
7754 ! IF (RTOLI < 0.0D0) GO TO 619
7755 ! IF (ATOLI < 0.0D0) GO TO 620
7756 ! 70 END DO
7757 ! Load SQRT(N) and its reciprocal in Common. ---------------------------
7758 ! SQRTN = SQRT(REAL(N))
7759 ! RSQRTN = 1.0D0/SQRTN
7760 ! IF (ISTATE == 1) GO TO 100
7761 ! If ISTATE = 3, set flag to signal parameter changes to DSTODPK. ------
7762 ! JSTART = -1
7763 ! IF (NQ <= MAXORD) GO TO 90
7764 ! MAXORD was reduced below NQ. Copy YH(*,MAXORD+2) into SAVF. ---------
7765 ! DO 80 I = 1,N
7766 ! RWORK(I+LSAVF-1) = RWORK(I+LWM-1)
7767 ! 80 END DO
7768 ! 90 CONTINUE
7769 ! IF (N == NYH) GO TO 200
7770 ! NEQ was reduced. Zero part of YH to avoid undefined references. -----
7771 ! I1 = LYH + L*NYH
7772 ! I2 = LYH + (MAXORD + 1)*NYH - 1
7773 ! IF (I1 > I2) GO TO 200
7774 ! DO 95 I = I1,I2
7775 ! RWORK(I) = 0.0D0
7776 ! 95 END DO
7777 ! GO TO 200
7778 !-----------------------------------------------------------------------
7779 ! Block C.
7780 ! The next block is for the initial call only (ISTATE = 1).
7781 ! It contains all remaining initializations, the initial call to F,
7782 ! and the calculation of the initial step size.
7783 ! The error weights in EWT are inverted after being loaded.
7784 !-----------------------------------------------------------------------
7785 ! 100 UROUND = DUMACH()
7786 ! TN = T
7787 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 110
7788 ! TCRIT = RWORK(1)
7789 ! IF ((TCRIT - TOUT)*(TOUT - T) < 0.0D0) GO TO 625
7790 ! IF (H0 /= 0.0D0 .AND. (T + H0 - TCRIT)*H0 > 0.0D0) &
7791 ! H0 = TCRIT - T
7792 ! 110 JSTART = 0
7793 ! NHNIL = 0
7794 ! NST = 0
7795 ! NJE = 0
7796 ! NSLAST = 0
7797 ! NLI0 = 0
7798 ! NNI0 = 0
7799 ! NCFN0 = 0
7800 ! NCFL0 = 0
7801 ! NWARN = 0
7802 ! HU = 0.0D0
7803 ! NQU = 0
7804 ! CCMAX = 0.3D0
7805 ! MAXCOR = 3
7806 ! MSBP = 20
7807 ! MXNCF = 10
7808 ! NNI = 0
7809 ! NLI = 0
7810 ! NPS = 0
7811 ! NCFN = 0
7812 ! NCFL = 0
7813 ! Initial call to F. (LF0 points to YH(*,2).) -------------------------
7814 ! LF0 = LYH + NYH
7815 ! CALL F (NEQ, T, Y, RWORK(LF0))
7816 ! NFE = 1
7817 ! Load the initial value vector in YH. ---------------------------------
7818 ! DO 115 I = 1,N
7819 ! RWORK(I+LYH-1) = Y(I)
7820 ! 115 END DO
7821 ! Load and invert the EWT array. (H is temporarily set to 1.0.) -------
7822 ! NQ = 1
7823 ! H = 1.0D0
7824 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
7825 ! DO 120 I = 1,N
7826 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
7827 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
7828 ! 120 END DO
7829 !-----------------------------------------------------------------------
7830 ! The coding below computes the step size, H0, to be attempted on the
7831 ! first step, unless the user has supplied a value for this.
7832 ! First check that TOUT - T differs significantly from zero.
7833 ! A scalar tolerance quantity TOL is computed, as MAX(RTOL(i))
7834 ! if this is positive, or MAX(ATOL(i)/ABS(Y(i))) otherwise, adjusted
7835 ! so as to be between 100*UROUND and 1.0E-3.
7836 ! Then the computed value H0 is given by..
7837 ! NEQ
7838 ! H0**2 = TOL / ( w0**-2 + (1/NEQ) * Sum ( f(i)/ywt(i) )**2 )
7839 ! 1
7840 ! where w0 = MAX ( ABS(T), ABS(TOUT) ),
7841 ! f(i) = i-th component of initial value of f,
7842 ! ywt(i) = EWT(i)/TOL (a weight for y(i)).
7843 ! The sign of H0 is inferred from the initial values of TOUT and T.
7844 !-----------------------------------------------------------------------
7845 ! IF (H0 /= 0.0D0) GO TO 180
7846 ! TDIST = ABS(TOUT - T)
7847 ! W0 = MAX(ABS(T),ABS(TOUT))
7848 ! IF (TDIST < 2.0D0*UROUND*W0) GO TO 622
7849 ! TOL = RTOL(1)
7850 ! IF (ITOL <= 2) GO TO 140
7851 ! DO 130 I = 1,N
7852 ! TOL = MAX(TOL,RTOL(I))
7853 ! 130 END DO
7854 ! 140 IF (TOL > 0.0D0) GO TO 160
7855 ! ATOLI = ATOL(1)
7856 ! DO 150 I = 1,N
7857 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
7858 ! AYI = ABS(Y(I))
7859 ! IF (AYI /= 0.0D0) TOL = MAX(TOL,ATOLI/AYI)
7860 ! 150 END DO
7861 ! 160 TOL = MAX(TOL,100.0D0*UROUND)
7862 ! TOL = MIN(TOL,0.001D0)
7863 ! SUM = DVNORM (N, RWORK(LF0), RWORK(LEWT))
7864 ! SUM = 1.0D0/(TOL*W0*W0) + TOL*SUM**2
7865 ! H0 = 1.0D0/SQRT(SUM)
7866 ! H0 = MIN(H0,TDIST)
7867 ! H0 = SIGN(H0,TOUT-T)
7868 ! Adjust H0 if necessary to meet HMAX bound. ---------------------------
7869 ! 180 RH = ABS(H0)*HMXI
7870 ! IF (RH > 1.0D0) H0 = H0/RH
7871 ! Load H with H0 and scale YH(*,2) by H0. ------------------------------
7872 ! H = H0
7873 ! DO 190 I = 1,N
7874 ! RWORK(I+LF0-1) = H0*RWORK(I+LF0-1)
7875 ! 190 END DO
7876 ! GO TO 270
7877 !-----------------------------------------------------------------------
7878 ! Block D.
7879 ! The next code block is for continuation calls only (ISTATE = 2 or 3)
7880 ! and is to check stop conditions before taking a step.
7881 !-----------------------------------------------------------------------
7882 ! 200 NSLAST = NST
7883 ! NLI0 = NLI
7884 ! NNI0 = NNI
7885 ! NCFN0 = NCFN
7886 ! NCFL0 = NCFL
7887 ! NWARN = 0
7888 ! GO TO (210, 250, 220, 230, 240), ITASK
7889 ! 210 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
7890 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
7891 ! IF (IFLAG /= 0) GO TO 627
7892 ! T = TOUT
7893 ! GO TO 420
7894 ! 220 TP = TN - HU*(1.0D0 + 100.0D0*UROUND)
7895 ! IF ((TP - TOUT)*H > 0.0D0) GO TO 623
7896 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 250
7897 ! GO TO 400
7898 ! 230 TCRIT = RWORK(1)
7899 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
7900 ! IF ((TCRIT - TOUT)*H < 0.0D0) GO TO 625
7901 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 245
7902 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
7903 ! IF (IFLAG /= 0) GO TO 627
7904 ! T = TOUT
7905 ! GO TO 420
7906 ! 240 TCRIT = RWORK(1)
7907 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
7908 ! 245 HMX = ABS(TN) + ABS(H)
7909 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
7910 ! IF (IHIT) GO TO 400
7911 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
7912 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
7913 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
7914 ! IF (ISTATE == 2) JSTART = -2
7915 !-----------------------------------------------------------------------
7916 ! Block E.
7917 ! The next block is normally executed for all calls and contains
7918 ! the call to the one-step core integrator DSTODPK.
7919 ! This is a looping point for the integration steps.
7920 ! First check for too many steps being taken,
7921 ! Check for poor Newton/Krylov method performance, update EWT (if not
7922 ! at start of problem), check for too much accuracy being requested,
7923 ! and check for H below the roundoff level in T.
7924 !-----------------------------------------------------------------------
7925 ! 250 CONTINUE
7926 ! IF ((NST-NSLAST) >= MXSTEP) GO TO 500
7927 ! NSTD = NST - NSLAST
7928 ! NNID = NNI - NNI0
7929 ! IF (NSTD < 10 .OR. NNID == 0) GO TO 255
7930 ! AVDIM = REAL(NLI - NLI0)/REAL(NNID)
7931 ! RCFN = REAL(NCFN - NCFN0)/REAL(NSTD)
7932 ! RCFL = REAL(NCFL - NCFL0)/REAL(NNID)
7933 ! LAVD = AVDIM > (MAXL - 0.05D0)
7934 ! LCFN = RCFN > 0.9D0
7935 ! LCFL = RCFL > 0.9D0
7936 ! LWARN = LAVD .OR. LCFN .OR. LCFL
7937 ! IF ( .NOT. LWARN) GO TO 255
7938 ! NWARN = NWARN + 1
7939 ! IF (NWARN > 10) GO TO 255
7940 ! IF (LAVD) THEN
7941 ! MSG='DLSODPK- Warning. Poor iterative algorithm performance seen '
7942 ! CALL XERRWD (MSG, 60, 111, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
7943 ! ENDIF
7944 ! IF (LAVD) THEN
7945 ! MSG=' at T = R1 by average no. of linear iterations = R2 '
7946 ! CALL XERRWD (MSG, 60, 111, 0, 0, 0, 0, 2, TN, AVDIM)
7947 ! ENDIF
7948 ! IF (LCFN) THEN
7949 ! MSG='DLSODPK- Warning. Poor iterative algorithm performance seen '
7950 ! CALL XERRWD (MSG, 60, 112, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
7951 ! ENDIF
7952 ! IF (LCFN) THEN
7953 ! MSG=' at T = R1 by nonlinear convergence failure rate = R2 '
7954 ! CALL XERRWD (MSG, 60, 112, 0, 0, 0, 0, 2, TN, RCFN)
7955 ! ENDIF
7956 ! IF (LCFL) THEN
7957 ! MSG='DLSODPK- Warning. Poor iterative algorithm performance seen '
7958 ! CALL XERRWD (MSG, 60, 113, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
7959 ! ENDIF
7960 ! IF (LCFL) THEN
7961 ! MSG=' at T = R1 by linear convergence failure rate = R2 '
7962 ! CALL XERRWD (MSG, 60, 113, 0, 0, 0, 0, 2, TN, RCFL)
7963 ! ENDIF
7964 ! 255 CONTINUE
7965 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
7966 ! DO 260 I = 1,N
7967 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 510
7968 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
7969 ! 260 END DO
7970 ! 270 TOLSF = UROUND*DVNORM (N, RWORK(LYH), RWORK(LEWT))
7971 ! IF (TOLSF <= 1.0D0) GO TO 280
7972 ! TOLSF = TOLSF*2.0D0
7973 ! IF (NST == 0) GO TO 626
7974 ! GO TO 520
7975 ! 280 IF ((TN + H) /= TN) GO TO 290
7976 ! NHNIL = NHNIL + 1
7977 ! IF (NHNIL > MXHNIL) GO TO 290
7978 ! MSG = 'DLSODPK- Warning..Internal T(=R1) and H(=R2) are '
7979 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
7980 ! MSG=' such that in the machine, T + H = T on the next step '
7981 ! CALL XERRWD (MSG, 60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
7982 ! MSG = ' (H = step size). Solver will continue anyway.'
7983 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 2, TN, H)
7984 ! IF (NHNIL < MXHNIL) GO TO 290
7985 ! MSG = 'DLSODPK- Above warning has been issued I1 times. '
7986 ! CALL XERRWD (MSG, 50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
7987 ! MSG = ' It will not be issued again for this problem.'
7988 ! CALL XERRWD (MSG, 50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
7989 ! 290 CONTINUE
7990 !-----------------------------------------------------------------------
7991 ! CALL DSTODPK(NEQ,Y,YH,NYH,YH,EWT,SAVF,SAVX,ACOR,WM,IWM,F,JAC,PSOL)
7992 !-----------------------------------------------------------------------
7993 ! CALL DSTODPK (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT), &
7994 ! RWORK(LSAVF), RWORK(LSAVX), RWORK(LACOR), RWORK(LWM), &
7995 ! IWORK(LIWM), F, JAC, PSOL)
7996 ! KGO = 1 - KFLAG
7997 ! GO TO (300, 530, 540, 550), KGO
7998 !-----------------------------------------------------------------------
7999 ! Block F.
8000 ! The following block handles the case of a successful return from the
8001 ! core integrator (KFLAG = 0). Test for stop conditions.
8002 !-----------------------------------------------------------------------
8003 ! 300 INIT = 1
8004 ! GO TO (310, 400, 330, 340, 350), ITASK
8005 ! ITASK = 1. If TOUT has been reached, interpolate. -------------------
8006 ! 310 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
8007 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
8008 ! T = TOUT
8009 ! GO TO 420
8010 ! ITASK = 3. Jump to exit if TOUT was reached. ------------------------
8011 ! 330 IF ((TN - TOUT)*H >= 0.0D0) GO TO 400
8012 ! GO TO 250
8013 ! ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary.
8014 ! 340 IF ((TN - TOUT)*H < 0.0D0) GO TO 345
8015 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
8016 ! T = TOUT
8017 ! GO TO 420
8018 ! 345 HMX = ABS(TN) + ABS(H)
8019 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
8020 ! IF (IHIT) GO TO 400
8021 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
8022 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
8023 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
8024 ! JSTART = -2
8025 ! GO TO 250
8026 ! ITASK = 5. see if TCRIT was reached and jump to exit. ---------------
8027 ! 350 HMX = ABS(TN) + ABS(H)
8028 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
8029 !-----------------------------------------------------------------------
8030 ! Block G.
8031 ! The following block handles all successful returns from DLSODPK.
8032 ! If ITASK .ne. 1, Y is loaded from YH and T is set accordingly.
8033 ! ISTATE is set to 2, and the optional outputs are loaded into the
8034 ! work arrays before returning.
8035 !-----------------------------------------------------------------------
8036 ! 400 DO 410 I = 1,N
8037 ! Y(I) = RWORK(I+LYH-1)
8038 ! 410 END DO
8039 ! T = TN
8040 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 420
8041 ! IF (IHIT) T = TCRIT
8042 ! 420 ISTATE = 2
8043 ! RWORK(11) = HU
8044 ! RWORK(12) = H
8045 ! RWORK(13) = TN
8046 ! IWORK(11) = NST
8047 ! IWORK(12) = NFE
8048 ! IWORK(13) = NJE
8049 ! IWORK(14) = NQU
8050 ! IWORK(15) = NQ
8051 ! IWORK(19) = NNI
8052 ! IWORK(20) = NLI
8053 ! IWORK(21) = NPS
8054 ! IWORK(22) = NCFN
8055 ! IWORK(23) = NCFL
8056 ! RETURN
8057 !-----------------------------------------------------------------------
8058 ! Block H.
8059 ! The following block handles all unsuccessful returns other than
8060 ! those for illegal input. First the error message routine is called.
8061 ! If there was an error test or convergence test failure, IMXER is set.
8062 ! Then Y is loaded from YH and T is set to TN.
8063 ! The optional outputs are loaded into the work arrays before returning.
8064 !-----------------------------------------------------------------------
8065 ! The maximum number of steps was taken before reaching TOUT. ----------
8066 ! 500 MSG = 'DLSODPK- At current T (=R1), MXSTEP (=I1) steps '
8067 ! CALL XERRWD (MSG, 50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
8068 ! MSG = ' taken on this call before reaching TOUT '
8069 ! CALL XERRWD (MSG, 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0)
8070 ! ISTATE = -1
8071 ! GO TO 580
8072 ! EWT(i) .le. 0.0 for some i (not at start of problem). ----------------
8073 ! 510 EWTI = RWORK(LEWT+I-1)
8074 ! MSG = 'DLSODPK- At T (=R1), EWT(I1) has become R2 <= 0. '
8075 ! CALL XERRWD (MSG, 50, 202, 0, 1, I, 0, 2, TN, EWTI)
8076 ! ISTATE = -6
8077 ! GO TO 580
8078 ! Too much accuracy requested for machine precision. -------------------
8079 ! 520 MSG = 'DLSODPK- At T (=R1), too much accuracy requested '
8080 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
8081 ! MSG = ' for precision of machine.. See TOLSF (=R2) '
8082 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
8083 ! RWORK(14) = TOLSF
8084 ! ISTATE = -2
8085 ! GO TO 580
8086 ! KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
8087 ! 530 MSG = 'DLSODPK- At T(=R1), step size H(=R2), the error '
8088 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
8089 ! MSG = ' test failed repeatedly or with ABS(H) = HMIN'
8090 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 2, TN, H)
8091 ! ISTATE = -4
8092 ! GO TO 560
8093 ! KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
8094 ! 540 MSG = 'DLSODPK- At T (=R1) and step size H (=R2), the '
8095 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
8096 ! MSG = ' corrector convergence failed repeatedly '
8097 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
8098 ! MSG = ' or with ABS(H) = HMIN '
8099 ! CALL XERRWD (MSG, 30, 205, 0, 0, 0, 0, 2, TN, H)
8100 ! ISTATE = -5
8101 ! GO TO 560
8102 ! KFLAG = -3. Unrecoverable error from PSOL. --------------------------
8103 ! 550 MSG = 'DLSODPK- At T (=R1) an unrecoverable error return'
8104 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
8105 ! MSG = ' was made from Subroutine PSOL '
8106 ! CALL XERRWD (MSG, 40, 205, 0, 0, 0, 0, 1, TN, 0.0D0)
8107 ! ISTATE = -7
8108 ! GO TO 580
8109 ! Compute IMXER if relevant. -------------------------------------------
8110 ! 560 BIG = 0.0D0
8111 ! IMXER = 1
8112 ! DO 570 I = 1,N
8113 ! SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
8114 ! IF (BIG >= SIZE) GO TO 570
8115 ! BIG = SIZE
8116 ! IMXER = I
8117 ! 570 END DO
8118 ! IWORK(16) = IMXER
8119 ! Set Y vector, T, and optional outputs. -------------------------------
8120 ! 580 DO 590 I = 1,N
8121 ! Y(I) = RWORK(I+LYH-1)
8122 ! 590 END DO
8123 ! T = TN
8124 ! RWORK(11) = HU
8125 ! RWORK(12) = H
8126 ! RWORK(13) = TN
8127 ! IWORK(11) = NST
8128 ! IWORK(12) = NFE
8129 ! IWORK(13) = NJE
8130 ! IWORK(14) = NQU
8131 ! IWORK(15) = NQ
8132 ! IWORK(19) = NNI
8133 ! IWORK(20) = NLI
8134 ! IWORK(21) = NPS
8135 ! IWORK(22) = NCFN
8136 ! IWORK(23) = NCFL
8137 ! RETURN
8138 !-----------------------------------------------------------------------
8139 ! Block I.
8140 ! The following block handles all error returns due to illegal input
8141 ! (ISTATE = -3), as detected before calling the core integrator.
8142 ! First the error message routine is called. If the illegal input
8143 ! is a negative ISTATE, the run is aborted (apparent infinite loop).
8144 !-----------------------------------------------------------------------
8145 ! 601 MSG = 'DLSODPK- ISTATE(=I1) illegal.'
8146 ! CALL XERRWD (MSG, 30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0)
8147 ! IF (ISTATE < 0) GO TO 800
8148 ! GO TO 700
8149 ! 602 MSG = 'DLSODPK- ITASK (=I1) illegal.'
8150 ! CALL XERRWD (MSG, 30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0)
8151 ! GO TO 700
8152 ! 603 MSG = 'DLSODPK- ISTATE > 1 but DLSODPK not initialized.'
8153 ! CALL XERRWD (MSG, 50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
8154 ! GO TO 700
8155 ! 604 MSG = 'DLSODPK- NEQ (=I1) < 1 '
8156 ! CALL XERRWD (MSG, 30, 4, 0, 1, NEQ(1), 0, 0, 0.0D0, 0.0D0)
8157 ! GO TO 700
8158 ! 605 MSG = 'DLSODPK- ISTATE = 3 and NEQ increased (I1 to I2).'
8159 ! CALL XERRWD (MSG, 50, 5, 0, 2, N, NEQ(1), 0, 0.0D0, 0.0D0)
8160 ! GO TO 700
8161 ! 606 MSG = 'DLSODPK- ITOL (=I1) illegal. '
8162 ! CALL XERRWD (MSG, 30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0)
8163 ! GO TO 700
8164 ! 607 MSG = 'DLSODPK- IOPT (=I1) illegal. '
8165 ! CALL XERRWD (MSG, 30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0)
8166 ! GO TO 700
8167 ! 608 MSG = 'DLSODPK- MF (=I1) illegal. '
8168 ! CALL XERRWD (MSG, 30, 8, 0, 1, MF, 0, 0, 0.0D0, 0.0D0)
8169 ! GO TO 700
8170 ! 611 MSG = 'DLSODPK- MAXORD (=I1) < 0 '
8171 ! CALL XERRWD (MSG, 30, 11, 0, 1, MAXORD, 0, 0, 0.0D0, 0.0D0)
8172 ! GO TO 700
8173 ! 612 MSG = 'DLSODPK- MXSTEP (=I1) < 0 '
8174 ! CALL XERRWD (MSG, 30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0)
8175 ! GO TO 700
8176 ! 613 MSG = 'DLSODPK- MXHNIL (=I1) < 0 '
8177 ! CALL XERRWD (MSG, 30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
8178 ! GO TO 700
8179 ! 614 MSG = 'DLSODPK- TOUT (=R1) behind T (=R2) '
8180 ! CALL XERRWD (MSG, 40, 14, 0, 0, 0, 0, 2, TOUT, T)
8181 ! MSG = ' Integration direction is given by H0 (=R1) '
8182 ! CALL XERRWD (MSG, 50, 14, 0, 0, 0, 0, 1, H0, 0.0D0)
8183 ! GO TO 700
8184 ! 615 MSG = 'DLSODPK- HMAX (=R1) < 0.0 '
8185 ! CALL XERRWD (MSG, 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0)
8186 ! GO TO 700
8187 ! 616 MSG = 'DLSODPK- HMIN (=R1) < 0.0 '
8188 ! CALL XERRWD (MSG, 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0)
8189 ! GO TO 700
8190 ! 617 MSG='DLSODPK- RWORK length needed, LENRW(=I1), exceeds LRW(=I2) '
8191 ! CALL XERRWD (MSG, 60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
8192 ! GO TO 700
8193 ! 618 MSG='DLSODPK- IWORK length needed, LENIW(=I1), exceeds LIW(=I2) '
8194 ! CALL XERRWD (MSG, 60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
8195 ! GO TO 700
8196 ! 619 MSG = 'DLSODPK- RTOL(I1) is R1 < 0.0 '
8197 ! CALL XERRWD (MSG, 40, 19, 0, 1, I, 0, 1, RTOLI, 0.0D0)
8198 ! GO TO 700
8199 ! 620 MSG = 'DLSODPK- ATOL(I1) is R1 < 0.0 '
8200 ! CALL XERRWD (MSG, 40, 20, 0, 1, I, 0, 1, ATOLI, 0.0D0)
8201 ! GO TO 700
8202 ! 621 EWTI = RWORK(LEWT+I-1)
8203 ! MSG = 'DLSODPK- EWT(I1) is R1 <= 0.0 '
8204 ! CALL XERRWD (MSG, 40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0)
8205 ! GO TO 700
8206 ! 622 MSG='DLSODPK- TOUT(=R1) too close to T(=R2) to start integration.'
8207 ! CALL XERRWD (MSG, 60, 22, 0, 0, 0, 0, 2, TOUT, T)
8208 ! GO TO 700
8209 ! 623 MSG='DLSODPK- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
8210 ! CALL XERRWD (MSG, 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
8211 ! GO TO 700
8212 ! 624 MSG='DLSODPK- ITASK = 4 or 5 and TCRIT (=R1) behind TCUR (=R2) '
8213 ! CALL XERRWD (MSG, 60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
8214 ! GO TO 700
8215 ! 625 MSG='DLSODPK- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
8216 ! CALL XERRWD (MSG, 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
8217 ! GO TO 700
8218 ! 626 MSG = 'DLSODPK- At start of problem, too much accuracy '
8219 ! CALL XERRWD (MSG, 50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
8220 ! MSG=' requested for precision of machine.. See TOLSF (=R1) '
8221 ! CALL XERRWD (MSG, 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0)
8222 ! RWORK(14) = TOLSF
8223 ! GO TO 700
8224 ! 627 MSG = 'DLSODPK- Trouble in DINTDY. ITASK = I1, TOUT = R1'
8225 ! CALL XERRWD (MSG, 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0)
8226 ! 700 ISTATE = -3
8227 ! RETURN
8228 ! 800 MSG = 'DLSODPK- Run aborted.. apparent infinite loop. '
8229 ! CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0)
8230 ! RETURN
8231 !----------------------- End of Subroutine DLSODPK ---------------------
8232 ! END SUBROUTINE DLSODPK
8233 ! ECK DLSODKR
8234 ! SUBROUTINE DLSODKR (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK, &
8235 ! ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, PSOL, &
8236 ! MF, G, NG, JROOT)
8237 ! EXTERNAL F, JAC, PSOL, G
8238 ! INTEGER :: NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, MF, &
8239 ! NG, JROOT
8240 ! DOUBLE PRECISION :: Y, T, TOUT, RTOL, ATOL, RWORK
8241 ! DIMENSION NEQ(*), Y(*), RTOL(*), ATOL(*), RWORK(LRW), IWORK(LIW), &
8242 ! JROOT(*)
8243 !-----------------------------------------------------------------------
8244 ! This is the 18 November 2003 version of
8245 ! DLSODKR: Livermore Solver for Ordinary Differential equations,
8246 ! with preconditioned Krylov iteration methods for the
8247 ! Newton correction linear systems, and with Rootfinding.
8248 ! This version is in double precision.
8249 ! DLSODKR solves the initial value problem for stiff or nonstiff
8250 ! systems of first order ODEs,
8251 ! dy/dt = f(t,y) , or, in component form,
8252 ! dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ)) (i = 1,...,NEQ).
8253 ! At the same time, it locates the roots of any of a set of functions
8254 ! g(i) = g(i,t,y(1),...,y(NEQ)) (i = 1,...,ng).
8255 !-----------------------------------------------------------------------
8256 ! Introduction.
8257 ! This is a modification of the DLSODE package, and differs from it
8258 ! in five ways:
8259 ! (a) It uses various preconditioned Krylov subspace iteration methods
8260 ! for the linear algebraic systems that arise in the case of stiff
8261 ! systems. See the introductory notes below.
8262 ! (b) It does automatic switching between functional (fixpoint)
8263 ! iteration and Newton iteration in the corrector iteration.
8264 ! (c) It finds the root of at least one of a set of constraint
8265 ! functions g(i) of the independent and dependent variables.
8266 ! It finds only those roots for which some g(i), as a function
8267 ! of t, changes sign in the interval of integration.
8268 ! It then returns the solution at the root, if that occurs
8269 ! sooner than the specified stop condition, and otherwise returns
8270 ! the solution according the specified stop condition.
8271 ! (d) It supplies to JAC an input flag, JOK, which indicates whether
8272 ! JAC may (optionally) bypass the evaluation of Jacobian matrix data
8273 ! and instead process saved data (with the current value of scalar hl0).
8274 ! (e) It contains a new subroutine that calculates the initial step
8275 ! size to be attempted.
8276 ! Introduction to the Krylov methods in DLSODKR:
8277 ! The linear systems that must be solved have the form
8278 ! A * x = b , where A = identity - hl0 * (df/dy) .
8279 ! Here hl0 is a scalar, and df/dy is the Jacobian matrix of partial
8280 ! derivatives of f (NEQ by NEQ).
8281 ! The particular Krylov method is chosen by setting the second digit,
8282 ! MITER, in the method flag MF.
8283 ! Currently, the values of MITER have the following meanings:
8284 ! MITER = 1 means the Scaled Preconditioned Incomplete
8285 ! Orthogonalization Method (SPIOM).
8286 ! 2 means an incomplete version of the preconditioned scaled
8287 ! Generalized Minimal Residual method (SPIGMR).
8288 ! This is the best choice in general.
8289 ! 3 means the Preconditioned Conjugate Gradient method (PCG).
8290 ! Recommended only when df/dy is symmetric or nearly so.
8291 ! 4 means the scaled Preconditioned Conjugate Gradient method
8292 ! (PCGS). Recommended only when D-inverse * df/dy * D is
8293 ! symmetric or nearly so, where D is the diagonal scaling
8294 ! matrix with elements 1/EWT(i) (see RTOL/ATOL description).
8295 ! 9 means that only a user-supplied matrix P (approximating A)
8296 ! will be used, with no Krylov iteration done. This option
8297 ! allows the user to provide the complete linear system
8298 ! solution algorithm, if desired.
8299 ! The user can apply preconditioning to the linear system A*x = b,
8300 ! by means of arbitrary matrices (the preconditioners).
8301 ! In the case of SPIOM and SPIGMR, one can apply left and right
8302 ! preconditioners P1 and P2, and the basic iterative method is then
8303 ! applied to the matrix (P1-inverse)*A*(P2-inverse) instead of to the
8304 ! matrix A. The product P1*P2 should be an approximation to matrix A
8305 ! such that linear systems with P1 or P2 are easier to solve than with
8306 ! A. Preconditioning from the left only or right only means using
8307 ! P2 = identity or P1 = identity, respectively.
8308 ! In the case of the PCG and PCGS methods, there is only one
8309 ! preconditioner matrix P (but it can be the product of more than one).
8310 ! It should approximate the matrix A but allow for relatively
8311 ! easy solution of linear systems with coefficient matrix P.
8312 ! For PCG, P should be positive definite symmetric, or nearly so,
8313 ! and for PCGS, the scaled preconditioner D-inverse * P * D
8314 ! should be symmetric or nearly so.
8315 ! If the Jacobian J = df/dy splits in a natural way into a sum
8316 ! J = J1 + J2, then one possible choice of preconditioners is
8317 ! P1 = identity - hl0 * J1 and P2 = identity - hl0 * J2
8318 ! provided each of these is easy to solve (or approximately solve).
8319 !-----------------------------------------------------------------------
8320 ! References:
8321 ! 1. Peter N. Brown and Alan C. Hindmarsh, Reduced Storage Matrix
8322 ! Methods in Stiff ODE Systems, J. Appl. Math. & Comp., 31 (1989),
8323 ! pp. 40-91; also L.L.N.L. Report UCRL-95088, Rev. 1, June 1987.
8324 ! 2. Alan C. Hindmarsh, ODEPACK, A Systematized Collection of ODE
8325 ! Solvers, in Scientific Computing, R. S. Stepleman et al. (Eds.),
8326 ! North-Holland, Amsterdam, 1983, pp. 55-64.
8327 !-----------------------------------------------------------------------
8328 ! Authors: Alan C. Hindmarsh and Peter N. Brown
8329 ! Center for Applied Scientific Computing, L-561
8330 ! Lawrence Livermore National Laboratory
8331 ! Livermore, CA 94551
8332 !-----------------------------------------------------------------------
8333 ! Summary of Usage.
8334 ! Communication between the user and the DLSODKR package, for normal
8335 ! situations, is summarized here. This summary describes only a subset
8336 ! of the full set of options available. See the full description for
8337 ! details, including optional communication, nonstandard options,
8338 ! and instructions for special situations. See also the demonstration
8339 ! program distributed with this solver.
8340 ! A. First provide a subroutine of the form:
8341 ! SUBROUTINE F (NEQ, T, Y, YDOT)
8342 ! DOUBLE PRECISION T, Y(*), YDOT(*)
8343 ! which supplies the vector function f by loading YDOT(i) with f(i).
8344 ! B. Provide a subroutine of the form:
8345 ! SUBROUTINE G (NEQ, T, Y, NG, GOUT)
8346 ! DOUBLE PRECISION T, Y(*), GOUT(NG)
8347 ! which supplies the vector function g by loading GOUT(i) with
8348 ! g(i), the i-th constraint function whose root is sought.
8349 ! C. Next determine (or guess) whether or not the problem is stiff.
8350 ! Stiffness occurs when the Jacobian matrix df/dy has an eigenvalue
8351 ! whose real part is negative and large in magnitude, compared to the
8352 ! reciprocal of the t span of interest. If the problem is nonstiff,
8353 ! use a method flag MF = 10. If it is stiff, MF should be between 21
8354 ! and 24, or possibly 29. MF = 22 is generally the best choice.
8355 ! Use 23 or 24 only if symmetry is present. Use MF = 29 if the
8356 ! complete linear system solution is to be provided by the user.
8357 ! The following four parameters must also be set.
8358 ! IWORK(1) = LWP = length of real array WP for preconditioning.
8359 ! IWORK(2) = LIWP = length of integer array IWP for preconditioning.
8360 ! IWORK(3) = JPRE = preconditioner type flag:
8361 ! = 0 for no preconditioning (P1 = P2 = P = identity)
8362 ! = 1 for left-only preconditioning (P2 = identity)
8363 ! = 2 for right-only preconditioning (P1 = identity)
8364 ! = 3 for two-sided preconditioning (and PCG or PCGS)
8365 ! IWORK(4) = JACFLG = flag for whether JAC is called.
8366 ! = 0 if JAC is not to be called,
8367 ! = 1 if JAC is to be called.
8368 ! Use JACFLG = 1 if JAC computes any nonconstant data for use in
8369 ! preconditioning, such as Jacobian elements.
8370 ! The arrays WP and IWP are work arrays under the user's control,
8371 ! for use in the routines that perform preconditioning operations.
8372 ! D. If the problem is stiff, you must supply two routines that deal
8373 ! with the preconditioning of the linear systems to be solved.
8374 ! These are as follows:
8375 ! SUBROUTINE JAC (F, NEQ, T, Y, YSV, REWT, FTY,V,HL0,JOK,WP,IWP,IER)
8376 ! DOUBLE PRECISION T, Y(*), YSV(*), REWT(*), FTY(*), V(*), HL0,WP(*)
8377 ! INTEGER IWP(*)
8378 ! This routine must evaluate and preprocess any parts of the
8379 ! Jacobian matrix df/dy involved in the preconditioners P1, P2, P.
8380 ! The Y and FTY arrays contain the current values of y and f(t,y),
8381 ! respectively, and YSV also contains the current value of y.
8382 ! The array V is work space of length NEQ.
8383 ! JAC must multiply all computed Jacobian elements by the scalar
8384 ! -HL0, add the identity matrix, and do any factorization
8385 ! operations called for, in preparation for solving linear systems
8386 ! with a coefficient matrix of P1, P2, or P. The matrix P1*P2 or P
8387 ! should be an approximation to identity - hl0 * (df/dy).
8388 ! JAC should return IER = 0 if successful, and IER .ne. 0 if not.
8389 ! (If IER .ne. 0, a smaller time step will be tried.)
8390 ! JAC may alter Y and V, but not YSV, REWT, FTY, or HL0.
8391 ! The JOK argument can be ignored (or see full description below).
8392 ! SUBROUTINE PSOL (NEQ, T, Y, FTY, WK, HL0, WP, IWP, B, LR, IER)
8393 ! DOUBLE PRECISION T, Y(*), FTY(*), WK(*), HL0, WP(*), B(*)
8394 ! INTEGER IWP(*)
8395 ! This routine must solve a linear system with B as right-hand
8396 ! side and one of the preconditioning matrices, P1, P2, or P, as
8397 ! coefficient matrix, and return the solution vector in B.
8398 ! LR is a flag concerning left vs right preconditioning, input
8399 ! to PSOL. PSOL is to use P1 if LR = 1 and P2 if LR = 2.
8400 ! In the case of the PCG or PCGS method, LR will be 3, and PSOL
8401 ! should solve the system P*x = B with the preconditioner matrix P.
8402 ! In the case MF = 29 (no Krylov iteration), LR will be 0,
8403 ! and PSOL is to return in B the desired approximate solution
8404 ! to A * x = B, where A = identity - hl0 * (df/dy).
8405 ! PSOL can use data generated in the JAC routine and stored in
8406 ! WP and IWP. WK is a work array of length NEQ.
8407 ! The argument HL0 is the current value of the scalar appearing
8408 ! in the linear system. If the old value, at the time of the last
8409 ! JAC call, is needed, it must have been saved by JAC in WP.
8410 ! on return, PSOL should set the error flag IER as follows:
8411 ! IER = 0 if PSOL was successful,
8412 ! IER .gt. 0 if a recoverable error occurred, meaning that the
8413 ! time step will be retried,
8414 ! IER .lt. 0 if an unrecoverable error occurred, meaning that the
8415 ! solver is to stop immediately.
8416 ! E. Write a main program which calls Subroutine DLSODKR once for
8417 ! each point at which answers are desired. This should also provide
8418 ! for possible use of logical unit 6 for output of error messages
8419 ! by DLSODKR. On the first call to DLSODKR, supply arguments as
8420 ! follows:
8421 ! F = name of subroutine for right-hand side vector f.
8422 ! This name must be declared External in calling program.
8423 ! NEQ = number of first order ODEs.
8424 ! Y = array of initial values, of length NEQ.
8425 ! T = the initial value of the independent variable.
8426 ! TOUT = first point where output is desired (.ne. T).
8427 ! ITOL = 1 or 2 according as ATOL (below) is a scalar or array.
8428 ! RTOL = relative tolerance parameter (scalar).
8429 ! ATOL = absolute tolerance parameter (scalar or array).
8430 ! The estimated local error in y(i) will be controlled so as
8431 ! to be roughly less (in magnitude) than
8432 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or
8433 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2.
8434 ! Thus the local error test passes if, in each component,
8435 ! either the absolute error is less than ATOL (or ATOL(i)),
8436 ! or the relative error is less than RTOL.
8437 ! Use RTOL = 0.0 for pure absolute error control, and
8438 ! use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative error
8439 ! control. Caution: Actual (global) errors may exceed these
8440 ! local tolerances, so choose them conservatively.
8441 ! ITASK = 1 for normal computation of output values of y at t = TOUT.
8442 ! ISTATE = integer flag (input and output). Set ISTATE = 1.
8443 ! IOPT = 0 to indicate no optional inputs used.
8444 ! RWORK = real work array of length at least:
8445 ! 20 + 16*NEQ + 3*NG for MF = 10,
8446 ! 45 + 17*NEQ + 3*NG + LWP for MF = 21,
8447 ! 61 + 17*NEQ + 3*NG + LWP for MF = 22,
8448 ! 20 + 15*NEQ + 3*NG + LWP for MF = 23 or 24,
8449 ! 20 + 12*NEQ + 3*NG + LWP for MF = 29.
8450 ! LRW = declared length of RWORK (in user's dimension).
8451 ! IWORK = integer work array of length at least:
8452 ! 30 for MF = 10,
8453 ! 35 + LIWP for MF = 21,
8454 ! 30 + LIWP for MF = 22, 23, 24, or 29.
8455 ! LIW = declared length of IWORK (in user's dimension).
8456 ! JAC,PSOL = names of subroutines for preconditioning.
8457 ! These names must be declared External in the calling program.
8458 ! MF = method flag. Standard values are:
8459 ! 10 for nonstiff (Adams) method.
8460 ! 21 for stiff (BDF) method, with preconditioned SIOM.
8461 ! 22 for stiff method, with preconditioned GMRES method.
8462 ! 23 for stiff method, with preconditioned CG method.
8463 ! 24 for stiff method, with scaled preconditioned CG method.
8464 ! 29 for stiff method, with user's PSOL routine only.
8465 ! G = name of subroutine for constraint functions, whose
8466 ! roots are desired during the integration.
8467 ! This name must be declared External in calling program.
8468 ! NG = number of constraint functions g(i). If there are none,
8469 ! set NG = 0, and pass a dummy name for G.
8470 ! JROOT = integer array of length NG for output of root information.
8471 ! See next paragraph.
8472 ! Note that the main program must declare arrays Y, RWORK, IWORK,
8473 ! JROOT, and possibly ATOL.
8474 ! F. The output from the first call (or any call) is:
8475 ! Y = array of computed values of y(t) vector.
8476 ! T = corresponding value of independent variable (normally TOUT).
8477 ! ISTATE = 2 or 3 if DLSODKR was successful, negative otherwise.
8478 ! 2 means no root was found, and TOUT was reached as desired.
8479 ! 3 means a root was found prior to reaching TOUT.
8480 ! -1 means excess work done on this call (perhaps wrong MF).
8481 ! -2 means excess accuracy requested (tolerances too small).
8482 ! -3 means illegal input detected (see printed message).
8483 ! -4 means repeated error test failures (check all inputs).
8484 ! -5 means repeated convergence failures (perhaps bad JAC
8485 ! or PSOL routine supplied or wrong choice of MF or
8486 ! tolerances, or this solver is inappropriate).
8487 ! -6 means error weight became zero during problem. (Solution
8488 ! component i vanished, and ATOL or ATOL(i) = 0.)
8489 ! -7 means an unrecoverable error occurred in PSOL.
8490 ! JROOT = array showing roots found if ISTATE = 3 on return.
8491 ! JROOT(i) = 1 if g(i) has a root at T, or 0 otherwise.
8492 ! G. To continue the integration after a successful return, proceed
8493 ! as follows:
8494 ! (a) If ISTATE = 2 on return, reset TOUT and call DLSODKR again.
8495 ! (b) If ISTATE = 3 on return, reset ISTATE to 2 and call DLSODKR again.
8496 ! In either case, no other parameters need be reset.
8497 !-----------------------------------------------------------------------
8498 !-----------------------------------------------------------------------
8499 ! Full Description of User Interface to DLSODKR.
8500 ! The user interface to DLSODKR consists of the following parts.
8501 ! 1. The call sequence to Subroutine DLSODKR, which is a driver
8502 ! routine for the solver. This includes descriptions of both
8503 ! the call sequence arguments and of user-supplied routines.
8504 ! Following these descriptions is a description of
8505 ! optional inputs available through the call sequence, and then
8506 ! a description of optional outputs (in the work arrays).
8507 ! 2. Descriptions of other routines in the DLSODKR package that may be
8508 ! (optionally) called by the user. These provide the ability to
8509 ! alter error message handling, save and restore the internal
8510 ! Common, and obtain specified derivatives of the solution y(t).
8511 ! 3. Descriptions of Common blocks to be declared in overlay
8512 ! or similar environments, or to be saved when doing an interrupt
8513 ! of the problem and continued solution later.
8514 ! 4. Description of two routines in the DLSODKR package, either of
8515 ! which the user may replace with his/her own version, if desired.
8516 ! These relate to the measurement of errors.
8517 !-----------------------------------------------------------------------
8518 ! Part 1. Call Sequence.
8519 ! The call sequence parameters used for input only are
8520 ! F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC, PSOL, MF,
8521 ! G, and NG,
8522 ! that used only for output is JROOT,
8523 ! and those used for both input and output are
8524 ! Y, T, ISTATE.
8525 ! The work arrays RWORK and IWORK are also used for conditional and
8526 ! optional inputs and optional outputs. (The term output here refers
8527 ! to the return from Subroutine DLSODKR to the user's calling program.)
8528 ! The legality of input parameters will be thoroughly checked on the
8529 ! initial call for the problem, but not checked thereafter unless a
8530 ! change in input parameters is flagged by ISTATE = 3 on input.
8531 ! The descriptions of the call arguments are as follows.
8532 ! F = the name of the user-supplied subroutine defining the
8533 ! ODE system. The system must be put in the first-order
8534 ! form dy/dt = f(t,y), where f is a vector-valued function
8535 ! of the scalar t and the vector y. Subroutine F is to
8536 ! compute the function f. It is to have the form
8537 ! SUBROUTINE F (NEQ, T, Y, YDOT)
8538 ! DOUBLE PRECISION T, Y(*), YDOT(*)
8539 ! where NEQ, T, and Y are input, and the array YDOT = f(t,y)
8540 ! is output. Y and YDOT are arrays of length NEQ.
8541 ! Subroutine F should not alter Y(1),...,Y(NEQ).
8542 ! F must be declared External in the calling program.
8543 ! Subroutine F may access user-defined quantities in
8544 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
8545 ! (dimensioned in F) and/or Y has length exceeding NEQ(1).
8546 ! See the descriptions of NEQ and Y below.
8547 ! If quantities computed in the F routine are needed
8548 ! externally to DLSODKR, an extra call to F should be made
8549 ! for this purpose, for consistent and accurate results.
8550 ! If only the derivative dy/dt is needed, use DINTDY instead.
8551 ! NEQ = the size of the ODE system (number of first order
8552 ! ordinary differential equations). Used only for input.
8553 ! NEQ may be decreased, but not increased, during the problem.
8554 ! If NEQ is decreased (with ISTATE = 3 on input), the
8555 ! remaining components of Y should be left undisturbed, if
8556 ! these are to be accessed in the user-supplied routines.
8557 ! Normally, NEQ is a scalar, and it is generally referred to
8558 ! as a scalar in this user interface description. However,
8559 ! NEQ may be an array, with NEQ(1) set to the system size.
8560 ! (The DLSODKR package accesses only NEQ(1).) In either case,
8561 ! this parameter is passed as the NEQ argument in all calls
8562 ! to the user-supplied routines. Hence, if it is an array,
8563 ! locations NEQ(2),... may be used to store other integer data
8564 ! and pass it to the user-supplied routines. Each such routine
8565 ! must include NEQ in a Dimension statement in that case.
8566 ! Y = a real array for the vector of dependent variables, of
8567 ! length NEQ or more. Used for both input and output on the
8568 ! first call (ISTATE = 1), and only for output on other calls.
8569 ! On the first call, Y must contain the vector of initial
8570 ! values. On output, Y contains the computed solution vector,
8571 ! evaluated at T. If desired, the Y array may be used
8572 ! for other purposes between calls to the solver.
8573 ! This array is passed as the Y argument in all calls to F, G,
8574 ! JAC, and PSOL. Hence its length may exceed NEQ, and
8575 ! locations Y(NEQ+1),... may be used to store other real data
8576 ! and pass it to the user-supplied routines.
8577 ! (The DLSODKR package accesses only Y(1),...,Y(NEQ).)
8578 ! T = the independent variable. On input, T is used only on the
8579 ! first call, as the initial point of the integration.
8580 ! On output, after each call, T is the value at which a
8581 ! computed solution y is evaluated (usually the same as TOUT).
8582 ! If a root was found, T is the computed location of the
8583 ! root reached first, on output.
8584 ! On an error return, T is the farthest point reached.
8585 ! TOUT = the next value of t at which a computed solution is desired.
8586 ! Used only for input.
8587 ! When starting the problem (ISTATE = 1), TOUT may be equal
8588 ! to T for one call, then should .ne. T for the next call.
8589 ! For the initial T, an input value of TOUT .ne. T is used
8590 ! in order to determine the direction of the integration
8591 ! (i.e. the algebraic sign of the step sizes) and the rough
8592 ! scale of the problem. Integration in either direction
8593 ! (forward or backward in t) is permitted.
8594 ! If ITASK = 2 or 5 (one-step modes), TOUT is ignored after
8595 ! the first call (i.e. the first call with TOUT .ne. T).
8596 ! Otherwise, TOUT is required on every call.
8597 ! If ITASK = 1, 3, or 4, the values of TOUT need not be
8598 ! monotone, but a value of TOUT which backs up is limited
8599 ! to the current internal T interval, whose endpoints are
8600 ! TCUR - HU and TCUR (see optional outputs, below, for
8601 ! TCUR and HU).
8602 ! ITOL = an indicator for the type of error control. See
8603 ! description below under ATOL. Used only for input.
8604 ! RTOL = a relative error tolerance parameter, either a scalar or
8605 ! an array of length NEQ. See description below under ATOL.
8606 ! Input only.
8607 ! ATOL = an absolute error tolerance parameter, either a scalar or
8608 ! an array of length NEQ. Input only.
8609 ! The input parameters ITOL, RTOL, and ATOL determine
8610 ! the error control performed by the solver. The solver will
8611 ! control the vector E = (E(i)) of estimated local errors
8612 ! in y, according to an inequality of the form
8613 ! RMS-norm of ( E(i)/EWT(i) ) .le. 1,
8614 ! where EWT(i) = RTOL(i)*ABS(Y(i)) + ATOL(i),
8615 ! and the RMS-norm (root-mean-square norm) here is
8616 ! RMS-norm(v) = SQRT(sum v(i)**2 / NEQ). Here EWT = (EWT(i))
8617 ! is a vector of weights which must always be positive, and
8618 ! the values of RTOL and ATOL should all be non-negative.
8619 ! The following table gives the types (scalar/array) of
8620 ! RTOL and ATOL, and the corresponding form of EWT(i).
8621 ! ITOL RTOL ATOL EWT(i)
8622 ! 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
8623 ! 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
8624 ! 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
8625 ! 4 array array RTOL(i)*ABS(Y(i)) + ATOL(i)
8626 ! When either of these parameters is a scalar, it need not
8627 ! be dimensioned in the user's calling program.
8628 ! If none of the above choices (with ITOL, RTOL, and ATOL
8629 ! fixed throughout the problem) is suitable, more general
8630 ! error controls can be obtained by substituting
8631 ! user-supplied routines for the setting of EWT and/or for
8632 ! the norm calculation. See Part 4 below.
8633 ! If global errors are to be estimated by making a repeated
8634 ! run on the same problem with smaller tolerances, then all
8635 ! components of RTOL and ATOL (i.e. of EWT) should be scaled
8636 ! down uniformly.
8637 ! ITASK = an index specifying the task to be performed.
8638 ! Input only. ITASK has the following values and meanings.
8639 ! 1 means normal computation of output values of y(t) at
8640 ! t = TOUT (by overshooting and interpolating).
8641 ! 2 means take one step only and return.
8642 ! 3 means stop at the first internal mesh point at or
8643 ! beyond t = TOUT and return.
8644 ! 4 means normal computation of output values of y(t) at
8645 ! t = TOUT but without overshooting t = TCRIT.
8646 ! TCRIT must be input as RWORK(1). TCRIT may be equal to
8647 ! or beyond TOUT, but not behind it in the direction of
8648 ! integration. This option is useful if the problem
8649 ! has a singularity at or beyond t = TCRIT.
8650 ! 5 means take one step, without passing TCRIT, and return.
8651 ! TCRIT must be input as RWORK(1).
8652 ! Note: If ITASK = 4 or 5 and the solver reaches TCRIT
8653 ! (within roundoff), it will return T = TCRIT (exactly) to
8654 ! indicate this (unless ITASK = 4 and TOUT comes before TCRIT,
8655 ! in which case answers at T = TOUT are returned first).
8656 ! ISTATE = an index used for input and output to specify the
8657 ! the state of the calculation.
8658 ! On input, the values of ISTATE are as follows.
8659 ! 1 means this is the first call for the problem
8660 ! (initializations will be done). See note below.
8661 ! 2 means this is not the first call, and the calculation
8662 ! is to continue normally, with no change in any input
8663 ! parameters except possibly TOUT and ITASK.
8664 ! (If ITOL, RTOL, and/or ATOL are changed between calls
8665 ! with ISTATE = 2, the new values will be used but not
8666 ! tested for legality.)
8667 ! 3 means this is not the first call, and the
8668 ! calculation is to continue normally, but with
8669 ! a change in input parameters other than
8670 ! TOUT and ITASK. Changes are allowed in
8671 ! NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF,
8672 ! and any of the optional inputs except H0.
8673 ! In addition, immediately following a return with
8674 ! ISTATE = 3 (root found), NG and G may be changed.
8675 ! (But changing NG from 0 to .gt. 0 is not allowed.)
8676 ! Note: A preliminary call with TOUT = T is not counted
8677 ! as a first call here, as no initialization or checking of
8678 ! input is done. (Such a call is sometimes useful for the
8679 ! purpose of outputting the initial conditions.)
8680 ! Thus the first call for which TOUT .ne. T requires
8681 ! ISTATE = 1 on input.
8682 ! On output, ISTATE has the following values and meanings.
8683 ! 1 means nothing was done; TOUT = T and ISTATE = 1 on input.
8684 ! 2 means the integration was performed successfully.
8685 ! 3 means the integration was successful, and one or more
8686 ! roots were found before satisfying the stop condition
8687 ! specified by ITASK. See JROOT.
8688 ! -1 means an excessive amount of work (more than MXSTEP
8689 ! steps) was done on this call, before completing the
8690 ! requested task, but the integration was otherwise
8691 ! successful as far as T. (MXSTEP is an optional input
8692 ! and is normally 500.) To continue, the user may
8693 ! simply reset ISTATE to a value .gt. 1 and call again
8694 ! (the excess work step counter will be reset to 0).
8695 ! In addition, the user may increase MXSTEP to avoid
8696 ! this error return (see below on optional inputs).
8697 ! -2 means too much accuracy was requested for the precision
8698 ! of the machine being used. This was detected before
8699 ! completing the requested task, but the integration
8700 ! was successful as far as T. To continue, the tolerance
8701 ! parameters must be reset, and ISTATE must be set
8702 ! to 3. The optional output TOLSF may be used for this
8703 ! purpose. (Note: If this condition is detected before
8704 ! taking any steps, then an illegal input return
8705 ! (ISTATE = -3) occurs instead.)
8706 ! -3 means illegal input was detected, before taking any
8707 ! integration steps. See written message for details.
8708 ! Note: If the solver detects an infinite loop of calls
8709 ! to the solver with illegal input, it will cause
8710 ! the run to stop.
8711 ! -4 means there were repeated error test failures on
8712 ! one attempted step, before completing the requested
8713 ! task, but the integration was successful as far as T.
8714 ! The problem may have a singularity, or the input
8715 ! may be inappropriate.
8716 ! -5 means there were repeated convergence test failures on
8717 ! one attempted step, before completing the requested
8718 ! task, but the integration was successful as far as T.
8719 ! -6 means EWT(i) became zero for some i during the
8720 ! integration. Pure relative error control (ATOL(i)=0.0)
8721 ! was requested on a variable which has now vanished.
8722 ! The integration was successful as far as T.
8723 ! -7 means the PSOL routine returned an unrecoverable error
8724 ! flag (IER .lt. 0). The integration was successful as
8725 ! far as T.
8726 ! Note: Since the normal output value of ISTATE is 2,
8727 ! it does not need to be reset for normal continuation.
8728 ! Also, since a negative input value of ISTATE will be
8729 ! regarded as illegal, a negative output value requires the
8730 ! user to change it, and possibly other inputs, before
8731 ! calling the solver again.
8732 ! IOPT = an integer flag to specify whether or not any optional
8733 ! inputs are being used on this call. Input only.
8734 ! The optional inputs are listed separately below.
8735 ! IOPT = 0 means no optional inputs are being used.
8736 ! Default values will be used in all cases.
8737 ! IOPT = 1 means one or more optional inputs are being used.
8738 ! RWORK = a real working array (double precision).
8739 ! The length of RWORK must be at least
8740 ! 20 + NYH*(MAXORD+1) + 3*NEQ + 3*NG + LENLS + LWP where
8741 ! NYH = the initial value of NEQ,
8742 ! MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a
8743 ! smaller value is given as an optional input),
8744 ! LENLS = length of work space for linear system (Krylov)
8745 ! method, excluding preconditioning:
8746 ! LENLS = 0 if MITER = 0,
8747 ! LENLS = NEQ*(MAXL+3) + MAXL**2 if MITER = 1,
8748 ! LENLS = NEQ*(MAXL+3+MIN(1,MAXL-KMP))
8749 ! + (MAXL+3)*MAXL + 1 if MITER = 2,
8750 ! LENLS = 6*NEQ if MITER = 3 or 4,
8751 ! LENLS = 3*NEQ if MITER = 9.
8752 ! (See the MF description for METH and MITER, and the
8753 ! list of optional inputs for MAXL and KMP.)
8754 ! LWP = length of real user work space for preconditioning
8755 ! (see JAC/PSOL).
8756 ! Thus if default values are used and NEQ is constant,
8757 ! this length is:
8758 ! 20 + 16*NEQ + 3*NG for MF = 10,
8759 ! 45 + 24*NEQ + 3*NG + LWP for MF = 11,
8760 ! 61 + 24*NEQ + 3*NG + LWP for MF = 12,
8761 ! 20 + 22*NEQ + 3*NG + LWP for MF = 13 or 14,
8762 ! 20 + 19*NEQ + 3*NG + LWP for MF = 19,
8763 ! 20 + 9*NEQ + 3*NG for MF = 20,
8764 ! 45 + 17*NEQ + 3*NG + LWP for MF = 21,
8765 ! 61 + 17*NEQ + 3*NG + LWP for MF = 22,
8766 ! 20 + 15*NEQ + 3*NG + LWP for MF = 23 or 24,
8767 ! 20 + 12*NEQ + 3*NG + LWP for MF = 29.
8768 ! The first 20 words of RWORK are reserved for conditional
8769 ! and optional inputs and optional outputs.
8770 ! The following word in RWORK is a conditional input:
8771 ! RWORK(1) = TCRIT = critical value of t which the solver
8772 ! is not to overshoot. Required if ITASK is
8773 ! 4 or 5, and ignored otherwise. (See ITASK.)
8774 ! LRW = the length of the array RWORK, as declared by the user.
8775 ! (This will be checked by the solver.)
8776 ! IWORK = an integer work array. The length of IWORK must be at least
8777 ! 30 if MITER = 0 (MF = 10 or 20),
8778 ! 30 + MAXL + LIWP if MITER = 1 (MF = 11, 21),
8779 ! 30 + LIWP if MITER = 2, 3, 4, or 9.
8780 ! MAXL = 5 unless a different optional input value is given.
8781 ! LIWP = length of integer user work space for preconditioning
8782 ! (see conditional input list following).
8783 ! The first few words of IWORK are used for conditional and
8784 ! optional inputs and optional outputs.
8785 ! The following 4 words in IWORK are conditional inputs,
8786 ! required if MITER .ge. 1:
8787 ! IWORK(1) = LWP = length of real array WP for use in
8788 ! preconditioning (part of RWORK array).
8789 ! IWORK(2) = LIWP = length of integer array IWP for use in
8790 ! preconditioning (part of IWORK array).
8791 ! The arrays WP and IWP are work arrays under the
8792 ! user's control, for use in the routines that
8793 ! perform preconditioning operations (JAC and PSOL).
8794 ! IWORK(3) = JPRE = preconditioner type flag:
8795 ! = 0 for no preconditioning (P1 = P2 = P = identity)
8796 ! = 1 for left-only preconditioning (P2 = identity)
8797 ! = 2 for right-only preconditioning (P1 = identity)
8798 ! = 3 for two-sided preconditioning (and PCG or PCGS)
8799 ! IWORK(4) = JACFLG = flag for whether JAC is called.
8800 ! = 0 if JAC is not to be called,
8801 ! = 1 if JAC is to be called.
8802 ! Use JACFLG = 1 if JAC computes any nonconstant
8803 ! data needed in preconditioning operations,
8804 ! such as some of the Jacobian elements.
8805 ! LIW = the length of the array IWORK, as declared by the user.
8806 ! (This will be checked by the solver.)
8807 ! Note: The work arrays must not be altered between calls to DLSODKR
8808 ! for the same problem, except possibly for the conditional and
8809 ! optional inputs, and except for the last 3*NEQ words of RWORK.
8810 ! The latter space is used for internal scratch space, and so is
8811 ! available for use by the user outside DLSODKR between calls, if
8812 ! desired (but not for use by any of the user-supplied routines).
8813 ! JAC = the name of the user-supplied routine to compute any
8814 ! Jacobian elements (or approximations) involved in the
8815 ! matrix preconditioning operations (MITER .ge. 1).
8816 ! It is to have the form
8817 ! SUBROUTINE JAC (F, NEQ, T, Y, YSV, REWT, FTY, V,
8818 ! 1 HL0, JOK, WP, IWP, IER)
8819 ! DOUBLE PRECISION T, Y(*), YSV(*), REWT(*), FTY(*), V(*),
8820 ! 1 HL0, WP(*)
8821 ! INTEGER IWP(*)
8822 ! This routine must evaluate and preprocess any parts of the
8823 ! Jacobian matrix df/dy used in the preconditioners P1, P2, P.
8824 ! The Y and FTY arrays contain the current values of y and
8825 ! f(t,y), respectively, and the YSV array also contains
8826 ! the current y vector. The array V is work space of length
8827 ! NEQ for use by JAC. REWT is the array of reciprocal error
8828 ! weights (1/EWT). JAC must multiply all computed Jacobian
8829 ! elements by the scalar -HL0, add the identity matrix, and do
8830 ! any factorization operations called for, in preparation
8831 ! for solving linear systems with a coefficient matrix of
8832 ! P1, P2, or P. The matrix P1*P2 or P should be an
8833 ! approximation to identity - hl0 * (df/dy). JAC should
8834 ! return IER = 0 if successful, and IER .ne. 0 if not.
8835 ! (If IER .ne. 0, a smaller time step will be tried.)
8836 ! The arrays WP (of length LWP) and IWP (of length LIWP)
8837 ! are for use by JAC and PSOL for work space and for storage
8838 ! of data needed for the solution of the preconditioner
8839 ! linear systems. Their lengths and contents are under the
8840 ! user's control.
8841 ! The argument JOK is an input flag for optional use
8842 ! by JAC in deciding whether to recompute Jacobian elements
8843 ! or use saved values. If JOK = -1, then JAC must compute
8844 ! any relevant Jacobian elements (or approximations) used in
8845 ! the preconditioners. Optionally, JAC may also save these
8846 ! elements for later reuse. If JOK = 1, the integrator has
8847 ! made a judgement (based on the convergence history and the
8848 ! value of HL0) that JAC need not recompute Jacobian elements,
8849 ! but instead use saved values, and the current value of HL0,
8850 ! to reconstruct the preconditioner matrices, followed by
8851 ! any required factorizations. This may be cost-effective if
8852 ! Jacobian elements are costly and storage is available.
8853 ! JAC may alter Y and V, but not YSV, REWT, FTY, or HL0.
8854 ! JAC must be declared External in the calling program.
8855 ! Subroutine JAC may access user-defined quantities in
8856 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
8857 ! (dimensioned in JAC) and/or Y has length exceeding NEQ(1).
8858 ! See the descriptions of NEQ and Y above.
8859 ! PSOL = the name of the user-supplied routine for the
8860 ! solution of preconditioner linear systems.
8861 ! It is to have the form
8862 ! SUBROUTINE PSOL (NEQ, T, Y, FTY, WK,HL0, WP,IWP, B, LR,IER)
8863 ! DOUBLE PRECISION T, Y(*), FTY(*), WK(*), HL0, WP(*), B(*)
8864 ! INTEGER IWP(*)
8865 ! This routine must solve a linear system with B as right-hand
8866 ! side and one of the preconditioning matrices, P1, P2, or P,
8867 ! as coefficient matrix, and return the solution vector in B.
8868 ! LR is a flag concerning left vs right preconditioning, input
8869 ! to PSOL. PSOL is to use P1 if LR = 1 and P2 if LR = 2.
8870 ! In the case of the PCG or PCGS method, LR will be 3, and PSOL
8871 ! should solve the system P*x = B with the preconditioner P.
8872 ! In the case MITER = 9 (no Krylov iteration), LR will be 0,
8873 ! and PSOL is to return in B the desired approximate solution
8874 ! to A * x = B, where A = identity - hl0 * (df/dy).
8875 ! PSOL can use data generated in the JAC routine and stored in
8876 ! WP and IWP.
8877 ! The Y and FTY arrays contain the current values of y and
8878 ! f(t,y), respectively. The array WK is work space of length
8879 ! NEQ for use by PSOL.
8880 ! The argument HL0 is the current value of the scalar appearing
8881 ! in the linear system. If the old value, as of the last
8882 ! JAC call, is needed, it must have been saved by JAC in WP.
8883 ! On return, PSOL should set the error flag IER as follows:
8884 ! IER = 0 if PSOL was successful,
8885 ! IER .gt. 0 on a recoverable error, meaning that the
8886 ! time step will be retried,
8887 ! IER .lt. 0 on an unrecoverable error, meaning that the
8888 ! solver is to stop immediately.
8889 ! PSOL may not alter Y, FTY, or HL0.
8890 ! PSOL must be declared External in the calling program.
8891 ! Subroutine PSOL may access user-defined quantities in
8892 ! NEQ(2),... and Y(NEQ(1)+1),... if NEQ is an array
8893 ! (dimensioned in PSOL) and/or Y has length exceeding NEQ(1).
8894 ! See the descriptions of NEQ and Y above.
8895 ! MF = the method flag. Used only for input. The legal values of
8896 ! MF are 10, 11, 12, 13, 14, 19, 20, 21, 22, 23, 24, and 29.
8897 ! MF has decimal digits METH and MITER: MF = 10*METH + MITER.
8898 ! METH indicates the basic linear multistep method:
8899 ! METH = 1 means the implicit Adams method.
8900 ! METH = 2 means the method based on Backward
8901 ! Differentiation Formulas (BDFs).
8902 ! MITER indicates the corrector iteration method:
8903 ! MITER = 0 means functional iteration (no linear system
8904 ! is involved).
8905 ! MITER = 1 means Newton iteration with Scaled Preconditioned
8906 ! Incomplete Orthogonalization Method (SPIOM)
8907 ! for the linear systems.
8908 ! MITER = 2 means Newton iteration with Scaled Preconditioned
8909 ! Incomplete Generalized Minimal Residual method
8910 ! (SPIGMR) for the linear systems.
8911 ! MITER = 3 means Newton iteration with Preconditioned
8912 ! Conjugate Gradient method (PCG)
8913 ! for the linear systems.
8914 ! MITER = 4 means Newton iteration with scaled preconditioned
8915 ! Conjugate Gradient method (PCGS)
8916 ! for the linear systems.
8917 ! MITER = 9 means Newton iteration with only the
8918 ! user-supplied PSOL routine called (no Krylov
8919 ! iteration) for the linear systems.
8920 ! JPRE is ignored, and PSOL is called with LR = 0.
8921 ! See comments in the introduction about the choice of MITER.
8922 ! If MITER .ge. 1, the user must supply routines JAC and PSOL
8923 ! (the names are arbitrary) as described above.
8924 ! For MITER = 0, a dummy argument can be used.
8925 ! G = the name of subroutine for constraint functions, whose
8926 ! roots are desired during the integration. It is to have
8927 ! the form
8928 ! SUBROUTINE G (NEQ, T, Y, NG, GOUT)
8929 ! DOUBLE PRECISION T, Y(*), GOUT(NG)
8930 ! where NEQ, T, Y, and NG are input, and the array GOUT
8931 ! is output. NEQ, T, and Y have the same meaning as in
8932 ! the F routine, and GOUT is an array of length NG.
8933 ! For i = 1,...,NG, this routine is to load into GOUT(i)
8934 ! the value at (t,y) of the i-th constraint function g(i).
8935 ! DLSODKR will find roots of the g(i) of odd multiplicity
8936 ! (i.e. sign changes) as they occur during the integration.
8937 ! G must be declared External in the calling program.
8938 ! Caution: Because of numerical errors in the functions
8939 ! g(i) due to roundoff and integration error, DLSODKR may
8940 ! return false roots, or return the same root at two or more
8941 ! nearly equal values of t. If such false roots are
8942 ! suspected, the user should consider smaller error tolerances
8943 ! and/or higher precision in the evaluation of the g(i).
8944 ! If a root of some g(i) defines the end of the problem,
8945 ! the input to DLSODKR should nevertheless allow integration
8946 ! to a point slightly past that root, so that DLSODKR can
8947 ! locate the root by interpolation.
8948 ! Subroutine G may access user-defined quantities in
8949 ! NEQ(2),... and Y(NEQ(1)+1),... if NEQ is an array
8950 ! (dimensioned in G) and/or Y has length exceeding NEQ(1).
8951 ! See the descriptions of NEQ and Y above.
8952 ! NG = number of constraint functions g(i). If there are none,
8953 ! set NG = 0, and pass a dummy name for G.
8954 ! JROOT = integer array of length NG. Used only for output.
8955 ! On a return with ISTATE = 3 (one or more roots found),
8956 ! JROOT(i) = 1 if g(i) has a root at t, or JROOT(i) = 0 if not.
8957 !-----------------------------------------------------------------------
8958 ! Optional Inputs.
8959 ! The following is a list of the optional inputs provided for in the
8960 ! call sequence. (See also Part 2.) For each such input variable,
8961 ! this table lists its name as used in this documentation, its
8962 ! location in the call sequence, its meaning, and the default value.
8963 ! The use of any of these inputs requires IOPT = 1, and in that
8964 ! case all of these inputs are examined. A value of zero for any
8965 ! of these optional inputs will cause the default value to be used.
8966 ! Thus to use a subset of the optional inputs, simply preload
8967 ! locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, and
8968 ! then set those of interest to nonzero values.
8969 ! Name Location Meaning and Default Value
8970 ! H0 RWORK(5) the step size to be attempted on the first step.
8971 ! The default value is determined by the solver.
8972 ! HMAX RWORK(6) the maximum absolute step size allowed.
8973 ! The default value is infinite.
8974 ! HMIN RWORK(7) the minimum absolute step size allowed.
8975 ! The default value is 0. (This lower bound is not
8976 ! enforced on the final step before reaching TCRIT
8977 ! when ITASK = 4 or 5.)
8978 ! DELT RWORK(8) convergence test constant in Krylov iteration
8979 ! algorithm. The default is .05.
8980 ! MAXORD IWORK(5) the maximum order to be allowed. The default
8981 ! value is 12 if METH = 1, and 5 if METH = 2.
8982 ! If MAXORD exceeds the default value, it will
8983 ! be reduced to the default value.
8984 ! If MAXORD is changed during the problem, it may
8985 ! cause the current order to be reduced.
8986 ! MXSTEP IWORK(6) maximum number of (internally defined) steps
8987 ! allowed during one call to the solver.
8988 ! The default value is 500.
8989 ! MXHNIL IWORK(7) maximum number of messages printed (per problem)
8990 ! warning that T + H = T on a step (H = step size).
8991 ! This must be positive to result in a non-default
8992 ! value. The default value is 10.
8993 ! MAXL IWORK(8) maximum number of iterations in the SPIOM, SPIGMR,
8994 ! PCG, or PCGS algorithm (.le. NEQ).
8995 ! The default is MAXL = MIN(5,NEQ).
8996 ! KMP IWORK(9) number of vectors on which orthogonalization
8997 ! is done in SPIOM or SPIGMR algorithm (.le. MAXL).
8998 ! The default is KMP = MAXL.
8999 ! Note: When KMP .lt. MAXL and MF = 22, the length
9000 ! of RWORK must be defined accordingly. See
9001 ! the definition of RWORK above.
9002 !-----------------------------------------------------------------------
9003 ! Optional Outputs.
9004 ! As optional additional output from DLSODKR, the variables listed
9005 ! below are quantities related to the performance of DLSODKR
9006 ! which are available to the user. These are communicated by way of
9007 ! the work arrays, but also have internal mnemonic names as shown.
9008 ! Except where stated otherwise, all of these outputs are defined
9009 ! on any successful return from DLSODKR, and on any return with
9010 ! ISTATE = -1, -2, -4, -5, -6, or -7. On an illegal input return
9011 ! (ISTATE = -3), they will be unchanged from their existing values
9012 ! (if any), except possibly for TOLSF, LENRW, and LENIW.
9013 ! On any error return, outputs relevant to the error will be defined,
9014 ! as noted below.
9015 ! Name Location Meaning
9016 ! HU RWORK(11) the step size in t last used (successfully).
9017 ! HCUR RWORK(12) the step size to be attempted on the next step.
9018 ! TCUR RWORK(13) the current value of the independent variable
9019 ! which the solver has actually reached, i.e. the
9020 ! current internal mesh point in t. On output, TCUR
9021 ! will always be at least as far as the argument
9022 ! T, but may be farther (if interpolation was done).
9023 ! TOLSF RWORK(14) a tolerance scale factor, greater than 1.0,
9024 ! computed when a request for too much accuracy was
9025 ! detected (ISTATE = -3 if detected at the start of
9026 ! the problem, ISTATE = -2 otherwise). If ITOL is
9027 ! left unaltered but RTOL and ATOL are uniformly
9028 ! scaled up by a factor of TOLSF for the next call,
9029 ! then the solver is deemed likely to succeed.
9030 ! (The user may also ignore TOLSF and alter the
9031 ! tolerance parameters in any other way appropriate.)
9032 ! NGE IWORK(10) the number of g evaluations for the problem so far.
9033 ! NST IWORK(11) the number of steps taken for the problem so far.
9034 ! NFE IWORK(12) the number of f evaluations for the problem so far.
9035 ! NPE IWORK(13) the number of calls to JAC so far (for evaluation
9036 ! of preconditioners).
9037 ! NQU IWORK(14) the method order last used (successfully).
9038 ! NQCUR IWORK(15) the order to be attempted on the next step.
9039 ! IMXER IWORK(16) the index of the component of largest magnitude in
9040 ! the weighted local error vector ( E(i)/EWT(i) ),
9041 ! on an error return with ISTATE = -4 or -5.
9042 ! LENRW IWORK(17) the length of RWORK actually required.
9043 ! This is defined on normal returns and on an illegal
9044 ! input return for insufficient storage.
9045 ! LENIW IWORK(18) the length of IWORK actually required.
9046 ! This is defined on normal returns and on an illegal
9047 ! input return for insufficient storage.
9048 ! NNI IWORK(19) number of nonlinear iterations so far (each of
9049 ! which calls an iterative linear solver).
9050 ! NLI IWORK(20) number of linear iterations so far.
9051 ! Note: A measure of the success of algorithm is
9052 ! the average number of linear iterations per
9053 ! nonlinear iteration, given by NLI/NNI.
9054 ! If this is close to MAXL, MAXL may be too small.
9055 ! NPS IWORK(21) number of preconditioning solve operations
9056 ! (PSOL calls) so far.
9057 ! NCFN IWORK(22) number of convergence failures of the nonlinear
9058 ! (Newton) iteration so far.
9059 ! Note: A measure of success is the overall
9060 ! rate of nonlinear convergence failures, NCFN/NST.
9061 ! NCFL IWORK(23) number of convergence failures of the linear
9062 ! iteration so far.
9063 ! Note: A measure of success is the overall
9064 ! rate of linear convergence failures, NCFL/NNI.
9065 ! NSFI IWORK(24) number of functional iteration steps so far.
9066 ! Note: A measure of the extent to which the
9067 ! problem is nonstiff is the ratio NSFI/NST.
9068 ! NJEV IWORK(25) number of JAC calls with JOK = -1 so far
9069 ! (number of evaluations of Jacobian data).
9070 ! The following two arrays are segments of the RWORK array which
9071 ! may also be of interest to the user as optional outputs.
9072 ! For each array, the table below gives its internal name,
9073 ! its base address in RWORK, and its description.
9074 ! Name Base Address Description
9075 ! YH 21 + 3*NG the Nordsieck history array, of size NYH by
9076 ! (NQCUR + 1), where NYH is the initial value
9077 ! of NEQ. For j = 0,1,...,NQCUR, column j+1
9078 ! of YH contains HCUR**j/factorial(j) times
9079 ! the j-th derivative of the interpolating
9080 ! polynomial currently representing the solution,
9081 ! evaluated at t = TCUR.
9082 ! ACOR LENRW-NEQ+1 array of size NEQ used for the accumulated
9083 ! corrections on each step, scaled on output
9084 ! to represent the estimated local error in y
9085 ! on the last step. This is the vector E in
9086 ! the description of the error control. It is
9087 ! defined only on a successful return from
9088 ! DLSODKR.
9089 !-----------------------------------------------------------------------
9090 ! Part 2. Other Routines Callable.
9091 ! The following are optional calls which the user may make to
9092 ! gain additional capabilities in conjunction with DLSODKR.
9093 ! (The routines XSETUN and XSETF are designed to conform to the
9094 ! SLATEC error handling package.)
9095 ! Form of Call Function
9096 ! CALL XSETUN(LUN) Set the logical unit number, LUN, for
9097 ! output of messages from DLSODKR, if
9098 ! the default is not desired.
9099 ! The default value of LUN is 6.
9100 ! CALL XSETF(MFLAG) Set a flag to control the printing of
9101 ! messages by DLSODKR.
9102 ! MFLAG = 0 means do not print. (Danger:
9103 ! This risks losing valuable information.)
9104 ! MFLAG = 1 means print (the default).
9105 ! Either of the above calls may be made at
9106 ! any time and will take effect immediately.
9107 ! CALL DSRCKR(RSAV,ISAV,JOB) saves and restores the contents of
9108 ! the internal Common blocks used by
9109 ! DLSODKR (see Part 3 below).
9110 ! RSAV must be a real array of length 228
9111 ! or more, and ISAV must be an integer
9112 ! array of length 63 or more.
9113 ! JOB=1 means save Common into RSAV/ISAV.
9114 ! JOB=2 means restore Common from RSAV/ISAV.
9115 ! DSRCKR is useful if one is
9116 ! interrupting a run and restarting
9117 ! later, or alternating between two or
9118 ! more problems solved with DLSODKR.
9119 ! CALL DINTDY(,,,,,) Provide derivatives of y, of various
9120 ! (see below) orders, at a specified point t, if
9121 ! desired. It may be called only after
9122 ! a successful return from DLSODKR.
9123 ! The detailed instructions for using DINTDY are as follows.
9124 ! The form of the call is:
9125 ! LYH = 21 + 3*NG
9126 ! CALL DINTDY (T, K, RWORK(LYH), NYH, DKY, IFLAG)
9127 ! The input parameters are:
9128 ! T = value of independent variable where answers are desired
9129 ! (normally the same as the T last returned by DLSODKR).
9130 ! For valid results, T must lie between TCUR - HU and TCUR.
9131 ! (See optional outputs for TCUR and HU.)
9132 ! K = integer order of the derivative desired. K must satisfy
9133 ! 0 .le. K .le. NQCUR, where NQCUR is the current order
9134 ! (see optional outputs). The capability corresponding
9135 ! to K = 0, i.e. computing y(T), is already provided
9136 ! by DLSODKR directly. Since NQCUR .ge. 1, the first
9137 ! derivative dy/dt is always available with DINTDY.
9138 ! LYH = 21 + 3*NG = base address in RWORK of the history array YH.
9139 ! NYH = column length of YH, equal to the initial value of NEQ.
9140 ! The output parameters are:
9141 ! DKY = a real array of length NEQ containing the computed value
9142 ! of the K-th derivative of y(t).
9143 ! IFLAG = integer flag, returned as 0 if K and T were legal,
9144 ! -1 if K was illegal, and -2 if T was illegal.
9145 ! On an error return, a message is also written.
9146 !-----------------------------------------------------------------------
9147 ! Part 3. Common Blocks.
9148 ! If DLSODKR is to be used in an overlay situation, the user
9149 ! must declare, in the primary overlay, the variables in:
9150 ! (1) the call sequence to DLSODKR, and
9151 ! (2) the four internal Common blocks
9152 ! /DLS001/ of length 255 (218 double precision words
9153 ! followed by 37 integer words),
9154 ! /DLS002/ of length 5 (1 double precision word
9155 ! followed by 4 integer words),
9156 ! /DLPK01/ of length 17 (4 double precision words
9157 ! followed by 13 integer words),
9158 ! /DLSR01/ of length 14 (5 double precision words
9159 ! followed by 9 integer words).
9160 ! If DLSODKR is used on a system in which the contents of internal
9161 ! Common blocks are not preserved between calls, the user should
9162 ! declare the above Common blocks in the calling program to insure
9163 ! that their contents are preserved.
9164 ! If the solution of a given problem by DLSODKR is to be interrupted
9165 ! and then later continued, such as when restarting an interrupted run
9166 ! or alternating between two or more problems, the user should save,
9167 ! following the return from the last DLSODKR call prior to the
9168 ! interruption, the contents of the call sequence variables and the
9169 ! internal Common blocks, and later restore these values before the
9170 ! next DLSODKR call for that problem. To save and restore the Common
9171 ! blocks, use Subroutine DSRCKR (see Part 2 above).
9172 !-----------------------------------------------------------------------
9173 ! Part 4. Optionally Replaceable Solver Routines.
9174 ! Below are descriptions of two routines in the DLSODKR package which
9175 ! relate to the measurement of errors. Either routine can be
9176 ! replaced by a user-supplied version, if desired. However, since such
9177 ! a replacement may have a major impact on performance, it should be
9178 ! done only when absolutely necessary, and only with great caution.
9179 ! (Note: The means by which the package version of a routine is
9180 ! superseded by the user's version may be system-dependent.)
9181 ! (a) DEWSET.
9182 ! The following subroutine is called just before each internal
9183 ! integration step, and sets the array of error weights, EWT, as
9184 ! described under ITOL/RTOL/ATOL above:
9185 ! SUBROUTINE DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
9186 ! where NEQ, ITOL, RTOL, and ATOL are as in the DLSODKR call sequence,
9187 ! YCUR contains the current dependent variable vector, and
9188 ! EWT is the array of weights set by DEWSET.
9189 ! If the user supplies this subroutine, it must return in EWT(i)
9190 ! (i = 1,...,NEQ) a positive quantity suitable for comparing errors
9191 ! in y(i) to. The EWT array returned by DEWSET is passed to the DVNORM
9192 ! routine (see below), and also used by DLSODKR in the computation
9193 ! of the optional output IMXER, the diagonal Jacobian approximation,
9194 ! and the increments for difference quotient Jacobians.
9195 ! In the user-supplied version of DEWSET, it may be desirable to use
9196 ! the current values of derivatives of y. Derivatives up to order NQ
9197 ! are available from the history array YH, described above under
9198 ! optional outputs. In DEWSET, YH is identical to the YCUR array,
9199 ! extended to NQ + 1 columns with a column length of NYH and scale
9200 ! factors of H**j/factorial(j). On the first call for the problem,
9201 ! given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
9202 ! NYH is the initial value of NEQ. The quantities NQ, H, and NST
9203 ! can be obtained by including in DEWSET the statements:
9204 ! DOUBLE PRECISION RLS
9205 ! COMMON /DLS001/ RLS(218),ILS(37)
9206 ! NQ = ILS(33)
9207 ! NST = ILS(34)
9208 ! H = RLS(212)
9209 ! Thus, for example, the current value of dy/dt can be obtained as
9210 ! YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is
9211 ! unnecessary when NST = 0).
9212 ! (b) DVNORM.
9213 ! The following is a real function routine which computes the weighted
9214 ! root-mean-square norm of a vector v:
9215 ! D = DVNORM (N, V, W)
9216 ! where:
9217 ! N = the length of the vector,
9218 ! V = real array of length N containing the vector,
9219 ! W = real array of length N containing weights,
9220 ! D = SQRT( (1/N) * sum(V(i)*W(i))**2 ).
9221 ! DVNORM is called with N = NEQ and with W(i) = 1.0/EWT(i), where
9222 ! EWT is as set by Subroutine DEWSET.
9223 ! If the user supplies this function, it should return a non-negative
9224 ! value of DVNORM suitable for use in the error control in DLSODKR.
9225 ! None of the arguments should be altered by DVNORM.
9226 ! For example, a user-supplied DVNORM routine might:
9227 ! -substitute a max-norm of (V(i)*W(i)) for the RMS-norm, or
9228 ! -ignore some components of V in the norm, with the effect of
9229 ! suppressing the error control on those components of y.
9230 !-----------------------------------------------------------------------
9231 !***REVISION HISTORY (YYYYMMDD)
9232 ! 19900117 DATE WRITTEN
9233 ! 19900503 Added iteration switching (functional/Newton).
9234 ! 19900802 Added flag for Jacobian-saving in user preconditioner.
9235 ! 19900910 Added new initial stepsize routine LHIN.
9236 ! 19901019 Corrected LHIN - y array restored.
9237 ! 19910909 Changed names STOPK to STOKA, PKSET to SETPK;
9238 ! removed unused variables in driver declarations;
9239 ! minor corrections to main prologue.
9240 ! 20010425 Major update: convert source lines to upper case;
9241 ! added *DECK lines; changed from 1 to * in dummy dimensions;
9242 ! changed names R1MACH/D1MACH to RUMACH/DUMACH;
9243 ! renamed routines for uniqueness across single/double prec.;
9244 ! converted intrinsic names to generic form;
9245 ! removed ILLIN and NTREP (data loaded) from Common;
9246 ! removed all 'own' variables from Common;
9247 ! changed error messages to quoted strings;
9248 ! replaced XERRWV/XERRWD with 1993 revised version;
9249 ! converted prologues, comments, error messages to mixed case;
9250 ! numerous corrections to prologues and internal comments.
9251 ! 20010507 Converted single precision source to double precision.
9252 ! 20020502 Corrected declarations in descriptions of user routines.
9253 ! 20030603 Corrected duplicate type declaration for DUMACH.
9254 ! 20031105 Restored 'own' variables to Common blocks, to enable
9255 ! interrupt/restart feature.
9256 ! 20031112 Added SAVE statements for data-loaded constants.
9257 ! 20031117 Changed internal name NPE to NJE.
9258 !-----------------------------------------------------------------------
9259 ! Other routines in the DLSODKR package.
9260 ! In addition to Subroutine DLSODKR, the DLSODKR package includes the
9261 ! following subroutines and function routines:
9262 ! DLHIN calculates a step size to be attempted initially.
9263 ! DRCHEK does preliminary checking for roots, and serves as an
9264 ! interface between Subroutine DLSODKR and Subroutine DROOTS.
9265 ! DROOTS finds the leftmost root of a set of functions.
9266 ! DINTDY computes an interpolated value of the y vector at t = TOUT.
9267 ! DEWSET sets the error weight vector EWT before each step.
9268 ! DVNORM computes the weighted RMS-norm of a vector.
9269 ! DSTOKA is the core integrator, which does one step of the
9270 ! integration and the associated error control.
9271 ! DCFODE sets all method coefficients and test constants.
9272 ! DSETPK interfaces between DSTOKA and the JAC routine.
9273 ! DSOLPK manages solution of linear system in Newton iteration.
9274 ! DSPIOM performs the SPIOM algorithm.
9275 ! DATV computes a scaled, preconditioned product (I-hl0*J)*v.
9276 ! DORTHOG orthogonalizes a vector against previous basis vectors.
9277 ! DHEFA generates an LU factorization of a Hessenberg matrix.
9278 ! DHESL solves a Hessenberg square linear system.
9279 ! DSPIGMR performs the SPIGMR algorithm.
9280 ! DHEQR generates a QR factorization of a Hessenberg matrix.
9281 ! DHELS finds the least squares solution of a Hessenberg system.
9282 ! DPCG performs preconditioned conjugate gradient algorithm (PCG).
9283 ! DPCGS performs the PCGS algorithm.
9284 ! DATP computes the product A*p, where A = I - hl0*df/dy.
9285 ! DUSOL interfaces to the user's PSOL routine (MITER = 9).
9286 ! DSRCKR is a user-callable routine to save and restore
9287 ! the contents of the internal Common blocks.
9288 ! DAXPY, DCOPY, DDOT, DNRM2, and DSCAL are basic linear
9289 ! algebra modules (from the BLAS collection).
9290 ! DUMACH computes the unit roundoff in a machine-independent manner.
9291 ! XERRWD, XSETUN, XSETF, IXSAV, and IUMACH handle the printing of all
9292 ! error messages and warnings. XERRWD is machine-dependent.
9293 ! Note: DVNORM, DDOT, DNRM2, DUMACH, IXSAV, and IUMACH are function
9294 ! routines. All the others are subroutines.
9295 !-----------------------------------------------------------------------
9296 ! DOUBLE PRECISION :: DUMACH, DVNORM
9297 ! INTEGER :: INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS, &
9298 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
9299 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
9300 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
9301 ! INTEGER :: NEWT, NSFI, NSLJ, NJEV
9302 ! INTEGER :: LG0, LG1, LGX, IOWNR3, IRFND, ITASKC, NGC, NGE
9303 ! INTEGER :: JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
9304 ! NNI, NLI, NPS, NCFN, NCFL
9305 ! INTEGER :: I, I1, I2, IER, IFLAG, IMXER, KGO, LF0, &
9306 ! LENIW, LENIWK, LENRW, LENWM, LENWK, LIWP, LWP, MORD, MXHNL0, &
9307 ! MXSTP0, NCFN0, NCFL0, NITER, NLI0, NNI0, NNID, NSTD, NWARN
9308 ! INTEGER :: IRFP, IRT, LENYH, LYHNEW
9309 ! DOUBLE PRECISION :: ROWNS, &
9310 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
9311 ! DOUBLE PRECISION :: STIFR
9312 ! DOUBLE PRECISION :: ROWNR3, T0, TLAST, TOUTC
9313 ! DOUBLE PRECISION :: DELT, EPCON, SQRTN, RSQRTN
9314 ! DOUBLE PRECISION :: ATOLI, AVDIM, BIG, EWTI, H0, HMAX, HMX, RCFL, &
9315 ! RCFN, RH, RTOLI, TCRIT, TNEXT, TOLSF, TP, SIZE
9316 ! DIMENSION MORD(2)
9317 ! LOGICAL :: IHIT, LAVD, LCFN, LCFL, LWARN
9318 ! CHARACTER(60) :: MSG
9319 ! SAVE MORD, MXSTP0, MXHNL0
9320 !-----------------------------------------------------------------------
9321 ! The following four internal Common blocks contain
9322 ! (a) variables which are local to any subroutine but whose values must
9323 ! be preserved between calls to the routine ("own" variables), and
9324 ! (b) variables which are communicated between subroutines.
9325 ! The block DLS001 is declared in subroutines DLSODKR, DINTDY,
9326 ! DSTOKA, DSOLPK, and DATV.
9327 ! The block DLS002 is declared in subroutines DLSODKR and DSTOKA.
9328 ! The block DLSR01 is declared in subroutines DLSODKR, DRCHEK, DROOTS.
9329 ! The block DLPK01 is declared in subroutines DLSODKR, DSTOKA, DSETPK,
9330 ! and DSOLPK.
9331 ! Groups of variables are replaced by dummy arrays in the Common
9332 ! declarations in routines where those variables are not used.
9333 !-----------------------------------------------------------------------
9334 ! COMMON /DLS001/ ROWNS(209), &
9335 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
9336 ! INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6), &
9337 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
9338 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
9339 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
9340 ! COMMON /DLS002/ STIFR, NEWT, NSFI, NSLJ, NJEV
9341 ! COMMON /DLSR01/ ROWNR3(2), T0, TLAST, TOUTC, &
9342 ! LG0, LG1, LGX, IOWNR3(2), IRFND, ITASKC, NGC, NGE
9343 ! COMMON /DLPK01/ DELT, EPCON, SQRTN, RSQRTN, &
9344 ! JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
9345 ! NNI, NLI, NPS, NCFN, NCFL
9346 ! DATA MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
9347 !-----------------------------------------------------------------------
9348 ! Block A.
9349 ! This code block is executed on every call.
9350 ! It tests ISTATE and ITASK for legality and branches appropriately.
9351 ! If ISTATE .gt. 1 but the flag INIT shows that initialization has
9352 ! not yet been done, an error return occurs.
9353 ! If ISTATE = 1 and TOUT = T, return immediately.
9354 !-----------------------------------------------------------------------
9355 ! IF (ISTATE < 1 .OR. ISTATE > 3) GO TO 601
9356 ! IF (ITASK < 1 .OR. ITASK > 5) GO TO 602
9357 ! ITASKC = ITASK
9358 ! IF (ISTATE == 1) GO TO 10
9359 ! IF (INIT == 0) GO TO 603
9360 ! IF (ISTATE == 2) GO TO 200
9361 ! GO TO 20
9362 ! 10 INIT = 0
9363 ! IF (TOUT == T) RETURN
9364 !-----------------------------------------------------------------------
9365 ! Block B.
9366 ! The next code block is executed for the initial call (ISTATE = 1),
9367 ! or for a continuation call with parameter changes (ISTATE = 3).
9368 ! It contains checking of all inputs and various initializations.
9369 ! First check legality of the non-optional inputs NEQ, ITOL, IOPT, MF,
9370 ! and NG.
9371 !-----------------------------------------------------------------------
9372 ! 20 IF (NEQ(1) <= 0) GO TO 604
9373 ! IF (ISTATE == 1) GO TO 25
9374 ! IF (NEQ(1) > N) GO TO 605
9375 ! 25 N = NEQ(1)
9376 ! IF (ITOL < 1 .OR. ITOL > 4) GO TO 606
9377 ! IF (IOPT < 0 .OR. IOPT > 1) GO TO 607
9378 ! METH = MF/10
9379 ! MITER = MF - 10*METH
9380 ! IF (METH < 1 .OR. METH > 2) GO TO 608
9381 ! IF (MITER < 0) GO TO 608
9382 ! IF (MITER > 4 .AND. MITER < 9) GO TO 608
9383 ! IF (MITER >= 1) JPRE = IWORK(3)
9384 ! JACFLG = 0
9385 ! IF (MITER >= 1) JACFLG = IWORK(4)
9386 ! IF (NG < 0) GO TO 630
9387 ! IF (ISTATE == 1) GO TO 35
9388 ! IF (IRFND == 0 .AND. NG /= NGC) GO TO 631
9389 ! 35 NGC = NG
9390 ! Next process and check the optional inputs. --------------------------
9391 ! IF (IOPT == 1) GO TO 40
9392 ! MAXORD = MORD(METH)
9393 ! MXSTEP = MXSTP0
9394 ! MXHNIL = MXHNL0
9395 ! IF (ISTATE == 1) H0 = 0.0D0
9396 ! HMXI = 0.0D0
9397 ! HMIN = 0.0D0
9398 ! MAXL = MIN(5,N)
9399 ! KMP = MAXL
9400 ! DELT = 0.05D0
9401 ! GO TO 60
9402 ! 40 MAXORD = IWORK(5)
9403 ! IF (MAXORD < 0) GO TO 611
9404 ! IF (MAXORD == 0) MAXORD = 100
9405 ! MAXORD = MIN(MAXORD,MORD(METH))
9406 ! MXSTEP = IWORK(6)
9407 ! IF (MXSTEP < 0) GO TO 612
9408 ! IF (MXSTEP == 0) MXSTEP = MXSTP0
9409 ! MXHNIL = IWORK(7)
9410 ! IF (MXHNIL < 0) GO TO 613
9411 ! IF (MXHNIL == 0) MXHNIL = MXHNL0
9412 ! IF (ISTATE /= 1) GO TO 50
9413 ! H0 = RWORK(5)
9414 ! IF ((TOUT - T)*H0 < 0.0D0) GO TO 614
9415 ! 50 HMAX = RWORK(6)
9416 ! IF (HMAX < 0.0D0) GO TO 615
9417 ! HMXI = 0.0D0
9418 ! IF (HMAX > 0.0D0) HMXI = 1.0D0/HMAX
9419 ! HMIN = RWORK(7)
9420 ! IF (HMIN < 0.0D0) GO TO 616
9421 ! MAXL = IWORK(8)
9422 ! IF (MAXL == 0) MAXL = 5
9423 ! MAXL = MIN(MAXL,N)
9424 ! KMP = IWORK(9)
9425 ! IF (KMP == 0 .OR. KMP > MAXL) KMP = MAXL
9426 ! DELT = RWORK(8)
9427 ! IF (DELT == 0.0D0) DELT = 0.05D0
9428 !-----------------------------------------------------------------------
9429 ! Set work array pointers and check lengths LRW and LIW.
9430 ! Pointers to segments of RWORK and IWORK are named by prefixing L to
9431 ! the name of the segment. E.g., the segment YH starts at RWORK(LYH).
9432 ! RWORK segments (in order) are denoted G0, G1, GX, YH, WM,
9433 ! EWT, SAVF, SAVX, ACOR.
9434 !-----------------------------------------------------------------------
9435 ! 60 IF (ISTATE == 1) NYH = N
9436 ! LG0 = 21
9437 ! LG1 = LG0 + NG
9438 ! LGX = LG1 + NG
9439 ! LYHNEW = LGX + NG
9440 ! IF (ISTATE == 1) LYH = LYHNEW
9441 ! IF (LYHNEW == LYH) GO TO 62
9442 ! If ISTATE = 3 and NG was changed, shift YH to its new location. ------
9443 ! LENYH = L*NYH
9444 ! IF (LRW < LYHNEW-1+LENYH) GO TO 62
9445 ! I1 = 1
9446 ! IF (LYHNEW > LYH) I1 = -1
9447 ! CALL DCOPY (LENYH, RWORK(LYH), I1, RWORK(LYHNEW), I1)
9448 ! LYH = LYHNEW
9449 ! 62 CONTINUE
9450 ! LWM = LYH + (MAXORD + 1)*NYH
9451 ! IF (MITER == 0) LENWK = 0
9452 ! IF (MITER == 1) LENWK = N*(MAXL+2) + MAXL*MAXL
9453 ! IF (MITER == 2) &
9454 ! LENWK = N*(MAXL+2+MIN(1,MAXL-KMP)) + (MAXL+3)*MAXL + 1
9455 ! IF (MITER == 3 .OR. MITER == 4) LENWK = 5*N
9456 ! IF (MITER == 9) LENWK = 2*N
9457 ! LWP = 0
9458 ! IF (MITER >= 1) LWP = IWORK(1)
9459 ! LENWM = LENWK + LWP
9460 ! LOCWP = LENWK + 1
9461 ! LEWT = LWM + LENWM
9462 ! LSAVF = LEWT + N
9463 ! LSAVX = LSAVF + N
9464 ! LACOR = LSAVX + N
9465 ! IF (MITER == 0) LACOR = LSAVF + N
9466 ! LENRW = LACOR + N - 1
9467 ! IWORK(17) = LENRW
9468 ! LIWM = 31
9469 ! LENIWK = 0
9470 ! IF (MITER == 1) LENIWK = MAXL
9471 ! LIWP = 0
9472 ! IF (MITER >= 1) LIWP = IWORK(2)
9473 ! LENIW = 30 + LENIWK + LIWP
9474 ! LOCIWP = LENIWK + 1
9475 ! IWORK(18) = LENIW
9476 ! IF (LENRW > LRW) GO TO 617
9477 ! IF (LENIW > LIW) GO TO 618
9478 ! Check RTOL and ATOL for legality. ------------------------------------
9479 ! RTOLI = RTOL(1)
9480 ! ATOLI = ATOL(1)
9481 ! DO 70 I = 1,N
9482 ! IF (ITOL >= 3) RTOLI = RTOL(I)
9483 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
9484 ! IF (RTOLI < 0.0D0) GO TO 619
9485 ! IF (ATOLI < 0.0D0) GO TO 620
9486 ! 70 END DO
9487 ! Load SQRT(N) and its reciprocal in Common. ---------------------------
9488 ! SQRTN = SQRT(REAL(N))
9489 ! RSQRTN = 1.0D0/SQRTN
9490 ! IF (ISTATE == 1) GO TO 100
9491 ! If ISTATE = 3, set flag to signal parameter changes to DSTOKA.--------
9492 ! JSTART = -1
9493 ! IF (NQ <= MAXORD) GO TO 90
9494 ! MAXORD was reduced below NQ. Copy YH(*,MAXORD+2) into SAVF. ---------
9495 ! DO 80 I = 1,N
9496 ! RWORK(I+LSAVF-1) = RWORK(I+LWM-1)
9497 ! 80 END DO
9498 ! 90 CONTINUE
9499 ! IF (N == NYH) GO TO 200
9500 ! NEQ was reduced. Zero part of YH to avoid undefined references. -----
9501 ! I1 = LYH + L*NYH
9502 ! I2 = LYH + (MAXORD + 1)*NYH - 1
9503 ! IF (I1 > I2) GO TO 200
9504 ! DO 95 I = I1,I2
9505 ! RWORK(I) = 0.0D0
9506 ! 95 END DO
9507 ! GO TO 200
9508 !-----------------------------------------------------------------------
9509 ! Block C.
9510 ! The next block is for the initial call only (ISTATE = 1).
9511 ! It contains all remaining initializations, the initial call to F,
9512 ! and the calculation of the initial step size.
9513 ! The error weights in EWT are inverted after being loaded.
9514 !-----------------------------------------------------------------------
9515 ! 100 UROUND = DUMACH()
9516 ! TN = T
9517 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 110
9518 ! TCRIT = RWORK(1)
9519 ! IF ((TCRIT - TOUT)*(TOUT - T) < 0.0D0) GO TO 625
9520 ! IF (H0 /= 0.0D0 .AND. (T + H0 - TCRIT)*H0 > 0.0D0) &
9521 ! H0 = TCRIT - T
9522 ! 110 JSTART = 0
9523 ! NHNIL = 0
9524 ! NST = 0
9525 ! NJE = 0
9526 ! NSLAST = 0
9527 ! NLI0 = 0
9528 ! NNI0 = 0
9529 ! NCFN0 = 0
9530 ! NCFL0 = 0
9531 ! NWARN = 0
9532 ! HU = 0.0D0
9533 ! NQU = 0
9534 ! CCMAX = 0.3D0
9535 ! MAXCOR = 3
9536 ! MSBP = 20
9537 ! MXNCF = 10
9538 ! NNI = 0
9539 ! NLI = 0
9540 ! NPS = 0
9541 ! NCFN = 0
9542 ! NCFL = 0
9543 ! NSFI = 0
9544 ! NJEV = 0
9545 ! Initial call to F. (LF0 points to YH(*,2).) -------------------------
9546 ! LF0 = LYH + NYH
9547 ! CALL F (NEQ, T, Y, RWORK(LF0))
9548 ! NFE = 1
9549 ! Load the initial value vector in YH. ---------------------------------
9550 ! DO 115 I = 1,N
9551 ! RWORK(I+LYH-1) = Y(I)
9552 ! 115 END DO
9553 ! Load and invert the EWT array. (H is temporarily set to 1.0.) -------
9554 ! NQ = 1
9555 ! H = 1.0D0
9556 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
9557 ! DO 120 I = 1,N
9558 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
9559 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
9560 ! 120 END DO
9561 ! IF (H0 /= 0.0D0) GO TO 180
9562 ! Call DLHIN to set initial step size H0 to be attempted. --------------
9563 ! CALL DLHIN (NEQ, N, T, RWORK(LYH), RWORK(LF0), F, TOUT, UROUND, &
9564 ! RWORK(LEWT), ITOL, ATOL, Y, RWORK(LACOR), H0, NITER, IER)
9565 ! NFE = NFE + NITER
9566 ! IF (IER /= 0) GO TO 622
9567 ! Adjust H0 if necessary to meet HMAX bound. ---------------------------
9568 ! 180 RH = ABS(H0)*HMXI
9569 ! IF (RH > 1.0D0) H0 = H0/RH
9570 ! Load H with H0 and scale YH(*,2) by H0. ------------------------------
9571 ! H = H0
9572 ! DO 190 I = 1,N
9573 ! RWORK(I+LF0-1) = H0*RWORK(I+LF0-1)
9574 ! 190 END DO
9575 ! Check for a zero of g at T. ------------------------------------------
9576 ! IRFND = 0
9577 ! TOUTC = TOUT
9578 ! IF (NGC == 0) GO TO 270
9579 ! CALL DRCHEK (1, G, NEQ, Y, RWORK(LYH), NYH, &
9580 ! RWORK(LG0), RWORK(LG1), RWORK(LGX), JROOT, IRT)
9581 ! IF (IRT == 0) GO TO 270
9582 ! GO TO 632
9583 !-----------------------------------------------------------------------
9584 ! Block D.
9585 ! The next code block is for continuation calls only (ISTATE = 2 or 3)
9586 ! and is to check stop conditions before taking a step.
9587 ! First, DRCHEK is called to check for a root within the last step
9588 ! taken, other than the last root found there, if any.
9589 ! If ITASK = 2 or 5, and y(TN) has not yet been returned to the user
9590 ! because of an intervening root, return through Block G.
9591 !-----------------------------------------------------------------------
9592 ! 200 NSLAST = NST
9593 ! IRFP = IRFND
9594 ! IF (NGC == 0) GO TO 205
9595 ! IF (ITASK == 1 .OR. ITASK == 4) TOUTC = TOUT
9596 ! CALL DRCHEK (2, G, NEQ, Y, RWORK(LYH), NYH, &
9597 ! RWORK(LG0), RWORK(LG1), RWORK(LGX), JROOT, IRT)
9598 ! IF (IRT /= 1) GO TO 205
9599 ! IRFND = 1
9600 ! ISTATE = 3
9601 ! T = T0
9602 ! GO TO 425
9603 ! 205 CONTINUE
9604 ! IRFND = 0
9605 ! IF (IRFP == 1 .AND. TLAST /= TN .AND. ITASK == 2) GO TO 400
9606 ! NLI0 = NLI
9607 ! NNI0 = NNI
9608 ! NCFN0 = NCFN
9609 ! NCFL0 = NCFL
9610 ! NWARN = 0
9611 ! GO TO (210, 250, 220, 230, 240), ITASK
9612 ! 210 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
9613 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
9614 ! IF (IFLAG /= 0) GO TO 627
9615 ! T = TOUT
9616 ! GO TO 420
9617 ! 220 TP = TN - HU*(1.0D0 + 100.0D0*UROUND)
9618 ! IF ((TP - TOUT)*H > 0.0D0) GO TO 623
9619 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 250
9620 ! GO TO 400
9621 ! 230 TCRIT = RWORK(1)
9622 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
9623 ! IF ((TCRIT - TOUT)*H < 0.0D0) GO TO 625
9624 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 245
9625 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
9626 ! IF (IFLAG /= 0) GO TO 627
9627 ! T = TOUT
9628 ! GO TO 420
9629 ! 240 TCRIT = RWORK(1)
9630 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
9631 ! 245 HMX = ABS(TN) + ABS(H)
9632 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
9633 ! IF (IHIT) T = TCRIT
9634 ! IF (IRFP == 1 .AND. TLAST /= TN .AND. ITASK == 5) GO TO 400
9635 ! IF (IHIT) GO TO 400
9636 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
9637 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
9638 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
9639 ! IF (ISTATE == 2) JSTART = -2
9640 !-----------------------------------------------------------------------
9641 ! Block E.
9642 ! The next block is normally executed for all calls and contains
9643 ! the call to the one-step core integrator DSTOKA.
9644 ! This is a looping point for the integration steps.
9645 ! First check for too many steps being taken,
9646 ! check for poor Newton/Krylov method performance, update EWT (if not
9647 ! at start of problem), check for too much accuracy being requested,
9648 ! and check for H below the roundoff level in T.
9649 !-----------------------------------------------------------------------
9650 ! 250 CONTINUE
9651 ! IF ((NST-NSLAST) >= MXSTEP) GO TO 500
9652 ! NSTD = NST - NSLAST
9653 ! NNID = NNI - NNI0
9654 ! IF (NSTD < 10 .OR. NNID == 0) GO TO 255
9655 ! AVDIM = REAL(NLI - NLI0)/REAL(NNID)
9656 ! RCFN = REAL(NCFN - NCFN0)/REAL(NSTD)
9657 ! RCFL = REAL(NCFL - NCFL0)/REAL(NNID)
9658 ! LAVD = AVDIM > (MAXL - 0.05D0)
9659 ! LCFN = RCFN > 0.9D0
9660 ! LCFL = RCFL > 0.9D0
9661 ! LWARN = LAVD .OR. LCFN .OR. LCFL
9662 ! IF ( .NOT. LWARN) GO TO 255
9663 ! NWARN = NWARN + 1
9664 ! IF (NWARN > 10) GO TO 255
9665 ! IF (LAVD) THEN
9666 ! MSG='DLSODKR- Warning. Poor iterative algorithm performance seen '
9667 ! CALL XERRWD (MSG, 60, 111, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9668 ! ENDIF
9669 ! IF (LAVD) THEN
9670 ! MSG=' at T = R1 by average no. of linear iterations = R2 '
9671 ! CALL XERRWD (MSG, 60, 111, 0, 0, 0, 0, 2, TN, AVDIM)
9672 ! ENDIF
9673 ! IF (LCFN) THEN
9674 ! MSG='DLSODKR- Warning. Poor iterative algorithm performance seen '
9675 ! CALL XERRWD (MSG, 60, 112, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9676 ! ENDIF
9677 ! IF (LCFN) THEN
9678 ! MSG=' at T = R1 by nonlinear convergence failure rate = R2 '
9679 ! CALL XERRWD (MSG, 60, 112, 0, 0, 0, 0, 2, TN, RCFN)
9680 ! ENDIF
9681 ! IF (LCFL) THEN
9682 ! MSG='DLSODKR- Warning. Poor iterative algorithm performance seen '
9683 ! CALL XERRWD (MSG, 60, 113, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9684 ! ENDIF
9685 ! IF (LCFL) THEN
9686 ! MSG=' at T = R1 by linear convergence failure rate = R2 '
9687 ! CALL XERRWD (MSG, 60, 113, 0, 0, 0, 0, 2, TN, RCFL)
9688 ! ENDIF
9689 ! 255 CONTINUE
9690 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
9691 ! DO 260 I = 1,N
9692 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 510
9693 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
9694 ! 260 END DO
9695 ! 270 TOLSF = UROUND*DVNORM (N, RWORK(LYH), RWORK(LEWT))
9696 ! IF (TOLSF <= 1.0D0) GO TO 280
9697 ! TOLSF = TOLSF*2.0D0
9698 ! IF (NST == 0) GO TO 626
9699 ! GO TO 520
9700 ! 280 IF ((TN + H) /= TN) GO TO 290
9701 ! NHNIL = NHNIL + 1
9702 ! IF (NHNIL > MXHNIL) GO TO 290
9703 ! MSG = 'DLSODKR- Warning.. Internal T(=R1) and H(=R2) are'
9704 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9705 ! MSG=' such that in the machine, T + H = T on the next step '
9706 ! CALL XERRWD (MSG, 60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9707 ! MSG = ' (H = step size). Solver will continue anyway.'
9708 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 2, TN, H)
9709 ! IF (NHNIL < MXHNIL) GO TO 290
9710 ! MSG = 'DLSODKR- Above warning has been issued I1 times. '
9711 ! CALL XERRWD (MSG, 50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9712 ! MSG = ' It will not be issued again for this problem.'
9713 ! CALL XERRWD (MSG, 50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
9714 ! 290 CONTINUE
9715 !-----------------------------------------------------------------------
9716 ! CALL DSTOKA(NEQ,Y,YH,NYH,YH,EWT,SAVF,SAVX,ACOR,WM,IWM,F,JAC,PSOL)
9717 !-----------------------------------------------------------------------
9718 ! CALL DSTOKA (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT), &
9719 ! RWORK(LSAVF), RWORK(LSAVX), RWORK(LACOR), RWORK(LWM), &
9720 ! IWORK(LIWM), F, JAC, PSOL)
9721 ! KGO = 1 - KFLAG
9722 ! GO TO (300, 530, 540, 550), KGO
9723 !-----------------------------------------------------------------------
9724 ! Block F.
9725 ! The following block handles the case of a successful return from the
9726 ! core integrator (KFLAG = 0).
9727 ! Call DRCHEK to check for a root within the last step.
9728 ! Then, if no root was found, check for stop conditions.
9729 !-----------------------------------------------------------------------
9730 ! 300 INIT = 1
9731 ! IF (NGC == 0) GO TO 315
9732 ! CALL DRCHEK (3, G, NEQ, Y, RWORK(LYH), NYH, &
9733 ! RWORK(LG0), RWORK(LG1), RWORK(LGX), JROOT, IRT)
9734 ! IF (IRT /= 1) GO TO 315
9735 ! IRFND = 1
9736 ! ISTATE = 3
9737 ! T = T0
9738 ! GO TO 425
9739 ! 315 CONTINUE
9740 ! GO TO (310, 400, 330, 340, 350), ITASK
9741 ! ITASK = 1. If TOUT has been reached, interpolate. -------------------
9742 ! 310 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
9743 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
9744 ! T = TOUT
9745 ! GO TO 420
9746 ! ITASK = 3. Jump to exit if TOUT was reached. ------------------------
9747 ! 330 IF ((TN - TOUT)*H >= 0.0D0) GO TO 400
9748 ! GO TO 250
9749 ! ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary.
9750 ! 340 IF ((TN - TOUT)*H < 0.0D0) GO TO 345
9751 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
9752 ! T = TOUT
9753 ! GO TO 420
9754 ! 345 HMX = ABS(TN) + ABS(H)
9755 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
9756 ! IF (IHIT) GO TO 400
9757 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
9758 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
9759 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
9760 ! JSTART = -2
9761 ! GO TO 250
9762 ! ITASK = 5. See if TCRIT was reached and jump to exit. ---------------
9763 ! 350 HMX = ABS(TN) + ABS(H)
9764 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
9765 !-----------------------------------------------------------------------
9766 ! Block G.
9767 ! The following block handles all successful returns from DLSODKR.
9768 ! If ITASK .ne. 1, Y is loaded from YH and T is set accordingly.
9769 ! ISTATE is set to 2, and the optional outputs are loaded into the
9770 ! work arrays before returning.
9771 !-----------------------------------------------------------------------
9772 ! 400 DO 410 I = 1,N
9773 ! Y(I) = RWORK(I+LYH-1)
9774 ! 410 END DO
9775 ! T = TN
9776 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 420
9777 ! IF (IHIT) T = TCRIT
9778 ! 420 ISTATE = 2
9779 ! 425 CONTINUE
9780 ! RWORK(11) = HU
9781 ! RWORK(12) = H
9782 ! RWORK(13) = TN
9783 ! IWORK(11) = NST
9784 ! IWORK(12) = NFE
9785 ! IWORK(13) = NJE
9786 ! IWORK(14) = NQU
9787 ! IWORK(15) = NQ
9788 ! IWORK(19) = NNI
9789 ! IWORK(20) = NLI
9790 ! IWORK(21) = NPS
9791 ! IWORK(22) = NCFN
9792 ! IWORK(23) = NCFL
9793 ! IWORK(24) = NSFI
9794 ! IWORK(25) = NJEV
9795 ! IWORK(10) = NGE
9796 ! TLAST = T
9797 ! RETURN
9798 !-----------------------------------------------------------------------
9799 ! Block H.
9800 ! The following block handles all unsuccessful returns other than
9801 ! those for illegal input. First the error message routine is called.
9802 ! If there was an error test or convergence test failure, IMXER is set.
9803 ! Then Y is loaded from YH and T is set to TN.
9804 ! The optional outputs are loaded into the work arrays before returning.
9805 !-----------------------------------------------------------------------
9806 ! The maximum number of steps was taken before reaching TOUT. ----------
9807 ! 500 MSG = 'DLSODKR- At current T (=R1), MXSTEP (=I1) steps '
9808 ! CALL XERRWD (MSG, 50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9809 ! MSG = ' taken on this call before reaching TOUT '
9810 ! CALL XERRWD (MSG, 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0)
9811 ! ISTATE = -1
9812 ! GO TO 580
9813 ! EWT(i) .le. 0.0 for some i (not at start of problem). ----------------
9814 ! 510 EWTI = RWORK(LEWT+I-1)
9815 ! MSG = 'DLSODKR- At T(=R1), EWT(I1) has become R2 <= 0.'
9816 ! CALL XERRWD (MSG, 50, 202, 0, 1, I, 0, 2, TN, EWTI)
9817 ! ISTATE = -6
9818 ! GO TO 580
9819 ! Too much accuracy requested for machine precision. -------------------
9820 ! 520 MSG = 'DLSODKR- At T (=R1), too much accuracy requested '
9821 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9822 ! MSG = ' for precision of machine.. See TOLSF (=R2) '
9823 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
9824 ! RWORK(14) = TOLSF
9825 ! ISTATE = -2
9826 ! GO TO 580
9827 ! KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
9828 ! 530 MSG = 'DLSODKR- At T(=R1) and step size H(=R2), the error'
9829 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9830 ! MSG = ' test failed repeatedly or with ABS(H) = HMIN'
9831 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 2, TN, H)
9832 ! ISTATE = -4
9833 ! GO TO 560
9834 ! KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
9835 ! 540 MSG = 'DLSODKR- At T (=R1) and step size H (=R2), the '
9836 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9837 ! MSG = ' corrector convergence failed repeatedly '
9838 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9839 ! MSG = ' or with ABS(H) = HMIN '
9840 ! CALL XERRWD (MSG, 30, 205, 0, 0, 0, 0, 2, TN, H)
9841 ! ISTATE = -5
9842 ! GO TO 580
9843 ! KFLAG = -3. Unrecoverable error from PSOL. --------------------------
9844 ! 550 MSG = 'DLSODKR- At T (=R1) an unrecoverable error return'
9845 ! CALL XERRWD (MSG, 50, 206, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9846 ! MSG = ' was made from Subroutine PSOL '
9847 ! CALL XERRWD (MSG, 40, 206, 0, 0, 0, 0, 1, TN, 0.0D0)
9848 ! ISTATE = -7
9849 ! GO TO 580
9850 ! Compute IMXER if relevant. -------------------------------------------
9851 ! 560 BIG = 0.0D0
9852 ! IMXER = 1
9853 ! DO 570 I = 1,N
9854 ! SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
9855 ! IF (BIG >= SIZE) GO TO 570
9856 ! BIG = SIZE
9857 ! IMXER = I
9858 ! 570 END DO
9859 ! IWORK(16) = IMXER
9860 ! Set Y vector, T, and optional outputs. -------------------------------
9861 ! 580 DO 590 I = 1,N
9862 ! Y(I) = RWORK(I+LYH-1)
9863 ! 590 END DO
9864 ! T = TN
9865 ! RWORK(11) = HU
9866 ! RWORK(12) = H
9867 ! RWORK(13) = TN
9868 ! IWORK(11) = NST
9869 ! IWORK(12) = NFE
9870 ! IWORK(13) = NJE
9871 ! IWORK(14) = NQU
9872 ! IWORK(15) = NQ
9873 ! IWORK(19) = NNI
9874 ! IWORK(20) = NLI
9875 ! IWORK(21) = NPS
9876 ! IWORK(22) = NCFN
9877 ! IWORK(23) = NCFL
9878 ! IWORK(24) = NSFI
9879 ! IWORK(25) = NJEV
9880 ! IWORK(10) = NGE
9881 ! TLAST = T
9882 ! RETURN
9883 !-----------------------------------------------------------------------
9884 ! Block I.
9885 ! The following block handles all error returns due to illegal input
9886 ! (ISTATE = -3), as detected before calling the core integrator.
9887 ! First the error message routine is called. If the illegal input
9888 ! is a negative ISTATE, the run is aborted (apparent infinite loop).
9889 !-----------------------------------------------------------------------
9890 ! 601 MSG = 'DLSODKR- ISTATE(=I1) illegal.'
9891 ! CALL XERRWD (MSG, 30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0)
9892 ! IF (ISTATE < 0) GO TO 800
9893 ! GO TO 700
9894 ! 602 MSG = 'DLSODKR- ITASK (=I1) illegal.'
9895 ! CALL XERRWD (MSG, 30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0)
9896 ! GO TO 700
9897 ! 603 MSG = 'DLSODKR- ISTATE > 1 but DLSODKR not initialized. '
9898 ! CALL XERRWD (MSG, 50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9899 ! GO TO 700
9900 ! 604 MSG = 'DLSODKR- NEQ (=I1) < 1 '
9901 ! CALL XERRWD (MSG, 30, 4, 0, 1, NEQ(1), 0, 0, 0.0D0, 0.0D0)
9902 ! GO TO 700
9903 ! 605 MSG = 'DLSODKR- ISTATE = 3 and NEQ increased (I1 to I2).'
9904 ! CALL XERRWD (MSG, 50, 5, 0, 2, N, NEQ(1), 0, 0.0D0, 0.0D0)
9905 ! GO TO 700
9906 ! 606 MSG = 'DLSODKR- ITOL (=I1) illegal. '
9907 ! CALL XERRWD (MSG, 30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0)
9908 ! GO TO 700
9909 ! 607 MSG = 'DLSODKR- IOPT (=I1) illegal. '
9910 ! CALL XERRWD (MSG, 30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0)
9911 ! GO TO 700
9912 ! 608 MSG = 'DLSODKR- MF (=I1) illegal. '
9913 ! CALL XERRWD (MSG, 30, 8, 0, 1, MF, 0, 0, 0.0D0, 0.0D0)
9914 ! GO TO 700
9915 ! 611 MSG = 'DLSODKR- MAXORD (=I1) < 0 '
9916 ! CALL XERRWD (MSG, 30, 11, 0, 1, MAXORD, 0, 0, 0.0D0, 0.0D0)
9917 ! GO TO 700
9918 ! 612 MSG = 'DLSODKR- MXSTEP (=I1) < 0 '
9919 ! CALL XERRWD (MSG, 30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0)
9920 ! GO TO 700
9921 ! 613 MSG = 'DLSODKR- MXHNIL (=I1) < 0 '
9922 ! CALL XERRWD (MSG, 30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
9923 ! GO TO 700
9924 ! 614 MSG = 'DLSODKR- TOUT (=R1) behind T (=R2) '
9925 ! CALL XERRWD (MSG, 40, 14, 0, 0, 0, 0, 2, TOUT, T)
9926 ! MSG = ' Integration direction is given by H0 (=R1) '
9927 ! CALL XERRWD (MSG, 50, 14, 0, 0, 0, 0, 1, H0, 0.0D0)
9928 ! GO TO 700
9929 ! 615 MSG = 'DLSODKR- HMAX (=R1) < 0.0 '
9930 ! CALL XERRWD (MSG, 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0)
9931 ! GO TO 700
9932 ! 616 MSG = 'DLSODKR- HMIN (=R1) < 0.0 '
9933 ! CALL XERRWD (MSG, 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0)
9934 ! GO TO 700
9935 ! 617 MSG='DLSODKR- RWORK length needed, LENRW(=I1), exceeds LRW(=I2) '
9936 ! CALL XERRWD (MSG, 60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
9937 ! GO TO 700
9938 ! 618 MSG='DLSODKR- IWORK length needed, LENIW(=I1), exceeds LIW(=I2) '
9939 ! CALL XERRWD (MSG, 60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
9940 ! GO TO 700
9941 ! 619 MSG = 'DLSODKR- RTOL(I1) is R1 < 0.0 '
9942 ! CALL XERRWD (MSG, 40, 19, 0, 1, I, 0, 1, RTOLI, 0.0D0)
9943 ! GO TO 700
9944 ! 620 MSG = 'DLSODKR- ATOL(I1) is R1 < 0.0 '
9945 ! CALL XERRWD (MSG, 40, 20, 0, 1, I, 0, 1, ATOLI, 0.0D0)
9946 ! GO TO 700
9947 ! 621 EWTI = RWORK(LEWT+I-1)
9948 ! MSG = 'DLSODKR- EWT(I1) is R1 <= 0.0 '
9949 ! CALL XERRWD (MSG, 40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0)
9950 ! GO TO 700
9951 ! 622 MSG='DLSODKR- TOUT(=R1) too close to T(=R2) to start integration.'
9952 ! CALL XERRWD (MSG, 60, 22, 0, 0, 0, 0, 2, TOUT, T)
9953 ! GO TO 700
9954 ! 623 MSG='DLSODKR- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
9955 ! CALL XERRWD (MSG, 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
9956 ! GO TO 700
9957 ! 624 MSG='DLSODKR- ITASK = 4 or 5 and TCRIT (=R1) behind TCUR (=R2) '
9958 ! CALL XERRWD (MSG, 60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
9959 ! GO TO 700
9960 ! 625 MSG='DLSODKR- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
9961 ! CALL XERRWD (MSG, 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
9962 ! GO TO 700
9963 ! 626 MSG = 'DLSODKR- At start of problem, too much accuracy '
9964 ! CALL XERRWD (MSG, 50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9965 ! MSG=' requested for precision of machine.. See TOLSF (=R1) '
9966 ! CALL XERRWD (MSG, 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0)
9967 ! RWORK(14) = TOLSF
9968 ! GO TO 700
9969 ! 627 MSG = 'DLSODKR- Trouble in DINTDY. ITASK = I1, TOUT = R1'
9970 ! CALL XERRWD (MSG, 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0)
9971 ! GO TO 700
9972 ! 630 MSG = 'DLSODKR- NG (=I1) < 0 '
9973 ! CALL XERRWD (MSG, 30, 30, 0, 1, NG, 0, 0, 0.0D0, 0.0D0)
9974 ! GO TO 700
9975 ! 631 MSG = 'DLSODKR- NG changed (from I1 to I2) illegally, '
9976 ! CALL XERRWD (MSG, 50, 31, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9977 ! MSG = ' i.e. not immediately after a root was found.'
9978 ! CALL XERRWD (MSG, 50, 31, 0, 2, NGC, NG, 0, 0.0D0, 0.0D0)
9979 ! GO TO 700
9980 ! 632 MSG = 'DLSODKR- One or more components of g has a root '
9981 ! CALL XERRWD (MSG, 50, 32, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9982 ! MSG = ' too near to the initial point. '
9983 ! CALL XERRWD (MSG, 40, 32, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
9984 ! 700 ISTATE = -3
9985 ! RETURN
9986 ! 800 MSG = 'DLSODKR- Run aborted.. apparent infinite loop. '
9987 ! CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0)
9988 ! RETURN
9989 !----------------------- End of Subroutine DLSODKR ---------------------
9990 ! END SUBROUTINE DLSODKR
9991 ! ECK DLSODI
9992 ! SUBROUTINE DLSODI (RES, ADDA, JAC, NEQ, Y, YDOTI, T, TOUT, ITOL, &
9993 ! RTOL, ATOL, ITASK, ISTATE, IOPT, RWORK, LRW, IWORK, LIW, MF )
9994 ! EXTERNAL RES, ADDA, JAC
9995 ! INTEGER :: NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, MF
9996 ! DOUBLE PRECISION :: Y, YDOTI, T, TOUT, RTOL, ATOL, RWORK
9997 ! DIMENSION NEQ(*), Y(*), YDOTI(*), RTOL(*), ATOL(*), RWORK(LRW), &
9998 ! IWORK(LIW)
9999 !-----------------------------------------------------------------------
10000 ! This is the 18 November 2003 version of
10001 ! DLSODI: Livermore Solver for Ordinary Differential Equations
10002 ! (Implicit form).
10003 ! This version is in double precision.
10004 ! DLSODI solves the initial value problem for linearly implicit
10005 ! systems of first order ODEs,
10006 ! A(t,y) * dy/dt = g(t,y) , where A(t,y) is a square matrix,
10007 ! or, in component form,
10008 ! ( a * ( dy / dt )) + ... + ( a * ( dy / dt )) =
10009 ! i,1 1 i,NEQ NEQ
10010 ! = g ( t, y , y ,..., y ) ( i = 1,...,NEQ )
10011 ! i 1 2 NEQ
10012 ! If A is singular, this is a differential-algebraic system.
10013 ! DLSODI is a variant version of the DLSODE package.
10014 !-----------------------------------------------------------------------
10015 ! Reference:
10016 ! Alan C. Hindmarsh, ODEPACK, A Systematized Collection of ODE
10017 ! Solvers, in Scientific Computing, R. S. Stepleman et al. (Eds.),
10018 ! North-Holland, Amsterdam, 1983, pp. 55-64.
10019 !-----------------------------------------------------------------------
10020 ! Authors: Alan C. Hindmarsh and Jeffrey F. Painter
10021 ! Center for Applied Scientific Computing, L-561
10022 ! Lawrence Livermore National Laboratory
10023 ! Livermore, CA 94551
10024 !-----------------------------------------------------------------------
10025 ! Summary of Usage.
10026 ! Communication between the user and the DLSODI package, for normal
10027 ! situations, is summarized here. This summary describes only a subset
10028 ! of the full set of options available. See the full description for
10029 ! details, including optional communication, nonstandard options,
10030 ! and instructions for special situations. See also the example
10031 ! problem (with program and output) following this summary.
10032 ! A. First, provide a subroutine of the form:
10033 ! SUBROUTINE RES (NEQ, T, Y, S, R, IRES)
10034 ! DOUBLE PRECISION T, Y(*), S(*), R(*)
10035 ! which computes the residual function
10036 ! r = g(t,y) - A(t,y) * s ,
10037 ! as a function of t and the vectors y and s. (s is an internally
10038 ! generated approximation to dy/dt.) The arrays Y and S are inputs
10039 ! to the RES routine and should not be altered. The residual
10040 ! vector is to be stored in the array R. The argument IRES should be
10041 ! ignored for casual use of DLSODI. (For uses of IRES, see the
10042 ! paragraph on RES in the full description below.)
10043 ! B. Next, decide whether full or banded form is more economical
10044 ! for the storage of matrices. DLSODI must deal internally with the
10045 ! matrices A and dr/dy, where r is the residual function defined above.
10046 ! DLSODI generates a linear combination of these two matrices, and
10047 ! this is treated in either full or banded form.
10048 ! The matrix structure is communicated by a method flag MF,
10049 ! which is 21 or 22 for the full case, and 24 or 25 in the band case.
10050 ! In the banded case, DLSODI requires two half-bandwidth
10051 ! parameters ML and MU. These are, respectively, the widths of the
10052 ! lower and upper parts of the band, excluding the main diagonal.
10053 ! Thus the band consists of the locations (i,j) with
10054 ! i-ML .le. j .le. i+MU, and the full bandwidth is ML+MU+1.
10055 ! Note that the band must accommodate the nonzero elements of
10056 ! A(t,y), dg/dy, and d(A*s)/dy (s fixed). Alternatively, one
10057 ! can define a band that encloses only the elements that are relatively
10058 ! large in magnitude, and gain some economy in storage and possibly
10059 ! also efficiency, although the appropriate threshhold for
10060 ! retaining matrix elements is highly problem-dependent.
10061 ! C. You must also provide a subroutine of the form:
10062 ! SUBROUTINE ADDA (NEQ, T, Y, ML, MU, P, NROWP)
10063 ! DOUBLE PRECISION T, Y(*), P(NROWP,*)
10064 ! which adds the matrix A = A(t,y) to the contents of the array P.
10065 ! T and the Y array are input and should not be altered.
10066 ! In the full matrix case, this routine should add elements of
10067 ! to P in the usual order. I.e., add A(i,j) to P(i,j). (Ignore the
10068 ! ML and MU arguments in this case.)
10069 ! In the band matrix case, this routine should add element A(i,j)
10070 ! to P(i-j+MU+1,j). I.e., add the diagonal lines of A to the rows of
10071 ! P from the top down (the top line of A added to the first row of P).
10072 ! D. For the sake of efficiency, you are encouraged to supply the
10073 ! Jacobian matrix dr/dy in closed form, where r = g(t,y) - A(t,y)*s
10074 ! (s = a fixed vector) as above. If dr/dy is being supplied,
10075 ! use MF = 21 or 24, and provide a subroutine of the form:
10076 ! SUBROUTINE JAC (NEQ, T, Y, S, ML, MU, P, NROWP)
10077 ! DOUBLE PRECISION T, Y(*), S(*), P(NROWP,*)
10078 ! which computes dr/dy as a function of t, y, and s. Here T, Y, and
10079 ! S are inputs, and the routine is to load dr/dy into P as follows:
10080 ! In the full matrix case (MF = 21), load P(i,j) with dr(i)/dy(j),
10081 ! the partial derivative of r(i) with respect to y(j). (Ignore the
10082 ! ML and MU arguments in this case.)
10083 ! In the band matrix case (MF = 24), load P(i-j+mu+1,j) with
10084 ! dr(i)/dy(j), i.e. load the diagonal lines of dr/dy into the rows of
10085 ! P from the top down.
10086 ! In either case, only nonzero elements need be loaded, and the
10087 ! indexing of P is the same as in the ADDA routine.
10088 ! Note that if A is independent of y (or this dependence
10089 ! is weak enough to be ignored) then JAC is to compute dg/dy.
10090 ! If it is not feasible to provide a JAC routine, use
10091 ! MF = 22 or 25, and DLSODI will compute an approximate Jacobian
10092 ! internally by difference quotients.
10093 ! E. Next decide whether or not to provide the initial value of the
10094 ! derivative vector dy/dt. If the initial value of A(t,y) is
10095 ! nonsingular (and not too ill-conditioned), you may let DLSODI compute
10096 ! this vector (ISTATE = 0). (DLSODI will solve the system A*s = g for
10097 ! s, with initial values of A and g.) If A(t,y) is initially
10098 ! singular, then the system is a differential-algebraic system, and
10099 ! you must make use of the particular form of the system to compute the
10100 ! initial values of y and dy/dt. In that case, use ISTATE = 1 and
10101 ! load the initial value of dy/dt into the array YDOTI.
10102 ! The input array YDOTI and the initial Y array must be consistent with
10103 ! the equations A*dy/dt = g. This implies that the initial residual
10104 ! r = g(t,y) - A(t,y)*YDOTI must be approximately zero.
10105 ! F. Write a main program which calls Subroutine DLSODI once for
10106 ! each point at which answers are desired. This should also provide
10107 ! for possible use of logical unit 6 for output of error messages
10108 ! by DLSODI. On the first call to DLSODI, supply arguments as follows:
10109 ! RES = name of user subroutine for residual function r.
10110 ! ADDA = name of user subroutine for computing and adding A(t,y).
10111 ! JAC = name of user subroutine for Jacobian matrix dr/dy
10112 ! (MF = 21 or 24). If not used, pass a dummy name.
10113 ! Note: the names for the RES and ADDA routines and (if used) the
10114 ! JAC routine must be declared External in the calling program.
10115 ! NEQ = number of scalar equations in the system.
10116 ! Y = array of initial values, of length NEQ.
10117 ! YDOTI = array of length NEQ (containing initial dy/dt if ISTATE = 1).
10118 ! T = the initial value of the independent variable.
10119 ! TOUT = first point where output is desired (.ne. T).
10120 ! ITOL = 1 or 2 according as ATOL (below) is a scalar or array.
10121 ! RTOL = relative tolerance parameter (scalar).
10122 ! ATOL = absolute tolerance parameter (scalar or array).
10123 ! the estimated local error in y(i) will be controlled so as
10124 ! to be roughly less (in magnitude) than
10125 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or
10126 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2.
10127 ! Thus the local error test passes if, in each component,
10128 ! either the absolute error is less than ATOL (or ATOL(i)),
10129 ! or the relative error is less than RTOL.
10130 ! Use RTOL = 0.0 for pure absolute error control, and
10131 ! use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative error
10132 ! control. Caution: Actual (global) errors may exceed these
10133 ! local tolerances, so choose them conservatively.
10134 ! ITASK = 1 for normal computation of output values of y at t = TOUT.
10135 ! ISTATE = integer flag (input and output). Set ISTATE = 1 if the
10136 ! initial dy/dt is supplied, and 0 otherwise.
10137 ! IOPT = 0 to indicate no optional inputs used.
10138 ! RWORK = real work array of length at least:
10139 ! 22 + 9*NEQ + NEQ**2 for MF = 21 or 22,
10140 ! 22 + 10*NEQ + (2*ML + MU)*NEQ for MF = 24 or 25.
10141 ! LRW = declared length of RWORK (in user's dimension).
10142 ! IWORK = integer work array of length at least 20 + NEQ.
10143 ! If MF = 24 or 25, input in IWORK(1),IWORK(2) the lower
10144 ! and upper half-bandwidths ML,MU.
10145 ! LIW = declared length of IWORK (in user's dimension).
10146 ! MF = method flag. Standard values are:
10147 ! 21 for a user-supplied full Jacobian.
10148 ! 22 for an internally generated full Jacobian.
10149 ! 24 for a user-supplied banded Jacobian.
10150 ! 25 for an internally generated banded Jacobian.
10151 ! for other choices of MF, see the paragraph on MF in
10152 ! the full description below.
10153 ! Note that the main program must declare arrays Y, YDOTI, RWORK, IWORK,
10154 ! and possibly ATOL.
10155 ! G. The output from the first call (or any call) is:
10156 ! Y = array of computed values of y(t) vector.
10157 ! T = corresponding value of independent variable (normally TOUT).
10158 ! ISTATE = 2 if DLSODI was successful, negative otherwise.
10159 ! -1 means excess work done on this call (check all inputs).
10160 ! -2 means excess accuracy requested (tolerances too small).
10161 ! -3 means illegal input detected (see printed message).
10162 ! -4 means repeated error test failures (check all inputs).
10163 ! -5 means repeated convergence failures (perhaps bad Jacobian
10164 ! supplied or wrong choice of tolerances).
10165 ! -6 means error weight became zero during problem. (Solution
10166 ! component i vanished, and ATOL or ATOL(i) = 0.)
10167 ! -7 cannot occur in casual use.
10168 ! -8 means DLSODI was unable to compute the initial dy/dt.
10169 ! In casual use, this means A(t,y) is initially singular.
10170 ! Supply YDOTI and use ISTATE = 1 on the first call.
10171 ! If DLSODI returns ISTATE = -1, -4, or -5, then the output of
10172 ! DLSODI also includes YDOTI = array containing residual vector
10173 ! r = g - A * dy/dt evaluated at the current t, y, and dy/dt.
10174 ! H. To continue the integration after a successful return, simply
10175 ! reset TOUT and call DLSODI again. No other parameters need be reset.
10176 !-----------------------------------------------------------------------
10177 ! Example Problem.
10178 ! The following is a simple example problem, with the coding
10179 ! needed for its solution by DLSODI. The problem is from chemical
10180 ! kinetics, and consists of the following three equations:
10181 ! dy1/dt = -.04*y1 + 1.e4*y2*y3
10182 ! dy2/dt = .04*y1 - 1.e4*y2*y3 - 3.e7*y2**2
10183 ! 0. = y1 + y2 + y3 - 1.
10184 ! on the interval from t = 0.0 to t = 4.e10, with initial conditions
10185 ! y1 = 1.0, y2 = y3 = 0.
10186 ! The following coding solves this problem with DLSODI, using MF = 21
10187 ! and printing results at t = .4, 4., ..., 4.e10. It uses
10188 ! ITOL = 2 and ATOL much smaller for y2 than y1 or y3 because
10189 ! y2 has much smaller values. dy/dt is supplied in YDOTI. We had
10190 ! obtained the initial value of dy3/dt by differentiating the
10191 ! third equation and evaluating the first two at t = 0.
10192 ! At the end of the run, statistical quantities of interest are
10193 ! printed (see optional outputs in the full description below).
10194 ! EXTERNAL RESID, APLUSP, DGBYDY
10195 ! DOUBLE PRECISION ATOL, RTOL, RWORK, T, TOUT, Y, YDOTI
10196 ! DIMENSION Y(3), YDOTI(3), ATOL(3), RWORK(58), IWORK(23)
10197 ! NEQ = 3
10198 ! Y(1) = 1.
10199 ! Y(2) = 0.
10200 ! Y(3) = 0.
10201 ! YDOTI(1) = -.04
10202 ! YDOTI(2) = .04
10203 ! YDOTI(3) = 0.
10204 ! T = 0.
10205 ! TOUT = .4
10206 ! ITOL = 2
10207 ! RTOL = 1.D-4
10208 ! ATOL(1) = 1.D-6
10209 ! ATOL(2) = 1.D-10
10210 ! ATOL(3) = 1.D-6
10211 ! ITASK = 1
10212 ! ISTATE = 1
10213 ! IOPT = 0
10214 ! LRW = 58
10215 ! LIW = 23
10216 ! MF = 21
10217 ! DO 40 IOUT = 1,12
10218 ! CALL DLSODI(RESID, APLUSP, DGBYDY, NEQ, Y, YDOTI, T, TOUT, ITOL,
10219 ! 1 RTOL, ATOL, ITASK, ISTATE, IOPT, RWORK, LRW, IWORK, LIW, MF)
10220 ! WRITE (6,20) T, Y(1), Y(2), Y(3)
10221 ! 20 FORMAT(' At t =',D12.4,' Y =',3D14.6)
10222 ! IF (ISTATE .LT. 0 ) GO TO 80
10223 ! 40 TOUT = TOUT*10.
10224 ! WRITE (6,60) IWORK(11), IWORK(12), IWORK(13)
10225 ! 60 FORMAT(/' No. steps =',I4,' No. r-s =',I4,' No. J-s =',I4)
10226 ! STOP
10227 ! 80 WRITE (6,90) ISTATE
10228 ! 90 FORMAT(///' Error halt.. ISTATE =',I3)
10229 ! STOP
10230 ! END
10231 ! SUBROUTINE RESID(NEQ, T, Y, S, R, IRES)
10232 ! DOUBLE PRECISION T, Y, S, R
10233 ! DIMENSION Y(3), S(3), R(3)
10234 ! R(1) = -.04*Y(1) + 1.D4*Y(2)*Y(3) - S(1)
10235 ! R(2) = .04*Y(1) - 1.D4*Y(2)*Y(3) - 3.D7*Y(2)*Y(2) - S(2)
10236 ! R(3) = Y(1) + Y(2) + Y(3) - 1.
10237 ! RETURN
10238 ! END
10239 ! SUBROUTINE APLUSP(NEQ, T, Y, ML, MU, P, NROWP)
10240 ! DOUBLE PRECISION T, Y, P
10241 ! DIMENSION Y(3), P(NROWP,3)
10242 ! P(1,1) = P(1,1) + 1.
10243 ! P(2,2) = P(2,2) + 1.
10244 ! RETURN
10245 ! END
10246 ! SUBROUTINE DGBYDY(NEQ, T, Y, S, ML, MU, P, NROWP)
10247 ! DOUBLE PRECISION T, Y, S, P
10248 ! DIMENSION Y(3), S(3), P(NROWP,3)
10249 ! P(1,1) = -.04
10250 ! P(1,2) = 1.D4*Y(3)
10251 ! P(1,3) = 1.D4*Y(2)
10252 ! P(2,1) = .04
10253 ! P(2,2) = -1.D4*Y(3) - 6.D7*Y(2)
10254 ! P(2,3) = -1.D4*Y(2)
10255 ! P(3,1) = 1.
10256 ! P(3,2) = 1.
10257 ! P(3,3) = 1.
10258 ! RETURN
10259 ! END
10260 ! The output of this program (on a CDC-7600 in single precision)
10261 ! is as follows:
10262 ! At t = 4.0000e-01 Y = 9.851726e-01 3.386406e-05 1.479357e-02
10263 ! At t = 4.0000e+00 Y = 9.055142e-01 2.240418e-05 9.446344e-02
10264 ! At t = 4.0000e+01 Y = 7.158050e-01 9.184616e-06 2.841858e-01
10265 ! At t = 4.0000e+02 Y = 4.504846e-01 3.222434e-06 5.495122e-01
10266 ! At t = 4.0000e+03 Y = 1.831701e-01 8.940379e-07 8.168290e-01
10267 ! At t = 4.0000e+04 Y = 3.897016e-02 1.621193e-07 9.610297e-01
10268 ! At t = 4.0000e+05 Y = 4.935213e-03 1.983756e-08 9.950648e-01
10269 ! At t = 4.0000e+06 Y = 5.159269e-04 2.064759e-09 9.994841e-01
10270 ! At t = 4.0000e+07 Y = 5.306413e-05 2.122677e-10 9.999469e-01
10271 ! At t = 4.0000e+08 Y = 5.494532e-06 2.197826e-11 9.999945e-01
10272 ! At t = 4.0000e+09 Y = 5.129457e-07 2.051784e-12 9.999995e-01
10273 ! At t = 4.0000e+10 Y = -7.170472e-08 -2.868188e-13 1.000000e+00
10274 ! No. steps = 330 No. r-s = 404 No. J-s = 69
10275 !-----------------------------------------------------------------------
10276 ! Full Description of User Interface to DLSODI.
10277 ! The user interface to DLSODI consists of the following parts.
10278 ! 1. The call sequence to Subroutine DLSODI, which is a driver
10279 ! routine for the solver. This includes descriptions of both
10280 ! the call sequence arguments and of user-supplied routines.
10281 ! Following these descriptions is a description of
10282 ! optional inputs available through the call sequence, and then
10283 ! a description of optional outputs (in the work arrays).
10284 ! 2. Descriptions of other routines in the DLSODI package that may be
10285 ! (optionally) called by the user. These provide the ability to
10286 ! alter error message handling, save and restore the internal
10287 ! Common, and obtain specified derivatives of the solution y(t).
10288 ! 3. Descriptions of Common blocks to be declared in overlay
10289 ! or similar environments, or to be saved when doing an interrupt
10290 ! of the problem and continued solution later.
10291 ! 4. Description of two routines in the DLSODI package, either of
10292 ! which the user may replace with his/her own version, if desired.
10293 ! These relate to the measurement of errors.
10294 !-----------------------------------------------------------------------
10295 ! Part 1. Call Sequence.
10296 ! The call sequence parameters used for input only are
10297 ! RES, ADDA, JAC, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK,
10298 ! IOPT, LRW, LIW, MF,
10299 ! and those used for both input and output are
10300 ! Y, T, ISTATE, YDOTI.
10301 ! The work arrays RWORK and IWORK are also used for conditional and
10302 ! optional inputs and optional outputs. (The term output here refers
10303 ! to the return from Subroutine DLSODI to the user's calling program.)
10304 ! The legality of input parameters will be thoroughly checked on the
10305 ! initial call for the problem, but not checked thereafter unless a
10306 ! change in input parameters is flagged by ISTATE = 3 on input.
10307 ! The descriptions of the call arguments are as follows.
10308 ! RES = the name of the user-supplied subroutine which supplies
10309 ! the residual vector for the ODE system, defined by
10310 ! r = g(t,y) - A(t,y) * s
10311 ! as a function of the scalar t and the vectors
10312 ! s and y (s approximates dy/dt). This subroutine
10313 ! is to have the form
10314 ! SUBROUTINE RES (NEQ, T, Y, S, R, IRES)
10315 ! DOUBLE PRECISION T, Y(*), S(*), R(*)
10316 ! where NEQ, T, Y, S, and IRES are input, and R and
10317 ! IRES are output. Y, S, and R are arrays of length NEQ.
10318 ! On input, IRES indicates how DLSODI will use the
10319 ! returned array R, as follows:
10320 ! IRES = 1 means that DLSODI needs the full residual,
10321 ! r = g - A*s, exactly.
10322 ! IRES = -1 means that DLSODI is using R only to compute
10323 ! the Jacobian dr/dy by difference quotients.
10324 ! The RES routine can ignore IRES, or it can omit some terms
10325 ! if IRES = -1. If A does not depend on y, then RES can
10326 ! just return R = g when IRES = -1. If g - A*s contains other
10327 ! additive terms that are independent of y, these can also be
10328 ! dropped, if done consistently, when IRES = -1.
10329 ! The subroutine should set the flag IRES if it
10330 ! encounters a halt condition or illegal input.
10331 ! Otherwise, it should not reset IRES. On output,
10332 ! IRES = 1 or -1 represents a normal return, and
10333 ! DLSODI continues integrating the ODE. Leave IRES
10334 ! unchanged from its input value.
10335 ! IRES = 2 tells DLSODI to immediately return control
10336 ! to the calling program, with ISTATE = 3. This lets
10337 ! the calling program change parameters of the problem,
10338 ! if necessary.
10339 ! IRES = 3 represents an error condition (for example, an
10340 ! illegal value of y). DLSODI tries to integrate the system
10341 ! without getting IRES = 3 from RES. If it cannot, DLSODI
10342 ! returns with ISTATE = -7 or -1.
10343 ! On an DLSODI return with ISTATE = 3, -1, or -7, the values
10344 ! of T and Y returned correspond to the last point reached
10345 ! successfully without getting the flag IRES = 2 or 3.
10346 ! The flag values IRES = 2 and 3 should not be used to
10347 ! handle switches or root-stop conditions. This is better
10348 ! done by calling DLSODI in a one-step mode and checking the
10349 ! stopping function for a sign change at each step.
10350 ! If quantities computed in the RES routine are needed
10351 ! externally to DLSODI, an extra call to RES should be made
10352 ! for this purpose, for consistent and accurate results.
10353 ! To get the current dy/dt for the S argument, use DINTDY.
10354 ! RES must be declared External in the calling
10355 ! program. See note below for more about RES.
10356 ! ADDA = the name of the user-supplied subroutine which adds the
10357 ! matrix A = A(t,y) to another matrix stored in the same form
10358 ! as A. The storage form is determined by MITER (see MF).
10359 ! This subroutine is to have the form
10360 ! SUBROUTINE ADDA (NEQ, T, Y, ML, MU, P, NROWP)
10361 ! DOUBLE PRECISION T, Y(*), P(NROWP,*)
10362 ! where NEQ, T, Y, ML, MU, and NROWP are input and P is
10363 ! output. Y is an array of length NEQ, and the matrix P is
10364 ! stored in an NROWP by NEQ array.
10365 ! In the full matrix case ( MITER = 1 or 2) ADDA should
10366 ! add A to P(i,j). ML and MU are ignored.
10367 ! i,j
10368 ! In the band matrix case ( MITER = 4 or 5) ADDA should
10369 ! add A to P(i-j+MU+1,j).
10370 ! i,j
10371 ! See JAC for details on this band storage form.
10372 ! ADDA must be declared External in the calling program.
10373 ! See note below for more information about ADDA.
10374 ! JAC = the name of the user-supplied subroutine which supplies the
10375 ! Jacobian matrix, dr/dy, where r = g - A*s. The form of the
10376 ! Jacobian matrix is determined by MITER. JAC is required
10377 ! if MITER = 1 or 4 -- otherwise a dummy name can be
10378 ! passed. This subroutine is to have the form
10379 ! SUBROUTINE JAC ( NEQ, T, Y, S, ML, MU, P, NROWP )
10380 ! DOUBLE PRECISION T, Y(*), S(*), P(NROWP,*)
10381 ! where NEQ, T, Y, S, ML, MU, and NROWP are input and P
10382 ! is output. Y and S are arrays of length NEQ, and the
10383 ! matrix P is stored in an NROWP by NEQ array.
10384 ! P is to be loaded with partial derivatives (elements
10385 ! of the Jacobian matrix) on output.
10386 ! In the full matrix case (MITER = 1), ML and MU
10387 ! are ignored and the Jacobian is to be loaded into P
10388 ! by columns-- i.e., dr(i)/dy(j) is loaded into P(i,j).
10389 ! In the band matrix case (MITER = 4), the elements
10390 ! within the band are to be loaded into P by columns,
10391 ! with diagonal lines of dr/dy loaded into the
10392 ! rows of P. Thus dr(i)/dy(j) is to be loaded
10393 ! into P(i-j+MU+1,j). The locations in P in the two
10394 ! triangular areas which correspond to nonexistent matrix
10395 ! elements can be ignored or loaded arbitrarily, as they
10396 ! they are overwritten by DLSODI. ML and MU are the
10397 ! half-bandwidth parameters (see IWORK).
10398 ! In either case, P is preset to zero by the solver,
10399 ! so that only the nonzero elements need be loaded by JAC.
10400 ! Each call to JAC is preceded by a call to RES with the same
10401 ! arguments NEQ, T, Y, and S. Thus to gain some efficiency,
10402 ! intermediate quantities shared by both calculations may be
10403 ! saved in a user Common block by RES and not recomputed by JAC
10404 ! if desired. Also, JAC may alter the Y array, if desired.
10405 ! JAC need not provide dr/dy exactly. A crude
10406 ! approximation (possibly with a smaller bandwidth) will do.
10407 ! JAC must be declared External in the calling program.
10408 ! See note below for more about JAC.
10409 ! Note on RES, ADDA, and JAC:
10410 ! These subroutines may access user-defined quantities in
10411 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
10412 ! (dimensioned in the subroutines) and/or Y has length
10413 ! exceeding NEQ(1). However, these routines should not alter
10414 ! NEQ(1), Y(1),...,Y(NEQ) or any other input variables.
10415 ! See the descriptions of NEQ and Y below.
10416 ! NEQ = the size of the system (number of first order ordinary
10417 ! differential equations or scalar algebraic equations).
10418 ! Used only for input.
10419 ! NEQ may be decreased, but not increased, during the problem.
10420 ! If NEQ is decreased (with ISTATE = 3 on input), the
10421 ! remaining components of Y should be left undisturbed, if
10422 ! these are to be accessed in RES, ADDA, or JAC.
10423 ! Normally, NEQ is a scalar, and it is generally referred to
10424 ! as a scalar in this user interface description. However,
10425 ! NEQ may be an array, with NEQ(1) set to the system size.
10426 ! (The DLSODI package accesses only NEQ(1).) In either case,
10427 ! this parameter is passed as the NEQ argument in all calls
10428 ! to RES, ADDA, and JAC. Hence, if it is an array,
10429 ! locations NEQ(2),... may be used to store other integer data
10430 ! and pass it to RES, ADDA, or JAC. Each such subroutine
10431 ! must include NEQ in a Dimension statement in that case.
10432 ! Y = a real array for the vector of dependent variables, of
10433 ! length NEQ or more. Used for both input and output on the
10434 ! first call (ISTATE = 0 or 1), and only for output on other
10435 ! calls. On the first call, Y must contain the vector of
10436 ! initial values. On output, Y contains the computed solution
10437 ! vector, evaluated at T. If desired, the Y array may be used
10438 ! for other purposes between calls to the solver.
10439 ! This array is passed as the Y argument in all calls to RES,
10440 ! ADDA, and JAC. Hence its length may exceed NEQ,
10441 ! and locations Y(NEQ+1),... may be used to store other real
10442 ! data and pass it to RES, ADDA, or JAC. (The DLSODI
10443 ! package accesses only Y(1),...,Y(NEQ). )
10444 ! YDOTI = a real array for the initial value of the vector
10445 ! dy/dt and for work space, of dimension at least NEQ.
10446 ! On input:
10447 ! If ISTATE = 0, then DLSODI will compute the initial value
10448 ! of dy/dt, if A is nonsingular. Thus YDOTI will
10449 ! serve only as work space and may have any value.
10450 ! If ISTATE = 1, then YDOTI must contain the initial value
10451 ! of dy/dt.
10452 ! If ISTATE = 2 or 3 (continuation calls), then YDOTI
10453 ! may have any value.
10454 ! Note: If the initial value of A is singular, then
10455 ! DLSODI cannot compute the initial value of dy/dt, so
10456 ! it must be provided in YDOTI, with ISTATE = 1.
10457 ! On output, when DLSODI terminates abnormally with ISTATE =
10458 ! -1, -4, or -5, YDOTI will contain the residual
10459 ! r = g(t,y) - A(t,y)*(dy/dt). If r is large, t is near
10460 ! its initial value, and YDOTI is supplied with ISTATE = 1,
10461 ! then there may have been an incorrect input value of
10462 ! YDOTI = dy/dt, or the problem (as given to DLSODI)
10463 ! may not have a solution.
10464 ! If desired, the YDOTI array may be used for other
10465 ! purposes between calls to the solver.
10466 ! T = the independent variable. On input, T is used only on the
10467 ! first call, as the initial point of the integration.
10468 ! On output, after each call, T is the value at which a
10469 ! computed solution Y is evaluated (usually the same as TOUT).
10470 ! on an error return, T is the farthest point reached.
10471 ! TOUT = the next value of t at which a computed solution is desired.
10472 ! Used only for input.
10473 ! When starting the problem (ISTATE = 0 or 1), TOUT may be
10474 ! equal to T for one call, then should .ne. T for the next
10475 ! call. For the initial T, an input value of TOUT .ne. T is
10476 ! used in order to determine the direction of the integration
10477 ! (i.e. the algebraic sign of the step sizes) and the rough
10478 ! scale of the problem. Integration in either direction
10479 ! (forward or backward in t) is permitted.
10480 ! If ITASK = 2 or 5 (one-step modes), TOUT is ignored after
10481 ! the first call (i.e. the first call with TOUT .ne. T).
10482 ! Otherwise, TOUT is required on every call.
10483 ! If ITASK = 1, 3, or 4, the values of TOUT need not be
10484 ! monotone, but a value of TOUT which backs up is limited
10485 ! to the current internal T interval, whose endpoints are
10486 ! TCUR - HU and TCUR (see optional outputs, below, for
10487 ! TCUR and HU).
10488 ! ITOL = an indicator for the type of error control. See
10489 ! description below under ATOL. Used only for input.
10490 ! RTOL = a relative error tolerance parameter, either a scalar or
10491 ! an array of length NEQ. See description below under ATOL.
10492 ! Input only.
10493 ! ATOL = an absolute error tolerance parameter, either a scalar or
10494 ! an array of length NEQ. Input only.
10495 ! The input parameters ITOL, RTOL, and ATOL determine
10496 ! the error control performed by the solver. The solver will
10497 ! control the vector E = (E(i)) of estimated local errors
10498 ! in y, according to an inequality of the form
10499 ! RMS-norm of ( E(i)/EWT(i) ) .le. 1,
10500 ! where EWT(i) = RTOL(i)*ABS(Y(i)) + ATOL(i),
10501 ! and the RMS-norm (root-mean-square norm) here is
10502 ! RMS-norm(v) = SQRT(sum v(i)**2 / NEQ). Here EWT = (EWT(i))
10503 ! is a vector of weights which must always be positive, and
10504 ! the values of RTOL and ATOL should all be non-negative.
10505 ! The following table gives the types (scalar/array) of
10506 ! RTOL and ATOL, and the corresponding form of EWT(i).
10507 ! ITOL RTOL ATOL EWT(i)
10508 ! 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
10509 ! 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
10510 ! 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
10511 ! 4 array scalar RTOL(i)*ABS(Y(i)) + ATOL(i)
10512 ! When either of these parameters is a scalar, it need not
10513 ! be dimensioned in the user's calling program.
10514 ! If none of the above choices (with ITOL, RTOL, and ATOL
10515 ! fixed throughout the problem) is suitable, more general
10516 ! error controls can be obtained by substituting
10517 ! user-supplied routines for the setting of EWT and/or for
10518 ! the norm calculation. See Part 4 below.
10519 ! If global errors are to be estimated by making a repeated
10520 ! run on the same problem with smaller tolerances, then all
10521 ! components of RTOL and ATOL (i.e. of EWT) should be scaled
10522 ! down uniformly.
10523 ! ITASK = an index specifying the task to be performed.
10524 ! Input only. ITASK has the following values and meanings.
10525 ! 1 means normal computation of output values of y(t) at
10526 ! t = TOUT (by overshooting and interpolating).
10527 ! 2 means take one step only and return.
10528 ! 3 means stop at the first internal mesh point at or
10529 ! beyond t = TOUT and return.
10530 ! 4 means normal computation of output values of y(t) at
10531 ! t = TOUT but without overshooting t = TCRIT.
10532 ! TCRIT must be input as RWORK(1). TCRIT may be equal to
10533 ! or beyond TOUT, but not behind it in the direction of
10534 ! integration. This option is useful if the problem
10535 ! has a singularity at or beyond t = TCRIT.
10536 ! 5 means take one step, without passing TCRIT, and return.
10537 ! TCRIT must be input as RWORK(1).
10538 ! Note: If ITASK = 4 or 5 and the solver reaches TCRIT
10539 ! (within roundoff), it will return T = TCRIT (exactly) to
10540 ! indicate this (unless ITASK = 4 and TOUT comes before TCRIT,
10541 ! in which case answers at t = TOUT are returned first).
10542 ! ISTATE = an index used for input and output to specify the
10543 ! state of the calculation.
10544 ! On input, the values of ISTATE are as follows.
10545 ! 0 means this is the first call for the problem, and
10546 ! DLSODI is to compute the initial value of dy/dt
10547 ! (while doing other initializations). See note below.
10548 ! 1 means this is the first call for the problem, and
10549 ! the initial value of dy/dt has been supplied in
10550 ! YDOTI (DLSODI will do other initializations). See note
10551 ! below.
10552 ! 2 means this is not the first call, and the calculation
10553 ! is to continue normally, with no change in any input
10554 ! parameters except possibly TOUT and ITASK.
10555 ! (If ITOL, RTOL, and/or ATOL are changed between calls
10556 ! with ISTATE = 2, the new values will be used but not
10557 ! tested for legality.)
10558 ! 3 means this is not the first call, and the
10559 ! calculation is to continue normally, but with
10560 ! a change in input parameters other than
10561 ! TOUT and ITASK. Changes are allowed in
10562 ! NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF, ML, MU,
10563 ! and any of the optional inputs except H0.
10564 ! (See IWORK description for ML and MU.)
10565 ! Note: A preliminary call with TOUT = T is not counted
10566 ! as a first call here, as no initialization or checking of
10567 ! input is done. (Such a call is sometimes useful for the
10568 ! purpose of outputting the initial conditions.)
10569 ! Thus the first call for which TOUT .ne. T requires
10570 ! ISTATE = 0 or 1 on input.
10571 ! On output, ISTATE has the following values and meanings.
10572 ! 0 or 1 means nothing was done; TOUT = t and
10573 ! ISTATE = 0 or 1 on input.
10574 ! 2 means that the integration was performed successfully.
10575 ! 3 means that the user-supplied Subroutine RES signalled
10576 ! DLSODI to halt the integration and return (IRES = 2).
10577 ! Integration as far as T was achieved with no occurrence
10578 ! of IRES = 2, but this flag was set on attempting the
10579 ! next step.
10580 ! -1 means an excessive amount of work (more than MXSTEP
10581 ! steps) was done on this call, before completing the
10582 ! requested task, but the integration was otherwise
10583 ! successful as far as T. (MXSTEP is an optional input
10584 ! and is normally 500.) To continue, the user may
10585 ! simply reset ISTATE to a value .gt. 1 and call again
10586 ! (the excess work step counter will be reset to 0).
10587 ! In addition, the user may increase MXSTEP to avoid
10588 ! this error return (see below on optional inputs).
10589 ! -2 means too much accuracy was requested for the precision
10590 ! of the machine being used. This was detected before
10591 ! completing the requested task, but the integration
10592 ! was successful as far as T. To continue, the tolerance
10593 ! parameters must be reset, and ISTATE must be set
10594 ! to 3. The optional output TOLSF may be used for this
10595 ! purpose. (Note: If this condition is detected before
10596 ! taking any steps, then an illegal input return
10597 ! (ISTATE = -3) occurs instead.)
10598 ! -3 means illegal input was detected, before taking any
10599 ! integration steps. See written message for details.
10600 ! Note: If the solver detects an infinite loop of calls
10601 ! to the solver with illegal input, it will cause
10602 ! the run to stop.
10603 ! -4 means there were repeated error test failures on
10604 ! one attempted step, before completing the requested
10605 ! task, but the integration was successful as far as T.
10606 ! The problem may have a singularity, or the input
10607 ! may be inappropriate.
10608 ! -5 means there were repeated convergence test failures on
10609 ! one attempted step, before completing the requested
10610 ! task, but the integration was successful as far as T.
10611 ! This may be caused by an inaccurate Jacobian matrix.
10612 ! -6 means EWT(i) became zero for some i during the
10613 ! integration. pure relative error control (ATOL(i)=0.0)
10614 ! was requested on a variable which has now vanished.
10615 ! the integration was successful as far as T.
10616 ! -7 means that the user-supplied Subroutine RES set
10617 ! its error flag (IRES = 3) despite repeated tries by
10618 ! DLSODI to avoid that condition.
10619 ! -8 means that ISTATE was 0 on input but DLSODI was unable
10620 ! to compute the initial value of dy/dt. See the
10621 ! printed message for details.
10622 ! Note: Since the normal output value of ISTATE is 2,
10623 ! it does not need to be reset for normal continuation.
10624 ! Similarly, ISTATE (= 3) need not be reset if RES told
10625 ! DLSODI to return because the calling program must change
10626 ! the parameters of the problem.
10627 ! Also, since a negative input value of ISTATE will be
10628 ! regarded as illegal, a negative output value requires the
10629 ! user to change it, and possibly other inputs, before
10630 ! calling the solver again.
10631 ! IOPT = an integer flag to specify whether or not any optional
10632 ! inputs are being used on this call. Input only.
10633 ! The optional inputs are listed separately below.
10634 ! IOPT = 0 means no optional inputs are being used.
10635 ! Default values will be used in all cases.
10636 ! IOPT = 1 means one or more optional inputs are being used.
10637 ! RWORK = a real working array (double precision).
10638 ! The length of RWORK must be at least
10639 ! 20 + NYH*(MAXORD + 1) + 3*NEQ + LENWM where
10640 ! NYH = the initial value of NEQ,
10641 ! MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a
10642 ! smaller value is given as an optional input),
10643 ! LENWM = NEQ**2 + 2 if MITER is 1 or 2, and
10644 ! LENWM = (2*ML+MU+1)*NEQ + 2 if MITER is 4 or 5.
10645 ! (See MF description for the definition of METH and MITER.)
10646 ! Thus if MAXORD has its default value and NEQ is constant,
10647 ! this length is
10648 ! 22 + 16*NEQ + NEQ**2 for MF = 11 or 12,
10649 ! 22 + 17*NEQ + (2*ML+MU)*NEQ for MF = 14 or 15,
10650 ! 22 + 9*NEQ + NEQ**2 for MF = 21 or 22,
10651 ! 22 + 10*NEQ + (2*ML+MU)*NEQ for MF = 24 or 25.
10652 ! The first 20 words of RWORK are reserved for conditional
10653 ! and optional inputs and optional outputs.
10654 ! The following word in RWORK is a conditional input:
10655 ! RWORK(1) = TCRIT = critical value of t which the solver
10656 ! is not to overshoot. Required if ITASK is
10657 ! 4 or 5, and ignored otherwise. (See ITASK.)
10658 ! LRW = the length of the array RWORK, as declared by the user.
10659 ! (This will be checked by the solver.)
10660 ! IWORK = an integer work array. The length of IWORK must be at least
10661 ! 20 + NEQ . The first few words of IWORK are used for
10662 ! conditional and optional inputs and optional outputs.
10663 ! The following 2 words in IWORK are conditional inputs:
10664 ! IWORK(1) = ML These are the lower and upper
10665 ! IWORK(2) = MU half-bandwidths, respectively, of the
10666 ! matrices in the problem-- the Jacobian dr/dy
10667 ! and the left-hand side matrix A. These
10668 ! half-bandwidths exclude the main diagonal,
10669 ! so the total bandwidth is ML + MU + 1 .
10670 ! The band is defined by the matrix locations
10671 ! (i,j) with i-ML .le. j .le. i+MU. ML and MU
10672 ! must satisfy 0 .le. ML,MU .le. NEQ-1.
10673 ! These are required if MITER is 4 or 5, and
10674 ! ignored otherwise.
10675 ! ML and MU may in fact be the band parameters
10676 ! for matrices to which dr/dy and A are only
10677 ! approximately equal.
10678 ! LIW = the length of the array IWORK, as declared by the user.
10679 ! (This will be checked by the solver.)
10680 ! Note: The work arrays must not be altered between calls to DLSODI
10681 ! for the same problem, except possibly for the conditional and
10682 ! optional inputs, and except for the last 3*NEQ words of RWORK.
10683 ! The latter space is used for internal scratch space, and so is
10684 ! available for use by the user outside DLSODI between calls, if
10685 ! desired (but not for use by RES, ADDA, or JAC).
10686 ! MF = the method flag. Used only for input. The legal values of
10687 ! MF are 11, 12, 14, 15, 21, 22, 24, and 25.
10688 ! MF has decimal digits METH and MITER: MF = 10*METH + MITER.
10689 ! METH indicates the basic linear multistep method:
10690 ! METH = 1 means the implicit Adams method.
10691 ! METH = 2 means the method based on Backward
10692 ! Differentiation Formulas (BDFs).
10693 ! The BDF method is strongly preferred for stiff
10694 ! problems, while the Adams method is preferred when
10695 ! the problem is not stiff. If the matrix A(t,y) is
10696 ! nonsingular, stiffness here can be taken to mean that of
10697 ! the explicit ODE system dy/dt = A-inverse * g. If A is
10698 ! singular, the concept of stiffness is not well defined.
10699 ! If you do not know whether the problem is stiff, we
10700 ! recommend using METH = 2. If it is stiff, the advantage
10701 ! of METH = 2 over METH = 1 will be great, while if it is
10702 ! not stiff, the advantage of METH = 1 will be slight.
10703 ! If maximum efficiency is important, some experimentation
10704 ! with METH may be necessary.
10705 ! MITER indicates the corrector iteration method:
10706 ! MITER = 1 means chord iteration with a user-supplied
10707 ! full (NEQ by NEQ) Jacobian.
10708 ! MITER = 2 means chord iteration with an internally
10709 ! generated (difference quotient) full Jacobian.
10710 ! This uses NEQ+1 extra calls to RES per dr/dy
10711 ! evaluation.
10712 ! MITER = 4 means chord iteration with a user-supplied
10713 ! banded Jacobian.
10714 ! MITER = 5 means chord iteration with an internally
10715 ! generated banded Jacobian (using ML+MU+2
10716 ! extra calls to RES per dr/dy evaluation).
10717 ! If MITER = 1 or 4, the user must supply a Subroutine JAC
10718 ! (the name is arbitrary) as described above under JAC.
10719 ! For other values of MITER, a dummy argument can be used.
10720 !-----------------------------------------------------------------------
10721 ! Optional Inputs.
10722 ! The following is a list of the optional inputs provided for in the
10723 ! call sequence. (See also Part 2.) For each such input variable,
10724 ! this table lists its name as used in this documentation, its
10725 ! location in the call sequence, its meaning, and the default value.
10726 ! the use of any of these inputs requires IOPT = 1, and in that
10727 ! case all of these inputs are examined. A value of zero for any
10728 ! of these optional inputs will cause the default value to be used.
10729 ! Thus to use a subset of the optional inputs, simply preload
10730 ! locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, and
10731 ! then set those of interest to nonzero values.
10732 ! Name Location Meaning and Default Value
10733 ! H0 RWORK(5) the step size to be attempted on the first step.
10734 ! The default value is determined by the solver.
10735 ! HMAX RWORK(6) the maximum absolute step size allowed.
10736 ! The default value is infinite.
10737 ! HMIN RWORK(7) the minimum absolute step size allowed.
10738 ! The default value is 0. (This lower bound is not
10739 ! enforced on the final step before reaching TCRIT
10740 ! when ITASK = 4 or 5.)
10741 ! MAXORD IWORK(5) the maximum order to be allowed. The default
10742 ! value is 12 if METH = 1, and 5 if METH = 2.
10743 ! If MAXORD exceeds the default value, it will
10744 ! be reduced to the default value.
10745 ! If MAXORD is changed during the problem, it may
10746 ! cause the current order to be reduced.
10747 ! MXSTEP IWORK(6) maximum number of (internally defined) steps
10748 ! allowed during one call to the solver.
10749 ! The default value is 500.
10750 ! MXHNIL IWORK(7) maximum number of messages printed (per problem)
10751 ! warning that T + H = T on a step (H = step size).
10752 ! This must be positive to result in a non-default
10753 ! value. The default value is 10.
10754 !-----------------------------------------------------------------------
10755 ! Optional Outputs.
10756 ! As optional additional output from DLSODI, the variables listed
10757 ! below are quantities related to the performance of DLSODI
10758 ! which are available to the user. These are communicated by way of
10759 ! the work arrays, but also have internal mnemonic names as shown.
10760 ! Except where stated otherwise, all of these outputs are defined
10761 ! on any successful return from DLSODI, and on any return with
10762 ! ISTATE = -1, -2, -4, -5, -6, or -7. On a return with -3 (illegal
10763 ! input) or -8, they will be unchanged from their existing values
10764 ! (if any), except possibly for TOLSF, LENRW, and LENIW.
10765 ! On any error return, outputs relevant to the error will be defined,
10766 ! as noted below.
10767 ! Name Location Meaning
10768 ! HU RWORK(11) the step size in t last used (successfully).
10769 ! HCUR RWORK(12) the step size to be attempted on the next step.
10770 ! TCUR RWORK(13) the current value of the independent variable
10771 ! which the solver has actually reached, i.e. the
10772 ! current internal mesh point in t. On output, TCUR
10773 ! will always be at least as far as the argument
10774 ! T, but may be farther (if interpolation was done).
10775 ! TOLSF RWORK(14) a tolerance scale factor, greater than 1.0,
10776 ! computed when a request for too much accuracy was
10777 ! detected (ISTATE = -3 if detected at the start of
10778 ! the problem, ISTATE = -2 otherwise). If ITOL is
10779 ! left unaltered but RTOL and ATOL are uniformly
10780 ! scaled up by a factor of TOLSF for the next call,
10781 ! then the solver is deemed likely to succeed.
10782 ! (The user may also ignore TOLSF and alter the
10783 ! tolerance parameters in any other way appropriate.)
10784 ! NST IWORK(11) the number of steps taken for the problem so far.
10785 ! NRE IWORK(12) the number of residual evaluations (RES calls)
10786 ! for the problem so far.
10787 ! NJE IWORK(13) the number of Jacobian evaluations (each involving
10788 ! an evaluation of A and dr/dy) for the problem so
10789 ! far. This equals the number of calls to ADDA and
10790 ! (if MITER = 1 or 4) JAC, and the number of matrix
10791 ! LU decompositions.
10792 ! NQU IWORK(14) the method order last used (successfully).
10793 ! NQCUR IWORK(15) the order to be attempted on the next step.
10794 ! IMXER IWORK(16) the index of the component of largest magnitude in
10795 ! the weighted local error vector ( E(i)/EWT(i) ),
10796 ! on an error return with ISTATE = -4 or -5.
10797 ! LENRW IWORK(17) the length of RWORK actually required.
10798 ! This is defined on normal returns and on an illegal
10799 ! input return for insufficient storage.
10800 ! LENIW IWORK(18) the length of IWORK actually required.
10801 ! This is defined on normal returns and on an illegal
10802 ! input return for insufficient storage.
10803 ! The following two arrays are segments of the RWORK array which
10804 ! may also be of interest to the user as optional outputs.
10805 ! For each array, the table below gives its internal name,
10806 ! its base address in RWORK, and its description.
10807 ! Name Base Address Description
10808 ! YH 21 the Nordsieck history array, of size NYH by
10809 ! (NQCUR + 1), where NYH is the initial value
10810 ! of NEQ. For j = 0,1,...,NQCUR, column j+1
10811 ! of YH contains HCUR**j/factorial(j) times
10812 ! the j-th derivative of the interpolating
10813 ! polynomial currently representing the solution,
10814 ! evaluated at t = TCUR.
10815 ! ACOR LENRW-NEQ+1 array of size NEQ used for the accumulated
10816 ! corrections on each step, scaled on output to
10817 ! represent the estimated local error in y on the
10818 ! last step. This is the vector E in the descrip-
10819 ! tion of the error control. It is defined only
10820 ! on a return from DLSODI with ISTATE = 2.
10821 !-----------------------------------------------------------------------
10822 ! Part 2. Other Routines Callable.
10823 ! The following are optional calls which the user may make to
10824 ! gain additional capabilities in conjunction with DLSODI.
10825 ! (The routines XSETUN and XSETF are designed to conform to the
10826 ! SLATEC error handling package.)
10827 ! Form of Call Function
10828 ! CALL XSETUN(LUN) Set the logical unit number, LUN, for
10829 ! output of messages from DLSODI, if
10830 ! the default is not desired.
10831 ! The default value of LUN is 6.
10832 ! CALL XSETF(MFLAG) Set a flag to control the printing of
10833 ! messages by DLSODI.
10834 ! MFLAG = 0 means do not print. (Danger:
10835 ! This risks losing valuable information.)
10836 ! MFLAG = 1 means print (the default).
10837 ! Either of the above calls may be made at
10838 ! any time and will take effect immediately.
10839 ! CALL DSRCOM(RSAV,ISAV,JOB) saves and restores the contents of
10840 ! the internal Common blocks used by
10841 ! DLSODI (see Part 3 below).
10842 ! RSAV must be a real array of length 218
10843 ! or more, and ISAV must be an integer
10844 ! array of length 37 or more.
10845 ! JOB=1 means save Common into RSAV/ISAV.
10846 ! JOB=2 means restore Common from RSAV/ISAV.
10847 ! DSRCOM is useful if one is
10848 ! interrupting a run and restarting
10849 ! later, or alternating between two or
10850 ! more problems solved with DLSODI.
10851 ! CALL DINTDY(,,,,,) Provide derivatives of y, of various
10852 ! (see below) orders, at a specified point t, if
10853 ! desired. It may be called only after
10854 ! a successful return from DLSODI.
10855 ! The detailed instructions for using DINTDY are as follows.
10856 ! The form of the call is:
10857 ! CALL DINTDY (T, K, RWORK(21), NYH, DKY, IFLAG)
10858 ! The input parameters are:
10859 ! T = value of independent variable where answers are desired
10860 ! (normally the same as the T last returned by DLSODI).
10861 ! For valid results, T must lie between TCUR - HU and TCUR.
10862 ! (See optional outputs for TCUR and HU.)
10863 ! K = integer order of the derivative desired. K must satisfy
10864 ! 0 .le. K .le. NQCUR, where NQCUR is the current order
10865 ! (see optional outputs). The capability corresponding
10866 ! to K = 0, i.e. computing y(T), is already provided
10867 ! by DLSODI directly. Since NQCUR .ge. 1, the first
10868 ! derivative dy/dt is always available with DINTDY.
10869 ! RWORK(21) = the base address of the history array YH.
10870 ! NYH = column length of YH, equal to the initial value of NEQ.
10871 ! The output parameters are:
10872 ! DKY = a real array of length NEQ containing the computed value
10873 ! of the K-th derivative of y(t).
10874 ! IFLAG = integer flag, returned as 0 if K and T were legal,
10875 ! -1 if K was illegal, and -2 if T was illegal.
10876 ! On an error return, a message is also written.
10877 !-----------------------------------------------------------------------
10878 ! Part 3. Common Blocks.
10879 ! If DLSODI is to be used in an overlay situation, the user
10880 ! must declare, in the primary overlay, the variables in:
10881 ! (1) the call sequence to DLSODI, and
10882 ! (2) the internal Common block
10883 ! /DLS001/ of length 255 (218 double precision words
10884 ! followed by 37 integer words),
10885 ! If DLSODI is used on a system in which the contents of internal
10886 ! Common blocks are not preserved between calls, the user should
10887 ! declare the above Common block in the calling program to insure
10888 ! that their contents are preserved.
10889 ! If the solution of a given problem by DLSODI is to be interrupted
10890 ! and then later continued, such as when restarting an interrupted run
10891 ! or alternating between two or more problems, the user should save,
10892 ! following the return from the last DLSODI call prior to the
10893 ! interruption, the contents of the call sequence variables and the
10894 ! internal Common blocks, and later restore these values before the
10895 ! next DLSODI call for that problem. To save and restore the Common
10896 ! blocks, use Subroutine DSRCOM (see Part 2 above).
10897 !-----------------------------------------------------------------------
10898 ! Part 4. Optionally Replaceable Solver Routines.
10899 ! Below are descriptions of two routines in the DLSODI package which
10900 ! relate to the measurement of errors. Either routine can be
10901 ! replaced by a user-supplied version, if desired. However, since such
10902 ! a replacement may have a major impact on performance, it should be
10903 ! done only when absolutely necessary, and only with great caution.
10904 ! (Note: The means by which the package version of a routine is
10905 ! superseded by the user's version may be system-dependent.)
10906 ! (a) DEWSET.
10907 ! The following subroutine is called just before each internal
10908 ! integration step, and sets the array of error weights, EWT, as
10909 ! described under ITOL/RTOL/ATOL above:
10910 ! SUBROUTINE DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
10911 ! where NEQ, ITOL, RTOL, and ATOL are as in the DLSODI call sequence,
10912 ! YCUR contains the current dependent variable vector, and
10913 ! EWT is the array of weights set by DEWSET.
10914 ! If the user supplies this subroutine, it must return in EWT(i)
10915 ! (i = 1,...,NEQ) a positive quantity suitable for comparing errors
10916 ! in y(i) to. The EWT array returned by DEWSET is passed to the DVNORM
10917 ! routine (see below), and also used by DLSODI in the computation
10918 ! of the optional output IMXER, the diagonal Jacobian approximation,
10919 ! and the increments for difference quotient Jacobians.
10920 ! In the user-supplied version of DEWSET, it may be desirable to use
10921 ! the current values of derivatives of y. Derivatives up to order NQ
10922 ! are available from the history array YH, described above under
10923 ! optional outputs. In DEWSET, YH is identical to the YCUR array,
10924 ! extended to NQ + 1 columns with a column length of NYH and scale
10925 ! factors of H**j/factorial(j). On the first call for the problem,
10926 ! given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
10927 ! NYH is the initial value of NEQ. The quantities NQ, H, and NST
10928 ! can be obtained by including in DEWSET the statements:
10929 ! DOUBLE PRECISION RLS
10930 ! COMMON /DLS001/ RLS(218),ILS(37)
10931 ! NQ = ILS(33)
10932 ! NST = ILS(34)
10933 ! H = RLS(212)
10934 ! Thus, for example, the current value of dy/dt can be obtained as
10935 ! YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is
10936 ! unnecessary when NST = 0).
10937 ! (b) DVNORM.
10938 ! The following is a real function routine which computes the weighted
10939 ! root-mean-square norm of a vector v:
10940 ! D = DVNORM (N, V, W)
10941 ! where:
10942 ! N = the length of the vector,
10943 ! V = real array of length N containing the vector,
10944 ! W = real array of length N containing weights,
10945 ! D = SQRT( (1/N) * sum(V(i)*W(i))**2 ).
10946 ! DVNORM is called with N = NEQ and with W(i) = 1.0/EWT(i), where
10947 ! EWT is as set by Subroutine DEWSET.
10948 ! If the user supplies this function, it should return a non-negative
10949 ! value of DVNORM suitable for use in the error control in DLSODI.
10950 ! None of the arguments should be altered by DVNORM.
10951 ! For example, a user-supplied DVNORM routine might:
10952 ! -substitute a max-norm of (V(i)*W(i)) for the RMS-norm, or
10953 ! -ignore some components of V in the norm, with the effect of
10954 ! suppressing the error control on those components of y.
10955 !-----------------------------------------------------------------------
10956 !***REVISION HISTORY (YYYYMMDD)
10957 ! 19800424 DATE WRITTEN
10958 ! 19800519 Corrected access of YH on forced order reduction;
10959 ! numerous corrections to prologues and other comments.
10960 ! 19800617 In main driver, added loading of SQRT(UROUND) in RWORK;
10961 ! minor corrections to main prologue.
10962 ! 19800903 Corrected ISTATE logic; minor changes in prologue.
10963 ! 19800923 Added zero initialization of HU and NQU.
10964 ! 19801028 Reorganized RES calls in AINVG, STODI, and PREPJI;
10965 ! in LSODI, corrected NRE increment and reset LDY0 at 580;
10966 ! numerous corrections to main prologue.
10967 ! 19801218 Revised XERRWD routine; minor corrections to main prologue.
10968 ! 19810330 Added Common block /LSI001/; use LSODE's INTDY and SOLSY;
10969 ! minor corrections to XERRWD and error message at 604;
10970 ! minor corrections to declarations; corrections to prologues.
10971 ! 19810818 Numerous revisions: replaced EWT by 1/EWT; used flags
10972 ! JCUR, ICF, IERPJ, IERSL between STODI and subordinates;
10973 ! added tuning parameters CCMAX, MAXCOR, MSBP, MXNCF;
10974 ! reorganized returns from STODI; reorganized type decls.;
10975 ! fixed message length in XERRWD; changed default LUNIT to 6;
10976 ! changed Common lengths; changed comments throughout.
10977 ! 19820906 Corrected use of ABS(H) in STODI; minor comment fixes.
10978 ! 19830510 Numerous revisions: revised diff. quotient increment;
10979 ! eliminated block /LSI001/, using IERPJ flag;
10980 ! revised STODI logic after PJAC return;
10981 ! revised tuning of H change and step attempts in STODI;
10982 ! corrections to main prologue and internal comments.
10983 ! 19870330 Major update: corrected comments throughout;
10984 ! removed TRET from Common; rewrote EWSET with 4 loops;
10985 ! fixed t test in INTDY; added Cray directives in STODI;
10986 ! in STODI, fixed DELP init. and logic around PJAC call;
10987 ! combined routines to save/restore Common;
10988 ! passed LEVEL = 0 in error message calls (except run abort).
10989 ! 20010425 Major update: convert source lines to upper case;
10990 ! added *DECK lines; changed from 1 to * in dummy dimensions;
10991 ! changed names R1MACH/D1MACH to RUMACH/DUMACH;
10992 ! renamed routines for uniqueness across single/double prec.;
10993 ! converted intrinsic names to generic form;
10994 ! removed ILLIN and NTREP (data loaded) from Common;
10995 ! removed all 'own' variables from Common;
10996 ! changed error messages to quoted strings;
10997 ! replaced XERRWV/XERRWD with 1993 revised version;
10998 ! converted prologues, comments, error messages to mixed case;
10999 ! converted arithmetic IF statements to logical IF statements;
11000 ! numerous corrections to prologues and internal comments.
11001 ! 20010507 Converted single precision source to double precision.
11002 ! 20020502 Corrected declarations in descriptions of user routines.
11003 ! 20031105 Restored 'own' variables to Common block, to enable
11004 ! interrupt/restart feature.
11005 ! 20031112 Added SAVE statements for data-loaded constants.
11006 ! 20031117 Changed internal names NRE, LSAVR to NFE, LSAVF resp.
11007 !-----------------------------------------------------------------------
11008 ! Other routines in the DLSODI package.
11009 ! In addition to Subroutine DLSODI, the DLSODI package includes the
11010 ! following subroutines and function routines:
11011 ! DAINVG computes the initial value of the vector
11012 ! dy/dt = A-inverse * g
11013 ! DINTDY computes an interpolated value of the y vector at t = TOUT.
11014 ! DSTODI is the core integrator, which does one step of the
11015 ! integration and the associated error control.
11016 ! DCFODE sets all method coefficients and test constants.
11017 ! DPREPJI computes and preprocesses the Jacobian matrix
11018 ! and the Newton iteration matrix P.
11019 ! DSOLSY manages solution of linear system in chord iteration.
11020 ! DEWSET sets the error weight vector EWT before each step.
11021 ! DVNORM computes the weighted RMS-norm of a vector.
11022 ! DSRCOM is a user-callable routine to save and restore
11023 ! the contents of the internal Common blocks.
11024 ! DGEFA and DGESL are routines from LINPACK for solving full
11025 ! systems of linear algebraic equations.
11026 ! DGBFA and DGBSL are routines from LINPACK for solving banded
11027 ! linear systems.
11028 ! DUMACH computes the unit roundoff in a machine-independent manner.
11029 ! XERRWD, XSETUN, XSETF, IXSAV, and IUMACH handle the printing of all
11030 ! error messages and warnings. XERRWD is machine-dependent.
11031 ! Note: DVNORM, DUMACH, IXSAV, and IUMACH are function routines.
11032 ! All the others are subroutines.
11033 !-----------------------------------------------------------------------
11034 ! EXTERNAL DPREPJI, DSOLSY
11035 ! DOUBLE PRECISION :: DUMACH, DVNORM
11036 ! INTEGER :: INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS, &
11037 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
11038 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
11039 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
11040 ! INTEGER :: I, I1, I2, IER, IFLAG, IMXER, IRES, KGO, &
11041 ! LENIW, LENRW, LENWM, LP, LYD0, ML, MORD, MU, MXHNL0, MXSTP0
11042 ! DOUBLE PRECISION :: ROWNS, &
11043 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
11044 ! DOUBLE PRECISION :: ATOLI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RTOLI, &
11045 ! TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0
11046 ! DIMENSION MORD(2)
11047 ! LOGICAL :: IHIT
11048 ! CHARACTER(60) :: MSG
11049 ! SAVE MORD, MXSTP0, MXHNL0
11050 !-----------------------------------------------------------------------
11051 ! The following internal Common block contains
11052 ! (a) variables which are local to any subroutine but whose values must
11053 ! be preserved between calls to the routine ("own" variables), and
11054 ! (b) variables which are communicated between subroutines.
11055 ! The block DLS001 is declared in subroutines DLSODI, DINTDY, DSTODI,
11056 ! DPREPJI, and DSOLSY.
11057 ! Groups of variables are replaced by dummy arrays in the Common
11058 ! declarations in routines where those variables are not used.
11059 !-----------------------------------------------------------------------
11060 ! COMMON /DLS001/ ROWNS(209), &
11061 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
11062 ! INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6), &
11063 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
11064 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
11065 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
11066 ! DATA MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
11067 !-----------------------------------------------------------------------
11068 ! Block A.
11069 ! This code block is executed on every call.
11070 ! It tests ISTATE and ITASK for legality and branches appropriately.
11071 ! If ISTATE .gt. 1 but the flag INIT shows that initialization has
11072 ! not yet been done, an error return occurs.
11073 ! If ISTATE = 0 or 1 and TOUT = T, return immediately.
11074 !-----------------------------------------------------------------------
11075 ! IF (ISTATE < 0 .OR. ISTATE > 3) GO TO 601
11076 ! IF (ITASK < 1 .OR. ITASK > 5) GO TO 602
11077 ! IF (ISTATE <= 1) GO TO 10
11078 ! IF (INIT == 0) GO TO 603
11079 ! IF (ISTATE == 2) GO TO 200
11080 ! GO TO 20
11081 ! 10 INIT = 0
11082 ! IF (TOUT == T) RETURN
11083 !-----------------------------------------------------------------------
11084 ! Block B.
11085 ! The next code block is executed for the initial call (ISTATE = 0 or 1)
11086 ! or for a continuation call with parameter changes (ISTATE = 3).
11087 ! It contains checking of all inputs and various initializations.
11088 ! First check legality of the non-optional inputs NEQ, ITOL, IOPT,
11089 ! MF, ML, and MU.
11090 !-----------------------------------------------------------------------
11091 ! 20 IF (NEQ(1) <= 0) GO TO 604
11092 ! IF (ISTATE <= 1) GO TO 25
11093 ! IF (NEQ(1) > N) GO TO 605
11094 ! 25 N = NEQ(1)
11095 ! IF (ITOL < 1 .OR. ITOL > 4) GO TO 606
11096 ! IF (IOPT < 0 .OR. IOPT > 1) GO TO 607
11097 ! METH = MF/10
11098 ! MITER = MF - 10*METH
11099 ! IF (METH < 1 .OR. METH > 2) GO TO 608
11100 ! IF (MITER <= 0 .OR. MITER > 5) GO TO 608
11101 ! IF (MITER == 3) GO TO 608
11102 ! IF (MITER < 3) GO TO 30
11103 ! ML = IWORK(1)
11104 ! MU = IWORK(2)
11105 ! IF (ML < 0 .OR. ML >= N) GO TO 609
11106 ! IF (MU < 0 .OR. MU >= N) GO TO 610
11107 ! 30 CONTINUE
11108 ! Next process and check the optional inputs. --------------------------
11109 ! IF (IOPT == 1) GO TO 40
11110 ! MAXORD = MORD(METH)
11111 ! MXSTEP = MXSTP0
11112 ! MXHNIL = MXHNL0
11113 ! IF (ISTATE <= 1) H0 = 0.0D0
11114 ! HMXI = 0.0D0
11115 ! HMIN = 0.0D0
11116 ! GO TO 60
11117 ! 40 MAXORD = IWORK(5)
11118 ! IF (MAXORD < 0) GO TO 611
11119 ! IF (MAXORD == 0) MAXORD = 100
11120 ! MAXORD = MIN(MAXORD,MORD(METH))
11121 ! MXSTEP = IWORK(6)
11122 ! IF (MXSTEP < 0) GO TO 612
11123 ! IF (MXSTEP == 0) MXSTEP = MXSTP0
11124 ! MXHNIL = IWORK(7)
11125 ! IF (MXHNIL < 0) GO TO 613
11126 ! IF (MXHNIL == 0) MXHNIL = MXHNL0
11127 ! IF (ISTATE > 1) GO TO 50
11128 ! H0 = RWORK(5)
11129 ! IF ((TOUT - T)*H0 < 0.0D0) GO TO 614
11130 ! 50 HMAX = RWORK(6)
11131 ! IF (HMAX < 0.0D0) GO TO 615
11132 ! HMXI = 0.0D0
11133 ! IF (HMAX > 0.0D0) HMXI = 1.0D0/HMAX
11134 ! HMIN = RWORK(7)
11135 ! IF (HMIN < 0.0D0) GO TO 616
11136 !-----------------------------------------------------------------------
11137 ! Set work array pointers and check lengths LRW and LIW.
11138 ! Pointers to segments of RWORK and IWORK are named by prefixing L to
11139 ! the name of the segment. E.g., the segment YH starts at RWORK(LYH).
11140 ! Segments of RWORK (in order) are denoted YH, WM, EWT, SAVR, ACOR.
11141 !-----------------------------------------------------------------------
11142 ! 60 LYH = 21
11143 ! IF (ISTATE <= 1) NYH = N
11144 ! LWM = LYH + (MAXORD + 1)*NYH
11145 ! IF (MITER <= 2) LENWM = N*N + 2
11146 ! IF (MITER >= 4) LENWM = (2*ML + MU + 1)*N + 2
11147 ! LEWT = LWM + LENWM
11148 ! LSAVF = LEWT + N
11149 ! LACOR = LSAVF + N
11150 ! LENRW = LACOR + N - 1
11151 ! IWORK(17) = LENRW
11152 ! LIWM = 1
11153 ! LENIW = 20 + N
11154 ! IWORK(18) = LENIW
11155 ! IF (LENRW > LRW) GO TO 617
11156 ! IF (LENIW > LIW) GO TO 618
11157 ! Check RTOL and ATOL for legality. ------------------------------------
11158 ! RTOLI = RTOL(1)
11159 ! ATOLI = ATOL(1)
11160 ! DO 70 I = 1,N
11161 ! IF (ITOL >= 3) RTOLI = RTOL(I)
11162 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
11163 ! IF (RTOLI < 0.0D0) GO TO 619
11164 ! IF (ATOLI < 0.0D0) GO TO 620
11165 ! 70 END DO
11166 ! IF (ISTATE <= 1) GO TO 100
11167 ! If ISTATE = 3, set flag to signal parameter changes to DSTODI. -------
11168 ! JSTART = -1
11169 ! IF (NQ <= MAXORD) GO TO 90
11170 ! MAXORD was reduced below NQ. Copy YH(*,MAXORD+2) into YDOTI.---------
11171 ! DO 80 I = 1,N
11172 ! YDOTI(I) = RWORK(I+LWM-1)
11173 ! 80 END DO
11174 ! Reload WM(1) = RWORK(lWM), since lWM may have changed. ---------------
11175 ! 90 RWORK(LWM) = SQRT(UROUND)
11176 ! IF (N == NYH) GO TO 200
11177 ! NEQ was reduced. Zero part of YH to avoid undefined references. -----
11178 ! I1 = LYH + L*NYH
11179 ! I2 = LYH + (MAXORD + 1)*NYH - 1
11180 ! IF (I1 > I2) GO TO 200
11181 ! DO 95 I = I1,I2
11182 ! RWORK(I) = 0.0D0
11183 ! 95 END DO
11184 ! GO TO 200
11185 !-----------------------------------------------------------------------
11186 ! Block C.
11187 ! The next block is for the initial call only (ISTATE = 0 or 1).
11188 ! It contains all remaining initializations, the call to DAINVG
11189 ! (if ISTATE = 1), and the calculation of the initial step size.
11190 ! The error weights in EWT are inverted after being loaded.
11191 !-----------------------------------------------------------------------
11192 ! 100 UROUND = DUMACH()
11193 ! TN = T
11194 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 105
11195 ! TCRIT = RWORK(1)
11196 ! IF ((TCRIT - TOUT)*(TOUT - T) < 0.0D0) GO TO 625
11197 ! IF (H0 /= 0.0D0 .AND. (T + H0 - TCRIT)*H0 > 0.0D0) &
11198 ! H0 = TCRIT - T
11199 ! 105 JSTART = 0
11200 ! RWORK(LWM) = SQRT(UROUND)
11201 ! NHNIL = 0
11202 ! NST = 0
11203 ! NFE = 0
11204 ! NJE = 0
11205 ! NSLAST = 0
11206 ! HU = 0.0D0
11207 ! NQU = 0
11208 ! CCMAX = 0.3D0
11209 ! MAXCOR = 3
11210 ! MSBP = 20
11211 ! MXNCF = 10
11212 ! Compute initial dy/dt, if necessary, and load it and initial Y into YH
11213 ! LYD0 = LYH + NYH
11214 ! LP = LWM + 1
11215 ! IF (ISTATE == 1) GO TO 120
11216 ! DLSODI must compute initial dy/dt (LYD0 points to YH(*,2)). ----------
11217 ! CALL DAINVG( RES, ADDA, NEQ, T, Y, RWORK(LYD0), MITER, &
11218 ! ML, MU, RWORK(LP), IWORK(21), IER )
11219 ! NFE = NFE + 1
11220 ! IF (IER < 0) GO TO 560
11221 ! IF (IER > 0) GO TO 565
11222 ! DO 115 I = 1,N
11223 ! RWORK(I+LYH-1) = Y(I)
11224 ! 115 END DO
11225 ! GO TO 130
11226 ! Initial dy/dt was supplied. Load into YH (LYD0 points to YH(*,2).). -
11227 ! 120 DO 125 I = 1,N
11228 ! RWORK(I+LYH-1) = Y(I)
11229 ! RWORK(I+LYD0-1) = YDOTI(I)
11230 ! 125 END DO
11231 ! Load and invert the EWT array. (H is temporarily set to 1.0.) -------
11232 ! 130 CONTINUE
11233 ! NQ = 1
11234 ! H = 1.0D0
11235 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
11236 ! DO 135 I = 1,N
11237 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
11238 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
11239 ! 135 END DO
11240 !-----------------------------------------------------------------------
11241 ! The coding below computes the step size, H0, to be attempted on the
11242 ! first step, unless the user has supplied a value for this.
11243 ! First check that TOUT - T differs significantly from zero.
11244 ! A scalar tolerance quantity TOL is computed, as MAX(RTOL(i))
11245 ! if this is positive, or MAX(ATOL(i)/ABS(Y(i))) otherwise, adjusted
11246 ! so as to be between 100*UROUND and 1.0E-3.
11247 ! Then the computed value H0 is given by..
11248 ! NEQ
11249 ! H0**2 = TOL / ( w0**-2 + (1/NEQ) * Sum ( YDOT(i)/ywt(i) )**2 )
11250 ! 1
11251 ! where w0 = MAX ( ABS(T), ABS(TOUT) ),
11252 ! YDOT(i) = i-th component of initial value of dy/dt,
11253 ! ywt(i) = EWT(i)/TOL (a weight for y(i)).
11254 ! The sign of H0 is inferred from the initial values of TOUT and T.
11255 !-----------------------------------------------------------------------
11256 ! IF (H0 /= 0.0D0) GO TO 180
11257 ! TDIST = ABS(TOUT - T)
11258 ! W0 = MAX(ABS(T),ABS(TOUT))
11259 ! IF (TDIST < 2.0D0*UROUND*W0) GO TO 622
11260 ! TOL = RTOL(1)
11261 ! IF (ITOL <= 2) GO TO 145
11262 ! DO 140 I = 1,N
11263 ! TOL = MAX(TOL,RTOL(I))
11264 ! 140 END DO
11265 ! 145 IF (TOL > 0.0D0) GO TO 160
11266 ! ATOLI = ATOL(1)
11267 ! DO 150 I = 1,N
11268 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
11269 ! AYI = ABS(Y(I))
11270 ! IF (AYI /= 0.0D0) TOL = MAX(TOL,ATOLI/AYI)
11271 ! 150 END DO
11272 ! 160 TOL = MAX(TOL,100.0D0*UROUND)
11273 ! TOL = MIN(TOL,0.001D0)
11274 ! SUM = DVNORM (N, RWORK(LYD0), RWORK(LEWT))
11275 ! SUM = 1.0D0/(TOL*W0*W0) + TOL*SUM**2
11276 ! H0 = 1.0D0/SQRT(SUM)
11277 ! H0 = MIN(H0,TDIST)
11278 ! H0 = SIGN(H0,TOUT-T)
11279 ! Adjust H0 if necessary to meet HMAX bound. ---------------------------
11280 ! 180 RH = ABS(H0)*HMXI
11281 ! IF (RH > 1.0D0) H0 = H0/RH
11282 ! Load H with H0 and scale YH(*,2) by H0. ------------------------------
11283 ! H = H0
11284 ! DO 190 I = 1,N
11285 ! RWORK(I+LYD0-1) = H0*RWORK(I+LYD0-1)
11286 ! 190 END DO
11287 ! GO TO 270
11288 !-----------------------------------------------------------------------
11289 ! Block D.
11290 ! The next code block is for continuation calls only (ISTATE = 2 or 3)
11291 ! and is to check stop conditions before taking a step.
11292 !-----------------------------------------------------------------------
11293 ! 200 NSLAST = NST
11294 ! GO TO (210, 250, 220, 230, 240), ITASK
11295 ! 210 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
11296 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
11297 ! IF (IFLAG /= 0) GO TO 627
11298 ! T = TOUT
11299 ! GO TO 420
11300 ! 220 TP = TN - HU*(1.0D0 + 100.0D0*UROUND)
11301 ! IF ((TP - TOUT)*H > 0.0D0) GO TO 623
11302 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 250
11303 ! GO TO 400
11304 ! 230 TCRIT = RWORK(1)
11305 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
11306 ! IF ((TCRIT - TOUT)*H < 0.0D0) GO TO 625
11307 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 245
11308 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
11309 ! IF (IFLAG /= 0) GO TO 627
11310 ! T = TOUT
11311 ! GO TO 420
11312 ! 240 TCRIT = RWORK(1)
11313 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
11314 ! 245 HMX = ABS(TN) + ABS(H)
11315 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
11316 ! IF (IHIT) GO TO 400
11317 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
11318 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
11319 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
11320 ! IF (ISTATE == 2) JSTART = -2
11321 !-----------------------------------------------------------------------
11322 ! Block E.
11323 ! The next block is normally executed for all calls and contains
11324 ! the call to the one-step core integrator DSTODI.
11325 ! This is a looping point for the integration steps.
11326 ! First check for too many steps being taken, update EWT (if not at
11327 ! start of problem), check for too much accuracy being requested, and
11328 ! check for H below the roundoff level in T.
11329 !-----------------------------------------------------------------------
11330 ! 250 CONTINUE
11331 ! IF ((NST-NSLAST) >= MXSTEP) GO TO 500
11332 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
11333 ! DO 260 I = 1,N
11334 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 510
11335 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
11336 ! 260 END DO
11337 ! 270 TOLSF = UROUND*DVNORM (N, RWORK(LYH), RWORK(LEWT))
11338 ! IF (TOLSF <= 1.0D0) GO TO 280
11339 ! TOLSF = TOLSF*2.0D0
11340 ! IF (NST == 0) GO TO 626
11341 ! GO TO 520
11342 ! 280 IF ((TN + H) /= TN) GO TO 290
11343 ! NHNIL = NHNIL + 1
11344 ! IF (NHNIL > MXHNIL) GO TO 290
11345 ! MSG = 'DLSODI- Warning..Internal T (=R1) and H (=R2) are'
11346 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11347 ! MSG=' such that in the machine, T + H = T on the next step '
11348 ! CALL XERRWD (MSG, 60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11349 ! MSG = ' (H = step size). Solver will continue anyway.'
11350 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 2, TN, H)
11351 ! IF (NHNIL < MXHNIL) GO TO 290
11352 ! MSG = 'DLSODI- Above warning has been issued I1 times. '
11353 ! CALL XERRWD (MSG, 50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11354 ! MSG = ' It will not be issued again for this problem.'
11355 ! CALL XERRWD (MSG, 50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
11356 ! 290 CONTINUE
11357 !-----------------------------------------------------------------------
11358 ! CALL DSTODI(NEQ,Y,YH,NYH,YH1,EWT,SAVF,SAVR,ACOR,WM,IWM,RES,
11359 ! ADDA,JAC,DPREPJI,DSOLSY)
11360 ! Note: SAVF in DSTODI occupies the same space as YDOTI in DLSODI.
11361 !-----------------------------------------------------------------------
11362 ! CALL DSTODI (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT), &
11363 ! YDOTI, RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), &
11364 ! IWORK(LIWM), RES, ADDA, JAC, DPREPJI, DSOLSY )
11365 ! KGO = 1 - KFLAG
11366 ! GO TO (300, 530, 540, 400, 550), KGO
11367 ! KGO = 1:success; 2:error test failure; 3:convergence failure;
11368 ! 4:RES ordered return. 5:RES returned error.
11369 !-----------------------------------------------------------------------
11370 ! Block F.
11371 ! The following block handles the case of a successful return from the
11372 ! core integrator (KFLAG = 0). Test for stop conditions.
11373 !-----------------------------------------------------------------------
11374 ! 300 INIT = 1
11375 ! GO TO (310, 400, 330, 340, 350), ITASK
11376 ! ITASK = 1. If TOUT has been reached, interpolate. -------------------
11377 ! 310 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
11378 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
11379 ! T = TOUT
11380 ! GO TO 420
11381 ! ITASK = 3. Jump to exit if TOUT was reached. ------------------------
11382 ! 330 IF ((TN - TOUT)*H >= 0.0D0) GO TO 400
11383 ! GO TO 250
11384 ! ITASK = 4. see if TOUT or TCRIT was reached. adjust h if necessary.
11385 ! 340 IF ((TN - TOUT)*H < 0.0D0) GO TO 345
11386 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
11387 ! T = TOUT
11388 ! GO TO 420
11389 ! 345 HMX = ABS(TN) + ABS(H)
11390 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
11391 ! IF (IHIT) GO TO 400
11392 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
11393 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
11394 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
11395 ! JSTART = -2
11396 ! GO TO 250
11397 ! ITASK = 5. See if TCRIT was reached and jump to exit. ---------------
11398 ! 350 HMX = ABS(TN) + ABS(H)
11399 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
11400 !-----------------------------------------------------------------------
11401 ! Block G.
11402 ! The following block handles all successful returns from DLSODI.
11403 ! if ITASK .ne. 1, Y is loaded from YH and T is set accordingly.
11404 ! ISTATE is set to 2, and the optional outputs are loaded into the
11405 ! work arrays before returning.
11406 !-----------------------------------------------------------------------
11407 ! 400 DO 410 I = 1,N
11408 ! Y(I) = RWORK(I+LYH-1)
11409 ! 410 END DO
11410 ! T = TN
11411 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 420
11412 ! IF (IHIT) T = TCRIT
11413 ! 420 ISTATE = 2
11414 ! IF (KFLAG == -3) ISTATE = 3
11415 ! RWORK(11) = HU
11416 ! RWORK(12) = H
11417 ! RWORK(13) = TN
11418 ! IWORK(11) = NST
11419 ! IWORK(12) = NFE
11420 ! IWORK(13) = NJE
11421 ! IWORK(14) = NQU
11422 ! IWORK(15) = NQ
11423 ! RETURN
11424 !-----------------------------------------------------------------------
11425 ! Block H.
11426 ! The following block handles all unsuccessful returns other than
11427 ! those for illegal input. First the error message routine is called.
11428 ! If there was an error test or convergence test failure, IMXER is set.
11429 ! Then Y is loaded from YH and T is set to TN.
11430 ! The optional outputs are loaded into the work arrays before returning.
11431 !-----------------------------------------------------------------------
11432 ! The maximum number of steps was taken before reaching TOUT. ----------
11433 ! 500 MSG = 'DLSODI- At current T (=R1), MXSTEP (=I1) steps '
11434 ! CALL XERRWD (MSG, 50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11435 ! MSG = ' taken on this call before reaching TOUT '
11436 ! CALL XERRWD (MSG, 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0)
11437 ! ISTATE = -1
11438 ! GO TO 580
11439 ! EWT(i) .le. 0.0 for some i (not at start of problem). ----------------
11440 ! 510 EWTI = RWORK(LEWT+I-1)
11441 ! MSG = 'DLSODI- At T (=R1), EWT(I1) has become R2 <= 0.'
11442 ! CALL XERRWD (MSG, 50, 202, 0, 1, I, 0, 2, TN, EWTI)
11443 ! ISTATE = -6
11444 ! GO TO 590
11445 ! Too much accuracy requested for machine precision. -------------------
11446 ! 520 MSG = 'DLSODI- At T (=R1), too much accuracy requested '
11447 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11448 ! MSG = ' for precision of machine.. See TOLSF (=R2) '
11449 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
11450 ! RWORK(14) = TOLSF
11451 ! ISTATE = -2
11452 ! GO TO 590
11453 ! KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
11454 ! 530 MSG = 'DLSODI- At T(=R1) and step size H(=R2), the error'
11455 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11456 ! MSG = ' test failed repeatedly or with ABS(H) = HMIN'
11457 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 2, TN, H)
11458 ! ISTATE = -4
11459 ! GO TO 570
11460 ! KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
11461 ! 540 MSG = 'DLSODI- At T (=R1) and step size H (=R2), the '
11462 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11463 ! MSG = ' corrector convergence failed repeatedly '
11464 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11465 ! MSG = ' or with ABS(H) = HMIN '
11466 ! CALL XERRWD (MSG, 30, 205, 0, 0, 0, 0, 2, TN, H)
11467 ! ISTATE = -5
11468 ! GO TO 570
11469 ! IRES = 3 returned by RES, despite retries by DSTODI. -----------------
11470 ! 550 MSG = 'DLSODI- At T (=R1) residual routine returned '
11471 ! CALL XERRWD (MSG, 50, 206, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11472 ! MSG = ' error IRES = 3 repeatedly. '
11473 ! CALL XERRWD (MSG, 40, 206, 0, 0, 0, 0, 1, TN, 0.0D0)
11474 ! ISTATE = -7
11475 ! GO TO 590
11476 ! DAINVG failed because matrix A was singular. -------------------------
11477 ! 560 IER = -IER
11478 ! MSG='DLSODI- Attempt to initialize dy/dt failed: Matrix A is '
11479 ! CALL XERRWD (MSG, 60, 207, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11480 ! MSG = ' singular. DGEFA or DGBFA returned INFO = I1'
11481 ! CALL XERRWD (MSG, 50, 207, 0, 1, IER, 0, 0, 0.0D0, 0.0D0)
11482 ! ISTATE = -8
11483 ! RETURN
11484 ! DAINVG failed because RES set IRES to 2 or 3. ------------------------
11485 ! 565 MSG = 'DLSODI- Attempt to initialize dy/dt failed '
11486 ! CALL XERRWD (MSG, 50, 208, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11487 ! MSG = ' because residual routine set its error flag '
11488 ! CALL XERRWD (MSG, 50, 208, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11489 ! MSG = ' to IRES = (I1)'
11490 ! CALL XERRWD (MSG, 20, 208, 0, 1, IER, 0, 0, 0.0D0, 0.0D0)
11491 ! ISTATE = -8
11492 ! RETURN
11493 ! Compute IMXER if relevant. -------------------------------------------
11494 ! 570 BIG = 0.0D0
11495 ! IMXER = 1
11496 ! DO 575 I = 1,N
11497 ! SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
11498 ! IF (BIG >= SIZE) GO TO 575
11499 ! BIG = SIZE
11500 ! IMXER = I
11501 ! 575 END DO
11502 ! IWORK(16) = IMXER
11503 ! Compute residual if relevant. ----------------------------------------
11504 ! 580 LYD0 = LYH + NYH
11505 ! DO 585 I = 1,N
11506 ! RWORK(I+LSAVF-1) = RWORK(I+LYD0-1)/H
11507 ! Y(I) = RWORK(I+LYH-1)
11508 ! 585 END DO
11509 ! IRES = 1
11510 ! CALL RES (NEQ, TN, Y, RWORK(LSAVF), YDOTI, IRES )
11511 ! NFE = NFE + 1
11512 ! IF (IRES <= 1) GO TO 595
11513 ! MSG = 'DLSODI- Residual routine set its flag IRES '
11514 ! CALL XERRWD (MSG, 50, 210, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11515 ! MSG = ' to (I1) when called for final output. '
11516 ! CALL XERRWD (MSG, 50, 210, 0, 1, IRES, 0, 0, 0.0D0, 0.0D0)
11517 ! GO TO 595
11518 ! Set Y vector, T, and optional outputs. -------------------------------
11519 ! 590 DO 592 I = 1,N
11520 ! Y(I) = RWORK(I+LYH-1)
11521 ! 592 END DO
11522 ! 595 T = TN
11523 ! RWORK(11) = HU
11524 ! RWORK(12) = H
11525 ! RWORK(13) = TN
11526 ! IWORK(11) = NST
11527 ! IWORK(12) = NFE
11528 ! IWORK(13) = NJE
11529 ! IWORK(14) = NQU
11530 ! IWORK(15) = NQ
11531 ! RETURN
11532 !-----------------------------------------------------------------------
11533 ! Block I.
11534 ! The following block handles all error returns due to illegal input
11535 ! (ISTATE = -3), as detected before calling the core integrator.
11536 ! First the error message routine is called. If the illegal input
11537 ! is a negative ISTATE, the run is aborted (apparent infinite loop).
11538 !-----------------------------------------------------------------------
11539 ! 601 MSG = 'DLSODI- ISTATE (=I1) illegal.'
11540 ! CALL XERRWD (MSG, 30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0)
11541 ! IF (ISTATE < 0) GO TO 800
11542 ! GO TO 700
11543 ! 602 MSG = 'DLSODI- ITASK (=I1) illegal. '
11544 ! CALL XERRWD (MSG, 30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0)
11545 ! GO TO 700
11546 ! 603 MSG = 'DLSODI- ISTATE > 1 but DLSODI not initialized.'
11547 ! CALL XERRWD (MSG, 50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11548 ! GO TO 700
11549 ! 604 MSG = 'DLSODI- NEQ (=I1) < 1 '
11550 ! CALL XERRWD (MSG, 30, 4, 0, 1, NEQ(1), 0, 0, 0.0D0, 0.0D0)
11551 ! GO TO 700
11552 ! 605 MSG = 'DLSODI- ISTATE = 3 and NEQ increased (I1 to I2). '
11553 ! CALL XERRWD (MSG, 50, 5, 0, 2, N, NEQ(1), 0, 0.0D0, 0.0D0)
11554 ! GO TO 700
11555 ! 606 MSG = 'DLSODI- ITOL (=I1) illegal. '
11556 ! CALL XERRWD (MSG, 30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0)
11557 ! GO TO 700
11558 ! 607 MSG = 'DLSODI- IOPT (=I1) illegal. '
11559 ! CALL XERRWD (MSG, 30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0)
11560 ! GO TO 700
11561 ! 608 MSG = 'DLSODI- MF (=I1) illegal. '
11562 ! CALL XERRWD (MSG, 30, 8, 0, 1, MF, 0, 0, 0.0D0, 0.0D0)
11563 ! GO TO 700
11564 ! 609 MSG = 'DLSODI- ML(=I1) illegal: < 0 or >= NEQ(=I2) '
11565 ! CALL XERRWD (MSG, 50, 9, 0, 2, ML, NEQ(1), 0, 0.0D0, 0.0D0)
11566 ! GO TO 700
11567 ! 610 MSG = 'DLSODI- MU(=I1) illegal: < 0 or >= NEQ(=I2) '
11568 ! CALL XERRWD (MSG, 50, 10, 0, 2, MU, NEQ(1), 0, 0.0D0, 0.0D0)
11569 ! GO TO 700
11570 ! 611 MSG = 'DLSODI- MAXORD (=I1) < 0 '
11571 ! CALL XERRWD (MSG, 30, 11, 0, 1, MAXORD, 0, 0, 0.0D0, 0.0D0)
11572 ! GO TO 700
11573 ! 612 MSG = 'DLSODI- MXSTEP (=I1) < 0 '
11574 ! CALL XERRWD (MSG, 30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0)
11575 ! GO TO 700
11576 ! 613 MSG = 'DLSODI- MXHNIL (=I1) < 0 '
11577 ! CALL XERRWD (MSG, 30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
11578 ! GO TO 700
11579 ! 614 MSG = 'DLSODI- TOUT (=R1) behind T (=R2) '
11580 ! CALL XERRWD (MSG, 40, 14, 0, 0, 0, 0, 2, TOUT, T)
11581 ! MSG = ' Integration direction is given by H0 (=R1) '
11582 ! CALL XERRWD (MSG, 50, 14, 0, 0, 0, 0, 1, H0, 0.0D0)
11583 ! GO TO 700
11584 ! 615 MSG = 'DLSODI- HMAX (=R1) < 0.0 '
11585 ! CALL XERRWD (MSG, 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0)
11586 ! GO TO 700
11587 ! 616 MSG = 'DLSODI- HMIN (=R1) < 0.0 '
11588 ! CALL XERRWD (MSG, 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0)
11589 ! GO TO 700
11590 ! 617 MSG='DLSODI- RWORK length needed, LENRW (=I1), exceeds LRW (=I2)'
11591 ! CALL XERRWD (MSG, 60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
11592 ! GO TO 700
11593 ! 618 MSG='DLSODI- IWORK length needed, LENIW (=I1), exceeds LIW (=I2)'
11594 ! CALL XERRWD (MSG, 60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
11595 ! GO TO 700
11596 ! 619 MSG = 'DLSODI- RTOL(=I1) is R1 < 0.0 '
11597 ! CALL XERRWD (MSG, 40, 19, 0, 1, I, 0, 1, RTOLI, 0.0D0)
11598 ! GO TO 700
11599 ! 620 MSG = 'DLSODI- ATOL(=I1) is R1 < 0.0 '
11600 ! CALL XERRWD (MSG, 40, 20, 0, 1, I, 0, 1, ATOLI, 0.0D0)
11601 ! GO TO 700
11602 ! 621 EWTI = RWORK(LEWT+I-1)
11603 ! MSG = 'DLSODI- EWT(I1) is R1 <= 0.0 '
11604 ! CALL XERRWD (MSG, 40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0)
11605 ! GO TO 700
11606 ! 622 MSG='DLSODI- TOUT(=R1) too close to T(=R2) to start integration.'
11607 ! CALL XERRWD (MSG, 60, 22, 0, 0, 0, 0, 2, TOUT, T)
11608 ! GO TO 700
11609 ! 623 MSG='DLSODI- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
11610 ! CALL XERRWD (MSG, 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
11611 ! GO TO 700
11612 ! 624 MSG='DLSODI- ITASK = 4 or 5 and TCRIT (=R1) behind TCUR (=R2) '
11613 ! CALL XERRWD (MSG, 60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
11614 ! GO TO 700
11615 ! 625 MSG='DLSODI- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
11616 ! CALL XERRWD (MSG, 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
11617 ! GO TO 700
11618 ! 626 MSG = 'DLSODI- At start of problem, too much accuracy '
11619 ! CALL XERRWD (MSG, 50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
11620 ! MSG=' requested for precision of machine.. See TOLSF (=R1) '
11621 ! CALL XERRWD (MSG, 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0)
11622 ! RWORK(14) = TOLSF
11623 ! GO TO 700
11624 ! 627 MSG = 'DLSODI- Trouble in DINTDY. ITASK = I1, TOUT = R1'
11625 ! CALL XERRWD (MSG, 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0)
11626 ! 700 ISTATE = -3
11627 ! RETURN
11628 ! 800 MSG = 'DLSODI- Run aborted.. apparent infinite loop. '
11629 ! CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0)
11630 ! RETURN
11631 !----------------------- End of Subroutine DLSODI ----------------------
11632 ! END SUBROUTINE DLSODI
11633 ! ECK DLSOIBT
11634 ! SUBROUTINE DLSOIBT (RES, ADDA, JAC, NEQ, Y, YDOTI, T, TOUT, ITOL, &
11635 ! RTOL, ATOL, ITASK, ISTATE, IOPT, RWORK, LRW, IWORK, LIW, MF )
11636 ! EXTERNAL RES, ADDA, JAC
11637 ! INTEGER :: NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, MF
11638 ! DOUBLE PRECISION :: Y, YDOTI, T, TOUT, RTOL, ATOL, RWORK
11639 ! DIMENSION NEQ(*), Y(*), YDOTI(*), RTOL(*), ATOL(*), RWORK(LRW), &
11640 ! IWORK(LIW)
11641 !-----------------------------------------------------------------------
11642 ! This is the 18 November 2003 version of
11643 ! DLSOIBT: Livermore Solver for Ordinary differential equations given
11644 ! in Implicit form, with Block-Tridiagonal Jacobian treatment.
11645 ! This version is in double precision.
11646 ! DLSOIBT solves the initial value problem for linearly implicit
11647 ! systems of first order ODEs,
11648 ! A(t,y) * dy/dt = g(t,y) , where A(t,y) is a square matrix,
11649 ! or, in component form,
11650 ! ( a * ( dy / dt )) + ... + ( a * ( dy / dt )) =
11651 ! i,1 1 i,NEQ NEQ
11652 ! = g ( t, y , y ,..., y ) ( i = 1,...,NEQ )
11653 ! i 1 2 NEQ
11654 ! If A is singular, this is a differential-algebraic system.
11655 ! DLSOIBT is a variant version of the DLSODI package, for the case where
11656 ! the matrices A, dg/dy, and d(A*s)/dy are all block-tridiagonal.
11657 !-----------------------------------------------------------------------
11658 ! Reference:
11659 ! Alan C. Hindmarsh, ODEPACK, A Systematized Collection of ODE
11660 ! Solvers, in Scientific Computing, R. S. Stepleman et al. (Eds.),
11661 ! North-Holland, Amsterdam, 1983, pp. 55-64.
11662 !-----------------------------------------------------------------------
11663 ! Authors: Alan C. Hindmarsh and Jeffrey F. Painter
11664 ! Center for Applied Scientific Computing, L-561
11665 ! Lawrence Livermore National Laboratory
11666 ! Livermore, CA 94551
11667 ! and
11668 ! Charles S. Kenney
11669 ! formerly at: Naval Weapons Center
11670 ! China Lake, CA 93555
11671 !-----------------------------------------------------------------------
11672 ! Summary of Usage.
11673 ! Communication between the user and the DLSOIBT package, for normal
11674 ! situations, is summarized here. This summary describes only a subset
11675 ! of the full set of options available. See the full description for
11676 ! details, including optional communication, nonstandard options,
11677 ! and instructions for special situations. See also the example
11678 ! problem (with program and output) following this summary.
11679 ! A. First, provide a subroutine of the form:
11680 ! SUBROUTINE RES (NEQ, T, Y, S, R, IRES)
11681 ! DOUBLE PRECISION T, Y(*), S(*), R(*)
11682 ! which computes the residual function
11683 ! r = g(t,y) - A(t,y) * s ,
11684 ! as a function of t and the vectors y and s. (s is an internally
11685 ! generated approximation to dy/dt.) The arrays Y and S are inputs
11686 ! to the RES routine and should not be altered. The residual
11687 ! vector is to be stored in the array R. The argument IRES should be
11688 ! ignored for casual use of DLSOIBT. (For uses of IRES, see the
11689 ! paragraph on RES in the full description below.)
11690 ! B. Next, identify the block structure of the matrices A = A(t,y) and
11691 ! dr/dy. DLSOIBT must deal internally with a linear combination, P, of
11692 ! these two matrices. The matrix P (hence both A and dr/dy) must have
11693 ! a block-tridiagonal form with fixed structure parameters
11694 ! MB = block size, MB .ge. 1, and
11695 ! NB = number of blocks in each direction, NB .ge. 4,
11696 ! with MB*NB = NEQ. In each of the NB block-rows of the matrix P
11697 ! (each consisting of MB consecutive rows), the nonzero elements are
11698 ! to lie in three consecutive MB by MB blocks. In block-rows
11699 ! 2 through NB - 1, these are centered about the main diagonal.
11700 ! in block-rows 1 and NB, they are the diagonal blocks and the two
11701 ! blocks adjacent to the diagonal block. (Thus block positions (1,3)
11702 ! and (NB,NB-2) can be nonzero.)
11703 ! Alternatively, P (hence A and dr/dy) may be only approximately
11704 ! equal to matrices with this form, and DLSOIBT should still succeed.
11705 ! The block-tridiagonal matrix P is described by three arrays,
11706 ! each of size MB by MB by NB:
11707 ! PA = array of diagonal blocks,
11708 ! PB = array of superdiagonal (and one subdiagonal) blocks, and
11709 ! PC = array of subdiagonal (and one superdiagonal) blocks.
11710 ! Specifically, the three MB by MB blocks in the k-th block-row of P
11711 ! are stored in (reading across):
11712 ! PC(*,*,k) = block to the left of the diagonal block,
11713 ! PA(*,*,k) = diagonal block, and
11714 ! PB(*,*,k) = block to the right of the diagonal block,
11715 ! except for k = 1, where the three blocks (reading across) are
11716 ! PA(*,*,1) (= diagonal block), PB(*,*,1), and PC(*,*,1),
11717 ! and k = NB, where they are
11718 ! PB(*,*,NB), PC(*,*,NB), and PA(*,*,NB) (= diagonal block).
11719 ! (Each asterisk * stands for an index that ranges from 1 to MB.)
11720 ! C. You must also provide a subroutine of the form:
11721 ! SUBROUTINE ADDA (NEQ, T, Y, MB, NB, PA, PB, PC)
11722 ! DOUBLE PRECISION T, Y(*), PA(MB,MB,NB), PB(MB,MB,NB), PC(MB,MB,NB)
11723 ! which adds the nonzero blocks of the matrix A = A(t,y) to the
11724 ! contents of the arrays PA, PB, and PC, following the structure
11725 ! description in Paragraph B above.
11726 ! T and the Y array are input and should not be altered.
11727 ! Thus the affect of ADDA should be the following:
11728 ! DO 30 K = 1,NB
11729 ! DO 20 J = 1,MB
11730 ! DO 10 I = 1,MB
11731 ! PA(I,J,K) = PA(I,J,K) +
11732 ! ( (I,J) element of K-th diagonal block of A)
11733 ! PB(I,J,K) = PB(I,J,K) +
11734 ! ( (I,J) element of block in block position (K,K+1) of A,
11735 ! or in block position (NB,NB-2) if K = NB)
11736 ! PC(I,J,K) = PC(I,J,K) +
11737 ! ( (I,J) element of block in block position (K,K-1) of A,
11738 ! or in block position (1,3) if K = 1)
11739 ! 10 CONTINUE
11740 ! 20 CONTINUE
11741 ! 30 CONTINUE
11742 ! D. For the sake of efficiency, you are encouraged to supply the
11743 ! Jacobian matrix dr/dy in closed form, where r = g(t,y) - A(t,y)*s
11744 ! (s = a fixed vector) as above. If dr/dy is being supplied,
11745 ! use MF = 21, and provide a subroutine of the form:
11746 ! SUBROUTINE JAC (NEQ, T, Y, S, MB, NB, PA, PB, PC)
11747 ! DOUBLE PRECISION T, Y(*), S(*), PA(MB,MB,NB), PB(MB,MB,NB),
11748 ! 1 PC(MB,MB,NB)
11749 ! which computes dr/dy as a function of t, y, and s. Here T, Y, and
11750 ! S are inputs, and the routine is to load dr/dy into PA, PB, PC,
11751 ! according to the structure description in Paragraph B above.
11752 ! That is, load the diagonal blocks into PA, the superdiagonal blocks
11753 ! (and block (NB,NB-2) ) into PB, and the subdiagonal blocks (and
11754 ! block (1,3) ) into PC. The blocks in block-row k of dr/dy are to
11755 ! be loaded into PA(*,*,k), PB(*,*,k), and PC(*,*,k).
11756 ! Only nonzero elements need be loaded, and the indexing
11757 ! of PA, PB, and PC is the same as in the ADDA routine.
11758 ! Note that if A is independent of Y (or this dependence
11759 ! is weak enough to be ignored) then JAC is to compute dg/dy.
11760 ! If it is not feasible to provide a JAC routine, use
11761 ! MF = 22, and DLSOIBT will compute an approximate Jacobian
11762 ! internally by difference quotients.
11763 ! E. Next decide whether or not to provide the initial value of the
11764 ! derivative vector dy/dt. If the initial value of A(t,y) is
11765 ! nonsingular (and not too ill-conditioned), you may let DLSOIBT compute
11766 ! this vector (ISTATE = 0). (DLSOIBT will solve the system A*s = g for
11767 ! s, with initial values of A and g.) If A(t,y) is initially
11768 ! singular, then the system is a differential-algebraic system, and
11769 ! you must make use of the particular form of the system to compute the
11770 ! initial values of y and dy/dt. In that case, use ISTATE = 1 and
11771 ! load the initial value of dy/dt into the array YDOTI.
11772 ! The input array YDOTI and the initial Y array must be consistent with
11773 ! the equations A*dy/dt = g. This implies that the initial residual
11774 ! r = g(t,y) - A(t,y)*YDOTI must be approximately zero.
11775 ! F. Write a main program which calls Subroutine DLSOIBT once for
11776 ! each point at which answers are desired. This should also provide
11777 ! for possible use of logical unit 6 for output of error messages by
11778 ! DLSOIBT. on the first call to DLSOIBT, supply arguments as follows:
11779 ! RES = name of user subroutine for residual function r.
11780 ! ADDA = name of user subroutine for computing and adding A(t,y).
11781 ! JAC = name of user subroutine for Jacobian matrix dr/dy
11782 ! (MF = 21). If not used, pass a dummy name.
11783 ! Note: the names for the RES and ADDA routines and (if used) the
11784 ! JAC routine must be declared External in the calling program.
11785 ! NEQ = number of scalar equations in the system.
11786 ! Y = array of initial values, of length NEQ.
11787 ! YDOTI = array of length NEQ (containing initial dy/dt if ISTATE = 1).
11788 ! T = the initial value of the independent variable.
11789 ! TOUT = first point where output is desired (.ne. T).
11790 ! ITOL = 1 or 2 according as ATOL (below) is a scalar or array.
11791 ! RTOL = relative tolerance parameter (scalar).
11792 ! ATOL = absolute tolerance parameter (scalar or array).
11793 ! the estimated local error in y(i) will be controlled so as
11794 ! to be roughly less (in magnitude) than
11795 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or
11796 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2.
11797 ! Thus the local error test passes if, in each component,
11798 ! either the absolute error is less than ATOL (or ATOL(i)),
11799 ! or the relative error is less than RTOL.
11800 ! Use RTOL = 0.0 for pure absolute error control, and
11801 ! use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative error
11802 ! control. Caution: Actual (global) errors may exceed these
11803 ! local tolerances, so choose them conservatively.
11804 ! ITASK = 1 for normal computation of output values of y at t = TOUT.
11805 ! ISTATE = integer flag (input and output). Set ISTATE = 1 if the
11806 ! initial dy/dt is supplied, and 0 otherwise.
11807 ! IOPT = 0 to indicate no optional inputs used.
11808 ! RWORK = real work array of length at least:
11809 ! 22 + 9*NEQ + 3*MB*MB*NB for MF = 21 or 22.
11810 ! LRW = declared length of RWORK (in user's dimension).
11811 ! IWORK = integer work array of length at least 20 + NEQ.
11812 ! Input in IWORK(1) the block size MB and in IWORK(2) the
11813 ! number NB of blocks in each direction along the matrix A.
11814 ! These must satisfy MB .ge. 1, NB .ge. 4, and MB*NB = NEQ.
11815 ! LIW = declared length of IWORK (in user's dimension).
11816 ! MF = method flag. Standard values are:
11817 ! 21 for a user-supplied Jacobian.
11818 ! 22 for an internally generated Jacobian.
11819 ! For other choices of MF, see the paragraph on MF in
11820 ! the full description below.
11821 ! Note that the main program must declare arrays Y, YDOTI, RWORK, IWORK,
11822 ! and possibly ATOL.
11823 ! G. The output from the first call (or any call) is:
11824 ! Y = array of computed values of y(t) vector.
11825 ! T = corresponding value of independent variable (normally TOUT).
11826 ! ISTATE = 2 if DLSOIBT was successful, negative otherwise.
11827 ! -1 means excess work done on this call (check all inputs).
11828 ! -2 means excess accuracy requested (tolerances too small).
11829 ! -3 means illegal input detected (see printed message).
11830 ! -4 means repeated error test failures (check all inputs).
11831 ! -5 means repeated convergence failures (perhaps bad Jacobian
11832 ! supplied or wrong choice of tolerances).
11833 ! -6 means error weight became zero during problem. (Solution
11834 ! component i vanished, and ATOL or ATOL(i) = 0.)
11835 ! -7 cannot occur in casual use.
11836 ! -8 means DLSOIBT was unable to compute the initial dy/dt.
11837 ! In casual use, this means A(t,y) is initially singular.
11838 ! Supply YDOTI and use ISTATE = 1 on the first call.
11839 ! If DLSOIBT returns ISTATE = -1, -4, or -5, then the output of
11840 ! DLSOIBT also includes YDOTI = array containing residual vector
11841 ! r = g - A * dy/dt evaluated at the current t, y, and dy/dt.
11842 ! H. To continue the integration after a successful return, simply
11843 ! reset TOUT and call DLSOIBT again. No other parameters need be reset.
11844 !-----------------------------------------------------------------------
11845 ! Example Problem.
11846 ! The following is an example problem, with the coding needed
11847 ! for its solution by DLSOIBT. The problem comes from the partial
11848 ! differential equation (the Burgers equation)
11849 ! du/dt = - u * du/dx + eta * d**2 u/dx**2, eta = .05,
11850 ! on -1 .le. x .le. 1. The boundary conditions are
11851 ! du/dx = 0 at x = -1 and at x = 1.
11852 ! The initial profile is a square wave,
11853 ! u = 1 in ABS(x) .lt. .5, u = .5 at ABS(x) = .5, u = 0 elsewhere.
11854 ! The PDE is discretized in x by a simplified Galerkin method,
11855 ! using piecewise linear basis functions, on a grid of 40 intervals.
11856 ! The equations at x = -1 and 1 use a 3-point difference approximation
11857 ! for the right-hand side. The result is a system A * dy/dt = g(y),
11858 ! of size NEQ = 41, where y(i) is the approximation to u at x = x(i),
11859 ! with x(i) = -1 + (i-1)*delx, delx = 2/(NEQ-1) = .05. The individual
11860 ! equations in the system are
11861 ! dy(1)/dt = ( y(3) - 2*y(2) + y(1) ) * eta / delx**2,
11862 ! dy(NEQ)/dt = ( y(NEQ-2) - 2*y(NEQ-1) + y(NEQ) ) * eta / delx**2,
11863 ! and for i = 2, 3, ..., NEQ-1,
11864 ! (1/6) dy(i-1)/dt + (4/6) dy(i)/dt + (1/6) dy(i+1)/dt
11865 ! = ( y(i-1)**2 - y(i+1)**2 ) / (4*delx)
11866 ! + ( y(i+1) - 2*y(i) + y(i-1) ) * eta / delx**2.
11867 ! The following coding solves the problem with MF = 21, with output
11868 ! of solution statistics at t = .1, .2, .3, and .4, and of the
11869 ! solution vector at t = .4. Here the block size is just MB = 1.
11870 ! EXTERNAL RESID, ADDABT, JACBT
11871 ! DOUBLE PRECISION ATOL, RTOL, RWORK, T, TOUT, Y, YDOTI
11872 ! DIMENSION Y(41), YDOTI(41), RWORK(514), IWORK(61)
11873 ! NEQ = 41
11874 ! DO 10 I = 1,NEQ
11875 ! 10 Y(I) = 0.0
11876 ! Y(11) = 0.5
11877 ! DO 20 I = 12,30
11878 ! 20 Y(I) = 1.0
11879 ! Y(31) = 0.5
11880 ! T = 0.0
11881 ! TOUT = 0.1
11882 ! ITOL = 1
11883 ! RTOL = 1.0D-4
11884 ! ATOL = 1.0D-5
11885 ! ITASK = 1
11886 ! ISTATE = 0
11887 ! IOPT = 0
11888 ! LRW = 514
11889 ! LIW = 61
11890 ! IWORK(1) = 1
11891 ! IWORK(2) = NEQ
11892 ! MF = 21
11893 ! DO 40 IO = 1,4
11894 ! CALL DLSOIBT (RESID, ADDABT, JACBT, NEQ, Y, YDOTI, T, TOUT,
11895 ! 1 ITOL,RTOL,ATOL, ITASK, ISTATE, IOPT, RWORK,LRW,IWORK,LIW, MF)
11896 ! WRITE (6,30) T, IWORK(11), IWORK(12), IWORK(13)
11897 ! 30 FORMAT(' At t =',F5.2,' No. steps =',I4,' No. r-s =',I4,
11898 ! 1 ' No. J-s =',I3)
11899 ! IF (ISTATE .NE. 2) GO TO 90
11900 ! TOUT = TOUT + 0.1
11901 ! 40 CONTINUE
11902 ! WRITE(6,50) (Y(I),I=1,NEQ)
11903 ! 50 FORMAT(/' Final solution values..'/9(5D12.4/))
11904 ! STOP
11905 ! 90 WRITE(6,95) ISTATE
11906 ! 95 FORMAT(///' Error halt.. ISTATE =',I3)
11907 ! STOP
11908 ! END
11909 ! SUBROUTINE RESID (N, T, Y, S, R, IRES)
11910 ! DOUBLE PRECISION T, Y, S, R, ETA, DELX, EODSQ
11911 ! DIMENSION Y(N), S(N), R(N)
11912 ! DATA ETA/0.05/, DELX/0.05/
11913 ! EODSQ = ETA/DELX**2
11914 ! R(1) = EODSQ*(Y(3) - 2.0*Y(2) + Y(1)) - S(1)
11915 ! NM1 = N - 1
11916 ! DO 10 I = 2,NM1
11917 ! R(I) = (Y(I-1)**2 - Y(I+1)**2)/(4.0*DELX)
11918 ! 1 + EODSQ*(Y(I+1) - 2.0*Y(I) + Y(I-1))
11919 ! 2 - (S(I-1) + 4.0*S(I) + S(I+1))/6.0
11920 ! 10 CONTINUE
11921 ! R(N) = EODSQ*(Y(N-2) - 2.0*Y(NM1) + Y(N)) - S(N)
11922 ! RETURN
11923 ! END
11924 ! SUBROUTINE ADDABT (N, T, Y, MB, NB, PA, PB, PC)
11925 ! DOUBLE PRECISION T, Y, PA, PB, PC
11926 ! DIMENSION Y(N), PA(MB,MB,NB), PB(MB,MB,NB), PC(MB,MB,NB)
11927 ! PA(1,1,1) = PA(1,1,1) + 1.0
11928 ! NM1 = N - 1
11929 ! DO 10 K = 2,NM1
11930 ! PA(1,1,K) = PA(1,1,K) + (4.0/6.0)
11931 ! PB(1,1,K) = PB(1,1,K) + (1.0/6.0)
11932 ! PC(1,1,K) = PC(1,1,K) + (1.0/6.0)
11933 ! 10 CONTINUE
11934 ! PA(1,1,N) = PA(1,1,N) + 1.0
11935 ! RETURN
11936 ! END
11937 ! SUBROUTINE JACBT (N, T, Y, S, MB, NB, PA, PB, PC)
11938 ! DOUBLE PRECISION T, Y, S, PA, PB, PC, ETA, DELX, EODSQ
11939 ! DIMENSION Y(N), S(N), PA(MB,MB,NB),PB(MB,MB,NB),PC(MB,MB,NB)
11940 ! DATA ETA/0.05/, DELX/0.05/
11941 ! EODSQ = ETA/DELX**2
11942 ! PA(1,1,1) = EODSQ
11943 ! PB(1,1,1) = -2.0*EODSQ
11944 ! PC(1,1,1) = EODSQ
11945 ! DO 10 K = 2,N
11946 ! PA(1,1,K) = -2.0*EODSQ
11947 ! PB(1,1,K) = -Y(K+1)*(0.5/DELX) + EODSQ
11948 ! PC(1,1,K) = Y(K-1)*(0.5/DELX) + EODSQ
11949 ! 10 CONTINUE
11950 ! PB(1,1,N) = EODSQ
11951 ! PC(1,1,N) = -2.0*EODSQ
11952 ! PA(1,1,N) = EODSQ
11953 ! RETURN
11954 ! END
11955 ! The output of this program (on a CDC-7600 in single precision)
11956 ! is as follows:
11957 ! At t = 0.10 No. steps = 35 No. r-s = 45 No. J-s = 9
11958 ! At t = 0.20 No. steps = 43 No. r-s = 54 No. J-s = 10
11959 ! At t = 0.30 No. steps = 48 No. r-s = 60 No. J-s = 11
11960 ! At t = 0.40 No. steps = 51 No. r-s = 64 No. J-s = 12
11961 ! Final solution values..
11962 ! 1.2747e-02 1.1997e-02 1.5560e-02 2.3767e-02 3.7224e-02
11963 ! 5.6646e-02 8.2645e-02 1.1557e-01 1.5541e-01 2.0177e-01
11964 ! 2.5397e-01 3.1104e-01 3.7189e-01 4.3530e-01 5.0000e-01
11965 ! 5.6472e-01 6.2816e-01 6.8903e-01 7.4612e-01 7.9829e-01
11966 ! 8.4460e-01 8.8438e-01 9.1727e-01 9.4330e-01 9.6281e-01
11967 ! 9.7632e-01 9.8426e-01 9.8648e-01 9.8162e-01 9.6617e-01
11968 ! 9.3374e-01 8.7535e-01 7.8236e-01 6.5321e-01 5.0003e-01
11969 ! 3.4709e-01 2.1876e-01 1.2771e-01 7.3671e-02 5.0642e-02
11970 ! 5.4496e-02
11971 !-----------------------------------------------------------------------
11972 ! Full Description of User Interface to DLSOIBT.
11973 ! The user interface to DLSOIBT consists of the following parts.
11974 ! 1. The call sequence to Subroutine DLSOIBT, which is a driver
11975 ! routine for the solver. This includes descriptions of both
11976 ! the call sequence arguments and of user-supplied routines.
11977 ! Following these descriptions is a description of
11978 ! optional inputs available through the call sequence, and then
11979 ! a description of optional outputs (in the work arrays).
11980 ! 2. Descriptions of other routines in the DLSOIBT package that may be
11981 ! (optionally) called by the user. These provide the ability to
11982 ! alter error message handling, save and restore the internal
11983 ! Common, and obtain specified derivatives of the solution y(t).
11984 ! 3. Descriptions of Common blocks to be declared in overlay
11985 ! or similar environments, or to be saved when doing an interrupt
11986 ! of the problem and continued solution later.
11987 ! 4. Description of two routines in the DLSOIBT package, either of
11988 ! which the user may replace with his/her own version, if desired.
11989 ! These relate to the measurement of errors.
11990 !-----------------------------------------------------------------------
11991 ! Part 1. Call Sequence.
11992 ! The call sequence parameters used for input only are
11993 ! RES, ADDA, JAC, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK,
11994 ! IOPT, LRW, LIW, MF,
11995 ! and those used for both input and output are
11996 ! Y, T, ISTATE, YDOTI.
11997 ! The work arrays RWORK and IWORK are also used for additional and
11998 ! optional inputs and optional outputs. (The term output here refers
11999 ! to the return from Subroutine DLSOIBT to the user's calling program.)
12000 ! The legality of input parameters will be thoroughly checked on the
12001 ! initial call for the problem, but not checked thereafter unless a
12002 ! change in input parameters is flagged by ISTATE = 3 on input.
12003 ! The descriptions of the call arguments are as follows.
12004 ! RES = the name of the user-supplied subroutine which supplies
12005 ! the residual vector for the ODE system, defined by
12006 ! r = g(t,y) - A(t,y) * s
12007 ! as a function of the scalar t and the vectors
12008 ! s and y (s approximates dy/dt). This subroutine
12009 ! is to have the form
12010 ! SUBROUTINE RES (NEQ, T, Y, S, R, IRES)
12011 ! DOUBLE PRECISION T, Y(*), S(*), R(*)
12012 ! where NEQ, T, Y, S, and IRES are input, and R and
12013 ! IRES are output. Y, S, and R are arrays of length NEQ.
12014 ! On input, IRES indicates how DLSOIBT will use the
12015 ! returned array R, as follows:
12016 ! IRES = 1 means that DLSOIBT needs the full residual,
12017 ! r = g - A*s, exactly.
12018 ! IRES = -1 means that DLSOIBT is using R only to compute
12019 ! the Jacobian dr/dy by difference quotients.
12020 ! The RES routine can ignore IRES, or it can omit some terms
12021 ! if IRES = -1. If A does not depend on y, then RES can
12022 ! just return R = g when IRES = -1. If g - A*s contains other
12023 ! additive terms that are independent of y, these can also be
12024 ! dropped, if done consistently, when IRES = -1.
12025 ! The subroutine should set the flag IRES if it
12026 ! encounters a halt condition or illegal input.
12027 ! Otherwise, it should not reset IRES. On output,
12028 ! IRES = 1 or -1 represents a normal return, and
12029 ! DLSOIBT continues integrating the ODE. Leave IRES
12030 ! unchanged from its input value.
12031 ! IRES = 2 tells DLSOIBT to immediately return control
12032 ! to the calling program, with ISTATE = 3. This lets
12033 ! the calling program change parameters of the problem
12034 ! if necessary.
12035 ! IRES = 3 represents an error condition (for example, an
12036 ! illegal value of y). DLSOIBT tries to integrate the system
12037 ! without getting IRES = 3 from RES. If it cannot, DLSOIBT
12038 ! returns with ISTATE = -7 or -1.
12039 ! On an DLSOIBT return with ISTATE = 3, -1, or -7, the
12040 ! values of T and Y returned correspond to the last point
12041 ! reached successfully without getting the flag IRES = 2 or 3.
12042 ! The flag values IRES = 2 and 3 should not be used to
12043 ! handle switches or root-stop conditions. This is better
12044 ! done by calling DLSOIBT in a one-step mode and checking the
12045 ! stopping function for a sign change at each step.
12046 ! If quantities computed in the RES routine are needed
12047 ! externally to DLSOIBT, an extra call to RES should be made
12048 ! for this purpose, for consistent and accurate results.
12049 ! To get the current dy/dt for the S argument, use DINTDY.
12050 ! RES must be declared External in the calling
12051 ! program. See note below for more about RES.
12052 ! ADDA = the name of the user-supplied subroutine which adds the
12053 ! matrix A = A(t,y) to another matrix, P, stored in
12054 ! block-tridiagonal form. This routine is to have the form
12055 ! SUBROUTINE ADDA (NEQ, T, Y, MB, NB, PA, PB, PC)
12056 ! DOUBLE PRECISION T, Y(*), PA(MB,MB,NB), PB(MB,MB,NB),
12057 ! 1 PC(MB,MB,NB)
12058 ! where NEQ, T, Y, MB, NB, and the arrays PA, PB, and PC
12059 ! are input, and the arrays PA, PB, and PC are output.
12060 ! Y is an array of length NEQ, and the arrays PA, PB, PC
12061 ! are all MB by MB by NB.
12062 ! Here a block-tridiagonal structure is assumed for A(t,y),
12063 ! and also for the matrix P to which A is added here,
12064 ! as described in Paragraph B of the Summary of Usage above.
12065 ! Thus the affect of ADDA should be the following:
12066 ! DO 30 K = 1,NB
12067 ! DO 20 J = 1,MB
12068 ! DO 10 I = 1,MB
12069 ! PA(I,J,K) = PA(I,J,K) +
12070 ! ( (I,J) element of K-th diagonal block of A)
12071 ! PB(I,J,K) = PB(I,J,K) +
12072 ! ( (I,J) element of block (K,K+1) of A,
12073 ! or block (NB,NB-2) if K = NB)
12074 ! PC(I,J,K) = PC(I,J,K) +
12075 ! ( (I,J) element of block (K,K-1) of A,
12076 ! or block (1,3) if K = 1)
12077 ! 10 CONTINUE
12078 ! 20 CONTINUE
12079 ! 30 CONTINUE
12080 ! ADDA must be declared External in the calling program.
12081 ! See note below for more information about ADDA.
12082 ! JAC = the name of the user-supplied subroutine which supplies
12083 ! the Jacobian matrix, dr/dy, where r = g - A*s. JAC is
12084 ! required if MITER = 1. Otherwise a dummy name can be
12085 ! passed. This subroutine is to have the form
12086 ! SUBROUTINE JAC (NEQ, T, Y, S, MB, NB, PA, PB, PC)
12087 ! DOUBLE PRECISION T, Y(*), S(*), PA(MB,MB,NB),
12088 ! 1 PB(MB,MB,NB), PC(MB,MB,NB)
12089 ! where NEQ, T, Y, S, MB, NB, and the arrays PA, PB, and PC
12090 ! are input, and the arrays PA, PB, and PC are output.
12091 ! Y and S are arrays of length NEQ, and the arrays PA, PB, PC
12092 ! are all MB by MB by NB.
12093 ! PA, PB, and PC are to be loaded with partial derivatives
12094 ! (elements of the Jacobian matrix) on output, in terms of the
12095 ! block-tridiagonal structure assumed, as described
12096 ! in Paragraph B of the Summary of Usage above.
12097 ! That is, load the diagonal blocks into PA, the
12098 ! superdiagonal blocks (and block (NB,NB-2) ) into PB, and
12099 ! the subdiagonal blocks (and block (1,3) ) into PC.
12100 ! The blocks in block-row k of dr/dy are to be loaded into
12101 ! PA(*,*,k), PB(*,*,k), and PC(*,*,k).
12102 ! Thus the affect of JAC should be the following:
12103 ! DO 30 K = 1,NB
12104 ! DO 20 J = 1,MB
12105 ! DO 10 I = 1,MB
12106 ! PA(I,J,K) = ( (I,J) element of
12107 ! K-th diagonal block of dr/dy)
12108 ! PB(I,J,K) = ( (I,J) element of block (K,K+1)
12109 ! of dr/dy, or block (NB,NB-2) if K = NB)
12110 ! PC(I,J,K) = ( (I,J) element of block (K,K-1)
12111 ! of dr/dy, or block (1,3) if K = 1)
12112 ! 10 CONTINUE
12113 ! 20 CONTINUE
12114 ! 30 CONTINUE
12115 ! PA, PB, and PC are preset to zero by the solver,
12116 ! so that only the nonzero elements need be loaded by JAC.
12117 ! Each call to JAC is preceded by a call to RES with the same
12118 ! arguments NEQ, T, Y, and S. Thus to gain some efficiency,
12119 ! intermediate quantities shared by both calculations may be
12120 ! saved in a user Common block by RES and not recomputed by JAC
12121 ! if desired. Also, JAC may alter the Y array, if desired.
12122 ! JAC need not provide dr/dy exactly. A crude
12123 ! approximation will do, so that DLSOIBT may be used when
12124 ! A and dr/dy are not really block-tridiagonal, but are close
12125 ! to matrices that are.
12126 ! JAC must be declared External in the calling program.
12127 ! See note below for more about JAC.
12128 ! Note on RES, ADDA, and JAC:
12129 ! These subroutines may access user-defined quantities in
12130 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
12131 ! (dimensioned in the subroutines) and/or Y has length
12132 ! exceeding NEQ(1). However, these routines should not alter
12133 ! NEQ(1), Y(1),...,Y(NEQ) or any other input variables.
12134 ! See the descriptions of NEQ and Y below.
12135 ! NEQ = the size of the system (number of first order ordinary
12136 ! differential equations or scalar algebraic equations).
12137 ! Used only for input.
12138 ! NEQ may be decreased, but not increased, during the problem.
12139 ! If NEQ is decreased (with ISTATE = 3 on input), the
12140 ! remaining components of Y should be left undisturbed, if
12141 ! these are to be accessed in RES, ADDA, or JAC.
12142 ! Normally, NEQ is a scalar, and it is generally referred to
12143 ! as a scalar in this user interface description. However,
12144 ! NEQ may be an array, with NEQ(1) set to the system size.
12145 ! (The DLSOIBT package accesses only NEQ(1).) In either case,
12146 ! this parameter is passed as the NEQ argument in all calls
12147 ! to RES, ADDA, and JAC. Hence, if it is an array,
12148 ! locations NEQ(2),... may be used to store other integer data
12149 ! and pass it to RES, ADDA, or JAC. Each such subroutine
12150 ! must include NEQ in a Dimension statement in that case.
12151 ! Y = a real array for the vector of dependent variables, of
12152 ! length NEQ or more. Used for both input and output on the
12153 ! first call (ISTATE = 0 or 1), and only for output on other
12154 ! calls. On the first call, Y must contain the vector of
12155 ! initial values. On output, Y contains the computed solution
12156 ! vector, evaluated at t. If desired, the Y array may be used
12157 ! for other purposes between calls to the solver.
12158 ! This array is passed as the Y argument in all calls to RES,
12159 ! ADDA, and JAC. Hence its length may exceed NEQ,
12160 ! and locations Y(NEQ+1),... may be used to store other real
12161 ! data and pass it to RES, ADDA, or JAC. (The DLSOIBT
12162 ! package accesses only Y(1),...,Y(NEQ). )
12163 ! YDOTI = a real array for the initial value of the vector
12164 ! dy/dt and for work space, of dimension at least NEQ.
12165 ! On input:
12166 ! If ISTATE = 0 then DLSOIBT will compute the initial value
12167 ! of dy/dt, if A is nonsingular. Thus YDOTI will
12168 ! serve only as work space and may have any value.
12169 ! If ISTATE = 1 then YDOTI must contain the initial value
12170 ! of dy/dt.
12171 ! If ISTATE = 2 or 3 (continuation calls) then YDOTI
12172 ! may have any value.
12173 ! Note: If the initial value of A is singular, then
12174 ! DLSOIBT cannot compute the initial value of dy/dt, so
12175 ! it must be provided in YDOTI, with ISTATE = 1.
12176 ! On output, when DLSOIBT terminates abnormally with ISTATE =
12177 ! -1, -4, or -5, YDOTI will contain the residual
12178 ! r = g(t,y) - A(t,y)*(dy/dt). If r is large, t is near
12179 ! its initial value, and YDOTI is supplied with ISTATE = 1,
12180 ! there may have been an incorrect input value of
12181 ! YDOTI = dy/dt, or the problem (as given to DLSOIBT)
12182 ! may not have a solution.
12183 ! If desired, the YDOTI array may be used for other
12184 ! purposes between calls to the solver.
12185 ! T = the independent variable. On input, T is used only on the
12186 ! first call, as the initial point of the integration.
12187 ! On output, after each call, T is the value at which a
12188 ! computed solution y is evaluated (usually the same as TOUT).
12189 ! On an error return, T is the farthest point reached.
12190 ! TOUT = the next value of t at which a computed solution is desired.
12191 ! Used only for input.
12192 ! When starting the problem (ISTATE = 0 or 1), TOUT may be
12193 ! equal to T for one call, then should .ne. T for the next
12194 ! call. For the initial T, an input value of TOUT .ne. T is
12195 ! used in order to determine the direction of the integration
12196 ! (i.e. the algebraic sign of the step sizes) and the rough
12197 ! scale of the problem. Integration in either direction
12198 ! (forward or backward in t) is permitted.
12199 ! If ITASK = 2 or 5 (one-step modes), TOUT is ignored after
12200 ! the first call (i.e. the first call with TOUT .ne. T).
12201 ! Otherwise, TOUT is required on every call.
12202 ! If ITASK = 1, 3, or 4, the values of TOUT need not be
12203 ! monotone, but a value of TOUT which backs up is limited
12204 ! to the current internal T interval, whose endpoints are
12205 ! TCUR - HU and TCUR (see optional outputs, below, for
12206 ! TCUR and HU).
12207 ! ITOL = an indicator for the type of error control. See
12208 ! description below under ATOL. Used only for input.
12209 ! RTOL = a relative error tolerance parameter, either a scalar or
12210 ! an array of length NEQ. See description below under ATOL.
12211 ! Input only.
12212 ! ATOL = an absolute error tolerance parameter, either a scalar or
12213 ! an array of length NEQ. Input only.
12214 ! The input parameters ITOL, RTOL, and ATOL determine
12215 ! the error control performed by the solver. The solver will
12216 ! control the vector E = (E(i)) of estimated local errors
12217 ! in y, according to an inequality of the form
12218 ! RMS-norm of ( E(i)/EWT(i) ) .le. 1,
12219 ! where EWT(i) = RTOL(i)*ABS(Y(i)) + ATOL(i),
12220 ! and the RMS-norm (root-mean-square norm) here is
12221 ! RMS-norm(v) = SQRT(sum v(i)**2 / NEQ). Here EWT = (EWT(i))
12222 ! is a vector of weights which must always be positive, and
12223 ! the values of RTOL and ATOL should all be non-negative.
12224 ! The following table gives the types (scalar/array) of
12225 ! RTOL and ATOL, and the corresponding form of EWT(i).
12226 ! ITOL RTOL ATOL EWT(i)
12227 ! 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
12228 ! 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
12229 ! 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
12230 ! 4 array scalar RTOL(i)*ABS(Y(i)) + ATOL(i)
12231 ! When either of these parameters is a scalar, it need not
12232 ! be dimensioned in the user's calling program.
12233 ! If none of the above choices (with ITOL, RTOL, and ATOL
12234 ! fixed throughout the problem) is suitable, more general
12235 ! error controls can be obtained by substituting
12236 ! user-supplied routines for the setting of EWT and/or for
12237 ! the norm calculation. See Part 4 below.
12238 ! If global errors are to be estimated by making a repeated
12239 ! run on the same problem with smaller tolerances, then all
12240 ! components of RTOL and ATOL (i.e. of EWT) should be scaled
12241 ! down uniformly.
12242 ! ITASK = an index specifying the task to be performed.
12243 ! Input only. ITASK has the following values and meanings.
12244 ! 1 means normal computation of output values of y(t) at
12245 ! t = TOUT (by overshooting and interpolating).
12246 ! 2 means take one step only and return.
12247 ! 3 means stop at the first internal mesh point at or
12248 ! beyond t = TOUT and return.
12249 ! 4 means normal computation of output values of y(t) at
12250 ! t = TOUT but without overshooting t = TCRIT.
12251 ! TCRIT must be input as RWORK(1). TCRIT may be equal to
12252 ! or beyond TOUT, but not behind it in the direction of
12253 ! integration. This option is useful if the problem
12254 ! has a singularity at or beyond t = TCRIT.
12255 ! 5 means take one step, without passing TCRIT, and return.
12256 ! TCRIT must be input as RWORK(1).
12257 ! Note: If ITASK = 4 or 5 and the solver reaches TCRIT
12258 ! (within roundoff), it will return T = TCRIT (exactly) to
12259 ! indicate this (unless ITASK = 4 and TOUT comes before TCRIT,
12260 ! in which case answers at t = TOUT are returned first).
12261 ! ISTATE = an index used for input and output to specify the
12262 ! state of the calculation.
12263 ! On input, the values of ISTATE are as follows.
12264 ! 0 means this is the first call for the problem, and
12265 ! DLSOIBT is to compute the initial value of dy/dt
12266 ! (while doing other initializations). See note below.
12267 ! 1 means this is the first call for the problem, and
12268 ! the initial value of dy/dt has been supplied in
12269 ! YDOTI (DLSOIBT will do other initializations).
12270 ! See note below.
12271 ! 2 means this is not the first call, and the calculation
12272 ! is to continue normally, with no change in any input
12273 ! parameters except possibly TOUT and ITASK.
12274 ! (If ITOL, RTOL, and/or ATOL are changed between calls
12275 ! with ISTATE = 2, the new values will be used but not
12276 ! tested for legality.)
12277 ! 3 means this is not the first call, and the
12278 ! calculation is to continue normally, but with
12279 ! a change in input parameters other than
12280 ! TOUT and ITASK. Changes are allowed in
12281 ! NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF, MB, NB,
12282 ! and any of the optional inputs except H0.
12283 ! (See IWORK description for MB and NB.)
12284 ! Note: A preliminary call with TOUT = T is not counted
12285 ! as a first call here, as no initialization or checking of
12286 ! input is done. (Such a call is sometimes useful for the
12287 ! purpose of outputting the initial conditions.)
12288 ! Thus the first call for which TOUT .ne. T requires
12289 ! ISTATE = 0 or 1 on input.
12290 ! On output, ISTATE has the following values and meanings.
12291 ! 0 or 1 means nothing was done; TOUT = t and
12292 ! ISTATE = 0 or 1 on input.
12293 ! 2 means that the integration was performed successfully.
12294 ! 3 means that the user-supplied Subroutine RES signalled
12295 ! DLSOIBT to halt the integration and return (IRES = 2).
12296 ! Integration as far as T was achieved with no occurrence
12297 ! of IRES = 2, but this flag was set on attempting the
12298 ! next step.
12299 ! -1 means an excessive amount of work (more than MXSTEP
12300 ! steps) was done on this call, before completing the
12301 ! requested task, but the integration was otherwise
12302 ! successful as far as T. (MXSTEP is an optional input
12303 ! and is normally 500.) To continue, the user may
12304 ! simply reset ISTATE to a value .gt. 1 and call again
12305 ! (the excess work step counter will be reset to 0).
12306 ! In addition, the user may increase MXSTEP to avoid
12307 ! this error return (see below on optional inputs).
12308 ! -2 means too much accuracy was requested for the precision
12309 ! of the machine being used. This was detected before
12310 ! completing the requested task, but the integration
12311 ! was successful as far as T. To continue, the tolerance
12312 ! parameters must be reset, and ISTATE must be set
12313 ! to 3. The optional output TOLSF may be used for this
12314 ! purpose. (Note: If this condition is detected before
12315 ! taking any steps, then an illegal input return
12316 ! (ISTATE = -3) occurs instead.)
12317 ! -3 means illegal input was detected, before taking any
12318 ! integration steps. See written message for details.
12319 ! Note: If the solver detects an infinite loop of calls
12320 ! to the solver with illegal input, it will cause
12321 ! the run to stop.
12322 ! -4 means there were repeated error test failures on
12323 ! one attempted step, before completing the requested
12324 ! task, but the integration was successful as far as T.
12325 ! The problem may have a singularity, or the input
12326 ! may be inappropriate.
12327 ! -5 means there were repeated convergence test failures on
12328 ! one attempted step, before completing the requested
12329 ! task, but the integration was successful as far as T.
12330 ! This may be caused by an inaccurate Jacobian matrix.
12331 ! -6 means EWT(i) became zero for some i during the
12332 ! integration. Pure relative error control (ATOL(i) = 0.0)
12333 ! was requested on a variable which has now vanished.
12334 ! The integration was successful as far as T.
12335 ! -7 means that the user-supplied Subroutine RES set
12336 ! its error flag (IRES = 3) despite repeated tries by
12337 ! DLSOIBT to avoid that condition.
12338 ! -8 means that ISTATE was 0 on input but DLSOIBT was unable
12339 ! to compute the initial value of dy/dt. See the
12340 ! printed message for details.
12341 ! Note: Since the normal output value of ISTATE is 2,
12342 ! it does not need to be reset for normal continuation.
12343 ! Similarly, ISTATE (= 3) need not be reset if RES told
12344 ! DLSOIBT to return because the calling program must change
12345 ! the parameters of the problem.
12346 ! Also, since a negative input value of ISTATE will be
12347 ! regarded as illegal, a negative output value requires the
12348 ! user to change it, and possibly other inputs, before
12349 ! calling the solver again.
12350 ! IOPT = an integer flag to specify whether or not any optional
12351 ! inputs are being used on this call. Input only.
12352 ! The optional inputs are listed separately below.
12353 ! IOPT = 0 means no optional inputs are being used.
12354 ! Default values will be used in all cases.
12355 ! IOPT = 1 means one or more optional inputs are being used.
12356 ! RWORK = a real working array (double precision).
12357 ! The length of RWORK must be at least
12358 ! 20 + NYH*(MAXORD + 1) + 3*NEQ + LENWM where
12359 ! NYH = the initial value of NEQ,
12360 ! MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a
12361 ! smaller value is given as an optional input),
12362 ! LENWM = 3*MB*MB*NB + 2.
12363 ! (See MF description for the definition of METH.)
12364 ! Thus if MAXORD has its default value and NEQ is constant,
12365 ! this length is
12366 ! 22 + 16*NEQ + 3*MB*MB*NB for MF = 11 or 12,
12367 ! 22 + 9*NEQ + 3*MB*MB*NB for MF = 21 or 22.
12368 ! The first 20 words of RWORK are reserved for conditional
12369 ! and optional inputs and optional outputs.
12370 ! The following word in RWORK is a conditional input:
12371 ! RWORK(1) = TCRIT = critical value of t which the solver
12372 ! is not to overshoot. Required if ITASK is
12373 ! 4 or 5, and ignored otherwise. (See ITASK.)
12374 ! LRW = the length of the array RWORK, as declared by the user.
12375 ! (This will be checked by the solver.)
12376 ! IWORK = an integer work array. The length of IWORK must be at least
12377 ! 20 + NEQ . The first few words of IWORK are used for
12378 ! additional and optional inputs and optional outputs.
12379 ! The following 2 words in IWORK are additional required
12380 ! inputs to DLSOIBT:
12381 ! IWORK(1) = MB = block size
12382 ! IWORK(2) = NB = number of blocks in the main diagonal
12383 ! These must satisfy MB .ge. 1, NB .ge. 4, and MB*NB = NEQ.
12384 ! LIW = the length of the array IWORK, as declared by the user.
12385 ! (This will be checked by the solver.)
12386 ! Note: The work arrays must not be altered between calls to DLSOIBT
12387 ! for the same problem, except possibly for the additional and
12388 ! optional inputs, and except for the last 3*NEQ words of RWORK.
12389 ! The latter space is used for internal scratch space, and so is
12390 ! available for use by the user outside DLSOIBT between calls, if
12391 ! desired (but not for use by RES, ADDA, or JAC).
12392 ! MF = the method flag. used only for input. The legal values of
12393 ! MF are 11, 12, 21, and 22.
12394 ! MF has decimal digits METH and MITER: MF = 10*METH + MITER.
12395 ! METH indicates the basic linear multistep method:
12396 ! METH = 1 means the implicit Adams method.
12397 ! METH = 2 means the method based on Backward
12398 ! Differentiation Formulas (BDFS).
12399 ! The BDF method is strongly preferred for stiff
12400 ! problems, while the Adams method is preferred when the
12401 ! problem is not stiff. If the matrix A(t,y) is
12402 ! nonsingular, stiffness here can be taken to mean that of
12403 ! the explicit ODE system dy/dt = A-inverse * g. If A is
12404 ! singular, the concept of stiffness is not well defined.
12405 ! If you do not know whether the problem is stiff, we
12406 ! recommend using METH = 2. If it is stiff, the advantage
12407 ! of METH = 2 over METH = 1 will be great, while if it is
12408 ! not stiff, the advantage of METH = 1 will be slight.
12409 ! If maximum efficiency is important, some experimentation
12410 ! with METH may be necessary.
12411 ! MITER indicates the corrector iteration method:
12412 ! MITER = 1 means chord iteration with a user-supplied
12413 ! block-tridiagonal Jacobian.
12414 ! MITER = 2 means chord iteration with an internally
12415 ! generated (difference quotient) block-
12416 ! tridiagonal Jacobian approximation, using
12417 ! 3*MB+1 extra calls to RES per dr/dy evaluation.
12418 ! If MITER = 1, the user must supply a Subroutine JAC
12419 ! (the name is arbitrary) as described above under JAC.
12420 ! For MITER = 2, a dummy argument can be used.
12421 !-----------------------------------------------------------------------
12422 ! Optional Inputs.
12423 ! The following is a list of the optional inputs provided for in the
12424 ! call sequence. (See also Part 2.) For each such input variable,
12425 ! this table lists its name as used in this documentation, its
12426 ! location in the call sequence, its meaning, and the default value.
12427 ! The use of any of these inputs requires IOPT = 1, and in that
12428 ! case all of these inputs are examined. A value of zero for any
12429 ! of these optional inputs will cause the default value to be used.
12430 ! Thus to use a subset of the optional inputs, simply preload
12431 ! locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, and
12432 ! then set those of interest to nonzero values.
12433 ! Name Location Meaning and Default Value
12434 ! H0 RWORK(5) the step size to be attempted on the first step.
12435 ! The default value is determined by the solver.
12436 ! HMAX RWORK(6) the maximum absolute step size allowed.
12437 ! The default value is infinite.
12438 ! HMIN RWORK(7) the minimum absolute step size allowed.
12439 ! The default value is 0. (This lower bound is not
12440 ! enforced on the final step before reaching TCRIT
12441 ! when ITASK = 4 or 5.)
12442 ! MAXORD IWORK(5) the maximum order to be allowed. The default
12443 ! value is 12 if METH = 1, and 5 if METH = 2.
12444 ! If MAXORD exceeds the default value, it will
12445 ! be reduced to the default value.
12446 ! If MAXORD is changed during the problem, it may
12447 ! cause the current order to be reduced.
12448 ! MXSTEP IWORK(6) maximum number of (internally defined) steps
12449 ! allowed during one call to the solver.
12450 ! The default value is 500.
12451 ! MXHNIL IWORK(7) maximum number of messages printed (per problem)
12452 ! warning that T + H = T on a step (H = step size).
12453 ! This must be positive to result in a non-default
12454 ! value. The default value is 10.
12455 !-----------------------------------------------------------------------
12456 ! Optional Outputs.
12457 ! As optional additional output from DLSOIBT, the variables listed
12458 ! below are quantities related to the performance of DLSOIBT
12459 ! which are available to the user. These are communicated by way of
12460 ! the work arrays, but also have internal mnemonic names as shown.
12461 ! Except where stated otherwise, all of these outputs are defined
12462 ! on any successful return from DLSOIBT, and on any return with
12463 ! ISTATE = -1, -2, -4, -5, -6, or -7. On a return with -3 (illegal
12464 ! input) or -8, they will be unchanged from their existing values
12465 ! (if any), except possibly for TOLSF, LENRW, and LENIW.
12466 ! On any error return, outputs relevant to the error will be defined,
12467 ! as noted below.
12468 ! Name Location Meaning
12469 ! HU RWORK(11) the step size in t last used (successfully).
12470 ! HCUR RWORK(12) the step size to be attempted on the next step.
12471 ! TCUR RWORK(13) the current value of the independent variable
12472 ! which the solver has actually reached, i.e. the
12473 ! current internal mesh point in t. On output, TCUR
12474 ! will always be at least as far as the argument
12475 ! T, but may be farther (if interpolation was done).
12476 ! TOLSF RWORK(14) a tolerance scale factor, greater than 1.0,
12477 ! computed when a request for too much accuracy was
12478 ! detected (ISTATE = -3 if detected at the start of
12479 ! the problem, ISTATE = -2 otherwise). If ITOL is
12480 ! left unaltered but RTOL and ATOL are uniformly
12481 ! scaled up by a factor of TOLSF for the next call,
12482 ! then the solver is deemed likely to succeed.
12483 ! (The user may also ignore TOLSF and alter the
12484 ! tolerance parameters in any other way appropriate.)
12485 ! NST IWORK(11) the number of steps taken for the problem so far.
12486 ! NRE IWORK(12) the number of residual evaluations (RES calls)
12487 ! for the problem so far.
12488 ! NJE IWORK(13) the number of Jacobian evaluations (each involving
12489 ! an evaluation of a and dr/dy) for the problem so
12490 ! far. This equals the number of calls to ADDA and
12491 ! (if MITER = 1) to JAC, and the number of matrix
12492 ! LU decompositions.
12493 ! NQU IWORK(14) the method order last used (successfully).
12494 ! NQCUR IWORK(15) the order to be attempted on the next step.
12495 ! IMXER IWORK(16) the index of the component of largest magnitude in
12496 ! the weighted local error vector ( E(i)/EWT(i) ),
12497 ! on an error return with ISTATE = -4 or -5.
12498 ! LENRW IWORK(17) the length of RWORK actually required.
12499 ! This is defined on normal returns and on an illegal
12500 ! input return for insufficient storage.
12501 ! LENIW IWORK(18) the length of IWORK actually required.
12502 ! This is defined on normal returns and on an illegal
12503 ! input return for insufficient storage.
12504 ! The following two arrays are segments of the RWORK array which
12505 ! may also be of interest to the user as optional outputs.
12506 ! For each array, the table below gives its internal name,
12507 ! its base address in RWORK, and its description.
12508 ! Name Base Address Description
12509 ! YH 21 the Nordsieck history array, of size NYH by
12510 ! (NQCUR + 1), where NYH is the initial value
12511 ! of NEQ. For j = 0,1,...,NQCUR, column j+1
12512 ! of YH contains HCUR**j/factorial(j) times
12513 ! the j-th derivative of the interpolating
12514 ! polynomial currently representing the solution,
12515 ! evaluated at t = TCUR.
12516 ! ACOR LENRW-NEQ+1 array of size NEQ used for the accumulated
12517 ! corrections on each step, scaled on output to
12518 ! represent the estimated local error in y on
12519 ! the last step. This is the vector E in the
12520 ! description of the error control. It is
12521 ! defined only on a return from DLSOIBT with
12522 ! ISTATE = 2.
12523 !-----------------------------------------------------------------------
12524 ! Part 2. Other Routines Callable.
12525 ! The following are optional calls which the user may make to
12526 ! gain additional capabilities in conjunction with DLSOIBT.
12527 ! (The routines XSETUN and XSETF are designed to conform to the
12528 ! SLATEC error handling package.)
12529 ! Form of Call Function
12530 ! CALL XSETUN(LUN) Set the logical unit number, LUN, for
12531 ! output of messages from DLSOIBT, if
12532 ! the default is not desired.
12533 ! The default value of LUN is 6.
12534 ! CALL XSETF(MFLAG) Set a flag to control the printing of
12535 ! messages by DLSOIBT.
12536 ! MFLAG = 0 means do not print. (Danger:
12537 ! This risks losing valuable information.)
12538 ! MFLAG = 1 means print (the default).
12539 ! Either of the above calls may be made at
12540 ! any time and will take effect immediately.
12541 ! CALL DSRCOM(RSAV,ISAV,JOB) saves and restores the contents of
12542 ! the internal Common blocks used by
12543 ! DLSOIBT (see Part 3 below).
12544 ! RSAV must be a real array of length 218
12545 ! or more, and ISAV must be an integer
12546 ! array of length 37 or more.
12547 ! JOB=1 means save Common into RSAV/ISAV.
12548 ! JOB=2 means restore Common from RSAV/ISAV.
12549 ! DSRCOM is useful if one is
12550 ! interrupting a run and restarting
12551 ! later, or alternating between two or
12552 ! more problems solved with DLSOIBT.
12553 ! CALL DINTDY(,,,,,) Provide derivatives of y, of various
12554 ! (see below) orders, at a specified point t, if
12555 ! desired. It may be called only after
12556 ! a successful return from DLSOIBT.
12557 ! The detailed instructions for using DINTDY are as follows.
12558 ! The form of the call is:
12559 ! CALL DINTDY (T, K, RWORK(21), NYH, DKY, IFLAG)
12560 ! The input parameters are:
12561 ! T = value of independent variable where answers are desired
12562 ! (normally the same as the t last returned by DLSOIBT).
12563 ! For valid results, T must lie between TCUR - HU and TCUR.
12564 ! (See optional outputs for TCUR and HU.)
12565 ! K = integer order of the derivative desired. K must satisfy
12566 ! 0 .le. K .le. NQCUR, where NQCUR is the current order
12567 ! (see optional outputs). The capability corresponding
12568 ! to K = 0, i.e. computing y(t), is already provided
12569 ! by DLSOIBT directly. Since NQCUR .ge. 1, the first
12570 ! derivative dy/dt is always available with DINTDY.
12571 ! RWORK(21) = the base address of the history array YH.
12572 ! NYH = column length of YH, equal to the initial value of NEQ.
12573 ! The output parameters are:
12574 ! DKY = a real array of length NEQ containing the computed value
12575 ! of the K-th derivative of y(t).
12576 ! IFLAG = integer flag, returned as 0 if K and T were legal,
12577 ! -1 if K was illegal, and -2 if T was illegal.
12578 ! On an error return, a message is also written.
12579 !-----------------------------------------------------------------------
12580 ! Part 3. Common Blocks.
12581 ! If DLSOIBT is to be used in an overlay situation, the user
12582 ! must declare, in the primary overlay, the variables in:
12583 ! (1) the call sequence to DLSOIBT, and
12584 ! (2) the internal Common block
12585 ! /DLS001/ of length 255 (218 double precision words
12586 ! followed by 37 integer words),
12587 ! If DLSOIBT is used on a system in which the contents of internal
12588 ! Common blocks are not preserved between calls, the user should
12589 ! declare the above Common block in the calling program to insure
12590 ! that their contents are preserved.
12591 ! If the solution of a given problem by DLSOIBT is to be interrupted
12592 ! and then later continued, such as when restarting an interrupted run
12593 ! or alternating between two or more problems, the user should save,
12594 ! following the return from the last DLSOIBT call prior to the
12595 ! interruption, the contents of the call sequence variables and the
12596 ! internal Common blocks, and later restore these values before the
12597 ! next DLSOIBT call for that problem. To save and restore the Common
12598 ! blocks, use Subroutine DSRCOM (see Part 2 above).
12599 !-----------------------------------------------------------------------
12600 ! Part 4. Optionally Replaceable Solver Routines.
12601 ! Below are descriptions of two routines in the DLSOIBT package which
12602 ! relate to the measurement of errors. Either routine can be
12603 ! replaced by a user-supplied version, if desired. However, since such
12604 ! a replacement may have a major impact on performance, it should be
12605 ! done only when absolutely necessary, and only with great caution.
12606 ! (Note: The means by which the package version of a routine is
12607 ! superseded by the user's version may be system-dependent.)
12608 ! (a) DEWSET.
12609 ! The following subroutine is called just before each internal
12610 ! integration step, and sets the array of error weights, EWT, as
12611 ! described under ITOL/RTOL/ATOL above:
12612 ! SUBROUTINE DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
12613 ! where NEQ, ITOL, RTOL, and ATOL are as in the DLSOIBT call sequence,
12614 ! YCUR contains the current dependent variable vector, and
12615 ! EWT is the array of weights set by DEWSET.
12616 ! If the user supplies this subroutine, it must return in EWT(i)
12617 ! (i = 1,...,NEQ) a positive quantity suitable for comparing errors
12618 ! in y(i) to. The EWT array returned by DEWSET is passed to the DVNORM
12619 ! routine (see below), and also used by DLSOIBT in the computation
12620 ! of the optional output IMXER, the diagonal Jacobian approximation,
12621 ! and the increments for difference quotient Jacobians.
12622 ! In the user-supplied version of DEWSET, it may be desirable to use
12623 ! the current values of derivatives of y. Derivatives up to order NQ
12624 ! are available from the history array YH, described above under
12625 ! optional outputs. In DEWSET, YH is identical to the YCUR array,
12626 ! extended to NQ + 1 columns with a column length of NYH and scale
12627 ! factors of H**j/factorial(j). On the first call for the problem,
12628 ! given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
12629 ! NYH is the initial value of NEQ. The quantities NQ, H, and NST
12630 ! can be obtained by including in DEWSET the statements:
12631 ! DOUBLE PRECISION RLS
12632 ! COMMON /DLS001/ RLS(218),ILS(37)
12633 ! NQ = ILS(33)
12634 ! NST = ILS(34)
12635 ! H = RLS(212)
12636 ! Thus, for example, the current value of dy/dt can be obtained as
12637 ! YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is
12638 ! unnecessary when NST = 0).
12639 ! (b) DVNORM.
12640 ! The following is a real function routine which computes the weighted
12641 ! root-mean-square norm of a vector v:
12642 ! D = DVNORM (N, V, W)
12643 ! where:
12644 ! N = the length of the vector,
12645 ! V = real array of length N containing the vector,
12646 ! W = real array of length N containing weights,
12647 ! D = SQRT( (1/N) * sum(V(i)*W(i))**2 ).
12648 ! DVNORM is called with N = NEQ and with W(i) = 1.0/EWT(i), where
12649 ! EWT is as set by Subroutine DEWSET.
12650 ! If the user supplies this function, it should return a non-negative
12651 ! value of DVNORM suitable for use in the error control in DLSOIBT.
12652 ! None of the arguments should be altered by DVNORM.
12653 ! For example, a user-supplied DVNORM routine might:
12654 ! -substitute a max-norm of (V(i)*W(i)) for the RMS-norm, or
12655 ! -ignore some components of V in the norm, with the effect of
12656 ! suppressing the error control on those components of y.
12657 !-----------------------------------------------------------------------
12658 !***REVISION HISTORY (YYYYMMDD)
12659 ! 19840625 DATE WRITTEN
12660 ! 19870330 Major update: corrected comments throughout;
12661 ! removed TRET from Common; rewrote EWSET with 4 loops;
12662 ! fixed t test in INTDY; added Cray directives in STODI;
12663 ! in STODI, fixed DELP init. and logic around PJAC call;
12664 ! combined routines to save/restore Common;
12665 ! passed LEVEL = 0 in error message calls (except run abort).
12666 ! 20010425 Major update: convert source lines to upper case;
12667 ! added *DECK lines; changed from 1 to * in dummy dimensions;
12668 ! changed names R1MACH/D1MACH to RUMACH/DUMACH;
12669 ! renamed routines for uniqueness across single/double prec.;
12670 ! converted intrinsic names to generic form;
12671 ! removed ILLIN and NTREP (data loaded) from Common;
12672 ! removed all 'own' variables from Common;
12673 ! changed error messages to quoted strings;
12674 ! replaced XERRWV/XERRWD with 1993 revised version;
12675 ! converted prologues, comments, error messages to mixed case;
12676 ! converted arithmetic IF statements to logical IF statements;
12677 ! numerous corrections to prologues and internal comments.
12678 ! 20010507 Converted single precision source to double precision.
12679 ! 20020502 Corrected declarations in descriptions of user routines.
12680 ! 20031105 Restored 'own' variables to Common block, to enable
12681 ! interrupt/restart feature.
12682 ! 20031112 Added SAVE statements for data-loaded constants.
12683 ! 20031117 Changed internal names NRE, LSAVR to NFE, LSAVF resp.
12684 !-----------------------------------------------------------------------
12685 ! Other routines in the DLSOIBT package.
12686 ! In addition to Subroutine DLSOIBT, the DLSOIBT package includes the
12687 ! following subroutines and function routines:
12688 ! DAIGBT computes the initial value of the vector
12689 ! dy/dt = A-inverse * g
12690 ! DINTDY computes an interpolated value of the y vector at t = TOUT.
12691 ! DSTODI is the core integrator, which does one step of the
12692 ! integration and the associated error control.
12693 ! DCFODE sets all method coefficients and test constants.
12694 ! DEWSET sets the error weight vector EWT before each step.
12695 ! DVNORM computes the weighted RMS-norm of a vector.
12696 ! DSRCOM is a user-callable routine to save and restore
12697 ! the contents of the internal Common blocks.
12698 ! DPJIBT computes and preprocesses the Jacobian matrix
12699 ! and the Newton iteration matrix P.
12700 ! DSLSBT manages solution of linear system in chord iteration.
12701 ! DDECBT and DSOLBT are routines for solving block-tridiagonal
12702 ! systems of linear algebraic equations.
12703 ! DGEFA and DGESL are routines from LINPACK for solving full
12704 ! systems of linear algebraic equations.
12705 ! DDOT is one of the basic linear algebra modules (BLAS).
12706 ! DUMACH computes the unit roundoff in a machine-independent manner.
12707 ! XERRWD, XSETUN, XSETF, IXSAV, and IUMACH handle the printing of all
12708 ! error messages and warnings. XERRWD is machine-dependent.
12709 ! Note: DVNORM, DDOT, DUMACH, IXSAV, and IUMACH are function routines.
12710 ! All the others are subroutines.
12711 !-----------------------------------------------------------------------
12712 ! EXTERNAL DPJIBT, DSLSBT
12713 ! DOUBLE PRECISION :: DUMACH, DVNORM
12714 ! INTEGER :: INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS, &
12715 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
12716 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
12717 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
12718 ! INTEGER :: I, I1, I2, IER, IFLAG, IMXER, IRES, KGO, &
12719 ! LENIW, LENRW, LENWM, LP, LYD0, MB, MORD, MXHNL0, MXSTP0, NB
12720 ! DOUBLE PRECISION :: ROWNS, &
12721 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
12722 ! DOUBLE PRECISION :: ATOLI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RTOLI, &
12723 ! TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0
12724 ! DIMENSION MORD(2)
12725 ! LOGICAL :: IHIT
12726 ! CHARACTER(60) :: MSG
12727 ! SAVE MORD, MXSTP0, MXHNL0
12728 !-----------------------------------------------------------------------
12729 ! The following internal Common block contains
12730 ! (a) variables which are local to any subroutine but whose values must
12731 ! be preserved between calls to the routine ("own" variables), and
12732 ! (b) variables which are communicated between subroutines.
12733 ! The block DLS001 is declared in subroutines DLSOIBT, DINTDY, DSTODI,
12734 ! DPJIBT, and DSLSBT.
12735 ! Groups of variables are replaced by dummy arrays in the Common
12736 ! declarations in routines where those variables are not used.
12737 !-----------------------------------------------------------------------
12738 ! COMMON /DLS001/ ROWNS(209), &
12739 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
12740 ! INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6), &
12741 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
12742 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
12743 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
12744 ! DATA MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
12745 !-----------------------------------------------------------------------
12746 ! Block A.
12747 ! This code block is executed on every call.
12748 ! It tests ISTATE and ITASK for legality and branches appropriately.
12749 ! If ISTATE .gt. 1 but the flag INIT shows that initialization has
12750 ! not yet been done, an error return occurs.
12751 ! If ISTATE = 0 or 1 and TOUT = T, return immediately.
12752 !-----------------------------------------------------------------------
12753 ! IF (ISTATE < 0 .OR. ISTATE > 3) GO TO 601
12754 ! IF (ITASK < 1 .OR. ITASK > 5) GO TO 602
12755 ! IF (ISTATE <= 1) GO TO 10
12756 ! IF (INIT == 0) GO TO 603
12757 ! IF (ISTATE == 2) GO TO 200
12758 ! GO TO 20
12759 ! 10 INIT = 0
12760 ! IF (TOUT == T) RETURN
12761 !-----------------------------------------------------------------------
12762 ! Block B.
12763 ! The next code block is executed for the initial call (ISTATE = 0 or 1)
12764 ! or for a continuation call with parameter changes (ISTATE = 3).
12765 ! It contains checking of all inputs and various initializations.
12766 ! First check legality of the non-optional inputs NEQ, ITOL, IOPT,
12767 ! MF, MB, and NB.
12768 !-----------------------------------------------------------------------
12769 ! 20 IF (NEQ(1) <= 0) GO TO 604
12770 ! IF (ISTATE <= 1) GO TO 25
12771 ! IF (NEQ(1) > N) GO TO 605
12772 ! 25 N = NEQ(1)
12773 ! IF (ITOL < 1 .OR. ITOL > 4) GO TO 606
12774 ! IF (IOPT < 0 .OR. IOPT > 1) GO TO 607
12775 ! METH = MF/10
12776 ! MITER = MF - 10*METH
12777 ! IF (METH < 1 .OR. METH > 2) GO TO 608
12778 ! IF (MITER < 1 .OR. MITER > 2) GO TO 608
12779 ! MB = IWORK(1)
12780 ! NB = IWORK(2)
12781 ! IF (MB < 1 .OR. MB > N) GO TO 609
12782 ! IF (NB < 4) GO TO 610
12783 ! IF (MB*NB /= N) GO TO 609
12784 ! Next process and check the optional inputs. --------------------------
12785 ! IF (IOPT == 1) GO TO 40
12786 ! MAXORD = MORD(METH)
12787 ! MXSTEP = MXSTP0
12788 ! MXHNIL = MXHNL0
12789 ! IF (ISTATE <= 1) H0 = 0.0D0
12790 ! HMXI = 0.0D0
12791 ! HMIN = 0.0D0
12792 ! GO TO 60
12793 ! 40 MAXORD = IWORK(5)
12794 ! IF (MAXORD < 0) GO TO 611
12795 ! IF (MAXORD == 0) MAXORD = 100
12796 ! MAXORD = MIN(MAXORD,MORD(METH))
12797 ! MXSTEP = IWORK(6)
12798 ! IF (MXSTEP < 0) GO TO 612
12799 ! IF (MXSTEP == 0) MXSTEP = MXSTP0
12800 ! MXHNIL = IWORK(7)
12801 ! IF (MXHNIL < 0) GO TO 613
12802 ! IF (MXHNIL == 0) MXHNIL = MXHNL0
12803 ! IF (ISTATE > 1) GO TO 50
12804 ! H0 = RWORK(5)
12805 ! IF ((TOUT - T)*H0 < 0.0D0) GO TO 614
12806 ! 50 HMAX = RWORK(6)
12807 ! IF (HMAX < 0.0D0) GO TO 615
12808 ! HMXI = 0.0D0
12809 ! IF (HMAX > 0.0D0) HMXI = 1.0D0/HMAX
12810 ! HMIN = RWORK(7)
12811 ! IF (HMIN < 0.0D0) GO TO 616
12812 !-----------------------------------------------------------------------
12813 ! Set work array pointers and check lengths LRW and LIW.
12814 ! Pointers to segments of RWORK and IWORK are named by prefixing L to
12815 ! the name of the segment. E.g., the segment YH starts at RWORK(LYH).
12816 ! Segments of RWORK (in order) are denoted YH, WM, EWT, SAVR, ACOR.
12817 !-----------------------------------------------------------------------
12818 ! 60 LYH = 21
12819 ! IF (ISTATE <= 1) NYH = N
12820 ! LWM = LYH + (MAXORD + 1)*NYH
12821 ! LENWM = 3*MB*MB*NB + 2
12822 ! LEWT = LWM + LENWM
12823 ! LSAVF = LEWT + N
12824 ! LACOR = LSAVF + N
12825 ! LENRW = LACOR + N - 1
12826 ! IWORK(17) = LENRW
12827 ! LIWM = 1
12828 ! LENIW = 20 + N
12829 ! IWORK(18) = LENIW
12830 ! IF (LENRW > LRW) GO TO 617
12831 ! IF (LENIW > LIW) GO TO 618
12832 ! Check RTOL and ATOL for legality. ------------------------------------
12833 ! RTOLI = RTOL(1)
12834 ! ATOLI = ATOL(1)
12835 ! DO 70 I = 1,N
12836 ! IF (ITOL >= 3) RTOLI = RTOL(I)
12837 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
12838 ! IF (RTOLI < 0.0D0) GO TO 619
12839 ! IF (ATOLI < 0.0D0) GO TO 620
12840 ! 70 END DO
12841 ! IF (ISTATE <= 1) GO TO 100
12842 ! If ISTATE = 3, set flag to signal parameter changes to DSTODI. -------
12843 ! JSTART = -1
12844 ! IF (NQ <= MAXORD) GO TO 90
12845 ! MAXORD was reduced below NQ. Copy YH(*,MAXORD+2) into YDOTI.---------
12846 ! DO 80 I = 1,N
12847 ! YDOTI(I) = RWORK(I+LWM-1)
12848 ! 80 END DO
12849 ! Reload WM(1) = RWORK(lWM), since lWM may have changed. ---------------
12850 ! 90 RWORK(LWM) = SQRT(UROUND)
12851 ! IF (N == NYH) GO TO 200
12852 ! NEQ was reduced. Zero part of YH to avoid undefined references. -----
12853 ! I1 = LYH + L*NYH
12854 ! I2 = LYH + (MAXORD + 1)*NYH - 1
12855 ! IF (I1 > I2) GO TO 200
12856 ! DO 95 I = I1,I2
12857 ! RWORK(I) = 0.0D0
12858 ! 95 END DO
12859 ! GO TO 200
12860 !-----------------------------------------------------------------------
12861 ! Block C.
12862 ! The next block is for the initial call only (ISTATE = 0 or 1).
12863 ! It contains all remaining initializations, the call to DAIGBT
12864 ! (if ISTATE = 1), and the calculation of the initial step size.
12865 ! The error weights in EWT are inverted after being loaded.
12866 !-----------------------------------------------------------------------
12867 ! 100 UROUND = DUMACH()
12868 ! TN = T
12869 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 105
12870 ! TCRIT = RWORK(1)
12871 ! IF ((TCRIT - TOUT)*(TOUT - T) < 0.0D0) GO TO 625
12872 ! IF (H0 /= 0.0D0 .AND. (T + H0 - TCRIT)*H0 > 0.0D0) &
12873 ! H0 = TCRIT - T
12874 ! 105 JSTART = 0
12875 ! RWORK(LWM) = SQRT(UROUND)
12876 ! NHNIL = 0
12877 ! NST = 0
12878 ! NFE = 0
12879 ! NJE = 0
12880 ! NSLAST = 0
12881 ! HU = 0.0D0
12882 ! NQU = 0
12883 ! CCMAX = 0.3D0
12884 ! MAXCOR = 3
12885 ! MSBP = 20
12886 ! MXNCF = 10
12887 ! Compute initial dy/dt, if necessary, and load it and initial Y into YH
12888 ! LYD0 = LYH + NYH
12889 ! LP = LWM + 1
12890 ! IF ( ISTATE == 1 ) GO TO 120
12891 ! DLSOIBT must compute initial dy/dt (LYD0 points to YH(*,2)). ---------
12892 ! CALL DAIGBT( RES, ADDA, NEQ, T, Y, RWORK(LYD0), &
12893 ! MB, NB, RWORK(LP), IWORK(21), IER )
12894 ! NFE = NFE + 1
12895 ! IF (IER < 0) GO TO 560
12896 ! IF (IER > 0) GO TO 565
12897 ! DO 115 I = 1,N
12898 ! RWORK(I+LYH-1) = Y(I)
12899 ! 115 END DO
12900 ! GO TO 130
12901 ! Initial dy/dt was supplied. Load into YH (LYD0 points to YH(*,2).). -
12902 ! 120 DO 125 I = 1,N
12903 ! RWORK(I+LYH-1) = Y(I)
12904 ! RWORK(I+LYD0-1) = YDOTI(I)
12905 ! 125 END DO
12906 ! Load and invert the EWT array. (H is temporarily set to 1.0.) -------
12907 ! 130 CONTINUE
12908 ! NQ = 1
12909 ! H = 1.0D0
12910 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
12911 ! DO 135 I = 1,N
12912 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
12913 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
12914 ! 135 END DO
12915 !-----------------------------------------------------------------------
12916 ! The coding below computes the step size, H0, to be attempted on the
12917 ! first step, unless the user has supplied a value for this.
12918 ! First check that TOUT - T differs significantly from zero.
12919 ! A scalar tolerance quantity TOL is computed, as MAX(RTOL(i))
12920 ! if this is positive, or MAX(ATOL(i)/ABS(Y(i))) otherwise, adjusted
12921 ! so as to be between 100*UROUND and 1.0E-3.
12922 ! Then the computed value H0 is given by..
12923 ! NEQ
12924 ! H0**2 = TOL / ( w0**-2 + (1/NEQ) * Sum ( YDOT(i)/ywt(i) )**2 )
12925 ! 1
12926 ! where w0 = MAX ( ABS(T), ABS(TOUT) ),
12927 ! YDOT(i) = i-th component of initial value of dy/dt,
12928 ! ywt(i) = EWT(i)/TOL (a weight for y(i)).
12929 ! The sign of H0 is inferred from the initial values of TOUT and T.
12930 !-----------------------------------------------------------------------
12931 ! IF (H0 /= 0.0D0) GO TO 180
12932 ! TDIST = ABS(TOUT - T)
12933 ! W0 = MAX(ABS(T),ABS(TOUT))
12934 ! IF (TDIST < 2.0D0*UROUND*W0) GO TO 622
12935 ! TOL = RTOL(1)
12936 ! IF (ITOL <= 2) GO TO 145
12937 ! DO 140 I = 1,N
12938 ! TOL = MAX(TOL,RTOL(I))
12939 ! 140 END DO
12940 ! 145 IF (TOL > 0.0D0) GO TO 160
12941 ! ATOLI = ATOL(1)
12942 ! DO 150 I = 1,N
12943 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
12944 ! AYI = ABS(Y(I))
12945 ! IF (AYI /= 0.0D0) TOL = MAX(TOL,ATOLI/AYI)
12946 ! 150 END DO
12947 ! 160 TOL = MAX(TOL,100.0D0*UROUND)
12948 ! TOL = MIN(TOL,0.001D0)
12949 ! SUM = DVNORM (N, RWORK(LYD0), RWORK(LEWT))
12950 ! SUM = 1.0D0/(TOL*W0*W0) + TOL*SUM**2
12951 ! H0 = 1.0D0/SQRT(SUM)
12952 ! H0 = MIN(H0,TDIST)
12953 ! H0 = SIGN(H0,TOUT-T)
12954 ! Adjust H0 if necessary to meet HMAX bound. ---------------------------
12955 ! 180 RH = ABS(H0)*HMXI
12956 ! IF (RH > 1.0D0) H0 = H0/RH
12957 ! Load H with H0 and scale YH(*,2) by H0. ------------------------------
12958 ! H = H0
12959 ! DO 190 I = 1,N
12960 ! RWORK(I+LYD0-1) = H0*RWORK(I+LYD0-1)
12961 ! 190 END DO
12962 ! GO TO 270
12963 !-----------------------------------------------------------------------
12964 ! Block D.
12965 ! The next code block is for continuation calls only (ISTATE = 2 or 3)
12966 ! and is to check stop conditions before taking a step.
12967 !-----------------------------------------------------------------------
12968 ! 200 NSLAST = NST
12969 ! GO TO (210, 250, 220, 230, 240), ITASK
12970 ! 210 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
12971 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
12972 ! IF (IFLAG /= 0) GO TO 627
12973 ! T = TOUT
12974 ! GO TO 420
12975 ! 220 TP = TN - HU*(1.0D0 + 100.0D0*UROUND)
12976 ! IF ((TP - TOUT)*H > 0.0D0) GO TO 623
12977 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 250
12978 ! GO TO 400
12979 ! 230 TCRIT = RWORK(1)
12980 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
12981 ! IF ((TCRIT - TOUT)*H < 0.0D0) GO TO 625
12982 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 245
12983 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
12984 ! IF (IFLAG /= 0) GO TO 627
12985 ! T = TOUT
12986 ! GO TO 420
12987 ! 240 TCRIT = RWORK(1)
12988 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
12989 ! 245 HMX = ABS(TN) + ABS(H)
12990 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
12991 ! IF (IHIT) GO TO 400
12992 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
12993 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
12994 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
12995 ! IF (ISTATE == 2) JSTART = -2
12996 !-----------------------------------------------------------------------
12997 ! Block E.
12998 ! The next block is normally executed for all calls and contains
12999 ! the call to the one-step core integrator DSTODI.
13000 ! This is a looping point for the integration steps.
13001 ! First check for too many steps being taken, update EWT (if not at
13002 ! start of problem), check for too much accuracy being requested, and
13003 ! check for H below the roundoff level in T.
13004 !-----------------------------------------------------------------------
13005 ! 250 CONTINUE
13006 ! IF ((NST-NSLAST) >= MXSTEP) GO TO 500
13007 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
13008 ! DO 260 I = 1,N
13009 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 510
13010 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
13011 ! 260 END DO
13012 ! 270 TOLSF = UROUND*DVNORM (N, RWORK(LYH), RWORK(LEWT))
13013 ! IF (TOLSF <= 1.0D0) GO TO 280
13014 ! TOLSF = TOLSF*2.0D0
13015 ! IF (NST == 0) GO TO 626
13016 ! GO TO 520
13017 ! 280 IF ((TN + H) /= TN) GO TO 290
13018 ! NHNIL = NHNIL + 1
13019 ! IF (NHNIL > MXHNIL) GO TO 290
13020 ! MSG = 'DLSOIBT- Warning..Internal T (=R1) and H (=R2) are'
13021 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13022 ! MSG=' such that in the machine, T + H = T on the next step '
13023 ! CALL XERRWD (MSG, 60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13024 ! MSG = ' (H = step size). Solver will continue anyway.'
13025 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 2, TN, H)
13026 ! IF (NHNIL < MXHNIL) GO TO 290
13027 ! MSG = 'DLSOIBT- Above warning has been issued I1 times. '
13028 ! CALL XERRWD (MSG, 50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13029 ! MSG = ' It will not be issued again for this problem.'
13030 ! CALL XERRWD (MSG, 50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
13031 ! 290 CONTINUE
13032 !-----------------------------------------------------------------------
13033 ! CALL DSTODI(NEQ,Y,YH,NYH,YH1,EWT,SAVF,SAVR,ACOR,WM,IWM,RES,
13034 ! ADDA,JAC,DPJIBT,DSLSBT)
13035 ! Note: SAVF in DSTODI occupies the same space as YDOTI in DLSOIBT.
13036 !-----------------------------------------------------------------------
13037 ! CALL DSTODI (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT), &
13038 ! YDOTI, RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), &
13039 ! IWORK(LIWM), RES, ADDA, JAC, DPJIBT, DSLSBT )
13040 ! KGO = 1 - KFLAG
13041 ! GO TO (300, 530, 540, 400, 550), KGO
13042 ! KGO = 1:success; 2:error test failure; 3:convergence failure;
13043 ! 4:RES ordered return; 5:RES returned error.
13044 !-----------------------------------------------------------------------
13045 ! Block F.
13046 ! The following block handles the case of a successful return from the
13047 ! core integrator (KFLAG = 0). Test for stop conditions.
13048 !-----------------------------------------------------------------------
13049 ! 300 INIT = 1
13050 ! GO TO (310, 400, 330, 340, 350), ITASK
13051 ! ITASK = 1. If TOUT has been reached, interpolate. -------------------
13052 ! 310 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
13053 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
13054 ! T = TOUT
13055 ! GO TO 420
13056 ! ITASK = 3. Jump to exit if TOUT was reached. ------------------------
13057 ! 330 IF ((TN - TOUT)*H >= 0.0D0) GO TO 400
13058 ! GO TO 250
13059 ! ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary.
13060 ! 340 IF ((TN - TOUT)*H < 0.0D0) GO TO 345
13061 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
13062 ! T = TOUT
13063 ! GO TO 420
13064 ! 345 HMX = ABS(TN) + ABS(H)
13065 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
13066 ! IF (IHIT) GO TO 400
13067 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
13068 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
13069 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
13070 ! JSTART = -2
13071 ! GO TO 250
13072 ! ITASK = 5. see if TCRIT was reached and jump to exit. ---------------
13073 ! 350 HMX = ABS(TN) + ABS(H)
13074 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
13075 !-----------------------------------------------------------------------
13076 ! Block G.
13077 ! The following block handles all successful returns from DLSOIBT.
13078 ! If ITASK .ne. 1, Y is loaded from YH and T is set accordingly.
13079 ! ISTATE is set to 2, and the optional outputs are loaded into the
13080 ! work arrays before returning.
13081 !-----------------------------------------------------------------------
13082 ! 400 DO 410 I = 1,N
13083 ! Y(I) = RWORK(I+LYH-1)
13084 ! 410 END DO
13085 ! T = TN
13086 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 420
13087 ! IF (IHIT) T = TCRIT
13088 ! 420 ISTATE = 2
13089 ! IF ( KFLAG == -3 ) ISTATE = 3
13090 ! RWORK(11) = HU
13091 ! RWORK(12) = H
13092 ! RWORK(13) = TN
13093 ! IWORK(11) = NST
13094 ! IWORK(12) = NFE
13095 ! IWORK(13) = NJE
13096 ! IWORK(14) = NQU
13097 ! IWORK(15) = NQ
13098 ! RETURN
13099 !-----------------------------------------------------------------------
13100 ! Block H.
13101 ! The following block handles all unsuccessful returns other than
13102 ! those for illegal input. First the error message routine is called.
13103 ! If there was an error test or convergence test failure, IMXER is set.
13104 ! Then Y is loaded from YH and T is set to TN.
13105 ! The optional outputs are loaded into the work arrays before returning.
13106 !-----------------------------------------------------------------------
13107 ! The maximum number of steps was taken before reaching TOUT. ----------
13108 ! 500 MSG = 'DLSOIBT- At current T (=R1), MXSTEP (=I1) steps '
13109 ! CALL XERRWD (MSG, 50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13110 ! MSG = ' taken on this call before reaching TOUT '
13111 ! CALL XERRWD (MSG, 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0)
13112 ! ISTATE = -1
13113 ! GO TO 580
13114 ! EWT(i) .le. 0.0 for some i (not at start of problem). ----------------
13115 ! 510 EWTI = RWORK(LEWT+I-1)
13116 ! MSG = 'DLSOIBT- At T (=R1), EWT(I1) has become R2 <= 0.'
13117 ! CALL XERRWD (MSG, 50, 202, 0, 1, I, 0, 2, TN, EWTI)
13118 ! ISTATE = -6
13119 ! GO TO 590
13120 ! Too much accuracy requested for machine precision. -------------------
13121 ! 520 MSG = 'DLSOIBT- At T (=R1), too much accuracy requested '
13122 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13123 ! MSG = ' for precision of machine.. See TOLSF (=R2) '
13124 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
13125 ! RWORK(14) = TOLSF
13126 ! ISTATE = -2
13127 ! GO TO 590
13128 ! KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
13129 ! 530 MSG = 'DLSOIBT- At T (=R1) and step size H (=R2), the '
13130 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13131 ! MSG = 'error test failed repeatedly or with ABS(H) = HMIN'
13132 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 2, TN, H)
13133 ! ISTATE = -4
13134 ! GO TO 570
13135 ! KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
13136 ! 540 MSG = 'DLSOIBT- At T (=R1) and step size H (=R2), the '
13137 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13138 ! MSG = ' corrector convergence failed repeatedly '
13139 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13140 ! MSG = ' or with ABS(H) = HMIN '
13141 ! CALL XERRWD (MSG, 30, 205, 0, 0, 0, 0, 2, TN, H)
13142 ! ISTATE = -5
13143 ! GO TO 570
13144 ! IRES = 3 returned by RES, despite retries by DSTODI.------------------
13145 ! 550 MSG = 'DLSOIBT- At T (=R1) residual routine returned '
13146 ! CALL XERRWD (MSG, 50, 206, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13147 ! MSG = ' error IRES = 3 repeatedly. '
13148 ! CALL XERRWD (MSG, 40, 206, 0, 0, 0, 0, 1, TN, 0.0D0)
13149 ! ISTATE = -7
13150 ! GO TO 590
13151 ! DAIGBT failed because a diagonal block of A matrix was singular. -----
13152 ! 560 IER = -IER
13153 ! MSG='DLSOIBT- Attempt to initialize dy/dt failed: Matrix A has a'
13154 ! CALL XERRWD (MSG, 60, 207, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13155 ! MSG = ' singular diagonal block, block no. = (I1) '
13156 ! CALL XERRWD (MSG, 50, 207, 0, 1, IER, 0, 0, 0.0D0, 0.0D0)
13157 ! ISTATE = -8
13158 ! RETURN
13159 ! DAIGBT failed because RES set IRES to 2 or 3. ------------------------
13160 ! 565 MSG = 'DLSOIBT- Attempt to initialize dy/dt failed '
13161 ! CALL XERRWD (MSG, 50, 208, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13162 ! MSG = ' because residual routine set its error flag '
13163 ! CALL XERRWD (MSG, 50, 208, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13164 ! MSG = ' to IRES = (I1)'
13165 ! CALL XERRWD (MSG, 20, 208, 0, 1, IER, 0, 0, 0.0D0, 0.0D0)
13166 ! ISTATE = -8
13167 ! RETURN
13168 ! Compute IMXER if relevant. -------------------------------------------
13169 ! 570 BIG = 0.0D0
13170 ! IMXER = 1
13171 ! DO 575 I = 1,N
13172 ! SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
13173 ! IF (BIG >= SIZE) GO TO 575
13174 ! BIG = SIZE
13175 ! IMXER = I
13176 ! 575 END DO
13177 ! IWORK(16) = IMXER
13178 ! Compute residual if relevant. ----------------------------------------
13179 ! 580 LYD0 = LYH + NYH
13180 ! DO 585 I = 1,N
13181 ! RWORK(I+LSAVF-1) = RWORK(I+LYD0-1)/H
13182 ! Y(I) = RWORK(I+LYH-1)
13183 ! 585 END DO
13184 ! IRES = 1
13185 ! CALL RES (NEQ, TN, Y, RWORK(LSAVF), YDOTI, IRES)
13186 ! NFE = NFE + 1
13187 ! IF (IRES <= 1) GO TO 595
13188 ! MSG = 'DLSOIBT- Residual routine set its flag IRES '
13189 ! CALL XERRWD (MSG, 50, 210, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13190 ! MSG = ' to (I1) when called for final output. '
13191 ! CALL XERRWD (MSG, 50, 210, 0, 1, IRES, 0, 0, 0.0D0, 0.0D0)
13192 ! GO TO 595
13193 ! Set Y vector, T, and optional outputs. -------------------------------
13194 ! 590 DO 592 I = 1,N
13195 ! Y(I) = RWORK(I+LYH-1)
13196 ! 592 END DO
13197 ! 595 T = TN
13198 ! RWORK(11) = HU
13199 ! RWORK(12) = H
13200 ! RWORK(13) = TN
13201 ! IWORK(11) = NST
13202 ! IWORK(12) = NFE
13203 ! IWORK(13) = NJE
13204 ! IWORK(14) = NQU
13205 ! IWORK(15) = NQ
13206 ! RETURN
13207 !-----------------------------------------------------------------------
13208 ! Block I.
13209 ! The following block handles all error returns due to illegal input
13210 ! (ISTATE = -3), as detected before calling the core integrator.
13211 ! First the error message routine is called. If the illegal input
13212 ! is a negative ISTATE, the run is aborted (apparent infinite loop).
13213 !-----------------------------------------------------------------------
13214 ! 601 MSG = 'DLSOIBT- ISTATE (=I1) illegal.'
13215 ! CALL XERRWD (MSG, 30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0)
13216 ! IF (ISTATE < 0) GO TO 800
13217 ! GO TO 700
13218 ! 602 MSG = 'DLSOIBT- ITASK (=I1) illegal. '
13219 ! CALL XERRWD (MSG, 30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0)
13220 ! GO TO 700
13221 ! 603 MSG = 'DLSOIBT- ISTATE > 1 but DLSOIBT not initialized. '
13222 ! CALL XERRWD (MSG, 50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13223 ! GO TO 700
13224 ! 604 MSG = 'DLSOIBT- NEQ (=I1) < 1 '
13225 ! CALL XERRWD (MSG, 30, 4, 0, 1, NEQ(1), 0, 0, 0.0D0, 0.0D0)
13226 ! GO TO 700
13227 ! 605 MSG = 'DLSOIBT- ISTATE = 3 and NEQ increased (I1 to I2). '
13228 ! CALL XERRWD (MSG, 50, 5, 0, 2, N, NEQ(1), 0, 0.0D0, 0.0D0)
13229 ! GO TO 700
13230 ! 606 MSG = 'DLSOIBT- ITOL (=I1) illegal. '
13231 ! CALL XERRWD (MSG, 30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0)
13232 ! GO TO 700
13233 ! 607 MSG = 'DLSOIBT- IOPT (=I1) illegal. '
13234 ! CALL XERRWD (MSG, 30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0)
13235 ! GO TO 700
13236 ! 608 MSG = 'DLSOIBT- MF (=I1) illegal. '
13237 ! CALL XERRWD (MSG, 30, 8, 0, 1, MF, 0, 0, 0.0D0, 0.0D0)
13238 ! GO TO 700
13239 ! 609 MSG = 'DLSOIBT- MB (=I1) or NB (=I2) illegal. '
13240 ! CALL XERRWD (MSG, 40, 9, 0, 2, MB, NB, 0, 0.0D0, 0.0D0)
13241 ! GO TO 700
13242 ! 610 MSG = 'DLSOIBT- NB (=I1) < 4 illegal. '
13243 ! CALL XERRWD (MSG, 40, 10, 0, 1, NB, 0, 0, 0.0D0, 0.0D0)
13244 ! GO TO 700
13245 ! 611 MSG = 'DLSOIBT- MAXORD (=I1) < 0 '
13246 ! CALL XERRWD (MSG, 30, 11, 0, 1, MAXORD, 0, 0, 0.0D0, 0.0D0)
13247 ! GO TO 700
13248 ! 612 MSG = 'DLSOIBT- MXSTEP (=I1) < 0 '
13249 ! CALL XERRWD (MSG, 30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0)
13250 ! GO TO 700
13251 ! 613 MSG = 'DLSOIBT- MXHNIL (=I1) < 0 '
13252 ! CALL XERRWD (MSG, 30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
13253 ! GO TO 700
13254 ! 614 MSG = 'DLSOIBT- TOUT (=R1) behind T (=R2) '
13255 ! CALL XERRWD (MSG, 40, 14, 0, 0, 0, 0, 2, TOUT, T)
13256 ! MSG = ' Integration direction is given by H0 (=R1) '
13257 ! CALL XERRWD (MSG, 50, 14, 0, 0, 0, 0, 1, H0, 0.0D0)
13258 ! GO TO 700
13259 ! 615 MSG = 'DLSOIBT- HMAX (=R1) < 0.0 '
13260 ! CALL XERRWD (MSG, 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0)
13261 ! GO TO 700
13262 ! 616 MSG = 'DLSOIBT- HMIN (=R1) < 0.0 '
13263 ! CALL XERRWD (MSG, 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0)
13264 ! GO TO 700
13265 ! 617 MSG='DLSOIBT- RWORK length needed, LENRW (=I1), exceeds LRW (=I2)'
13266 ! CALL XERRWD (MSG, 60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
13267 ! GO TO 700
13268 ! 618 MSG='DLSOIBT- IWORK length needed, LENIW (=I1), exceeds LIW (=I2)'
13269 ! CALL XERRWD (MSG, 60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
13270 ! GO TO 700
13271 ! 619 MSG = 'DLSOIBT- RTOL(=I1) is R1 < 0.0 '
13272 ! CALL XERRWD (MSG, 40, 19, 0, 1, I, 0, 1, RTOLI, 0.0D0)
13273 ! GO TO 700
13274 ! 620 MSG = 'DLSOIBT- ATOL(=I1) is R1 < 0.0 '
13275 ! CALL XERRWD (MSG, 40, 20, 0, 1, I, 0, 1, ATOLI, 0.0D0)
13276 ! GO TO 700
13277 ! 621 EWTI = RWORK(LEWT+I-1)
13278 ! MSG = 'DLSOIBT- EWT(I1) is R1 <= 0.0 '
13279 ! CALL XERRWD (MSG, 40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0)
13280 ! GO TO 700
13281 ! 622 MSG='DLSOIBT- TOUT(=R1) too close to T(=R2) to start integration.'
13282 ! CALL XERRWD (MSG, 60, 22, 0, 0, 0, 0, 2, TOUT, T)
13283 ! GO TO 700
13284 ! 623 MSG='DLSOIBT- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
13285 ! CALL XERRWD (MSG, 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
13286 ! GO TO 700
13287 ! 624 MSG='DLSOIBT- ITASK = 4 or 5 and TCRIT (=R1) behind TCUR (=R2) '
13288 ! CALL XERRWD (MSG, 60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
13289 ! GO TO 700
13290 ! 625 MSG='DLSOIBT- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
13291 ! CALL XERRWD (MSG, 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
13292 ! GO TO 700
13293 ! 626 MSG = 'DLSOIBT- At start of problem, too much accuracy '
13294 ! CALL XERRWD (MSG, 50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
13295 ! MSG=' requested for precision of machine.. See TOLSF (=R1) '
13296 ! CALL XERRWD (MSG, 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0)
13297 ! RWORK(14) = TOLSF
13298 ! GO TO 700
13299 ! 627 MSG = 'DLSOIBT- Trouble in DINTDY. ITASK = I1, TOUT = R1'
13300 ! CALL XERRWD (MSG, 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0)
13301 ! 700 ISTATE = -3
13302 ! RETURN
13303 ! 800 MSG = 'DLSOIBT- Run aborted.. apparent infinite loop. '
13304 ! CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0)
13305 ! RETURN
13306 !----------------------- End of Subroutine DLSOIBT ---------------------
13307 ! END SUBROUTINE DLSOIBT
13308 ! ECK DLSODIS
13309 ! SUBROUTINE DLSODIS (RES, ADDA, JAC, NEQ, Y, YDOTI, T, TOUT, ITOL, &
13310 ! RTOL, ATOL, ITASK, ISTATE, IOPT, RWORK, LRW, IWORK, LIW, MF )
13311 ! EXTERNAL RES, ADDA, JAC
13312 ! INTEGER :: NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW, MF
13313 ! DOUBLE PRECISION :: Y, YDOTI, T, TOUT, RTOL, ATOL, RWORK
13314 ! DIMENSION NEQ(*), Y(*), YDOTI(*), RTOL(*), ATOL(*), RWORK(LRW), &
13315 ! IWORK(LIW)
13316 !-----------------------------------------------------------------------
13317 ! This is the 18 November 2003 version of
13318 ! DLSODIS: Livermore Solver for Ordinary Differential equations
13319 ! (Implicit form) with general Sparse Jacobian matrices.
13320 ! This version is in double precision.
13321 ! DLSODIS solves the initial value problem for linearly implicit
13322 ! systems of first order ODEs,
13323 ! A(t,y) * dy/dt = g(t,y) , where A(t,y) is a square matrix,
13324 ! or, in component form,
13325 ! ( a * ( dy / dt )) + ... + ( a * ( dy / dt )) =
13326 ! i,1 1 i,NEQ NEQ
13327 ! = g ( t, y , y ,..., y ) ( i = 1,...,NEQ )
13328 ! i 1 2 NEQ
13329 ! If A is singular, this is a differential-algebraic system.
13330 ! DLSODIS is a variant version of the DLSODI package, and is intended
13331 ! for stiff problems in which the matrix A and the Jacobian matrix
13332 ! d(g - A*s)/dy have arbitrary sparse structures.
13333 ! Authors: Alan C. Hindmarsh
13334 ! Center for Applied Scientific Computing, L-561
13335 ! Lawrence Livermore National Laboratory
13336 ! Livermore, CA 94551
13337 ! and
13338 ! Sheila Balsdon
13339 ! Zycor, Inc.
13340 ! Austin, TX 78741
13341 !-----------------------------------------------------------------------
13342 ! References:
13343 ! 1. M. K. Seager and S. Balsdon, LSODIS, A Sparse Implicit
13344 ! ODE Solver, in Proceedings of the IMACS 10th World Congress,
13345 ! Montreal, August 8-13, 1982.
13346 ! 2. Alan C. Hindmarsh, LSODE and LSODI, Two New Initial Value
13347 ! Ordinary Differential Equation Solvers,
13348 ! ACM-SIGNUM Newsletter, vol. 15, no. 4 (1980), pp. 10-11.
13349 ! 3. S. C. Eisenstat, M. C. Gursky, M. H. Schultz, and A. H. Sherman,
13350 ! Yale Sparse Matrix Package: I. The Symmetric Codes,
13351 ! Int. J. Num. Meth. Eng., vol. 18 (1982), pp. 1145-1151.
13352 ! 4. S. C. Eisenstat, M. C. Gursky, M. H. Schultz, and A. H. Sherman,
13353 ! Yale Sparse Matrix Package: II. The Nonsymmetric Codes,
13354 ! Research Report No. 114, Dept. of Computer Sciences, Yale
13355 ! University, 1977.
13356 !-----------------------------------------------------------------------
13357 ! Summary of Usage.
13358 ! Communication between the user and the DLSODIS package, for normal
13359 ! situations, is summarized here. This summary describes only a subset
13360 ! of the full set of options available. See the full description for
13361 ! details, including optional communication, nonstandard options,
13362 ! and instructions for special situations. See also the example
13363 ! problem (with program and output) following this summary.
13364 ! A. First, provide a subroutine of the form:
13365 ! SUBROUTINE RES (NEQ, T, Y, S, R, IRES)
13366 ! DOUBLE PRECISION T, Y(*), S(*), R(*)
13367 ! which computes the residual function
13368 ! r = g(t,y) - A(t,y) * s ,
13369 ! as a function of t and the vectors y and s. (s is an internally
13370 ! generated approximation to dy/dt.) The arrays Y and S are inputs
13371 ! to the RES routine and should not be altered. The residual
13372 ! vector is to be stored in the array R. The argument IRES should be
13373 ! ignored for casual use of DLSODIS. (For uses of IRES, see the
13374 ! paragraph on RES in the full description below.)
13375 ! B. DLSODIS must deal internally with the matrices A and dr/dy, where
13376 ! r is the residual function defined above. DLSODIS generates a linear
13377 ! combination of these two matrices in sparse form.
13378 ! The matrix structure is communicated by a method flag, MF:
13379 ! MF = 21 or 22 when the user provides the structures of
13380 ! matrix A and dr/dy,
13381 ! MF = 121 or 222 when the user does not provide structure
13382 ! information, and
13383 ! MF = 321 or 422 when the user provides the structure
13384 ! of matrix A.
13385 ! C. You must also provide a subroutine of the form:
13386 ! SUBROUTINE ADDA (NEQ, T, Y, J, IAN, JAN, P)
13387 ! DOUBLE PRECISION T, Y(*), P(*)
13388 ! INTEGER IAN(*), JAN(*)
13389 ! which adds the matrix A = A(t,y) to the contents of the array P.
13390 ! NEQ, T, Y, and J are input arguments and should not be altered.
13391 ! This routine should add the J-th column of matrix A to the array
13392 ! P (of length NEQ). I.e. add A(i,J) to P(i) for all relevant
13393 ! values of i. The arguments IAN and JAN should be ignored for normal
13394 ! situations. DLSODIS will call the ADDA routine with J = 1,2,...,NEQ.
13395 ! D. For the sake of efficiency, you are encouraged to supply the
13396 ! Jacobian matrix dr/dy in closed form, where r = g(t,y) - A(t,y)*s
13397 ! (s = a fixed vector) as above. If dr/dy is being supplied,
13398 ! use MF = 21, 121, or 321, and provide a subroutine of the form:
13399 ! SUBROUTINE JAC (NEQ, T, Y, S, J, IAN, JAN, PDJ)
13400 ! DOUBLE PRECISION T, Y(*), S(*), PDJ(*)
13401 ! INTEGER IAN(*), JAN(*)
13402 ! which computes dr/dy as a function of t, y, and s. Here NEQ, T, Y, S,
13403 ! and J are input arguments, and the JAC routine is to load the array
13404 ! PDJ (of length NEQ) with the J-th column of dr/dy. I.e. load PDJ(i)
13405 ! with dr(i)/dy(J) for all relevant values of i. The arguments IAN and
13406 ! JAN should be ignored for normal situations. DLSODIS will call the
13407 ! JAC routine with J = 1,2,...,NEQ.
13408 ! Only nonzero elements need be loaded. A crude approximation
13409 ! to dr/dy, possibly with fewer nonzero elememts, will suffice.
13410 ! Note that if A is independent of y (or this dependence
13411 ! is weak enough to be ignored) then JAC is to compute dg/dy.
13412 ! If it is not feasible to provide a JAC routine, use
13413 ! MF = 22, 222, or 422 and DLSODIS will compute an approximate
13414 ! Jacobian internally by difference quotients.
13415 ! E. Next decide whether or not to provide the initial value of the
13416 ! derivative vector dy/dt. If the initial value of A(t,y) is
13417 ! nonsingular (and not too ill-conditioned), you may let DLSODIS compute
13418 ! this vector (ISTATE = 0). (DLSODIS will solve the system A*s = g for
13419 ! s, with initial values of A and g.) If A(t,y) is initially
13420 ! singular, then the system is a differential-algebraic system, and
13421 ! you must make use of the particular form of the system to compute the
13422 ! initial values of y and dy/dt. In that case, use ISTATE = 1 and
13423 ! load the initial value of dy/dt into the array YDOTI.
13424 ! The input array YDOTI and the initial Y array must be consistent with
13425 ! the equations A*dy/dt = g. This implies that the initial residual
13426 ! r = g(t,y) - A(t,y)*YDOTI must be approximately zero.
13427 ! F. Write a main program which calls Subroutine DLSODIS once for
13428 ! each point at which answers are desired. This should also provide
13429 ! for possible use of logical unit 6 for output of error messages by
13430 ! DLSODIS. On the first call to DLSODIS, supply arguments as follows:
13431 ! RES = name of user subroutine for residual function r.
13432 ! ADDA = name of user subroutine for computing and adding A(t,y).
13433 ! JAC = name of user subroutine for Jacobian matrix dr/dy
13434 ! (MF = 121). If not used, pass a dummy name.
13435 ! Note: The names for the RES and ADDA routines and (if used) the
13436 ! JAC routine must be declared External in the calling program.
13437 ! NEQ = number of scalar equations in the system.
13438 ! Y = array of initial values, of length NEQ.
13439 ! YDOTI = array of length NEQ (containing initial dy/dt if ISTATE = 1).
13440 ! T = the initial value of the independent variable.
13441 ! TOUT = first point where output is desired (.ne. T).
13442 ! ITOL = 1 or 2 according as ATOL (below) is a scalar or array.
13443 ! RTOL = relative tolerance parameter (scalar).
13444 ! ATOL = absolute tolerance parameter (scalar or array).
13445 ! The estimated local error in y(i) will be controlled so as
13446 ! to be roughly less (in magnitude) than
13447 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or
13448 ! EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2.
13449 ! Thus the local error test passes if, in each component,
13450 ! either the absolute error is less than ATOL (or ATOL(i)),
13451 ! or the relative error is less than RTOL.
13452 ! Use RTOL = 0.0 for pure absolute error control, and
13453 ! use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative error
13454 ! control. Caution: Actual (global) errors may exceed these
13455 ! local tolerances, so choose them conservatively.
13456 ! ITASK = 1 for normal computation of output values of y at t = TOUT.
13457 ! ISTATE = integer flag (input and output). Set ISTATE = 1 if the
13458 ! initial dy/dt is supplied, and 0 otherwise.
13459 ! IOPT = 0 to indicate no optional inputs used.
13460 ! RWORK = real work array of length at least:
13461 ! 20 + (2 + 1./LENRAT)*NNZ + (11 + 9./LENRAT)*NEQ
13462 ! where:
13463 ! NNZ = the number of nonzero elements in the sparse
13464 ! iteration matrix P = A - con*dr/dy (con = scalar)
13465 ! (If NNZ is unknown, use an estimate of it.)
13466 ! LENRAT = the real to integer wordlength ratio (usually 1 in
13467 ! single precision and 2 in double precision).
13468 ! In any case, the required size of RWORK cannot generally
13469 ! be predicted in advance for any value of MF, and the
13470 ! value above is a rough estimate of a crude lower bound.
13471 ! Some experimentation with this size may be necessary.
13472 ! (When known, the correct required length is an optional
13473 ! output, available in IWORK(17).)
13474 ! LRW = declared length of RWORK (in user's dimension).
13475 ! IWORK = integer work array of length at least 30.
13476 ! LIW = declared length of IWORK (in user's dimension).
13477 ! MF = method flag. Standard values are:
13478 ! 121 for a user-supplied sparse Jacobian.
13479 ! 222 for an internally generated sparse Jacobian.
13480 ! For other choices of MF, see the paragraph on MF in
13481 ! the full description below.
13482 ! Note that the main program must declare arrays Y, YDOTI, RWORK, IWORK,
13483 ! and possibly ATOL.
13484 ! G. The output from the first call, or any call, is:
13485 ! Y = array of computed values of y(t) vector.
13486 ! T = corresponding value of independent variable (normally TOUT).
13487 ! ISTATE = 2 if DLSODIS was successful, negative otherwise.
13488 ! -1 means excess work done on this call (check all inputs).
13489 ! -2 means excess accuracy requested (tolerances too small).
13490 ! -3 means illegal input detected (see printed message).
13491 ! -4 means repeated error test failures (check all inputs).
13492 ! -5 means repeated convergence failures (perhaps bad Jacobian
13493 ! supplied or wrong choice of tolerances).
13494 ! -6 means error weight became zero during problem. (Solution
13495 ! component i vanished, and ATOL or ATOL(i) = 0.)
13496 ! -7 cannot occur in casual use.
13497 ! -8 means DLSODIS was unable to compute the initial dy/dt.
13498 ! in casual use, this means A(t,y) is initially singular.
13499 ! Supply YDOTI and use ISTATE = 1 on the first call.
13500 ! -9 means a fatal error return flag came from sparse solver
13501 ! CDRV by way of DPRJIS or DSOLSS. Should never happen.
13502 ! A return with ISTATE = -1, -4, or -5, may result from using
13503 ! an inappropriate sparsity structure, one that is quite
13504 ! different from the initial structure. Consider calling
13505 ! DLSODIS again with ISTATE = 3 to force the structure to be
13506 ! reevaluated. See the full description of ISTATE below.
13507 ! If DLSODIS returns ISTATE = -1, -4 or -5, then the output of
13508 ! DLSODIS also includes YDOTI = array containing residual vector
13509 ! r = g - A * dy/dt evaluated at the current t, y, and dy/dt.
13510 ! H. To continue the integration after a successful return, simply
13511 ! reset TOUT and call DLSODIS again. No other parameters need be reset.
13512 !-----------------------------------------------------------------------
13513 ! Example Problem.
13514 ! The following is an example problem, with the coding needed
13515 ! for its solution by DLSODIS. The problem comes from the partial
13516 ! differential equation (the Burgers equation)
13517 ! du/dt = - u * du/dx + eta * d**2 u/dx**2, eta = .05,
13518 ! on -1 .le. x .le. 1. The boundary conditions are periodic:
13519 ! u(-1,t) = u(1,t) and du/dx(-1,t) = du/dx(1,t)
13520 ! The initial profile is a square wave,
13521 ! u = 1 in ABS(x) .lt. .5, u = .5 at ABS(x) = .5, u = 0 elsewhere.
13522 ! The PDE is discretized in x by a simplified Galerkin method,
13523 ! using piecewise linear basis functions, on a grid of 40 intervals.
13524 ! The result is a system A * dy/dt = g(y), of size NEQ = 40,
13525 ! where y(i) is the approximation to u at x = x(i), with
13526 ! x(i) = -1 + (i-1)*delx, delx = 2/NEQ = .05.
13527 ! The individual equations in the system are (in order):
13528 ! (1/6)dy(NEQ)/dt+(4/6)dy(1)/dt+(1/6)dy(2)/dt
13529 ! = r4d*(y(NEQ)**2-y(2)**2)+eodsq*(y(2)-2*y(1)+y(NEQ))
13530 ! for i = 2,3,...,nm1,
13531 ! (1/6)dy(i-1)/dt+(4/6)dy(i)/dt+(1/6)dy(i+1)/dt
13532 ! = r4d*(y(i-1)**2-y(i+1)**2)+eodsq*(y(i+1)-2*y(i)+y(i-1))
13533 ! and finally
13534 ! (1/6)dy(nm1)/dt+(4/6)dy(NEQ)/dt+(1/6)dy(1)/dt
13535 ! = r4d*(y(nm1)**2-y(1)**2)+eodsq*(y(1)-2*y(NEQ)+y(nm1))
13536 ! where r4d = 1/(4*delx), eodsq = eta/delx**2 and nm1 = NEQ-1.
13537 ! The following coding solves the problem with MF = 121, with output
13538 ! of solution statistics at t = .1, .2, .3, and .4, and of the
13539 ! solution vector at t = .4. Optional outputs (run statistics) are
13540 ! also printed.
13541 ! EXTERNAL RESID, ADDASP, JACSP
13542 ! DOUBLE PRECISION ATOL, RTOL, RW, T, TOUT, Y, YDOTI, R4D, EODSQ, DELX
13543 ! DIMENSION Y(40), YDOTI(40), RW(1409), IW(30)
13544 ! COMMON /TEST1/ R4D, EODSQ, NM1
13545 ! DATA ITOL/1/, RTOL/1.0D-3/, ATOL/1.0D-3/, ITASK/1/, IOPT/0/
13546 ! DATA NEQ/40/, LRW/1409/, LIW/30/, MF/121/
13547 ! DELX = 2.0/NEQ
13548 ! R4D = 0.25/DELX
13549 ! EODSQ = 0.05/DELX**2
13550 ! NM1 = NEQ - 1
13551 ! DO 10 I = 1,NEQ
13552 ! 10 Y(I) = 0.0
13553 ! Y(11) = 0.5
13554 ! DO 15 I = 12,30
13555 ! 15 Y(I) = 1.0
13556 ! Y(31) = 0.5
13557 ! T = 0.0
13558 ! TOUT = 0.1
13559 ! ISTATE = 0
13560 ! DO 30 IO = 1,4
13561 ! CALL DLSODIS (RESID, ADDASP, JACSP, NEQ, Y, YDOTI, T, TOUT,
13562 ! 1 ITOL, RTOL, ATOL, ITASK, ISTATE, IOPT, RW, LRW, IW, LIW, MF)
13563 ! WRITE(6,20) T,IW(11),RW(11)
13564 ! 20 FORMAT(' At t =',F5.2,' No. steps =',I4,
13565 ! 1 ' Last step =',D12.4)
13566 ! IF (ISTATE .NE. 2) GO TO 90
13567 ! TOUT = TOUT + 0.1
13568 ! 30 CONTINUE
13569 ! WRITE (6,40) (Y(I),I=1,NEQ)
13570 ! 40 FORMAT(/' Final solution values..'/8(5D12.4/))
13571 ! WRITE(6,50) IW(17),IW(18),IW(11),IW(12),IW(13)
13572 ! NNZLU = IW(25) + IW(26) + NEQ
13573 ! WRITE(6,60) IW(19),NNZLU
13574 ! 50 FORMAT(/' Required RW size =',I5,' IW size =',I4/
13575 ! 1 ' No. steps =',I4,' No. r-s =',I4,' No. J-s =',i4)
13576 ! 60 FORMAT(' No. of nonzeros in P matrix =',I4,
13577 ! 1 ' No. of nonzeros in LU =',I4)
13578 ! STOP
13579 ! 90 WRITE (6,95) ISTATE
13580 ! 95 FORMAT(///' Error halt.. ISTATE =',I3)
13581 ! STOP
13582 ! END
13583 ! SUBROUTINE GFUN (N, T, Y, G)
13584 ! DOUBLE PRECISION T, Y, G, R4D, EODSQ
13585 ! DIMENSION G(N), Y(N)
13586 ! COMMON /TEST1/ R4D, EODSQ, NM1
13587 ! G(1) = R4D*(Y(N)**2-Y(2)**2) + EODSQ*(Y(2)-2.0*Y(1)+Y(N))
13588 ! DO 10 I = 2,NM1
13589 ! G(I) = R4D*(Y(I-1)**2 - Y(I+1)**2)
13590 ! 1 + EODSQ*(Y(I+1) - 2.0*Y(I) + Y(I-1))
13591 ! 10 CONTINUE
13592 ! G(N) = R4D*(Y(NM1)**2-Y(1)**2) + EODSQ*(Y(1)-2.0*Y(N)+Y(NM1))
13593 ! RETURN
13594 ! END
13595 ! SUBROUTINE RESID (N, T, Y, S, R, IRES)
13596 ! DOUBLE PRECISION T, Y, S, R, R4D, EODSQ
13597 ! DIMENSION Y(N), S(N), R(N)
13598 ! COMMON /TEST1/ R4D, EODSQ, NM1
13599 ! CALL GFUN (N, T, Y, R)
13600 ! R(1) = R(1) - (S(N) + 4.0*S(1) + S(2))/6.0
13601 ! DO 10 I = 2,NM1
13602 ! 10 R(I) = R(I) - (S(I-1) + 4.0*S(I) + S(I+1))/6.0
13603 ! R(N) = R(N) - (S(NM1) + 4.0*S(N) + S(1))/6.0
13604 ! RETURN
13605 ! END
13606 ! SUBROUTINE ADDASP (N, T, Y, J, IP, JP, P)
13607 ! DOUBLE PRECISION T, Y, P
13608 ! DIMENSION Y(N), IP(*), JP(*), P(N)
13609 ! JM1 = J - 1
13610 ! JP1 = J + 1
13611 ! IF (J .EQ. N) JP1 = 1
13612 ! IF (J .EQ. 1) JM1 = N
13613 ! P(J) = P(J) + (2.0/3.0)
13614 ! P(JP1) = P(JP1) + (1.0/6.0)
13615 ! P(JM1) = P(JM1) + (1.0/6.0)
13616 ! RETURN
13617 ! END
13618 ! SUBROUTINE JACSP (N, T, Y, S, J, IP, JP, PDJ)
13619 ! DOUBLE PRECISION T, Y, S, PDJ, R4D, EODSQ
13620 ! DIMENSION Y(N), S(N), IP(*), JP(*), PDJ(N)
13621 ! COMMON /TEST1/ R4D, EODSQ, NM1
13622 ! JM1 = J - 1
13623 ! JP1 = J + 1
13624 ! IF (J .EQ. 1) JM1 = N
13625 ! IF (J .EQ. N) JP1 = 1
13626 ! PDJ(JM1) = -2.0*R4D*Y(J) + EODSQ
13627 ! PDJ(J) = -2.0*EODSQ
13628 ! PDJ(JP1) = 2.0*R4D*Y(J) + EODSQ
13629 ! RETURN
13630 ! END
13631 ! The output of this program (on a CDC-7600 in single precision)
13632 ! is as follows:
13633 ! At t = 0.10 No. steps = 15 Last step = 1.6863e-02
13634 ! At t = 0.20 No. steps = 19 Last step = 2.4101e-02
13635 ! At t = 0.30 No. steps = 22 Last step = 4.3143e-02
13636 ! At t = 0.40 No. steps = 24 Last step = 5.7819e-02
13637 ! Final solution values..
13638 ! 1.8371e-02 1.3578e-02 1.5864e-02 2.3805e-02 3.7245e-02
13639 ! 5.6630e-02 8.2538e-02 1.1538e-01 1.5522e-01 2.0172e-01
13640 ! 2.5414e-01 3.1150e-01 3.7259e-01 4.3608e-01 5.0060e-01
13641 ! 5.6482e-01 6.2751e-01 6.8758e-01 7.4415e-01 7.9646e-01
13642 ! 8.4363e-01 8.8462e-01 9.1853e-01 9.4500e-01 9.6433e-01
13643 ! 9.7730e-01 9.8464e-01 9.8645e-01 9.8138e-01 9.6584e-01
13644 ! 9.3336e-01 8.7497e-01 7.8213e-01 6.5315e-01 4.9997e-01
13645 ! 3.4672e-01 2.1758e-01 1.2461e-01 6.6208e-02 3.3784e-02
13646 ! Required RW size = 1409 IW size = 30
13647 ! No. steps = 24 No. r-s = 33 No. J-s = 8
13648 ! No. of nonzeros in P matrix = 120 No. of nonzeros in LU = 194
13649 !-----------------------------------------------------------------------
13650 ! Full Description of User Interface to DLSODIS.
13651 ! The user interface to DLSODIS consists of the following parts.
13652 ! 1. The call sequence to Subroutine DLSODIS, which is a driver
13653 ! routine for the solver. This includes descriptions of both
13654 ! the call sequence arguments and of user-supplied routines.
13655 ! Following these descriptions is a description of
13656 ! optional inputs available through the call sequence, and then
13657 ! a description of optional outputs (in the work arrays).
13658 ! 2. Descriptions of other routines in the DLSODIS package that may be
13659 ! (optionally) called by the user. These provide the ability to
13660 ! alter error message handling, save and restore the internal
13661 ! Common, and obtain specified derivatives of the solution y(t).
13662 ! 3. Descriptions of Common blocks to be declared in overlay
13663 ! or similar environments, or to be saved when doing an interrupt
13664 ! of the problem and continued solution later.
13665 ! 4. Description of two routines in the DLSODIS package, either of
13666 ! which the user may replace with his/her own version, if desired.
13667 ! These relate to the measurement of errors.
13668 !-----------------------------------------------------------------------
13669 ! Part 1. Call Sequence.
13670 ! The call sequence parameters used for input only are
13671 ! RES, ADDA, JAC, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK,
13672 ! IOPT, LRW, LIW, MF,
13673 ! and those used for both input and output are
13674 ! Y, T, ISTATE, YDOTI.
13675 ! The work arrays RWORK and IWORK are also used for conditional and
13676 ! optional inputs and optional outputs. (The term output here refers
13677 ! to the return from Subroutine DLSODIS to the user's calling program.)
13678 ! The legality of input parameters will be thoroughly checked on the
13679 ! initial call for the problem, but not checked thereafter unless a
13680 ! change in input parameters is flagged by ISTATE = 3 on input.
13681 ! The descriptions of the call arguments are as follows.
13682 ! RES = the name of the user-supplied subroutine which supplies
13683 ! the residual vector for the ODE system, defined by
13684 ! r = g(t,y) - A(t,y) * s
13685 ! as a function of the scalar t and the vectors
13686 ! s and y (s approximates dy/dt). This subroutine
13687 ! is to have the form
13688 ! SUBROUTINE RES (NEQ, T, Y, S, R, IRES)
13689 ! DOUBLE PRECISION T, Y(*), S(*), R(*)
13690 ! where NEQ, T, Y, S, and IRES are input, and R and
13691 ! IRES are output. Y, S, and R are arrays of length NEQ.
13692 ! On input, IRES indicates how DLSODIS will use the
13693 ! returned array R, as follows:
13694 ! IRES = 1 means that DLSODIS needs the full residual,
13695 ! r = g - A*s, exactly.
13696 ! IRES = -1 means that DLSODIS is using R only to compute
13697 ! the Jacobian dr/dy by difference quotients.
13698 ! The RES routine can ignore IRES, or it can omit some terms
13699 ! if IRES = -1. If A does not depend on y, then RES can
13700 ! just return R = g when IRES = -1. If g - A*s contains other
13701 ! additive terms that are independent of y, these can also be
13702 ! dropped, if done consistently, when IRES = -1.
13703 ! The subroutine should set the flag IRES if it
13704 ! encounters a halt condition or illegal input.
13705 ! Otherwise, it should not reset IRES. On output,
13706 ! IRES = 1 or -1 represents a normal return, and
13707 ! DLSODIS continues integrating the ODE. Leave IRES
13708 ! unchanged from its input value.
13709 ! IRES = 2 tells DLSODIS to immediately return control
13710 ! to the calling program, with ISTATE = 3. This lets
13711 ! the calling program change parameters of the problem
13712 ! if necessary.
13713 ! IRES = 3 represents an error condition (for example, an
13714 ! illegal value of y). DLSODIS tries to integrate the system
13715 ! without getting IRES = 3 from RES. If it cannot, DLSODIS
13716 ! returns with ISTATE = -7 or -1.
13717 ! On a return with ISTATE = 3, -1, or -7, the values
13718 ! of T and Y returned correspond to the last point reached
13719 ! successfully without getting the flag IRES = 2 or 3.
13720 ! The flag values IRES = 2 and 3 should not be used to
13721 ! handle switches or root-stop conditions. This is better
13722 ! done by calling DLSODIS in a one-step mode and checking the
13723 ! stopping function for a sign change at each step.
13724 ! If quantities computed in the RES routine are needed
13725 ! externally to DLSODIS, an extra call to RES should be made
13726 ! for this purpose, for consistent and accurate results.
13727 ! To get the current dy/dt for the S argument, use DINTDY.
13728 ! RES must be declared External in the calling
13729 ! program. See note below for more about RES.
13730 ! ADDA = the name of the user-supplied subroutine which adds the
13731 ! matrix A = A(t,y) to another matrix stored in sparse form.
13732 ! This subroutine is to have the form
13733 ! SUBROUTINE ADDA (NEQ, T, Y, J, IAN, JAN, P)
13734 ! DOUBLE PRECISION T, Y(*), P(*)
13735 ! INTEGER IAN(*), JAN(*)
13736 ! where NEQ, T, Y, J, IAN, JAN, and P are input. This routine
13737 ! should add the J-th column of matrix A to the array P, of
13738 ! length NEQ. Thus a(i,J) is to be added to P(i) for all
13739 ! relevant values of i. Here T and Y have the same meaning as
13740 ! in Subroutine RES, and J is a column index (1 to NEQ).
13741 ! IAN and JAN are undefined in calls to ADDA for structure
13742 ! determination (MOSS .ne. 0). Otherwise, IAN and JAN are
13743 ! structure descriptors, as defined under optional outputs
13744 ! below, and so can be used to determine the relevant row
13745 ! indices i, if desired.
13746 ! Calls to ADDA are made with J = 1,...,NEQ, in that
13747 ! order. ADDA must not alter its input arguments.
13748 ! ADDA must be declared External in the calling program.
13749 ! See note below for more information about ADDA.
13750 ! JAC = the name of the user-supplied subroutine which supplies
13751 ! the Jacobian matrix, dr/dy, where r = g - A*s. JAC is
13752 ! required if MITER = 1, or MOSS = 1 or 3. Otherwise a dummy
13753 ! name can be passed. This subroutine is to have the form
13754 ! SUBROUTINE JAC (NEQ, T, Y, S, J, IAN, JAN, PDJ)
13755 ! DOUBLE PRECISION T, Y(*), S(*), PDJ(*)
13756 ! INTEGER IAN(*), JAN(*)
13757 ! where NEQ, T, Y, S, J, IAN, and JAN are input. The
13758 ! array PDJ, of length NEQ, is to be loaded with column J
13759 ! of the Jacobian on output. Thus dr(i)/dy(J) is to be
13760 ! loaded into PDJ(i) for all relevant values of i.
13761 ! Here T, Y, and S have the same meaning as in Subroutine RES,
13762 ! and J is a column index (1 to NEQ). IAN and JAN
13763 ! are undefined in calls to JAC for structure determination
13764 ! (MOSS .ne. 0). Otherwise, IAN and JAN are structure
13765 ! descriptors, as defined under optional outputs below, and
13766 ! so can be used to determine the relevant row indices i, if
13767 ! desired.
13768 ! JAC need not provide dr/dy exactly. A crude
13769 ! approximation (possibly with greater sparsity) will do.
13770 ! In any case, PDJ is preset to zero by the solver,
13771 ! so that only the nonzero elements need be loaded by JAC.
13772 ! Calls to JAC are made with J = 1,...,NEQ, in that order, and
13773 ! each such set of calls is preceded by a call to RES with the
13774 ! same arguments NEQ, T, Y, S, and IRES. Thus to gain some
13775 ! efficiency intermediate quantities shared by both calculations
13776 ! may be saved in a user Common block by RES and not recomputed
13777 ! by JAC, if desired. JAC must not alter its input arguments.
13778 ! JAC must be declared External in the calling program.
13779 ! See note below for more about JAC.
13780 ! Note on RES, ADDA, and JAC:
13781 ! These subroutines may access user-defined quantities in
13782 ! NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
13783 ! (dimensioned in the subroutines) and/or Y has length
13784 ! exceeding NEQ(1). However, these subroutines should not
13785 ! alter NEQ(1), Y(1),...,Y(NEQ) or any other input variables.
13786 ! See the descriptions of NEQ and Y below.
13787 ! NEQ = the size of the system (number of first order ordinary
13788 ! differential equations or scalar algebraic equations).
13789 ! Used only for input.
13790 ! NEQ may be decreased, but not increased, during the problem.
13791 ! If NEQ is decreased (with ISTATE = 3 on input), the
13792 ! remaining components of Y should be left undisturbed, if
13793 ! these are to be accessed in RES, ADDA, or JAC.
13794 ! Normally, NEQ is a scalar, and it is generally referred to
13795 ! as a scalar in this user interface description. However,
13796 ! NEQ may be an array, with NEQ(1) set to the system size.
13797 ! (The DLSODIS package accesses only NEQ(1).) In either case,
13798 ! this parameter is passed as the NEQ argument in all calls
13799 ! to RES, ADDA, and JAC. Hence, if it is an array,
13800 ! locations NEQ(2),... may be used to store other integer data
13801 ! and pass it to RES, ADDA, or JAC. Each such subroutine
13802 ! must include NEQ in a Dimension statement in that case.
13803 ! Y = a real array for the vector of dependent variables, of
13804 ! length NEQ or more. Used for both input and output on the
13805 ! first call (ISTATE = 0 or 1), and only for output on other
13806 ! calls. On the first call, Y must contain the vector of
13807 ! initial values. On output, Y contains the computed solution
13808 ! vector, evaluated at T. If desired, the Y array may be used
13809 ! for other purposes between calls to the solver.
13810 ! This array is passed as the Y argument in all calls to RES,
13811 ! ADDA, and JAC. Hence its length may exceed NEQ,
13812 ! and locations Y(NEQ+1),... may be used to store other real
13813 ! data and pass it to RES, ADDA, or JAC. (The DLSODIS
13814 ! package accesses only Y(1),...,Y(NEQ). )
13815 ! YDOTI = a real array for the initial value of the vector
13816 ! dy/dt and for work space, of dimension at least NEQ.
13817 ! On input:
13818 ! If ISTATE = 0 then DLSODIS will compute the initial value
13819 ! of dy/dt, if A is nonsingular. Thus YDOTI will
13820 ! serve only as work space and may have any value.
13821 ! If ISTATE = 1 then YDOTI must contain the initial value
13822 ! of dy/dt.
13823 ! If ISTATE = 2 or 3 (continuation calls) then YDOTI
13824 ! may have any value.
13825 ! Note: If the initial value of A is singular, then
13826 ! DLSODIS cannot compute the initial value of dy/dt, so
13827 ! it must be provided in YDOTI, with ISTATE = 1.
13828 ! On output, when DLSODIS terminates abnormally with ISTATE =
13829 ! -1, -4, or -5, YDOTI will contain the residual
13830 ! r = g(t,y) - A(t,y)*(dy/dt). If r is large, t is near
13831 ! its initial value, and YDOTI is supplied with ISTATE = 1,
13832 ! there may have been an incorrect input value of
13833 ! YDOTI = dy/dt, or the problem (as given to DLSODIS)
13834 ! may not have a solution.
13835 ! If desired, the YDOTI array may be used for other
13836 ! purposes between calls to the solver.
13837 ! T = the independent variable. On input, T is used only on the
13838 ! first call, as the initial point of the integration.
13839 ! On output, after each call, T is the value at which a
13840 ! computed solution y is evaluated (usually the same as TOUT).
13841 ! On an error return, T is the farthest point reached.
13842 ! TOUT = the next value of t at which a computed solution is desired.
13843 ! Used only for input.
13844 ! When starting the problem (ISTATE = 0 or 1), TOUT may be
13845 ! equal to T for one call, then should .ne. T for the next
13846 ! call. For the initial T, an input value of TOUT .ne. T is
13847 ! used in order to determine the direction of the integration
13848 ! (i.e. the algebraic sign of the step sizes) and the rough
13849 ! scale of the problem. Integration in either direction
13850 ! (forward or backward in t) is permitted.
13851 ! If ITASK = 2 or 5 (one-step modes), TOUT is ignored after
13852 ! the first call (i.e. the first call with TOUT .ne. T).
13853 ! Otherwise, TOUT is required on every call.
13854 ! If ITASK = 1, 3, or 4, the values of TOUT need not be
13855 ! monotone, but a value of TOUT which backs up is limited
13856 ! to the current internal T interval, whose endpoints are
13857 ! TCUR - HU and TCUR (see optional outputs, below, for
13858 ! TCUR and HU).
13859 ! ITOL = an indicator for the type of error control. See
13860 ! description below under ATOL. Used only for input.
13861 ! RTOL = a relative error tolerance parameter, either a scalar or
13862 ! an array of length NEQ. See description below under ATOL.
13863 ! Input only.
13864 ! ATOL = an absolute error tolerance parameter, either a scalar or
13865 ! an array of length NEQ. Input only.
13866 ! The input parameters ITOL, RTOL, and ATOL determine
13867 ! the error control performed by the solver. The solver will
13868 ! control the vector E = (E(i)) of estimated local errors
13869 ! in y, according to an inequality of the form
13870 ! RMS-norm of ( E(i)/EWT(i) ) .le. 1,
13871 ! where EWT(i) = RTOL(i)*ABS(Y(i)) + ATOL(i),
13872 ! and the RMS-norm (root-mean-square norm) here is
13873 ! RMS-norm(v) = SQRT(sum v(i)**2 / NEQ). Here EWT = (EWT(i))
13874 ! is a vector of weights which must always be positive, and
13875 ! the values of RTOL and ATOL should all be non-negative.
13876 ! The following table gives the types (scalar/array) of
13877 ! RTOL and ATOL, and the corresponding form of EWT(i).
13878 ! ITOL RTOL ATOL EWT(i)
13879 ! 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
13880 ! 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
13881 ! 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
13882 ! 4 array scalar RTOL(i)*ABS(Y(i)) + ATOL(i)
13883 ! When either of these parameters is a scalar, it need not
13884 ! be dimensioned in the user's calling program.
13885 ! If none of the above choices (with ITOL, RTOL, and ATOL
13886 ! fixed throughout the problem) is suitable, more general
13887 ! error controls can be obtained by substituting
13888 ! user-supplied routines for the setting of EWT and/or for
13889 ! the norm calculation. See Part 4 below.
13890 ! If global errors are to be estimated by making a repeated
13891 ! run on the same problem with smaller tolerances, then all
13892 ! components of RTOL and ATOL (i.e. of EWT) should be scaled
13893 ! down uniformly.
13894 ! ITASK = an index specifying the task to be performed.
13895 ! Input only. ITASK has the following values and meanings.
13896 ! 1 means normal computation of output values of y(t) at
13897 ! t = TOUT (by overshooting and interpolating).
13898 ! 2 means take one step only and return.
13899 ! 3 means stop at the first internal mesh point at or
13900 ! beyond t = TOUT and return.
13901 ! 4 means normal computation of output values of y(t) at
13902 ! t = TOUT but without overshooting t = TCRIT.
13903 ! TCRIT must be input as RWORK(1). TCRIT may be equal to
13904 ! or beyond TOUT, but not behind it in the direction of
13905 ! integration. This option is useful if the problem
13906 ! has a singularity at or beyond t = TCRIT.
13907 ! 5 means take one step, without passing TCRIT, and return.
13908 ! TCRIT must be input as RWORK(1).
13909 ! Note: If ITASK = 4 or 5 and the solver reaches TCRIT
13910 ! (within roundoff), it will return T = TCRIT (exactly) to
13911 ! indicate this (unless ITASK = 4 and TOUT comes before TCRIT,
13912 ! in which case answers at t = TOUT are returned first).
13913 ! ISTATE = an index used for input and output to specify the
13914 ! state of the calculation.
13915 ! On input, the values of ISTATE are as follows.
13916 ! 0 means this is the first call for the problem, and
13917 ! DLSODIS is to compute the initial value of dy/dt
13918 ! (while doing other initializations). See note below.
13919 ! 1 means this is the first call for the problem, and
13920 ! the initial value of dy/dt has been supplied in
13921 ! YDOTI (DLSODIS will do other initializations).
13922 ! See note below.
13923 ! 2 means this is not the first call, and the calculation
13924 ! is to continue normally, with no change in any input
13925 ! parameters except possibly TOUT and ITASK.
13926 ! (If ITOL, RTOL, and/or ATOL are changed between calls
13927 ! with ISTATE = 2, the new values will be used but not
13928 ! tested for legality.)
13929 ! 3 means this is not the first call, and the
13930 ! calculation is to continue normally, but with
13931 ! a change in input parameters other than
13932 ! TOUT and ITASK. Changes are allowed in
13933 ! NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF,
13934 ! the conditional inputs IA, JA, IC, and JC,
13935 ! and any of the optional inputs except H0.
13936 ! A call with ISTATE = 3 will cause the sparsity
13937 ! structure of the problem to be recomputed.
13938 ! (Structure information is reread from IA and JA if
13939 ! MOSS = 0, 3, or 4 and from IC and JC if MOSS = 0).
13940 ! Note: A preliminary call with TOUT = T is not counted
13941 ! as a first call here, as no initialization or checking of
13942 ! input is done. (Such a call is sometimes useful for the
13943 ! purpose of outputting the initial conditions.)
13944 ! Thus the first call for which TOUT .ne. T requires
13945 ! ISTATE = 0 or 1 on input.
13946 ! On output, ISTATE has the following values and meanings.
13947 ! 0 or 1 means nothing was done; TOUT = T and
13948 ! ISTATE = 0 or 1 on input.
13949 ! 2 means that the integration was performed successfully.
13950 ! 3 means that the user-supplied Subroutine RES signalled
13951 ! DLSODIS to halt the integration and return (IRES = 2).
13952 ! Integration as far as T was achieved with no occurrence
13953 ! of IRES = 2, but this flag was set on attempting the
13954 ! next step.
13955 ! -1 means an excessive amount of work (more than MXSTEP
13956 ! steps) was done on this call, before completing the
13957 ! requested task, but the integration was otherwise
13958 ! successful as far as T. (MXSTEP is an optional input
13959 ! and is normally 500.) To continue, the user may
13960 ! simply reset ISTATE to a value .gt. 1 and call again
13961 ! (the excess work step counter will be reset to 0).
13962 ! In addition, the user may increase MXSTEP to avoid
13963 ! this error return (see below on optional inputs).
13964 ! -2 means too much accuracy was requested for the precision
13965 ! of the machine being used. This was detected before
13966 ! completing the requested task, but the integration
13967 ! was successful as far as T. To continue, the tolerance
13968 ! parameters must be reset, and ISTATE must be set
13969 ! to 3. The optional output TOLSF may be used for this
13970 ! purpose. (Note: If this condition is detected before
13971 ! taking any steps, then an illegal input return
13972 ! (ISTATE = -3) occurs instead.)
13973 ! -3 means illegal input was detected, before taking any
13974 ! integration steps. See written message for details.
13975 ! Note: If the solver detects an infinite loop of calls
13976 ! to the solver with illegal input, it will cause
13977 ! the run to stop.
13978 ! -4 means there were repeated error test failures on
13979 ! one attempted step, before completing the requested
13980 ! task, but the integration was successful as far as T.
13981 ! The problem may have a singularity, or the input
13982 ! may be inappropriate.
13983 ! -5 means there were repeated convergence test failures on
13984 ! one attempted step, before completing the requested
13985 ! task, but the integration was successful as far as T.
13986 ! This may be caused by an inaccurate Jacobian matrix.
13987 ! -6 means EWT(i) became zero for some i during the
13988 ! integration. Pure relative error control (ATOL(i) = 0.0)
13989 ! was requested on a variable which has now vanished.
13990 ! the integration was successful as far as T.
13991 ! -7 means that the user-supplied Subroutine RES set
13992 ! its error flag (IRES = 3) despite repeated tries by
13993 ! DLSODIS to avoid that condition.
13994 ! -8 means that ISTATE was 0 on input but DLSODIS was unable
13995 ! to compute the initial value of dy/dt. See the
13996 ! printed message for details.
13997 ! -9 means a fatal error return flag came from the sparse
13998 ! solver CDRV by way of DPRJIS or DSOLSS (numerical
13999 ! factorization or backsolve). This should never happen.
14000 ! The integration was successful as far as T.
14001 ! Note: An error return with ISTATE = -1, -4, or -5
14002 ! may mean that the sparsity structure of the
14003 ! problem has changed significantly since it was last
14004 ! determined (or input). In that case, one can attempt to
14005 ! complete the integration by setting ISTATE = 3 on the next
14006 ! call, so that a new structure determination is done.
14007 ! Note: Since the normal output value of ISTATE is 2,
14008 ! it does not need to be reset for normal continuation.
14009 ! similarly, ISTATE (= 3) need not be reset if RES told
14010 ! DLSODIS to return because the calling program must change
14011 ! the parameters of the problem.
14012 ! Also, since a negative input value of ISTATE will be
14013 ! regarded as illegal, a negative output value requires the
14014 ! user to change it, and possibly other inputs, before
14015 ! calling the solver again.
14016 ! IOPT = an integer flag to specify whether or not any optional
14017 ! inputs are being used on this call. Input only.
14018 ! The optional inputs are listed separately below.
14019 ! IOPT = 0 means no optional inputs are being used.
14020 ! Default values will be used in all cases.
14021 ! IOPT = 1 means one or more optional inputs are being used.
14022 ! RWORK = a work array used for a mixture of real (double precision)
14023 ! and integer work space.
14024 ! The length of RWORK (in real words) must be at least
14025 ! 20 + NYH*(MAXORD + 1) + 3*NEQ + LWM where
14026 ! NYH = the initial value of NEQ,
14027 ! MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a
14028 ! smaller value is given as an optional input),
14029 ! LWM = 2*NNZ + 2*NEQ + (NNZ+9*NEQ)/LENRAT if MITER = 1,
14030 ! LWM = 2*NNZ + 2*NEQ + (NNZ+10*NEQ)/LENRAT if MITER = 2.
14031 ! in the above formulas,
14032 ! NNZ = number of nonzero elements in the iteration matrix
14033 ! P = A - con*J (con is a constant and J is the
14034 ! Jacobian matrix dr/dy).
14035 ! LENRAT = the real to integer wordlength ratio (usually 1 in
14036 ! single precision and 2 in double precision).
14037 ! (See the MF description for METH and MITER.)
14038 ! Thus if MAXORD has its default value and NEQ is constant,
14039 ! the minimum length of RWORK is:
14040 ! 20 + 16*NEQ + LWM for MF = 11, 111, 311, 12, 212, 412,
14041 ! 20 + 9*NEQ + LWM for MF = 21, 121, 321, 22, 222, 422.
14042 ! The above formula for LWM is only a crude lower bound.
14043 ! The required length of RWORK cannot be readily predicted
14044 ! in general, as it depends on the sparsity structure
14045 ! of the problem. Some experimentation may be necessary.
14046 ! The first 20 words of RWORK are reserved for conditional
14047 ! and optional inputs and optional outputs.
14048 ! The following word in RWORK is a conditional input:
14049 ! RWORK(1) = TCRIT = critical value of t which the solver
14050 ! is not to overshoot. Required if ITASK is
14051 ! 4 or 5, and ignored otherwise. (See ITASK.)
14052 ! LRW = the length of the array RWORK, as declared by the user.
14053 ! (This will be checked by the solver.)
14054 ! IWORK = an integer work array. The length of IWORK must be at least
14055 ! 32 + 2*NEQ + NZA + NZC for MOSS = 0,
14056 ! 30 for MOSS = 1 or 2,
14057 ! 31 + NEQ + NZA for MOSS = 3 or 4.
14058 ! (NZA is the number of nonzero elements in matrix A, and
14059 ! NZC is the number of nonzero elements in dr/dy.)
14060 ! In DLSODIS, IWORK is used for conditional and
14061 ! optional inputs and optional outputs.
14062 ! The following two blocks of words in IWORK are conditional
14063 ! inputs, required if MOSS = 0, 3, or 4, but not otherwise
14064 ! (see the description of MF for MOSS).
14065 ! IWORK(30+j) = IA(j) (j=1,...,NEQ+1)
14066 ! IWORK(31+NEQ+k) = JA(k) (k=1,...,NZA)
14067 ! The two arrays IA and JA describe the sparsity structure
14068 ! to be assumed for the matrix A. JA contains the row
14069 ! indices where nonzero elements occur, reading in columnwise
14070 ! order, and IA contains the starting locations in JA of the
14071 ! descriptions of columns 1,...,NEQ, in that order, with
14072 ! IA(1) = 1. Thus, for each column index j = 1,...,NEQ, the
14073 ! values of the row index i in column j where a nonzero
14074 ! element may occur are given by
14075 ! i = JA(k), where IA(j) .le. k .lt. IA(j+1).
14076 ! If NZA is the total number of nonzero locations assumed,
14077 ! then the length of the JA array is NZA, and IA(NEQ+1) must
14078 ! be NZA + 1. Duplicate entries are not allowed.
14079 ! The following additional blocks of words are required
14080 ! if MOSS = 0, but not otherwise. If LC = 31 + NEQ + NZA, then
14081 ! IWORK(LC+j) = IC(j) (j=1,...,NEQ+1), and
14082 ! IWORK(LC+NEQ+1+k) = JC(k) (k=1,...,NZC)
14083 ! The two arrays IC and JC describe the sparsity
14084 ! structure to be assumed for the Jacobian matrix dr/dy.
14085 ! They are used in the same manner as the above IA and JA
14086 ! arrays. If NZC is the number of nonzero locations
14087 ! assumed, then the length of the JC array is NZC, and
14088 ! IC(NEQ+1) must be NZC + 1. Duplicate entries are not
14089 ! allowed.
14090 ! LIW = the length of the array IWORK, as declared by the user.
14091 ! (This will be checked by the solver.)
14092 ! Note: The work arrays must not be altered between calls to DLSODIS
14093 ! for the same problem, except possibly for the conditional and
14094 ! optional inputs, and except for the last 3*NEQ words of RWORK.
14095 ! The latter space is used for internal scratch space, and so is
14096 ! available for use by the user outside DLSODIS between calls, if
14097 ! desired (but not for use by RES, ADDA, or JAC).
14098 ! MF = the method flag. Used only for input.
14099 ! MF has three decimal digits-- MOSS, METH, and MITER.
14100 ! For standard options:
14101 ! MF = 100*MOSS + 10*METH + MITER.
14102 ! MOSS indicates the method to be used to obtain the sparsity
14103 ! structure of the Jacobian matrix:
14104 ! MOSS = 0 means the user has supplied IA, JA, IC, and JC
14105 ! (see descriptions under IWORK above).
14106 ! MOSS = 1 means the user has supplied JAC (see below) and
14107 ! the structure will be obtained from NEQ initial
14108 ! calls to JAC and NEQ initial calls to ADDA.
14109 ! MOSS = 2 means the structure will be obtained from NEQ+1
14110 ! initial calls to RES and NEQ initial calls to ADDA
14111 ! MOSS = 3 like MOSS = 1, except user has supplied IA and JA.
14112 ! MOSS = 4 like MOSS = 2, except user has supplied IA and JA.
14113 ! METH indicates the basic linear multistep method:
14114 ! METH = 1 means the implicit Adams method.
14115 ! METH = 2 means the method based on Backward
14116 ! Differentiation Formulas (BDFs).
14117 ! The BDF method is strongly preferred for stiff problems,
14118 ! while the Adams method is preferred when the problem is
14119 ! not stiff. If the matrix A(t,y) is nonsingular,
14120 ! stiffness here can be taken to mean that of the explicit
14121 ! ODE system dy/dt = A-inverse * g. If A is singular,
14122 ! the concept of stiffness is not well defined.
14123 ! If you do not know whether the problem is stiff, we
14124 ! recommend using METH = 2. If it is stiff, the advantage
14125 ! of METH = 2 over METH = 1 will be great, while if it is
14126 ! not stiff, the advantage of METH = 1 will be slight.
14127 ! If maximum efficiency is important, some experimentation
14128 ! with METH may be necessary.
14129 ! MITER indicates the corrector iteration method:
14130 ! MITER = 1 means chord iteration with a user-supplied
14131 ! sparse Jacobian, given by Subroutine JAC.
14132 ! MITER = 2 means chord iteration with an internally
14133 ! generated (difference quotient) sparse
14134 ! Jacobian (using NGP extra calls to RES per
14135 ! dr/dy value, where NGP is an optional
14136 ! output described below.)
14137 ! If MITER = 1 or MOSS = 1 or 3 the user must supply a
14138 ! Subroutine JAC (the name is arbitrary) as described above
14139 ! under JAC. Otherwise, a dummy argument can be used.
14140 ! The standard choices for MF are:
14141 ! MF = 21 or 22 for a stiff problem with IA/JA and IC/JC
14142 ! supplied,
14143 ! MF = 121 for a stiff problem with JAC supplied, but not
14144 ! IA/JA or IC/JC,
14145 ! MF = 222 for a stiff problem with neither IA/JA, IC/JC/,
14146 ! nor JAC supplied,
14147 ! MF = 321 for a stiff problem with IA/JA and JAC supplied,
14148 ! but not IC/JC,
14149 ! MF = 422 for a stiff problem with IA/JA supplied, but not
14150 ! IC/JC or JAC.
14151 ! The sparseness structure can be changed during the problem
14152 ! by making a call to DLSODIS with ISTATE = 3.
14153 !-----------------------------------------------------------------------
14154 ! Optional Inputs.
14155 ! The following is a list of the optional inputs provided for in the
14156 ! call sequence. (See also Part 2.) For each such input variable,
14157 ! this table lists its name as used in this documentation, its
14158 ! location in the call sequence, its meaning, and the default value.
14159 ! The use of any of these inputs requires IOPT = 1, and in that
14160 ! case all of these inputs are examined. A value of zero for any
14161 ! of these optional inputs will cause the default value to be used.
14162 ! Thus to use a subset of the optional inputs, simply preload
14163 ! locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, and
14164 ! then set those of interest to nonzero values.
14165 ! Name Location Meaning and Default Value
14166 ! H0 RWORK(5) the step size to be attempted on the first step.
14167 ! The default value is determined by the solver.
14168 ! HMAX RWORK(6) the maximum absolute step size allowed.
14169 ! The default value is infinite.
14170 ! HMIN RWORK(7) the minimum absolute step size allowed.
14171 ! The default value is 0. (This lower bound is not
14172 ! enforced on the final step before reaching TCRIT
14173 ! when ITASK = 4 or 5.)
14174 ! MAXORD IWORK(5) the maximum order to be allowed. The default
14175 ! value is 12 if METH = 1, and 5 if METH = 2.
14176 ! If MAXORD exceeds the default value, it will
14177 ! be reduced to the default value.
14178 ! If MAXORD is changed during the problem, it may
14179 ! cause the current order to be reduced.
14180 ! MXSTEP IWORK(6) maximum number of (internally defined) steps
14181 ! allowed during one call to the solver.
14182 ! The default value is 500.
14183 ! MXHNIL IWORK(7) maximum number of messages printed (per problem)
14184 ! warning that T + H = T on a step (H = step size).
14185 ! This must be positive to result in a non-default
14186 ! value. The default value is 10.
14187 !-----------------------------------------------------------------------
14188 ! Optional Outputs.
14189 ! As optional additional output from DLSODIS, the variables listed
14190 ! below are quantities related to the performance of DLSODIS
14191 ! which are available to the user. These are communicated by way of
14192 ! the work arrays, but also have internal mnemonic names as shown.
14193 ! Except where stated otherwise, all of these outputs are defined
14194 ! on any successful return from DLSODIS, and on any return with
14195 ! ISTATE = -1, -2, -4, -5, -6, or -7. On a return with -3 (illegal
14196 ! input) or -8, they will be unchanged from their existing values
14197 ! (if any), except possibly for TOLSF, LENRW, and LENIW.
14198 ! On any error return, outputs relevant to the error will be defined,
14199 ! as noted below.
14200 ! Name Location Meaning
14201 ! HU RWORK(11) the step size in t last used (successfully).
14202 ! HCUR RWORK(12) the step size to be attempted on the next step.
14203 ! TCUR RWORK(13) the current value of the independent variable
14204 ! which the solver has actually reached, i.e. the
14205 ! current internal mesh point in t. On output, TCUR
14206 ! will always be at least as far as the argument
14207 ! T, but may be farther (if interpolation was done).
14208 ! TOLSF RWORK(14) a tolerance scale factor, greater than 1.0,
14209 ! computed when a request for too much accuracy was
14210 ! detected (ISTATE = -3 if detected at the start of
14211 ! the problem, ISTATE = -2 otherwise). If ITOL is
14212 ! left unaltered but RTOL and ATOL are uniformly
14213 ! scaled up by a factor of TOLSF for the next call,
14214 ! then the solver is deemed likely to succeed.
14215 ! (The user may also ignore TOLSF and alter the
14216 ! tolerance parameters in any other way appropriate.)
14217 ! NST IWORK(11) the number of steps taken for the problem so far.
14218 ! NRE IWORK(12) the number of residual evaluations (RES calls)
14219 ! for the problem so far, excluding those for
14220 ! structure determination (MOSS = 2 or 4).
14221 ! NJE IWORK(13) the number of Jacobian evaluations (each involving
14222 ! an evaluation of A and dr/dy) for the problem so
14223 ! far, excluding those for structure determination
14224 ! (MOSS = 1 or 3). This equals the number of calls
14225 ! to ADDA and (if MITER = 1) JAC.
14226 ! NQU IWORK(14) the method order last used (successfully).
14227 ! NQCUR IWORK(15) the order to be attempted on the next step.
14228 ! IMXER IWORK(16) the index of the component of largest magnitude in
14229 ! the weighted local error vector ( E(i)/EWT(i) ),
14230 ! on an error return with ISTATE = -4 or -5.
14231 ! LENRW IWORK(17) the length of RWORK actually required.
14232 ! This is defined on normal returns and on an illegal
14233 ! input return for insufficient storage.
14234 ! LENIW IWORK(18) the length of IWORK actually required.
14235 ! This is defined on normal returns and on an illegal
14236 ! input return for insufficient storage.
14237 ! NNZ IWORK(19) the number of nonzero elements in the iteration
14238 ! matrix P = A - con*J (con is a constant and
14239 ! J is the Jacobian matrix dr/dy).
14240 ! NGP IWORK(20) the number of groups of column indices, used in
14241 ! difference quotient Jacobian aproximations if
14242 ! MITER = 2. This is also the number of extra RES
14243 ! evaluations needed for each Jacobian evaluation.
14244 ! NLU IWORK(21) the number of sparse LU decompositions for the
14245 ! problem so far. (Excludes the LU decomposition
14246 ! necessary when ISTATE = 0.)
14247 ! LYH IWORK(22) the base address in RWORK of the history array YH,
14248 ! described below in this list.
14249 ! IPIAN IWORK(23) the base address of the structure descriptor array
14250 ! IAN, described below in this list.
14251 ! IPJAN IWORK(24) the base address of the structure descriptor array
14252 ! JAN, described below in this list.
14253 ! NZL IWORK(25) the number of nonzero elements in the strict lower
14254 ! triangle of the LU factorization used in the chord
14255 ! iteration.
14256 ! NZU IWORK(26) the number of nonzero elements in the strict upper
14257 ! triangle of the LU factorization used in the chord
14258 ! iteration. The total number of nonzeros in the
14259 ! factorization is therefore NZL + NZU + NEQ.
14260 ! The following four arrays are segments of the RWORK array which
14261 ! may also be of interest to the user as optional outputs.
14262 ! For each array, the table below gives its internal name,
14263 ! its base address, and its description.
14264 ! For YH and ACOR, the base addresses are in RWORK (a real array).
14265 ! The integer arrays IAN and JAN are to be obtained by declaring an
14266 ! integer array IWK and identifying IWK(1) with RWORK(21), using either
14267 ! an equivalence statement or a subroutine call. Then the base
14268 ! addresses IPIAN (of IAN) and IPJAN (of JAN) in IWK are to be obtained
14269 ! as optional outputs IWORK(23) and IWORK(24), respectively.
14270 ! Thus IAN(1) is IWK(ipian), etc.
14271 ! Name Base Address Description
14272 ! IAN IPIAN (in IWK) structure descriptor array of size NEQ + 1.
14273 ! JAN IPJAN (in IWK) structure descriptor array of size NNZ.
14274 ! (see above) IAN and JAN together describe the sparsity
14275 ! structure of the iteration matrix
14276 ! P = A - con*J, as used by DLSODIS.
14277 ! JAN contains the row indices of the nonzero
14278 ! locations, reading in columnwise order, and
14279 ! IAN contains the starting locations in JAN of
14280 ! the descriptions of columns 1,...,NEQ, in
14281 ! that order, with IAN(1) = 1. Thus for each
14282 ! j = 1,...,NEQ, the row indices i of the
14283 ! nonzero locations in column j are
14284 ! i = JAN(k), IAN(j) .le. k .lt. IAN(j+1).
14285 ! Note that IAN(NEQ+1) = NNZ + 1.
14286 ! YH LYH the Nordsieck history array, of size NYH by
14287 ! (optional (NQCUR + 1), where NYH is the initial value
14288 ! output) of NEQ. For j = 0,1,...,NQCUR, column j+1
14289 ! of YH contains HCUR**j/factorial(j) times
14290 ! the j-th derivative of the interpolating
14291 ! polynomial currently representing the solution,
14292 ! evaluated at t = TCUR. The base address LYH
14293 ! is another optional output, listed above.
14294 ! ACOR LENRW-NEQ+1 array of size NEQ used for the accumulated
14295 ! corrections on each step, scaled on output to
14296 ! represent the estimated local error in y on the
14297 ! last step. This is the vector E in the
14298 ! description of the error control. It is defined
14299 ! only on a return from DLSODIS with ISTATE = 2.
14300 !-----------------------------------------------------------------------
14301 ! Part 2. Other Routines Callable.
14302 ! The following are optional calls which the user may make to
14303 ! gain additional capabilities in conjunction with DLSODIS.
14304 ! (The routines XSETUN and XSETF are designed to conform to the
14305 ! SLATEC error handling package.)
14306 ! Form of Call Function
14307 ! CALL XSETUN(LUN) Set the logical unit number, LUN, for
14308 ! output of messages from DLSODIS, if
14309 ! The default is not desired.
14310 ! The default value of LUN is 6.
14311 ! CALL XSETF(MFLAG) Set a flag to control the printing of
14312 ! messages by DLSODIS.
14313 ! MFLAG = 0 means do not print. (Danger:
14314 ! This risks losing valuable information.)
14315 ! MFLAG = 1 means print (the default).
14316 ! Either of the above calls may be made at
14317 ! any time and will take effect immediately.
14318 ! CALL DSRCMS(RSAV,ISAV,JOB) saves and restores the contents of
14319 ! the internal Common blocks used by
14320 ! DLSODIS (see Part 3 below).
14321 ! RSAV must be a real array of length 224
14322 ! or more, and ISAV must be an integer
14323 ! array of length 71 or more.
14324 ! JOB=1 means save Common into RSAV/ISAV.
14325 ! JOB=2 means restore Common from RSAV/ISAV.
14326 ! DSRCMS is useful if one is
14327 ! interrupting a run and restarting
14328 ! later, or alternating between two or
14329 ! more problems solved with DLSODIS.
14330 ! CALL DINTDY(,,,,,) Provide derivatives of y, of various
14331 ! (see below) orders, at a specified point t, if
14332 ! desired. It may be called only after
14333 ! a successful return from DLSODIS.
14334 ! The detailed instructions for using DINTDY are as follows.
14335 ! The form of the call is:
14336 ! LYH = IWORK(22)
14337 ! CALL DINTDY (T, K, RWORK(LYH), NYH, DKY, IFLAG)
14338 ! The input parameters are:
14339 ! T = value of independent variable where answers are desired
14340 ! (normally the same as the T last returned by DLSODIS).
14341 ! For valid results, T must lie between TCUR - HU and TCUR.
14342 ! (See optional outputs for TCUR and HU.)
14343 ! K = integer order of the derivative desired. K must satisfy
14344 ! 0 .le. K .le. NQCUR, where NQCUR is the current order
14345 ! (see optional outputs). The capability corresponding
14346 ! to K = 0, i.e. computing y(t), is already provided
14347 ! by DLSODIS directly. Since NQCUR .ge. 1, the first
14348 ! derivative dy/dt is always available with DINTDY.
14349 ! LYH = the base address of the history array YH, obtained
14350 ! as an optional output as shown above.
14351 ! NYH = column length of YH, equal to the initial value of NEQ.
14352 ! The output parameters are:
14353 ! DKY = a real array of length NEQ containing the computed value
14354 ! of the K-th derivative of y(t).
14355 ! IFLAG = integer flag, returned as 0 if K and T were legal,
14356 ! -1 if K was illegal, and -2 if T was illegal.
14357 ! On an error return, a message is also written.
14358 !-----------------------------------------------------------------------
14359 ! Part 3. Common Blocks.
14360 ! If DLSODIS is to be used in an overlay situation, the user
14361 ! must declare, in the primary overlay, the variables in:
14362 ! (1) the call sequence to DLSODIS, and
14363 ! (2) the two internal Common blocks
14364 ! /DLS001/ of length 255 (218 double precision words
14365 ! followed by 37 integer words),
14366 ! /DLSS01/ of length 40 (6 double precision words
14367 ! followed by 34 integer words).
14368 ! If DLSODIS is used on a system in which the contents of internal
14369 ! Common blocks are not preserved between calls, the user should
14370 ! declare the above Common blocks in the calling program to insure
14371 ! that their contents are preserved.
14372 ! If the solution of a given problem by DLSODIS is to be interrupted
14373 ! and then later continued, such as when restarting an interrupted run
14374 ! or alternating between two or more problems, the user should save,
14375 ! following the return from the last DLSODIS call prior to the
14376 ! interruption, the contents of the call sequence variables and the
14377 ! internal Common blocks, and later restore these values before the
14378 ! next DLSODIS call for that problem. To save and restore the Common
14379 ! blocks, use Subroutines DSRCMS (see Part 2 above).
14380 !-----------------------------------------------------------------------
14381 ! Part 4. Optionally Replaceable Solver Routines.
14382 ! Below are descriptions of two routines in the DLSODIS package which
14383 ! relate to the measurement of errors. Either routine can be
14384 ! replaced by a user-supplied version, if desired. However, since such
14385 ! a replacement may have a major impact on performance, it should be
14386 ! done only when absolutely necessary, and only with great caution.
14387 ! (Note: The means by which the package version of a routine is
14388 ! superseded by the user's version may be system-dependent.)
14389 ! (a) DEWSET.
14390 ! The following subroutine is called just before each internal
14391 ! integration step, and sets the array of error weights, EWT, as
14392 ! described under ITOL/RTOL/ATOL above:
14393 ! SUBROUTINE DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
14394 ! where NEQ, ITOL, RTOL, and ATOL are as in the DLSODIS call sequence,
14395 ! YCUR contains the current dependent variable vector, and
14396 ! EWT is the array of weights set by DEWSET.
14397 ! If the user supplies this subroutine, it must return in EWT(i)
14398 ! (i = 1,...,NEQ) a positive quantity suitable for comparing errors
14399 ! in y(i) to. The EWT array returned by DEWSET is passed to the DVNORM
14400 ! routine (see below), and also used by DLSODIS in the computation
14401 ! of the optional output IMXER, and the increments for difference
14402 ! quotient Jacobians.
14403 ! In the user-supplied version of DEWSET, it may be desirable to use
14404 ! the current values of derivatives of y. Derivatives up to order NQ
14405 ! are available from the history array YH, described above under
14406 ! optional outputs. In DEWSET, YH is identical to the YCUR array,
14407 ! extended to NQ + 1 columns with a column length of NYH and scale
14408 ! factors of H**j/factorial(j). On the first call for the problem,
14409 ! given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
14410 ! NYH is the initial value of NEQ. The quantities NQ, H, and NST
14411 ! can be obtained by including in DEWSET the statements:
14412 ! DOUBLE PRECISION RLS
14413 ! COMMON /DLS001/ RLS(218),ILS(37)
14414 ! NQ = ILS(33)
14415 ! NST = ILS(34)
14416 ! H = RLS(212)
14417 ! Thus, for example, the current value of dy/dt can be obtained as
14418 ! YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is
14419 ! unnecessary when NST = 0).
14420 ! (b) DVNORM.
14421 ! The following is a real function routine which computes the weighted
14422 ! root-mean-square norm of a vector v:
14423 ! D = DVNORM (N, V, W)
14424 ! where:
14425 ! N = the length of the vector,
14426 ! V = real array of length N containing the vector,
14427 ! W = real array of length N containing weights,
14428 ! D = SQRT( (1/N) * sum(V(i)*W(i))**2 ).
14429 ! DVNORM is called with N = NEQ and with W(i) = 1.0/EWT(i), where
14430 ! EWT is as set by Subroutine DEWSET.
14431 ! If the user supplies this function, it should return a non-negative
14432 ! value of DVNORM suitable for use in the error control in DLSODIS.
14433 ! None of the arguments should be altered by DVNORM.
14434 ! For example, a user-supplied DVNORM routine might:
14435 ! -substitute a max-norm of (V(i)*w(I)) for the RMS-norm, or
14436 ! -ignore some components of V in the norm, with the effect of
14437 ! suppressing the error control on those components of y.
14438 !-----------------------------------------------------------------------
14439 !***REVISION HISTORY (YYYYMMDD)
14440 ! 19820714 DATE WRITTEN
14441 ! 19830812 Major update, based on recent LSODI and LSODES revisions:
14442 ! Upgraded MDI in ODRV package: operates on M + M-transpose.
14443 ! Numerous revisions in use of work arrays;
14444 ! use wordlength ratio LENRAT; added IPISP & LRAT to Common;
14445 ! added optional outputs IPIAN/IPJAN;
14446 ! Added routine CNTNZU; added NZL and NZU to /LSS001/;
14447 ! changed ADJLR call logic; added optional outputs NZL & NZU;
14448 ! revised counter initializations; revised PREPI stmt. nos.;
14449 ! revised difference quotient increment;
14450 ! eliminated block /LSI001/, using IERPJ flag;
14451 ! revised STODI logic after PJAC return;
14452 ! revised tuning of H change and step attempts in STODI;
14453 ! corrections to main prologue and comments throughout.
14454 ! 19870320 Corrected jump on test of umax in CDRV routine.
14455 ! 20010125 Numerous revisions: corrected comments throughout;
14456 ! removed TRET from Common; rewrote EWSET with 4 loops;
14457 ! fixed t test in INTDY; added Cray directives in STODI;
14458 ! in STODI, fixed DELP init. and logic around PJAC call;
14459 ! combined routines to save/restore Common;
14460 ! passed LEVEL = 0 in error message calls (except run abort).
14461 ! 20010425 Major update: convert source lines to upper case;
14462 ! added *DECK lines; changed from 1 to * in dummy dimensions;
14463 ! changed names R1MACH/D1MACH to RUMACH/DUMACH;
14464 ! renamed routines for uniqueness across single/double prec.;
14465 ! converted intrinsic names to generic form;
14466 ! removed ILLIN and NTREP (data loaded) from Common;
14467 ! removed all 'own' variables from Common;
14468 ! changed error messages to quoted strings;
14469 ! replaced XERRWV/XERRWD with 1993 revised version;
14470 ! converted prologues, comments, error messages to mixed case;
14471 ! converted arithmetic IF statements to logical IF statements;
14472 ! numerous corrections to prologues and internal comments.
14473 ! 20010507 Converted single precision source to double precision.
14474 ! 20020502 Corrected declarations in descriptions of user routines.
14475 ! 20031021 Fixed address offset bugs in Subroutine DPREPI.
14476 ! 20031027 Changed 0. to 0.0D0 in Subroutine DPREPI.
14477 ! 20031105 Restored 'own' variables to Common blocks, to enable
14478 ! interrupt/restart feature.
14479 ! 20031112 Added SAVE statements for data-loaded constants.
14480 ! 20031117 Changed internal names NRE, LSAVR to NFE, LSAVF resp.
14481 !-----------------------------------------------------------------------
14482 ! Other routines in the DLSODIS package.
14483 ! In addition to Subroutine DLSODIS, the DLSODIS package includes the
14484 ! following subroutines and function routines:
14485 ! DIPREPI acts as an interface between DLSODIS and DPREPI, and also
14486 ! does adjusting of work space pointers and work arrays.
14487 ! DPREPI is called by DIPREPI to compute sparsity and do sparse
14488 ! matrix preprocessing.
14489 ! DAINVGS computes the initial value of the vector
14490 ! dy/dt = A-inverse * g
14491 ! ADJLR adjusts the length of required sparse matrix work space.
14492 ! It is called by DPREPI.
14493 ! CNTNZU is called by DPREPI and counts the nonzero elements in the
14494 ! strict upper triangle of P + P-transpose.
14495 ! JGROUP is called by DPREPI to compute groups of Jacobian column
14496 ! indices for use when MITER = 2.
14497 ! DINTDY computes an interpolated value of the y vector at t = TOUT.
14498 ! DSTODI is the core integrator, which does one step of the
14499 ! integration and the associated error control.
14500 ! DCFODE sets all method coefficients and test constants.
14501 ! DPRJIS computes and preprocesses the Jacobian matrix J = dr/dy
14502 ! and the Newton iteration matrix P = A - h*l0*J.
14503 ! DSOLSS manages solution of linear system in chord iteration.
14504 ! DEWSET sets the error weight vector EWT before each step.
14505 ! DVNORM computes the weighted RMS-norm of a vector.
14506 ! DSRCMS is a user-callable routine to save and restore
14507 ! the contents of the internal Common blocks.
14508 ! ODRV constructs a reordering of the rows and columns of
14509 ! a matrix by the minimum degree algorithm. ODRV is a
14510 ! driver routine which calls Subroutines MD, MDI, MDM,
14511 ! MDP, MDU, and SRO. See Ref. 2 for details. (The ODRV
14512 ! module has been modified since Ref. 2, however.)
14513 ! CDRV performs reordering, symbolic factorization, numerical
14514 ! factorization, or linear system solution operations,
14515 ! depending on a path argument IPATH. CDRV is a
14516 ! driver routine which calls Subroutines NROC, NSFC,
14517 ! NNFC, NNSC, and NNTC. See Ref. 3 for details.
14518 ! DLSODIS uses CDRV to solve linear systems in which the
14519 ! coefficient matrix is P = A - con*J, where A is the
14520 ! matrix for the linear system A(t,y)*dy/dt = g(t,y),
14521 ! con is a scalar, and J is an approximation to
14522 ! the Jacobian dr/dy. Because CDRV deals with rowwise
14523 ! sparsity descriptions, CDRV works with P-transpose, not P.
14524 ! DLSODIS also uses CDRV to solve the linear system
14525 ! A(t,y)*dy/dt = g(t,y) for dy/dt when ISTATE = 0.
14526 ! (For this, CDRV works with A-transpose, not A.)
14527 ! DUMACH computes the unit roundoff in a machine-independent manner.
14528 ! XERRWD, XSETUN, XSETF, IXSAV, and IUMACH handle the printing of all
14529 ! error messages and warnings. XERRWD is machine-dependent.
14530 ! Note: DVNORM, DUMACH, IXSAV, and IUMACH are function routines.
14531 ! All the others are subroutines.
14532 !-----------------------------------------------------------------------
14533 ! EXTERNAL DPRJIS, DSOLSS
14534 ! DOUBLE PRECISION :: DUMACH, DVNORM
14535 ! INTEGER :: INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS, &
14536 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
14537 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
14538 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
14539 ! INTEGER :: IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
14540 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
14541 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
14542 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
14543 ! INTEGER :: I, I1, I2, IER, IGO, IFLAG, IMAX, IMUL, IMXER, IPFLAG, &
14544 ! IPGO, IREM, IRES, J, KGO, LENRAT, LENYHT, LENIW, LENRW, &
14545 ! LIA, LIC, LJA, LJC, LRTEM, LWTEM, LYD0, LYHD, LYHN, MF1, &
14546 ! MORD, MXHNL0, MXSTP0, NCOLM
14547 ! DOUBLE PRECISION :: ROWNS, &
14548 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
14549 ! DOUBLE PRECISION :: CON0, CONMIN, CCMXJ, PSMALL, RBIG, SETH
14550 ! DOUBLE PRECISION :: ATOLI, AYI, BIG, EWTI, H0, HMAX, HMX, RH, RTOLI, &
14551 ! TCRIT, TDIST, TNEXT, TOL, TOLSF, TP, SIZE, SUM, W0
14552 ! DIMENSION MORD(2)
14553 ! LOGICAL :: IHIT
14554 ! CHARACTER(60) :: MSG
14555 ! SAVE LENRAT, MORD, MXSTP0, MXHNL0
14556 !-----------------------------------------------------------------------
14557 ! The following two internal Common blocks contain
14558 ! (a) variables which are local to any subroutine but whose values must
14559 ! be preserved between calls to the routine ("own" variables), and
14560 ! (b) variables which are communicated between subroutines.
14561 ! The block DLS001 is declared in subroutines DLSODIS, DIPREPI, DPREPI,
14562 ! DINTDY, DSTODI, DPRJIS, and DSOLSS.
14563 ! The block DLSS01 is declared in subroutines DLSODIS, DAINVGS,
14564 ! DIPREPI, DPREPI, DPRJIS, and DSOLSS.
14565 ! Groups of variables are replaced by dummy arrays in the Common
14566 ! declarations in routines where those variables are not used.
14567 !-----------------------------------------------------------------------
14568 ! COMMON /DLS001/ ROWNS(209), &
14569 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
14570 ! INIT, MXSTEP, MXHNIL, NHNIL, NSLAST, NYH, IOWNS(6), &
14571 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
14572 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
14573 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
14574 ! COMMON /DLSS01/ CON0, CONMIN, CCMXJ, PSMALL, RBIG, SETH, &
14575 ! IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
14576 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
14577 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
14578 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
14579 ! DATA MORD(1),MORD(2)/12,5/, MXSTP0/500/, MXHNL0/10/
14580 !-----------------------------------------------------------------------
14581 ! In the Data statement below, set LENRAT equal to the ratio of
14582 ! the wordlength for a real number to that for an integer. Usually,
14583 ! LENRAT = 1 for single precision and 2 for double precision. If the
14584 ! true ratio is not an integer, use the next smaller integer (.ge. 1),
14585 !-----------------------------------------------------------------------
14586 ! DATA LENRAT/2/
14587 !-----------------------------------------------------------------------
14588 ! Block A.
14589 ! This code block is executed on every call.
14590 ! It tests ISTATE and ITASK for legality and branches appropirately.
14591 ! If ISTATE .gt. 1 but the flag INIT shows that initialization has
14592 ! not yet been done, an error return occurs.
14593 ! If ISTATE = 0 or 1 and TOUT = T, return immediately.
14594 !-----------------------------------------------------------------------
14595 ! IF (ISTATE < 0 .OR. ISTATE > 3) GO TO 601
14596 ! IF (ITASK < 1 .OR. ITASK > 5) GO TO 602
14597 ! IF (ISTATE <= 1) GO TO 10
14598 ! IF (INIT == 0) GO TO 603
14599 ! IF (ISTATE == 2) GO TO 200
14600 ! GO TO 20
14601 ! 10 INIT = 0
14602 ! IF (TOUT == T) RETURN
14603 !-----------------------------------------------------------------------
14604 ! Block B.
14605 ! The next code block is executed for the initial call (ISTATE = 0 or 1)
14606 ! or for a continuation call with parameter changes (ISTATE = 3).
14607 ! It contains checking of all inputs and various initializations.
14608 ! If ISTATE = 0 or 1, the final setting of work space pointers, the
14609 ! matrix preprocessing, and other initializations are done in Block C.
14610 ! First check legality of the non-optional inputs NEQ, ITOL, IOPT, and
14611 ! MF.
14612 !-----------------------------------------------------------------------
14613 ! 20 IF (NEQ(1) <= 0) GO TO 604
14614 ! IF (ISTATE <= 1) GO TO 25
14615 ! IF (NEQ(1) > N) GO TO 605
14616 ! 25 N = NEQ(1)
14617 ! IF (ITOL < 1 .OR. ITOL > 4) GO TO 606
14618 ! IF (IOPT < 0 .OR. IOPT > 1) GO TO 607
14619 ! MOSS = MF/100
14620 ! MF1 = MF - 100*MOSS
14621 ! METH = MF1/10
14622 ! MITER = MF1 - 10*METH
14623 ! IF (MOSS < 0 .OR. MOSS > 4) GO TO 608
14624 ! IF (MITER == 2 .AND. MOSS == 1) MOSS = MOSS + 1
14625 ! IF (MITER == 2 .AND. MOSS == 3) MOSS = MOSS + 1
14626 ! IF (MITER == 1 .AND. MOSS == 2) MOSS = MOSS - 1
14627 ! IF (MITER == 1 .AND. MOSS == 4) MOSS = MOSS - 1
14628 ! IF (METH < 1 .OR. METH > 2) GO TO 608
14629 ! IF (MITER < 1 .OR. MITER > 2) GO TO 608
14630 ! Next process and check the optional inputs. --------------------------
14631 ! IF (IOPT == 1) GO TO 40
14632 ! MAXORD = MORD(METH)
14633 ! MXSTEP = MXSTP0
14634 ! MXHNIL = MXHNL0
14635 ! IF (ISTATE <= 1) H0 = 0.0D0
14636 ! HMXI = 0.0D0
14637 ! HMIN = 0.0D0
14638 ! GO TO 60
14639 ! 40 MAXORD = IWORK(5)
14640 ! IF (MAXORD < 0) GO TO 611
14641 ! IF (MAXORD == 0) MAXORD = 100
14642 ! MAXORD = MIN(MAXORD,MORD(METH))
14643 ! MXSTEP = IWORK(6)
14644 ! IF (MXSTEP < 0) GO TO 612
14645 ! IF (MXSTEP == 0) MXSTEP = MXSTP0
14646 ! MXHNIL = IWORK(7)
14647 ! IF (MXHNIL < 0) GO TO 613
14648 ! IF (MXHNIL == 0) MXHNIL = MXHNL0
14649 ! IF (ISTATE > 1) GO TO 50
14650 ! H0 = RWORK(5)
14651 ! IF ((TOUT - T)*H0 < 0.0D0) GO TO 614
14652 ! 50 HMAX = RWORK(6)
14653 ! IF (HMAX < 0.0D0) GO TO 615
14654 ! HMXI = 0.0D0
14655 ! IF (HMAX > 0.0D0) HMXI = 1.0D0/HMAX
14656 ! HMIN = RWORK(7)
14657 ! IF (HMIN < 0.0D0) GO TO 616
14658 ! Check RTOL and ATOL for legality. ------------------------------------
14659 ! 60 RTOLI = RTOL(1)
14660 ! ATOLI = ATOL(1)
14661 ! DO 65 I = 1,N
14662 ! IF (ITOL >= 3) RTOLI = RTOL(I)
14663 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
14664 ! IF (RTOLI < 0.0D0) GO TO 619
14665 ! IF (ATOLI < 0.0D0) GO TO 620
14666 ! 65 END DO
14667 !-----------------------------------------------------------------------
14668 ! Compute required work array lengths, as far as possible, and test
14669 ! these against LRW and LIW. Then set tentative pointers for work
14670 ! arrays. Pointers to RWORK/IWORK segments are named by prefixing L to
14671 ! the name of the segment. E.g., the segment YH starts at RWORK(LYH).
14672 ! Segments of RWORK (in order) are denoted WM, YH, SAVR, EWT, ACOR.
14673 ! The required length of the matrix work space WM is not yet known,
14674 ! and so a crude minimum value is used for the initial tests of LRW
14675 ! and LIW, and YH is temporarily stored as far to the right in RWORK
14676 ! as possible, to leave the maximum amount of space for WM for matrix
14677 ! preprocessing. Thus if MOSS .ne. 2 or 4, some of the segments of
14678 ! RWORK are temporarily omitted, as they are not needed in the
14679 ! preprocessing. These omitted segments are: ACOR if ISTATE = 1,
14680 ! EWT and ACOR if ISTATE = 3 and MOSS = 1, and SAVR, EWT, and ACOR if
14681 ! ISTATE = 3 and MOSS = 0.
14682 !-----------------------------------------------------------------------
14683 ! LRAT = LENRAT
14684 ! IF (ISTATE <= 1) NYH = N
14685 ! IF (MITER == 1) LWMIN = 4*N + 10*N/LRAT
14686 ! IF (MITER == 2) LWMIN = 4*N + 11*N/LRAT
14687 ! LENYH = (MAXORD+1)*NYH
14688 ! LREST = LENYH + 3*N
14689 ! LENRW = 20 + LWMIN + LREST
14690 ! IWORK(17) = LENRW
14691 ! LENIW = 30
14692 ! IF (MOSS /= 1 .AND. MOSS /= 2) LENIW = LENIW + N + 1
14693 ! IWORK(18) = LENIW
14694 ! IF (LENRW > LRW) GO TO 617
14695 ! IF (LENIW > LIW) GO TO 618
14696 ! LIA = 31
14697 ! IF (MOSS /= 1 .AND. MOSS /= 2) &
14698 ! LENIW = LENIW + IWORK(LIA+N) - 1
14699 ! IWORK(18) = LENIW
14700 ! IF (LENIW > LIW) GO TO 618
14701 ! LJA = LIA + N + 1
14702 ! LIA = MIN(LIA,LIW)
14703 ! LJA = MIN(LJA,LIW)
14704 ! LIC = LENIW + 1
14705 ! IF (MOSS == 0) LENIW = LENIW + N + 1
14706 ! IWORK(18) = LENIW
14707 ! IF (LENIW > LIW) GO TO 618
14708 ! IF (MOSS == 0) LENIW = LENIW + IWORK(LIC+N) - 1
14709 ! IWORK(18) = LENIW
14710 ! IF (LENIW > LIW) GO TO 618
14711 ! LJC = LIC + N + 1
14712 ! LIC = MIN(LIC,LIW)
14713 ! LJC = MIN(LJC,LIW)
14714 ! LWM = 21
14715 ! IF (ISTATE <= 1) NQ = ISTATE
14716 ! NCOLM = MIN(NQ+1,MAXORD+2)
14717 ! LENYHM = NCOLM*NYH
14718 ! LENYHT = LENYHM
14719 ! IMUL = 2
14720 ! IF (ISTATE == 3) IMUL = MOSS
14721 ! IF (ISTATE == 3 .AND. MOSS == 3) IMUL = 1
14722 ! IF (MOSS == 2 .OR. MOSS == 4) IMUL = 3
14723 ! LRTEM = LENYHT + IMUL*N
14724 ! LWTEM = LRW - 20 - LRTEM
14725 ! LENWK = LWTEM
14726 ! LYHN = LWM + LWTEM
14727 ! LSAVF = LYHN + LENYHT
14728 ! LEWT = LSAVF + N
14729 ! LACOR = LEWT + N
14730 ! ISTATC = ISTATE
14731 ! IF (ISTATE <= 1) GO TO 100
14732 !-----------------------------------------------------------------------
14733 ! ISTATE = 3. Move YH to its new location.
14734 ! Note that only the part of YH needed for the next step, namely
14735 ! MIN(NQ+1,MAXORD+2) columns, is actually moved.
14736 ! A temporary error weight array EWT is loaded if MOSS = 2 or 4.
14737 ! Sparse matrix processing is done in DIPREPI/DPREPI.
14738 ! If MAXORD was reduced below NQ, then the pointers are finally set
14739 ! so that SAVR is identical to (YH*,MAXORD+2)
14740 !-----------------------------------------------------------------------
14741 ! LYHD = LYH - LYHN
14742 ! IMAX = LYHN - 1 + LENYHM
14743 ! Move YH. Move right if LYHD < 0; move left if LYHD > 0. -------------
14744 ! IF (LYHD < 0) THEN
14745 ! DO 72 I = LYHN,IMAX
14746 ! J = IMAX + LYHN - I
14747 ! RWORK(J) = RWORK(J+LYHD)
14748 ! 72 END DO
14749 ! ENDIF
14750 ! IF (LYHD > 0) THEN
14751 ! DO 76 I = LYHN,IMAX
14752 ! RWORK(I) = RWORK(I+LYHD)
14753 ! 76 END DO
14754 ! ENDIF
14755 ! 80 LYH = LYHN
14756 ! IWORK(22) = LYH
14757 ! IF (MOSS /= 2 .AND. MOSS /= 4) GO TO 85
14758 ! Temporarily load EWT if MOSS = 2 or 4.
14759 ! CALL DEWSET (N,ITOL,RTOL,ATOL,RWORK(LYH),RWORK(LEWT))
14760 ! DO 82 I = 1,N
14761 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
14762 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
14763 ! 82 END DO
14764 ! 85 CONTINUE
14765 ! DIPREPI and DPREPI do sparse matrix preprocessing. -------------------
14766 ! LSAVF = MIN(LSAVF,LRW)
14767 ! LEWT = MIN(LEWT,LRW)
14768 ! LACOR = MIN(LACOR,LRW)
14769 ! CALL DIPREPI (NEQ, Y, YDOTI, RWORK, IWORK(LIA), IWORK(LJA), &
14770 ! IWORK(LIC), IWORK(LJC), IPFLAG, RES, JAC, ADDA)
14771 ! LENRW = LWM - 1 + LENWK + LREST
14772 ! IWORK(17) = LENRW
14773 ! IF (IPFLAG /= -1) IWORK(23) = IPIAN
14774 ! IF (IPFLAG /= -1) IWORK(24) = IPJAN
14775 ! IPGO = -IPFLAG + 1
14776 ! GO TO (90, 628, 629, 630, 631, 632, 633, 634, 634), IPGO
14777 ! 90 IWORK(22) = LYH
14778 ! LYD0 = LYH + N
14779 ! IF (LENRW > LRW) GO TO 617
14780 ! Set flag to signal changes to DSTODI.---------------------------------
14781 ! JSTART = -1
14782 ! IF (NQ <= MAXORD) GO TO 94
14783 ! MAXORD was reduced below NQ. Copy YH(*,MAXORD+2) into YDOTI. --------
14784 ! DO 92 I = 1,N
14785 ! YDOTI(I) = RWORK(I+LSAVF-1)
14786 ! 92 END DO
14787 ! 94 IF (N == NYH) GO TO 200
14788 ! NEQ was reduced. Zero part of YH to avoid undefined references. -----
14789 ! I1 = LYH + L*NYH
14790 ! I2 = LYH + (MAXORD + 1)*NYH - 1
14791 ! IF (I1 > I2) GO TO 200
14792 ! DO 95 I = I1,I2
14793 ! RWORK(I) = 0.0D0
14794 ! 95 END DO
14795 ! GO TO 200
14796 !-----------------------------------------------------------------------
14797 ! Block C.
14798 ! The next block is for the initial call only (ISTATE = 0 or 1).
14799 ! It contains all remaining initializations, the call to DAINVGS
14800 ! (if ISTATE = 0), the sparse matrix preprocessing, and the
14801 ! calculation if the initial step size.
14802 ! The error weights in EWT are inverted after being loaded.
14803 !-----------------------------------------------------------------------
14804 ! 100 CONTINUE
14805 ! LYH = LYHN
14806 ! IWORK(22) = LYH
14807 ! TN = T
14808 ! NST = 0
14809 ! NFE = 0
14810 ! H = 1.0D0
14811 ! NNZ = 0
14812 ! NGP = 0
14813 ! NZL = 0
14814 ! NZU = 0
14815 ! Load the initial value vector in YH.----------------------------------
14816 ! DO 105 I = 1,N
14817 ! RWORK(I+LYH-1) = Y(I)
14818 ! 105 END DO
14819 ! IF (ISTATE /= 1) GO TO 108
14820 ! Initial dy/dt was supplied. Load it into YH (LYD0 points to YH(*,2).)
14821 ! LYD0 = LYH + NYH
14822 ! DO 106 I = 1,N
14823 ! RWORK(I+LYD0-1) = YDOTI(I)
14824 ! 106 END DO
14825 ! 108 CONTINUE
14826 ! Load and invert the EWT array. (H is temporarily set to 1.0.)--------
14827 ! CALL DEWSET (N,ITOL,RTOL,ATOL,RWORK(LYH),RWORK(LEWT))
14828 ! DO 110 I = 1,N
14829 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 621
14830 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
14831 ! 110 END DO
14832 ! Call DIPREPI and DPREPI to do sparse matrix preprocessing.------------
14833 ! LACOR = MIN(LACOR,LRW)
14834 ! CALL DIPREPI (NEQ, Y, YDOTI, RWORK, IWORK(LIA), IWORK(LJA), &
14835 ! IWORK(LIC), IWORK(LJC), IPFLAG, RES, JAC, ADDA)
14836 ! LENRW = LWM - 1 + LENWK + LREST
14837 ! IWORK(17) = LENRW
14838 ! IF (IPFLAG /= -1) IWORK(23) = IPIAN
14839 ! IF (IPFLAG /= -1) IWORK(24) = IPJAN
14840 ! IPGO = -IPFLAG + 1
14841 ! GO TO (115, 628, 629, 630, 631, 632, 633, 634, 634), IPGO
14842 ! 115 IWORK(22) = LYH
14843 ! IF (LENRW > LRW) GO TO 617
14844 ! Compute initial dy/dt, if necessary, and load it into YH.-------------
14845 ! LYD0 = LYH + N
14846 ! IF (ISTATE /= 0) GO TO 120
14847 ! CALL DAINVGS (NEQ, T, Y, RWORK(LWM), RWORK(LWM), RWORK(LACOR), &
14848 ! RWORK(LYD0), IER, RES, ADDA)
14849 ! NFE = NFE + 1
14850 ! IGO = IER + 1
14851 ! GO TO (120, 565, 560, 560), IGO
14852 ! Check TCRIT for legality (ITASK = 4 or 5). ---------------------------
14853 ! 120 CONTINUE
14854 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 125
14855 ! TCRIT = RWORK(1)
14856 ! IF ((TCRIT - TOUT)*(TOUT - T) < 0.0D0) GO TO 625
14857 ! IF (H0 /= 0.0D0 .AND. (T + H0 - TCRIT)*H0 > 0.0D0) &
14858 ! H0 = TCRIT - T
14859 ! Initialize all remaining parameters. ---------------------------------
14860 ! 125 UROUND = DUMACH()
14861 ! JSTART = 0
14862 ! RWORK(LWM) = SQRT(UROUND)
14863 ! NHNIL = 0
14864 ! NJE = 0
14865 ! NLU = 0
14866 ! NSLAST = 0
14867 ! HU = 0.0D0
14868 ! NQU = 0
14869 ! CCMAX = 0.3D0
14870 ! MAXCOR = 3
14871 ! MSBP = 20
14872 ! MXNCF = 10
14873 !-----------------------------------------------------------------------
14874 ! The coding below computes the step size, H0, to be attempted on the
14875 ! first step, unless the user has supplied a value for this.
14876 ! First check that TOUT - T differs significantly from zero.
14877 ! A scalar tolerance quantity TOL is computed, as MAX(RTOL(i))
14878 ! if this is positive, or MAX(ATOL(i)/ABS(Y(i))) otherwise, adjusted
14879 ! so as to be between 100*UROUND and 1.0E-3.
14880 ! Then the computed value H0 is given by..
14881 ! NEQ
14882 ! H0**2 = TOL / ( w0**-2 + (1/NEQ) * Sum ( YDOT(i)/ywt(i) )**2 )
14883 ! 1
14884 ! where w0 = MAX ( ABS(T), ABS(TOUT) ),
14885 ! YDOT(i) = i-th component of initial value of dy/dt,
14886 ! ywt(i) = EWT(i)/TOL (a weight for y(i)).
14887 ! The sign of H0 is inferred from the initial values of TOUT and T.
14888 !-----------------------------------------------------------------------
14889 ! IF (H0 /= 0.0D0) GO TO 180
14890 ! TDIST = ABS(TOUT - T)
14891 ! W0 = MAX(ABS(T),ABS(TOUT))
14892 ! IF (TDIST < 2.0D0*UROUND*W0) GO TO 622
14893 ! TOL = RTOL(1)
14894 ! IF (ITOL <= 2) GO TO 145
14895 ! DO 140 I = 1,N
14896 ! TOL = MAX(TOL,RTOL(I))
14897 ! 140 END DO
14898 ! 145 IF (TOL > 0.0D0) GO TO 160
14899 ! ATOLI = ATOL(1)
14900 ! DO 150 I = 1,N
14901 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
14902 ! AYI = ABS(Y(I))
14903 ! IF (AYI /= 0.0D0) TOL = MAX(TOL,ATOLI/AYI)
14904 ! 150 END DO
14905 ! 160 TOL = MAX(TOL,100.0D0*UROUND)
14906 ! TOL = MIN(TOL,0.001D0)
14907 ! SUM = DVNORM (N, RWORK(LYD0), RWORK(LEWT))
14908 ! SUM = 1.0D0/(TOL*W0*W0) + TOL*SUM**2
14909 ! H0 = 1.0D0/SQRT(SUM)
14910 ! H0 = MIN(H0,TDIST)
14911 ! H0 = SIGN(H0,TOUT-T)
14912 ! Adjust H0 if necessary to meet HMAX bound. ---------------------------
14913 ! 180 RH = ABS(H0)*HMXI
14914 ! IF (RH > 1.0D0) H0 = H0/RH
14915 ! Load H with H0 and scale YH(*,2) by H0. ------------------------------
14916 ! H = H0
14917 ! DO 190 I = 1,N
14918 ! RWORK(I+LYD0-1) = H0*RWORK(I+LYD0-1)
14919 ! 190 END DO
14920 ! GO TO 270
14921 !-----------------------------------------------------------------------
14922 ! Block D.
14923 ! The next code block is for continuation calls only (ISTATE = 2 or 3)
14924 ! and is to check stop conditions before taking a step.
14925 !-----------------------------------------------------------------------
14926 ! 200 NSLAST = NST
14927 ! GO TO (210, 250, 220, 230, 240), ITASK
14928 ! 210 IF ((TN - TOUT)*H < 0.0D0) GO TO 250
14929 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
14930 ! IF (IFLAG /= 0) GO TO 627
14931 ! T = TOUT
14932 ! GO TO 420
14933 ! 220 TP = TN - HU*(1.0D0 + 100.0D0*UROUND)
14934 ! IF ((TP - TOUT)*H > 0.0D0) GO TO 623
14935 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 250
14936 ! GO TO 400
14937 ! 230 TCRIT = RWORK(1)
14938 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
14939 ! IF ((TCRIT - TOUT)*H < 0.0D0) GO TO 625
14940 ! IF ((TN - TOUT)*H < 0.0D0) GO TO 245
14941 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
14942 ! IF (IFLAG /= 0) GO TO 627
14943 ! T = TOUT
14944 ! GO TO 420
14945 ! 240 TCRIT = RWORK(1)
14946 ! IF ((TN - TCRIT)*H > 0.0D0) GO TO 624
14947 ! 245 HMX = ABS(TN) + ABS(H)
14948 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
14949 ! IF (IHIT) GO TO 400
14950 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
14951 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
14952 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
14953 ! IF (ISTATE == 2) JSTART = -2
14954 !-----------------------------------------------------------------------
14955 ! Block E.
14956 ! The next block is normally executed for all calls and contains
14957 ! the call to the one-step core integrator DSTODI.
14958 ! This is a looping point for the integration steps.
14959 ! First check for too many steps being taken, update EWT (if not at
14960 ! start of problem), check for too much accuracy being requested, and
14961 ! check for H below the roundoff level in T.
14962 !-----------------------------------------------------------------------
14963 ! 250 CONTINUE
14964 ! IF ((NST-NSLAST) >= MXSTEP) GO TO 500
14965 ! CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
14966 ! DO 260 I = 1,N
14967 ! IF (RWORK(I+LEWT-1) <= 0.0D0) GO TO 510
14968 ! RWORK(I+LEWT-1) = 1.0D0/RWORK(I+LEWT-1)
14969 ! 260 END DO
14970 ! 270 TOLSF = UROUND*DVNORM (N, RWORK(LYH), RWORK(LEWT))
14971 ! IF (TOLSF <= 1.0D0) GO TO 280
14972 ! TOLSF = TOLSF*2.0D0
14973 ! IF (NST == 0) GO TO 626
14974 ! GO TO 520
14975 ! 280 IF ((TN + H) /= TN) GO TO 290
14976 ! NHNIL = NHNIL + 1
14977 ! IF (NHNIL > MXHNIL) GO TO 290
14978 ! MSG = 'DLSODIS- Warning..Internal T (=R1) and H (=R2) are'
14979 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
14980 ! MSG=' such that in the machine, T + H = T on the next step '
14981 ! CALL XERRWD (MSG, 60, 101, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
14982 ! MSG = ' (H = step size). Solver will continue anyway.'
14983 ! CALL XERRWD (MSG, 50, 101, 0, 0, 0, 0, 2, TN, H)
14984 ! IF (NHNIL < MXHNIL) GO TO 290
14985 ! MSG = 'DLSODIS- Above warning has been issued I1 times. '
14986 ! CALL XERRWD (MSG, 50, 102, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
14987 ! MSG = ' It will not be issued again for this problem.'
14988 ! CALL XERRWD (MSG, 50, 102, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
14989 ! 290 CONTINUE
14990 !-----------------------------------------------------------------------
14991 ! CALL DSTODI(NEQ,Y,YH,NYH,YH1,EWT,SAVF,SAVR,ACOR,WM,WM,RES,
14992 ! ADDA,JAC,DPRJIS,DSOLSS)
14993 ! Note: SAVF in DSTODI occupies the same space as YDOTI in DLSODIS.
14994 !-----------------------------------------------------------------------
14995 ! CALL DSTODI (NEQ, Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT), &
14996 ! YDOTI, RWORK(LSAVF), RWORK(LACOR), RWORK(LWM), &
14997 ! RWORK(LWM), RES, ADDA, JAC, DPRJIS, DSOLSS )
14998 ! KGO = 1 - KFLAG
14999 ! GO TO (300, 530, 540, 400, 550, 555), KGO
15000 ! KGO = 1:success; 2:error test failure; 3:convergence failure;
15001 ! 4:RES ordered return; 5:RES returned error;
15002 ! 6:fatal error from CDRV via DPRJIS or DSOLSS.
15003 !-----------------------------------------------------------------------
15004 ! Block F.
15005 ! The following block handles the case of a successful return from the
15006 ! core integrator (KFLAG = 0). Test for stop conditions.
15007 !-----------------------------------------------------------------------
15008 ! 300 INIT = 1
15009 ! GO TO (310, 400, 330, 340, 350), ITASK
15010 ! ITASK = 1. If TOUT has been reached, interpolate. -------------------
15011 ! 310 iF ((TN - TOUT)*H < 0.0D0) GO TO 250
15012 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
15013 ! T = TOUT
15014 ! GO TO 420
15015 ! ITASK = 3. Jump to exit if TOUT was reached. ------------------------
15016 ! 330 IF ((TN - TOUT)*H >= 0.0D0) GO TO 400
15017 ! GO TO 250
15018 ! ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary.
15019 ! 340 IF ((TN - TOUT)*H < 0.0D0) GO TO 345
15020 ! CALL DINTDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
15021 ! T = TOUT
15022 ! GO TO 420
15023 ! 345 HMX = ABS(TN) + ABS(H)
15024 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
15025 ! IF (IHIT) GO TO 400
15026 ! TNEXT = TN + H*(1.0D0 + 4.0D0*UROUND)
15027 ! IF ((TNEXT - TCRIT)*H <= 0.0D0) GO TO 250
15028 ! H = (TCRIT - TN)*(1.0D0 - 4.0D0*UROUND)
15029 ! JSTART = -2
15030 ! GO TO 250
15031 ! ITASK = 5. See if TCRIT was reached and jump to exit. ---------------
15032 ! 350 HMX = ABS(TN) + ABS(H)
15033 ! IHIT = ABS(TN - TCRIT) <= 100.0D0*UROUND*HMX
15034 !-----------------------------------------------------------------------
15035 ! Block G.
15036 ! The following block handles all successful returns from DLSODIS.
15037 ! if ITASK .ne. 1, Y is loaded from YH and T is set accordingly.
15038 ! ISTATE is set to 2, and the optional outputs are loaded into the
15039 ! work arrays before returning.
15040 !-----------------------------------------------------------------------
15041 ! 400 DO 410 I = 1,N
15042 ! Y(I) = RWORK(I+LYH-1)
15043 ! 410 END DO
15044 ! T = TN
15045 ! IF (ITASK /= 4 .AND. ITASK /= 5) GO TO 420
15046 ! IF (IHIT) T = TCRIT
15047 ! 420 ISTATE = 2
15048 ! IF ( KFLAG == -3 ) ISTATE = 3
15049 ! RWORK(11) = HU
15050 ! RWORK(12) = H
15051 ! RWORK(13) = TN
15052 ! IWORK(11) = NST
15053 ! IWORK(12) = NFE
15054 ! IWORK(13) = NJE
15055 ! IWORK(14) = NQU
15056 ! IWORK(15) = NQ
15057 ! IWORK(19) = NNZ
15058 ! IWORK(20) = NGP
15059 ! IWORK(21) = NLU
15060 ! IWORK(25) = NZL
15061 ! IWORK(26) = NZU
15062 ! RETURN
15063 !-----------------------------------------------------------------------
15064 ! Block H.
15065 ! The following block handles all unsuccessful returns other than
15066 ! those for illegal input. First the error message routine is called.
15067 ! If there was an error test or convergence test failure, IMXER is set.
15068 ! Then Y is loaded from YH and T is set to TN.
15069 ! The optional outputs are loaded into the work arrays before returning.
15070 !-----------------------------------------------------------------------
15071 ! The maximum number of steps was taken before reaching TOUT. ----------
15072 ! 500 MSG = 'DLSODIS- At current T (=R1), MXSTEP (=I1) steps '
15073 ! CALL XERRWD (MSG, 50, 201, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15074 ! MSG = ' taken on this call before reaching TOUT '
15075 ! CALL XERRWD (MSG, 50, 201, 0, 1, MXSTEP, 0, 1, TN, 0.0D0)
15076 ! ISTATE = -1
15077 ! GO TO 580
15078 ! EWT(i) .le. 0.0 for some i (not at start of problem). ----------------
15079 ! 510 EWTI = RWORK(LEWT+I-1)
15080 ! MSG = 'DLSODIS- At T (=R1), EWT(I1) has become R2 <= 0.'
15081 ! CALL XERRWD (MSG, 50, 202, 0, 1, I, 0, 2, TN, EWTI)
15082 ! ISTATE = -6
15083 ! GO TO 590
15084 ! Too much accuracy requested for machine precision. -------------------
15085 ! 520 MSG = 'DLSODIS- At T (=R1), too much accuracy requested '
15086 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15087 ! MSG = ' for precision of machine.. See TOLSF (=R2) '
15088 ! CALL XERRWD (MSG, 50, 203, 0, 0, 0, 0, 2, TN, TOLSF)
15089 ! RWORK(14) = TOLSF
15090 ! ISTATE = -2
15091 ! GO TO 590
15092 ! KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
15093 ! 530 MSG = 'DLSODIS- At T (=R1) and step size H (=R2), the '
15094 ! CALL XERRWD (MSG, 50, 204, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15095 ! MSG=' error test failed repeatedly or with ABS(H) = HMIN '
15096 ! CALL XERRWD (MSG, 60, 204, 0, 0, 0, 0, 2, TN, H)
15097 ! ISTATE = -4
15098 ! GO TO 570
15099 ! KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
15100 ! 540 MSG = 'DLSODIS- At T (=R1) and step size H (=R2), the '
15101 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15102 ! MSG = ' corrector convergence failed repeatedly '
15103 ! CALL XERRWD (MSG, 50, 205, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15104 ! MSG = ' or with ABS(H) = HMIN '
15105 ! CALL XERRWD (MSG, 30, 205, 0, 0, 0, 0, 2, TN, H)
15106 ! ISTATE = -5
15107 ! GO TO 570
15108 ! IRES = 3 returned by RES, despite retries by DSTODI. -----------------
15109 ! 550 MSG = 'DLSODIS- At T (=R1) residual routine returned '
15110 ! CALL XERRWD (MSG, 50, 206, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15111 ! MSG = ' error IRES = 3 repeatedly.'
15112 ! CALL XERRWD (MSG, 30, 206, 1, 0, 0, 0, 0, TN, 0.0D0)
15113 ! ISTATE = -7
15114 ! GO TO 590
15115 ! KFLAG = -5. Fatal error flag returned by DPRJIS or DSOLSS (CDRV). ---
15116 ! 555 MSG = 'DLSODIS- At T (=R1) and step size H (=R2), a fatal'
15117 ! CALL XERRWD (MSG, 50, 207, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15118 ! MSG = ' error flag was returned by CDRV (by way of '
15119 ! CALL XERRWD (MSG, 50, 207, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15120 ! MSG = ' Subroutine DPRJIS or DSOLSS) '
15121 ! CALL XERRWD (MSG, 40, 207, 0, 0, 0, 0, 2, TN, H)
15122 ! ISTATE = -9
15123 ! GO TO 580
15124 ! DAINVGS failed because matrix A was singular. ------------------------
15125 ! 560 MSG='DLSODIS- Attempt to initialize dy/dt failed because matrix A'
15126 ! CALL XERRWD (MSG, 60, 208, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15127 ! MSG=' was singular. CDRV returned zero pivot error flag. '
15128 ! CALL XERRWD (MSG, 60, 208, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15129 ! MSG = 'DAINVGS set its error flag to IER = (I1)'
15130 ! CALL XERRWD (MSG, 40, 208, 0, 1, IER, 0, 0, 0.0D0, 0.0D0)
15131 ! ISTATE = -8
15132 ! RETURN
15133 ! DAINVGS failed because RES set IRES to 2 or 3. -----------------------
15134 ! 565 MSG = 'DLSODIS- Attempt to initialize dy/dt failed '
15135 ! CALL XERRWD (MSG, 50, 209, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15136 ! MSG = ' because residual routine set its error flag '
15137 ! CALL XERRWD (MSG, 50, 209, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15138 ! MSG = ' to IRES = (I1)'
15139 ! CALL XERRWD (MSG, 20, 209, 0, 1, IER, 0, 0, 0.0D0, 0.0D0)
15140 ! ISTATE = -8
15141 ! RETURN
15142 ! Compute IMXER if relevant. -------------------------------------------
15143 ! 570 BIG = 0.0D0
15144 ! IMXER = 1
15145 ! DO 575 I = 1,N
15146 ! SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
15147 ! IF (BIG >= SIZE) GO TO 575
15148 ! BIG = SIZE
15149 ! IMXER = I
15150 ! 575 END DO
15151 ! IWORK(16) = IMXER
15152 ! Compute residual if relevant. ----------------------------------------
15153 ! 580 LYD0 = LYH + NYH
15154 ! DO 585 I = 1, N
15155 ! RWORK(I+LSAVF-1) = RWORK(I+LYD0-1) / H
15156 ! Y(I) = RWORK(I+LYH-1)
15157 ! 585 END DO
15158 ! IRES = 1
15159 ! CALL RES (NEQ, TN, Y, RWORK(LSAVF), YDOTI, IRES)
15160 ! NFE = NFE + 1
15161 ! IF ( IRES <= 1 ) GO TO 595
15162 ! MSG = 'DLSODIS- Residual routine set its flag IRES '
15163 ! CALL XERRWD (MSG, 50, 210, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15164 ! MSG = ' to (I1) when called for final output. '
15165 ! CALL XERRWD (MSG, 50, 210, 0, 1, IRES, 0, 0, 0.0D0, 0.0D0)
15166 ! GO TO 595
15167 ! set y vector, t, and optional outputs. -------------------------------
15168 ! 590 DO 592 I = 1,N
15169 ! Y(I) = RWORK(I+LYH-1)
15170 ! 592 END DO
15171 ! 595 T = TN
15172 ! RWORK(11) = HU
15173 ! RWORK(12) = H
15174 ! RWORK(13) = TN
15175 ! IWORK(11) = NST
15176 ! IWORK(12) = NFE
15177 ! IWORK(13) = NJE
15178 ! IWORK(14) = NQU
15179 ! IWORK(15) = NQ
15180 ! IWORK(19) = NNZ
15181 ! IWORK(20) = NGP
15182 ! IWORK(21) = NLU
15183 ! IWORK(25) = NZL
15184 ! IWORK(26) = NZU
15185 ! RETURN
15186 !-----------------------------------------------------------------------
15187 ! Block I.
15188 ! The following block handles all error returns due to illegal input
15189 ! (ISTATE = -3), as detected before calling the core integrator.
15190 ! First the error message routine is called. If the illegal input
15191 ! is a negative ISTATE, the run is aborted (apparent infinite loop).
15192 !-----------------------------------------------------------------------
15193 ! 601 MSG = 'DLSODIS- ISTATE (=I1) illegal.'
15194 ! CALL XERRWD (MSG, 30, 1, 0, 1, ISTATE, 0, 0, 0.0D0, 0.0D0)
15195 ! IF (ISTATE < 0) GO TO 800
15196 ! GO TO 700
15197 ! 602 MSG = 'DLSODIS- ITASK (=I1) illegal. '
15198 ! CALL XERRWD (MSG, 30, 2, 0, 1, ITASK, 0, 0, 0.0D0, 0.0D0)
15199 ! GO TO 700
15200 ! 603 MSG = 'DLSODIS-ISTATE > 1 but DLSODIS not initialized.'
15201 ! CALL XERRWD (MSG, 50, 3, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15202 ! GO TO 700
15203 ! 604 MSG = 'DLSODIS- NEQ (=I1) < 1 '
15204 ! CALL XERRWD (MSG, 30, 4, 0, 1, NEQ(1), 0, 0, 0.0D0, 0.0D0)
15205 ! GO TO 700
15206 ! 605 MSG = 'DLSODIS- ISTATE = 3 and NEQ increased (I1 to I2). '
15207 ! CALL XERRWD (MSG, 50, 5, 0, 2, N, NEQ(1), 0, 0.0D0, 0.0D0)
15208 ! GO TO 700
15209 ! 606 MSG = 'DLSODIS- ITOL (=I1) illegal. '
15210 ! CALL XERRWD (MSG, 30, 6, 0, 1, ITOL, 0, 0, 0.0D0, 0.0D0)
15211 ! GO TO 700
15212 ! 607 MSG = 'DLSODIS- IOPT (=I1) illegal. '
15213 ! CALL XERRWD (MSG, 30, 7, 0, 1, IOPT, 0, 0, 0.0D0, 0.0D0)
15214 ! GO TO 700
15215 ! 608 MSG = 'DLSODIS- MF (=I1) illegal. '
15216 ! CALL XERRWD (MSG, 30, 8, 0, 1, MF, 0, 0, 0.0D0, 0.0D0)
15217 ! GO TO 700
15218 ! 611 MSG = 'DLSODIS- MAXORD (=I1) < 0 '
15219 ! CALL XERRWD (MSG, 30, 11, 0, 1, MAXORD, 0, 0, 0.0D0, 0.0D0)
15220 ! GO TO 700
15221 ! 612 MSG = 'DLSODIS- MXSTEP (=I1) < 0 '
15222 ! CALL XERRWD (MSG, 30, 12, 0, 1, MXSTEP, 0, 0, 0.0D0, 0.0D0)
15223 ! GO TO 700
15224 ! 613 MSG = 'DLSODIS- MXHNIL (=I1) < 0 '
15225 ! CALL XERRWD (MSG, 30, 13, 0, 1, MXHNIL, 0, 0, 0.0D0, 0.0D0)
15226 ! GO TO 700
15227 ! 614 MSG = 'DLSODIS- TOUT (=R1) behind T (=R2) '
15228 ! CALL XERRWD (MSG, 40, 14, 0, 0, 0, 0, 2, TOUT, T)
15229 ! MSG = ' Integration direction is given by H0 (=R1) '
15230 ! CALL XERRWD (MSG, 50, 14, 0, 0, 0, 0, 1, H0, 0.0D0)
15231 ! GO TO 700
15232 ! 615 MSG = 'DLSODIS- HMAX (=R1) < 0.0 '
15233 ! CALL XERRWD (MSG, 30, 15, 0, 0, 0, 0, 1, HMAX, 0.0D0)
15234 ! GO TO 700
15235 ! 616 MSG = 'DLSODIS- HMIN (=R1) < 0.0 '
15236 ! CALL XERRWD (MSG, 30, 16, 0, 0, 0, 0, 1, HMIN, 0.0D0)
15237 ! GO TO 700
15238 ! 617 MSG = 'DLSODIS- RWORK length is insufficient to proceed. '
15239 ! CALL XERRWD (MSG, 50, 17, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15240 ! MSG=' Length needed is >= LENRW (=I1), exceeds LRW (=I2)'
15241 ! CALL XERRWD (MSG, 60, 17, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
15242 ! GO TO 700
15243 ! 618 MSG = 'DLSODIS- IWORK length is insufficient to proceed. '
15244 ! CALL XERRWD (MSG, 50, 18, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15245 ! MSG=' Length needed is >= LENIW (=I1), exceeds LIW (=I2)'
15246 ! CALL XERRWD (MSG, 60, 18, 0, 2, LENIW, LIW, 0, 0.0D0, 0.0D0)
15247 ! GO TO 700
15248 ! 619 MSG = 'DLSODIS- RTOL(=I1) is R1 < 0.0 '
15249 ! CALL XERRWD (MSG, 40, 19, 0, 1, I, 0, 1, RTOLI, 0.0D0)
15250 ! GO TO 700
15251 ! 620 MSG = 'DLSODIS- ATOL(=I1) is R1 < 0.0 '
15252 ! CALL XERRWD (MSG, 40, 20, 0, 1, I, 0, 1, ATOLI, 0.0D0)
15253 ! GO TO 700
15254 ! 621 EWTI = RWORK(LEWT+I-1)
15255 ! MSG = 'DLSODIS- EWT(I1) is R1 <= 0.0 '
15256 ! CALL XERRWD (MSG, 40, 21, 0, 1, I, 0, 1, EWTI, 0.0D0)
15257 ! GO TO 700
15258 ! 622 MSG='DLSODIS- TOUT(=R1) too close to T(=R2) to start integration.'
15259 ! CALL XERRWD (MSG, 60, 22, 0, 0, 0, 0, 2, TOUT, T)
15260 ! GO TO 700
15261 ! 623 MSG='DLSODIS- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
15262 ! CALL XERRWD (MSG, 60, 23, 0, 1, ITASK, 0, 2, TOUT, TP)
15263 ! GO TO 700
15264 ! 624 MSG='DLSODIS- ITASK = 4 or 5 and TCRIT (=R1) behind TCUR (=R2) '
15265 ! CALL XERRWD (MSG, 60, 24, 0, 0, 0, 0, 2, TCRIT, TN)
15266 ! GO TO 700
15267 ! 625 MSG='DLSODIS- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
15268 ! CALL XERRWD (MSG, 60, 25, 0, 0, 0, 0, 2, TCRIT, TOUT)
15269 ! GO TO 700
15270 ! 626 MSG = 'DLSODIS- At start of problem, too much accuracy '
15271 ! CALL XERRWD (MSG, 50, 26, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15272 ! MSG=' requested for precision of machine.. See TOLSF (=R1) '
15273 ! CALL XERRWD (MSG, 60, 26, 0, 0, 0, 0, 1, TOLSF, 0.0D0)
15274 ! RWORK(14) = TOLSF
15275 ! GO TO 700
15276 ! 627 MSG = 'DLSODIS- Trouble in DINTDY. ITASK = I1, TOUT = R1'
15277 ! CALL XERRWD (MSG, 50, 27, 0, 1, ITASK, 0, 1, TOUT, 0.0D0)
15278 ! GO TO 700
15279 ! 628 MSG='DLSODIS- RWORK length insufficient (for Subroutine DPREPI). '
15280 ! CALL XERRWD (MSG, 60, 28, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15281 ! MSG=' Length needed is >= LENRW (=I1), exceeds LRW (=I2)'
15282 ! CALL XERRWD (MSG, 60, 28, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
15283 ! GO TO 700
15284 ! 629 MSG='DLSODIS- RWORK length insufficient (for Subroutine JGROUP). '
15285 ! CALL XERRWD (MSG, 60, 29, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15286 ! MSG=' Length needed is >= LENRW (=I1), exceeds LRW (=I2)'
15287 ! CALL XERRWD (MSG, 60, 29, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
15288 ! GO TO 700
15289 ! 630 MSG='DLSODIS- RWORK length insufficient (for Subroutine ODRV). '
15290 ! CALL XERRWD (MSG, 60, 30, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15291 ! MSG=' Length needed is >= LENRW (=I1), exceeds LRW (=I2)'
15292 ! CALL XERRWD (MSG, 60, 30, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
15293 ! GO TO 700
15294 ! 631 MSG='DLSODIS- Error from ODRV in Yale Sparse Matrix Package. '
15295 ! CALL XERRWD (MSG, 60, 31, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15296 ! IMUL = (IYS - 1)/N
15297 ! IREM = IYS - IMUL*N
15298 ! MSG=' At T (=R1), ODRV returned error flag = I1*NEQ + I2. '
15299 ! CALL XERRWD (MSG, 60, 31, 0, 2, IMUL, IREM, 1, TN, 0.0D0)
15300 ! GO TO 700
15301 ! 632 MSG='DLSODIS- RWORK length insufficient (for Subroutine CDRV). '
15302 ! CALL XERRWD (MSG, 60, 32, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15303 ! MSG=' Length needed is >= LENRW (=I1), exceeds LRW (=I2)'
15304 ! CALL XERRWD (MSG, 60, 32, 0, 2, LENRW, LRW, 0, 0.0D0, 0.0D0)
15305 ! GO TO 700
15306 ! 633 MSG='DLSODIS- Error from CDRV in Yale Sparse Matrix Package. '
15307 ! CALL XERRWD (MSG, 60, 33, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15308 ! IMUL = (IYS - 1)/N
15309 ! IREM = IYS - IMUL*N
15310 ! MSG=' At T (=R1), CDRV returned error flag = I1*NEQ + I2. '
15311 ! CALL XERRWD (MSG, 60, 33, 0, 2, IMUL, IREM, 1, TN, 0.0D0)
15312 ! IF (IMUL == 2) THEN
15313 ! MSG=' Duplicate entry in sparsity structure descriptors. '
15314 ! CALL XERRWD (MSG, 60, 33, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15315 ! ENDIF
15316 ! IF (IMUL == 3 .OR. IMUL == 6) THEN
15317 ! MSG=' Insufficient storage for NSFC (called by CDRV). '
15318 ! CALL XERRWD (MSG, 60, 33, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15319 ! ENDIF
15320 ! GO TO 700
15321 ! 634 MSG='DLSODIS- At T (=R1) residual routine (called by DPREPI) '
15322 ! CALL XERRWD (MSG, 60, 34, 0, 0, 0, 0, 0, 0.0D0, 0.0D0)
15323 ! IER = -IPFLAG - 5
15324 ! MSG = ' returned error IRES (=I1)'
15325 ! CALL XERRWD (MSG, 30, 34, 0, 1, IER, 0, 1, TN, 0.0D0)
15326 ! 700 ISTATE = -3
15327 ! RETURN
15328 ! 800 MSG = 'DLSODIS- Run aborted.. apparent infinite loop. '
15329 ! CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, 0.0D0, 0.0D0)
15330 ! RETURN
15331 !----------------------- End of Subroutine DLSODIS ---------------------
15332 ! END SUBROUTINE DLSODIS