ode 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ double precision function vmnorm (n, v, w)
2
+ clll. optimize
3
+ c-----------------------------------------------------------------------
4
+ c this function routine computes the weighted max-norm
5
+ c of the vector of length n contained in the array v, with weights
6
+ c contained in the array w of length n..
7
+ c vmnorm = max(i=1,...,n) abs(v(i))*w(i)
8
+ c-----------------------------------------------------------------------
9
+ integer n, i
10
+ double precision v, w, vm
11
+ dimension v(n), w(n)
12
+ vm = 0.0d0
13
+ do 10 i = 1,n
14
+ 10 vm = dmax1(vm,dabs(v(i))*w(i))
15
+ vmnorm = vm
16
+ return
17
+ c----------------------- end of function vmnorm ------------------------
18
+ end
@@ -0,0 +1,3667 @@
1
+
2
+ *DECK DVODE
3
+ SUBROUTINE DVODE (F, NEQ, Y, T, TOUT, ITOL, RTOL, ATOL, ITASK,
4
+ 1 ISTATE, IOPT, RWORK, LRW, IWORK, LIW, JAC, MF,
5
+ 2 RPAR, IPAR)
6
+ EXTERNAL F, JAC
7
+ DOUBLE PRECISION Y, T, TOUT, RTOL, ATOL, RWORK, RPAR
8
+ INTEGER NEQ, ITOL, ITASK, ISTATE, IOPT, LRW, IWORK, LIW,
9
+ 1 MF, IPAR
10
+ DIMENSION Y(*), RTOL(*), ATOL(*), RWORK(LRW), IWORK(LIW),
11
+ 1 RPAR(*), IPAR(*)
12
+ C-----------------------------------------------------------------------
13
+ C DVODE.. Variable-coefficient Ordinary Differential Equation solver,
14
+ C with fixed-leading-coefficient implementation.
15
+ C This version is in double precision.
16
+ C
17
+ C DVODE solves the initial value problem for stiff or nonstiff
18
+ C systems of first order ODEs,
19
+ C dy/dt = f(t,y) , or, in component form,
20
+ C dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(NEQ)) (i = 1,...,NEQ).
21
+ C DVODE is a package based on the EPISODE and EPISODEB packages, and
22
+ C on the ODEPACK user interface standard, with minor modifications.
23
+ C-----------------------------------------------------------------------
24
+ C Revision History (YYMMDD)
25
+ C 890615 Date Written
26
+ C 890922 Added interrupt/restart ability, minor changes throughout.
27
+ C 910228 Minor revisions in line format, prologue, etc.
28
+ C 920227 Modifications by D. Pang:
29
+ C (1) Applied subgennam to get generic intrinsic names.
30
+ C (2) Changed intrinsic names to generic in comments.
31
+ C (3) Added *DECK lines before each routine.
32
+ C 920721 Names of routines and labeled Common blocks changed, so as
33
+ C to be unique in combined single/double precision code (ACH).
34
+ C 920722 Minor revisions to prologue (ACH).
35
+ C 920831 Conversion to double precision done (ACH).
36
+ C 921106 Fixed minor bug: ETAQ,ETAQM1 in DVSTEP SAVE statement (ACH).
37
+ C 921118 Changed LUNSAV/MFLGSV to IXSAV (ACH).
38
+ C 941222 Removed MF overwrite; attached sign to H in estimated second
39
+ C derivative in DVHIN; misc. comment corrections throughout.
40
+ C 970515 Minor corrections to comments in prologue, DVJAC.
41
+ C-----------------------------------------------------------------------
42
+ C References..
43
+ C
44
+ C 1. P. N. Brown, G. D. Byrne, and A. C. Hindmarsh, "VODE: A Variable
45
+ C Coefficient ODE Solver," SIAM J. Sci. Stat. Comput., 10 (1989),
46
+ C pp. 1038-1051. Also, LLNL Report UCRL-98412, June 1988.
47
+ C 2. G. D. Byrne and A. C. Hindmarsh, "A Polyalgorithm for the
48
+ C Numerical Solution of Ordinary Differential Equations,"
49
+ C ACM Trans. Math. Software, 1 (1975), pp. 71-96.
50
+ C 3. A. C. Hindmarsh and G. D. Byrne, "EPISODE: An Effective Package
51
+ C for the Integration of Systems of Ordinary Differential
52
+ C Equations," LLNL Report UCID-30112, Rev. 1, April 1977.
53
+ C 4. G. D. Byrne and A. C. Hindmarsh, "EPISODEB: An Experimental
54
+ C Package for the Integration of Systems of Ordinary Differential
55
+ C Equations with Banded Jacobians," LLNL Report UCID-30132, April
56
+ C 1976.
57
+ C 5. A. C. Hindmarsh, "ODEPACK, a Systematized Collection of ODE
58
+ C Solvers," in Scientific Computing, R. S. Stepleman et al., eds.,
59
+ C North-Holland, Amsterdam, 1983, pp. 55-64.
60
+ C 6. K. R. Jackson and R. Sacks-Davis, "An Alternative Implementation
61
+ C of Variable Step-Size Multistep Formulas for Stiff ODEs," ACM
62
+ C Trans. Math. Software, 6 (1980), pp. 295-318.
63
+ C-----------------------------------------------------------------------
64
+ C Authors..
65
+ C
66
+ C Peter N. Brown and Alan C. Hindmarsh
67
+ C Center for Applied Scientific Computing, L-561
68
+ C Lawrence Livermore National Laboratory
69
+ C Livermore, CA 94551
70
+ C and
71
+ C George D. Byrne
72
+ C Illinois Institute of Technology
73
+ C Chicago, IL 60616
74
+ C-----------------------------------------------------------------------
75
+ C Summary of usage.
76
+ C
77
+ C Communication between the user and the DVODE package, for normal
78
+ C situations, is summarized here. This summary describes only a subset
79
+ C of the full set of options available. See the full description for
80
+ C details, including optional communication, nonstandard options,
81
+ C and instructions for special situations. See also the example
82
+ C problem (with program and output) following this summary.
83
+ C
84
+ C A. First provide a subroutine of the form..
85
+ C
86
+ C SUBROUTINE F (NEQ, T, Y, YDOT, RPAR, IPAR)
87
+ C DOUBLE PRECISION T, Y, YDOT, RPAR
88
+ C DIMENSION Y(NEQ), YDOT(NEQ)
89
+ C
90
+ C which supplies the vector function f by loading YDOT(i) with f(i).
91
+ C
92
+ C B. Next determine (or guess) whether or not the problem is stiff.
93
+ C Stiffness occurs when the Jacobian matrix df/dy has an eigenvalue
94
+ C whose real part is negative and large in magnitude, compared to the
95
+ C reciprocal of the t span of interest. If the problem is nonstiff,
96
+ C use a method flag MF = 10. If it is stiff, there are four standard
97
+ C choices for MF (21, 22, 24, 25), and DVODE requires the Jacobian
98
+ C matrix in some form. In these cases (MF .gt. 0), DVODE will use a
99
+ C saved copy of the Jacobian matrix. If this is undesirable because of
100
+ C storage limitations, set MF to the corresponding negative value
101
+ C (-21, -22, -24, -25). (See full description of MF below.)
102
+ C The Jacobian matrix is regarded either as full (MF = 21 or 22),
103
+ C or banded (MF = 24 or 25). In the banded case, DVODE requires two
104
+ C half-bandwidth parameters ML and MU. These are, respectively, the
105
+ C widths of the lower and upper parts of the band, excluding the main
106
+ C diagonal. Thus the band consists of the locations (i,j) with
107
+ C i-ML .le. j .le. i+MU, and the full bandwidth is ML+MU+1.
108
+ C
109
+ C C. If the problem is stiff, you are encouraged to supply the Jacobian
110
+ C directly (MF = 21 or 24), but if this is not feasible, DVODE will
111
+ C compute it internally by difference quotients (MF = 22 or 25).
112
+ C If you are supplying the Jacobian, provide a subroutine of the form..
113
+ C
114
+ C SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD, RPAR, IPAR)
115
+ C DOUBLE PRECISION T, Y, PD, RPAR
116
+ C DIMENSION Y(NEQ), PD(NROWPD,NEQ)
117
+ C
118
+ C which supplies df/dy by loading PD as follows..
119
+ C For a full Jacobian (MF = 21), load PD(i,j) with df(i)/dy(j),
120
+ C the partial derivative of f(i) with respect to y(j). (Ignore the
121
+ C ML and MU arguments in this case.)
122
+ C For a banded Jacobian (MF = 24), load PD(i-j+MU+1,j) with
123
+ C df(i)/dy(j), i.e. load the diagonal lines of df/dy into the rows of
124
+ C PD from the top down.
125
+ C In either case, only nonzero elements need be loaded.
126
+ C
127
+ C D. Write a main program which calls subroutine DVODE once for
128
+ C each point at which answers are desired. This should also provide
129
+ C for possible use of logical unit 6 for output of error messages
130
+ C by DVODE. On the first call to DVODE, supply arguments as follows..
131
+ C F = Name of subroutine for right-hand side vector f.
132
+ C This name must be declared external in calling program.
133
+ C NEQ = Number of first order ODE-s.
134
+ C Y = Array of initial values, of length NEQ.
135
+ C T = The initial value of the independent variable.
136
+ C TOUT = First point where output is desired (.ne. T).
137
+ C ITOL = 1 or 2 according as ATOL (below) is a scalar or array.
138
+ C RTOL = Relative tolerance parameter (scalar).
139
+ C ATOL = Absolute tolerance parameter (scalar or array).
140
+ C The estimated local error in Y(i) will be controlled so as
141
+ C to be roughly less (in magnitude) than
142
+ C EWT(i) = RTOL*abs(Y(i)) + ATOL if ITOL = 1, or
143
+ C EWT(i) = RTOL*abs(Y(i)) + ATOL(i) if ITOL = 2.
144
+ C Thus the local error test passes if, in each component,
145
+ C either the absolute error is less than ATOL (or ATOL(i)),
146
+ C or the relative error is less than RTOL.
147
+ C Use RTOL = 0.0 for pure absolute error control, and
148
+ C use ATOL = 0.0 (or ATOL(i) = 0.0) for pure relative error
149
+ C control. Caution.. Actual (global) errors may exceed these
150
+ C local tolerances, so choose them conservatively.
151
+ C ITASK = 1 for normal computation of output values of Y at t = TOUT.
152
+ C ISTATE = Integer flag (input and output). Set ISTATE = 1.
153
+ C IOPT = 0 to indicate no optional input used.
154
+ C RWORK = Real work array of length at least..
155
+ C 20 + 16*NEQ for MF = 10,
156
+ C 22 + 9*NEQ + 2*NEQ**2 for MF = 21 or 22,
157
+ C 22 + 11*NEQ + (3*ML + 2*MU)*NEQ for MF = 24 or 25.
158
+ C LRW = Declared length of RWORK (in user's DIMENSION statement).
159
+ C IWORK = Integer work array of length at least..
160
+ C 30 for MF = 10,
161
+ C 30 + NEQ for MF = 21, 22, 24, or 25.
162
+ C If MF = 24 or 25, input in IWORK(1),IWORK(2) the lower
163
+ C and upper half-bandwidths ML,MU.
164
+ C LIW = Declared length of IWORK (in user's DIMENSION statement).
165
+ C JAC = Name of subroutine for Jacobian matrix (MF = 21 or 24).
166
+ C If used, this name must be declared external in calling
167
+ C program. If not used, pass a dummy name.
168
+ C MF = Method flag. Standard values are..
169
+ C 10 for nonstiff (Adams) method, no Jacobian used.
170
+ C 21 for stiff (BDF) method, user-supplied full Jacobian.
171
+ C 22 for stiff method, internally generated full Jacobian.
172
+ C 24 for stiff method, user-supplied banded Jacobian.
173
+ C 25 for stiff method, internally generated banded Jacobian.
174
+ C RPAR,IPAR = user-defined real and integer arrays passed to F and JAC.
175
+ C Note that the main program must declare arrays Y, RWORK, IWORK,
176
+ C and possibly ATOL, RPAR, and IPAR.
177
+ C
178
+ C E. The output from the first call (or any call) is..
179
+ C Y = Array of computed values of y(t) vector.
180
+ C T = Corresponding value of independent variable (normally TOUT).
181
+ C ISTATE = 2 if DVODE was successful, negative otherwise.
182
+ C -1 means excess work done on this call. (Perhaps wrong MF.)
183
+ C -2 means excess accuracy requested. (Tolerances too small.)
184
+ C -3 means illegal input detected. (See printed message.)
185
+ C -4 means repeated error test failures. (Check all input.)
186
+ C -5 means repeated convergence failures. (Perhaps bad
187
+ C Jacobian supplied or wrong choice of MF or tolerances.)
188
+ C -6 means error weight became zero during problem. (Solution
189
+ C component i vanished, and ATOL or ATOL(i) = 0.)
190
+ C
191
+ C F. To continue the integration after a successful return, simply
192
+ C reset TOUT and call DVODE again. No other parameters need be reset.
193
+ C
194
+ C-----------------------------------------------------------------------
195
+ C EXAMPLE PROBLEM
196
+ C
197
+ C The following is a simple example problem, with the coding
198
+ C needed for its solution by DVODE. The problem is from chemical
199
+ C kinetics, and consists of the following three rate equations..
200
+ C dy1/dt = -.04*y1 + 1.e4*y2*y3
201
+ C dy2/dt = .04*y1 - 1.e4*y2*y3 - 3.e7*y2**2
202
+ C dy3/dt = 3.e7*y2**2
203
+ C on the interval from t = 0.0 to t = 4.e10, with initial conditions
204
+ C y1 = 1.0, y2 = y3 = 0. The problem is stiff.
205
+ C
206
+ C The following coding solves this problem with DVODE, using MF = 21
207
+ C and printing results at t = .4, 4., ..., 4.e10. It uses
208
+ C ITOL = 2 and ATOL much smaller for y2 than y1 or y3 because
209
+ C y2 has much smaller values.
210
+ C At the end of the run, statistical quantities of interest are
211
+ C printed. (See optional output in the full description below.)
212
+ C To generate Fortran source code, replace C in column 1 with a blank
213
+ C in the coding below.
214
+ C
215
+ C EXTERNAL FEX, JEX
216
+ C DOUBLE PRECISION ATOL, RPAR, RTOL, RWORK, T, TOUT, Y
217
+ C DIMENSION Y(3), ATOL(3), RWORK(67), IWORK(33)
218
+ C NEQ = 3
219
+ C Y(1) = 1.0D0
220
+ C Y(2) = 0.0D0
221
+ C Y(3) = 0.0D0
222
+ C T = 0.0D0
223
+ C TOUT = 0.4D0
224
+ C ITOL = 2
225
+ C RTOL = 1.D-4
226
+ C ATOL(1) = 1.D-8
227
+ C ATOL(2) = 1.D-14
228
+ C ATOL(3) = 1.D-6
229
+ C ITASK = 1
230
+ C ISTATE = 1
231
+ C IOPT = 0
232
+ C LRW = 67
233
+ C LIW = 33
234
+ C MF = 21
235
+ C DO 40 IOUT = 1,12
236
+ C CALL DVODE(FEX,NEQ,Y,T,TOUT,ITOL,RTOL,ATOL,ITASK,ISTATE,
237
+ C 1 IOPT,RWORK,LRW,IWORK,LIW,JEX,MF,RPAR,IPAR)
238
+ C WRITE(6,20)T,Y(1),Y(2),Y(3)
239
+ C 20 FORMAT(' At t =',D12.4,' y =',3D14.6)
240
+ C IF (ISTATE .LT. 0) GO TO 80
241
+ C 40 TOUT = TOUT*10.
242
+ C WRITE(6,60) IWORK(11),IWORK(12),IWORK(13),IWORK(19),
243
+ C 1 IWORK(20),IWORK(21),IWORK(22)
244
+ C 60 FORMAT(/' No. steps =',I4,' No. f-s =',I4,
245
+ C 1 ' No. J-s =',I4,' No. LU-s =',I4/
246
+ C 2 ' No. nonlinear iterations =',I4/
247
+ C 3 ' No. nonlinear convergence failures =',I4/
248
+ C 4 ' No. error test failures =',I4/)
249
+ C STOP
250
+ C 80 WRITE(6,90)ISTATE
251
+ C 90 FORMAT(///' Error halt.. ISTATE =',I3)
252
+ C STOP
253
+ C END
254
+ C
255
+ C SUBROUTINE FEX (NEQ, T, Y, YDOT, RPAR, IPAR)
256
+ C DOUBLE PRECISION RPAR, T, Y, YDOT
257
+ C DIMENSION Y(NEQ), YDOT(NEQ)
258
+ C YDOT(1) = -.04D0*Y(1) + 1.D4*Y(2)*Y(3)
259
+ C YDOT(3) = 3.D7*Y(2)*Y(2)
260
+ C YDOT(2) = -YDOT(1) - YDOT(3)
261
+ C RETURN
262
+ C END
263
+ C
264
+ C SUBROUTINE JEX (NEQ, T, Y, ML, MU, PD, NRPD, RPAR, IPAR)
265
+ C DOUBLE PRECISION PD, RPAR, T, Y
266
+ C DIMENSION Y(NEQ), PD(NRPD,NEQ)
267
+ C PD(1,1) = -.04D0
268
+ C PD(1,2) = 1.D4*Y(3)
269
+ C PD(1,3) = 1.D4*Y(2)
270
+ C PD(2,1) = .04D0
271
+ C PD(2,3) = -PD(1,3)
272
+ C PD(3,2) = 6.D7*Y(2)
273
+ C PD(2,2) = -PD(1,2) - PD(3,2)
274
+ C RETURN
275
+ C END
276
+ C
277
+ C The following output was obtained from the above program on a
278
+ C Cray-1 computer with the CFT compiler.
279
+ C
280
+ C At t = 4.0000e-01 y = 9.851680e-01 3.386314e-05 1.479817e-02
281
+ C At t = 4.0000e+00 y = 9.055255e-01 2.240539e-05 9.445214e-02
282
+ C At t = 4.0000e+01 y = 7.158108e-01 9.184883e-06 2.841800e-01
283
+ C At t = 4.0000e+02 y = 4.505032e-01 3.222940e-06 5.494936e-01
284
+ C At t = 4.0000e+03 y = 1.832053e-01 8.942690e-07 8.167938e-01
285
+ C At t = 4.0000e+04 y = 3.898560e-02 1.621875e-07 9.610142e-01
286
+ C At t = 4.0000e+05 y = 4.935882e-03 1.984013e-08 9.950641e-01
287
+ C At t = 4.0000e+06 y = 5.166183e-04 2.067528e-09 9.994834e-01
288
+ C At t = 4.0000e+07 y = 5.201214e-05 2.080593e-10 9.999480e-01
289
+ C At t = 4.0000e+08 y = 5.213149e-06 2.085271e-11 9.999948e-01
290
+ C At t = 4.0000e+09 y = 5.183495e-07 2.073399e-12 9.999995e-01
291
+ C At t = 4.0000e+10 y = 5.450996e-08 2.180399e-13 9.999999e-01
292
+ C
293
+ C No. steps = 595 No. f-s = 832 No. J-s = 13 No. LU-s = 112
294
+ C No. nonlinear iterations = 831
295
+ C No. nonlinear convergence failures = 0
296
+ C No. error test failures = 22
297
+ C-----------------------------------------------------------------------
298
+ C Full description of user interface to DVODE.
299
+ C
300
+ C The user interface to DVODE consists of the following parts.
301
+ C
302
+ C i. The call sequence to subroutine DVODE, which is a driver
303
+ C routine for the solver. This includes descriptions of both
304
+ C the call sequence arguments and of user-supplied routines.
305
+ C Following these descriptions is
306
+ C * a description of optional input available through the
307
+ C call sequence,
308
+ C * a description of optional output (in the work arrays), and
309
+ C * instructions for interrupting and restarting a solution.
310
+ C
311
+ C ii. Descriptions of other routines in the DVODE package that may be
312
+ C (optionally) called by the user. These provide the ability to
313
+ C alter error message handling, save and restore the internal
314
+ C COMMON, and obtain specified derivatives of the solution y(t).
315
+ C
316
+ C iii. Descriptions of COMMON blocks to be declared in overlay
317
+ C or similar environments.
318
+ C
319
+ C iv. Description of two routines in the DVODE package, either of
320
+ C which the user may replace with his own version, if desired.
321
+ C these relate to the measurement of errors.
322
+ C
323
+ C-----------------------------------------------------------------------
324
+ C Part i. Call Sequence.
325
+ C
326
+ C The call sequence parameters used for input only are
327
+ C F, NEQ, TOUT, ITOL, RTOL, ATOL, ITASK, IOPT, LRW, LIW, JAC, MF,
328
+ C and those used for both input and output are
329
+ C Y, T, ISTATE.
330
+ C The work arrays RWORK and IWORK are also used for conditional and
331
+ C optional input and optional output. (The term output here refers
332
+ C to the return from subroutine DVODE to the user's calling program.)
333
+ C
334
+ C The legality of input parameters will be thoroughly checked on the
335
+ C initial call for the problem, but not checked thereafter unless a
336
+ C change in input parameters is flagged by ISTATE = 3 in the input.
337
+ C
338
+ C The descriptions of the call arguments are as follows.
339
+ C
340
+ C F = The name of the user-supplied subroutine defining the
341
+ C ODE system. The system must be put in the first-order
342
+ C form dy/dt = f(t,y), where f is a vector-valued function
343
+ C of the scalar t and the vector y. Subroutine F is to
344
+ C compute the function f. It is to have the form
345
+ C SUBROUTINE F (NEQ, T, Y, YDOT, RPAR, IPAR)
346
+ C DOUBLE PRECISION T, Y, YDOT, RPAR
347
+ C DIMENSION Y(NEQ), YDOT(NEQ)
348
+ C where NEQ, T, and Y are input, and the array YDOT = f(t,y)
349
+ C is output. Y and YDOT are arrays of length NEQ.
350
+ C (In the DIMENSION statement above, NEQ can be replaced by
351
+ C * to make Y and YDOT assumed size arrays.)
352
+ C Subroutine F should not alter Y(1),...,Y(NEQ).
353
+ C F must be declared EXTERNAL in the calling program.
354
+ C
355
+ C Subroutine F may access user-defined real and integer
356
+ C work arrays RPAR and IPAR, which are to be dimensioned
357
+ C in the main program.
358
+ C
359
+ C If quantities computed in the F routine are needed
360
+ C externally to DVODE, an extra call to F should be made
361
+ C for this purpose, for consistent and accurate results.
362
+ C If only the derivative dy/dt is needed, use DVINDY instead.
363
+ C
364
+ C NEQ = The size of the ODE system (number of first order
365
+ C ordinary differential equations). Used only for input.
366
+ C NEQ may not be increased during the problem, but
367
+ C can be decreased (with ISTATE = 3 in the input).
368
+ C
369
+ C Y = A real array for the vector of dependent variables, of
370
+ C length NEQ or more. Used for both input and output on the
371
+ C first call (ISTATE = 1), and only for output on other calls.
372
+ C On the first call, Y must contain the vector of initial
373
+ C values. In the output, Y contains the computed solution
374
+ C evaluated at T. If desired, the Y array may be used
375
+ C for other purposes between calls to the solver.
376
+ C
377
+ C This array is passed as the Y argument in all calls to
378
+ C F and JAC.
379
+ C
380
+ C T = The independent variable. In the input, T is used only on
381
+ C the first call, as the initial point of the integration.
382
+ C In the output, after each call, T is the value at which a
383
+ C computed solution Y is evaluated (usually the same as TOUT).
384
+ C On an error return, T is the farthest point reached.
385
+ C
386
+ C TOUT = The next value of t at which a computed solution is desired.
387
+ C Used only for input.
388
+ C
389
+ C When starting the problem (ISTATE = 1), TOUT may be equal
390
+ C to T for one call, then should .ne. T for the next call.
391
+ C For the initial T, an input value of TOUT .ne. T is used
392
+ C in order to determine the direction of the integration
393
+ C (i.e. the algebraic sign of the step sizes) and the rough
394
+ C scale of the problem. Integration in either direction
395
+ C (forward or backward in t) is permitted.
396
+ C
397
+ C If ITASK = 2 or 5 (one-step modes), TOUT is ignored after
398
+ C the first call (i.e. the first call with TOUT .ne. T).
399
+ C Otherwise, TOUT is required on every call.
400
+ C
401
+ C If ITASK = 1, 3, or 4, the values of TOUT need not be
402
+ C monotone, but a value of TOUT which backs up is limited
403
+ C to the current internal t interval, whose endpoints are
404
+ C TCUR - HU and TCUR. (See optional output, below, for
405
+ C TCUR and HU.)
406
+ C
407
+ C ITOL = An indicator for the type of error control. See
408
+ C description below under ATOL. Used only for input.
409
+ C
410
+ C RTOL = A relative error tolerance parameter, either a scalar or
411
+ C an array of length NEQ. See description below under ATOL.
412
+ C Input only.
413
+ C
414
+ C ATOL = An absolute error tolerance parameter, either a scalar or
415
+ C an array of length NEQ. Input only.
416
+ C
417
+ C The input parameters ITOL, RTOL, and ATOL determine
418
+ C the error control performed by the solver. The solver will
419
+ C control the vector e = (e(i)) of estimated local errors
420
+ C in Y, according to an inequality of the form
421
+ C rms-norm of ( e(i)/EWT(i) ) .le. 1,
422
+ C where EWT(i) = RTOL(i)*abs(Y(i)) + ATOL(i),
423
+ C and the rms-norm (root-mean-square norm) here is
424
+ C rms-norm(v) = sqrt(sum v(i)**2 / NEQ). Here EWT = (EWT(i))
425
+ C is a vector of weights which must always be positive, and
426
+ C the values of RTOL and ATOL should all be non-negative.
427
+ C The following table gives the types (scalar/array) of
428
+ C RTOL and ATOL, and the corresponding form of EWT(i).
429
+ C
430
+ C ITOL RTOL ATOL EWT(i)
431
+ C 1 scalar scalar RTOL*ABS(Y(i)) + ATOL
432
+ C 2 scalar array RTOL*ABS(Y(i)) + ATOL(i)
433
+ C 3 array scalar RTOL(i)*ABS(Y(i)) + ATOL
434
+ C 4 array array RTOL(i)*ABS(Y(i)) + ATOL(i)
435
+ C
436
+ C When either of these parameters is a scalar, it need not
437
+ C be dimensioned in the user's calling program.
438
+ C
439
+ C If none of the above choices (with ITOL, RTOL, and ATOL
440
+ C fixed throughout the problem) is suitable, more general
441
+ C error controls can be obtained by substituting
442
+ C user-supplied routines for the setting of EWT and/or for
443
+ C the norm calculation. See Part iv below.
444
+ C
445
+ C If global errors are to be estimated by making a repeated
446
+ C run on the same problem with smaller tolerances, then all
447
+ C components of RTOL and ATOL (i.e. of EWT) should be scaled
448
+ C down uniformly.
449
+ C
450
+ C ITASK = An index specifying the task to be performed.
451
+ C Input only. ITASK has the following values and meanings.
452
+ C 1 means normal computation of output values of y(t) at
453
+ C t = TOUT (by overshooting and interpolating).
454
+ C 2 means take one step only and return.
455
+ C 3 means stop at the first internal mesh point at or
456
+ C beyond t = TOUT and return.
457
+ C 4 means normal computation of output values of y(t) at
458
+ C t = TOUT but without overshooting t = TCRIT.
459
+ C TCRIT must be input as RWORK(1). TCRIT may be equal to
460
+ C or beyond TOUT, but not behind it in the direction of
461
+ C integration. This option is useful if the problem
462
+ C has a singularity at or beyond t = TCRIT.
463
+ C 5 means take one step, without passing TCRIT, and return.
464
+ C TCRIT must be input as RWORK(1).
465
+ C
466
+ C Note.. If ITASK = 4 or 5 and the solver reaches TCRIT
467
+ C (within roundoff), it will return T = TCRIT (exactly) to
468
+ C indicate this (unless ITASK = 4 and TOUT comes before TCRIT,
469
+ C in which case answers at T = TOUT are returned first).
470
+ C
471
+ C ISTATE = an index used for input and output to specify the
472
+ C the state of the calculation.
473
+ C
474
+ C In the input, the values of ISTATE are as follows.
475
+ C 1 means this is the first call for the problem
476
+ C (initializations will be done). See note below.
477
+ C 2 means this is not the first call, and the calculation
478
+ C is to continue normally, with no change in any input
479
+ C parameters except possibly TOUT and ITASK.
480
+ C (If ITOL, RTOL, and/or ATOL are changed between calls
481
+ C with ISTATE = 2, the new values will be used but not
482
+ C tested for legality.)
483
+ C 3 means this is not the first call, and the
484
+ C calculation is to continue normally, but with
485
+ C a change in input parameters other than
486
+ C TOUT and ITASK. Changes are allowed in
487
+ C NEQ, ITOL, RTOL, ATOL, IOPT, LRW, LIW, MF, ML, MU,
488
+ C and any of the optional input except H0.
489
+ C (See IWORK description for ML and MU.)
490
+ C Note.. A preliminary call with TOUT = T is not counted
491
+ C as a first call here, as no initialization or checking of
492
+ C input is done. (Such a call is sometimes useful to include
493
+ C the initial conditions in the output.)
494
+ C Thus the first call for which TOUT .ne. T requires
495
+ C ISTATE = 1 in the input.
496
+ C
497
+ C In the output, ISTATE has the following values and meanings.
498
+ C 1 means nothing was done, as TOUT was equal to T with
499
+ C ISTATE = 1 in the input.
500
+ C 2 means the integration was performed successfully.
501
+ C -1 means an excessive amount of work (more than MXSTEP
502
+ C steps) was done on this call, before completing the
503
+ C requested task, but the integration was otherwise
504
+ C successful as far as T. (MXSTEP is an optional input
505
+ C and is normally 500.) To continue, the user may
506
+ C simply reset ISTATE to a value .gt. 1 and call again.
507
+ C (The excess work step counter will be reset to 0.)
508
+ C In addition, the user may increase MXSTEP to avoid
509
+ C this error return. (See optional input below.)
510
+ C -2 means too much accuracy was requested for the precision
511
+ C of the machine being used. This was detected before
512
+ C completing the requested task, but the integration
513
+ C was successful as far as T. To continue, the tolerance
514
+ C parameters must be reset, and ISTATE must be set
515
+ C to 3. The optional output TOLSF may be used for this
516
+ C purpose. (Note.. If this condition is detected before
517
+ C taking any steps, then an illegal input return
518
+ C (ISTATE = -3) occurs instead.)
519
+ C -3 means illegal input was detected, before taking any
520
+ C integration steps. See written message for details.
521
+ C Note.. If the solver detects an infinite loop of calls
522
+ C to the solver with illegal input, it will cause
523
+ C the run to stop.
524
+ C -4 means there were repeated error test failures on
525
+ C one attempted step, before completing the requested
526
+ C task, but the integration was successful as far as T.
527
+ C The problem may have a singularity, or the input
528
+ C may be inappropriate.
529
+ C -5 means there were repeated convergence test failures on
530
+ C one attempted step, before completing the requested
531
+ C task, but the integration was successful as far as T.
532
+ C This may be caused by an inaccurate Jacobian matrix,
533
+ C if one is being used.
534
+ C -6 means EWT(i) became zero for some i during the
535
+ C integration. Pure relative error control (ATOL(i)=0.0)
536
+ C was requested on a variable which has now vanished.
537
+ C The integration was successful as far as T.
538
+ C
539
+ C Note.. Since the normal output value of ISTATE is 2,
540
+ C it does not need to be reset for normal continuation.
541
+ C Also, since a negative input value of ISTATE will be
542
+ C regarded as illegal, a negative output value requires the
543
+ C user to change it, and possibly other input, before
544
+ C calling the solver again.
545
+ C
546
+ C IOPT = An integer flag to specify whether or not any optional
547
+ C input is being used on this call. Input only.
548
+ C The optional input is listed separately below.
549
+ C IOPT = 0 means no optional input is being used.
550
+ C Default values will be used in all cases.
551
+ C IOPT = 1 means optional input is being used.
552
+ C
553
+ C RWORK = A real working array (double precision).
554
+ C The length of RWORK must be at least
555
+ C 20 + NYH*(MAXORD + 1) + 3*NEQ + LWM where
556
+ C NYH = the initial value of NEQ,
557
+ C MAXORD = 12 (if METH = 1) or 5 (if METH = 2) (unless a
558
+ C smaller value is given as an optional input),
559
+ C LWM = length of work space for matrix-related data..
560
+ C LWM = 0 if MITER = 0,
561
+ C LWM = 2*NEQ**2 + 2 if MITER = 1 or 2, and MF.gt.0,
562
+ C LWM = NEQ**2 + 2 if MITER = 1 or 2, and MF.lt.0,
563
+ C LWM = NEQ + 2 if MITER = 3,
564
+ C LWM = (3*ML+2*MU+2)*NEQ + 2 if MITER = 4 or 5, and MF.gt.0,
565
+ C LWM = (2*ML+MU+1)*NEQ + 2 if MITER = 4 or 5, and MF.lt.0.
566
+ C (See the MF description for METH and MITER.)
567
+ C Thus if MAXORD has its default value and NEQ is constant,
568
+ C this length is..
569
+ C 20 + 16*NEQ for MF = 10,
570
+ C 22 + 16*NEQ + 2*NEQ**2 for MF = 11 or 12,
571
+ C 22 + 16*NEQ + NEQ**2 for MF = -11 or -12,
572
+ C 22 + 17*NEQ for MF = 13,
573
+ C 22 + 18*NEQ + (3*ML+2*MU)*NEQ for MF = 14 or 15,
574
+ C 22 + 17*NEQ + (2*ML+MU)*NEQ for MF = -14 or -15,
575
+ C 20 + 9*NEQ for MF = 20,
576
+ C 22 + 9*NEQ + 2*NEQ**2 for MF = 21 or 22,
577
+ C 22 + 9*NEQ + NEQ**2 for MF = -21 or -22,
578
+ C 22 + 10*NEQ for MF = 23,
579
+ C 22 + 11*NEQ + (3*ML+2*MU)*NEQ for MF = 24 or 25.
580
+ C 22 + 10*NEQ + (2*ML+MU)*NEQ for MF = -24 or -25.
581
+ C The first 20 words of RWORK are reserved for conditional
582
+ C and optional input and optional output.
583
+ C
584
+ C The following word in RWORK is a conditional input..
585
+ C RWORK(1) = TCRIT = critical value of t which the solver
586
+ C is not to overshoot. Required if ITASK is
587
+ C 4 or 5, and ignored otherwise. (See ITASK.)
588
+ C
589
+ C LRW = The length of the array RWORK, as declared by the user.
590
+ C (This will be checked by the solver.)
591
+ C
592
+ C IWORK = An integer work array. The length of IWORK must be at least
593
+ C 30 if MITER = 0 or 3 (MF = 10, 13, 20, 23), or
594
+ C 30 + NEQ otherwise (abs(MF) = 11,12,14,15,21,22,24,25).
595
+ C The first 30 words of IWORK are reserved for conditional and
596
+ C optional input and optional output.
597
+ C
598
+ C The following 2 words in IWORK are conditional input..
599
+ C IWORK(1) = ML These are the lower and upper
600
+ C IWORK(2) = MU half-bandwidths, respectively, of the
601
+ C banded Jacobian, excluding the main diagonal.
602
+ C The band is defined by the matrix locations
603
+ C (i,j) with i-ML .le. j .le. i+MU. ML and MU
604
+ C must satisfy 0 .le. ML,MU .le. NEQ-1.
605
+ C These are required if MITER is 4 or 5, and
606
+ C ignored otherwise. ML and MU may in fact be
607
+ C the band parameters for a matrix to which
608
+ C df/dy is only approximately equal.
609
+ C
610
+ C LIW = the length of the array IWORK, as declared by the user.
611
+ C (This will be checked by the solver.)
612
+ C
613
+ C Note.. The work arrays must not be altered between calls to DVODE
614
+ C for the same problem, except possibly for the conditional and
615
+ C optional input, and except for the last 3*NEQ words of RWORK.
616
+ C The latter space is used for internal scratch space, and so is
617
+ C available for use by the user outside DVODE between calls, if
618
+ C desired (but not for use by F or JAC).
619
+ C
620
+ C JAC = The name of the user-supplied routine (MITER = 1 or 4) to
621
+ C compute the Jacobian matrix, df/dy, as a function of
622
+ C the scalar t and the vector y. It is to have the form
623
+ C SUBROUTINE JAC (NEQ, T, Y, ML, MU, PD, NROWPD,
624
+ C RPAR, IPAR)
625
+ C DOUBLE PRECISION T, Y, PD, RPAR
626
+ C DIMENSION Y(NEQ), PD(NROWPD, NEQ)
627
+ C where NEQ, T, Y, ML, MU, and NROWPD are input and the array
628
+ C PD is to be loaded with partial derivatives (elements of the
629
+ C Jacobian matrix) in the output. PD must be given a first
630
+ C dimension of NROWPD. T and Y have the same meaning as in
631
+ C Subroutine F. (In the DIMENSION statement above, NEQ can
632
+ C be replaced by * to make Y and PD assumed size arrays.)
633
+ C In the full matrix case (MITER = 1), ML and MU are
634
+ C ignored, and the Jacobian is to be loaded into PD in
635
+ C columnwise manner, with df(i)/dy(j) loaded into PD(i,j).
636
+ C In the band matrix case (MITER = 4), the elements
637
+ C within the band are to be loaded into PD in columnwise
638
+ C manner, with diagonal lines of df/dy loaded into the rows
639
+ C of PD. Thus df(i)/dy(j) is to be loaded into PD(i-j+MU+1,j).
640
+ C ML and MU are the half-bandwidth parameters. (See IWORK).
641
+ C The locations in PD in the two triangular areas which
642
+ C correspond to nonexistent matrix elements can be ignored
643
+ C or loaded arbitrarily, as they are overwritten by DVODE.
644
+ C JAC need not provide df/dy exactly. A crude
645
+ C approximation (possibly with a smaller bandwidth) will do.
646
+ C In either case, PD is preset to zero by the solver,
647
+ C so that only the nonzero elements need be loaded by JAC.
648
+ C Each call to JAC is preceded by a call to F with the same
649
+ C arguments NEQ, T, and Y. Thus to gain some efficiency,
650
+ C intermediate quantities shared by both calculations may be
651
+ C saved in a user COMMON block by F and not recomputed by JAC,
652
+ C if desired. Also, JAC may alter the Y array, if desired.
653
+ C JAC must be declared external in the calling program.
654
+ C Subroutine JAC may access user-defined real and integer
655
+ C work arrays, RPAR and IPAR, whose dimensions are set by the
656
+ C user in the main program.
657
+ C
658
+ C MF = The method flag. Used only for input. The legal values of
659
+ C MF are 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25,
660
+ C -11, -12, -14, -15, -21, -22, -24, -25.
661
+ C MF is a signed two-digit integer, MF = JSV*(10*METH + MITER).
662
+ C JSV = SIGN(MF) indicates the Jacobian-saving strategy..
663
+ C JSV = 1 means a copy of the Jacobian is saved for reuse
664
+ C in the corrector iteration algorithm.
665
+ C JSV = -1 means a copy of the Jacobian is not saved
666
+ C (valid only for MITER = 1, 2, 4, or 5).
667
+ C METH indicates the basic linear multistep method..
668
+ C METH = 1 means the implicit Adams method.
669
+ C METH = 2 means the method based on backward
670
+ C differentiation formulas (BDF-s).
671
+ C MITER indicates the corrector iteration method..
672
+ C MITER = 0 means functional iteration (no Jacobian matrix
673
+ C is involved).
674
+ C MITER = 1 means chord iteration with a user-supplied
675
+ C full (NEQ by NEQ) Jacobian.
676
+ C MITER = 2 means chord iteration with an internally
677
+ C generated (difference quotient) full Jacobian
678
+ C (using NEQ extra calls to F per df/dy value).
679
+ C MITER = 3 means chord iteration with an internally
680
+ C generated diagonal Jacobian approximation
681
+ C (using 1 extra call to F per df/dy evaluation).
682
+ C MITER = 4 means chord iteration with a user-supplied
683
+ C banded Jacobian.
684
+ C MITER = 5 means chord iteration with an internally
685
+ C generated banded Jacobian (using ML+MU+1 extra
686
+ C calls to F per df/dy evaluation).
687
+ C If MITER = 1 or 4, the user must supply a subroutine JAC
688
+ C (the name is arbitrary) as described above under JAC.
689
+ C For other values of MITER, a dummy argument can be used.
690
+ C
691
+ C RPAR User-specified array used to communicate real parameters
692
+ C to user-supplied subroutines. If RPAR is a vector, then
693
+ C it must be dimensioned in the user's main program. If it
694
+ C is unused or it is a scalar, then it need not be
695
+ C dimensioned.
696
+ C
697
+ C IPAR User-specified array used to communicate integer parameter
698
+ C to user-supplied subroutines. The comments on dimensioning
699
+ C RPAR apply to IPAR.
700
+ C-----------------------------------------------------------------------
701
+ C Optional Input.
702
+ C
703
+ C The following is a list of the optional input provided for in the
704
+ C call sequence. (See also Part ii.) For each such input variable,
705
+ C this table lists its name as used in this documentation, its
706
+ C location in the call sequence, its meaning, and the default value.
707
+ C The use of any of this input requires IOPT = 1, and in that
708
+ C case all of this input is examined. A value of zero for any
709
+ C of these optional input variables will cause the default value to be
710
+ C used. Thus to use a subset of the optional input, simply preload
711
+ C locations 5 to 10 in RWORK and IWORK to 0.0 and 0 respectively, and
712
+ C then set those of interest to nonzero values.
713
+ C
714
+ C NAME LOCATION MEANING AND DEFAULT VALUE
715
+ C
716
+ C H0 RWORK(5) The step size to be attempted on the first step.
717
+ C The default value is determined by the solver.
718
+ C
719
+ C HMAX RWORK(6) The maximum absolute step size allowed.
720
+ C The default value is infinite.
721
+ C
722
+ C HMIN RWORK(7) The minimum absolute step size allowed.
723
+ C The default value is 0. (This lower bound is not
724
+ C enforced on the final step before reaching TCRIT
725
+ C when ITASK = 4 or 5.)
726
+ C
727
+ C MAXORD IWORK(5) The maximum order to be allowed. The default
728
+ C value is 12 if METH = 1, and 5 if METH = 2.
729
+ C If MAXORD exceeds the default value, it will
730
+ C be reduced to the default value.
731
+ C If MAXORD is changed during the problem, it may
732
+ C cause the current order to be reduced.
733
+ C
734
+ C MXSTEP IWORK(6) Maximum number of (internally defined) steps
735
+ C allowed during one call to the solver.
736
+ C The default value is 500.
737
+ C
738
+ C MXHNIL IWORK(7) Maximum number of messages printed (per problem)
739
+ C warning that T + H = T on a step (H = step size).
740
+ C This must be positive to result in a non-default
741
+ C value. The default value is 10.
742
+ C
743
+ C-----------------------------------------------------------------------
744
+ C Optional Output.
745
+ C
746
+ C As optional additional output from DVODE, the variables listed
747
+ C below are quantities related to the performance of DVODE
748
+ C which are available to the user. These are communicated by way of
749
+ C the work arrays, but also have internal mnemonic names as shown.
750
+ C Except where stated otherwise, all of this output is defined
751
+ C on any successful return from DVODE, and on any return with
752
+ C ISTATE = -1, -2, -4, -5, or -6. On an illegal input return
753
+ C (ISTATE = -3), they will be unchanged from their existing values
754
+ C (if any), except possibly for TOLSF, LENRW, and LENIW.
755
+ C On any error return, output relevant to the error will be defined,
756
+ C as noted below.
757
+ C
758
+ C NAME LOCATION MEANING
759
+ C
760
+ C HU RWORK(11) The step size in t last used (successfully).
761
+ C
762
+ C HCUR RWORK(12) The step size to be attempted on the next step.
763
+ C
764
+ C TCUR RWORK(13) The current value of the independent variable
765
+ C which the solver has actually reached, i.e. the
766
+ C current internal mesh point in t. In the output,
767
+ C TCUR will always be at least as far from the
768
+ C initial value of t as the current argument T,
769
+ C but may be farther (if interpolation was done).
770
+ C
771
+ C TOLSF RWORK(14) A tolerance scale factor, greater than 1.0,
772
+ C computed when a request for too much accuracy was
773
+ C detected (ISTATE = -3 if detected at the start of
774
+ C the problem, ISTATE = -2 otherwise). If ITOL is
775
+ C left unaltered but RTOL and ATOL are uniformly
776
+ C scaled up by a factor of TOLSF for the next call,
777
+ C then the solver is deemed likely to succeed.
778
+ C (The user may also ignore TOLSF and alter the
779
+ C tolerance parameters in any other way appropriate.)
780
+ C
781
+ C NST IWORK(11) The number of steps taken for the problem so far.
782
+ C
783
+ C NFE IWORK(12) The number of f evaluations for the problem so far.
784
+ C
785
+ C NJE IWORK(13) The number of Jacobian evaluations so far.
786
+ C
787
+ C NQU IWORK(14) The method order last used (successfully).
788
+ C
789
+ C NQCUR IWORK(15) The order to be attempted on the next step.
790
+ C
791
+ C IMXER IWORK(16) The index of the component of largest magnitude in
792
+ C the weighted local error vector ( e(i)/EWT(i) ),
793
+ C on an error return with ISTATE = -4 or -5.
794
+ C
795
+ C LENRW IWORK(17) The length of RWORK actually required.
796
+ C This is defined on normal returns and on an illegal
797
+ C input return for insufficient storage.
798
+ C
799
+ C LENIW IWORK(18) The length of IWORK actually required.
800
+ C This is defined on normal returns and on an illegal
801
+ C input return for insufficient storage.
802
+ C
803
+ C NLU IWORK(19) The number of matrix LU decompositions so far.
804
+ C
805
+ C NNI IWORK(20) The number of nonlinear (Newton) iterations so far.
806
+ C
807
+ C NCFN IWORK(21) The number of convergence failures of the nonlinear
808
+ C solver so far.
809
+ C
810
+ C NETF IWORK(22) The number of error test failures of the integrator
811
+ C so far.
812
+ C
813
+ C The following two arrays are segments of the RWORK array which
814
+ C may also be of interest to the user as optional output.
815
+ C For each array, the table below gives its internal name,
816
+ C its base address in RWORK, and its description.
817
+ C
818
+ C NAME BASE ADDRESS DESCRIPTION
819
+ C
820
+ C YH 21 The Nordsieck history array, of size NYH by
821
+ C (NQCUR + 1), where NYH is the initial value
822
+ C of NEQ. For j = 0,1,...,NQCUR, column j+1
823
+ C of YH contains HCUR**j/factorial(j) times
824
+ C the j-th derivative of the interpolating
825
+ C polynomial currently representing the
826
+ C solution, evaluated at t = TCUR.
827
+ C
828
+ C ACOR LENRW-NEQ+1 Array of size NEQ used for the accumulated
829
+ C corrections on each step, scaled in the output
830
+ C to represent the estimated local error in Y
831
+ C on the last step. This is the vector e in
832
+ C the description of the error control. It is
833
+ C defined only on a successful return from DVODE.
834
+ C
835
+ C-----------------------------------------------------------------------
836
+ C Interrupting and Restarting
837
+ C
838
+ C If the integration of a given problem by DVODE is to be
839
+ C interrrupted and then later continued, such as when restarting
840
+ C an interrupted run or alternating between two or more ODE problems,
841
+ C the user should save, following the return from the last DVODE call
842
+ C prior to the interruption, the contents of the call sequence
843
+ C variables and internal COMMON blocks, and later restore these
844
+ C values before the next DVODE call for that problem. To save
845
+ C and restore the COMMON blocks, use subroutine DVSRCO, as
846
+ C described below in part ii.
847
+ C
848
+ C In addition, if non-default values for either LUN or MFLAG are
849
+ C desired, an extra call to XSETUN and/or XSETF should be made just
850
+ C before continuing the integration. See Part ii below for details.
851
+ C
852
+ C-----------------------------------------------------------------------
853
+ C Part ii. Other Routines Callable.
854
+ C
855
+ C The following are optional calls which the user may make to
856
+ C gain additional capabilities in conjunction with DVODE.
857
+ C (The routines XSETUN and XSETF are designed to conform to the
858
+ C SLATEC error handling package.)
859
+ C
860
+ C FORM OF CALL FUNCTION
861
+ C CALL XSETUN(LUN) Set the logical unit number, LUN, for
862
+ C output of messages from DVODE, if
863
+ C the default is not desired.
864
+ C The default value of LUN is 6.
865
+ C
866
+ C CALL XSETF(MFLAG) Set a flag to control the printing of
867
+ C messages by DVODE.
868
+ C MFLAG = 0 means do not print. (Danger..
869
+ C This risks losing valuable information.)
870
+ C MFLAG = 1 means print (the default).
871
+ C
872
+ C Either of the above calls may be made at
873
+ C any time and will take effect immediately.
874
+ C
875
+ C CALL DVSRCO(RSAV,ISAV,JOB) Saves and restores the contents of
876
+ C the internal COMMON blocks used by
877
+ C DVODE. (See Part iii below.)
878
+ C RSAV must be a real array of length 49
879
+ C or more, and ISAV must be an integer
880
+ C array of length 40 or more.
881
+ C JOB=1 means save COMMON into RSAV/ISAV.
882
+ C JOB=2 means restore COMMON from RSAV/ISAV.
883
+ C DVSRCO is useful if one is
884
+ C interrupting a run and restarting
885
+ C later, or alternating between two or
886
+ C more problems solved with DVODE.
887
+ C
888
+ C CALL DVINDY(,,,,,) Provide derivatives of y, of various
889
+ C (See below.) orders, at a specified point T, if
890
+ C desired. It may be called only after
891
+ C a successful return from DVODE.
892
+ C
893
+ C The detailed instructions for using DVINDY are as follows.
894
+ C The form of the call is..
895
+ C
896
+ C CALL DVINDY (T, K, RWORK(21), NYH, DKY, IFLAG)
897
+ C
898
+ C The input parameters are..
899
+ C
900
+ C T = Value of independent variable where answers are desired
901
+ C (normally the same as the T last returned by DVODE).
902
+ C For valid results, T must lie between TCUR - HU and TCUR.
903
+ C (See optional output for TCUR and HU.)
904
+ C K = Integer order of the derivative desired. K must satisfy
905
+ C 0 .le. K .le. NQCUR, where NQCUR is the current order
906
+ C (see optional output). The capability corresponding
907
+ C to K = 0, i.e. computing y(T), is already provided
908
+ C by DVODE directly. Since NQCUR .ge. 1, the first
909
+ C derivative dy/dt is always available with DVINDY.
910
+ C RWORK(21) = The base address of the history array YH.
911
+ C NYH = Column length of YH, equal to the initial value of NEQ.
912
+ C
913
+ C The output parameters are..
914
+ C
915
+ C DKY = A real array of length NEQ containing the computed value
916
+ C of the K-th derivative of y(t).
917
+ C IFLAG = Integer flag, returned as 0 if K and T were legal,
918
+ C -1 if K was illegal, and -2 if T was illegal.
919
+ C On an error return, a message is also written.
920
+ C-----------------------------------------------------------------------
921
+ C Part iii. COMMON Blocks.
922
+ C If DVODE is to be used in an overlay situation, the user
923
+ C must declare, in the primary overlay, the variables in..
924
+ C (1) the call sequence to DVODE,
925
+ C (2) the two internal COMMON blocks
926
+ C /DVOD01/ of length 81 (48 double precision words
927
+ C followed by 33 integer words),
928
+ C /DVOD02/ of length 9 (1 double precision word
929
+ C followed by 8 integer words),
930
+ C
931
+ C If DVODE is used on a system in which the contents of internal
932
+ C COMMON blocks are not preserved between calls, the user should
933
+ C declare the above two COMMON blocks in his main program to insure
934
+ C that their contents are preserved.
935
+ C
936
+ C-----------------------------------------------------------------------
937
+ C Part iv. Optionally Replaceable Solver Routines.
938
+ C
939
+ C Below are descriptions of two routines in the DVODE package which
940
+ C relate to the measurement of errors. Either routine can be
941
+ C replaced by a user-supplied version, if desired. However, since such
942
+ C a replacement may have a major impact on performance, it should be
943
+ C done only when absolutely necessary, and only with great caution.
944
+ C (Note.. The means by which the package version of a routine is
945
+ C superseded by the user's version may be system-dependent.)
946
+ C
947
+ C (a) DEWSET.
948
+ C The following subroutine is called just before each internal
949
+ C integration step, and sets the array of error weights, EWT, as
950
+ C described under ITOL/RTOL/ATOL above..
951
+ C SUBROUTINE DEWSET (NEQ, ITOL, RTOL, ATOL, YCUR, EWT)
952
+ C where NEQ, ITOL, RTOL, and ATOL are as in the DVODE call sequence,
953
+ C YCUR contains the current dependent variable vector, and
954
+ C EWT is the array of weights set by DEWSET.
955
+ C
956
+ C If the user supplies this subroutine, it must return in EWT(i)
957
+ C (i = 1,...,NEQ) a positive quantity suitable for comparison with
958
+ C errors in Y(i). The EWT array returned by DEWSET is passed to the
959
+ C DVNORM routine (See below.), and also used by DVODE in the computation
960
+ C of the optional output IMXER, the diagonal Jacobian approximation,
961
+ C and the increments for difference quotient Jacobians.
962
+ C
963
+ C In the user-supplied version of DEWSET, it may be desirable to use
964
+ C the current values of derivatives of y. Derivatives up to order NQ
965
+ C are available from the history array YH, described above under
966
+ C Optional Output. In DEWSET, YH is identical to the YCUR array,
967
+ C extended to NQ + 1 columns with a column length of NYH and scale
968
+ C factors of h**j/factorial(j). On the first call for the problem,
969
+ C given by NST = 0, NQ is 1 and H is temporarily set to 1.0.
970
+ C NYH is the initial value of NEQ. The quantities NQ, H, and NST
971
+ C can be obtained by including in DEWSET the statements..
972
+ C DOUBLE PRECISION RVOD, H, HU
973
+ C COMMON /DVOD01/ RVOD(48), IVOD(33)
974
+ C COMMON /DVOD02/ HU, NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
975
+ C NQ = IVOD(28)
976
+ C H = RVOD(21)
977
+ C Thus, for example, the current value of dy/dt can be obtained as
978
+ C YCUR(NYH+i)/H (i=1,...,NEQ) (and the division by H is
979
+ C unnecessary when NST = 0).
980
+ C
981
+ C (b) DVNORM.
982
+ C The following is a real function routine which computes the weighted
983
+ C root-mean-square norm of a vector v..
984
+ C D = DVNORM (N, V, W)
985
+ C where..
986
+ C N = the length of the vector,
987
+ C V = real array of length N containing the vector,
988
+ C W = real array of length N containing weights,
989
+ C D = sqrt( (1/N) * sum(V(i)*W(i))**2 ).
990
+ C DVNORM is called with N = NEQ and with W(i) = 1.0/EWT(i), where
991
+ C EWT is as set by subroutine DEWSET.
992
+ C
993
+ C If the user supplies this function, it should return a non-negative
994
+ C value of DVNORM suitable for use in the error control in DVODE.
995
+ C None of the arguments should be altered by DVNORM.
996
+ C For example, a user-supplied DVNORM routine might..
997
+ C -substitute a max-norm of (V(i)*W(i)) for the rms-norm, or
998
+ C -ignore some components of V in the norm, with the effect of
999
+ C suppressing the error control on those components of Y.
1000
+ C-----------------------------------------------------------------------
1001
+ C Other Routines in the DVODE Package.
1002
+ C
1003
+ C In addition to subroutine DVODE, the DVODE package includes the
1004
+ C following subroutines and function routines..
1005
+ C DVHIN computes an approximate step size for the initial step.
1006
+ C DVINDY computes an interpolated value of the y vector at t = TOUT.
1007
+ C DVSTEP is the core integrator, which does one step of the
1008
+ C integration and the associated error control.
1009
+ C DVSET sets all method coefficients and test constants.
1010
+ C DVNLSD solves the underlying nonlinear system -- the corrector.
1011
+ C DVJAC computes and preprocesses the Jacobian matrix J = df/dy
1012
+ C and the Newton iteration matrix P = I - (h/l1)*J.
1013
+ C DVSOL manages solution of linear system in chord iteration.
1014
+ C DVJUST adjusts the history array on a change of order.
1015
+ C DEWSET sets the error weight vector EWT before each step.
1016
+ C DVNORM computes the weighted r.m.s. norm of a vector.
1017
+ C DVSRCO is a user-callable routine to save and restore
1018
+ C the contents of the internal COMMON blocks.
1019
+ C DACOPY is a routine to copy one two-dimensional array to another.
1020
+ C DGETRF and DGETRS are routines from LAPACK for solving full
1021
+ C systems of linear algebraic equations.
1022
+ C DGBTRF and DGBTRS are routines from LAPACK for solving banded
1023
+ C linear systems.
1024
+ C DAXPY, DSCAL, and DCOPY are basic linear algebra modules (BLAS).
1025
+ C D1MACH sets the unit roundoff of the machine.
1026
+ C XERRWD, XSETUN, XSETF, and IXSAV handle the printing of all
1027
+ C error messages and warnings. XERRWD is machine-dependent.
1028
+ C Note.. DVNORM, D1MACH, and IXSAV are function routines.
1029
+ C All the others are subroutines.
1030
+ C
1031
+ C The intrinsic and external routines used by the DVODE package are..
1032
+ C ABS, MAX, MIN, REAL, SIGN, SQRT, and WRITE.
1033
+ C
1034
+ C-----------------------------------------------------------------------
1035
+ C
1036
+ C Type declarations for labeled COMMON block DVOD01 --------------------
1037
+ C
1038
+ DOUBLE PRECISION ACNRM, CCMXJ, CONP, CRATE, DRC, EL,
1039
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
1040
+ 2 RC, RL1, TAU, TQ, TN, UROUND
1041
+ INTEGER ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
1042
+ 1 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
1043
+ 2 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
1044
+ 3 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
1045
+ 4 NSLP, NYH
1046
+ C
1047
+ C Type declarations for labeled COMMON block DVOD02 --------------------
1048
+ C
1049
+ DOUBLE PRECISION HU
1050
+ INTEGER NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
1051
+ C
1052
+ C Type declarations for local variables --------------------------------
1053
+ C
1054
+ EXTERNAL DVNLSD
1055
+ LOGICAL IHIT
1056
+ DOUBLE PRECISION ATOLI, BIG, EWTI, FOUR, H0, HMAX, HMX, HUN, ONE,
1057
+ 1 PT2, RH, RTOLI, SIZE, TCRIT, TNEXT, TOLSF, TP, TWO, ZERO
1058
+ INTEGER I, IER, IFLAG, IMXER, JCO, KGO, LENIW, LENJ, LENP, LENRW,
1059
+ 1 LENWM, LF0, MBAND, MFA, ML, MORD, MU, MXHNL0, MXSTP0, NITER,
1060
+ 2 NSLAST
1061
+ CHARACTER*80 MSG
1062
+ C
1063
+ C Type declaration for function subroutines called ---------------------
1064
+ C
1065
+ DOUBLE PRECISION D1MACH, DVNORM
1066
+ C
1067
+ DIMENSION MORD(2)
1068
+ C-----------------------------------------------------------------------
1069
+ C The following Fortran-77 declaration is to cause the values of the
1070
+ C listed (local) variables to be saved between calls to DVODE.
1071
+ C-----------------------------------------------------------------------
1072
+ SAVE MORD, MXHNL0, MXSTP0
1073
+ SAVE ZERO, ONE, TWO, FOUR, PT2, HUN
1074
+ C-----------------------------------------------------------------------
1075
+ C The following internal COMMON blocks contain variables which are
1076
+ C communicated between subroutines in the DVODE package, or which are
1077
+ C to be saved between calls to DVODE.
1078
+ C In each block, real variables precede integers.
1079
+ C The block /DVOD01/ appears in subroutines DVODE, DVINDY, DVSTEP,
1080
+ C DVSET, DVNLSD, DVJAC, DVSOL, DVJUST and DVSRCO.
1081
+ C The block /DVOD02/ appears in subroutines DVODE, DVINDY, DVSTEP,
1082
+ C DVNLSD, DVJAC, and DVSRCO.
1083
+ C
1084
+ C The variables stored in the internal COMMON blocks are as follows..
1085
+ C
1086
+ C ACNRM = Weighted r.m.s. norm of accumulated correction vectors.
1087
+ C CCMXJ = Threshhold on DRC for updating the Jacobian. (See DRC.)
1088
+ C CONP = The saved value of TQ(5).
1089
+ C CRATE = Estimated corrector convergence rate constant.
1090
+ C DRC = Relative change in H*RL1 since last DVJAC call.
1091
+ C EL = Real array of integration coefficients. See DVSET.
1092
+ C ETA = Saved tentative ratio of new to old H.
1093
+ C ETAMAX = Saved maximum value of ETA to be allowed.
1094
+ C H = The step size.
1095
+ C HMIN = The minimum absolute value of the step size H to be used.
1096
+ C HMXI = Inverse of the maximum absolute value of H to be used.
1097
+ C HMXI = 0.0 is allowed and corresponds to an infinite HMAX.
1098
+ C HNEW = The step size to be attempted on the next step.
1099
+ C HSCAL = Stepsize in scaling of YH array.
1100
+ C PRL1 = The saved value of RL1.
1101
+ C RC = Ratio of current H*RL1 to value on last DVJAC call.
1102
+ C RL1 = The reciprocal of the coefficient EL(1).
1103
+ C TAU = Real vector of past NQ step sizes, length 13.
1104
+ C TQ = A real vector of length 5 in which DVSET stores constants
1105
+ C used for the convergence test, the error test, and the
1106
+ C selection of H at a new order.
1107
+ C TN = The independent variable, updated on each step taken.
1108
+ C UROUND = The machine unit roundoff. The smallest positive real number
1109
+ C such that 1.0 + UROUND .ne. 1.0
1110
+ C ICF = Integer flag for convergence failure in DVNLSD..
1111
+ C 0 means no failures.
1112
+ C 1 means convergence failure with out of date Jacobian
1113
+ C (recoverable error).
1114
+ C 2 means convergence failure with current Jacobian or
1115
+ C singular matrix (unrecoverable error).
1116
+ C INIT = Saved integer flag indicating whether initialization of the
1117
+ C problem has been done (INIT = 1) or not.
1118
+ C IPUP = Saved flag to signal updating of Newton matrix.
1119
+ C JCUR = Output flag from DVJAC showing Jacobian status..
1120
+ C JCUR = 0 means J is not current.
1121
+ C JCUR = 1 means J is current.
1122
+ C JSTART = Integer flag used as input to DVSTEP..
1123
+ C 0 means perform the first step.
1124
+ C 1 means take a new step continuing from the last.
1125
+ C -1 means take the next step with a new value of MAXORD,
1126
+ C HMIN, HMXI, N, METH, MITER, and/or matrix parameters.
1127
+ C On return, DVSTEP sets JSTART = 1.
1128
+ C JSV = Integer flag for Jacobian saving, = sign(MF).
1129
+ C KFLAG = A completion code from DVSTEP with the following meanings..
1130
+ C 0 the step was succesful.
1131
+ C -1 the requested error could not be achieved.
1132
+ C -2 corrector convergence could not be achieved.
1133
+ C -3, -4 fatal error in VNLS (can not occur here).
1134
+ C KUTH = Input flag to DVSTEP showing whether H was reduced by the
1135
+ C driver. KUTH = 1 if H was reduced, = 0 otherwise.
1136
+ C L = Integer variable, NQ + 1, current order plus one.
1137
+ C LMAX = MAXORD + 1 (used for dimensioning).
1138
+ C LOCJS = A pointer to the saved Jacobian, whose storage starts at
1139
+ C WM(LOCJS), if JSV = 1.
1140
+ C LYH, LEWT, LACOR, LSAVF, LWM, LIWM = Saved integer pointers
1141
+ C to segments of RWORK and IWORK.
1142
+ C MAXORD = The maximum order of integration method to be allowed.
1143
+ C METH/MITER = The method flags. See MF.
1144
+ C MSBJ = The maximum number of steps between J evaluations, = 50.
1145
+ C MXHNIL = Saved value of optional input MXHNIL.
1146
+ C MXSTEP = Saved value of optional input MXSTEP.
1147
+ C N = The number of first-order ODEs, = NEQ.
1148
+ C NEWH = Saved integer to flag change of H.
1149
+ C NEWQ = The method order to be used on the next step.
1150
+ C NHNIL = Saved counter for occurrences of T + H = T.
1151
+ C NQ = Integer variable, the current integration method order.
1152
+ C NQNYH = Saved value of NQ*NYH.
1153
+ C NQWAIT = A counter controlling the frequency of order changes.
1154
+ C An order change is about to be considered if NQWAIT = 1.
1155
+ C NSLJ = The number of steps taken as of the last Jacobian update.
1156
+ C NSLP = Saved value of NST as of last Newton matrix update.
1157
+ C NYH = Saved value of the initial value of NEQ.
1158
+ C HU = The step size in t last used.
1159
+ C NCFN = Number of nonlinear convergence failures so far.
1160
+ C NETF = The number of error test failures of the integrator so far.
1161
+ C NFE = The number of f evaluations for the problem so far.
1162
+ C NJE = The number of Jacobian evaluations so far.
1163
+ C NLU = The number of matrix LU decompositions so far.
1164
+ C NNI = Number of nonlinear iterations so far.
1165
+ C NQU = The method order last used.
1166
+ C NST = The number of steps taken for the problem so far.
1167
+ C-----------------------------------------------------------------------
1168
+ COMMON /DVOD01/ ACNRM, CCMXJ, CONP, CRATE, DRC, EL(13),
1169
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
1170
+ 2 RC, RL1, TAU(13), TQ(5), TN, UROUND,
1171
+ 3 ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
1172
+ 4 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
1173
+ 5 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
1174
+ 6 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
1175
+ 7 NSLP, NYH
1176
+ COMMON /DVOD02/ HU, NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
1177
+ C
1178
+ DATA MORD(1) /12/, MORD(2) /5/, MXSTP0 /500/, MXHNL0 /10/
1179
+ DATA ZERO /0.0D0/, ONE /1.0D0/, TWO /2.0D0/, FOUR /4.0D0/,
1180
+ 1 PT2 /0.2D0/, HUN /100.0D0/
1181
+ C-----------------------------------------------------------------------
1182
+ C Block A.
1183
+ C This code block is executed on every call.
1184
+ C It tests ISTATE and ITASK for legality and branches appropriately.
1185
+ C If ISTATE .gt. 1 but the flag INIT shows that initialization has
1186
+ C not yet been done, an error return occurs.
1187
+ C If ISTATE = 1 and TOUT = T, return immediately.
1188
+ C-----------------------------------------------------------------------
1189
+ IF (ISTATE .LT. 1 .OR. ISTATE .GT. 3) GO TO 601
1190
+ IF (ITASK .LT. 1 .OR. ITASK .GT. 5) GO TO 602
1191
+ IF (ISTATE .EQ. 1) GO TO 10
1192
+ IF (INIT .NE. 1) GO TO 603
1193
+ IF (ISTATE .EQ. 2) GO TO 200
1194
+ GO TO 20
1195
+ 10 INIT = 0
1196
+ IF (TOUT .EQ. T) RETURN
1197
+ C-----------------------------------------------------------------------
1198
+ C Block B.
1199
+ C The next code block is executed for the initial call (ISTATE = 1),
1200
+ C or for a continuation call with parameter changes (ISTATE = 3).
1201
+ C It contains checking of all input and various initializations.
1202
+ C
1203
+ C First check legality of the non-optional input NEQ, ITOL, IOPT,
1204
+ C MF, ML, and MU.
1205
+ C-----------------------------------------------------------------------
1206
+ 20 IF (NEQ .LE. 0) GO TO 604
1207
+ IF (ISTATE .EQ. 1) GO TO 25
1208
+ IF (NEQ .GT. N) GO TO 605
1209
+ 25 N = NEQ
1210
+ IF (ITOL .LT. 1 .OR. ITOL .GT. 4) GO TO 606
1211
+ IF (IOPT .LT. 0 .OR. IOPT .GT. 1) GO TO 607
1212
+ JSV = SIGN(1,MF)
1213
+ MFA = ABS(MF)
1214
+ METH = MFA/10
1215
+ MITER = MFA - 10*METH
1216
+ IF (METH .LT. 1 .OR. METH .GT. 2) GO TO 608
1217
+ IF (MITER .LT. 0 .OR. MITER .GT. 5) GO TO 608
1218
+ IF (MITER .LE. 3) GO TO 30
1219
+ ML = IWORK(1)
1220
+ MU = IWORK(2)
1221
+ IF (ML .LT. 0 .OR. ML .GE. N) GO TO 609
1222
+ IF (MU .LT. 0 .OR. MU .GE. N) GO TO 610
1223
+ 30 CONTINUE
1224
+ C Next process and check the optional input. ---------------------------
1225
+ IF (IOPT .EQ. 1) GO TO 40
1226
+ MAXORD = MORD(METH)
1227
+ MXSTEP = MXSTP0
1228
+ MXHNIL = MXHNL0
1229
+ IF (ISTATE .EQ. 1) H0 = ZERO
1230
+ HMXI = ZERO
1231
+ HMIN = ZERO
1232
+ GO TO 60
1233
+ 40 MAXORD = IWORK(5)
1234
+ IF (MAXORD .LT. 0) GO TO 611
1235
+ IF (MAXORD .EQ. 0) MAXORD = 100
1236
+ MAXORD = MIN(MAXORD,MORD(METH))
1237
+ MXSTEP = IWORK(6)
1238
+ IF (MXSTEP .LT. 0) GO TO 612
1239
+ IF (MXSTEP .EQ. 0) MXSTEP = MXSTP0
1240
+ MXHNIL = IWORK(7)
1241
+ IF (MXHNIL .LT. 0) GO TO 613
1242
+ IF (MXHNIL .EQ. 0) MXHNIL = MXHNL0
1243
+ IF (ISTATE .NE. 1) GO TO 50
1244
+ H0 = RWORK(5)
1245
+ IF ((TOUT - T)*H0 .LT. ZERO) GO TO 614
1246
+ 50 HMAX = RWORK(6)
1247
+ IF (HMAX .LT. ZERO) GO TO 615
1248
+ HMXI = ZERO
1249
+ IF (HMAX .GT. ZERO) HMXI = ONE/HMAX
1250
+ HMIN = RWORK(7)
1251
+ IF (HMIN .LT. ZERO) GO TO 616
1252
+ C-----------------------------------------------------------------------
1253
+ C Set work array pointers and check lengths LRW and LIW.
1254
+ C Pointers to segments of RWORK and IWORK are named by prefixing L to
1255
+ C the name of the segment. E.g., the segment YH starts at RWORK(LYH).
1256
+ C Segments of RWORK (in order) are denoted YH, WM, EWT, SAVF, ACOR.
1257
+ C Within WM, LOCJS is the location of the saved Jacobian (JSV .gt. 0).
1258
+ C-----------------------------------------------------------------------
1259
+ 60 LYH = 21
1260
+ IF (ISTATE .EQ. 1) NYH = N
1261
+ LWM = LYH + (MAXORD + 1)*NYH
1262
+ JCO = MAX(0,JSV)
1263
+ IF (MITER .EQ. 0) LENWM = 0
1264
+ IF (MITER .EQ. 1 .OR. MITER .EQ. 2) THEN
1265
+ LENWM = 2 + (1 + JCO)*N*N
1266
+ LOCJS = N*N + 3
1267
+ ENDIF
1268
+ IF (MITER .EQ. 3) LENWM = 2 + N
1269
+ IF (MITER .EQ. 4 .OR. MITER .EQ. 5) THEN
1270
+ MBAND = ML + MU + 1
1271
+ LENP = (MBAND + ML)*N
1272
+ LENJ = MBAND*N
1273
+ LENWM = 2 + LENP + JCO*LENJ
1274
+ LOCJS = LENP + 3
1275
+ ENDIF
1276
+ LEWT = LWM + LENWM
1277
+ LSAVF = LEWT + N
1278
+ LACOR = LSAVF + N
1279
+ LENRW = LACOR + N - 1
1280
+ IWORK(17) = LENRW
1281
+ LIWM = 1
1282
+ LENIW = 30 + N
1283
+ IF (MITER .EQ. 0 .OR. MITER .EQ. 3) LENIW = 30
1284
+ IWORK(18) = LENIW
1285
+ IF (LENRW .GT. LRW) GO TO 617
1286
+ IF (LENIW .GT. LIW) GO TO 618
1287
+ C Check RTOL and ATOL for legality. ------------------------------------
1288
+ RTOLI = RTOL(1)
1289
+ ATOLI = ATOL(1)
1290
+ DO 70 I = 1,N
1291
+ IF (ITOL .GE. 3) RTOLI = RTOL(I)
1292
+ IF (ITOL .EQ. 2 .OR. ITOL .EQ. 4) ATOLI = ATOL(I)
1293
+ IF (RTOLI .LT. ZERO) GO TO 619
1294
+ IF (ATOLI .LT. ZERO) GO TO 620
1295
+ 70 CONTINUE
1296
+ IF (ISTATE .EQ. 1) GO TO 100
1297
+ C If ISTATE = 3, set flag to signal parameter changes to DVSTEP. -------
1298
+ JSTART = -1
1299
+ IF (NQ .LE. MAXORD) GO TO 90
1300
+ C MAXORD was reduced below NQ. Copy YH(*,MAXORD+2) into SAVF. ---------
1301
+ CALL DCOPY (N, RWORK(LWM), 1, RWORK(LSAVF), 1)
1302
+ C Reload WM(1) = RWORK(LWM), since LWM may have changed. ---------------
1303
+ 90 IF (MITER .GT. 0) RWORK(LWM) = SQRT(UROUND)
1304
+ C bug fix 12 Nov 1998
1305
+ GO TO 200
1306
+ C-----------------------------------------------------------------------
1307
+ C Block C.
1308
+ C The next block is for the initial call only (ISTATE = 1).
1309
+ C It contains all remaining initializations, the initial call to F,
1310
+ C and the calculation of the initial step size.
1311
+ C The error weights in EWT are inverted after being loaded.
1312
+ C-----------------------------------------------------------------------
1313
+ 100 UROUND = D1MACH(4)
1314
+ TN = T
1315
+ IF (ITASK .NE. 4 .AND. ITASK .NE. 5) GO TO 110
1316
+ TCRIT = RWORK(1)
1317
+ IF ((TCRIT - TOUT)*(TOUT - T) .LT. ZERO) GO TO 625
1318
+ IF (H0 .NE. ZERO .AND. (T + H0 - TCRIT)*H0 .GT. ZERO)
1319
+ 1 H0 = TCRIT - T
1320
+ 110 JSTART = 0
1321
+ IF (MITER .GT. 0) RWORK(LWM) = SQRT(UROUND)
1322
+ CCMXJ = PT2
1323
+ MSBJ = 50
1324
+ NHNIL = 0
1325
+ NST = 0
1326
+ NJE = 0
1327
+ NNI = 0
1328
+ NCFN = 0
1329
+ NETF = 0
1330
+ NLU = 0
1331
+ NSLJ = 0
1332
+ NSLAST = 0
1333
+ HU = ZERO
1334
+ NQU = 0
1335
+ C Initial call to F. (LF0 points to YH(*,2).) -------------------------
1336
+ LF0 = LYH + NYH
1337
+ CALL F (N, T, Y, RWORK(LF0), RPAR, IPAR)
1338
+ NFE = 1
1339
+ C Load the initial value vector in YH. ---------------------------------
1340
+ CALL DCOPY (N, Y, 1, RWORK(LYH), 1)
1341
+ C Load and invert the EWT array. (H is temporarily set to 1.0.) -------
1342
+ NQ = 1
1343
+ H = ONE
1344
+ CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
1345
+ DO 120 I = 1,N
1346
+ IF (RWORK(I+LEWT-1) .LE. ZERO) GO TO 621
1347
+ 120 RWORK(I+LEWT-1) = ONE/RWORK(I+LEWT-1)
1348
+ IF (H0 .NE. ZERO) GO TO 180
1349
+ C Call DVHIN to set initial step size H0 to be attempted. --------------
1350
+ CALL DVHIN (N, T, RWORK(LYH), RWORK(LF0), F, RPAR, IPAR, TOUT,
1351
+ 1 UROUND, RWORK(LEWT), ITOL, ATOL, Y, RWORK(LACOR), H0,
1352
+ 2 NITER, IER)
1353
+ NFE = NFE + NITER
1354
+ IF (IER .NE. 0) GO TO 622
1355
+ C Adjust H0 if necessary to meet HMAX bound. ---------------------------
1356
+ 180 RH = ABS(H0)*HMXI
1357
+ IF (RH .GT. ONE) H0 = H0/RH
1358
+ C Load H with H0 and scale YH(*,2) by H0. ------------------------------
1359
+ H = H0
1360
+ CALL DSCAL (N, H0, RWORK(LF0), 1)
1361
+ GO TO 270
1362
+ C-----------------------------------------------------------------------
1363
+ C Block D.
1364
+ C The next code block is for continuation calls only (ISTATE = 2 or 3)
1365
+ C and is to check stop conditions before taking a step.
1366
+ C-----------------------------------------------------------------------
1367
+ 200 NSLAST = NST
1368
+ KUTH = 0
1369
+ GO TO (210, 250, 220, 230, 240), ITASK
1370
+ 210 IF ((TN - TOUT)*H .LT. ZERO) GO TO 250
1371
+ CALL DVINDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
1372
+ IF (IFLAG .NE. 0) GO TO 627
1373
+ T = TOUT
1374
+ GO TO 420
1375
+ 220 TP = TN - HU*(ONE + HUN*UROUND)
1376
+ IF ((TP - TOUT)*H .GT. ZERO) GO TO 623
1377
+ IF ((TN - TOUT)*H .LT. ZERO) GO TO 250
1378
+ GO TO 400
1379
+ 230 TCRIT = RWORK(1)
1380
+ IF ((TN - TCRIT)*H .GT. ZERO) GO TO 624
1381
+ IF ((TCRIT - TOUT)*H .LT. ZERO) GO TO 625
1382
+ IF ((TN - TOUT)*H .LT. ZERO) GO TO 245
1383
+ CALL DVINDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
1384
+ IF (IFLAG .NE. 0) GO TO 627
1385
+ T = TOUT
1386
+ GO TO 420
1387
+ 240 TCRIT = RWORK(1)
1388
+ IF ((TN - TCRIT)*H .GT. ZERO) GO TO 624
1389
+ 245 HMX = ABS(TN) + ABS(H)
1390
+ IHIT = ABS(TN - TCRIT) .LE. HUN*UROUND*HMX
1391
+ IF (IHIT) GO TO 400
1392
+ TNEXT = TN + HNEW*(ONE + FOUR*UROUND)
1393
+ IF ((TNEXT - TCRIT)*H .LE. ZERO) GO TO 250
1394
+ H = (TCRIT - TN)*(ONE - FOUR*UROUND)
1395
+ KUTH = 1
1396
+ C-----------------------------------------------------------------------
1397
+ C Block E.
1398
+ C The next block is normally executed for all calls and contains
1399
+ C the call to the one-step core integrator DVSTEP.
1400
+ C
1401
+ C This is a looping point for the integration steps.
1402
+ C
1403
+ C First check for too many steps being taken, update EWT (if not at
1404
+ C start of problem), check for too much accuracy being requested, and
1405
+ C check for H below the roundoff level in T.
1406
+ C-----------------------------------------------------------------------
1407
+ 250 CONTINUE
1408
+ IF ((NST-NSLAST) .GE. MXSTEP) GO TO 500
1409
+ CALL DEWSET (N, ITOL, RTOL, ATOL, RWORK(LYH), RWORK(LEWT))
1410
+ DO 260 I = 1,N
1411
+ IF (RWORK(I+LEWT-1) .LE. ZERO) GO TO 510
1412
+ 260 RWORK(I+LEWT-1) = ONE/RWORK(I+LEWT-1)
1413
+ 270 TOLSF = UROUND*DVNORM (N, RWORK(LYH), RWORK(LEWT))
1414
+ IF (TOLSF .LE. ONE) GO TO 280
1415
+ TOLSF = TOLSF*TWO
1416
+ IF (NST .EQ. 0) GO TO 626
1417
+ GO TO 520
1418
+ 280 IF ((TN + H) .NE. TN) GO TO 290
1419
+ NHNIL = NHNIL + 1
1420
+ IF (NHNIL .GT. MXHNIL) GO TO 290
1421
+ MSG = 'DVODE-- Warning..internal T (=R1) and H (=R2) are'
1422
+ CALL XERRWD (MSG, 50, 101, 1, 0, 0, 0, 0, ZERO, ZERO)
1423
+ MSG=' such that in the machine, T + H = T on the next step '
1424
+ CALL XERRWD (MSG, 60, 101, 1, 0, 0, 0, 0, ZERO, ZERO)
1425
+ MSG = ' (H = step size). solver will continue anyway'
1426
+ CALL XERRWD (MSG, 50, 101, 1, 0, 0, 0, 2, TN, H)
1427
+ IF (NHNIL .LT. MXHNIL) GO TO 290
1428
+ MSG = 'DVODE-- Above warning has been issued I1 times. '
1429
+ CALL XERRWD (MSG, 50, 102, 1, 0, 0, 0, 0, ZERO, ZERO)
1430
+ MSG = ' it will not be issued again for this problem'
1431
+ CALL XERRWD (MSG, 50, 102, 1, 1, MXHNIL, 0, 0, ZERO, ZERO)
1432
+ 290 CONTINUE
1433
+ C-----------------------------------------------------------------------
1434
+ C CALL DVSTEP (Y, YH, NYH, YH, EWT, SAVF, VSAV, ACOR,
1435
+ C WM, IWM, F, JAC, F, DVNLSD, RPAR, IPAR)
1436
+ C-----------------------------------------------------------------------
1437
+ CALL DVSTEP (Y, RWORK(LYH), NYH, RWORK(LYH), RWORK(LEWT),
1438
+ 1 RWORK(LSAVF), Y, RWORK(LACOR), RWORK(LWM), IWORK(LIWM),
1439
+ 2 F, JAC, F, DVNLSD, RPAR, IPAR)
1440
+ KGO = 1 - KFLAG
1441
+ C Branch on KFLAG. Note..In this version, KFLAG can not be set to -3.
1442
+ C KFLAG .eq. 0, -1, -2
1443
+ GO TO (300, 530, 540), KGO
1444
+ C-----------------------------------------------------------------------
1445
+ C Block F.
1446
+ C The following block handles the case of a successful return from the
1447
+ C core integrator (KFLAG = 0). Test for stop conditions.
1448
+ C-----------------------------------------------------------------------
1449
+ 300 INIT = 1
1450
+ KUTH = 0
1451
+ GO TO (310, 400, 330, 340, 350), ITASK
1452
+ C ITASK = 1. If TOUT has been reached, interpolate. -------------------
1453
+ 310 IF ((TN - TOUT)*H .LT. ZERO) GO TO 250
1454
+ CALL DVINDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
1455
+ T = TOUT
1456
+ GO TO 420
1457
+ C ITASK = 3. Jump to exit if TOUT was reached. ------------------------
1458
+ 330 IF ((TN - TOUT)*H .GE. ZERO) GO TO 400
1459
+ GO TO 250
1460
+ C ITASK = 4. See if TOUT or TCRIT was reached. Adjust H if necessary.
1461
+ 340 IF ((TN - TOUT)*H .LT. ZERO) GO TO 345
1462
+ CALL DVINDY (TOUT, 0, RWORK(LYH), NYH, Y, IFLAG)
1463
+ T = TOUT
1464
+ GO TO 420
1465
+ 345 HMX = ABS(TN) + ABS(H)
1466
+ IHIT = ABS(TN - TCRIT) .LE. HUN*UROUND*HMX
1467
+ IF (IHIT) GO TO 400
1468
+ TNEXT = TN + HNEW*(ONE + FOUR*UROUND)
1469
+ IF ((TNEXT - TCRIT)*H .LE. ZERO) GO TO 250
1470
+ H = (TCRIT - TN)*(ONE - FOUR*UROUND)
1471
+ KUTH = 1
1472
+ GO TO 250
1473
+ C ITASK = 5. See if TCRIT was reached and jump to exit. ---------------
1474
+ 350 HMX = ABS(TN) + ABS(H)
1475
+ IHIT = ABS(TN - TCRIT) .LE. HUN*UROUND*HMX
1476
+ C-----------------------------------------------------------------------
1477
+ C Block G.
1478
+ C The following block handles all successful returns from DVODE.
1479
+ C If ITASK .ne. 1, Y is loaded from YH and T is set accordingly.
1480
+ C ISTATE is set to 2, and the optional output is loaded into the work
1481
+ C arrays before returning.
1482
+ C-----------------------------------------------------------------------
1483
+ 400 CONTINUE
1484
+ CALL DCOPY (N, RWORK(LYH), 1, Y, 1)
1485
+ T = TN
1486
+ IF (ITASK .NE. 4 .AND. ITASK .NE. 5) GO TO 420
1487
+ IF (IHIT) T = TCRIT
1488
+ 420 ISTATE = 2
1489
+ RWORK(11) = HU
1490
+ RWORK(12) = HNEW
1491
+ RWORK(13) = TN
1492
+ IWORK(11) = NST
1493
+ IWORK(12) = NFE
1494
+ IWORK(13) = NJE
1495
+ IWORK(14) = NQU
1496
+ IWORK(15) = NEWQ
1497
+ IWORK(19) = NLU
1498
+ IWORK(20) = NNI
1499
+ IWORK(21) = NCFN
1500
+ IWORK(22) = NETF
1501
+ RETURN
1502
+ C-----------------------------------------------------------------------
1503
+ C Block H.
1504
+ C The following block handles all unsuccessful returns other than
1505
+ C those for illegal input. First the error message routine is called.
1506
+ C if there was an error test or convergence test failure, IMXER is set.
1507
+ C Then Y is loaded from YH, and T is set to TN.
1508
+ C The optional output is loaded into the work arrays before returning.
1509
+ C-----------------------------------------------------------------------
1510
+ C The maximum number of steps was taken before reaching TOUT. ----------
1511
+ 500 MSG = 'DVODE-- At current T (=R1), MXSTEP (=I1) steps '
1512
+ CALL XERRWD (MSG, 50, 201, 1, 0, 0, 0, 0, ZERO, ZERO)
1513
+ MSG = ' taken on this call before reaching TOUT '
1514
+ CALL XERRWD (MSG, 50, 201, 1, 1, MXSTEP, 0, 1, TN, ZERO)
1515
+ ISTATE = -1
1516
+ GO TO 580
1517
+ C EWT(i) .le. 0.0 for some i (not at start of problem). ----------------
1518
+ 510 EWTI = RWORK(LEWT+I-1)
1519
+ MSG = 'DVODE-- At T (=R1), EWT(I1) has become R2 .le. 0.'
1520
+ CALL XERRWD (MSG, 50, 202, 1, 1, I, 0, 2, TN, EWTI)
1521
+ ISTATE = -6
1522
+ GO TO 580
1523
+ C Too much accuracy requested for machine precision. -------------------
1524
+ 520 MSG = 'DVODE-- At T (=R1), too much accuracy requested '
1525
+ CALL XERRWD (MSG, 50, 203, 1, 0, 0, 0, 0, ZERO, ZERO)
1526
+ MSG = ' for precision of machine.. see TOLSF (=R2) '
1527
+ CALL XERRWD (MSG, 50, 203, 1, 0, 0, 0, 2, TN, TOLSF)
1528
+ RWORK(14) = TOLSF
1529
+ ISTATE = -2
1530
+ GO TO 580
1531
+ C KFLAG = -1. Error test failed repeatedly or with ABS(H) = HMIN. -----
1532
+ 530 MSG = 'DVODE-- At T(=R1) and step size H(=R2), the error'
1533
+ CALL XERRWD (MSG, 50, 204, 1, 0, 0, 0, 0, ZERO, ZERO)
1534
+ MSG = ' test failed repeatedly or with abs(H) = HMIN'
1535
+ CALL XERRWD (MSG, 50, 204, 1, 0, 0, 0, 2, TN, H)
1536
+ ISTATE = -4
1537
+ GO TO 560
1538
+ C KFLAG = -2. Convergence failed repeatedly or with ABS(H) = HMIN. ----
1539
+ 540 MSG = 'DVODE-- At T (=R1) and step size H (=R2), the '
1540
+ CALL XERRWD (MSG, 50, 205, 1, 0, 0, 0, 0, ZERO, ZERO)
1541
+ MSG = ' corrector convergence failed repeatedly '
1542
+ CALL XERRWD (MSG, 50, 205, 1, 0, 0, 0, 0, ZERO, ZERO)
1543
+ MSG = ' or with abs(H) = HMIN '
1544
+ CALL XERRWD (MSG, 30, 205, 1, 0, 0, 0, 2, TN, H)
1545
+ ISTATE = -5
1546
+ C Compute IMXER if relevant. -------------------------------------------
1547
+ 560 BIG = ZERO
1548
+ IMXER = 1
1549
+ DO 570 I = 1,N
1550
+ SIZE = ABS(RWORK(I+LACOR-1)*RWORK(I+LEWT-1))
1551
+ IF (BIG .GE. SIZE) GO TO 570
1552
+ BIG = SIZE
1553
+ IMXER = I
1554
+ 570 CONTINUE
1555
+ IWORK(16) = IMXER
1556
+ C Set Y vector, T, and optional output. --------------------------------
1557
+ 580 CONTINUE
1558
+ CALL DCOPY (N, RWORK(LYH), 1, Y, 1)
1559
+ T = TN
1560
+ RWORK(11) = HU
1561
+ RWORK(12) = H
1562
+ RWORK(13) = TN
1563
+ IWORK(11) = NST
1564
+ IWORK(12) = NFE
1565
+ IWORK(13) = NJE
1566
+ IWORK(14) = NQU
1567
+ IWORK(15) = NQ
1568
+ IWORK(19) = NLU
1569
+ IWORK(20) = NNI
1570
+ IWORK(21) = NCFN
1571
+ IWORK(22) = NETF
1572
+ RETURN
1573
+ C-----------------------------------------------------------------------
1574
+ C Block I.
1575
+ C The following block handles all error returns due to illegal input
1576
+ C (ISTATE = -3), as detected before calling the core integrator.
1577
+ C First the error message routine is called. If the illegal input
1578
+ C is a negative ISTATE, the run is aborted (apparent infinite loop).
1579
+ C-----------------------------------------------------------------------
1580
+ 601 MSG = 'DVODE-- ISTATE (=I1) illegal '
1581
+ CALL XERRWD (MSG, 30, 1, 1, 1, ISTATE, 0, 0, ZERO, ZERO)
1582
+ IF (ISTATE .LT. 0) GO TO 800
1583
+ GO TO 700
1584
+ 602 MSG = 'DVODE-- ITASK (=I1) illegal '
1585
+ CALL XERRWD (MSG, 30, 2, 1, 1, ITASK, 0, 0, ZERO, ZERO)
1586
+ GO TO 700
1587
+ 603 MSG='DVODE-- ISTATE (=I1) .gt. 1 but DVODE not initialized '
1588
+ CALL XERRWD (MSG, 60, 3, 1, 1, ISTATE, 0, 0, ZERO, ZERO)
1589
+ GO TO 700
1590
+ 604 MSG = 'DVODE-- NEQ (=I1) .lt. 1 '
1591
+ CALL XERRWD (MSG, 30, 4, 1, 1, NEQ, 0, 0, ZERO, ZERO)
1592
+ GO TO 700
1593
+ 605 MSG = 'DVODE-- ISTATE = 3 and NEQ increased (I1 to I2) '
1594
+ CALL XERRWD (MSG, 50, 5, 1, 2, N, NEQ, 0, ZERO, ZERO)
1595
+ GO TO 700
1596
+ 606 MSG = 'DVODE-- ITOL (=I1) illegal '
1597
+ CALL XERRWD (MSG, 30, 6, 1, 1, ITOL, 0, 0, ZERO, ZERO)
1598
+ GO TO 700
1599
+ 607 MSG = 'DVODE-- IOPT (=I1) illegal '
1600
+ CALL XERRWD (MSG, 30, 7, 1, 1, IOPT, 0, 0, ZERO, ZERO)
1601
+ GO TO 700
1602
+ 608 MSG = 'DVODE-- MF (=I1) illegal '
1603
+ CALL XERRWD (MSG, 30, 8, 1, 1, MF, 0, 0, ZERO, ZERO)
1604
+ GO TO 700
1605
+ 609 MSG = 'DVODE-- ML (=I1) illegal.. .lt.0 or .ge.NEQ (=I2)'
1606
+ CALL XERRWD (MSG, 50, 9, 1, 2, ML, NEQ, 0, ZERO, ZERO)
1607
+ GO TO 700
1608
+ 610 MSG = 'DVODE-- MU (=I1) illegal.. .lt.0 or .ge.NEQ (=I2)'
1609
+ CALL XERRWD (MSG, 50, 10, 1, 2, MU, NEQ, 0, ZERO, ZERO)
1610
+ GO TO 700
1611
+ 611 MSG = 'DVODE-- MAXORD (=I1) .lt. 0 '
1612
+ CALL XERRWD (MSG, 30, 11, 1, 1, MAXORD, 0, 0, ZERO, ZERO)
1613
+ GO TO 700
1614
+ 612 MSG = 'DVODE-- MXSTEP (=I1) .lt. 0 '
1615
+ CALL XERRWD (MSG, 30, 12, 1, 1, MXSTEP, 0, 0, ZERO, ZERO)
1616
+ GO TO 700
1617
+ 613 MSG = 'DVODE-- MXHNIL (=I1) .lt. 0 '
1618
+ CALL XERRWD (MSG, 30, 13, 1, 1, MXHNIL, 0, 0, ZERO, ZERO)
1619
+ GO TO 700
1620
+ 614 MSG = 'DVODE-- TOUT (=R1) behind T (=R2) '
1621
+ CALL XERRWD (MSG, 40, 14, 1, 0, 0, 0, 2, TOUT, T)
1622
+ MSG = ' integration direction is given by H0 (=R1) '
1623
+ CALL XERRWD (MSG, 50, 14, 1, 0, 0, 0, 1, H0, ZERO)
1624
+ GO TO 700
1625
+ 615 MSG = 'DVODE-- HMAX (=R1) .lt. 0.0 '
1626
+ CALL XERRWD (MSG, 30, 15, 1, 0, 0, 0, 1, HMAX, ZERO)
1627
+ GO TO 700
1628
+ 616 MSG = 'DVODE-- HMIN (=R1) .lt. 0.0 '
1629
+ CALL XERRWD (MSG, 30, 16, 1, 0, 0, 0, 1, HMIN, ZERO)
1630
+ GO TO 700
1631
+ 617 CONTINUE
1632
+ MSG='DVODE-- RWORK length needed, LENRW (=I1), exceeds LRW (=I2)'
1633
+ CALL XERRWD (MSG, 60, 17, 1, 2, LENRW, LRW, 0, ZERO, ZERO)
1634
+ GO TO 700
1635
+ 618 CONTINUE
1636
+ MSG='DVODE-- IWORK length needed, LENIW (=I1), exceeds LIW (=I2)'
1637
+ CALL XERRWD (MSG, 60, 18, 1, 2, LENIW, LIW, 0, ZERO, ZERO)
1638
+ GO TO 700
1639
+ 619 MSG = 'DVODE-- RTOL(I1) is R1 .lt. 0.0 '
1640
+ CALL XERRWD (MSG, 40, 19, 1, 1, I, 0, 1, RTOLI, ZERO)
1641
+ GO TO 700
1642
+ 620 MSG = 'DVODE-- ATOL(I1) is R1 .lt. 0.0 '
1643
+ CALL XERRWD (MSG, 40, 20, 1, 1, I, 0, 1, ATOLI, ZERO)
1644
+ GO TO 700
1645
+ 621 EWTI = RWORK(LEWT+I-1)
1646
+ MSG = 'DVODE-- EWT(I1) is R1 .le. 0.0 '
1647
+ CALL XERRWD (MSG, 40, 21, 1, 1, I, 0, 1, EWTI, ZERO)
1648
+ GO TO 700
1649
+ 622 CONTINUE
1650
+ MSG='DVODE-- TOUT (=R1) too close to T(=R2) to start integration'
1651
+ CALL XERRWD (MSG, 60, 22, 1, 0, 0, 0, 2, TOUT, T)
1652
+ GO TO 700
1653
+ 623 CONTINUE
1654
+ MSG='DVODE-- ITASK = I1 and TOUT (=R1) behind TCUR - HU (= R2) '
1655
+ CALL XERRWD (MSG, 60, 23, 1, 1, ITASK, 0, 2, TOUT, TP)
1656
+ GO TO 700
1657
+ 624 CONTINUE
1658
+ MSG='DVODE-- ITASK = 4 or 5 and TCRIT (=R1) behind TCUR (=R2) '
1659
+ CALL XERRWD (MSG, 60, 24, 1, 0, 0, 0, 2, TCRIT, TN)
1660
+ GO TO 700
1661
+ 625 CONTINUE
1662
+ MSG='DVODE-- ITASK = 4 or 5 and TCRIT (=R1) behind TOUT (=R2) '
1663
+ CALL XERRWD (MSG, 60, 25, 1, 0, 0, 0, 2, TCRIT, TOUT)
1664
+ GO TO 700
1665
+ 626 MSG = 'DVODE-- At start of problem, too much accuracy '
1666
+ CALL XERRWD (MSG, 50, 26, 1, 0, 0, 0, 0, ZERO, ZERO)
1667
+ MSG=' requested for precision of machine.. see TOLSF (=R1) '
1668
+ CALL XERRWD (MSG, 60, 26, 1, 0, 0, 0, 1, TOLSF, ZERO)
1669
+ RWORK(14) = TOLSF
1670
+ GO TO 700
1671
+ 627 MSG='DVODE-- Trouble from DVINDY. ITASK = I1, TOUT = R1. '
1672
+ CALL XERRWD (MSG, 60, 27, 1, 1, ITASK, 0, 1, TOUT, ZERO)
1673
+ C
1674
+ 700 CONTINUE
1675
+ ISTATE = -3
1676
+ RETURN
1677
+ C
1678
+ 800 MSG = 'DVODE-- Run aborted.. apparent infinite loop '
1679
+ CALL XERRWD (MSG, 50, 303, 2, 0, 0, 0, 0, ZERO, ZERO)
1680
+ RETURN
1681
+ C----------------------- End of Subroutine DVODE -----------------------
1682
+ END
1683
+ *DECK DVHIN
1684
+ SUBROUTINE DVHIN (N, T0, Y0, YDOT, F, RPAR, IPAR, TOUT, UROUND,
1685
+ 1 EWT, ITOL, ATOL, Y, TEMP, H0, NITER, IER)
1686
+ EXTERNAL F
1687
+ DOUBLE PRECISION T0, Y0, YDOT, RPAR, TOUT, UROUND, EWT, ATOL, Y,
1688
+ 1 TEMP, H0
1689
+ INTEGER N, IPAR, ITOL, NITER, IER
1690
+ DIMENSION Y0(*), YDOT(*), EWT(*), ATOL(*), Y(*),
1691
+ 1 TEMP(*), RPAR(*), IPAR(*)
1692
+ C-----------------------------------------------------------------------
1693
+ C Call sequence input -- N, T0, Y0, YDOT, F, RPAR, IPAR, TOUT, UROUND,
1694
+ C EWT, ITOL, ATOL, Y, TEMP
1695
+ C Call sequence output -- H0, NITER, IER
1696
+ C COMMON block variables accessed -- None
1697
+ C
1698
+ C Subroutines called by DVHIN.. F
1699
+ C Function routines called by DVHIN.. DVNORM
1700
+ C-----------------------------------------------------------------------
1701
+ C This routine computes the step size, H0, to be attempted on the
1702
+ C first step, when the user has not supplied a value for this.
1703
+ C
1704
+ C First we check that TOUT - T0 differs significantly from zero. Then
1705
+ C an iteration is done to approximate the initial second derivative
1706
+ C and this is used to define h from w.r.m.s.norm(h**2 * yddot / 2) = 1.
1707
+ C A bias factor of 1/2 is applied to the resulting h.
1708
+ C The sign of H0 is inferred from the initial values of TOUT and T0.
1709
+ C
1710
+ C Communication with DVHIN is done with the following variables..
1711
+ C
1712
+ C N = Size of ODE system, input.
1713
+ C T0 = Initial value of independent variable, input.
1714
+ C Y0 = Vector of initial conditions, input.
1715
+ C YDOT = Vector of initial first derivatives, input.
1716
+ C F = Name of subroutine for right-hand side f(t,y), input.
1717
+ C RPAR, IPAR = Dummy names for user's real and integer work arrays.
1718
+ C TOUT = First output value of independent variable
1719
+ C UROUND = Machine unit roundoff
1720
+ C EWT, ITOL, ATOL = Error weights and tolerance parameters
1721
+ C as described in the driver routine, input.
1722
+ C Y, TEMP = Work arrays of length N.
1723
+ C H0 = Step size to be attempted, output.
1724
+ C NITER = Number of iterations (and of f evaluations) to compute H0,
1725
+ C output.
1726
+ C IER = The error flag, returned with the value
1727
+ C IER = 0 if no trouble occurred, or
1728
+ C IER = -1 if TOUT and T0 are considered too close to proceed.
1729
+ C-----------------------------------------------------------------------
1730
+ C
1731
+ C Type declarations for local variables --------------------------------
1732
+ C
1733
+ DOUBLE PRECISION AFI, ATOLI, DELYI, H, HALF, HG, HLB, HNEW, HRAT,
1734
+ 1 HUB, HUN, PT1, T1, TDIST, TROUND, TWO, YDDNRM
1735
+ INTEGER I, ITER
1736
+ C
1737
+ C Type declaration for function subroutines called ---------------------
1738
+ C
1739
+ DOUBLE PRECISION DVNORM
1740
+ C-----------------------------------------------------------------------
1741
+ C The following Fortran-77 declaration is to cause the values of the
1742
+ C listed (local) variables to be saved between calls to this integrator.
1743
+ C-----------------------------------------------------------------------
1744
+ SAVE HALF, HUN, PT1, TWO
1745
+ DATA HALF /0.5D0/, HUN /100.0D0/, PT1 /0.1D0/, TWO /2.0D0/
1746
+ C
1747
+ NITER = 0
1748
+ TDIST = ABS(TOUT - T0)
1749
+ TROUND = UROUND*MAX(ABS(T0),ABS(TOUT))
1750
+ IF (TDIST .LT. TWO*TROUND) GO TO 100
1751
+ C
1752
+ C Set a lower bound on h based on the roundoff level in T0 and TOUT. ---
1753
+ HLB = HUN*TROUND
1754
+ C Set an upper bound on h based on TOUT-T0 and the initial Y and YDOT. -
1755
+ HUB = PT1*TDIST
1756
+ ATOLI = ATOL(1)
1757
+ DO 10 I = 1, N
1758
+ IF (ITOL .EQ. 2 .OR. ITOL .EQ. 4) ATOLI = ATOL(I)
1759
+ DELYI = PT1*ABS(Y0(I)) + ATOLI
1760
+ AFI = ABS(YDOT(I))
1761
+ IF (AFI*HUB .GT. DELYI) HUB = DELYI/AFI
1762
+ 10 CONTINUE
1763
+ C
1764
+ C Set initial guess for h as geometric mean of upper and lower bounds. -
1765
+ ITER = 0
1766
+ HG = SQRT(HLB*HUB)
1767
+ C If the bounds have crossed, exit with the mean value. ----------------
1768
+ IF (HUB .LT. HLB) THEN
1769
+ H0 = HG
1770
+ GO TO 90
1771
+ ENDIF
1772
+ C
1773
+ C Looping point for iteration. -----------------------------------------
1774
+ 50 CONTINUE
1775
+ C Estimate the second derivative as a difference quotient in f. --------
1776
+ H = SIGN (HG, TOUT - T0)
1777
+ T1 = T0 + H
1778
+ DO 60 I = 1, N
1779
+ 60 Y(I) = Y0(I) + H*YDOT(I)
1780
+ CALL F (N, T1, Y, TEMP, RPAR, IPAR)
1781
+ DO 70 I = 1, N
1782
+ 70 TEMP(I) = (TEMP(I) - YDOT(I))/H
1783
+ YDDNRM = DVNORM (N, TEMP, EWT)
1784
+ C Get the corresponding new value of h. --------------------------------
1785
+ IF (YDDNRM*HUB*HUB .GT. TWO) THEN
1786
+ HNEW = SQRT(TWO/YDDNRM)
1787
+ ELSE
1788
+ HNEW = SQRT(HG*HUB)
1789
+ ENDIF
1790
+ ITER = ITER + 1
1791
+ C-----------------------------------------------------------------------
1792
+ C Test the stopping conditions.
1793
+ C Stop if the new and previous h values differ by a factor of .lt. 2.
1794
+ C Stop if four iterations have been done. Also, stop with previous h
1795
+ C if HNEW/HG .gt. 2 after first iteration, as this probably means that
1796
+ C the second derivative value is bad because of cancellation error.
1797
+ C-----------------------------------------------------------------------
1798
+ IF (ITER .GE. 4) GO TO 80
1799
+ HRAT = HNEW/HG
1800
+ IF ( (HRAT .GT. HALF) .AND. (HRAT .LT. TWO) ) GO TO 80
1801
+ IF ( (ITER .GE. 2) .AND. (HNEW .GT. TWO*HG) ) THEN
1802
+ HNEW = HG
1803
+ GO TO 80
1804
+ ENDIF
1805
+ HG = HNEW
1806
+ GO TO 50
1807
+ C
1808
+ C Iteration done. Apply bounds, bias factor, and sign. Then exit. ----
1809
+ 80 H0 = HNEW*HALF
1810
+ IF (H0 .LT. HLB) H0 = HLB
1811
+ IF (H0 .GT. HUB) H0 = HUB
1812
+ 90 H0 = SIGN(H0, TOUT - T0)
1813
+ NITER = ITER
1814
+ IER = 0
1815
+ RETURN
1816
+ C Error return for TOUT - T0 too small. --------------------------------
1817
+ 100 IER = -1
1818
+ RETURN
1819
+ C----------------------- End of Subroutine DVHIN -----------------------
1820
+ END
1821
+ *DECK DVINDY
1822
+ SUBROUTINE DVINDY (T, K, YH, LDYH, DKY, IFLAG)
1823
+ DOUBLE PRECISION T, YH, DKY
1824
+ INTEGER K, LDYH, IFLAG
1825
+ DIMENSION YH(LDYH,*), DKY(*)
1826
+ C-----------------------------------------------------------------------
1827
+ C Call sequence input -- T, K, YH, LDYH
1828
+ C Call sequence output -- DKY, IFLAG
1829
+ C COMMON block variables accessed..
1830
+ C /DVOD01/ -- H, TN, UROUND, L, N, NQ
1831
+ C /DVOD02/ -- HU
1832
+ C
1833
+ C Subroutines called by DVINDY.. DSCAL, XERRWD
1834
+ C Function routines called by DVINDY.. None
1835
+ C-----------------------------------------------------------------------
1836
+ C DVINDY computes interpolated values of the K-th derivative of the
1837
+ C dependent variable vector y, and stores it in DKY. This routine
1838
+ C is called within the package with K = 0 and T = TOUT, but may
1839
+ C also be called by the user for any K up to the current order.
1840
+ C (See detailed instructions in the usage documentation.)
1841
+ C-----------------------------------------------------------------------
1842
+ C The computed values in DKY are gotten by interpolation using the
1843
+ C Nordsieck history array YH. This array corresponds uniquely to a
1844
+ C vector-valued polynomial of degree NQCUR or less, and DKY is set
1845
+ C to the K-th derivative of this polynomial at T.
1846
+ C The formula for DKY is..
1847
+ C q
1848
+ C DKY(i) = sum c(j,K) * (T - TN)**(j-K) * H**(-j) * YH(i,j+1)
1849
+ C j=K
1850
+ C where c(j,K) = j*(j-1)*...*(j-K+1), q = NQCUR, TN = TCUR, H = HCUR.
1851
+ C The quantities NQ = NQCUR, L = NQ+1, N, TN, and H are
1852
+ C communicated by COMMON. The above sum is done in reverse order.
1853
+ C IFLAG is returned negative if either K or T is out of bounds.
1854
+ C
1855
+ C Discussion above and comments in driver explain all variables.
1856
+ C-----------------------------------------------------------------------
1857
+ C
1858
+ C Type declarations for labeled COMMON block DVOD01 --------------------
1859
+ C
1860
+ DOUBLE PRECISION ACNRM, CCMXJ, CONP, CRATE, DRC, EL,
1861
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
1862
+ 2 RC, RL1, TAU, TQ, TN, UROUND
1863
+ INTEGER ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
1864
+ 1 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
1865
+ 2 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
1866
+ 3 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
1867
+ 4 NSLP, NYH
1868
+ C
1869
+ C Type declarations for labeled COMMON block DVOD02 --------------------
1870
+ C
1871
+ DOUBLE PRECISION HU
1872
+ INTEGER NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
1873
+ C
1874
+ C Type declarations for local variables --------------------------------
1875
+ C
1876
+ DOUBLE PRECISION C, HUN, R, S, TFUZZ, TN1, TP, ZERO
1877
+ INTEGER I, IC, J, JB, JB2, JJ, JJ1, JP1
1878
+ CHARACTER*80 MSG
1879
+ C-----------------------------------------------------------------------
1880
+ C The following Fortran-77 declaration is to cause the values of the
1881
+ C listed (local) variables to be saved between calls to this integrator.
1882
+ C-----------------------------------------------------------------------
1883
+ SAVE HUN, ZERO
1884
+ C
1885
+ COMMON /DVOD01/ ACNRM, CCMXJ, CONP, CRATE, DRC, EL(13),
1886
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
1887
+ 2 RC, RL1, TAU(13), TQ(5), TN, UROUND,
1888
+ 3 ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
1889
+ 4 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
1890
+ 5 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
1891
+ 6 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
1892
+ 7 NSLP, NYH
1893
+ COMMON /DVOD02/ HU, NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
1894
+ C
1895
+ DATA HUN /100.0D0/, ZERO /0.0D0/
1896
+ C
1897
+ IFLAG = 0
1898
+ IF (K .LT. 0 .OR. K .GT. NQ) GO TO 80
1899
+ TFUZZ = HUN*UROUND*(TN + HU)
1900
+ TP = TN - HU - TFUZZ
1901
+ TN1 = TN + TFUZZ
1902
+ IF ((T-TP)*(T-TN1) .GT. ZERO) GO TO 90
1903
+ C
1904
+ S = (T - TN)/H
1905
+ IC = 1
1906
+ IF (K .EQ. 0) GO TO 15
1907
+ JJ1 = L - K
1908
+ DO 10 JJ = JJ1, NQ
1909
+ 10 IC = IC*JJ
1910
+ 15 C = REAL(IC)
1911
+ DO 20 I = 1, N
1912
+ 20 DKY(I) = C*YH(I,L)
1913
+ IF (K .EQ. NQ) GO TO 55
1914
+ JB2 = NQ - K
1915
+ DO 50 JB = 1, JB2
1916
+ J = NQ - JB
1917
+ JP1 = J + 1
1918
+ IC = 1
1919
+ IF (K .EQ. 0) GO TO 35
1920
+ JJ1 = JP1 - K
1921
+ DO 30 JJ = JJ1, J
1922
+ 30 IC = IC*JJ
1923
+ 35 C = REAL(IC)
1924
+ DO 40 I = 1, N
1925
+ 40 DKY(I) = C*YH(I,JP1) + S*DKY(I)
1926
+ 50 CONTINUE
1927
+ IF (K .EQ. 0) RETURN
1928
+ 55 R = H**(-K)
1929
+ CALL DSCAL (N, R, DKY, 1)
1930
+ RETURN
1931
+ C
1932
+ 80 MSG = 'DVINDY-- K (=I1) illegal '
1933
+ CALL XERRWD (MSG, 30, 51, 1, 1, K, 0, 0, ZERO, ZERO)
1934
+ IFLAG = -1
1935
+ RETURN
1936
+ 90 MSG = 'DVINDY-- T (=R1) illegal '
1937
+ CALL XERRWD (MSG, 30, 52, 1, 0, 0, 0, 1, T, ZERO)
1938
+ MSG=' T not in interval TCUR - HU (= R1) to TCUR (=R2) '
1939
+ CALL XERRWD (MSG, 60, 52, 1, 0, 0, 0, 2, TP, TN)
1940
+ IFLAG = -2
1941
+ RETURN
1942
+ C----------------------- End of Subroutine DVINDY ----------------------
1943
+ END
1944
+ *DECK DVSTEP
1945
+ SUBROUTINE DVSTEP (Y, YH, LDYH, YH1, EWT, SAVF, VSAV, ACOR,
1946
+ 1 WM, IWM, F, JAC, PSOL, VNLS, RPAR, IPAR)
1947
+ EXTERNAL F, JAC, PSOL, VNLS
1948
+ DOUBLE PRECISION Y, YH, YH1, EWT, SAVF, VSAV, ACOR, WM, RPAR
1949
+ INTEGER LDYH, IWM, IPAR
1950
+ DIMENSION Y(*), YH(LDYH,*), YH1(*), EWT(*), SAVF(*), VSAV(*),
1951
+ 1 ACOR(*), WM(*), IWM(*), RPAR(*), IPAR(*)
1952
+ C-----------------------------------------------------------------------
1953
+ C Call sequence input -- Y, YH, LDYH, YH1, EWT, SAVF, VSAV,
1954
+ C ACOR, WM, IWM, F, JAC, PSOL, VNLS, RPAR, IPAR
1955
+ C Call sequence output -- YH, ACOR, WM, IWM
1956
+ C COMMON block variables accessed..
1957
+ C /DVOD01/ ACNRM, EL(13), H, HMIN, HMXI, HNEW, HSCAL, RC, TAU(13),
1958
+ C TQ(5), TN, JCUR, JSTART, KFLAG, KUTH,
1959
+ C L, LMAX, MAXORD, N, NEWQ, NQ, NQWAIT
1960
+ C /DVOD02/ HU, NCFN, NETF, NFE, NQU, NST
1961
+ C
1962
+ C Subroutines called by DVSTEP.. F, DAXPY, DCOPY, DSCAL,
1963
+ C DVJUST, VNLS, DVSET
1964
+ C Function routines called by DVSTEP.. DVNORM
1965
+ C-----------------------------------------------------------------------
1966
+ C DVSTEP performs one step of the integration of an initial value
1967
+ C problem for a system of ordinary differential equations.
1968
+ C DVSTEP calls subroutine VNLS for the solution of the nonlinear system
1969
+ C arising in the time step. Thus it is independent of the problem
1970
+ C Jacobian structure and the type of nonlinear system solution method.
1971
+ C DVSTEP returns a completion flag KFLAG (in COMMON).
1972
+ C A return with KFLAG = -1 or -2 means either ABS(H) = HMIN or 10
1973
+ C consecutive failures occurred. On a return with KFLAG negative,
1974
+ C the values of TN and the YH array are as of the beginning of the last
1975
+ C step, and H is the last step size attempted.
1976
+ C
1977
+ C Communication with DVSTEP is done with the following variables..
1978
+ C
1979
+ C Y = An array of length N used for the dependent variable vector.
1980
+ C YH = An LDYH by LMAX array containing the dependent variables
1981
+ C and their approximate scaled derivatives, where
1982
+ C LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
1983
+ C j-th derivative of y(i), scaled by H**j/factorial(j)
1984
+ C (j = 0,1,...,NQ). On entry for the first step, the first
1985
+ C two columns of YH must be set from the initial values.
1986
+ C LDYH = A constant integer .ge. N, the first dimension of YH.
1987
+ C N is the number of ODEs in the system.
1988
+ C YH1 = A one-dimensional array occupying the same space as YH.
1989
+ C EWT = An array of length N containing multiplicative weights
1990
+ C for local error measurements. Local errors in y(i) are
1991
+ C compared to 1.0/EWT(i) in various error tests.
1992
+ C SAVF = An array of working storage, of length N.
1993
+ C also used for input of YH(*,MAXORD+2) when JSTART = -1
1994
+ C and MAXORD .lt. the current order NQ.
1995
+ C VSAV = A work array of length N passed to subroutine VNLS.
1996
+ C ACOR = A work array of length N, used for the accumulated
1997
+ C corrections. On a successful return, ACOR(i) contains
1998
+ C the estimated one-step local error in y(i).
1999
+ C WM,IWM = Real and integer work arrays associated with matrix
2000
+ C operations in VNLS.
2001
+ C F = Dummy name for the user supplied subroutine for f.
2002
+ C JAC = Dummy name for the user supplied Jacobian subroutine.
2003
+ C PSOL = Dummy name for the subroutine passed to VNLS, for
2004
+ C possible use there.
2005
+ C VNLS = Dummy name for the nonlinear system solving subroutine,
2006
+ C whose real name is dependent on the method used.
2007
+ C RPAR, IPAR = Dummy names for user's real and integer work arrays.
2008
+ C-----------------------------------------------------------------------
2009
+ C
2010
+ C Type declarations for labeled COMMON block DVOD01 --------------------
2011
+ C
2012
+ DOUBLE PRECISION ACNRM, CCMXJ, CONP, CRATE, DRC, EL,
2013
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
2014
+ 2 RC, RL1, TAU, TQ, TN, UROUND
2015
+ INTEGER ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
2016
+ 1 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
2017
+ 2 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
2018
+ 3 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
2019
+ 4 NSLP, NYH
2020
+ C
2021
+ C Type declarations for labeled COMMON block DVOD02 --------------------
2022
+ C
2023
+ DOUBLE PRECISION HU
2024
+ INTEGER NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
2025
+ C
2026
+ C Type declarations for local variables --------------------------------
2027
+ C
2028
+ DOUBLE PRECISION ADDON, BIAS1,BIAS2,BIAS3, CNQUOT, DDN, DSM, DUP,
2029
+ 1 ETACF, ETAMIN, ETAMX1, ETAMX2, ETAMX3, ETAMXF,
2030
+ 2 ETAQ, ETAQM1, ETAQP1, FLOTL, ONE, ONEPSM,
2031
+ 3 R, THRESH, TOLD, ZERO
2032
+ INTEGER I, I1, I2, IBACK, J, JB, KFC, KFH, MXNCF, NCF, NFLAG
2033
+ C
2034
+ C Type declaration for function subroutines called ---------------------
2035
+ C
2036
+ DOUBLE PRECISION DVNORM
2037
+ C-----------------------------------------------------------------------
2038
+ C The following Fortran-77 declaration is to cause the values of the
2039
+ C listed (local) variables to be saved between calls to this integrator.
2040
+ C-----------------------------------------------------------------------
2041
+ SAVE ADDON, BIAS1, BIAS2, BIAS3,
2042
+ 1 ETACF, ETAMIN, ETAMX1, ETAMX2, ETAMX3, ETAMXF, ETAQ, ETAQM1,
2043
+ 2 KFC, KFH, MXNCF, ONEPSM, THRESH, ONE, ZERO
2044
+ C-----------------------------------------------------------------------
2045
+ COMMON /DVOD01/ ACNRM, CCMXJ, CONP, CRATE, DRC, EL(13),
2046
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
2047
+ 2 RC, RL1, TAU(13), TQ(5), TN, UROUND,
2048
+ 3 ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
2049
+ 4 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
2050
+ 5 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
2051
+ 6 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
2052
+ 7 NSLP, NYH
2053
+ COMMON /DVOD02/ HU, NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
2054
+ C
2055
+ DATA KFC/-3/, KFH/-7/, MXNCF/10/
2056
+ DATA ADDON /1.0D-6/, BIAS1 /6.0D0/, BIAS2 /6.0D0/,
2057
+ 1 BIAS3 /10.0D0/, ETACF /0.25D0/, ETAMIN /0.1D0/,
2058
+ 2 ETAMXF /0.2D0/, ETAMX1 /1.0D4/, ETAMX2 /10.0D0/,
2059
+ 3 ETAMX3 /10.0D0/, ONEPSM /1.00001D0/, THRESH /1.5D0/
2060
+ DATA ONE/1.0D0/, ZERO/0.0D0/
2061
+ C
2062
+ KFLAG = 0
2063
+ TOLD = TN
2064
+ NCF = 0
2065
+ JCUR = 0
2066
+ NFLAG = 0
2067
+ IF (JSTART .GT. 0) GO TO 20
2068
+ IF (JSTART .EQ. -1) GO TO 100
2069
+ C-----------------------------------------------------------------------
2070
+ C On the first call, the order is set to 1, and other variables are
2071
+ C initialized. ETAMAX is the maximum ratio by which H can be increased
2072
+ C in a single step. It is normally 10, but is larger during the
2073
+ C first step to compensate for the small initial H. If a failure
2074
+ C occurs (in corrector convergence or error test), ETAMAX is set to 1
2075
+ C for the next increase.
2076
+ C-----------------------------------------------------------------------
2077
+ LMAX = MAXORD + 1
2078
+ NQ = 1
2079
+ L = 2
2080
+ NQNYH = NQ*LDYH
2081
+ TAU(1) = H
2082
+ PRL1 = ONE
2083
+ RC = ZERO
2084
+ ETAMAX = ETAMX1
2085
+ NQWAIT = 2
2086
+ HSCAL = H
2087
+ GO TO 200
2088
+ C-----------------------------------------------------------------------
2089
+ C Take preliminary actions on a normal continuation step (JSTART.GT.0).
2090
+ C If the driver changed H, then ETA must be reset and NEWH set to 1.
2091
+ C If a change of order was dictated on the previous step, then
2092
+ C it is done here and appropriate adjustments in the history are made.
2093
+ C On an order decrease, the history array is adjusted by DVJUST.
2094
+ C On an order increase, the history array is augmented by a column.
2095
+ C On a change of step size H, the history array YH is rescaled.
2096
+ C-----------------------------------------------------------------------
2097
+ 20 CONTINUE
2098
+ IF (KUTH .EQ. 1) THEN
2099
+ ETA = MIN(ETA,H/HSCAL)
2100
+ NEWH = 1
2101
+ ENDIF
2102
+ 50 IF (NEWH .EQ. 0) GO TO 200
2103
+ IF (NEWQ .EQ. NQ) GO TO 150
2104
+ IF (NEWQ .LT. NQ) THEN
2105
+ CALL DVJUST (YH, LDYH, -1)
2106
+ NQ = NEWQ
2107
+ L = NQ + 1
2108
+ NQWAIT = L
2109
+ GO TO 150
2110
+ ENDIF
2111
+ IF (NEWQ .GT. NQ) THEN
2112
+ CALL DVJUST (YH, LDYH, 1)
2113
+ NQ = NEWQ
2114
+ L = NQ + 1
2115
+ NQWAIT = L
2116
+ GO TO 150
2117
+ ENDIF
2118
+ C-----------------------------------------------------------------------
2119
+ C The following block handles preliminaries needed when JSTART = -1.
2120
+ C If N was reduced, zero out part of YH to avoid undefined references.
2121
+ C If MAXORD was reduced to a value less than the tentative order NEWQ,
2122
+ C then NQ is set to MAXORD, and a new H ratio ETA is chosen.
2123
+ C Otherwise, we take the same preliminary actions as for JSTART .gt. 0.
2124
+ C In any case, NQWAIT is reset to L = NQ + 1 to prevent further
2125
+ C changes in order for that many steps.
2126
+ C The new H ratio ETA is limited by the input H if KUTH = 1,
2127
+ C by HMIN if KUTH = 0, and by HMXI in any case.
2128
+ C Finally, the history array YH is rescaled.
2129
+ C-----------------------------------------------------------------------
2130
+ 100 CONTINUE
2131
+ LMAX = MAXORD + 1
2132
+ IF (N .EQ. LDYH) GO TO 120
2133
+ I1 = 1 + (NEWQ + 1)*LDYH
2134
+ I2 = (MAXORD + 1)*LDYH
2135
+ IF (I1 .GT. I2) GO TO 120
2136
+ DO 110 I = I1, I2
2137
+ 110 YH1(I) = ZERO
2138
+ 120 IF (NEWQ .LE. MAXORD) GO TO 140
2139
+ FLOTL = REAL(LMAX)
2140
+ IF (MAXORD .LT. NQ-1) THEN
2141
+ DDN = DVNORM (N, SAVF, EWT)/TQ(1)
2142
+ ETA = ONE/((BIAS1*DDN)**(ONE/FLOTL) + ADDON)
2143
+ ENDIF
2144
+ IF (MAXORD .EQ. NQ .AND. NEWQ .EQ. NQ+1) ETA = ETAQ
2145
+ IF (MAXORD .EQ. NQ-1 .AND. NEWQ .EQ. NQ+1) THEN
2146
+ ETA = ETAQM1
2147
+ CALL DVJUST (YH, LDYH, -1)
2148
+ ENDIF
2149
+ IF (MAXORD .EQ. NQ-1 .AND. NEWQ .EQ. NQ) THEN
2150
+ DDN = DVNORM (N, SAVF, EWT)/TQ(1)
2151
+ ETA = ONE/((BIAS1*DDN)**(ONE/FLOTL) + ADDON)
2152
+ CALL DVJUST (YH, LDYH, -1)
2153
+ ENDIF
2154
+ ETA = MIN(ETA,ONE)
2155
+ NQ = MAXORD
2156
+ L = LMAX
2157
+ 140 IF (KUTH .EQ. 1) ETA = MIN(ETA,ABS(H/HSCAL))
2158
+ IF (KUTH .EQ. 0) ETA = MAX(ETA,HMIN/ABS(HSCAL))
2159
+ ETA = ETA/MAX(ONE,ABS(HSCAL)*HMXI*ETA)
2160
+ NEWH = 1
2161
+ NQWAIT = L
2162
+ IF (NEWQ .LE. MAXORD) GO TO 50
2163
+ C Rescale the history array for a change in H by a factor of ETA. ------
2164
+ 150 R = ONE
2165
+ DO 180 J = 2, L
2166
+ R = R*ETA
2167
+ CALL DSCAL (N, R, YH(1,J), 1 )
2168
+ 180 CONTINUE
2169
+ H = HSCAL*ETA
2170
+ HSCAL = H
2171
+ RC = RC*ETA
2172
+ NQNYH = NQ*LDYH
2173
+ C-----------------------------------------------------------------------
2174
+ C This section computes the predicted values by effectively
2175
+ C multiplying the YH array by the Pascal triangle matrix.
2176
+ C DVSET is called to calculate all integration coefficients.
2177
+ C RC is the ratio of new to old values of the coefficient H/EL(2)=h/l1.
2178
+ C-----------------------------------------------------------------------
2179
+ 200 TN = TN + H
2180
+ I1 = NQNYH + 1
2181
+ DO 220 JB = 1, NQ
2182
+ I1 = I1 - LDYH
2183
+ DO 210 I = I1, NQNYH
2184
+ 210 YH1(I) = YH1(I) + YH1(I+LDYH)
2185
+ 220 CONTINUE
2186
+ CALL DVSET
2187
+ RL1 = ONE/EL(2)
2188
+ RC = RC*(RL1/PRL1)
2189
+ PRL1 = RL1
2190
+ C
2191
+ C Call the nonlinear system solver. ------------------------------------
2192
+ C
2193
+ CALL VNLS (Y, YH, LDYH, VSAV, SAVF, EWT, ACOR, IWM, WM,
2194
+ 1 F, JAC, PSOL, NFLAG, RPAR, IPAR)
2195
+ C
2196
+ IF (NFLAG .EQ. 0) GO TO 450
2197
+ C-----------------------------------------------------------------------
2198
+ C The VNLS routine failed to achieve convergence (NFLAG .NE. 0).
2199
+ C The YH array is retracted to its values before prediction.
2200
+ C The step size H is reduced and the step is retried, if possible.
2201
+ C Otherwise, an error exit is taken.
2202
+ C-----------------------------------------------------------------------
2203
+ NCF = NCF + 1
2204
+ NCFN = NCFN + 1
2205
+ ETAMAX = ONE
2206
+ TN = TOLD
2207
+ I1 = NQNYH + 1
2208
+ DO 430 JB = 1, NQ
2209
+ I1 = I1 - LDYH
2210
+ DO 420 I = I1, NQNYH
2211
+ 420 YH1(I) = YH1(I) - YH1(I+LDYH)
2212
+ 430 CONTINUE
2213
+ IF (NFLAG .LT. -1) GO TO 680
2214
+ IF (ABS(H) .LE. HMIN*ONEPSM) GO TO 670
2215
+ IF (NCF .EQ. MXNCF) GO TO 670
2216
+ ETA = ETACF
2217
+ ETA = MAX(ETA,HMIN/ABS(H))
2218
+ NFLAG = -1
2219
+ GO TO 150
2220
+ C-----------------------------------------------------------------------
2221
+ C The corrector has converged (NFLAG = 0). The local error test is
2222
+ C made and control passes to statement 500 if it fails.
2223
+ C-----------------------------------------------------------------------
2224
+ 450 CONTINUE
2225
+ DSM = ACNRM/TQ(2)
2226
+ IF (DSM .GT. ONE) GO TO 500
2227
+ C-----------------------------------------------------------------------
2228
+ C After a successful step, update the YH and TAU arrays and decrement
2229
+ C NQWAIT. If NQWAIT is then 1 and NQ .lt. MAXORD, then ACOR is saved
2230
+ C for use in a possible order increase on the next step.
2231
+ C If ETAMAX = 1 (a failure occurred this step), keep NQWAIT .ge. 2.
2232
+ C-----------------------------------------------------------------------
2233
+ KFLAG = 0
2234
+ NST = NST + 1
2235
+ HU = H
2236
+ NQU = NQ
2237
+ DO 470 IBACK = 1, NQ
2238
+ I = L - IBACK
2239
+ 470 TAU(I+1) = TAU(I)
2240
+ TAU(1) = H
2241
+ DO 480 J = 1, L
2242
+ CALL DAXPY (N, EL(J), ACOR, 1, YH(1,J), 1 )
2243
+ 480 CONTINUE
2244
+ NQWAIT = NQWAIT - 1
2245
+ IF ((L .EQ. LMAX) .OR. (NQWAIT .NE. 1)) GO TO 490
2246
+ CALL DCOPY (N, ACOR, 1, YH(1,LMAX), 1 )
2247
+ CONP = TQ(5)
2248
+ 490 IF (ETAMAX .NE. ONE) GO TO 560
2249
+ IF (NQWAIT .LT. 2) NQWAIT = 2
2250
+ NEWQ = NQ
2251
+ NEWH = 0
2252
+ ETA = ONE
2253
+ HNEW = H
2254
+ GO TO 690
2255
+ C-----------------------------------------------------------------------
2256
+ C The error test failed. KFLAG keeps track of multiple failures.
2257
+ C Restore TN and the YH array to their previous values, and prepare
2258
+ C to try the step again. Compute the optimum step size for the
2259
+ C same order. After repeated failures, H is forced to decrease
2260
+ C more rapidly.
2261
+ C-----------------------------------------------------------------------
2262
+ 500 KFLAG = KFLAG - 1
2263
+ NETF = NETF + 1
2264
+ NFLAG = -2
2265
+ TN = TOLD
2266
+ I1 = NQNYH + 1
2267
+ DO 520 JB = 1, NQ
2268
+ I1 = I1 - LDYH
2269
+ DO 510 I = I1, NQNYH
2270
+ 510 YH1(I) = YH1(I) - YH1(I+LDYH)
2271
+ 520 CONTINUE
2272
+ IF (ABS(H) .LE. HMIN*ONEPSM) GO TO 660
2273
+ ETAMAX = ONE
2274
+ IF (KFLAG .LE. KFC) GO TO 530
2275
+ C Compute ratio of new H to current H at the current order. ------------
2276
+ FLOTL = REAL(L)
2277
+ ETA = ONE/((BIAS2*DSM)**(ONE/FLOTL) + ADDON)
2278
+ ETA = MAX(ETA,HMIN/ABS(H),ETAMIN)
2279
+ IF ((KFLAG .LE. -2) .AND. (ETA .GT. ETAMXF)) ETA = ETAMXF
2280
+ GO TO 150
2281
+ C-----------------------------------------------------------------------
2282
+ C Control reaches this section if 3 or more consecutive failures
2283
+ C have occurred. It is assumed that the elements of the YH array
2284
+ C have accumulated errors of the wrong order. The order is reduced
2285
+ C by one, if possible. Then H is reduced by a factor of 0.1 and
2286
+ C the step is retried. After a total of 7 consecutive failures,
2287
+ C an exit is taken with KFLAG = -1.
2288
+ C-----------------------------------------------------------------------
2289
+ 530 IF (KFLAG .EQ. KFH) GO TO 660
2290
+ IF (NQ .EQ. 1) GO TO 540
2291
+ ETA = MAX(ETAMIN,HMIN/ABS(H))
2292
+ CALL DVJUST (YH, LDYH, -1)
2293
+ L = NQ
2294
+ NQ = NQ - 1
2295
+ NQWAIT = L
2296
+ GO TO 150
2297
+ 540 ETA = MAX(ETAMIN,HMIN/ABS(H))
2298
+ H = H*ETA
2299
+ HSCAL = H
2300
+ TAU(1) = H
2301
+ CALL F (N, TN, Y, SAVF, RPAR, IPAR)
2302
+ NFE = NFE + 1
2303
+ DO 550 I = 1, N
2304
+ 550 YH(I,2) = H*SAVF(I)
2305
+ NQWAIT = 10
2306
+ GO TO 200
2307
+ C-----------------------------------------------------------------------
2308
+ C If NQWAIT = 0, an increase or decrease in order by one is considered.
2309
+ C Factors ETAQ, ETAQM1, ETAQP1 are computed by which H could
2310
+ C be multiplied at order q, q-1, or q+1, respectively.
2311
+ C The largest of these is determined, and the new order and
2312
+ C step size set accordingly.
2313
+ C A change of H or NQ is made only if H increases by at least a
2314
+ C factor of THRESH. If an order change is considered and rejected,
2315
+ C then NQWAIT is set to 2 (reconsider it after 2 steps).
2316
+ C-----------------------------------------------------------------------
2317
+ C Compute ratio of new H to current H at the current order. ------------
2318
+ 560 FLOTL = REAL(L)
2319
+ ETAQ = ONE/((BIAS2*DSM)**(ONE/FLOTL) + ADDON)
2320
+ IF (NQWAIT .NE. 0) GO TO 600
2321
+ NQWAIT = 2
2322
+ ETAQM1 = ZERO
2323
+ IF (NQ .EQ. 1) GO TO 570
2324
+ C Compute ratio of new H to current H at the current order less one. ---
2325
+ DDN = DVNORM (N, YH(1,L), EWT)/TQ(1)
2326
+ ETAQM1 = ONE/((BIAS1*DDN)**(ONE/(FLOTL - ONE)) + ADDON)
2327
+ 570 ETAQP1 = ZERO
2328
+ IF (L .EQ. LMAX) GO TO 580
2329
+ C Compute ratio of new H to current H at current order plus one. -------
2330
+ CNQUOT = (TQ(5)/CONP)*(H/TAU(2))**L
2331
+ DO 575 I = 1, N
2332
+ 575 SAVF(I) = ACOR(I) - CNQUOT*YH(I,LMAX)
2333
+ DUP = DVNORM (N, SAVF, EWT)/TQ(3)
2334
+ ETAQP1 = ONE/((BIAS3*DUP)**(ONE/(FLOTL + ONE)) + ADDON)
2335
+ 580 IF (ETAQ .GE. ETAQP1) GO TO 590
2336
+ IF (ETAQP1 .GT. ETAQM1) GO TO 620
2337
+ GO TO 610
2338
+ 590 IF (ETAQ .LT. ETAQM1) GO TO 610
2339
+ 600 ETA = ETAQ
2340
+ NEWQ = NQ
2341
+ GO TO 630
2342
+ 610 ETA = ETAQM1
2343
+ NEWQ = NQ - 1
2344
+ GO TO 630
2345
+ 620 ETA = ETAQP1
2346
+ NEWQ = NQ + 1
2347
+ CALL DCOPY (N, ACOR, 1, YH(1,LMAX), 1)
2348
+ C Test tentative new H against THRESH, ETAMAX, and HMXI, then exit. ----
2349
+ 630 IF (ETA .LT. THRESH .OR. ETAMAX .EQ. ONE) GO TO 640
2350
+ ETA = MIN(ETA,ETAMAX)
2351
+ ETA = ETA/MAX(ONE,ABS(H)*HMXI*ETA)
2352
+ NEWH = 1
2353
+ HNEW = H*ETA
2354
+ GO TO 690
2355
+ 640 NEWQ = NQ
2356
+ NEWH = 0
2357
+ ETA = ONE
2358
+ HNEW = H
2359
+ GO TO 690
2360
+ C-----------------------------------------------------------------------
2361
+ C All returns are made through this section.
2362
+ C On a successful return, ETAMAX is reset and ACOR is scaled.
2363
+ C-----------------------------------------------------------------------
2364
+ 660 KFLAG = -1
2365
+ GO TO 720
2366
+ 670 KFLAG = -2
2367
+ GO TO 720
2368
+ 680 IF (NFLAG .EQ. -2) KFLAG = -3
2369
+ IF (NFLAG .EQ. -3) KFLAG = -4
2370
+ GO TO 720
2371
+ 690 ETAMAX = ETAMX3
2372
+ IF (NST .LE. 10) ETAMAX = ETAMX2
2373
+ 700 R = ONE/TQ(2)
2374
+ CALL DSCAL (N, R, ACOR, 1)
2375
+ 720 JSTART = 1
2376
+ RETURN
2377
+ C----------------------- End of Subroutine DVSTEP ----------------------
2378
+ END
2379
+ *DECK DVSET
2380
+ SUBROUTINE DVSET
2381
+ C-----------------------------------------------------------------------
2382
+ C Call sequence communication.. None
2383
+ C COMMON block variables accessed..
2384
+ C /DVOD01/ -- EL(13), H, TAU(13), TQ(5), L(= NQ + 1),
2385
+ C METH, NQ, NQWAIT
2386
+ C
2387
+ C Subroutines called by DVSET.. None
2388
+ C Function routines called by DVSET.. None
2389
+ C-----------------------------------------------------------------------
2390
+ C DVSET is called by DVSTEP and sets coefficients for use there.
2391
+ C
2392
+ C For each order NQ, the coefficients in EL are calculated by use of
2393
+ C the generating polynomial lambda(x), with coefficients EL(i).
2394
+ C lambda(x) = EL(1) + EL(2)*x + ... + EL(NQ+1)*(x**NQ).
2395
+ C For the backward differentiation formulas,
2396
+ C NQ-1
2397
+ C lambda(x) = (1 + x/xi*(NQ)) * product (1 + x/xi(i) ) .
2398
+ C i = 1
2399
+ C For the Adams formulas,
2400
+ C NQ-1
2401
+ C (d/dx) lambda(x) = c * product (1 + x/xi(i) ) ,
2402
+ C i = 1
2403
+ C lambda(-1) = 0, lambda(0) = 1,
2404
+ C where c is a normalization constant.
2405
+ C In both cases, xi(i) is defined by
2406
+ C H*xi(i) = t sub n - t sub (n-i)
2407
+ C = H + TAU(1) + TAU(2) + ... TAU(i-1).
2408
+ C
2409
+ C
2410
+ C In addition to variables described previously, communication
2411
+ C with DVSET uses the following..
2412
+ C TAU = A vector of length 13 containing the past NQ values
2413
+ C of H.
2414
+ C EL = A vector of length 13 in which vset stores the
2415
+ C coefficients for the corrector formula.
2416
+ C TQ = A vector of length 5 in which vset stores constants
2417
+ C used for the convergence test, the error test, and the
2418
+ C selection of H at a new order.
2419
+ C METH = The basic method indicator.
2420
+ C NQ = The current order.
2421
+ C L = NQ + 1, the length of the vector stored in EL, and
2422
+ C the number of columns of the YH array being used.
2423
+ C NQWAIT = A counter controlling the frequency of order changes.
2424
+ C An order change is about to be considered if NQWAIT = 1.
2425
+ C-----------------------------------------------------------------------
2426
+ C
2427
+ C Type declarations for labeled COMMON block DVOD01 --------------------
2428
+ C
2429
+ DOUBLE PRECISION ACNRM, CCMXJ, CONP, CRATE, DRC, EL,
2430
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
2431
+ 2 RC, RL1, TAU, TQ, TN, UROUND
2432
+ INTEGER ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
2433
+ 1 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
2434
+ 2 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
2435
+ 3 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
2436
+ 4 NSLP, NYH
2437
+ C
2438
+ C Type declarations for local variables --------------------------------
2439
+ C
2440
+ DOUBLE PRECISION AHATN0, ALPH0, CNQM1, CORTES, CSUM, ELP, EM,
2441
+ 1 EM0, FLOTI, FLOTL, FLOTNQ, HSUM, ONE, RXI, RXIS, S, SIX,
2442
+ 2 T1, T2, T3, T4, T5, T6, TWO, XI, ZERO
2443
+ INTEGER I, IBACK, J, JP1, NQM1, NQM2
2444
+ C
2445
+ DIMENSION EM(13)
2446
+ C-----------------------------------------------------------------------
2447
+ C The following Fortran-77 declaration is to cause the values of the
2448
+ C listed (local) variables to be saved between calls to this integrator.
2449
+ C-----------------------------------------------------------------------
2450
+ SAVE CORTES, ONE, SIX, TWO, ZERO
2451
+ C
2452
+ COMMON /DVOD01/ ACNRM, CCMXJ, CONP, CRATE, DRC, EL(13),
2453
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
2454
+ 2 RC, RL1, TAU(13), TQ(5), TN, UROUND,
2455
+ 3 ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
2456
+ 4 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
2457
+ 5 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
2458
+ 6 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
2459
+ 7 NSLP, NYH
2460
+ C
2461
+ DATA CORTES /0.1D0/
2462
+ DATA ONE /1.0D0/, SIX /6.0D0/, TWO /2.0D0/, ZERO /0.0D0/
2463
+ C
2464
+ FLOTL = REAL(L)
2465
+ NQM1 = NQ - 1
2466
+ NQM2 = NQ - 2
2467
+ GO TO (100, 200), METH
2468
+ C
2469
+ C Set coefficients for Adams methods. ----------------------------------
2470
+ 100 IF (NQ .NE. 1) GO TO 110
2471
+ EL(1) = ONE
2472
+ EL(2) = ONE
2473
+ TQ(1) = ONE
2474
+ TQ(2) = TWO
2475
+ TQ(3) = SIX*TQ(2)
2476
+ TQ(5) = ONE
2477
+ GO TO 300
2478
+ 110 HSUM = H
2479
+ EM(1) = ONE
2480
+ FLOTNQ = FLOTL - ONE
2481
+ DO 115 I = 2, L
2482
+ 115 EM(I) = ZERO
2483
+ DO 150 J = 1, NQM1
2484
+ IF ((J .NE. NQM1) .OR. (NQWAIT .NE. 1)) GO TO 130
2485
+ S = ONE
2486
+ CSUM = ZERO
2487
+ DO 120 I = 1, NQM1
2488
+ CSUM = CSUM + S*EM(I)/REAL(I+1)
2489
+ 120 S = -S
2490
+ TQ(1) = EM(NQM1)/(FLOTNQ*CSUM)
2491
+ 130 RXI = H/HSUM
2492
+ DO 140 IBACK = 1, J
2493
+ I = (J + 2) - IBACK
2494
+ 140 EM(I) = EM(I) + EM(I-1)*RXI
2495
+ HSUM = HSUM + TAU(J)
2496
+ 150 CONTINUE
2497
+ C Compute integral from -1 to 0 of polynomial and of x times it. -------
2498
+ S = ONE
2499
+ EM0 = ZERO
2500
+ CSUM = ZERO
2501
+ DO 160 I = 1, NQ
2502
+ FLOTI = REAL(I)
2503
+ EM0 = EM0 + S*EM(I)/FLOTI
2504
+ CSUM = CSUM + S*EM(I)/(FLOTI+ONE)
2505
+ 160 S = -S
2506
+ C In EL, form coefficients of normalized integrated polynomial. --------
2507
+ S = ONE/EM0
2508
+ EL(1) = ONE
2509
+ DO 170 I = 1, NQ
2510
+ 170 EL(I+1) = S*EM(I)/REAL(I)
2511
+ XI = HSUM/H
2512
+ TQ(2) = XI*EM0/CSUM
2513
+ TQ(5) = XI/EL(L)
2514
+ IF (NQWAIT .NE. 1) GO TO 300
2515
+ C For higher order control constant, multiply polynomial by 1+x/xi(q). -
2516
+ RXI = ONE/XI
2517
+ DO 180 IBACK = 1, NQ
2518
+ I = (L + 1) - IBACK
2519
+ 180 EM(I) = EM(I) + EM(I-1)*RXI
2520
+ C Compute integral of polynomial. --------------------------------------
2521
+ S = ONE
2522
+ CSUM = ZERO
2523
+ DO 190 I = 1, L
2524
+ CSUM = CSUM + S*EM(I)/REAL(I+1)
2525
+ 190 S = -S
2526
+ TQ(3) = FLOTL*EM0/CSUM
2527
+ GO TO 300
2528
+ C
2529
+ C Set coefficients for BDF methods. ------------------------------------
2530
+ 200 DO 210 I = 3, L
2531
+ 210 EL(I) = ZERO
2532
+ EL(1) = ONE
2533
+ EL(2) = ONE
2534
+ ALPH0 = -ONE
2535
+ AHATN0 = -ONE
2536
+ HSUM = H
2537
+ RXI = ONE
2538
+ RXIS = ONE
2539
+ IF (NQ .EQ. 1) GO TO 240
2540
+ DO 230 J = 1, NQM2
2541
+ C In EL, construct coefficients of (1+x/xi(1))*...*(1+x/xi(j+1)). ------
2542
+ HSUM = HSUM + TAU(J)
2543
+ RXI = H/HSUM
2544
+ JP1 = J + 1
2545
+ ALPH0 = ALPH0 - ONE/REAL(JP1)
2546
+ DO 220 IBACK = 1, JP1
2547
+ I = (J + 3) - IBACK
2548
+ 220 EL(I) = EL(I) + EL(I-1)*RXI
2549
+ 230 CONTINUE
2550
+ ALPH0 = ALPH0 - ONE/REAL(NQ)
2551
+ RXIS = -EL(2) - ALPH0
2552
+ HSUM = HSUM + TAU(NQM1)
2553
+ RXI = H/HSUM
2554
+ AHATN0 = -EL(2) - RXI
2555
+ DO 235 IBACK = 1, NQ
2556
+ I = (NQ + 2) - IBACK
2557
+ 235 EL(I) = EL(I) + EL(I-1)*RXIS
2558
+ 240 T1 = ONE - AHATN0 + ALPH0
2559
+ T2 = ONE + REAL(NQ)*T1
2560
+ TQ(2) = ABS(ALPH0*T2/T1)
2561
+ TQ(5) = ABS(T2/(EL(L)*RXI/RXIS))
2562
+ IF (NQWAIT .NE. 1) GO TO 300
2563
+ CNQM1 = RXIS/EL(L)
2564
+ T3 = ALPH0 + ONE/REAL(NQ)
2565
+ T4 = AHATN0 + RXI
2566
+ ELP = T3/(ONE - T4 + T3)
2567
+ TQ(1) = ABS(ELP/CNQM1)
2568
+ HSUM = HSUM + TAU(NQ)
2569
+ RXI = H/HSUM
2570
+ T5 = ALPH0 - ONE/REAL(NQ+1)
2571
+ T6 = AHATN0 - RXI
2572
+ ELP = T2/(ONE - T6 + T5)
2573
+ TQ(3) = ABS(ELP*RXI*(FLOTL + ONE)*T5)
2574
+ 300 TQ(4) = CORTES*TQ(2)
2575
+ RETURN
2576
+ C----------------------- End of Subroutine DVSET -----------------------
2577
+ END
2578
+ *DECK DVJUST
2579
+ SUBROUTINE DVJUST (YH, LDYH, IORD)
2580
+ DOUBLE PRECISION YH
2581
+ INTEGER LDYH, IORD
2582
+ DIMENSION YH(LDYH,*)
2583
+ C-----------------------------------------------------------------------
2584
+ C Call sequence input -- YH, LDYH, IORD
2585
+ C Call sequence output -- YH
2586
+ C COMMON block input -- NQ, METH, LMAX, HSCAL, TAU(13), N
2587
+ C COMMON block variables accessed..
2588
+ C /DVOD01/ -- HSCAL, TAU(13), LMAX, METH, N, NQ,
2589
+ C
2590
+ C Subroutines called by DVJUST.. DAXPY
2591
+ C Function routines called by DVJUST.. None
2592
+ C-----------------------------------------------------------------------
2593
+ C This subroutine adjusts the YH array on reduction of order,
2594
+ C and also when the order is increased for the stiff option (METH = 2).
2595
+ C Communication with DVJUST uses the following..
2596
+ C IORD = An integer flag used when METH = 2 to indicate an order
2597
+ C increase (IORD = +1) or an order decrease (IORD = -1).
2598
+ C HSCAL = Step size H used in scaling of Nordsieck array YH.
2599
+ C (If IORD = +1, DVJUST assumes that HSCAL = TAU(1).)
2600
+ C See References 1 and 2 for details.
2601
+ C-----------------------------------------------------------------------
2602
+ C
2603
+ C Type declarations for labeled COMMON block DVOD01 --------------------
2604
+ C
2605
+ DOUBLE PRECISION ACNRM, CCMXJ, CONP, CRATE, DRC, EL,
2606
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
2607
+ 2 RC, RL1, TAU, TQ, TN, UROUND
2608
+ INTEGER ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
2609
+ 1 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
2610
+ 2 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
2611
+ 3 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
2612
+ 4 NSLP, NYH
2613
+ C
2614
+ C Type declarations for local variables --------------------------------
2615
+ C
2616
+ DOUBLE PRECISION ALPH0, ALPH1, HSUM, ONE, PROD, T1, XI,XIOLD, ZERO
2617
+ INTEGER I, IBACK, J, JP1, LP1, NQM1, NQM2, NQP1
2618
+ C-----------------------------------------------------------------------
2619
+ C The following Fortran-77 declaration is to cause the values of the
2620
+ C listed (local) variables to be saved between calls to this integrator.
2621
+ C-----------------------------------------------------------------------
2622
+ SAVE ONE, ZERO
2623
+ C
2624
+ COMMON /DVOD01/ ACNRM, CCMXJ, CONP, CRATE, DRC, EL(13),
2625
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
2626
+ 2 RC, RL1, TAU(13), TQ(5), TN, UROUND,
2627
+ 3 ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
2628
+ 4 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
2629
+ 5 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
2630
+ 6 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
2631
+ 7 NSLP, NYH
2632
+ C
2633
+ DATA ONE /1.0D0/, ZERO /0.0D0/
2634
+ C
2635
+ IF ((NQ .EQ. 2) .AND. (IORD .NE. 1)) RETURN
2636
+ NQM1 = NQ - 1
2637
+ NQM2 = NQ - 2
2638
+ GO TO (100, 200), METH
2639
+ C-----------------------------------------------------------------------
2640
+ C Nonstiff option...
2641
+ C Check to see if the order is being increased or decreased.
2642
+ C-----------------------------------------------------------------------
2643
+ 100 CONTINUE
2644
+ IF (IORD .EQ. 1) GO TO 180
2645
+ C Order decrease. ------------------------------------------------------
2646
+ DO 110 J = 1, LMAX
2647
+ 110 EL(J) = ZERO
2648
+ EL(2) = ONE
2649
+ HSUM = ZERO
2650
+ DO 130 J = 1, NQM2
2651
+ C Construct coefficients of x*(x+xi(1))*...*(x+xi(j)). -----------------
2652
+ HSUM = HSUM + TAU(J)
2653
+ XI = HSUM/HSCAL
2654
+ JP1 = J + 1
2655
+ DO 120 IBACK = 1, JP1
2656
+ I = (J + 3) - IBACK
2657
+ 120 EL(I) = EL(I)*XI + EL(I-1)
2658
+ 130 CONTINUE
2659
+ C Construct coefficients of integrated polynomial. ---------------------
2660
+ DO 140 J = 2, NQM1
2661
+ 140 EL(J+1) = REAL(NQ)*EL(J)/REAL(J)
2662
+ C Subtract correction terms from YH array. -----------------------------
2663
+ DO 170 J = 3, NQ
2664
+ DO 160 I = 1, N
2665
+ 160 YH(I,J) = YH(I,J) - YH(I,L)*EL(J)
2666
+ 170 CONTINUE
2667
+ RETURN
2668
+ C Order increase. ------------------------------------------------------
2669
+ C Zero out next column in YH array. ------------------------------------
2670
+ 180 CONTINUE
2671
+ LP1 = L + 1
2672
+ DO 190 I = 1, N
2673
+ 190 YH(I,LP1) = ZERO
2674
+ RETURN
2675
+ C-----------------------------------------------------------------------
2676
+ C Stiff option...
2677
+ C Check to see if the order is being increased or decreased.
2678
+ C-----------------------------------------------------------------------
2679
+ 200 CONTINUE
2680
+ IF (IORD .EQ. 1) GO TO 300
2681
+ C Order decrease. ------------------------------------------------------
2682
+ DO 210 J = 1, LMAX
2683
+ 210 EL(J) = ZERO
2684
+ EL(3) = ONE
2685
+ HSUM = ZERO
2686
+ DO 230 J = 1,NQM2
2687
+ C Construct coefficients of x*x*(x+xi(1))*...*(x+xi(j)). ---------------
2688
+ HSUM = HSUM + TAU(J)
2689
+ XI = HSUM/HSCAL
2690
+ JP1 = J + 1
2691
+ DO 220 IBACK = 1, JP1
2692
+ I = (J + 4) - IBACK
2693
+ 220 EL(I) = EL(I)*XI + EL(I-1)
2694
+ 230 CONTINUE
2695
+ C Subtract correction terms from YH array. -----------------------------
2696
+ DO 250 J = 3,NQ
2697
+ DO 240 I = 1, N
2698
+ 240 YH(I,J) = YH(I,J) - YH(I,L)*EL(J)
2699
+ 250 CONTINUE
2700
+ RETURN
2701
+ C Order increase. ------------------------------------------------------
2702
+ 300 DO 310 J = 1, LMAX
2703
+ 310 EL(J) = ZERO
2704
+ EL(3) = ONE
2705
+ ALPH0 = -ONE
2706
+ ALPH1 = ONE
2707
+ PROD = ONE
2708
+ XIOLD = ONE
2709
+ HSUM = HSCAL
2710
+ IF (NQ .EQ. 1) GO TO 340
2711
+ DO 330 J = 1, NQM1
2712
+ C Construct coefficients of x*x*(x+xi(1))*...*(x+xi(j)). ---------------
2713
+ JP1 = J + 1
2714
+ HSUM = HSUM + TAU(JP1)
2715
+ XI = HSUM/HSCAL
2716
+ PROD = PROD*XI
2717
+ ALPH0 = ALPH0 - ONE/REAL(JP1)
2718
+ ALPH1 = ALPH1 + ONE/XI
2719
+ DO 320 IBACK = 1, JP1
2720
+ I = (J + 4) - IBACK
2721
+ 320 EL(I) = EL(I)*XIOLD + EL(I-1)
2722
+ XIOLD = XI
2723
+ 330 CONTINUE
2724
+ 340 CONTINUE
2725
+ T1 = (-ALPH0 - ALPH1)/PROD
2726
+ C Load column L + 1 in YH array. ---------------------------------------
2727
+ LP1 = L + 1
2728
+ DO 350 I = 1, N
2729
+ 350 YH(I,LP1) = T1*YH(I,LMAX)
2730
+ C Add correction terms to YH array. ------------------------------------
2731
+ NQP1 = NQ + 1
2732
+ DO 370 J = 3, NQP1
2733
+ CALL DAXPY (N, EL(J), YH(1,LP1), 1, YH(1,J), 1 )
2734
+ 370 CONTINUE
2735
+ RETURN
2736
+ C----------------------- End of Subroutine DVJUST ----------------------
2737
+ END
2738
+ *DECK DVNLSD
2739
+ SUBROUTINE DVNLSD (Y, YH, LDYH, VSAV, SAVF, EWT, ACOR, IWM, WM,
2740
+ 1 F, JAC, PDUM, NFLAG, RPAR, IPAR)
2741
+ EXTERNAL F, JAC, PDUM
2742
+ DOUBLE PRECISION Y, YH, VSAV, SAVF, EWT, ACOR, WM, RPAR
2743
+ INTEGER LDYH, IWM, NFLAG, IPAR
2744
+ DIMENSION Y(*), YH(LDYH,*), VSAV(*), SAVF(*), EWT(*), ACOR(*),
2745
+ 1 IWM(*), WM(*), RPAR(*), IPAR(*)
2746
+ C-----------------------------------------------------------------------
2747
+ C Call sequence input -- Y, YH, LDYH, SAVF, EWT, ACOR, IWM, WM,
2748
+ C F, JAC, NFLAG, RPAR, IPAR
2749
+ C Call sequence output -- YH, ACOR, WM, IWM, NFLAG
2750
+ C COMMON block variables accessed..
2751
+ C /DVOD01/ ACNRM, CRATE, DRC, H, RC, RL1, TQ(5), TN, ICF,
2752
+ C JCUR, METH, MITER, N, NSLP
2753
+ C /DVOD02/ HU, NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
2754
+ C
2755
+ C Subroutines called by DVNLSD.. F, DAXPY, DCOPY, DSCAL, DVJAC, DVSOL
2756
+ C Function routines called by DVNLSD.. DVNORM
2757
+ C-----------------------------------------------------------------------
2758
+ C Subroutine DVNLSD is a nonlinear system solver, which uses functional
2759
+ C iteration or a chord (modified Newton) method. For the chord method
2760
+ C direct linear algebraic system solvers are used. Subroutine DVNLSD
2761
+ C then handles the corrector phase of this integration package.
2762
+ C
2763
+ C Communication with DVNLSD is done with the following variables. (For
2764
+ C more details, please see the comments in the driver subroutine.)
2765
+ C
2766
+ C Y = The dependent variable, a vector of length N, input.
2767
+ C YH = The Nordsieck (Taylor) array, LDYH by LMAX, input
2768
+ C and output. On input, it contains predicted values.
2769
+ C LDYH = A constant .ge. N, the first dimension of YH, input.
2770
+ C VSAV = Unused work array.
2771
+ C SAVF = A work array of length N.
2772
+ C EWT = An error weight vector of length N, input.
2773
+ C ACOR = A work array of length N, used for the accumulated
2774
+ C corrections to the predicted y vector.
2775
+ C WM,IWM = Real and integer work arrays associated with matrix
2776
+ C operations in chord iteration (MITER .ne. 0).
2777
+ C F = Dummy name for user supplied routine for f.
2778
+ C JAC = Dummy name for user supplied Jacobian routine.
2779
+ C PDUM = Unused dummy subroutine name. Included for uniformity
2780
+ C over collection of integrators.
2781
+ C NFLAG = Input/output flag, with values and meanings as follows..
2782
+ C INPUT
2783
+ C 0 first call for this time step.
2784
+ C -1 convergence failure in previous call to DVNLSD.
2785
+ C -2 error test failure in DVSTEP.
2786
+ C OUTPUT
2787
+ C 0 successful completion of nonlinear solver.
2788
+ C -1 convergence failure or singular matrix.
2789
+ C -2 unrecoverable error in matrix preprocessing
2790
+ C (cannot occur here).
2791
+ C -3 unrecoverable error in solution (cannot occur
2792
+ C here).
2793
+ C RPAR, IPAR = Dummy names for user's real and integer work arrays.
2794
+ C
2795
+ C IPUP = Own variable flag with values and meanings as follows..
2796
+ C 0, do not update the Newton matrix.
2797
+ C MITER .ne. 0, update Newton matrix, because it is the
2798
+ C initial step, order was changed, the error
2799
+ C test failed, or an update is indicated by
2800
+ C the scalar RC or step counter NST.
2801
+ C
2802
+ C For more details, see comments in driver subroutine.
2803
+ C-----------------------------------------------------------------------
2804
+ C Type declarations for labeled COMMON block DVOD01 --------------------
2805
+ C
2806
+ DOUBLE PRECISION ACNRM, CCMXJ, CONP, CRATE, DRC, EL,
2807
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
2808
+ 2 RC, RL1, TAU, TQ, TN, UROUND
2809
+ INTEGER ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
2810
+ 1 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
2811
+ 2 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
2812
+ 3 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
2813
+ 4 NSLP, NYH
2814
+ C
2815
+ C Type declarations for labeled COMMON block DVOD02 --------------------
2816
+ C
2817
+ DOUBLE PRECISION HU
2818
+ INTEGER NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
2819
+ C
2820
+ C Type declarations for local variables --------------------------------
2821
+ C
2822
+ DOUBLE PRECISION CCMAX, CRDOWN, CSCALE, DCON, DEL, DELP, ONE,
2823
+ 1 RDIV, TWO, ZERO
2824
+ INTEGER I, IERPJ, IERSL, M, MAXCOR, MSBP
2825
+ C
2826
+ C Type declaration for function subroutines called ---------------------
2827
+ C
2828
+ DOUBLE PRECISION DVNORM
2829
+ C-----------------------------------------------------------------------
2830
+ C The following Fortran-77 declaration is to cause the values of the
2831
+ C listed (local) variables to be saved between calls to this integrator.
2832
+ C-----------------------------------------------------------------------
2833
+ SAVE CCMAX, CRDOWN, MAXCOR, MSBP, RDIV, ONE, TWO, ZERO
2834
+ C
2835
+ COMMON /DVOD01/ ACNRM, CCMXJ, CONP, CRATE, DRC, EL(13),
2836
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
2837
+ 2 RC, RL1, TAU(13), TQ(5), TN, UROUND,
2838
+ 3 ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
2839
+ 4 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
2840
+ 5 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
2841
+ 6 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
2842
+ 7 NSLP, NYH
2843
+ COMMON /DVOD02/ HU, NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
2844
+ C
2845
+ DATA CCMAX /0.3D0/, CRDOWN /0.3D0/, MAXCOR /3/, MSBP /20/,
2846
+ 1 RDIV /2.0D0/
2847
+ DATA ONE /1.0D0/, TWO /2.0D0/, ZERO /0.0D0/
2848
+ C-----------------------------------------------------------------------
2849
+ C On the first step, on a change of method order, or after a
2850
+ C nonlinear convergence failure with NFLAG = -2, set IPUP = MITER
2851
+ C to force a Jacobian update when MITER .ne. 0.
2852
+ C-----------------------------------------------------------------------
2853
+ IF (JSTART .EQ. 0) NSLP = 0
2854
+ IF (NFLAG .EQ. 0) ICF = 0
2855
+ IF (NFLAG .EQ. -2) IPUP = MITER
2856
+ IF ( (JSTART .EQ. 0) .OR. (JSTART .EQ. -1) ) IPUP = MITER
2857
+ C If this is functional iteration, set CRATE .eq. 1 and drop to 220
2858
+ IF (MITER .EQ. 0) THEN
2859
+ CRATE = ONE
2860
+ GO TO 220
2861
+ ENDIF
2862
+ C-----------------------------------------------------------------------
2863
+ C RC is the ratio of new to old values of the coefficient H/EL(2)=h/l1.
2864
+ C When RC differs from 1 by more than CCMAX, IPUP is set to MITER
2865
+ C to force DVJAC to be called, if a Jacobian is involved.
2866
+ C In any case, DVJAC is called at least every MSBP steps.
2867
+ C-----------------------------------------------------------------------
2868
+ DRC = ABS(RC-ONE)
2869
+ IF (DRC .GT. CCMAX .OR. NST .GE. NSLP+MSBP) IPUP = MITER
2870
+ C-----------------------------------------------------------------------
2871
+ C Up to MAXCOR corrector iterations are taken. A convergence test is
2872
+ C made on the r.m.s. norm of each correction, weighted by the error
2873
+ C weight vector EWT. The sum of the corrections is accumulated in the
2874
+ C vector ACOR(i). The YH array is not altered in the corrector loop.
2875
+ C-----------------------------------------------------------------------
2876
+ 220 M = 0
2877
+ DELP = ZERO
2878
+ CALL DCOPY (N, YH(1,1), 1, Y, 1 )
2879
+ CALL F (N, TN, Y, SAVF, RPAR, IPAR)
2880
+ NFE = NFE + 1
2881
+ IF (IPUP .LE. 0) GO TO 250
2882
+ C-----------------------------------------------------------------------
2883
+ C If indicated, the matrix P = I - h*rl1*J is reevaluated and
2884
+ C preprocessed before starting the corrector iteration. IPUP is set
2885
+ C to 0 as an indicator that this has been done.
2886
+ C-----------------------------------------------------------------------
2887
+ CALL DVJAC (Y, YH, LDYH, EWT, ACOR, SAVF, WM, IWM, F, JAC, IERPJ,
2888
+ 1 RPAR, IPAR)
2889
+ IPUP = 0
2890
+ RC = ONE
2891
+ DRC = ZERO
2892
+ CRATE = ONE
2893
+ NSLP = NST
2894
+ C If matrix is singular, take error return to force cut in step size. --
2895
+ IF (IERPJ .NE. 0) GO TO 430
2896
+ 250 DO 260 I = 1,N
2897
+ 260 ACOR(I) = ZERO
2898
+ C This is a looping point for the corrector iteration. -----------------
2899
+ 270 IF (MITER .NE. 0) GO TO 350
2900
+ C-----------------------------------------------------------------------
2901
+ C In the case of functional iteration, update Y directly from
2902
+ C the result of the last function evaluation.
2903
+ C-----------------------------------------------------------------------
2904
+ DO 280 I = 1,N
2905
+ 280 SAVF(I) = RL1*(H*SAVF(I) - YH(I,2))
2906
+ DO 290 I = 1,N
2907
+ 290 Y(I) = SAVF(I) - ACOR(I)
2908
+ DEL = DVNORM (N, Y, EWT)
2909
+ DO 300 I = 1,N
2910
+ 300 Y(I) = YH(I,1) + SAVF(I)
2911
+ CALL DCOPY (N, SAVF, 1, ACOR, 1)
2912
+ GO TO 400
2913
+ C-----------------------------------------------------------------------
2914
+ C In the case of the chord method, compute the corrector error,
2915
+ C and solve the linear system with that as right-hand side and
2916
+ C P as coefficient matrix. The correction is scaled by the factor
2917
+ C 2/(1+RC) to account for changes in h*rl1 since the last DVJAC call.
2918
+ C-----------------------------------------------------------------------
2919
+ 350 DO 360 I = 1,N
2920
+ 360 Y(I) = (RL1*H)*SAVF(I) - (RL1*YH(I,2) + ACOR(I))
2921
+ CALL DVSOL (WM, IWM, Y, IERSL)
2922
+ NNI = NNI + 1
2923
+ IF (IERSL .GT. 0) GO TO 410
2924
+ IF (METH .EQ. 2 .AND. RC .NE. ONE) THEN
2925
+ CSCALE = TWO/(ONE + RC)
2926
+ CALL DSCAL (N, CSCALE, Y, 1)
2927
+ ENDIF
2928
+ DEL = DVNORM (N, Y, EWT)
2929
+ CALL DAXPY (N, ONE, Y, 1, ACOR, 1)
2930
+ DO 380 I = 1,N
2931
+ 380 Y(I) = YH(I,1) + ACOR(I)
2932
+ C-----------------------------------------------------------------------
2933
+ C Test for convergence. If M .gt. 0, an estimate of the convergence
2934
+ C rate constant is stored in CRATE, and this is used in the test.
2935
+ C-----------------------------------------------------------------------
2936
+ 400 IF (M .NE. 0) CRATE = MAX(CRDOWN*CRATE,DEL/DELP)
2937
+ DCON = DEL*MIN(ONE,CRATE)/TQ(4)
2938
+ IF (DCON .LE. ONE) GO TO 450
2939
+ M = M + 1
2940
+ IF (M .EQ. MAXCOR) GO TO 410
2941
+ IF (M .GE. 2 .AND. DEL .GT. RDIV*DELP) GO TO 410
2942
+ DELP = DEL
2943
+ CALL F (N, TN, Y, SAVF, RPAR, IPAR)
2944
+ NFE = NFE + 1
2945
+ GO TO 270
2946
+ C
2947
+ 410 IF (MITER .EQ. 0 .OR. JCUR .EQ. 1) GO TO 430
2948
+ ICF = 1
2949
+ IPUP = MITER
2950
+ GO TO 220
2951
+ C
2952
+ 430 CONTINUE
2953
+ NFLAG = -1
2954
+ ICF = 2
2955
+ IPUP = MITER
2956
+ RETURN
2957
+ C
2958
+ C Return for successful step. ------------------------------------------
2959
+ 450 NFLAG = 0
2960
+ JCUR = 0
2961
+ ICF = 0
2962
+ IF (M .EQ. 0) ACNRM = DEL
2963
+ IF (M .GT. 0) ACNRM = DVNORM (N, ACOR, EWT)
2964
+ RETURN
2965
+ C----------------------- End of Subroutine DVNLSD ----------------------
2966
+ END
2967
+ *DECK DVJAC
2968
+ SUBROUTINE DVJAC (Y, YH, LDYH, EWT, FTEM, SAVF, WM, IWM, F, JAC,
2969
+ 1 IERPJ, RPAR, IPAR)
2970
+ EXTERNAL F, JAC
2971
+ DOUBLE PRECISION Y, YH, EWT, FTEM, SAVF, WM, RPAR
2972
+ INTEGER LDYH, IWM, IERPJ, IPAR
2973
+ DIMENSION Y(*), YH(LDYH,*), EWT(*), FTEM(*), SAVF(*),
2974
+ 1 WM(*), IWM(*), RPAR(*), IPAR(*)
2975
+ C-----------------------------------------------------------------------
2976
+ C Call sequence input -- Y, YH, LDYH, EWT, FTEM, SAVF, WM, IWM,
2977
+ C F, JAC, RPAR, IPAR
2978
+ C Call sequence output -- WM, IWM, IERPJ
2979
+ C COMMON block variables accessed..
2980
+ C /DVOD01/ CCMXJ, DRC, H, RL1, TN, UROUND, ICF, JCUR, LOCJS,
2981
+ C MITER, MSBJ, N, NSLJ
2982
+ C /DVOD02/ NFE, NST, NJE, NLU
2983
+ C
2984
+ C Subroutines called by DVJAC.. F, JAC, DACOPY, DCOPY, DGBTRF, DGETRF,
2985
+ C DSCAL
2986
+ C Function routines called by DVJAC.. DVNORM
2987
+ C-----------------------------------------------------------------------
2988
+ C DVJAC is called by DVNLSD to compute and process the matrix
2989
+ C P = I - h*rl1*J , where J is an approximation to the Jacobian.
2990
+ C Here J is computed by the user-supplied routine JAC if
2991
+ C MITER = 1 or 4, or by finite differencing if MITER = 2, 3, or 5.
2992
+ C If MITER = 3, a diagonal approximation to J is used.
2993
+ C If JSV = -1, J is computed from scratch in all cases.
2994
+ C If JSV = 1 and MITER = 1, 2, 4, or 5, and if the saved value of J is
2995
+ C considered acceptable, then P is constructed from the saved J.
2996
+ C J is stored in wm and replaced by P. If MITER .ne. 3, P is then
2997
+ C subjected to LU decomposition in preparation for later solution
2998
+ C of linear systems with P as coefficient matrix. This is done
2999
+ C by DGETRF if MITER = 1 or 2, and by DGBTRF if MITER = 4 or 5.
3000
+ C
3001
+ C Communication with DVJAC is done with the following variables. (For
3002
+ C more details, please see the comments in the driver subroutine.)
3003
+ C Y = Vector containing predicted values on entry.
3004
+ C YH = The Nordsieck array, an LDYH by LMAX array, input.
3005
+ C LDYH = A constant .ge. N, the first dimension of YH, input.
3006
+ C EWT = An error weight vector of length N.
3007
+ C SAVF = Array containing f evaluated at predicted y, input.
3008
+ C WM = Real work space for matrices. In the output, it containS
3009
+ C the inverse diagonal matrix if MITER = 3 and the LU
3010
+ C decomposition of P if MITER is 1, 2 , 4, or 5.
3011
+ C Storage of matrix elements starts at WM(3).
3012
+ C Storage of the saved Jacobian starts at WM(LOCJS).
3013
+ C WM also contains the following matrix-related data..
3014
+ C WM(1) = SQRT(UROUND), used in numerical Jacobian step.
3015
+ C WM(2) = H*RL1, saved for later use if MITER = 3.
3016
+ C IWM = Integer work space containing pivot information,
3017
+ C starting at IWM(31), if MITER is 1, 2, 4, or 5.
3018
+ C IWM also contains band parameters ML = IWM(1) and
3019
+ C MU = IWM(2) if MITER is 4 or 5.
3020
+ C F = Dummy name for the user supplied subroutine for f.
3021
+ C JAC = Dummy name for the user supplied Jacobian subroutine.
3022
+ C RPAR, IPAR = Dummy names for user's real and integer work arrays.
3023
+ C RL1 = 1/EL(2) (input).
3024
+ C IERPJ = Output error flag, = 0 if no trouble, 1 if the P
3025
+ C matrix is found to be singular.
3026
+ C JCUR = Output flag to indicate whether the Jacobian matrix
3027
+ C (or approximation) is now current.
3028
+ C JCUR = 0 means J is not current.
3029
+ C JCUR = 1 means J is current.
3030
+ C-----------------------------------------------------------------------
3031
+ C
3032
+ C Type declarations for labeled COMMON block DVOD01 --------------------
3033
+ C
3034
+ DOUBLE PRECISION ACNRM, CCMXJ, CONP, CRATE, DRC, EL,
3035
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
3036
+ 2 RC, RL1, TAU, TQ, TN, UROUND
3037
+ INTEGER ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
3038
+ 1 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
3039
+ 2 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
3040
+ 3 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
3041
+ 4 NSLP, NYH
3042
+ C
3043
+ C Type declarations for labeled COMMON block DVOD02 --------------------
3044
+ C
3045
+ DOUBLE PRECISION HU
3046
+ INTEGER NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
3047
+ C
3048
+ C Type declarations for local variables --------------------------------
3049
+ C
3050
+ DOUBLE PRECISION CON, DI, FAC, HRL1, ONE, PT1, R, R0, SRUR, THOU,
3051
+ 1 YI, YJ, YJJ, ZERO
3052
+ INTEGER I, I1, I2, IER, II, J, J1, JJ, JOK, LENP, MBA, MBAND,
3053
+ 1 MEB1, MEBAND, ML, ML3, MU, NP1
3054
+ C
3055
+ C Type declaration for function subroutines called ---------------------
3056
+ C
3057
+ DOUBLE PRECISION DVNORM
3058
+ C-----------------------------------------------------------------------
3059
+ C The following Fortran-77 declaration is to cause the values of the
3060
+ C listed (local) variables to be saved between calls to this subroutine.
3061
+ C-----------------------------------------------------------------------
3062
+ SAVE ONE, PT1, THOU, ZERO
3063
+ C-----------------------------------------------------------------------
3064
+ COMMON /DVOD01/ ACNRM, CCMXJ, CONP, CRATE, DRC, EL(13),
3065
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
3066
+ 2 RC, RL1, TAU(13), TQ(5), TN, UROUND,
3067
+ 3 ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
3068
+ 4 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
3069
+ 5 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
3070
+ 6 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
3071
+ 7 NSLP, NYH
3072
+ COMMON /DVOD02/ HU, NCFN, NETF, NFE, NJE, NLU, NNI, NQU, NST
3073
+ C
3074
+ DATA ONE /1.0D0/, THOU /1000.0D0/, ZERO /0.0D0/, PT1 /0.1D0/
3075
+ C
3076
+ IERPJ = 0
3077
+ HRL1 = H*RL1
3078
+ C See whether J should be evaluated (JOK = -1) or not (JOK = 1). -------
3079
+ JOK = JSV
3080
+ IF (JSV .EQ. 1) THEN
3081
+ IF (NST .EQ. 0 .OR. NST .GT. NSLJ+MSBJ) JOK = -1
3082
+ IF (ICF .EQ. 1 .AND. DRC .LT. CCMXJ) JOK = -1
3083
+ IF (ICF .EQ. 2) JOK = -1
3084
+ ENDIF
3085
+ C End of setting JOK. --------------------------------------------------
3086
+ C
3087
+ IF (JOK .EQ. -1 .AND. MITER .EQ. 1) THEN
3088
+ C If JOK = -1 and MITER = 1, call JAC to evaluate Jacobian. ------------
3089
+ NJE = NJE + 1
3090
+ NSLJ = NST
3091
+ JCUR = 1
3092
+ LENP = N*N
3093
+ DO 110 I = 1,LENP
3094
+ 110 WM(I+2) = ZERO
3095
+ CALL JAC (N, TN, Y, 0, 0, WM(3), N, RPAR, IPAR)
3096
+ IF (JSV .EQ. 1) CALL DCOPY (LENP, WM(3), 1, WM(LOCJS), 1)
3097
+ ENDIF
3098
+ C
3099
+ IF (JOK .EQ. -1 .AND. MITER .EQ. 2) THEN
3100
+ C If MITER = 2, make N calls to F to approximate the Jacobian. ---------
3101
+ NJE = NJE + 1
3102
+ NSLJ = NST
3103
+ JCUR = 1
3104
+ FAC = DVNORM (N, SAVF, EWT)
3105
+ R0 = THOU*ABS(H)*UROUND*REAL(N)*FAC
3106
+ IF (R0 .EQ. ZERO) R0 = ONE
3107
+ SRUR = WM(1)
3108
+ J1 = 2
3109
+ DO 230 J = 1,N
3110
+ YJ = Y(J)
3111
+ R = MAX(SRUR*ABS(YJ),R0/EWT(J))
3112
+ Y(J) = Y(J) + R
3113
+ FAC = ONE/R
3114
+ CALL F (N, TN, Y, FTEM, RPAR, IPAR)
3115
+ DO 220 I = 1,N
3116
+ 220 WM(I+J1) = (FTEM(I) - SAVF(I))*FAC
3117
+ Y(J) = YJ
3118
+ J1 = J1 + N
3119
+ 230 CONTINUE
3120
+ NFE = NFE + N
3121
+ LENP = N*N
3122
+ IF (JSV .EQ. 1) CALL DCOPY (LENP, WM(3), 1, WM(LOCJS), 1)
3123
+ ENDIF
3124
+ C
3125
+ IF (JOK .EQ. 1 .AND. (MITER .EQ. 1 .OR. MITER .EQ. 2)) THEN
3126
+ JCUR = 0
3127
+ LENP = N*N
3128
+ CALL DCOPY (LENP, WM(LOCJS), 1, WM(3), 1)
3129
+ ENDIF
3130
+ C
3131
+ IF (MITER .EQ. 1 .OR. MITER .EQ. 2) THEN
3132
+ C Multiply Jacobian by scalar, add identity, and do LU decomposition. --
3133
+ CON = -HRL1
3134
+ CALL DSCAL (LENP, CON, WM(3), 1)
3135
+ J = 3
3136
+ NP1 = N + 1
3137
+ DO 250 I = 1,N
3138
+ WM(J) = WM(J) + ONE
3139
+ 250 J = J + NP1
3140
+ NLU = NLU + 1
3141
+ c Replaced LINPACK dgefa with LAPACK dgetrf
3142
+ c CALL DGEFA (WM(3), N, N, IWM(31), IER)
3143
+ CALL DGETRF (N, N, WM(3), N, IWM(31), IER)
3144
+ IF (IER .NE. 0) IERPJ = 1
3145
+ RETURN
3146
+ ENDIF
3147
+ C End of code block for MITER = 1 or 2. --------------------------------
3148
+ C
3149
+ IF (MITER .EQ. 3) THEN
3150
+ C If MITER = 3, construct a diagonal approximation to J and P. ---------
3151
+ NJE = NJE + 1
3152
+ JCUR = 1
3153
+ WM(2) = HRL1
3154
+ R = RL1*PT1
3155
+ DO 310 I = 1,N
3156
+ 310 Y(I) = Y(I) + R*(H*SAVF(I) - YH(I,2))
3157
+ CALL F (N, TN, Y, WM(3), RPAR, IPAR)
3158
+ NFE = NFE + 1
3159
+ DO 320 I = 1,N
3160
+ R0 = H*SAVF(I) - YH(I,2)
3161
+ DI = PT1*R0 - H*(WM(I+2) - SAVF(I))
3162
+ WM(I+2) = ONE
3163
+ IF (ABS(R0) .LT. UROUND/EWT(I)) GO TO 320
3164
+ IF (ABS(DI) .EQ. ZERO) GO TO 330
3165
+ WM(I+2) = PT1*R0/DI
3166
+ 320 CONTINUE
3167
+ RETURN
3168
+ 330 IERPJ = 1
3169
+ RETURN
3170
+ ENDIF
3171
+ C End of code block for MITER = 3. -------------------------------------
3172
+ C
3173
+ C Set constants for MITER = 4 or 5. ------------------------------------
3174
+ ML = IWM(1)
3175
+ MU = IWM(2)
3176
+ ML3 = ML + 3
3177
+ MBAND = ML + MU + 1
3178
+ MEBAND = MBAND + ML
3179
+ LENP = MEBAND*N
3180
+ C
3181
+ IF (JOK .EQ. -1 .AND. MITER .EQ. 4) THEN
3182
+ C If JOK = -1 and MITER = 4, call JAC to evaluate Jacobian. ------------
3183
+ NJE = NJE + 1
3184
+ NSLJ = NST
3185
+ JCUR = 1
3186
+ DO 410 I = 1,LENP
3187
+ 410 WM(I+2) = ZERO
3188
+ CALL JAC (N, TN, Y, ML, MU, WM(ML3), MEBAND, RPAR, IPAR)
3189
+ IF (JSV .EQ. 1)
3190
+ 1 CALL DACOPY (MBAND, N, WM(ML3), MEBAND, WM(LOCJS), MBAND)
3191
+ ENDIF
3192
+ C
3193
+ IF (JOK .EQ. -1 .AND. MITER .EQ. 5) THEN
3194
+ C If MITER = 5, make ML+MU+1 calls to F to approximate the Jacobian. ---
3195
+ NJE = NJE + 1
3196
+ NSLJ = NST
3197
+ JCUR = 1
3198
+ MBA = MIN(MBAND,N)
3199
+ MEB1 = MEBAND - 1
3200
+ SRUR = WM(1)
3201
+ FAC = DVNORM (N, SAVF, EWT)
3202
+ R0 = THOU*ABS(H)*UROUND*REAL(N)*FAC
3203
+ IF (R0 .EQ. ZERO) R0 = ONE
3204
+ DO 560 J = 1,MBA
3205
+ DO 530 I = J,N,MBAND
3206
+ YI = Y(I)
3207
+ R = MAX(SRUR*ABS(YI),R0/EWT(I))
3208
+ 530 Y(I) = Y(I) + R
3209
+ CALL F (N, TN, Y, FTEM, RPAR, IPAR)
3210
+ DO 550 JJ = J,N,MBAND
3211
+ Y(JJ) = YH(JJ,1)
3212
+ YJJ = Y(JJ)
3213
+ R = MAX(SRUR*ABS(YJJ),R0/EWT(JJ))
3214
+ FAC = ONE/R
3215
+ I1 = MAX(JJ-MU,1)
3216
+ I2 = MIN(JJ+ML,N)
3217
+ II = JJ*MEB1 - ML + 2
3218
+ DO 540 I = I1,I2
3219
+ 540 WM(II+I) = (FTEM(I) - SAVF(I))*FAC
3220
+ 550 CONTINUE
3221
+ 560 CONTINUE
3222
+ NFE = NFE + MBA
3223
+ IF (JSV .EQ. 1)
3224
+ 1 CALL DACOPY (MBAND, N, WM(ML3), MEBAND, WM(LOCJS), MBAND)
3225
+ ENDIF
3226
+ C
3227
+ IF (JOK .EQ. 1) THEN
3228
+ JCUR = 0
3229
+ CALL DACOPY (MBAND, N, WM(LOCJS), MBAND, WM(ML3), MEBAND)
3230
+ ENDIF
3231
+ C
3232
+ C Multiply Jacobian by scalar, add identity, and do LU decomposition.
3233
+ CON = -HRL1
3234
+ CALL DSCAL (LENP, CON, WM(3), 1 )
3235
+ II = MBAND + 2
3236
+ DO 580 I = 1,N
3237
+ WM(II) = WM(II) + ONE
3238
+ 580 II = II + MEBAND
3239
+ NLU = NLU + 1
3240
+ c Replaced LINPACK dgbfa with LAPACK dgbtrf
3241
+ c CALL DGBFA (WM(3), MEBAND, N, ML, MU, IWM(31), IER)
3242
+ CALL DGBTRF (N, N, ML, MU, WM(3), MEBAND, IWM(31), IER)
3243
+ IF (IER .NE. 0) IERPJ = 1
3244
+ RETURN
3245
+ C End of code block for MITER = 4 or 5. --------------------------------
3246
+ C
3247
+ C----------------------- End of Subroutine DVJAC -----------------------
3248
+ END
3249
+ *DECK DACOPY
3250
+ SUBROUTINE DACOPY (NROW, NCOL, A, NROWA, B, NROWB)
3251
+ DOUBLE PRECISION A, B
3252
+ INTEGER NROW, NCOL, NROWA, NROWB
3253
+ DIMENSION A(NROWA,NCOL), B(NROWB,NCOL)
3254
+ C-----------------------------------------------------------------------
3255
+ C Call sequence input -- NROW, NCOL, A, NROWA, NROWB
3256
+ C Call sequence output -- B
3257
+ C COMMON block variables accessed -- None
3258
+ C
3259
+ C Subroutines called by DACOPY.. DCOPY
3260
+ C Function routines called by DACOPY.. None
3261
+ C-----------------------------------------------------------------------
3262
+ C This routine copies one rectangular array, A, to another, B,
3263
+ C where A and B may have different row dimensions, NROWA and NROWB.
3264
+ C The data copied consists of NROW rows and NCOL columns.
3265
+ C-----------------------------------------------------------------------
3266
+ INTEGER IC
3267
+ C
3268
+ DO 20 IC = 1,NCOL
3269
+ CALL DCOPY (NROW, A(1,IC), 1, B(1,IC), 1)
3270
+ 20 CONTINUE
3271
+ C
3272
+ RETURN
3273
+ C----------------------- End of Subroutine DACOPY ----------------------
3274
+ END
3275
+ *DECK DVSOL
3276
+ SUBROUTINE DVSOL (WM, IWM, X, IERSL)
3277
+ DOUBLE PRECISION WM, X
3278
+ INTEGER IWM, IERSL
3279
+ DIMENSION WM(*), IWM(*), X(*)
3280
+ C-----------------------------------------------------------------------
3281
+ C Call sequence input -- WM, IWM, X
3282
+ C Call sequence output -- X, IERSL
3283
+ C COMMON block variables accessed..
3284
+ C /DVOD01/ -- H, RL1, MITER, N
3285
+ C
3286
+ C Subroutines called by DVSOL.. DGETRS, DGBTRS
3287
+ C Function routines called by DVSOL.. None
3288
+ C-----------------------------------------------------------------------
3289
+ C This routine manages the solution of the linear system arising from
3290
+ C a chord iteration. It is called if MITER .ne. 0.
3291
+ C If MITER is 1 or 2, it calls DGETRS to accomplish this.
3292
+ C If MITER = 3 it updates the coefficient H*RL1 in the diagonal
3293
+ C matrix, and then computes the solution.
3294
+ C If MITER is 4 or 5, it calls DGBTRS.
3295
+ C Communication with DVSOL uses the following variables..
3296
+ C WM = Real work space containing the inverse diagonal matrix if
3297
+ C MITER = 3 and the LU decomposition of the matrix otherwise.
3298
+ C Storage of matrix elements starts at WM(3).
3299
+ C WM also contains the following matrix-related data..
3300
+ C WM(1) = SQRT(UROUND) (not used here),
3301
+ C WM(2) = HRL1, the previous value of H*RL1, used if MITER = 3.
3302
+ C IWM = Integer work space containing pivot information, starting at
3303
+ C IWM(31), if MITER is 1, 2, 4, or 5. IWM also contains band
3304
+ C parameters ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
3305
+ C X = The right-hand side vector on input, and the solution vector
3306
+ C on output, of length N.
3307
+ C IERSL = Output flag. IERSL = 0 if no trouble occurred.
3308
+ C IERSL = 1 if a singular matrix arose with MITER = 3.
3309
+ C-----------------------------------------------------------------------
3310
+ C
3311
+ C Type declarations for labeled COMMON block DVOD01 --------------------
3312
+ C
3313
+ DOUBLE PRECISION ACNRM, CCMXJ, CONP, CRATE, DRC, EL,
3314
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
3315
+ 2 RC, RL1, TAU, TQ, TN, UROUND
3316
+ INTEGER ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
3317
+ 1 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
3318
+ 2 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
3319
+ 3 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
3320
+ 4 NSLP, NYH
3321
+ C
3322
+ C Type declarations for local variables --------------------------------
3323
+ C
3324
+ INTEGER I, MEBAND, ML, MU
3325
+ DOUBLE PRECISION DI, HRL1, ONE, PHRL1, R, ZERO
3326
+ C-----------------------------------------------------------------------
3327
+ C The following Fortran-77 declaration is to cause the values of the
3328
+ C listed (local) variables to be saved between calls to this integrator.
3329
+ C-----------------------------------------------------------------------
3330
+ SAVE ONE, ZERO
3331
+ C
3332
+ COMMON /DVOD01/ ACNRM, CCMXJ, CONP, CRATE, DRC, EL(13),
3333
+ 1 ETA, ETAMAX, H, HMIN, HMXI, HNEW, HSCAL, PRL1,
3334
+ 2 RC, RL1, TAU(13), TQ(5), TN, UROUND,
3335
+ 3 ICF, INIT, IPUP, JCUR, JSTART, JSV, KFLAG, KUTH,
3336
+ 4 L, LMAX, LYH, LEWT, LACOR, LSAVF, LWM, LIWM,
3337
+ 5 LOCJS, MAXORD, METH, MITER, MSBJ, MXHNIL, MXSTEP,
3338
+ 6 N, NEWH, NEWQ, NHNIL, NQ, NQNYH, NQWAIT, NSLJ,
3339
+ 7 NSLP, NYH
3340
+ C
3341
+ DATA ONE /1.0D0/, ZERO /0.0D0/
3342
+ C
3343
+ IERSL = 0
3344
+ GO TO (100, 100, 300, 400, 400), MITER
3345
+ c Replaced LINPACK dgesl with LAPACK dgetrs
3346
+ c 100 CALL DGESL (WM(3), N, N, IWM(31), X, 0)
3347
+ 100 CALL DGETRS ('N', N, 1, WM(3), N, IWM(31), X, N, IER)
3348
+ RETURN
3349
+ C
3350
+ 300 PHRL1 = WM(2)
3351
+ HRL1 = H*RL1
3352
+ WM(2) = HRL1
3353
+ IF (HRL1 .EQ. PHRL1) GO TO 330
3354
+ R = HRL1/PHRL1
3355
+ DO 320 I = 1,N
3356
+ DI = ONE - R*(ONE - ONE/WM(I+2))
3357
+ IF (ABS(DI) .EQ. ZERO) GO TO 390
3358
+ 320 WM(I+2) = ONE/DI
3359
+ C
3360
+ 330 DO 340 I = 1,N
3361
+ 340 X(I) = WM(I+2)*X(I)
3362
+ RETURN
3363
+ 390 IERSL = 1
3364
+ RETURN
3365
+ C
3366
+ 400 ML = IWM(1)
3367
+ MU = IWM(2)
3368
+ MEBAND = 2*ML + MU + 1
3369
+ c Replaced LINPACK dgbsl with LAPACK dgbtrs
3370
+ c CALL DGBSL (WM(3), MEBAND, N, ML, MU, IWM(31), X, 0)
3371
+ CALL DGBTRS ('N', N, ML, MU, 1, WM(3), MEBAND, IWM(31), X, N, IER)
3372
+ RETURN
3373
+ C----------------------- End of Subroutine DVSOL -----------------------
3374
+ END
3375
+ *DECK DVSRCO
3376
+ SUBROUTINE DVSRCO (RSAV, ISAV, JOB)
3377
+ DOUBLE PRECISION RSAV
3378
+ INTEGER ISAV, JOB
3379
+ DIMENSION RSAV(*), ISAV(*)
3380
+ C-----------------------------------------------------------------------
3381
+ C Call sequence input -- RSAV, ISAV, JOB
3382
+ C Call sequence output -- RSAV, ISAV
3383
+ C COMMON block variables accessed -- All of /DVOD01/ and /DVOD02/
3384
+ C
3385
+ C Subroutines/functions called by DVSRCO.. None
3386
+ C-----------------------------------------------------------------------
3387
+ C This routine saves or restores (depending on JOB) the contents of the
3388
+ C COMMON blocks DVOD01 and DVOD02, which are used internally by DVODE.
3389
+ C
3390
+ C RSAV = real array of length 49 or more.
3391
+ C ISAV = integer array of length 41 or more.
3392
+ C JOB = flag indicating to save or restore the COMMON blocks..
3393
+ C JOB = 1 if COMMON is to be saved (written to RSAV/ISAV).
3394
+ C JOB = 2 if COMMON is to be restored (read from RSAV/ISAV).
3395
+ C A call with JOB = 2 presumes a prior call with JOB = 1.
3396
+ C-----------------------------------------------------------------------
3397
+ DOUBLE PRECISION RVOD1, RVOD2
3398
+ INTEGER IVOD1, IVOD2
3399
+ INTEGER I, LENIV1, LENIV2, LENRV1, LENRV2
3400
+ C-----------------------------------------------------------------------
3401
+ C The following Fortran-77 declaration is to cause the values of the
3402
+ C listed (local) variables to be saved between calls to this integrator.
3403
+ C-----------------------------------------------------------------------
3404
+ SAVE LENRV1, LENIV1, LENRV2, LENIV2
3405
+ C
3406
+ COMMON /DVOD01/ RVOD1(48), IVOD1(33)
3407
+ COMMON /DVOD02/ RVOD2(1), IVOD2(8)
3408
+ DATA LENRV1/48/, LENIV1/33/, LENRV2/1/, LENIV2/8/
3409
+ C
3410
+ IF (JOB .EQ. 2) GO TO 100
3411
+ DO 10 I = 1,LENRV1
3412
+ 10 RSAV(I) = RVOD1(I)
3413
+ DO 15 I = 1,LENRV2
3414
+ 15 RSAV(LENRV1+I) = RVOD2(I)
3415
+ C
3416
+ DO 20 I = 1,LENIV1
3417
+ 20 ISAV(I) = IVOD1(I)
3418
+ DO 25 I = 1,LENIV2
3419
+ 25 ISAV(LENIV1+I) = IVOD2(I)
3420
+ C
3421
+ RETURN
3422
+ C
3423
+ 100 CONTINUE
3424
+ DO 110 I = 1,LENRV1
3425
+ 110 RVOD1(I) = RSAV(I)
3426
+ DO 115 I = 1,LENRV2
3427
+ 115 RVOD2(I) = RSAV(LENRV1+I)
3428
+ C
3429
+ DO 120 I = 1,LENIV1
3430
+ 120 IVOD1(I) = ISAV(I)
3431
+ DO 125 I = 1,LENIV2
3432
+ 125 IVOD2(I) = ISAV(LENIV1+I)
3433
+ C
3434
+ RETURN
3435
+ C----------------------- End of Subroutine DVSRCO ----------------------
3436
+ END
3437
+ *DECK DEWSET
3438
+ SUBROUTINE DEWSET (N, ITOL, RTOL, ATOL, YCUR, EWT)
3439
+ DOUBLE PRECISION RTOL, ATOL, YCUR, EWT
3440
+ INTEGER N, ITOL
3441
+ DIMENSION RTOL(*), ATOL(*), YCUR(N), EWT(N)
3442
+ C-----------------------------------------------------------------------
3443
+ C Call sequence input -- N, ITOL, RTOL, ATOL, YCUR
3444
+ C Call sequence output -- EWT
3445
+ C COMMON block variables accessed -- None
3446
+ C
3447
+ C Subroutines/functions called by DEWSET.. None
3448
+ C-----------------------------------------------------------------------
3449
+ C This subroutine sets the error weight vector EWT according to
3450
+ C EWT(i) = RTOL(i)*abs(YCUR(i)) + ATOL(i), i = 1,...,N,
3451
+ C with the subscript on RTOL and/or ATOL possibly replaced by 1 above,
3452
+ C depending on the value of ITOL.
3453
+ C-----------------------------------------------------------------------
3454
+ INTEGER I
3455
+ C
3456
+ GO TO (10, 20, 30, 40), ITOL
3457
+ 10 CONTINUE
3458
+ DO 15 I = 1, N
3459
+ 15 EWT(I) = RTOL(1)*ABS(YCUR(I)) + ATOL(1)
3460
+ RETURN
3461
+ 20 CONTINUE
3462
+ DO 25 I = 1, N
3463
+ 25 EWT(I) = RTOL(1)*ABS(YCUR(I)) + ATOL(I)
3464
+ RETURN
3465
+ 30 CONTINUE
3466
+ DO 35 I = 1, N
3467
+ 35 EWT(I) = RTOL(I)*ABS(YCUR(I)) + ATOL(1)
3468
+ RETURN
3469
+ 40 CONTINUE
3470
+ DO 45 I = 1, N
3471
+ 45 EWT(I) = RTOL(I)*ABS(YCUR(I)) + ATOL(I)
3472
+ RETURN
3473
+ C----------------------- End of Subroutine DEWSET ----------------------
3474
+ END
3475
+ *DECK DVNORM
3476
+ DOUBLE PRECISION FUNCTION DVNORM (N, V, W)
3477
+ DOUBLE PRECISION V, W
3478
+ INTEGER N
3479
+ DIMENSION V(N), W(N)
3480
+ C-----------------------------------------------------------------------
3481
+ C Call sequence input -- N, V, W
3482
+ C Call sequence output -- None
3483
+ C COMMON block variables accessed -- None
3484
+ C
3485
+ C Subroutines/functions called by DVNORM.. None
3486
+ C-----------------------------------------------------------------------
3487
+ C This function routine computes the weighted root-mean-square norm
3488
+ C of the vector of length N contained in the array V, with weights
3489
+ C contained in the array W of length N..
3490
+ C DVNORM = sqrt( (1/N) * sum( V(i)*W(i) )**2 )
3491
+ C-----------------------------------------------------------------------
3492
+ DOUBLE PRECISION SUM
3493
+ INTEGER I
3494
+ C
3495
+ SUM = 0.0D0
3496
+ DO 10 I = 1, N
3497
+ 10 SUM = SUM + (V(I)*W(I))**2
3498
+ DVNORM = SQRT(SUM/REAL(N))
3499
+ RETURN
3500
+ C----------------------- End of Function DVNORM ------------------------
3501
+ END
3502
+ *DECK D1MACH
3503
+ DOUBLE PRECISION FUNCTION D1MACH (IDUM)
3504
+ INTEGER IDUM
3505
+ C-----------------------------------------------------------------------
3506
+ C This routine computes the unit roundoff of the machine.
3507
+ C This is defined as the smallest positive machine number
3508
+ C u such that 1.0 + u .ne. 1.0
3509
+ C
3510
+ C Subroutines/functions called by D1MACH.. None
3511
+ C-----------------------------------------------------------------------
3512
+ DOUBLE PRECISION U, COMP
3513
+ U = 1.0D0
3514
+ 10 U = U*0.5D0
3515
+ COMP = 1.0D0 + U
3516
+ IF (COMP .NE. 1.0D0) GO TO 10
3517
+ D1MACH = U*2.0D0
3518
+ RETURN
3519
+ C----------------------- End of Function D1MACH ------------------------
3520
+ END
3521
+ *DECK XERRWD
3522
+ SUBROUTINE XERRWD (MSG, NMES, NERR, LEVEL, NI, I1, I2, NR, R1, R2)
3523
+ DOUBLE PRECISION R1, R2
3524
+ INTEGER NMES, NERR, LEVEL, NI, I1, I2, NR
3525
+ CHARACTER*1 MSG(NMES)
3526
+ C-----------------------------------------------------------------------
3527
+ C Subroutines XERRWD, XSETF, XSETUN, and the function routine IXSAV,
3528
+ C as given here, constitute a simplified version of the SLATEC error
3529
+ C handling package.
3530
+ C Written by A. C. Hindmarsh and P. N. Brown at LLNL.
3531
+ C Version of 18 November, 1992.
3532
+ C This version is in double precision.
3533
+ C
3534
+ C All arguments are input arguments.
3535
+ C
3536
+ C MSG = The message (character array).
3537
+ C NMES = The length of MSG (number of characters).
3538
+ C NERR = The error number (not used).
3539
+ C LEVEL = The error level..
3540
+ C 0 or 1 means recoverable (control returns to caller).
3541
+ C 2 means fatal (run is aborted--see note below).
3542
+ C NI = Number of integers (0, 1, or 2) to be printed with message.
3543
+ C I1,I2 = Integers to be printed, depending on NI.
3544
+ C NR = Number of reals (0, 1, or 2) to be printed with message.
3545
+ C R1,R2 = Reals to be printed, depending on NR.
3546
+ C
3547
+ C Note.. this routine is machine-dependent and specialized for use
3548
+ C in limited context, in the following ways..
3549
+ C 1. The argument MSG is assumed to be of type CHARACTER, and
3550
+ C the message is printed with a format of (1X,80A1).
3551
+ C 2. The message is assumed to take only one line.
3552
+ C Multi-line messages are generated by repeated calls.
3553
+ C 3. If LEVEL = 2, control passes to the statement STOP
3554
+ C to abort the run. This statement may be machine-dependent.
3555
+ C 4. R1 and R2 are assumed to be in double precision and are printed
3556
+ C in D21.13 format.
3557
+ C
3558
+ C For a different default logical unit number, change the data
3559
+ C statement in function routine IXSAV.
3560
+ C For a different run-abort command, change the statement following
3561
+ C statement 100 at the end.
3562
+ C-----------------------------------------------------------------------
3563
+ C Subroutines called by XERRWD.. None
3564
+ C Function routine called by XERRWD.. IXSAV
3565
+ C-----------------------------------------------------------------------
3566
+ C
3567
+ INTEGER I, LUNIT, IXSAV, MESFLG
3568
+ C
3569
+ C Get logical unit number and message print flag. ----------------------
3570
+ LUNIT = IXSAV (1, 0, .FALSE.)
3571
+ MESFLG = IXSAV (2, 0, .FALSE.)
3572
+ IF (MESFLG .EQ. 0) GO TO 100
3573
+ C Write the message. ---------------------------------------------------
3574
+ WRITE (LUNIT,10) (MSG(I),I=1,NMES)
3575
+ 10 FORMAT(1X,80A1)
3576
+ IF (NI .EQ. 1) WRITE (LUNIT, 20) I1
3577
+ 20 FORMAT(6X,'In above message, I1 =',I10)
3578
+ IF (NI .EQ. 2) WRITE (LUNIT, 30) I1,I2
3579
+ 30 FORMAT(6X,'In above message, I1 =',I10,3X,'I2 =',I10)
3580
+ IF (NR .EQ. 1) WRITE (LUNIT, 40) R1
3581
+ 40 FORMAT(6X,'In above message, R1 =',D21.13)
3582
+ IF (NR .EQ. 2) WRITE (LUNIT, 50) R1,R2
3583
+ 50 FORMAT(6X,'In above, R1 =',D21.13,3X,'R2 =',D21.13)
3584
+ C Abort the run if LEVEL = 2. ------------------------------------------
3585
+ 100 IF (LEVEL .NE. 2) RETURN
3586
+ STOP
3587
+ C----------------------- End of Subroutine XERRWD ----------------------
3588
+ END
3589
+ *DECK XSETUN
3590
+ SUBROUTINE XSETUN (LUN)
3591
+ C-----------------------------------------------------------------------
3592
+ C This routine resets the logical unit number for messages.
3593
+ C
3594
+ C Subroutines called by XSETUN.. None
3595
+ C Function routine called by XSETUN.. IXSAV
3596
+ C-----------------------------------------------------------------------
3597
+ INTEGER LUN, JUNK, IXSAV
3598
+ C
3599
+ IF (LUN .GT. 0) JUNK = IXSAV (1,LUN,.TRUE.)
3600
+ RETURN
3601
+ C----------------------- End of Subroutine XSETUN ----------------------
3602
+ END
3603
+ *DECK XSETF
3604
+ SUBROUTINE XSETF (MFLAG)
3605
+ C-----------------------------------------------------------------------
3606
+ C This routine resets the print control flag MFLAG.
3607
+ C
3608
+ C Subroutines called by XSETF.. None
3609
+ C Function routine called by XSETF.. IXSAV
3610
+ C-----------------------------------------------------------------------
3611
+ INTEGER MFLAG, JUNK, IXSAV
3612
+ C
3613
+ IF (MFLAG .EQ. 0 .OR. MFLAG .EQ. 1) JUNK = IXSAV (2,MFLAG,.TRUE.)
3614
+ RETURN
3615
+ C----------------------- End of Subroutine XSETF -----------------------
3616
+ END
3617
+ *DECK IXSAV
3618
+ INTEGER FUNCTION IXSAV (IPAR, IVALUE, ISET)
3619
+ LOGICAL ISET
3620
+ INTEGER IPAR, IVALUE
3621
+ C-----------------------------------------------------------------------
3622
+ C IXSAV saves and recalls one of two error message parameters:
3623
+ C LUNIT, the logical unit number to which messages are printed, and
3624
+ C MESFLG, the message print flag.
3625
+ C This is a modification of the SLATEC library routine J4SAVE.
3626
+ C
3627
+ C Saved local variables..
3628
+ C LUNIT = Logical unit number for messages.
3629
+ C The default is 6 (machine-dependent).
3630
+ C MESFLG = Print control flag..
3631
+ C 1 means print all messages (the default).
3632
+ C 0 means no printing.
3633
+ C
3634
+ C On input..
3635
+ C IPAR = Parameter indicator (1 for LUNIT, 2 for MESFLG).
3636
+ C IVALUE = The value to be set for the parameter, if ISET = .TRUE.
3637
+ C ISET = Logical flag to indicate whether to read or write.
3638
+ C If ISET = .TRUE., the parameter will be given
3639
+ C the value IVALUE. If ISET = .FALSE., the parameter
3640
+ C will be unchanged, and IVALUE is a dummy argument.
3641
+ C
3642
+ C On return..
3643
+ C IXSAV = The (old) value of the parameter.
3644
+ C
3645
+ C Subroutines/functions called by IXSAV.. None
3646
+ C-----------------------------------------------------------------------
3647
+ INTEGER LUNIT, MESFLG
3648
+ C-----------------------------------------------------------------------
3649
+ C The following Fortran-77 declaration is to cause the values of the
3650
+ C listed (local) variables to be saved between calls to this routine.
3651
+ C-----------------------------------------------------------------------
3652
+ SAVE LUNIT, MESFLG
3653
+ DATA LUNIT/6/, MESFLG/1/
3654
+ C
3655
+ IF (IPAR .EQ. 1) THEN
3656
+ IXSAV = LUNIT
3657
+ IF (ISET) LUNIT = IVALUE
3658
+ ENDIF
3659
+ C
3660
+ IF (IPAR .EQ. 2) THEN
3661
+ IXSAV = MESFLG
3662
+ IF (ISET) MESFLG = IVALUE
3663
+ ENDIF
3664
+ C
3665
+ RETURN
3666
+ C----------------------- End of Function IXSAV -------------------------
3667
+ END