ode 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +37 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +17 -0
- data/MIT-License.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +12 -0
- data/SciPy-License.txt +30 -0
- data/ext/ode/extconf.rb +25 -0
- data/ext/ode/ode.c +124 -0
- data/ext/ode/odepack.h +6 -0
- data/ext/ode/odepack/blkdta000.f +26 -0
- data/ext/ode/odepack/bnorm.f +30 -0
- data/ext/ode/odepack/cfode.f +112 -0
- data/ext/ode/odepack/ewset.f +32 -0
- data/ext/ode/odepack/fnorm.f +22 -0
- data/ext/ode/odepack/intdy.f +84 -0
- data/ext/ode/odepack/lsoda.f +1654 -0
- data/ext/ode/odepack/prja.f +177 -0
- data/ext/ode/odepack/readme +84 -0
- data/ext/ode/odepack/solsy.f +72 -0
- data/ext/ode/odepack/srcma.f +55 -0
- data/ext/ode/odepack/stoda.f +637 -0
- data/ext/ode/odepack/vmnorm.f +18 -0
- data/ext/ode/odepack/vode.f +3667 -0
- data/ext/ode/odepack/xerrwv.f +114 -0
- data/ext/ode/odepack/zvode.f +3658 -0
- data/lib/ode.rb +9 -0
- data/lib/ode/methods.rb +15 -0
- data/lib/ode/solver.rb +42 -0
- data/lib/ode/version.rb +3 -0
- data/ode.gemspec +23 -0
- metadata +105 -0
@@ -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
|