f2kodepack
Reference documentation for version 0.0
Main Page
Related Pages
Modules
Files
File List
source_new
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
Generated on Thu Jan 5 2017 13:37:15 for f2kodepack by
1.8.11