2 SUBROUTINE DLSODAR
(F
, NEQ
, Y
, T
, TOUT
, ITOL
, RTOL
, ATOL
, ITASK
,
3 1 ISTATE
, IOPT
, RWORK
, LRW
, IWORK
, LIW
, JAC
, JT
,
6 INTEGER NEQ
, ITOL
, ITASK
, ISTATE
, IOPT
, LRW
, IWORK
, LIW
, JT
,
8 DOUBLE PRECISION Y
, T
, TOUT
, RTOL
, ATOL
, RWORK
9 DIMENSION NEQ
(*), Y
(*), RTOL
(*), ATOL
(*), RWORK
(LRW
), IWORK
(LIW
),
11 C-----------------------------------------------------------------------
12 C This is the 12 November 2003 version of
13 C DLSODAR: Livermore Solver for Ordinary Differential Equations, with
14 C Automatic method switching for stiff and nonstiff problems,
15 C and with Root-finding.
17 C This version is in double precision.
19 C DLSODAR solves the initial value problem for stiff or nonstiff
20 C systems of first order ODEs,
21 C dy/dt = f(t,y) , or, in component form,
22 C dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ)) (i = 1,...,NEQ).
23 C At the same time, it locates the roots of any of a set of functions
24 C g(i) = g(i,t,y(1),...,y(NEQ)) (i = 1,...,ng).
26 C This a variant version of the DLSODE package. It differs from it
28 C (a) It switches automatically between stiff and nonstiff methods.
29 C This means that the user does not have to determine whether the
30 C problem is stiff or not, and the solver will automatically choose the
31 C appropriate method. It always starts with the nonstiff method.
32 C (b) It finds the root of at least one of a set of constraint
33 C functions g(i) of the independent and dependent variables.
34 C It finds only those roots for which some g(i), as a function
35 C of t, changes sign in the interval of integration.
36 C It then returns the solution at the root, if that occurs
37 C sooner than the specified stop condition, and otherwise returns
38 C the solution according the specified stop condition.
40 C Authors: Alan C. Hindmarsh,
41 C Center for Applied Scientific Computing, L-561
42 C Lawrence Livermore National Laboratory
46 C Univ. of California at Santa Barbara
47 C Dept. of Computer Science
48 C Santa Barbara, CA 93106
51 C 1. Alan C. Hindmarsh, ODEPACK, A Systematized Collection of ODE
52 C Solvers, in Scientific Computing, R. S. Stepleman et al. (Eds.),
53 C North-Holland, Amsterdam, 1983, pp. 55-64.
54 C 2. Linda R. Petzold, Automatic Selection of Methods for Solving
55 C Stiff and Nonstiff Systems of Ordinary Differential Equations,
56 C Siam J. Sci. Stat. Comput. 4 (1983), pp. 136-148.
57 C 3. Kathie L. Hiebert and Lawrence F. Shampine, Implicitly Defined
58 C Output Points for Solutions of ODEs, Sandia Report SAND80-0180,
60 C-----------------------------------------------------------------------
63 C Communication between the user and the DLSODAR package, for normal
64 C situations, is summarized here. This summary describes only a subset
65 C of the full set of options available. See the full description for
66 C details, including alternative treatment of the Jacobian matrix,
67 C optional inputs and outputs, nonstandard options, and
68 C instructions for special situations. See also the example
69 C problem (with program and output) following this summary.
71 C A. First provide a subroutine of the form:
72 C SUBROUTINE F (NEQ, T, Y, YDOT)
73 C DOUBLE PRECISION T, Y(*), YDOT(*)
74 C which supplies the vector function f by loading YDOT(i) with f(i).
76 C B. Provide a subroutine of the form:
77 C SUBROUTINE G (NEQ, T, Y, NG, GOUT)
78 C DOUBLE PRECISION T, Y(*), GOUT(NG)
79 C which supplies the vector function g by loading GOUT(i) with
80 C g(i), the i-th constraint function whose root is sought.
82 C C. Write a main program which calls Subroutine DLSODAR once for
83 C each point at which answers are desired. This should also provide
84 C for possible use of logical unit 6 for output of error messages by
85 C DLSODAR. On the first call to DLSODAR, supply arguments as follows:
86 C F = name of subroutine for right-hand side vector f.
87 C This name must be declared External in calling program.
88 C NEQ = number of first order ODEs.
89 C Y = array of initial values, of length NEQ.
90 C T = the initial value of the independent variable.
91 C TOUT = first point where output is desired (.ne. T).
92 C ITOL = 1 or 2 according as ATOL (below) is a scalar or array.
93 C RTOL = relative tolerance parameter (scalar).
94 C ATOL = absolute tolerance parameter (scalar or array).
95 C the estimated local error in y(i) will be controlled so as
97 C EWT(i) = RTOL*ABS(Y(i)) + ATOL if ITOL = 1, or
98 C EWT(i) = RTOL*ABS(Y(i)) + ATOL(i) if ITOL = 2.
99 C Thus the local error test passes if, in each component,
100 C either the absolute error is less than ATOL (or ATOL(i)),
101 C or the relative error is less than RTOL.
102 C Use RTOL = 0.0 for pure absolute error control, and
103 C use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative error
104 C control. Caution: actual (global) errors may exceed these
105 C local tolerances, so choose them conservatively.
106 C ITASK = 1 for normal computation of output values of y at t = TOUT.
107 C ISTATE = integer flag (input and output). Set ISTATE = 1.
108 C IOPT = 0 to indicate no optional inputs used.
109 C RWORK = real work array of length at least:
110 C 22 + NEQ * MAX(16, NEQ + 9) + 3*NG.
111 C See also Paragraph F below.
112 C LRW = declared length of RWORK (in user's dimension).
113 C IWORK = integer work array of length at least 20 + NEQ.
114 C LIW = declared length of IWORK (in user's dimension).
115 C JAC = name of subroutine for Jacobian matrix.
116 C Use a dummy name. See also Paragraph F below.
117 C JT = Jacobian type indicator. Set JT = 2.
118 C See also Paragraph F below.
119 C G = name of subroutine for constraint functions, whose
120 C roots are desired during the integration.
121 C This name must be declared External in calling program.
122 C NG = number of constraint functions g(i). If there are none,
123 C set NG = 0, and pass a dummy name for G.
124 C JROOT = integer array of length NG for output of root information.
125 C See next paragraph.
126 C Note that the main program must declare arrays Y, RWORK, IWORK,
127 C JROOT, and possibly ATOL.
129 C D. The output from the first call (or any call) is:
130 C Y = array of computed values of y(t) vector.
131 C T = corresponding value of independent variable. This is
132 C TOUT if ISTATE = 2, or the root location if ISTATE = 3,
133 C or the farthest point reached if DLSODAR was unsuccessful.
134 C ISTATE = 2 or 3 if DLSODAR was successful, negative otherwise.
135 C 2 means no root was found, and TOUT was reached as desired.
136 C 3 means a root was found prior to reaching TOUT.
137 C -1 means excess work done on this call (perhaps wrong JT).
138 C -2 means excess accuracy requested (tolerances too small).
139 C -3 means illegal input detected (see printed message).
140 C -4 means repeated error test failures (check all inputs).
141 C -5 means repeated convergence failures (perhaps bad Jacobian
142 C supplied or wrong choice of JT or tolerances).
143 C -6 means error weight became zero during problem. (Solution
144 C component i vanished, and ATOL or ATOL(i) = 0.)
145 C -7 means work space insufficient to finish (see messages).
146 C JROOT = array showing roots found if ISTATE = 3 on return.
147 C JROOT(i) = 1 if g(i) has a root at t, or 0 otherwise.
149 C E. To continue the integration after a successful return, proceed
151 C (a) If ISTATE = 2 on return, reset TOUT and call DLSODAR again.
152 C (b) If ISTATE = 3 on return, reset ISTATE to 2, call DLSODAR again.
153 C In either case, no other parameters need be reset.
155 C F. Note: If and when DLSODAR regards the problem as stiff, and
156 C switches methods accordingly, it must make use of the NEQ by NEQ
157 C Jacobian matrix, J = df/dy. For the sake of simplicity, the
158 C inputs to DLSODAR recommended in Paragraph C above cause DLSODAR to
159 C treat J as a full matrix, and to approximate it internally by
160 C difference quotients. Alternatively, J can be treated as a band
161 C matrix (with great potential reduction in the size of the RWORK
162 C array). Also, in either the full or banded case, the user can supply
163 C J in closed form, with a routine whose name is passed as the JAC
164 C argument. These alternatives are described in the paragraphs on
165 C RWORK, JAC, and JT in the full description of the call sequence below.
167 C-----------------------------------------------------------------------
170 C The following is a simple example problem, with the coding
171 C needed for its solution by DLSODAR. The problem is from chemical
172 C kinetics, and consists of the following three rate equations:
173 C dy1/dt = -.04*y1 + 1.e4*y2*y3
174 C dy2/dt = .04*y1 - 1.e4*y2*y3 - 3.e7*y2**2
175 C dy3/dt = 3.e7*y2**2
176 C on the interval from t = 0.0 to t = 4.e10, with initial conditions
177 C y1 = 1.0, y2 = y3 = 0. The problem is stiff.
178 C In addition, we want to find the values of t, y1, y2, and y3 at which
179 C (1) y1 reaches the value 1.e-4, and
180 C (2) y3 reaches the value 1.e-2.
182 C The following coding solves this problem with DLSODAR,
183 C printing results at t = .4, 4., ..., 4.e10, and at the computed
184 C roots. It uses ITOL = 2 and ATOL much smaller for y2 than y1 or y3
185 C because y2 has much smaller values.
186 C At the end of the run, statistical quantities of interest are
187 C printed (see optional outputs in the full description below).
190 C DOUBLE PRECISION ATOL, RTOL, RWORK, T, TOUT, Y
191 C DIMENSION Y(3), ATOL(3), RWORK(76), IWORK(23), JROOT(2)
211 C 10 CALL DLSODAR(FEX,NEQ,Y,T,TOUT,ITOL,RTOL,ATOL,ITASK,ISTATE,
212 C 1 IOPT,RWORK,LRW,IWORK,LIW,JDUM,JT,GEX,NG,JROOT)
213 C WRITE(6,20)T,Y(1),Y(2),Y(3)
214 C 20 FORMAT(' At t =',D12.4,' Y =',3D14.6)
215 C IF (ISTATE .LT. 0) GO TO 80
216 C IF (ISTATE .EQ. 2) GO TO 40
217 C WRITE(6,30)JROOT(1),JROOT(2)
218 C 30 FORMAT(5X,' The above line is a root, JROOT =',2I5)
222 C WRITE(6,60)IWORK(11),IWORK(12),IWORK(13),IWORK(10),
223 C 1 IWORK(19),RWORK(15)
224 C 60 FORMAT(/' No. steps =',I4,' No. f-s =',I4,' No. J-s =',I4,
226 C 2 ' Method last used =',I2,' Last switch was at t =',D12.4)
228 C 80 WRITE(6,90)ISTATE
229 C 90 FORMAT(///' Error halt.. ISTATE =',I3)
233 C SUBROUTINE FEX (NEQ, T, Y, YDOT)
234 C DOUBLE PRECISION T, Y, YDOT
235 C DIMENSION Y(3), YDOT(3)
236 C YDOT(1) = -.04*Y(1) + 1.D4*Y(2)*Y(3)
237 C YDOT(3) = 3.D7*Y(2)*Y(2)
238 C YDOT(2) = -YDOT(1) - YDOT(3)
242 C SUBROUTINE GEX (NEQ, T, Y, NG, GOUT)
243 C DOUBLE PRECISION T, Y, GOUT
244 C DIMENSION Y(3), GOUT(2)
245 C GOUT(1) = Y(1) - 1.D-4
246 C GOUT(2) = Y(3) - 1.D-2
250 C The output of this program (on a CDC-7600 in single precision)
253 C At t = 2.6400e-01 y = 9.899653e-01 3.470563e-05 1.000000e-02
254 C The above line is a root, JROOT = 0 1
255 C At t = 4.0000e-01 Y = 9.851712e-01 3.386380e-05 1.479493e-02
256 C At t = 4.0000e+00 Y = 9.055333e-01 2.240655e-05 9.444430e-02
257 C At t = 4.0000e+01 Y = 7.158403e-01 9.186334e-06 2.841505e-01
258 C At t = 4.0000e+02 Y = 4.505250e-01 3.222964e-06 5.494717e-01
259 C At t = 4.0000e+03 Y = 1.831975e-01 8.941774e-07 8.168016e-01
260 C At t = 4.0000e+04 Y = 3.898730e-02 1.621940e-07 9.610125e-01
261 C At t = 4.0000e+05 Y = 4.936363e-03 1.984221e-08 9.950636e-01
262 C At t = 4.0000e+06 Y = 5.161831e-04 2.065786e-09 9.994838e-01
263 C At t = 2.0745e+07 Y = 1.000000e-04 4.000395e-10 9.999000e-01
264 C The above line is a root, JROOT = 1 0
265 C At t = 4.0000e+07 Y = 5.179817e-05 2.072032e-10 9.999482e-01
266 C At t = 4.0000e+08 Y = 5.283401e-06 2.113371e-11 9.999947e-01
267 C At t = 4.0000e+09 Y = 4.659031e-07 1.863613e-12 9.999995e-01
268 C At t = 4.0000e+10 Y = 1.404280e-08 5.617126e-14 1.000000e+00
270 C No. steps = 361 No. f-s = 693 No. J-s = 64 No. g-s = 390
271 C Method last used = 2 Last switch was at t = 6.0092e-03
273 C-----------------------------------------------------------------------
274 C Full Description of User Interface to DLSODAR.
276 C The user interface to DLSODAR consists of the following parts.
278 C 1. The call sequence to Subroutine DLSODAR, which is a driver
279 C routine for the solver. This includes descriptions of both
280 C the call sequence arguments and of user-supplied routines.
281 C Following these descriptions is a description of
282 C optional inputs available through the call sequence, and then
283 C a description of optional outputs (in the work arrays).
285 C 2. Descriptions of other routines in the DLSODAR package that may be
286 C (optionally) called by the user. These provide the ability to
287 C alter error message handling, save and restore the internal
288 C Common, and obtain specified derivatives of the solution y(t).
290 C 3. Descriptions of Common blocks to be declared in overlay
291 C or similar environments, or to be saved when doing an interrupt
292 C of the problem and continued solution later.
294 C 4. Description of a subroutine in the DLSODAR package,
295 C which the user may replace with his/her own version, if desired.
296 C this relates to the measurement of errors.
298 C-----------------------------------------------------------------------
299 C Part 1. Call Sequence.
301 C The call sequence parameters used for input only are
302 C F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC,
304 C that used only for output is JROOT,
305 C and those used for both input and output are
307 C The work arrays RWORK and IWORK are also used for conditional and
308 C optional inputs and optional outputs. (The term output here refers
309 C to the return from Subroutine DLSODAR to the user's calling program.)
311 C The legality of input parameters will be thoroughly checked on the
312 C initial call for the problem, but not checked thereafter unless a
313 C change in input parameters is flagged by ISTATE = 3 on input.
315 C The descriptions of the call arguments are as follows.
317 C F = the name of the user-supplied subroutine defining the
318 C ODE system. The system must be put in the first-order
319 C form dy/dt = f(t,y), where f is a vector-valued function
320 C of the scalar t and the vector y. Subroutine F is to
321 C compute the function f. It is to have the form
322 C SUBROUTINE F (NEQ, T, Y, YDOT)
323 C DOUBLE PRECISION T, Y(*), YDOT(*)
324 C where NEQ, T, and Y are input, and the array YDOT = f(t,y)
325 C is output. Y and YDOT are arrays of length NEQ.
326 C Subroutine F should not alter Y(1),...,Y(NEQ).
327 C F must be declared External in the calling program.
329 C Subroutine F may access user-defined quantities in
330 C NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
331 C (dimensioned in F) and/or Y has length exceeding NEQ(1).
332 C See the descriptions of NEQ and Y below.
334 C If quantities computed in the F routine are needed
335 C externally to DLSODAR, an extra call to F should be made
336 C for this purpose, for consistent and accurate results.
337 C If only the derivative dy/dt is needed, use DINTDY instead.
339 C NEQ = the size of the ODE system (number of first order
340 C ordinary differential equations). Used only for input.
341 C NEQ may be decreased, but not increased, during the problem.
342 C If NEQ is decreased (with ISTATE = 3 on input), the
343 C remaining components of Y should be left undisturbed, if
344 C these are to be accessed in F and/or JAC.
346 C Normally, NEQ is a scalar, and it is generally referred to
347 C as a scalar in this user interface description. However,
348 C NEQ may be an array, with NEQ(1) set to the system size.
349 C (The DLSODAR package accesses only NEQ(1).) In either case,
350 C this parameter is passed as the NEQ argument in all calls
351 C to F, JAC, and G. Hence, if it is an array, locations
352 C NEQ(2),... may be used to store other integer data and pass
353 C it to F, JAC, and G. Each such subroutine must include
354 C NEQ in a Dimension statement in that case.
356 C Y = a real array for the vector of dependent variables, of
357 C length NEQ or more. Used for both input and output on the
358 C first call (ISTATE = 1), and only for output on other calls.
359 C On the first call, Y must contain the vector of initial
360 C values. On output, Y contains the computed solution vector,
361 C evaluated at T. If desired, the Y array may be used
362 C for other purposes between calls to the solver.
364 C This array is passed as the Y argument in all calls to F,
365 C JAC, and G. Hence its length may exceed NEQ, and locations
366 C Y(NEQ+1),... may be used to store other real data and
367 C pass it to F, JAC, and G. (The DLSODAR package accesses only
370 C T = the independent variable. On input, T is used only on the
371 C first call, as the initial point of the integration.
372 C On output, after each call, T is the value at which a
373 C computed solution y is evaluated (usually the same as TOUT).
374 C If a root was found, T is the computed location of the
375 C root reached first, on output.
376 C On an error return, T is the farthest point reached.
378 C TOUT = the next value of t at which a computed solution is desired.
379 C Used only for input.
381 C When starting the problem (ISTATE = 1), TOUT may be equal
382 C to T for one call, then should .ne. T for the next call.
383 C For the initial T, an input value of TOUT .ne. T is used
384 C in order to determine the direction of the integration
385 C (i.e. the algebraic sign of the step sizes) and the rough
386 C scale of the problem. Integration in either direction
387 C (forward or backward in t) is permitted.
389 C If ITASK = 2 or 5 (one-step modes), TOUT is ignored after
390 C the first call (i.e. the first call with TOUT .ne. T).
391 C Otherwise, TOUT is required on every call.
393 C If ITASK = 1, 3, or 4, the values of TOUT need not be
394 C monotone, but a value of TOUT which backs up is limited
395 C to the current internal T interval, whose endpoints are
396 C TCUR - HU and TCUR (see optional outputs, below, for
399 C ITOL = an indicator for the type of error control. See
400 C description below under ATOL. Used only for input.
402 C RTOL = a relative error tolerance parameter, either a scalar or
403 C an array of length NEQ. See description below under ATOL.
406 C ATOL = an absolute error tolerance parameter, either a scalar or
407 C an array of length NEQ. Input only.
409 C The input parameters ITOL, RTOL, and ATOL determine
410 C the error control performed by the solver. The solver will
411 C control the vector E = (E(i)) of estimated local errors
412 C in y, according to an inequality of the form
413 C max-norm of ( E(i)/EWT(i) ) .le. 1,
414 C where EWT = (EWT(i)) is a vector of positive error weights.
415 C The values of RTOL and ATOL should all be non-negative.
416 C The following table gives the types (scalar/array) of
417 C RTOL and ATOL, and the corresponding form of EWT(i).
419 C ITOL RTOL ATOL EWT(i)
420 C 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
421 C 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
422 C 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
423 C 4 array array RTOL(i)*ABS(Y(i)) + ATOL(i)
425 C When either of these parameters is a scalar, it need not
426 C be dimensioned in the user's calling program.
428 C If none of the above choices (with ITOL, RTOL, and ATOL
429 C fixed throughout the problem) is suitable, more general
430 C error controls can be obtained by substituting a
431 C user-supplied routine for the setting of EWT.
434 C If global errors are to be estimated by making a repeated
435 C run on the same problem with smaller tolerances, then all
436 C components of RTOL and ATOL (i.e. of EWT) should be scaled
439 C ITASK = an index specifying the task to be performed.
440 C input only. ITASK has the following values and meanings.
441 C 1 means normal computation of output values of y(t) at
442 C t = TOUT (by overshooting and interpolating).
443 C 2 means take one step only and return.
444 C 3 means stop at the first internal mesh point at or
445 C beyond t = TOUT and return.
446 C 4 means normal computation of output values of y(t) at
447 C t = TOUT but without overshooting t = TCRIT.
448 C TCRIT must be input as RWORK(1). TCRIT may be equal to
449 C or beyond TOUT, but not behind it in the direction of
450 C integration. This option is useful if the problem
451 C has a singularity at or beyond t = TCRIT.
452 C 5 means take one step, without passing TCRIT, and return.
453 C TCRIT must be input as RWORK(1).
455 C Note: If ITASK = 4 or 5 and the solver reaches TCRIT
456 C (within roundoff), it will return T = TCRIT (exactly) to
457 C indicate this (unless ITASK = 4 and TOUT comes before TCRIT,
458 C in which case answers at t = TOUT are returned first).
460 C ISTATE = an index used for input and output to specify the
461 C the state of the calculation.
463 C On input, the values of ISTATE are as follows.
464 C 1 means this is the first call for the problem
465 C (initializations will be done). See note below.
466 C 2 means this is not the first call, and the calculation
467 C is to continue normally, with no change in any input
468 C parameters except possibly TOUT and ITASK.
469 C (If ITOL, RTOL, and/or ATOL are changed between calls
470 C with ISTATE = 2, the new values will be used but not
471 C tested for legality.)
472 C 3 means this is not the first call, and the
473 C calculation is to continue normally, but with
474 C a change in input parameters other than
475 C TOUT and ITASK. Changes are allowed in
476 C NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, JT, ML, MU,
477 C and any optional inputs except H0, MXORDN, and MXORDS.
478 C (See IWORK description for ML and MU.)
479 C In addition, immediately following a return with
480 C ISTATE = 3 (root found), NG and G may be changed.
481 C (But changing NG from 0 to .gt. 0 is not allowed.)
482 C Note: A preliminary call with TOUT = T is not counted
483 C as a first call here, as no initialization or checking of
484 C input is done. (Such a call is sometimes useful for the
485 C purpose of outputting the initial conditions.)
486 C Thus the first call for which TOUT .ne. T requires
487 C ISTATE = 1 on input.
489 C On output, ISTATE has the following values and meanings.
490 C 1 means nothing was done; TOUT = t and ISTATE = 1 on input.
491 C 2 means the integration was performed successfully, and
492 C no roots were found.
493 C 3 means the integration was successful, and one or more
494 C roots were found before satisfying the stop condition
495 C specified by ITASK. See JROOT.
496 C -1 means an excessive amount of work (more than MXSTEP
497 C steps) was done on this call, before completing the
498 C requested task, but the integration was otherwise
499 C successful as far as T. (MXSTEP is an optional input
500 C and is normally 500.) To continue, the user may
501 C simply reset ISTATE to a value .gt. 1 and call again
502 C (the excess work step counter will be reset to 0).
503 C In addition, the user may increase MXSTEP to avoid
504 C this error return (see below on optional inputs).
505 C -2 means too much accuracy was requested for the precision
506 C of the machine being used. This was detected before
507 C completing the requested task, but the integration
508 C was successful as far as T. To continue, the tolerance
509 C parameters must be reset, and ISTATE must be set
510 C to 3. The optional output TOLSF may be used for this
511 C purpose. (Note: If this condition is detected before
512 C taking any steps, then an illegal input return
513 C (ISTATE = -3) occurs instead.)
514 C -3 means illegal input was detected, before taking any
515 C integration steps. See written message for details.
516 C Note: If the solver detects an infinite loop of calls
517 C to the solver with illegal input, it will cause
519 C -4 means there were repeated error test failures on
520 C one attempted step, before completing the requested
521 C task, but the integration was successful as far as T.
522 C The problem may have a singularity, or the input
523 C may be inappropriate.
524 C -5 means there were repeated convergence test failures on
525 C one attempted step, before completing the requested
526 C task, but the integration was successful as far as T.
527 C This may be caused by an inaccurate Jacobian matrix,
528 C if one is being used.
529 C -6 means EWT(i) became zero for some i during the
530 C integration. Pure relative error control (ATOL(i)=0.0)
531 C was requested on a variable which has now vanished.
532 C The integration was successful as far as T.
533 C -7 means the length of RWORK and/or IWORK was too small to
534 C proceed, but the integration was successful as far as T.
535 C This happens when DLSODAR chooses to switch methods
536 C but LRW and/or LIW is too small for the new method.
538 C Note: Since the normal output value of ISTATE is 2,
539 C it does not need to be reset for normal continuation.
540 C Also, since a negative input value of ISTATE will be
541 C regarded as illegal, a negative output value requires the
542 C user to change it, and possibly other inputs, before
543 C calling the solver again.
545 C IOPT = an integer flag to specify whether or not any optional
546 C inputs are being used on this call. Input only.
547 C The optional inputs are listed separately below.
548 C IOPT = 0 means no optional inputs are being used.
549 C Default values will be used in all cases.
550 C IOPT = 1 means one or more optional inputs are being used.
552 C RWORK = a real array (double precision) for work space, and (in the
553 C first 20 words) for conditional and optional inputs and
555 C As DLSODAR switches automatically between stiff and nonstiff
556 C methods, the required length of RWORK can change during the
557 C problem. Thus the RWORK array passed to DLSODAR can either
558 C have a static (fixed) length large enough for both methods,
559 C or have a dynamic (changing) length altered by the calling
560 C program in response to output from DLSODAR.
562 C --- Fixed Length Case ---
563 C If the RWORK length is to be fixed, it should be at least
565 C where LRN and LRS are the RWORK lengths required when the
566 C current method is nonstiff or stiff, respectively.
568 C The separate RWORK length requirements LRN and LRS are
570 C If NEQ is constant and the maximum method orders have
571 C their default values, then
572 C LRN = 20 + 16*NEQ + 3*NG,
573 C LRS = 22 + 9*NEQ + NEQ**2 + 3*NG (JT = 1 or 2),
574 C LRS = 22 + 10*NEQ + (2*ML+MU)*NEQ + 3*NG (JT = 4 or 5).
575 C Under any other conditions, LRN and LRS are given by:
576 C LRN = 20 + NYH*(MXORDN+1) + 3*NEQ + 3*NG,
577 C LRS = 20 + NYH*(MXORDS+1) + 3*NEQ + LMAT + 3*NG,
579 C NYH = the initial value of NEQ,
580 C MXORDN = 12, unless a smaller value is given as an
582 C MXORDS = 5, unless a smaller value is given as an
584 C LMAT = length of matrix work space:
585 C LMAT = NEQ**2 + 2 if JT = 1 or 2,
586 C LMAT = (2*ML + MU + 1)*NEQ + 2 if JT = 4 or 5.
588 C --- Dynamic Length Case ---
589 C If the length of RWORK is to be dynamic, then it should
590 C be at least LRN or LRS, as defined above, depending on the
591 C current method. Initially, it must be at least LRN (since
592 C DLSODAR starts with the nonstiff method). On any return
593 C from DLSODAR, the optional output MCUR indicates the current
594 C method. If MCUR differs from the value it had on the
595 C previous return, or if there has only been one call to
596 C DLSODAR and MCUR is now 2, then DLSODAR has switched
597 C methods during the last call, and the length of RWORK
598 C should be reset (to LRN if MCUR = 1, or to LRS if
599 C MCUR = 2). (An increase in the RWORK length is required
600 C if DLSODAR returned ISTATE = -7, but not otherwise.)
601 C After resetting the length, call DLSODAR with ISTATE = 3
602 C to signal that change.
604 C LRW = the length of the array RWORK, as declared by the user.
605 C (This will be checked by the solver.)
607 C IWORK = an integer array for work space.
608 C As DLSODAR switches automatically between stiff and nonstiff
609 C methods, the required length of IWORK can change during
611 C LIS = 20 + NEQ and LIN = 20,
612 C respectively. Thus the IWORK array passed to DLSODAR can
613 C either have a fixed length of at least 20 + NEQ, or have a
614 C dynamic length of at least LIN or LIS, depending on the
615 C current method. The comments on dynamic length under
616 C RWORK above apply here. Initially, this length need
617 C only be at least LIN = 20.
619 C The first few words of IWORK are used for conditional and
620 C optional inputs and optional outputs.
622 C The following 2 words in IWORK are conditional inputs:
623 C IWORK(1) = ML These are the lower and upper
624 C IWORK(2) = MU half-bandwidths, respectively, of the
625 C banded Jacobian, excluding the main diagonal.
626 C The band is defined by the matrix locations
627 C (i,j) with i-ML .le. j .le. i+MU. ML and MU
628 C must satisfy 0 .le. ML,MU .le. NEQ-1.
629 C These are required if JT is 4 or 5, and
630 C ignored otherwise. ML and MU may in fact be
631 C the band parameters for a matrix to which
632 C df/dy is only approximately equal.
634 C LIW = the length of the array IWORK, as declared by the user.
635 C (This will be checked by the solver.)
637 C Note: The base addresses of the work arrays must not be
638 C altered between calls to DLSODAR for the same problem.
639 C The contents of the work arrays must not be altered
640 C between calls, except possibly for the conditional and
641 C optional inputs, and except for the last 3*NEQ words of RWORK.
642 C The latter space is used for internal scratch space, and so is
643 C available for use by the user outside DLSODAR between calls, if
644 C desired (but not for use by F, JAC, or G).
646 C JAC = the name of the user-supplied routine to compute the
647 C Jacobian matrix, df/dy, if JT = 1 or 4. The JAC routine
648 C is optional, but if the problem is expected to be stiff much
649 C of the time, you are encouraged to supply JAC, for the sake
650 C of efficiency. (Alternatively, set JT = 2 or 5 to have
651 C DLSODAR compute df/dy internally by difference quotients.)
652 C If and when DLSODAR uses df/dy, it treats this NEQ by NEQ
653 C matrix either as full (JT = 1 or 2), or as banded (JT =
654 C 4 or 5) with half-bandwidths ML and MU (discussed under
655 C IWORK above). In either case, if JT = 1 or 4, the JAC
656 C routine must compute df/dy as a function of the scalar t
657 C and the vector y. It is to have the form
658 C SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD)
659 C DOUBLE PRECISION T, Y(*), PD(NROWPD,*)
660 C where NEQ, T, Y, ML, MU, and NROWPD are input and the array
661 C PD is to be loaded with partial derivatives (elements of
662 C the Jacobian matrix) on output. PD must be given a first
663 C dimension of NROWPD. T and Y have the same meaning as in
665 C In the full matrix case (JT = 1), ML and MU are
666 C ignored, and the Jacobian is to be loaded into PD in
667 C columnwise manner, with df(i)/dy(j) loaded into pd(i,j).
668 C In the band matrix case (JT = 4), the elements
669 C within the band are to be loaded into PD in columnwise
670 C manner, with diagonal lines of df/dy loaded into the rows
671 C of PD. Thus df(i)/dy(j) is to be loaded into PD(i-j+MU+1,j).
672 C ML and MU are the half-bandwidth parameters (see IWORK).
673 C The locations in PD in the two triangular areas which
674 C correspond to nonexistent matrix elements can be ignored
675 C or loaded arbitrarily, as they are overwritten by DLSODAR.
676 C JAC need not provide df/dy exactly. A crude
677 C approximation (possibly with a smaller bandwidth) will do.
678 C In either case, PD is preset to zero by the solver,
679 C so that only the nonzero elements need be loaded by JAC.
680 C Each call to JAC is preceded by a call to F with the same
681 C arguments NEQ, T, and Y. Thus to gain some efficiency,
682 C intermediate quantities shared by both calculations may be
683 C saved in a user Common block by F and not recomputed by JAC,
684 C if desired. Also, JAC may alter the Y array, if desired.
685 C JAC must be declared External in the calling program.
686 C Subroutine JAC may access user-defined quantities in
687 C NEQ(2),... and/or in Y(NEQ(1)+1),... if NEQ is an array
688 C (dimensioned in JAC) and/or Y has length exceeding NEQ(1).
689 C See the descriptions of NEQ and Y above.
691 C JT = Jacobian type indicator. Used only for input.
692 C JT specifies how the Jacobian matrix df/dy will be
693 C treated, if and when DLSODAR requires this matrix.
694 C JT has the following values and meanings:
695 C 1 means a user-supplied full (NEQ by NEQ) Jacobian.
696 C 2 means an internally generated (difference quotient) full
697 C Jacobian (using NEQ extra calls to F per df/dy value).
698 C 4 means a user-supplied banded Jacobian.
699 C 5 means an internally generated banded Jacobian (using
700 C ML+MU+1 extra calls to F per df/dy evaluation).
701 C If JT = 1 or 4, the user must supply a Subroutine JAC
702 C (the name is arbitrary) as described above under JAC.
703 C If JT = 2 or 5, a dummy argument can be used.
705 C G = the name of subroutine for constraint functions, whose
706 C roots are desired during the integration. It is to have
708 C SUBROUTINE G (NEQ, T, Y, NG, GOUT)
709 C DOUBLE PRECISION T, Y(*), GOUT(NG)
710 C where NEQ, T, Y, and NG are input, and the array GOUT
711 C is output. NEQ, T, and Y have the same meaning as in
712 C the F routine, and GOUT is an array of length NG.
713 C For i = 1,...,NG, this routine is to load into GOUT(i)
714 C the value at (T,Y) of the i-th constraint function g(i).
715 C DLSODAR will find roots of the g(i) of odd multiplicity
716 C (i.e. sign changes) as they occur during the integration.
717 C G must be declared External in the calling program.
719 C Caution: Because of numerical errors in the functions
720 C g(i) due to roundoff and integration error, DLSODAR may
721 C return false roots, or return the same root at two or more
722 C nearly equal values of t. If such false roots are
723 C suspected, the user should consider smaller error tolerances
724 C and/or higher precision in the evaluation of the g(i).
726 C If a root of some g(i) defines the end of the problem,
727 C the input to DLSODAR should nevertheless allow integration
728 C to a point slightly past that root, so that DLSODAR can
729 C locate the root by interpolation.
731 C Subroutine G may access user-defined quantities in
732 C NEQ(2),... and Y(NEQ(1)+1),... if NEQ is an array
733 C (dimensioned in G) and/or Y has length exceeding NEQ(1).
734 C See the descriptions of NEQ and Y above.
736 C NG = number of constraint functions g(i). If there are none,
737 C set NG = 0, and pass a dummy name for G.
739 C JROOT = integer array of length NG. Used only for output.
740 C On a return with ISTATE = 3 (one or more roots found),
741 C JROOT(i) = 1 if g(i) has a root at T, or JROOT(i) = 0 if not.
742 C-----------------------------------------------------------------------
745 C The following is a list of the optional inputs provided for in the
746 C call sequence. (See also Part 2.) For each such input variable,
747 C this table lists its name as used in this documentation, its
748 C location in the call sequence, its meaning, and the default value.
749 C The use of any of these inputs requires IOPT = 1, and in that
750 C case all of these inputs are examined. A value of zero for any
751 C of these optional inputs will cause the default value to be used.
752 C Thus to use a subset of the optional inputs, simply preload
753 C locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, and
754 C then set those of interest to nonzero values.
756 C Name Location Meaning and Default Value
758 C H0 RWORK(5) the step size to be attempted on the first step.
759 C The default value is determined by the solver.
761 C HMAX RWORK(6) the maximum absolute step size allowed.
762 C The default value is infinite.
764 C HMIN RWORK(7) the minimum absolute step size allowed.
765 C The default value is 0. (This lower bound is not
766 C enforced on the final step before reaching TCRIT
767 C when ITASK = 4 or 5.)
769 C IXPR IWORK(5) flag to generate extra printing at method switches.
770 C IXPR = 0 means no extra printing (the default).
771 C IXPR = 1 means print data on each switch.
772 C T, H, and NST will be printed on the same logical
773 C unit as used for error messages.
775 C MXSTEP IWORK(6) maximum number of (internally defined) steps
776 C allowed during one call to the solver.
777 C The default value is 500.
779 C MXHNIL IWORK(7) maximum number of messages printed (per problem)
780 C warning that T + H = T on a step (H = step size).
781 C This must be positive to result in a non-default
782 C value. The default value is 10.
784 C MXORDN IWORK(8) the maximum order to be allowed for the nonstiff
785 C (Adams) method. The default value is 12.
786 C If MXORDN exceeds the default value, it will
787 C be reduced to the default value.
788 C MXORDN is held constant during the problem.
790 C MXORDS IWORK(9) the maximum order to be allowed for the stiff
791 C (BDF) method. The default value is 5.
792 C If MXORDS exceeds the default value, it will
793 C be reduced to the default value.
794 C MXORDS is held constant during the problem.
795 C-----------------------------------------------------------------------
798 C As optional additional output from DLSODAR, the variables listed
799 C below are quantities related to the performance of DLSODAR
800 C which are available to the user. These are communicated by way of
801 C the work arrays, but also have internal mnemonic names as shown.
802 C Except where stated otherwise, all of these outputs are defined
803 C on any successful return from DLSODAR, and on any return with
804 C ISTATE = -1, -2, -4, -5, or -6. On an illegal input return
805 C (ISTATE = -3), they will be unchanged from their existing values
806 C (if any), except possibly for TOLSF, LENRW, and LENIW.
807 C On any error return, outputs relevant to the error will be defined,
810 C Name Location Meaning
812 C HU RWORK(11) the step size in t last used (successfully).
814 C HCUR RWORK(12) the step size to be attempted on the next step.
816 C TCUR RWORK(13) the current value of the independent variable
817 C which the solver has actually reached, i.e. the
818 C current internal mesh point in t. On output, TCUR
819 C will always be at least as far as the argument
820 C T, but may be farther (if interpolation was done).
822 C TOLSF RWORK(14) a tolerance scale factor, greater than 1.0,
823 C computed when a request for too much accuracy was
824 C detected (ISTATE = -3 if detected at the start of
825 C the problem, ISTATE = -2 otherwise). If ITOL is
826 C left unaltered but RTOL and ATOL are uniformly
827 C scaled up by a factor of TOLSF for the next call,
828 C then the solver is deemed likely to succeed.
829 C (The user may also ignore TOLSF and alter the
830 C tolerance parameters in any other way appropriate.)
832 C TSW RWORK(15) the value of t at the time of the last method
835 C NGE IWORK(10) the number of g evaluations for the problem so far.
837 C NST IWORK(11) the number of steps taken for the problem so far.
839 C NFE IWORK(12) the number of f evaluations for the problem so far.
841 C NJE IWORK(13) the number of Jacobian evaluations (and of matrix
842 C LU decompositions) for the problem so far.
844 C NQU IWORK(14) the method order last used (successfully).
846 C NQCUR IWORK(15) the order to be attempted on the next step.
848 C IMXER IWORK(16) the index of the component of largest magnitude in
849 C the weighted local error vector ( E(i)/EWT(i) ),
850 C on an error return with ISTATE = -4 or -5.
852 C LENRW IWORK(17) the length of RWORK actually required, assuming
853 C that the length of RWORK is to be fixed for the
854 C rest of the problem, and that switching may occur.
855 C This is defined on normal returns and on an illegal
856 C input return for insufficient storage.
858 C LENIW IWORK(18) the length of IWORK actually required, assuming
859 C that the length of IWORK is to be fixed for the
860 C rest of the problem, and that switching may occur.
861 C This is defined on normal returns and on an illegal
862 C input return for insufficient storage.
864 C MUSED IWORK(19) the method indicator for the last successful step:
865 C 1 means Adams (nonstiff), 2 means BDF (stiff).
867 C MCUR IWORK(20) the current method indicator:
868 C 1 means Adams (nonstiff), 2 means BDF (stiff).
869 C This is the method to be attempted
870 C on the next step. Thus it differs from MUSED
871 C only if a method switch has just been made.
873 C The following two arrays are segments of the RWORK array which
874 C may also be of interest to the user as optional outputs.
875 C For each array, the table below gives its internal name,
876 C its base address in RWORK, and its description.
878 C Name Base Address Description
880 C YH 21 + 3*NG the Nordsieck history array, of size NYH by
881 C (NQCUR + 1), where NYH is the initial value
882 C of NEQ. For j = 0,1,...,NQCUR, column j+1
883 C of YH contains HCUR**j/factorial(j) times
884 C the j-th derivative of the interpolating
885 C polynomial currently representing the solution,
886 C evaluated at t = TCUR.
888 C ACOR LACOR array of size NEQ used for the accumulated
889 C (from Common corrections on each step, scaled on output
890 C as noted) to represent the estimated local error in y
891 C on the last step. This is the vector E in
892 C the description of the error control. It is
893 C defined only on a successful return from
894 C DLSODAR. The base address LACOR is obtained by
895 C including in the user's program the
897 C COMMON /DLS001/ RLS(218), ILS(37)
900 C-----------------------------------------------------------------------
901 C Part 2. Other Routines Callable.
903 C The following are optional calls which the user may make to
904 C gain additional capabilities in conjunction with DLSODAR.
905 C (The routines XSETUN and XSETF are designed to conform to the
906 C SLATEC error handling package.)
908 C Form of Call Function
909 C CALL XSETUN(LUN) Set the logical unit number, LUN, for
910 C output of messages from DLSODAR, if
911 C the default is not desired.
912 C The default value of LUN is 6.
914 C CALL XSETF(MFLAG) Set a flag to control the printing of
915 C messages by DLSODAR.
916 C MFLAG = 0 means do not print. (Danger:
917 C This risks losing valuable information.)
918 C MFLAG = 1 means print (the default).
920 C Either of the above calls may be made at
921 C any time and will take effect immediately.
923 C CALL DSRCAR(RSAV,ISAV,JOB) saves and restores the contents of
924 C the internal Common blocks used by
925 C DLSODAR (see Part 3 below).
926 C RSAV must be a real array of length 245
927 C or more, and ISAV must be an integer
928 C array of length 55 or more.
929 C JOB=1 means save Common into RSAV/ISAV.
930 C JOB=2 means restore Common from RSAV/ISAV.
931 C DSRCAR is useful if one is
932 C interrupting a run and restarting
933 C later, or alternating between two or
934 C more problems solved with DLSODAR.
936 C CALL DINTDY(,,,,,) Provide derivatives of y, of various
937 C (see below) orders, at a specified point t, if
938 C desired. It may be called only after
939 C a successful return from DLSODAR.
941 C The detailed instructions for using DINTDY are as follows.
942 C The form of the call is:
945 C CALL DINTDY (T, K, RWORK(LYH), NYH, DKY, IFLAG)
947 C The input parameters are:
949 C T = value of independent variable where answers are desired
950 C (normally the same as the T last returned by DLSODAR).
951 C For valid results, T must lie between TCUR - HU and TCUR.
952 C (See optional outputs for TCUR and HU.)
953 C K = integer order of the derivative desired. K must satisfy
954 C 0 .le. K .le. NQCUR, where NQCUR is the current order
955 C (see optional outputs). The capability corresponding
956 C to K = 0, i.e. computing y(t), is already provided
957 C by DLSODAR directly. Since NQCUR .ge. 1, the first
958 C derivative dy/dt is always available with DINTDY.
959 C LYH = 21 + 3*NG = base address in RWORK of the history array YH.
960 C NYH = column length of YH, equal to the initial value of NEQ.
962 C The output parameters are:
964 C DKY = a real array of length NEQ containing the computed value
965 C of the K-th derivative of y(t).
966 C IFLAG = integer flag, returned as 0 if K and T were legal,
967 C -1 if K was illegal, and -2 if T was illegal.
968 C On an error return, a message is also written.
969 C-----------------------------------------------------------------------
970 C Part 3. Common Blocks.
972 C If DLSODAR is to be used in an overlay situation, the user
973 C must declare, in the primary overlay, the variables in:
974 C (1) the call sequence to DLSODAR, and
975 C (2) the three internal Common blocks
976 C /DLS001/ of length 255 (218 double precision words
977 C followed by 37 integer words),
978 C /DLSA01/ of length 31 (22 double precision words
979 C followed by 9 integer words).
980 C /DLSR01/ of length 7 (3 double precision words
981 C followed by 4 integer words).
983 C If DLSODAR is used on a system in which the contents of internal
984 C Common blocks are not preserved between calls, the user should
985 C declare the above Common blocks in the calling program to insure
986 C that their contents are preserved.
988 C If the solution of a given problem by DLSODAR is to be interrupted
989 C and then later continued, such as when restarting an interrupted run
990 C or alternating between two or more problems, the user should save,
991 C following the return from the last DLSODAR call prior to the
992 C interruption, the contents of the call sequence variables and the
993 C internal Common blocks, and later restore these values before the
994 C next DLSODAR call for that problem. To save and restore the Common
995 C blocks, use Subroutine DSRCAR (see Part 2 above).
997 C-----------------------------------------------------------------------
998 C Part 4. Optionally Replaceable Solver Routines.
1000 C Below is a description of a routine in the DLSODAR package which
1001 C relates to the measurement of errors, and can be
1002 C replaced by a user-supplied version, if desired. However, since such
1003 C a replacement may have a major impact on performance, it should be
1004 C done only when absolutely necessary, and only with great caution.
1005 C (Note: The means by which the package version of a routine is
1006 C superseded by the user's version may be system-dependent.)
1009 C The following subroutine is called just before each internal
1010 C integration step, and sets the array of error weights, EWT, as
1011 C described under ITOL/RTOL/ATOL above:
1012 C Subroutine DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
1013 C where NEQ, ITOL, RTOL, and ATOL are as in the DLSODAR call sequence,
1014 C YCUR contains the current dependent variable vector, and
1015 C EWT is the array of weights set by DEWSET.
1017 C If the user supplies this subroutine, it must return in EWT(i)
1018 C (i = 1,...,NEQ) a positive quantity suitable for comparing errors
1019 C in y(i) to. The EWT array returned by DEWSET is passed to the
1020 C DMNORM routine, and also used by DLSODAR in the computation
1021 C of the optional output IMXER, and the increments for difference
1022 C quotient Jacobians.
1024 C In the user-supplied version of DEWSET, it may be desirable to use
1025 C the current values of derivatives of y. Derivatives up to order NQ
1026 C are available from the history array YH, described above under
1027 C optional outputs. In DEWSET, YH is identical to the YCUR array,
1028 C extended to NQ + 1 columns with a column length of NYH and scale
1029 C factors of H**j/factorial(j). On the first call for the problem,
1030 C given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
1031 C NYH is the initial value of NEQ. The quantities NQ, H, and NST
1032 C can be obtained by including in DEWSET the statements:
1033 C DOUBLE PRECISION RLS
1034 C COMMON /DLS001/ RLS(218),ILS(37)
1038 C Thus, for example, the current value of dy/dt can be obtained as
1039 C YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is
1040 C unnecessary when NST = 0).
1041 C-----------------------------------------------------------------------
1043 C***REVISION HISTORY (YYYYMMDD)
1044 C 19811102 DATE WRITTEN
1045 C 19820126 Fixed bug in tests of work space lengths;
1046 C minor corrections in main prologue and comments.
1047 C 19820507 Fixed bug in RCHEK in setting HMING.
1048 C 19870330 Major update: corrected comments throughout;
1049 C removed TRET from Common; rewrote EWSET with 4 loops;
1050 C fixed t test in INTDY; added Cray directives in STODA;
1051 C in STODA, fixed DELP init. and logic around PJAC call;
1052 C combined routines to save/restore Common;
1053 C passed LEVEL = 0 in error message calls (except run abort).
1054 C 19970225 Fixed lines setting JSTART = -2 in Subroutine LSODAR.
1055 C 20010425 Major update: convert source lines to upper case;
1056 C added *DECK lines; changed from 1 to * in dummy dimensions;
1057 C changed names R1MACH/D1MACH to RUMACH/DUMACH;
1058 C renamed routines for uniqueness across single/double prec.;
1059 C converted intrinsic names to generic form;
1060 C removed ILLIN and NTREP (data loaded) from Common;
1061 C removed all 'own' variables from Common;
1062 C changed error messages to quoted strings;
1063 C replaced XERRWV/XERRWD with 1993 revised version;
1064 C converted prologues, comments, error messages to mixed case;
1065 C numerous corrections to prologues and internal comments.
1066 C 20010507 Converted single precision source to double precision.
1067 C 20010613 Revised excess accuracy test (to match rest of ODEPACK).
1068 C 20010808 Fixed bug in DPRJA (matrix in DBNORM call).
1069 C 20020502 Corrected declarations in descriptions of user routines.
1070 C 20031105 Restored 'own' variables to Common blocks, to enable
1071 C interrupt/restart feature.
1072 C 20031112 Added SAVE statements for data-loaded constants.
1074 C-----------------------------------------------------------------------
1075 C Other routines in the DLSODAR package.
1077 C In addition to Subroutine DLSODAR, the DLSODAR package includes the
1078 C following subroutines and function routines:
1079 C DRCHEK does preliminary checking for roots, and serves as an
1080 C interface between Subroutine DLSODAR and Subroutine DROOTS.
1081 C DROOTS finds the leftmost root of a set of functions.
1082 C DINTDY computes an interpolated value of the y vector at t = TOUT.
1083 C DSTODA is the core integrator, which does one step of the
1084 C integration and the associated error control.
1085 C DCFODE sets all method coefficients and test constants.
1086 C DPRJA computes and preprocesses the Jacobian matrix J = df/dy
1087 C and the Newton iteration matrix P = I - h*l0*J.
1088 C DSOLSY manages solution of linear system in chord iteration.
1089 C DEWSET sets the error weight vector EWT before each step.
1090 C DMNORM computes the weighted max-norm of a vector.
1091 C DFNORM computes the norm of a full matrix consistent with the
1092 C weighted max-norm on vectors.
1093 C DBNORM computes the norm of a band matrix consistent with the
1094 C weighted max-norm on vectors.
1095 C DSRCAR is a user-callable routine to save and restore
1096 C the contents of the internal Common blocks.
1097 C DGEFA and DGESL are routines from LINPACK for solving full
1098 C systems of linear algebraic equations.
1099 C DGBFA and DGBSL are routines from LINPACK for solving banded
1101 C DCOPY is one of the basic linear algebra modules (BLAS).
1102 C DUMACH computes the unit roundoff in a machine-independent manner.
1103 C XERRWD, XSETUN, XSETF, IXSAV, and IUMACH handle the printing of all
1104 C error messages and warnings. XERRWD is machine-dependent.
1105 C Note: DMNORM, DFNORM, DBNORM, DUMACH, IXSAV, and IUMACH are
1106 C function routines. All the others are subroutines.
1108 C-----------------------------------------------------------------------
1109 EXTERNAL DPRJA
, DSOLSY
1110 DOUBLE PRECISION DUMACH
, DMNORM
1111 INTEGER INIT
, MXSTEP
, MXHNIL
, NHNIL
, NSLAST
, NYH
, IOWNS
,
1112 1 ICF
, IERPJ
, IERSL
, JCUR
, JSTART
, KFLAG
, L
,
1113 2 LYH
, LEWT
, LACOR
, LSAVF
, LWM
, LIWM
, METH
, MITER
,
1114 3 MAXORD
, MAXCOR
, MSBP
, MXNCF
, N
, NQ
, NST
, NFE
, NJE
, NQU
1115 INTEGER INSUFR
, INSUFI
, IXPR
, IOWNS2
, JTYP
, MUSED
, MXORDN
, MXORDS
1116 INTEGER LG0
, LG1
, LGX
, IOWNR3
, IRFND
, ITASKC
, NGC
, NGE
1117 INTEGER I
, I1
, I2
, IFLAG
, IMXER
, KGO
, LENIW
,
1118 1 LENRW
, LENWM
, LF0
, ML
, MORD
, MU
, MXHNL0
, MXSTP0
1119 INTEGER LEN1
, LEN1C
, LEN1N
, LEN1S
, LEN2
, LENIWC
, LENRWC
1120 INTEGER IRFP
, IRT
, LENYH
, LYHNEW
1121 DOUBLE PRECISION ROWNS
,
1122 1 CCMAX
, EL0
, H
, HMIN
, HMXI
, HU
, RC
, TN
, UROUND
1123 DOUBLE PRECISION TSW
, ROWNS2
, PDNORM
1124 DOUBLE PRECISION ROWNR3
, T0
, TLAST
, TOUTC
1125 DOUBLE PRECISION ATOLI
, AYI
, BIG
, EWTI
, H0
, HMAX
, HMX
, RH
, RTOLI
,
1126 1 TCRIT
, TDIST
, TNEXT
, TOL
, TOLSF
, TP
, SIZE
, SUM
, W0
1130 SAVE MORD
, MXSTP0
, MXHNL0
1131 C-----------------------------------------------------------------------
1132 C The following three internal Common blocks contain
1133 C (a) variables which are local to any subroutine but whose values must
1134 C be preserved between calls to the routine ("own" variables), and
1135 C (b) variables which are communicated between subroutines.
1136 C The block DLS001 is declared in subroutines DLSODAR, DINTDY, DSTODA,
1137 C DPRJA, and DSOLSY.
1138 C The block DLSA01 is declared in subroutines DLSODAR, DSTODA, DPRJA.
1139 C The block DLSR01 is declared in subroutines DLSODAR, DRCHEK, DROOTS.
1140 C Groups of variables are replaced by dummy arrays in the Common
1141 C declarations in routines where those variables are not used.
1142 C-----------------------------------------------------------------------
1143 COMMON /DLS001
/ ROWNS
(209),
1144 1 CCMAX
, EL0
, H
, HMIN
, HMXI
, HU
, RC
, TN
, UROUND
,
1145 2 INIT
, MXSTEP
, MXHNIL
, NHNIL
, NSLAST
, NYH
, IOWNS
(6),
1146 3 ICF
, IERPJ
, IERSL
, JCUR
, JSTART
, KFLAG
, L
,
1147 4 LYH
, LEWT
, LACOR
, LSAVF
, LWM
, LIWM
, METH
, MITER
,
1148 5 MAXORD
, MAXCOR
, MSBP
, MXNCF
, N
, NQ
, NST
, NFE
, NJE
, NQU
1150 COMMON /DLSA01
/ TSW
, ROWNS2
(20), PDNORM
,
1151 1 INSUFR
, INSUFI
, IXPR
, IOWNS2
(2), JTYP
, MUSED
, MXORDN
, MXORDS
1153 COMMON /DLSR01
/ ROWNR3
(2), T0
, TLAST
, TOUTC
,
1154 1 LG0
, LG1
, LGX
, IOWNR3
(2), IRFND
, ITASKC
, NGC
, NGE
1156 DATA MORD
(1),MORD
(2)/12,5/, MXSTP0
/500/, MXHNL0
/10/
1157 C-----------------------------------------------------------------------
1159 C This code block is executed on every call.
1160 C It tests ISTATE and ITASK for legality and branches appropriately.
1161 C If ISTATE .gt. 1 but the flag INIT shows that initialization has
1162 C not yet been done, an error return occurs.
1163 C If ISTATE = 1 and TOUT = T, return immediately.
1164 C-----------------------------------------------------------------------
1165 IF (ISTATE
.LT
. 1 .OR
. ISTATE
.GT
. 3) GO TO 601
1166 IF (ITASK
.LT
. 1 .OR
. ITASK
.GT
. 5) GO TO 602
1168 IF (ISTATE
.EQ
. 1) GO TO 10
1169 IF (INIT
.EQ
. 0) GO TO 603
1170 IF (ISTATE
.EQ
. 2) GO TO 200
1173 IF (TOUT
.EQ
. T
) RETURN
1174 C-----------------------------------------------------------------------
1176 C The next code block is executed for the initial call (ISTATE = 1),
1177 C or for a continuation call with parameter changes (ISTATE = 3).
1178 C It contains checking of all inputs and various initializations.
1180 C First check legality of the non-optional inputs NEQ, ITOL, IOPT,
1181 C JT, ML, MU, and NG.
1182 C-----------------------------------------------------------------------
1183 20 IF (NEQ
(1) .LE
. 0) GO TO 604
1184 IF (ISTATE
.EQ
. 1) GO TO 25
1185 IF (NEQ
(1) .GT
. N
) GO TO 605
1187 IF (ITOL
.LT
. 1 .OR
. ITOL
.GT
. 4) GO TO 606
1188 IF (IOPT
.LT
. 0 .OR
. IOPT
.GT
. 1) GO TO 607
1189 IF (JT
.EQ
. 3 .OR
. JT
.LT
. 1 .OR
. JT
.GT
. 5) GO TO 608
1191 IF (JT
.LE
. 2) GO TO 30
1194 IF (ML
.LT
. 0 .OR
. ML
.GE
. N
) GO TO 609
1195 IF (MU
.LT
. 0 .OR
. MU
.GE
. N
) GO TO 610
1197 IF (NG
.LT
. 0) GO TO 630
1198 IF (ISTATE
.EQ
. 1) GO TO 35
1199 IF (IRFND
.EQ
. 0 .AND
. NG
.NE
. NGC
) GO TO 631
1201 C Next process and check the optional inputs. --------------------------
1202 IF (IOPT
.EQ
. 1) GO TO 40
1208 IF (ISTATE
.NE
. 1) GO TO 60
1214 IF (IXPR
.LT
. 0 .OR
. IXPR
.GT
. 1) GO TO 611
1216 IF (MXSTEP
.LT
. 0) GO TO 612
1217 IF (MXSTEP
.EQ
. 0) MXSTEP
= MXSTP0
1219 IF (MXHNIL
.LT
. 0) GO TO 613
1220 IF (MXHNIL
.EQ
. 0) MXHNIL
= MXHNL0
1221 IF (ISTATE
.NE
. 1) GO TO 50
1224 IF (MXORDN
.LT
. 0) GO TO 628
1225 IF (MXORDN
.EQ
. 0) MXORDN
= 100
1226 MXORDN
= MIN
(MXORDN
,MORD
(1))
1228 IF (MXORDS
.LT
. 0) GO TO 629
1229 IF (MXORDS
.EQ
. 0) MXORDS
= 100
1230 MXORDS
= MIN
(MXORDS
,MORD
(2))
1231 IF ((TOUT
- T
)*H0
.LT
. 0.0D0
) GO TO 614
1233 IF (HMAX
.LT
. 0.0D0
) GO TO 615
1235 IF (HMAX
.GT
. 0.0D0
) HMXI
= 1.0D0
/HMAX
1237 IF (HMIN
.LT
. 0.0D0
) GO TO 616
1238 C-----------------------------------------------------------------------
1239 C Set work array pointers and check lengths LRW and LIW.
1240 C If ISTATE = 1, METH is initialized to 1 here to facilitate the
1241 C checking of work space lengths.
1242 C Pointers to segments of RWORK and IWORK are named by prefixing L to
1243 C the name of the segment. E.g., the segment YH starts at RWORK(LYH).
1244 C Segments of RWORK (in order) are denoted G0, G1, GX, YH, WM,
1246 C If the lengths provided are insufficient for the current method,
1247 C an error return occurs. This is treated as illegal input on the
1248 C first call, but as a problem interruption with ISTATE = -7 on a
1249 C continuation call. If the lengths are sufficient for the current
1250 C method but not for both methods, a warning message is sent.
1251 C-----------------------------------------------------------------------
1252 60 IF (ISTATE
.EQ
. 1) METH
= 1
1253 IF (ISTATE
.EQ
. 1) NYH
= N
1258 IF (ISTATE
.EQ
. 1) LYH
= LYHNEW
1259 IF (LYHNEW
.EQ
. LYH
) GO TO 62
1260 C If ISTATE = 3 and NG was changed, shift YH to its new location. ------
1262 IF (LRW
.LT
. LYHNEW
-1+LENYH
) GO TO 62
1264 IF (LYHNEW
.GT
. LYH
) I1
= -1
1265 CALL DCOPY
(LENYH
, RWORK
(LYH
), I1
, RWORK
(LYHNEW
), I1
)
1268 LEN1N
= LYHNEW
- 1 + (MXORDN
+ 1)*NYH
1269 LEN1S
= LYHNEW
- 1 + (MXORDS
+ 1)*NYH
1271 IF (JT
.LE
. 2) LENWM
= N*N
+ 2
1272 IF (JT
.GE
. 4) LENWM
= (2*ML
+ MU
+ 1)*N
+ 2
1273 LEN1S
= LEN1S
+ LENWM
1275 IF (METH
.EQ
. 2) LEN1C
= LEN1S
1276 LEN1
= MAX
(LEN1N
,LEN1S
)
1279 LENRWC
= LEN1C
+ LEN2
1284 IF (METH
.EQ
. 2) LENIWC
= LENIW
1286 IF (ISTATE
.EQ
. 1 .AND
. LRW
.LT
. LENRWC
) GO TO 617
1287 IF (ISTATE
.EQ
. 1 .AND
. LIW
.LT
. LENIWC
) GO TO 618
1288 IF (ISTATE
.EQ
. 3 .AND
. LRW
.LT
. LENRWC
) GO TO 550
1289 IF (ISTATE
.EQ
. 3 .AND
. LIW
.LT
. LENIWC
) GO TO 555
1292 IF (LRW
.GE
. LENRW
) GO TO 65
1295 MSG
='DLSODAR- Warning.. RWORK length is sufficient for now, but '
1296 CALL XERRWD
(MSG
, 60, 103, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1297 MSG
=' may not be later. Integration will proceed anyway. '
1298 CALL XERRWD
(MSG
, 60, 103, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1299 MSG
= ' Length needed is LENRW = I1, while LRW = I2.'
1300 CALL XERRWD
(MSG
, 50, 103, 0, 2, LENRW
, LRW
, 0, 0.0D0
, 0.0D0
)
1304 IF (LIW
.GE
. LENIW
) GO TO 70
1306 MSG
='DLSODAR- Warning.. IWORK length is sufficient for now, but '
1307 CALL XERRWD
(MSG
, 60, 104, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1308 MSG
=' may not be later. Integration will proceed anyway. '
1309 CALL XERRWD
(MSG
, 60, 104, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1310 MSG
= ' Length needed is LENIW = I1, while LIW = I2.'
1311 CALL XERRWD
(MSG
, 50, 104, 0, 2, LENIW
, LIW
, 0, 0.0D0
, 0.0D0
)
1313 C Check RTOL and ATOL for legality. ------------------------------------
1317 IF (ITOL
.GE
. 3) RTOLI
= RTOL
(I
)
1318 IF (ITOL
.EQ
. 2 .OR
. ITOL
.EQ
. 4) ATOLI
= ATOL
(I
)
1319 IF (RTOLI
.LT
. 0.0D0
) GO TO 619
1320 IF (ATOLI
.LT
. 0.0D0
) GO TO 620
1322 IF (ISTATE
.EQ
. 1) GO TO 100
1323 C if ISTATE = 3, set flag to signal parameter changes to DSTODA. -------
1325 IF (N
.EQ
. NYH
) GO TO 200
1326 C NEQ was reduced. zero part of yh to avoid undefined references. -----
1328 I2
= LYH
+ (MAXORD
+ 1)*NYH
- 1
1329 IF (I1
.GT
. I2
) GO TO 200
1333 C-----------------------------------------------------------------------
1335 C The next block is for the initial call only (ISTATE = 1).
1336 C It contains all remaining initializations, the initial call to F,
1337 C and the calculation of the initial step size.
1338 C The error weights in EWT are inverted after being loaded.
1339 C-----------------------------------------------------------------------
1340 100 UROUND
= DUMACH
()
1344 IF (ITASK
.NE
. 4 .AND
. ITASK
.NE
. 5) GO TO 110
1346 IF ((TCRIT
- TOUT
)*(TOUT
- T
) .LT
. 0.0D0
) GO TO 625
1347 IF (H0
.NE
. 0.0D0
.AND
. (T
+ H0
- TCRIT
)*H0
.GT
. 0.0D0
)
1362 C Initial call to F. (LF0 points to YH(*,2).) -------------------------
1364 CALL F
(NEQ
, T
, Y
, RWORK
(LF0
))
1366 C Load the initial value vector in YH. ---------------------------------
1368 115 RWORK
(I
+LYH
-1) = Y
(I
)
1369 C Load and invert the EWT array. (H is temporarily set to 1.0.) -------
1372 CALL DEWSET
(N
, ITOL
, RTOL
, ATOL
, RWORK
(LYH
), RWORK
(LEWT
))
1374 IF (RWORK
(I
+LEWT
-1) .LE
. 0.0D0
) GO TO 621
1375 120 RWORK
(I
+LEWT
-1) = 1.0D0
/RWORK
(I
+LEWT
-1)
1376 C-----------------------------------------------------------------------
1377 C The coding below computes the step size, H0, to be attempted on the
1378 C first step, unless the user has supplied a value for this.
1379 C First check that TOUT - T differs significantly from zero.
1380 C A scalar tolerance quantity TOL is computed, as MAX(RTOL(i))
1381 C if this is positive, or MAX(ATOL(i)/ABS(Y(i))) otherwise, adjusted
1382 C so as to be between 100*UROUND and 1.0E-3.
1383 C Then the computed value H0 is given by:
1385 C H0**(-2) = 1./(TOL * w0**2) + TOL * (norm(F))**2
1387 C where w0 = MAX ( ABS(T), ABS(TOUT) ),
1388 C F = the initial value of the vector f(t,y), and
1389 C norm() = the weighted vector norm used throughout, given by
1390 C the DMNORM function routine, and weighted by the
1391 C tolerances initially loaded into the EWT array.
1392 C The sign of H0 is inferred from the initial values of TOUT and T.
1393 C ABS(H0) is made .le. ABS(TOUT-T) in any case.
1394 C-----------------------------------------------------------------------
1395 IF (H0
.NE
. 0.0D0
) GO TO 180
1396 TDIST
= ABS
(TOUT
- T
)
1397 W0
= MAX
(ABS
(T
),ABS
(TOUT
))
1398 IF (TDIST
.LT
. 2.0D0*UROUND*W0
) GO TO 622
1400 IF (ITOL
.LE
. 2) GO TO 140
1402 130 TOL
= MAX
(TOL
,RTOL
(I
))
1403 140 IF (TOL
.GT
. 0.0D0
) GO TO 160
1406 IF (ITOL
.EQ
. 2 .OR
. ITOL
.EQ
. 4) ATOLI
= ATOL
(I
)
1408 IF (AYI
.NE
. 0.0D0
) TOL
= MAX
(TOL
,ATOLI
/AYI
)
1410 160 TOL
= MAX
(TOL
,100.0D0*UROUND
)
1411 TOL
= MIN
(TOL
,0.001D0
)
1412 SUM
= DMNORM
(N
, RWORK
(LF0
), RWORK
(LEWT
))
1413 SUM
= 1.0D0
/(TOL*W0*W0
) + TOL*SUM**2
1414 H0
= 1.0D0
/SQRT
(SUM
)
1416 H0
= SIGN
(H0
,TOUT
-T
)
1417 C Adjust H0 if necessary to meet HMAX bound. ---------------------------
1418 180 RH
= ABS
(H0
)*HMXI
1419 IF (RH
.GT
. 1.0D0
) H0
= H0
/RH
1420 C Load H with H0 and scale YH(*,2) by H0. ------------------------------
1423 190 RWORK
(I
+LF0
-1) = H0*RWORK
(I
+LF0
-1)
1425 C Check for a zero of g at T. ------------------------------------------
1428 IF (NGC
.EQ
. 0) GO TO 270
1429 CALL DRCHEK
(1, G
, NEQ
, Y
, RWORK
(LYH
), NYH
,
1430 1 RWORK
(LG0
), RWORK
(LG1
), RWORK
(LGX
), JROOT
, IRT
)
1431 IF (IRT
.EQ
. 0) GO TO 270
1433 C-----------------------------------------------------------------------
1435 C The next code block is for continuation calls only (ISTATE = 2 or 3)
1436 C and is to check stop conditions before taking a step.
1437 C First, DRCHEK is called to check for a root within the last step
1438 C taken, other than the last root found there, if any.
1439 C If ITASK = 2 or 5, and y(TN) has not yet been returned to the user
1440 C because of an intervening root, return through Block G.
1441 C-----------------------------------------------------------------------
1445 IF (NGC
.EQ
. 0) GO TO 205
1446 IF (ITASK
.EQ
. 1 .OR
. ITASK
.EQ
. 4) TOUTC
= TOUT
1447 CALL DRCHEK
(2, G
, NEQ
, Y
, RWORK
(LYH
), NYH
,
1448 1 RWORK
(LG0
), RWORK
(LG1
), RWORK
(LGX
), JROOT
, IRT
)
1449 IF (IRT
.NE
. 1) GO TO 205
1456 IF (IRFP
.EQ
. 1 .AND
. TLAST
.NE
. TN
.AND
. ITASK
.EQ
. 2) GO TO 400
1458 GO TO (210, 250, 220, 230, 240), ITASK
1459 210 IF ((TN
- TOUT
)*H
.LT
. 0.0D0
) GO TO 250
1460 CALL DINTDY
(TOUT
, 0, RWORK
(LYH
), NYH
, Y
, IFLAG
)
1461 IF (IFLAG
.NE
. 0) GO TO 627
1464 220 TP
= TN
- HU*
(1.0D0
+ 100.0D0*UROUND
)
1465 IF ((TP
- TOUT
)*H
.GT
. 0.0D0
) GO TO 623
1466 IF ((TN
- TOUT
)*H
.LT
. 0.0D0
) GO TO 250
1469 230 TCRIT
= RWORK
(1)
1470 IF ((TN
- TCRIT
)*H
.GT
. 0.0D0
) GO TO 624
1471 IF ((TCRIT
- TOUT
)*H
.LT
. 0.0D0
) GO TO 625
1472 IF ((TN
- TOUT
)*H
.LT
. 0.0D0
) GO TO 245
1473 CALL DINTDY
(TOUT
, 0, RWORK
(LYH
), NYH
, Y
, IFLAG
)
1474 IF (IFLAG
.NE
. 0) GO TO 627
1477 240 TCRIT
= RWORK
(1)
1478 IF ((TN
- TCRIT
)*H
.GT
. 0.0D0
) GO TO 624
1479 245 HMX
= ABS
(TN
) + ABS
(H
)
1480 IHIT
= ABS
(TN
- TCRIT
) .LE
. 100.0D0*UROUND*HMX
1482 IF (IRFP
.EQ
. 1 .AND
. TLAST
.NE
. TN
.AND
. ITASK
.EQ
. 5) GO TO 400
1484 TNEXT
= TN
+ H*
(1.0D0
+ 4.0D0*UROUND
)
1485 IF ((TNEXT
- TCRIT
)*H
.LE
. 0.0D0
) GO TO 250
1486 H
= (TCRIT
- TN
)*(1.0D0
- 4.0D0*UROUND
)
1487 IF (ISTATE
.EQ
. 2 .AND
. JSTART
.GE
. 0) JSTART
= -2
1488 C-----------------------------------------------------------------------
1490 C The next block is normally executed for all calls and contains
1491 C the call to the one-step core integrator DSTODA.
1493 C This is a looping point for the integration steps.
1495 C First check for too many steps being taken, update EWT (if not at
1496 C start of problem), check for too much accuracy being requested, and
1497 C check for H below the roundoff level in T.
1498 C-----------------------------------------------------------------------
1500 IF (METH
.EQ
. MUSED
) GO TO 255
1501 IF (INSUFR
.EQ
. 1) GO TO 550
1502 IF (INSUFI
.EQ
. 1) GO TO 555
1503 255 IF ((NST
-NSLAST
) .GE
. MXSTEP
) GO TO 500
1504 CALL DEWSET
(N
, ITOL
, RTOL
, ATOL
, RWORK
(LYH
), RWORK
(LEWT
))
1506 IF (RWORK
(I
+LEWT
-1) .LE
. 0.0D0
) GO TO 510
1507 260 RWORK
(I
+LEWT
-1) = 1.0D0
/RWORK
(I
+LEWT
-1)
1508 270 TOLSF
= UROUND*DMNORM
(N
, RWORK
(LYH
), RWORK
(LEWT
))
1509 IF (TOLSF
.LE
. 1.0D0
) GO TO 280
1511 IF (NST
.EQ
. 0) GO TO 626
1513 280 IF ((TN
+ H
) .NE
. TN
) GO TO 290
1515 IF (NHNIL
.GT
. MXHNIL
) GO TO 290
1516 MSG
= 'DLSODAR- Warning..Internal T(=R1) and H(=R2) are '
1517 CALL XERRWD
(MSG
, 50, 101, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1518 MSG
=' such that in the machine, T + H = T on the next step '
1519 CALL XERRWD
(MSG
, 60, 101, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1520 MSG
= ' (H = step size). Solver will continue anyway.'
1521 CALL XERRWD
(MSG
, 50, 101, 0, 0, 0, 0, 2, TN
, H
)
1522 IF (NHNIL
.LT
. MXHNIL
) GO TO 290
1523 MSG
= 'DLSODAR- Above warning has been issued I1 times. '
1524 CALL XERRWD
(MSG
, 50, 102, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1525 MSG
= ' It will not be issued again for this problem.'
1526 CALL XERRWD
(MSG
, 50, 102, 0, 1, MXHNIL
, 0, 0, 0.0D0
, 0.0D0
)
1528 C-----------------------------------------------------------------------
1529 C CALL DSTODA(NEQ,Y,YH,NYH,YH,EWT,SAVF,ACOR,WM,IWM,F,JAC,DPRJA,DSOLSY)
1530 C-----------------------------------------------------------------------
1531 CALL DSTODA
(NEQ
, Y
, RWORK
(LYH
), NYH
, RWORK
(LYH
), RWORK
(LEWT
),
1532 1 RWORK
(LSAVF
), RWORK
(LACOR
), RWORK
(LWM
), IWORK
(LIWM
),
1533 2 F
, JAC
, DPRJA
, DSOLSY
)
1535 GO TO (300, 530, 540), KGO
1536 C-----------------------------------------------------------------------
1538 C The following block handles the case of a successful return from the
1539 C core integrator (KFLAG = 0).
1540 C If a method switch was just made, record TSW, reset MAXORD,
1541 C set JSTART to -1 to signal DSTODA to complete the switch,
1542 C and do extra printing of data if IXPR = 1.
1543 C Then call DRCHEK to check for a root within the last step.
1544 C Then, if no root was found, check for stop conditions.
1545 C-----------------------------------------------------------------------
1547 IF (METH
.EQ
. MUSED
) GO TO 310
1550 IF (METH
.EQ
. 2) MAXORD
= MXORDS
1551 IF (METH
.EQ
. 2) RWORK
(LWM
) = SQRT
(UROUND
)
1552 INSUFR
= MIN
(INSUFR
,1)
1553 INSUFI
= MIN
(INSUFI
,1)
1555 IF (IXPR
.EQ
. 0) GO TO 310
1556 IF (METH
.EQ
. 2) THEN
1557 MSG
='DLSODAR- A switch to the BDF (stiff) method has occurred '
1558 CALL XERRWD
(MSG
, 60, 105, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1560 IF (METH
.EQ
. 1) THEN
1561 MSG
='DLSODAR- A switch to the Adams (nonstiff) method occurred '
1562 CALL XERRWD
(MSG
, 60, 106, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1564 MSG
=' at T = R1, tentative step size H = R2, step NST = I1 '
1565 CALL XERRWD
(MSG
, 60, 107, 0, 1, NST
, 0, 2, TN
, H
)
1568 IF (NGC
.EQ
. 0) GO TO 315
1569 CALL DRCHEK
(3, G
, NEQ
, Y
, RWORK
(LYH
), NYH
,
1570 1 RWORK
(LG0
), RWORK
(LG1
), RWORK
(LGX
), JROOT
, IRT
)
1571 IF (IRT
.NE
. 1) GO TO 315
1578 GO TO (320, 400, 330, 340, 350), ITASK
1579 C ITASK = 1. If TOUT has been reached, interpolate. -------------------
1580 320 IF ((TN
- TOUT
)*H
.LT
. 0.0D0
) GO TO 250
1581 CALL DINTDY
(TOUT
, 0, RWORK
(LYH
), NYH
, Y
, IFLAG
)
1584 C ITASK = 3. Jump to exit if TOUT was reached. ------------------------
1585 330 IF ((TN
- TOUT
)*H
.GE
. 0.0D0
) GO TO 400
1587 C ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary.
1588 340 IF ((TN
- TOUT
)*H
.LT
. 0.0D0
) GO TO 345
1589 CALL DINTDY
(TOUT
, 0, RWORK
(LYH
), NYH
, Y
, IFLAG
)
1592 345 HMX
= ABS
(TN
) + ABS
(H
)
1593 IHIT
= ABS
(TN
- TCRIT
) .LE
. 100.0D0*UROUND*HMX
1595 TNEXT
= TN
+ H*
(1.0D0
+ 4.0D0*UROUND
)
1596 IF ((TNEXT
- TCRIT
)*H
.LE
. 0.0D0
) GO TO 250
1597 H
= (TCRIT
- TN
)*(1.0D0
- 4.0D0*UROUND
)
1598 IF (JSTART
.GE
. 0) JSTART
= -2
1600 C ITASK = 5. See if TCRIT was reached and jump to exit. ---------------
1601 350 HMX
= ABS
(TN
) + ABS
(H
)
1602 IHIT
= ABS
(TN
- TCRIT
) .LE
. 100.0D0*UROUND*HMX
1603 C-----------------------------------------------------------------------
1605 C The following block handles all successful returns from DLSODAR.
1606 C If ITASK .ne. 1, Y is loaded from YH and T is set accordingly.
1607 C ISTATE is set to 2, and the optional outputs are loaded into the
1608 C work arrays before returning.
1609 C-----------------------------------------------------------------------
1611 410 Y
(I
) = RWORK
(I
+LYH
-1)
1613 IF (ITASK
.NE
. 4 .AND
. ITASK
.NE
. 5) GO TO 420
1631 C-----------------------------------------------------------------------
1633 C The following block handles all unsuccessful returns other than
1634 C those for illegal input. First the error message routine is called.
1635 C If there was an error test or convergence test failure, IMXER is set.
1636 C Then Y is loaded from YH and T is set to TN.
1637 C The optional outputs are loaded into the work arrays before returning.
1638 C-----------------------------------------------------------------------
1639 C The maximum number of steps was taken before reaching TOUT. ----------
1640 500 MSG
= 'DLSODAR- At current T (=R1), MXSTEP (=I1) steps '
1641 CALL XERRWD
(MSG
, 50, 201, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1642 MSG
= ' taken on this call before reaching TOUT '
1643 CALL XERRWD
(MSG
, 50, 201, 0, 1, MXSTEP
, 0, 1, TN
, 0.0D0
)
1646 C EWT(i) .le. 0.0 for some i (not at start of problem). ----------------
1647 510 EWTI
= RWORK
(LEWT
+I
-1)
1648 MSG
= 'DLSODAR- At T(=R1), EWT(I1) has become R2 .le. 0.'
1649 CALL XERRWD
(MSG
, 50, 202, 0, 1, I
, 0, 2, TN
, EWTI
)
1652 C Too much accuracy requested for machine precision. -------------------
1653 520 MSG
= 'DLSODAR- At T (=R1), too much accuracy requested '
1654 CALL XERRWD
(MSG
, 50, 203, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1655 MSG
= ' for precision of machine.. See TOLSF (=R2) '
1656 CALL XERRWD
(MSG
, 50, 203, 0, 0, 0, 0, 2, TN
, TOLSF
)
1660 C KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
1661 530 MSG
= 'DLSODAR- At T(=R1), step size H(=R2), the error '
1662 CALL XERRWD
(MSG
, 50, 204, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1663 MSG
= ' test failed repeatedly or with ABS(H) = HMIN'
1664 CALL XERRWD
(MSG
, 50, 204, 0, 0, 0, 0, 2, TN
, H
)
1667 C KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
1668 540 MSG
= 'DLSODAR- At T (=R1) and step size H (=R2), the '
1669 CALL XERRWD
(MSG
, 50, 205, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1670 MSG
= ' corrector convergence failed repeatedly '
1671 CALL XERRWD
(MSG
, 50, 205, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1672 MSG
= ' or with ABS(H) = HMIN '
1673 CALL XERRWD
(MSG
, 30, 205, 0, 0, 0, 0, 2, TN
, H
)
1676 C RWORK length too small to proceed. -----------------------------------
1677 550 MSG
= 'DLSODAR- At current T(=R1), RWORK length too small'
1678 CALL XERRWD
(MSG
, 50, 206, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1679 MSG
=' to proceed. The integration was otherwise successful.'
1680 CALL XERRWD
(MSG
, 60, 206, 0, 0, 0, 0, 1, TN
, 0.0D0
)
1683 C IWORK length too small to proceed. -----------------------------------
1684 555 MSG
= 'DLSODAR- At current T(=R1), IWORK length too small'
1685 CALL XERRWD
(MSG
, 50, 207, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1686 MSG
=' to proceed. The integration was otherwise successful.'
1687 CALL XERRWD
(MSG
, 60, 207, 0, 0, 0, 0, 1, TN
, 0.0D0
)
1690 C Compute IMXER if relevant. -------------------------------------------
1694 SIZE
= ABS
(RWORK
(I
+LACOR
-1)*RWORK
(I
+LEWT
-1))
1695 IF (BIG
.GE
. SIZE
) GO TO 570
1700 C Set Y vector, T, and optional outputs. -------------------------------
1702 590 Y
(I
) = RWORK
(I
+LYH
-1)
1718 C-----------------------------------------------------------------------
1720 C The following block handles all error returns due to illegal input
1721 C (ISTATE = -3), as detected before calling the core integrator.
1722 C First the error message routine is called. If the illegal input
1723 C is a negative ISTATE, the run is aborted (apparent infinite loop).
1724 C-----------------------------------------------------------------------
1725 601 MSG
= 'DLSODAR- ISTATE(=I1) illegal.'
1726 CALL XERRWD
(MSG
, 30, 1, 0, 1, ISTATE
, 0, 0, 0.0D0
, 0.0D0
)
1727 IF (ISTATE
.LT
. 0) GO TO 800
1729 602 MSG
= 'DLSODAR- ITASK (=I1) illegal.'
1730 CALL XERRWD
(MSG
, 30, 2, 0, 1, ITASK
, 0, 0, 0.0D0
, 0.0D0
)
1732 603 MSG
= 'DLSODAR- ISTATE.gt.1 but DLSODAR not initialized.'
1733 CALL XERRWD
(MSG
, 50, 3, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1735 604 MSG
= 'DLSODAR- NEQ (=I1) .lt. 1 '
1736 CALL XERRWD
(MSG
, 30, 4, 0, 1, NEQ
(1), 0, 0, 0.0D0
, 0.0D0
)
1738 605 MSG
= 'DLSODAR- ISTATE = 3 and NEQ increased (I1 to I2).'
1739 CALL XERRWD
(MSG
, 50, 5, 0, 2, N
, NEQ
(1), 0, 0.0D0
, 0.0D0
)
1741 606 MSG
= 'DLSODAR- ITOL (=I1) illegal. '
1742 CALL XERRWD
(MSG
, 30, 6, 0, 1, ITOL
, 0, 0, 0.0D0
, 0.0D0
)
1744 607 MSG
= 'DLSODAR- IOPT (=I1) illegal. '
1745 CALL XERRWD
(MSG
, 30, 7, 0, 1, IOPT
, 0, 0, 0.0D0
, 0.0D0
)
1747 608 MSG
= 'DLSODAR- JT (=I1) illegal. '
1748 CALL XERRWD
(MSG
, 30, 8, 0, 1, JT
, 0, 0, 0.0D0
, 0.0D0
)
1750 609 MSG
= 'DLSODAR- ML (=I1) illegal: .lt.0 or .ge.NEQ (=I2)'
1751 CALL XERRWD
(MSG
, 50, 9, 0, 2, ML
, NEQ
(1), 0, 0.0D0
, 0.0D0
)
1753 610 MSG
= 'DLSODAR- MU (=I1) illegal: .lt.0 or .ge.NEQ (=I2)'
1754 CALL XERRWD
(MSG
, 50, 10, 0, 2, MU
, NEQ
(1), 0, 0.0D0
, 0.0D0
)
1756 611 MSG
= 'DLSODAR- IXPR (=I1) illegal. '
1757 CALL XERRWD
(MSG
, 30, 11, 0, 1, IXPR
, 0, 0, 0.0D0
, 0.0D0
)
1759 612 MSG
= 'DLSODAR- MXSTEP (=I1) .lt. 0 '
1760 CALL XERRWD
(MSG
, 30, 12, 0, 1, MXSTEP
, 0, 0, 0.0D0
, 0.0D0
)
1762 613 MSG
= 'DLSODAR- MXHNIL (=I1) .lt. 0 '
1763 CALL XERRWD
(MSG
, 30, 13, 0, 1, MXHNIL
, 0, 0, 0.0D0
, 0.0D0
)
1765 614 MSG
= 'DLSODAR- TOUT (=R1) behind T (=R2) '
1766 CALL XERRWD
(MSG
, 40, 14, 0, 0, 0, 0, 2, TOUT
, T
)
1767 MSG
= ' Integration direction is given by H0 (=R1) '
1768 CALL XERRWD
(MSG
, 50, 14, 0, 0, 0, 0, 1, H0
, 0.0D0
)
1770 615 MSG
= 'DLSODAR- HMAX (=R1) .lt. 0.0 '
1771 CALL XERRWD
(MSG
, 30, 15, 0, 0, 0, 0, 1, HMAX
, 0.0D0
)
1773 616 MSG
= 'DLSODAR- HMIN (=R1) .lt. 0.0 '
1774 CALL XERRWD
(MSG
, 30, 16, 0, 0, 0, 0, 1, HMIN
, 0.0D0
)
1776 617 MSG
='DLSODAR- RWORK length needed, LENRW(=I1), exceeds LRW(=I2) '
1777 CALL XERRWD
(MSG
, 60, 17, 0, 2, LENRW
, LRW
, 0, 0.0D0
, 0.0D0
)
1779 618 MSG
='DLSODAR- IWORK length needed, LENIW(=I1), exceeds LIW(=I2) '
1780 CALL XERRWD
(MSG
, 60, 18, 0, 2, LENIW
, LIW
, 0, 0.0D0
, 0.0D0
)
1782 619 MSG
= 'DLSODAR- RTOL(I1) is R1 .lt. 0.0 '
1783 CALL XERRWD
(MSG
, 40, 19, 0, 1, I
, 0, 1, RTOLI
, 0.0D0
)
1785 620 MSG
= 'DLSODAR- ATOL(I1) is R1 .lt. 0.0 '
1786 CALL XERRWD
(MSG
, 40, 20, 0, 1, I
, 0, 1, ATOLI
, 0.0D0
)
1788 621 EWTI
= RWORK
(LEWT
+I
-1)
1789 MSG
= 'DLSODAR- EWT(I1) is R1 .le. 0.0 '
1790 CALL XERRWD
(MSG
, 40, 21, 0, 1, I
, 0, 1, EWTI
, 0.0D0
)
1792 622 MSG
='DLSODAR- TOUT(=R1) too close to T(=R2) to start integration.'
1793 CALL XERRWD
(MSG
, 60, 22, 0, 0, 0, 0, 2, TOUT
, T
)
1795 623 MSG
='DLSODAR- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
1796 CALL XERRWD
(MSG
, 60, 23, 0, 1, ITASK
, 0, 2, TOUT
, TP
)
1798 624 MSG
='DLSODAR- ITASK = 4 or 5 and TCRIT (=R1) behind TCUR (=R2) '
1799 CALL XERRWD
(MSG
, 60, 24, 0, 0, 0, 0, 2, TCRIT
, TN
)
1801 625 MSG
='DLSODAR- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
1802 CALL XERRWD
(MSG
, 60, 25, 0, 0, 0, 0, 2, TCRIT
, TOUT
)
1804 626 MSG
= 'DLSODAR- At start of problem, too much accuracy '
1805 CALL XERRWD
(MSG
, 50, 26, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1806 MSG
=' requested for precision of machine.. See TOLSF (=R1) '
1807 CALL XERRWD
(MSG
, 60, 26, 0, 0, 0, 0, 1, TOLSF
, 0.0D0
)
1810 627 MSG
= 'DLSODAR- Trouble in DINTDY. ITASK = I1, TOUT = R1'
1811 CALL XERRWD
(MSG
, 50, 27, 0, 1, ITASK
, 0, 1, TOUT
, 0.0D0
)
1813 628 MSG
= 'DLSODAR- MXORDN (=I1) .lt. 0 '
1814 CALL XERRWD
(MSG
, 30, 28, 0, 1, MXORDN
, 0, 0, 0.0D0
, 0.0D0
)
1816 629 MSG
= 'DLSODAR- MXORDS (=I1) .lt. 0 '
1817 CALL XERRWD
(MSG
, 30, 29, 0, 1, MXORDS
, 0, 0, 0.0D0
, 0.0D0
)
1819 630 MSG
= 'DLSODAR- NG (=I1) .lt. 0 '
1820 CALL XERRWD
(MSG
, 30, 30, 0, 1, NG
, 0, 0, 0.0D0
, 0.0D0
)
1822 631 MSG
= 'DLSODAR- NG changed (from I1 to I2) illegally, '
1823 CALL XERRWD
(MSG
, 50, 31, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1824 MSG
= ' i.e. not immediately after a root was found.'
1825 CALL XERRWD
(MSG
, 50, 31, 0, 2, NGC
, NG
, 0, 0.0D0
, 0.0D0
)
1827 632 MSG
= 'DLSODAR- One or more components of g has a root '
1828 CALL XERRWD
(MSG
, 50, 32, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1829 MSG
= ' too near to the initial point. '
1830 CALL XERRWD
(MSG
, 40, 32, 0, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1835 800 MSG
= 'DLSODAR- Run aborted.. apparent infinite loop. '
1836 CALL XERRWD
(MSG
, 50, 303, 2, 0, 0, 0, 0, 0.0D0
, 0.0D0
)
1838 C----------------------- End of Subroutine DLSODAR ---------------------