ode 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,32 @@
1
+ subroutine ewset (n, itol, rtol, atol, ycur, ewt)
2
+ clll. optimize
3
+ c-----------------------------------------------------------------------
4
+ c this subroutine sets the error weight vector ewt according to
5
+ c ewt(i) = rtol(i)*abs(ycur(i)) + atol(i), i = 1,...,n,
6
+ c with the subscript on rtol and/or atol possibly replaced by 1 above,
7
+ c depending on the value of itol.
8
+ c-----------------------------------------------------------------------
9
+ integer n, itol
10
+ integer i
11
+ double precision rtol, atol, ycur, ewt
12
+ dimension rtol(1), atol(1), ycur(n), ewt(n)
13
+ c
14
+ go to (10, 20, 30, 40), itol
15
+ 10 continue
16
+ do 15 i = 1,n
17
+ 15 ewt(i) = rtol(1)*dabs(ycur(i)) + atol(1)
18
+ return
19
+ 20 continue
20
+ do 25 i = 1,n
21
+ 25 ewt(i) = rtol(1)*dabs(ycur(i)) + atol(i)
22
+ return
23
+ 30 continue
24
+ do 35 i = 1,n
25
+ 35 ewt(i) = rtol(i)*dabs(ycur(i)) + atol(1)
26
+ return
27
+ 40 continue
28
+ do 45 i = 1,n
29
+ 45 ewt(i) = rtol(i)*dabs(ycur(i)) + atol(i)
30
+ return
31
+ c----------------------- end of subroutine ewset -----------------------
32
+ end
@@ -0,0 +1,22 @@
1
+ double precision function fnorm (n, a, w)
2
+ clll. optimize
3
+ c-----------------------------------------------------------------------
4
+ c this function computes the norm of a full n by n matrix,
5
+ c stored in the array a, that is consistent with the weighted max-norm
6
+ c on vectors, with weights stored in the array w..
7
+ c fnorm = max(i=1,...,n) ( w(i) * sum(j=1,...,n) abs(a(i,j))/w(j) )
8
+ c-----------------------------------------------------------------------
9
+ integer n, i, j
10
+ double precision a, w, an, sum
11
+ dimension a(n,n), w(n)
12
+ an = 0.0d0
13
+ do 20 i = 1,n
14
+ sum = 0.0d0
15
+ do 10 j = 1,n
16
+ 10 sum = sum + dabs(a(i,j))/w(j)
17
+ an = dmax1(an,sum*w(i))
18
+ 20 continue
19
+ fnorm = an
20
+ return
21
+ c----------------------- end of function fnorm -------------------------
22
+ end
@@ -0,0 +1,84 @@
1
+ subroutine intdy (t, k, yh, nyh, dky, iflag)
2
+ clll. optimize
3
+ integer k, nyh, iflag
4
+ integer iownd, iowns,
5
+ 1 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter,
6
+ 2 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
7
+ integer i, ic, j, jb, jb2, jj, jj1, jp1
8
+ double precision t, yh, dky
9
+ double precision rowns,
10
+ 1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
11
+ double precision c, r, s, tp
12
+ dimension yh(nyh,1), dky(1)
13
+ common /ls0001/ rowns(209),
14
+ 2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
15
+ 3 iownd(14), iowns(6),
16
+ 4 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter,
17
+ 5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
18
+ c-----------------------------------------------------------------------
19
+ c intdy computes interpolated values of the k-th derivative of the
20
+ c dependent variable vector y, and stores it in dky. this routine
21
+ c is called within the package with k = 0 and t = tout, but may
22
+ c also be called by the user for any k up to the current order.
23
+ c (see detailed instructions in the usage documentation.)
24
+ c-----------------------------------------------------------------------
25
+ c the computed values in dky are gotten by interpolation using the
26
+ c nordsieck history array yh. this array corresponds uniquely to a
27
+ c vector-valued polynomial of degree nqcur or less, and dky is set
28
+ c to the k-th derivative of this polynomial at t.
29
+ c the formula for dky is..
30
+ c q
31
+ c dky(i) = sum c(j,k) * (t - tn)**(j-k) * h**(-j) * yh(i,j+1)
32
+ c j=k
33
+ c where c(j,k) = j*(j-1)*...*(j-k+1), q = nqcur, tn = tcur, h = hcur.
34
+ c the quantities nq = nqcur, l = nq+1, n = neq, tn, and h are
35
+ c communicated by common. the above sum is done in reverse order.
36
+ c iflag is returned negative if either k or t is out of bounds.
37
+ c-----------------------------------------------------------------------
38
+ iflag = 0
39
+ if (k .lt. 0 .or. k .gt. nq) go to 80
40
+ tp = tn - hu - 100.0d0*uround*(tn + hu)
41
+ if ((t-tp)*(t-tn) .gt. 0.0d0) go to 90
42
+ c
43
+ s = (t - tn)/h
44
+ ic = 1
45
+ if (k .eq. 0) go to 15
46
+ jj1 = l - k
47
+ do 10 jj = jj1,nq
48
+ 10 ic = ic*jj
49
+ 15 c = dfloat(ic)
50
+ do 20 i = 1,n
51
+ 20 dky(i) = c*yh(i,l)
52
+ if (k .eq. nq) go to 55
53
+ jb2 = nq - k
54
+ do 50 jb = 1,jb2
55
+ j = nq - jb
56
+ jp1 = j + 1
57
+ ic = 1
58
+ if (k .eq. 0) go to 35
59
+ jj1 = jp1 - k
60
+ do 30 jj = jj1,j
61
+ 30 ic = ic*jj
62
+ 35 c = dfloat(ic)
63
+ do 40 i = 1,n
64
+ 40 dky(i) = c*yh(i,jp1) + s*dky(i)
65
+ 50 continue
66
+ if (k .eq. 0) return
67
+ 55 r = h**(-k)
68
+ do 60 i = 1,n
69
+ 60 dky(i) = r*dky(i)
70
+ return
71
+ c
72
+ 80 call xerrwv('intdy-- k (=i1) illegal ',
73
+ 1 30, 51, 0, 1, k, 0, 0, 0.0d0, 0.0d0)
74
+ iflag = -1
75
+ return
76
+ 90 call xerrwv('intdy-- t (=r1) illegal ',
77
+ 1 30, 52, 0, 0, 0, 0, 1, t, 0.0d0)
78
+ call xerrwv(
79
+ 1 ' t not in interval tcur - hu (= r1) to tcur (=r2) ',
80
+ 1 60, 52, 0, 0, 0, 0, 2, tp, tn)
81
+ iflag = -2
82
+ return
83
+ c----------------------- end of subroutine intdy -----------------------
84
+ end
@@ -0,0 +1,1654 @@
1
+ subroutine lsoda (f, neq, y, t, tout, itol, rtol, atol, itask,
2
+ 1 istate, iopt, rwork, lrw, iwork, liw, jac, jt)
3
+ external f, jac
4
+ integer neq, itol, itask, istate, iopt, lrw, iwork, liw, jt, isav
5
+ double precision y, t, tout, rtol, atol, rwork, rsav
6
+ dimension neq(1), y(1), rtol(1), atol(1), rwork(lrw), iwork(liw)
7
+ dimension rsav(240), isav(50)
8
+ c-----------------------------------------------------------------------
9
+ c this is the 24 feb 1997 version of
10
+ c lsoda.. livermore solver for ordinary differential equations, with
11
+ c automatic method switching for stiff and nonstiff problems.
12
+ c
13
+ c this version is in double precision.
14
+ c
15
+ c lsoda solves the initial value problem for stiff or nonstiff
16
+ c systems of first order ode-s,
17
+ c dy/dt = f(t,y) , or, in component form,
18
+ c dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(neq)) (i = 1,...,neq).
19
+ c
20
+ c this a variant version of the lsode package.
21
+ c it switches automatically between stiff and nonstiff methods.
22
+ c this means that the user does not have to determine whether the
23
+ c problem is stiff or not, and the solver will automatically choose the
24
+ c appropriate method. it always starts with the nonstiff method.
25
+ c
26
+ c authors..
27
+ c linda r. petzold and alan c. hindmarsh,
28
+ c computing and mathematics research division, l-316
29
+ c lawrence livermore national laboratory
30
+ c livermore, ca 94550.
31
+ c
32
+ c references..
33
+ c 1. alan c. hindmarsh, odepack, a systematized collection of ode
34
+ c solvers, in scientific computing, r. s. stepleman et al. (eds.),
35
+ c north-holland, amsterdam, 1983, pp. 55-64.
36
+ c 2. linda r. petzold, automatic selection of methods for solving
37
+ c stiff and nonstiff systems of ordinary differential equations,
38
+ c siam j. sci. stat. comput. 4 (1983), pp. 136-148.
39
+ c-----------------------------------------------------------------------
40
+ c summary of usage.
41
+ c
42
+ c communication between the user and the lsoda package, for normal
43
+ c situations, is summarized here. this summary describes only a subset
44
+ c of the full set of options available. see the full description for
45
+ c details, including alternative treatment of the jacobian matrix,
46
+ c optional inputs and outputs, nonstandard options, and
47
+ c instructions for special situations. see also the example
48
+ c problem (with program and output) following this summary.
49
+ c
50
+ c a. first provide a subroutine of the form..
51
+ c subroutine f (neq, t, y, ydot)
52
+ c dimension y(neq), ydot(neq)
53
+ c which supplies the vector function f by loading ydot(i) with f(i).
54
+ c
55
+ c b. write a main program which calls subroutine lsoda once for
56
+ c each point at which answers are desired. this should also provide
57
+ c for possible use of logical unit 6 for output of error messages
58
+ c by lsoda. on the first call to lsoda, supply arguments as follows..
59
+ c f = name of subroutine for right-hand side vector f.
60
+ c this name must be declared external in calling program.
61
+ c neq = number of first order ode-s.
62
+ c y = array of initial values, of length neq.
63
+ c t = the initial value of the independent variable.
64
+ c tout = first point where output is desired (.ne. t).
65
+ c itol = 1 or 2 according as atol (below) is a scalar or array.
66
+ c rtol = relative tolerance parameter (scalar).
67
+ c atol = absolute tolerance parameter (scalar or array).
68
+ c the estimated local error in y(i) will be controlled so as
69
+ c to be less than
70
+ c ewt(i) = rtol*abs(y(i)) + atol if itol = 1, or
71
+ c ewt(i) = rtol*abs(y(i)) + atol(i) if itol = 2.
72
+ c thus the local error test passes if, in each component,
73
+ c either the absolute error is less than atol (or atol(i)),
74
+ c or the relative error is less than rtol.
75
+ c use rtol = 0.0 for pure absolute error control, and
76
+ c use atol = 0.0 (or atol(i) = 0.0) for pure relative error
77
+ c control. caution.. actual (global) errors may exceed these
78
+ c local tolerances, so choose them conservatively.
79
+ c itask = 1 for normal computation of output values of y at t = tout.
80
+ c istate = integer flag (input and output). set istate = 1.
81
+ c iopt = 0 to indicate no optional inputs used.
82
+ c rwork = real work array of length at least..
83
+ c 22 + neq * max(16, neq + 9).
84
+ c see also paragraph e below.
85
+ c lrw = declared length of rwork (in user-s dimension).
86
+ c iwork = integer work array of length at least 20 + neq.
87
+ c liw = declared length of iwork (in user-s dimension).
88
+ c jac = name of subroutine for jacobian matrix.
89
+ c use a dummy name. see also paragraph e below.
90
+ c jt = jacobian type indicator. set jt = 2.
91
+ c see also paragraph e below.
92
+ c note that the main program must declare arrays y, rwork, iwork,
93
+ c and possibly atol.
94
+ c
95
+ c c. the output from the first call (or any call) is..
96
+ c y = array of computed values of y(t) vector.
97
+ c t = corresponding value of independent variable (normally tout).
98
+ c istate = 2 if lsoda was successful, negative otherwise.
99
+ c -1 means excess work done on this call (perhaps wrong jt).
100
+ c -2 means excess accuracy requested (tolerances too small).
101
+ c -3 means illegal input detected (see printed message).
102
+ c -4 means repeated error test failures (check all inputs).
103
+ c -5 means repeated convergence failures (perhaps bad jacobian
104
+ c supplied or wrong choice of jt or tolerances).
105
+ c -6 means error weight became zero during problem. (solution
106
+ c component i vanished, and atol or atol(i) = 0.)
107
+ c -7 means work space insufficient to finish (see messages).
108
+ c
109
+ c d. to continue the integration after a successful return, simply
110
+ c reset tout and call lsoda again. no other parameters need be reset.
111
+ c
112
+ c e. note.. if and when lsoda regards the problem as stiff, and
113
+ c switches methods accordingly, it must make use of the neq by neq
114
+ c jacobian matrix, j = df/dy. for the sake of simplicity, the
115
+ c inputs to lsoda recommended in paragraph b above cause lsoda to
116
+ c treat j as a full matrix, and to approximate it internally by
117
+ c difference quotients. alternatively, j can be treated as a band
118
+ c matrix (with great potential reduction in the size of the rwork
119
+ c array). also, in either the full or banded case, the user can supply
120
+ c j in closed form, with a routine whose name is passed as the jac
121
+ c argument. these alternatives are described in the paragraphs on
122
+ c rwork, jac, and jt in the full description of the call sequence below.
123
+ c
124
+ c-----------------------------------------------------------------------
125
+ c example problem.
126
+ c
127
+ c the following is a simple example problem, with the coding
128
+ c needed for its solution by lsoda. the problem is from chemical
129
+ c kinetics, and consists of the following three rate equations..
130
+ c dy1/dt = -.04*y1 + 1.e4*y2*y3
131
+ c dy2/dt = .04*y1 - 1.e4*y2*y3 - 3.e7*y2**2
132
+ c dy3/dt = 3.e7*y2**2
133
+ c on the interval from t = 0.0 to t = 4.e10, with initial conditions
134
+ c y1 = 1.0, y2 = y3 = 0. the problem is stiff.
135
+ c
136
+ c the following coding solves this problem with lsoda,
137
+ c printing results at t = .4, 4., ..., 4.e10. it uses
138
+ c itol = 2 and atol much smaller for y2 than y1 or y3 because
139
+ c y2 has much smaller values.
140
+ c at the end of the run, statistical quantities of interest are
141
+ c printed (see optional outputs in the full description below).
142
+ c
143
+ c external fex
144
+ c double precision atol, rtol, rwork, t, tout, y
145
+ c dimension y(3), atol(3), rwork(70), iwork(23)
146
+ c neq = 3
147
+ c y(1) = 1.0d0
148
+ c y(2) = 0.0d0
149
+ c y(3) = 0.0d0
150
+ c t = 0.0d0
151
+ c tout = 0.4d0
152
+ c itol = 2
153
+ c rtol = 1.0d-4
154
+ c atol(1) = 1.0d-6
155
+ c atol(2) = 1.0d-10
156
+ c atol(3) = 1.0d-6
157
+ c itask = 1
158
+ c istate = 1
159
+ c iopt = 0
160
+ c lrw = 70
161
+ c liw = 23
162
+ c jt = 2
163
+ c do 40 iout = 1,12
164
+ c call lsoda(fex,neq,y,t,tout,itol,rtol,atol,itask,istate,
165
+ c 1 iopt,rwork,lrw,iwork,liw,jdum,jt)
166
+ c write(6,20)t,y(1),y(2),y(3)
167
+ c 20 format(' at t =',e12.4,' y =',3e14.6)
168
+ c if (istate .lt. 0) go to 80
169
+ c 40 tout = tout*10.0d0
170
+ c write(6,60)iwork(11),iwork(12),iwork(13),iwork(19),rwork(15)
171
+ c 60 format(/' no. steps =',i4,' no. f-s =',i4,' no. j-s =',i4/
172
+ c 1 ' method last used =',i2,' last switch was at t =',e12.4)
173
+ c stop
174
+ c 80 write(6,90)istate
175
+ c 90 format(///' error halt.. istate =',i3)
176
+ c stop
177
+ c end
178
+ c
179
+ c subroutine fex (neq, t, y, ydot)
180
+ c double precision t, y, ydot
181
+ c dimension y(3), ydot(3)
182
+ c ydot(1) = -.04d0*y(1) + 1.0d4*y(2)*y(3)
183
+ c ydot(3) = 3.0d7*y(2)*y(2)
184
+ c ydot(2) = -ydot(1) - ydot(3)
185
+ c return
186
+ c end
187
+ c
188
+ c the output of this program (on a cdc-7600 in single precision)
189
+ c is as follows..
190
+ c
191
+ c at t = 4.0000e-01 y = 9.851712e-01 3.386380e-05 1.479493e-02
192
+ c at t = 4.0000e+00 y = 9.055333e-01 2.240655e-05 9.444430e-02
193
+ c at t = 4.0000e+01 y = 7.158403e-01 9.186334e-06 2.841505e-01
194
+ c at t = 4.0000e+02 y = 4.505250e-01 3.222964e-06 5.494717e-01
195
+ c at t = 4.0000e+03 y = 1.831975e-01 8.941774e-07 8.168016e-01
196
+ c at t = 4.0000e+04 y = 3.898730e-02 1.621940e-07 9.610125e-01
197
+ c at t = 4.0000e+05 y = 4.936363e-03 1.984221e-08 9.950636e-01
198
+ c at t = 4.0000e+06 y = 5.161831e-04 2.065786e-09 9.994838e-01
199
+ c at t = 4.0000e+07 y = 5.179817e-05 2.072032e-10 9.999482e-01
200
+ c at t = 4.0000e+08 y = 5.283401e-06 2.113371e-11 9.999947e-01
201
+ c at t = 4.0000e+09 y = 4.659031e-07 1.863613e-12 9.999995e-01
202
+ c at t = 4.0000e+10 y = 1.404280e-08 5.617126e-14 1.000000e+00
203
+ c
204
+ c no. steps = 361 no. f-s = 693 no. j-s = 64
205
+ c method last used = 2 last switch was at t = 6.0092e-03
206
+ c-----------------------------------------------------------------------
207
+ c full description of user interface to lsoda.
208
+ c
209
+ c the user interface to lsoda consists of the following parts.
210
+ c
211
+ c i. the call sequence to subroutine lsoda, which is a driver
212
+ c routine for the solver. this includes descriptions of both
213
+ c the call sequence arguments and of user-supplied routines.
214
+ c following these descriptions is a description of
215
+ c optional inputs available through the call sequence, and then
216
+ c a description of optional outputs (in the work arrays).
217
+ c
218
+ c ii. descriptions of other routines in the lsoda package that may be
219
+ c (optionally) called by the user. these provide the ability to
220
+ c alter error message handling, save and restore the internal
221
+ c common, and obtain specified derivatives of the solution y(t).
222
+ c
223
+ c iii. descriptions of common blocks to be declared in overlay
224
+ c or similar environments, or to be saved when doing an interrupt
225
+ c of the problem and continued solution later.
226
+ c
227
+ c iv. description of a subroutine in the lsoda package,
228
+ c which the user may replace with his own version, if desired.
229
+ c this relates to the measurement of errors.
230
+ c
231
+ c-----------------------------------------------------------------------
232
+ c part i. call sequence.
233
+ c
234
+ c the call sequence parameters used for input only are
235
+ c f, neq, tout, itol, rtol, atol, itask, iopt, lrw, liw, jac, jt,
236
+ c and those used for both input and output are
237
+ c y, t, istate.
238
+ c the work arrays rwork and iwork are also used for conditional and
239
+ c optional inputs and optional outputs. (the term output here refers
240
+ c to the return from subroutine lsoda to the user-s calling program.)
241
+ c
242
+ c the legality of input parameters will be thoroughly checked on the
243
+ c initial call for the problem, but not checked thereafter unless a
244
+ c change in input parameters is flagged by istate = 3 on input.
245
+ c
246
+ c the descriptions of the call arguments are as follows.
247
+ c
248
+ c f = the name of the user-supplied subroutine defining the
249
+ c ode system. the system must be put in the first-order
250
+ c form dy/dt = f(t,y), where f is a vector-valued function
251
+ c of the scalar t and the vector y. subroutine f is to
252
+ c compute the function f. it is to have the form
253
+ c subroutine f (neq, t, y, ydot)
254
+ c dimension y(1), ydot(1)
255
+ c where neq, t, and y are input, and the array ydot = f(t,y)
256
+ c is output. y and ydot are arrays of length neq.
257
+ c (in the dimension statement above, 1 is a dummy
258
+ c dimension.. it can be replaced by any value.)
259
+ c subroutine f should not alter y(1),...,y(neq).
260
+ c f must be declared external in the calling program.
261
+ c
262
+ c subroutine f may access user-defined quantities in
263
+ c neq(2),... and/or in y(neq(1)+1),... if neq is an array
264
+ c (dimensioned in f) and/or y has length exceeding neq(1).
265
+ c see the descriptions of neq and y below.
266
+ c
267
+ c if quantities computed in the f routine are needed
268
+ c externally to lsoda, an extra call to f should be made
269
+ c for this purpose, for consistent and accurate results.
270
+ c if only the derivative dy/dt is needed, use intdy instead.
271
+ c
272
+ c neq = the size of the ode system (number of first order
273
+ c ordinary differential equations). used only for input.
274
+ c neq may be decreased, but not increased, during the problem.
275
+ c if neq is decreased (with istate = 3 on input), the
276
+ c remaining components of y should be left undisturbed, if
277
+ c these are to be accessed in f and/or jac.
278
+ c
279
+ c normally, neq is a scalar, and it is generally referred to
280
+ c as a scalar in this user interface description. however,
281
+ c neq may be an array, with neq(1) set to the system size.
282
+ c (the lsoda package accesses only neq(1).) in either case,
283
+ c this parameter is passed as the neq argument in all calls
284
+ c to f and jac. hence, if it is an array, locations
285
+ c neq(2),... may be used to store other integer data and pass
286
+ c it to f and/or jac. subroutines f and/or jac must include
287
+ c neq in a dimension statement in that case.
288
+ c
289
+ c y = a real array for the vector of dependent variables, of
290
+ c length neq or more. used for both input and output on the
291
+ c first call (istate = 1), and only for output on other calls.
292
+ c on the first call, y must contain the vector of initial
293
+ c values. on output, y contains the computed solution vector,
294
+ c evaluated at t. if desired, the y array may be used
295
+ c for other purposes between calls to the solver.
296
+ c
297
+ c this array is passed as the y argument in all calls to
298
+ c f and jac. hence its length may exceed neq, and locations
299
+ c y(neq+1),... may be used to store other real data and
300
+ c pass it to f and/or jac. (the lsoda package accesses only
301
+ c y(1),...,y(neq).)
302
+ c
303
+ c t = the independent variable. on input, t is used only on the
304
+ c first call, as the initial point of the integration.
305
+ c on output, after each call, t is the value at which a
306
+ c computed solution y is evaluated (usually the same as tout).
307
+ c on an error return, t is the farthest point reached.
308
+ c
309
+ c tout = the next value of t at which a computed solution is desired.
310
+ c used only for input.
311
+ c
312
+ c when starting the problem (istate = 1), tout may be equal
313
+ c to t for one call, then should .ne. t for the next call.
314
+ c for the initial t, an input value of tout .ne. t is used
315
+ c in order to determine the direction of the integration
316
+ c (i.e. the algebraic sign of the step sizes) and the rough
317
+ c scale of the problem. integration in either direction
318
+ c (forward or backward in t) is permitted.
319
+ c
320
+ c if itask = 2 or 5 (one-step modes), tout is ignored after
321
+ c the first call (i.e. the first call with tout .ne. t).
322
+ c otherwise, tout is required on every call.
323
+ c
324
+ c if itask = 1, 3, or 4, the values of tout need not be
325
+ c monotone, but a value of tout which backs up is limited
326
+ c to the current internal t interval, whose endpoints are
327
+ c tcur - hu and tcur (see optional outputs, below, for
328
+ c tcur and hu).
329
+ c
330
+ c itol = an indicator for the type of error control. see
331
+ c description below under atol. used only for input.
332
+ c
333
+ c rtol = a relative error tolerance parameter, either a scalar or
334
+ c an array of length neq. see description below under atol.
335
+ c input only.
336
+ c
337
+ c atol = an absolute error tolerance parameter, either a scalar or
338
+ c an array of length neq. input only.
339
+ c
340
+ c the input parameters itol, rtol, and atol determine
341
+ c the error control performed by the solver. the solver will
342
+ c control the vector e = (e(i)) of estimated local errors
343
+ c in y, according to an inequality of the form
344
+ c max-norm of ( e(i)/ewt(i) ) .le. 1,
345
+ c where ewt = (ewt(i)) is a vector of positive error weights.
346
+ c the values of rtol and atol should all be non-negative.
347
+ c the following table gives the types (scalar/array) of
348
+ c rtol and atol, and the corresponding form of ewt(i).
349
+ c
350
+ c itol rtol atol ewt(i)
351
+ c 1 scalar scalar rtol*abs(y(i)) + atol
352
+ c 2 scalar array rtol*abs(y(i)) + atol(i)
353
+ c 3 array scalar rtol(i)*abs(y(i)) + atol
354
+ c 4 array array rtol(i)*abs(y(i)) + atol(i)
355
+ c
356
+ c when either of these parameters is a scalar, it need not
357
+ c be dimensioned in the user-s calling program.
358
+ c
359
+ c if none of the above choices (with itol, rtol, and atol
360
+ c fixed throughout the problem) is suitable, more general
361
+ c error controls can be obtained by substituting a
362
+ c user-supplied routine for the setting of ewt.
363
+ c see part iv below.
364
+ c
365
+ c if global errors are to be estimated by making a repeated
366
+ c run on the same problem with smaller tolerances, then all
367
+ c components of rtol and atol (i.e. of ewt) should be scaled
368
+ c down uniformly.
369
+ c
370
+ c itask = an index specifying the task to be performed.
371
+ c input only. itask has the following values and meanings.
372
+ c 1 means normal computation of output values of y(t) at
373
+ c t = tout (by overshooting and interpolating).
374
+ c 2 means take one step only and return.
375
+ c 3 means stop at the first internal mesh point at or
376
+ c beyond t = tout and return.
377
+ c 4 means normal computation of output values of y(t) at
378
+ c t = tout but without overshooting t = tcrit.
379
+ c tcrit must be input as rwork(1). tcrit may be equal to
380
+ c or beyond tout, but not behind it in the direction of
381
+ c integration. this option is useful if the problem
382
+ c has a singularity at or beyond t = tcrit.
383
+ c 5 means take one step, without passing tcrit, and return.
384
+ c tcrit must be input as rwork(1).
385
+ c
386
+ c note.. if itask = 4 or 5 and the solver reaches tcrit
387
+ c (within roundoff), it will return t = tcrit (exactly) to
388
+ c indicate this (unless itask = 4 and tout comes before tcrit,
389
+ c in which case answers at t = tout are returned first).
390
+ c
391
+ c istate = an index used for input and output to specify the
392
+ c the state of the calculation.
393
+ c
394
+ c on input, the values of istate are as follows.
395
+ c 1 means this is the first call for the problem
396
+ c (initializations will be done). see note below.
397
+ c 2 means this is not the first call, and the calculation
398
+ c is to continue normally, with no change in any input
399
+ c parameters except possibly tout and itask.
400
+ c (if itol, rtol, and/or atol are changed between calls
401
+ c with istate = 2, the new values will be used but not
402
+ c tested for legality.)
403
+ c 3 means this is not the first call, and the
404
+ c calculation is to continue normally, but with
405
+ c a change in input parameters other than
406
+ c tout and itask. changes are allowed in
407
+ c neq, itol, rtol, atol, iopt, lrw, liw, jt, ml, mu,
408
+ c and any optional inputs except h0, mxordn, and mxords.
409
+ c (see iwork description for ml and mu.)
410
+ c note.. a preliminary call with tout = t is not counted
411
+ c as a first call here, as no initialization or checking of
412
+ c input is done. (such a call is sometimes useful for the
413
+ c purpose of outputting the initial conditions.)
414
+ c thus the first call for which tout .ne. t requires
415
+ c istate = 1 on input.
416
+ c
417
+ c on output, istate has the following values and meanings.
418
+ c 1 means nothing was done, as tout was equal to t with
419
+ c istate = 1 on input. (however, an internal counter was
420
+ c set to detect and prevent repeated calls of this type.)
421
+ c 2 means the integration was performed successfully.
422
+ c -1 means an excessive amount of work (more than mxstep
423
+ c steps) was done on this call, before completing the
424
+ c requested task, but the integration was otherwise
425
+ c successful as far as t. (mxstep is an optional input
426
+ c and is normally 500.) to continue, the user may
427
+ c simply reset istate to a value .gt. 1 and call again
428
+ c (the excess work step counter will be reset to 0).
429
+ c in addition, the user may increase mxstep to avoid
430
+ c this error return (see below on optional inputs).
431
+ c -2 means too much accuracy was requested for the precision
432
+ c of the machine being used. this was detected before
433
+ c completing the requested task, but the integration
434
+ c was successful as far as t. to continue, the tolerance
435
+ c parameters must be reset, and istate must be set
436
+ c to 3. the optional output tolsf may be used for this
437
+ c purpose. (note.. if this condition is detected before
438
+ c taking any steps, then an illegal input return
439
+ c (istate = -3) occurs instead.)
440
+ c -3 means illegal input was detected, before taking any
441
+ c integration steps. see written message for details.
442
+ c note.. if the solver detects an infinite loop of calls
443
+ c to the solver with illegal input, it will cause
444
+ c the run to stop.
445
+ c -4 means there were repeated error test failures on
446
+ c one attempted step, before completing the requested
447
+ c task, but the integration was successful as far as t.
448
+ c the problem may have a singularity, or the input
449
+ c may be inappropriate.
450
+ c -5 means there were repeated convergence test failures on
451
+ c one attempted step, before completing the requested
452
+ c task, but the integration was successful as far as t.
453
+ c this may be caused by an inaccurate jacobian matrix,
454
+ c if one is being used.
455
+ c -6 means ewt(i) became zero for some i during the
456
+ c integration. pure relative error control (atol(i)=0.0)
457
+ c was requested on a variable which has now vanished.
458
+ c the integration was successful as far as t.
459
+ c -7 means the length of rwork and/or iwork was too small to
460
+ c proceed, but the integration was successful as far as t.
461
+ c this happens when lsoda chooses to switch methods
462
+ c but lrw and/or liw is too small for the new method.
463
+ c
464
+ c note.. since the normal output value of istate is 2,
465
+ c it does not need to be reset for normal continuation.
466
+ c also, since a negative input value of istate will be
467
+ c regarded as illegal, a negative output value requires the
468
+ c user to change it, and possibly other inputs, before
469
+ c calling the solver again.
470
+ c
471
+ c iopt = an integer flag to specify whether or not any optional
472
+ c inputs are being used on this call. input only.
473
+ c the optional inputs are listed separately below.
474
+ c iopt = 0 means no optional inputs are being used.
475
+ c default values will be used in all cases.
476
+ c iopt = 1 means one or more optional inputs are being used.
477
+ c
478
+ c rwork = a real array (double precision) for work space, and (in the
479
+ c first 20 words) for conditional and optional inputs and
480
+ c optional outputs.
481
+ c as lsoda switches automatically between stiff and nonstiff
482
+ c methods, the required length of rwork can change during the
483
+ c problem. thus the rwork array passed to lsoda can either
484
+ c have a static (fixed) length large enough for both methods,
485
+ c or have a dynamic (changing) length altered by the calling
486
+ c program in response to output from lsoda.
487
+ c
488
+ c --- fixed length case ---
489
+ c if the rwork length is to be fixed, it should be at least
490
+ c max (lrn, lrs),
491
+ c where lrn and lrs are the rwork lengths required when the
492
+ c current method is nonstiff or stiff, respectively.
493
+ c
494
+ c the separate rwork length requirements lrn and lrs are
495
+ c as follows..
496
+ c if neq is constant and the maximum method orders have
497
+ c their default values, then
498
+ c lrn = 20 + 16*neq,
499
+ c lrs = 22 + 9*neq + neq**2 if jt = 1 or 2,
500
+ c lrs = 22 + 10*neq + (2*ml+mu)*neq if jt = 4 or 5.
501
+ c under any other conditions, lrn and lrs are given by..
502
+ c lrn = 20 + nyh*(mxordn+1) + 3*neq,
503
+ c lrs = 20 + nyh*(mxords+1) + 3*neq + lmat,
504
+ c where
505
+ c nyh = the initial value of neq,
506
+ c mxordn = 12, unless a smaller value is given as an
507
+ c optional input,
508
+ c mxords = 5, unless a smaller value is given as an
509
+ c optional input,
510
+ c lmat = length of matrix work space..
511
+ c lmat = neq**2 + 2 if jt = 1 or 2,
512
+ c lmat = (2*ml + mu + 1)*neq + 2 if jt = 4 or 5.
513
+ c
514
+ c --- dynamic length case ---
515
+ c if the length of rwork is to be dynamic, then it should
516
+ c be at least lrn or lrs, as defined above, depending on the
517
+ c current method. initially, it must be at least lrn (since
518
+ c lsoda starts with the nonstiff method). on any return
519
+ c from lsoda, the optional output mcur indicates the current
520
+ c method. if mcur differs from the value it had on the
521
+ c previous return, or if there has only been one call to
522
+ c lsoda and mcur is now 2, then lsoda has switched
523
+ c methods during the last call, and the length of rwork
524
+ c should be reset (to lrn if mcur = 1, or to lrs if
525
+ c mcur = 2). (an increase in the rwork length is required
526
+ c if lsoda returned istate = -7, but not otherwise.)
527
+ c after resetting the length, call lsoda with istate = 3
528
+ c to signal that change.
529
+ c
530
+ c lrw = the length of the array rwork, as declared by the user.
531
+ c (this will be checked by the solver.)
532
+ c
533
+ c iwork = an integer array for work space.
534
+ c as lsoda switches automatically between stiff and nonstiff
535
+ c methods, the required length of iwork can change during
536
+ c problem, between
537
+ c lis = 20 + neq and lin = 20,
538
+ c respectively. thus the iwork array passed to lsoda can
539
+ c either have a fixed length of at least 20 + neq, or have a
540
+ c dynamic length of at least lin or lis, depending on the
541
+ c current method. the comments on dynamic length under
542
+ c rwork above apply here. initially, this length need
543
+ c only be at least lin = 20.
544
+ c
545
+ c the first few words of iwork are used for conditional and
546
+ c optional inputs and optional outputs.
547
+ c
548
+ c the following 2 words in iwork are conditional inputs..
549
+ c iwork(1) = ml these are the lower and upper
550
+ c iwork(2) = mu half-bandwidths, respectively, of the
551
+ c banded jacobian, excluding the main diagonal.
552
+ c the band is defined by the matrix locations
553
+ c (i,j) with i-ml .le. j .le. i+mu. ml and mu
554
+ c must satisfy 0 .le. ml,mu .le. neq-1.
555
+ c these are required if jt is 4 or 5, and
556
+ c ignored otherwise. ml and mu may in fact be
557
+ c the band parameters for a matrix to which
558
+ c df/dy is only approximately equal.
559
+ c
560
+ c liw = the length of the array iwork, as declared by the user.
561
+ c (this will be checked by the solver.)
562
+ c
563
+ c note.. the base addresses of the work arrays must not be
564
+ c altered between calls to lsoda for the same problem.
565
+ c the contents of the work arrays must not be altered
566
+ c between calls, except possibly for the conditional and
567
+ c optional inputs, and except for the last 3*neq words of rwork.
568
+ c the latter space is used for internal scratch space, and so is
569
+ c available for use by the user outside lsoda between calls, if
570
+ c desired (but not for use by f or jac).
571
+ c
572
+ c jac = the name of the user-supplied routine to compute the
573
+ c jacobian matrix, df/dy, if jt = 1 or 4. the jac routine
574
+ c is optional, but if the problem is expected to be stiff much
575
+ c of the time, you are encouraged to supply jac, for the sake
576
+ c of efficiency. (alternatively, set jt = 2 or 5 to have
577
+ c lsoda compute df/dy internally by difference quotients.)
578
+ c if and when lsoda uses df/dy, if treats this neq by neq
579
+ c matrix either as full (jt = 1 or 2), or as banded (jt =
580
+ c 4 or 5) with half-bandwidths ml and mu (discussed under
581
+ c iwork above). in either case, if jt = 1 or 4, the jac
582
+ c routine must compute df/dy as a function of the scalar t
583
+ c and the vector y. it is to have the form
584
+ c subroutine jac (neq, t, y, ml, mu, pd, nrowpd)
585
+ c dimension y(1), pd(nrowpd,1)
586
+ c where neq, t, y, ml, mu, and nrowpd are input and the array
587
+ c pd is to be loaded with partial derivatives (elements of
588
+ c the jacobian matrix) on output. pd must be given a first
589
+ c dimension of nrowpd. t and y have the same meaning as in
590
+ c subroutine f. (in the dimension statement above, 1 is a
591
+ c dummy dimension.. it can be replaced by any value.)
592
+ c in the full matrix case (jt = 1), ml and mu are
593
+ c ignored, and the jacobian is to be loaded into pd in
594
+ c columnwise manner, with df(i)/dy(j) loaded into pd(i,j).
595
+ c in the band matrix case (jt = 4), the elements
596
+ c within the band are to be loaded into pd in columnwise
597
+ c manner, with diagonal lines of df/dy loaded into the rows
598
+ c of pd. thus df(i)/dy(j) is to be loaded into pd(i-j+mu+1,j).
599
+ c ml and mu are the half-bandwidth parameters (see iwork).
600
+ c the locations in pd in the two triangular areas which
601
+ c correspond to nonexistent matrix elements can be ignored
602
+ c or loaded arbitrarily, as they are overwritten by lsoda.
603
+ c jac need not provide df/dy exactly. a crude
604
+ c approximation (possibly with a smaller bandwidth) will do.
605
+ c in either case, pd is preset to zero by the solver,
606
+ c so that only the nonzero elements need be loaded by jac.
607
+ c each call to jac is preceded by a call to f with the same
608
+ c arguments neq, t, and y. thus to gain some efficiency,
609
+ c intermediate quantities shared by both calculations may be
610
+ c saved in a user common block by f and not recomputed by jac,
611
+ c if desired. also, jac may alter the y array, if desired.
612
+ c jac must be declared external in the calling program.
613
+ c subroutine jac may access user-defined quantities in
614
+ c neq(2),... and/or in y(neq(1)+1),... if neq is an array
615
+ c (dimensioned in jac) and/or y has length exceeding neq(1).
616
+ c see the descriptions of neq and y above.
617
+ c
618
+ c jt = jacobian type indicator. used only for input.
619
+ c jt specifies how the jacobian matrix df/dy will be
620
+ c treated, if and when lsoda requires this matrix.
621
+ c jt has the following values and meanings..
622
+ c 1 means a user-supplied full (neq by neq) jacobian.
623
+ c 2 means an internally generated (difference quotient) full
624
+ c jacobian (using neq extra calls to f per df/dy value).
625
+ c 4 means a user-supplied banded jacobian.
626
+ c 5 means an internally generated banded jacobian (using
627
+ c ml+mu+1 extra calls to f per df/dy evaluation).
628
+ c if jt = 1 or 4, the user must supply a subroutine jac
629
+ c (the name is arbitrary) as described above under jac.
630
+ c if jt = 2 or 5, a dummy argument can be used.
631
+ c-----------------------------------------------------------------------
632
+ c optional inputs.
633
+ c
634
+ c the following is a list of the optional inputs provided for in the
635
+ c call sequence. (see also part ii.) for each such input variable,
636
+ c this table lists its name as used in this documentation, its
637
+ c location in the call sequence, its meaning, and the default value.
638
+ c the use of any of these inputs requires iopt = 1, and in that
639
+ c case all of these inputs are examined. a value of zero for any
640
+ c of these optional inputs will cause the default value to be used.
641
+ c thus to use a subset of the optional inputs, simply preload
642
+ c locations 5 to 10 in rwork and iwork to 0.0 and 0 respectively, and
643
+ c then set those of interest to nonzero values.
644
+ c
645
+ c name location meaning and default value
646
+ c
647
+ c h0 rwork(5) the step size to be attempted on the first step.
648
+ c the default value is determined by the solver.
649
+ c
650
+ c hmax rwork(6) the maximum absolute step size allowed.
651
+ c the default value is infinite.
652
+ c
653
+ c hmin rwork(7) the minimum absolute step size allowed.
654
+ c the default value is 0. (this lower bound is not
655
+ c enforced on the final step before reaching tcrit
656
+ c when itask = 4 or 5.)
657
+ c
658
+ c ixpr iwork(5) flag to generate extra printing at method switches.
659
+ c ixpr = 0 means no extra printing (the default).
660
+ c ixpr = 1 means print data on each switch.
661
+ c t, h, and nst will be printed on the same logical
662
+ c unit as used for error messages.
663
+ c
664
+ c mxstep iwork(6) maximum number of (internally defined) steps
665
+ c allowed during one call to the solver.
666
+ c the default value is 500.
667
+ c
668
+ c mxhnil iwork(7) maximum number of messages printed (per problem)
669
+ c warning that t + h = t on a step (h = step size).
670
+ c this must be positive to result in a non-default
671
+ c value. the default value is 10.
672
+ c
673
+ c mxordn iwork(8) the maximum order to be allowed for the nonstiff
674
+ c (adams) method. the default value is 12.
675
+ c if mxordn exceeds the default value, it will
676
+ c be reduced to the default value.
677
+ c mxordn is held constant during the problem.
678
+ c
679
+ c mxords iwork(9) the maximum order to be allowed for the stiff
680
+ c (bdf) method. the default value is 5.
681
+ c if mxords exceeds the default value, it will
682
+ c be reduced to the default value.
683
+ c mxords is held constant during the problem.
684
+ c-----------------------------------------------------------------------
685
+ c optional outputs.
686
+ c
687
+ c as optional additional output from lsoda, the variables listed
688
+ c below are quantities related to the performance of lsoda
689
+ c which are available to the user. these are communicated by way of
690
+ c the work arrays, but also have internal mnemonic names as shown.
691
+ c except where stated otherwise, all of these outputs are defined
692
+ c on any successful return from lsoda, and on any return with
693
+ c istate = -1, -2, -4, -5, or -6. on an illegal input return
694
+ c (istate = -3), they will be unchanged from their existing values
695
+ c (if any), except possibly for tolsf, lenrw, and leniw.
696
+ c on any error return, outputs relevant to the error will be defined,
697
+ c as noted below.
698
+ c
699
+ c name location meaning
700
+ c
701
+ c hu rwork(11) the step size in t last used (successfully).
702
+ c
703
+ c hcur rwork(12) the step size to be attempted on the next step.
704
+ c
705
+ c tcur rwork(13) the current value of the independent variable
706
+ c which the solver has actually reached, i.e. the
707
+ c current internal mesh point in t. on output, tcur
708
+ c will always be at least as far as the argument
709
+ c t, but may be farther (if interpolation was done).
710
+ c
711
+ c tolsf rwork(14) a tolerance scale factor, greater than 1.0,
712
+ c computed when a request for too much accuracy was
713
+ c detected (istate = -3 if detected at the start of
714
+ c the problem, istate = -2 otherwise). if itol is
715
+ c left unaltered but rtol and atol are uniformly
716
+ c scaled up by a factor of tolsf for the next call,
717
+ c then the solver is deemed likely to succeed.
718
+ c (the user may also ignore tolsf and alter the
719
+ c tolerance parameters in any other way appropriate.)
720
+ c
721
+ c tsw rwork(15) the value of t at the time of the last method
722
+ c switch, if any.
723
+ c
724
+ c nst iwork(11) the number of steps taken for the problem so far.
725
+ c
726
+ c nfe iwork(12) the number of f evaluations for the problem so far.
727
+ c
728
+ c nje iwork(13) the number of jacobian evaluations (and of matrix
729
+ c lu decompositions) for the problem so far.
730
+ c
731
+ c nqu iwork(14) the method order last used (successfully).
732
+ c
733
+ c nqcur iwork(15) the order to be attempted on the next step.
734
+ c
735
+ c imxer iwork(16) the index of the component of largest magnitude in
736
+ c the weighted local error vector ( e(i)/ewt(i) ),
737
+ c on an error return with istate = -4 or -5.
738
+ c
739
+ c lenrw iwork(17) the length of rwork actually required, assuming
740
+ c that the length of rwork is to be fixed for the
741
+ c rest of the problem, and that switching may occur.
742
+ c this is defined on normal returns and on an illegal
743
+ c input return for insufficient storage.
744
+ c
745
+ c leniw iwork(18) the length of iwork actually required, assuming
746
+ c that the length of iwork is to be fixed for the
747
+ c rest of the problem, and that switching may occur.
748
+ c this is defined on normal returns and on an illegal
749
+ c input return for insufficient storage.
750
+ c
751
+ c mused iwork(19) the method indicator for the last successful step..
752
+ c 1 means adams (nonstiff), 2 means bdf (stiff).
753
+ c
754
+ c mcur iwork(20) the current method indicator..
755
+ c 1 means adams (nonstiff), 2 means bdf (stiff).
756
+ c this is the method to be attempted
757
+ c on the next step. thus it differs from mused
758
+ c only if a method switch has just been made.
759
+ c
760
+ c the following two arrays are segments of the rwork array which
761
+ c may also be of interest to the user as optional outputs.
762
+ c for each array, the table below gives its internal name,
763
+ c its base address in rwork, and its description.
764
+ c
765
+ c name base address description
766
+ c
767
+ c yh 21 the nordsieck history array, of size nyh by
768
+ c (nqcur + 1), where nyh is the initial value
769
+ c of neq. for j = 0,1,...,nqcur, column j+1
770
+ c of yh contains hcur**j/factorial(j) times
771
+ c the j-th derivative of the interpolating
772
+ c polynomial currently representing the solution,
773
+ c evaluated at t = tcur.
774
+ c
775
+ c acor lacor array of size neq used for the accumulated
776
+ c (from common corrections on each step, scaled on output
777
+ c as noted) to represent the estimated local error in y
778
+ c on the last step. this is the vector e in
779
+ c the description of the error control. it is
780
+ c defined only on a successful return from lsoda.
781
+ c the base address lacor is obtained by
782
+ c including in the user-s program the
783
+ c following 3 lines..
784
+ c double precision rls
785
+ c common /ls0001/ rls(218), ils(39)
786
+ c lacor = ils(5)
787
+ c
788
+ c-----------------------------------------------------------------------
789
+ c part ii. other routines callable.
790
+ c
791
+ c the following are optional calls which the user may make to
792
+ c gain additional capabilities in conjunction with lsoda.
793
+ c (the routines xsetun and xsetf are designed to conform to the
794
+ c slatec error handling package.)
795
+ c
796
+ c form of call function
797
+ c call xsetun(lun) set the logical unit number, lun, for
798
+ c output of messages from lsoda, if
799
+ c the default is not desired.
800
+ c the default value of lun is 6.
801
+ c
802
+ c call xsetf(mflag) set a flag to control the printing of
803
+ c messages by lsoda.
804
+ c mflag = 0 means do not print. (danger..
805
+ c this risks losing valuable information.)
806
+ c mflag = 1 means print (the default).
807
+ c
808
+ c either of the above calls may be made at
809
+ c any time and will take effect immediately.
810
+ c
811
+ c call srcma(rsav,isav,job) saves and restores the contents of
812
+ c the internal common blocks used by
813
+ c lsoda (see part iii below).
814
+ c rsav must be a real array of length 240
815
+ c or more, and isav must be an integer
816
+ c array of length 50 or more.
817
+ c job=1 means save common into rsav/isav.
818
+ c job=2 means restore common from rsav/isav.
819
+ c srcma is useful if one is
820
+ c interrupting a run and restarting
821
+ c later, or alternating between two or
822
+ c more problems solved with lsoda.
823
+ c
824
+ c call intdy(,,,,,) provide derivatives of y, of various
825
+ c (see below) orders, at a specified point t, if
826
+ c desired. it may be called only after
827
+ c a successful return from lsoda.
828
+ c
829
+ c the detailed instructions for using intdy are as follows.
830
+ c the form of the call is..
831
+ c
832
+ c call intdy (t, k, rwork(21), nyh, dky, iflag)
833
+ c
834
+ c the input parameters are..
835
+ c
836
+ c t = value of independent variable where answers are desired
837
+ c (normally the same as the t last returned by lsoda).
838
+ c for valid results, t must lie between tcur - hu and tcur.
839
+ c (see optional outputs for tcur and hu.)
840
+ c k = integer order of the derivative desired. k must satisfy
841
+ c 0 .le. k .le. nqcur, where nqcur is the current order
842
+ c (see optional outputs). the capability corresponding
843
+ c to k = 0, i.e. computing y(t), is already provided
844
+ c by lsoda directly. since nqcur .ge. 1, the first
845
+ c derivative dy/dt is always available with intdy.
846
+ c rwork(21) = the base address of the history array yh.
847
+ c nyh = column length of yh, equal to the initial value of neq.
848
+ c
849
+ c the output parameters are..
850
+ c
851
+ c dky = a real array of length neq containing the computed value
852
+ c of the k-th derivative of y(t).
853
+ c iflag = integer flag, returned as 0 if k and t were legal,
854
+ c -1 if k was illegal, and -2 if t was illegal.
855
+ c on an error return, a message is also written.
856
+ c-----------------------------------------------------------------------
857
+ c part iii. common blocks.
858
+ c
859
+ c if lsoda is to be used in an overlay situation, the user
860
+ c must declare, in the primary overlay, the variables in..
861
+ c (1) the call sequence to lsoda,
862
+ c (2) the three internal common blocks
863
+ c /ls0001/ of length 257 (218 double precision words
864
+ c followed by 39 integer words),
865
+ c /lsa001/ of length 31 (22 double precision words
866
+ c followed by 9 integer words),
867
+ c /eh0001/ of length 2 (integer words).
868
+ c
869
+ c if lsoda is used on a system in which the contents of internal
870
+ c common blocks are not preserved between calls, the user should
871
+ c declare the above common blocks in his main program to insure
872
+ c that their contents are preserved.
873
+ c
874
+ c if the solution of a given problem by lsoda is to be interrupted
875
+ c and then later continued, such as when restarting an interrupted run
876
+ c or alternating between two or more problems, the user should save,
877
+ c following the return from the last lsoda call prior to the
878
+ c interruption, the contents of the call sequence variables and the
879
+ c internal common blocks, and later restore these values before the
880
+ c next lsoda call for that problem. to save and restore the common
881
+ c blocks, use subroutine srcma (see part ii above).
882
+ c
883
+ c-----------------------------------------------------------------------
884
+ c part iv. optionally replaceable solver routines.
885
+ c
886
+ c below is a description of a routine in the lsoda package which
887
+ c relates to the measurement of errors, and can be
888
+ c replaced by a user-supplied version, if desired. however, since such
889
+ c a replacement may have a major impact on performance, it should be
890
+ c done only when absolutely necessary, and only with great caution.
891
+ c (note.. the means by which the package version of a routine is
892
+ c superseded by the user-s version may be system-dependent.)
893
+ c
894
+ c (a) ewset.
895
+ c the following subroutine is called just before each internal
896
+ c integration step, and sets the array of error weights, ewt, as
897
+ c described under itol/rtol/atol above..
898
+ c subroutine ewset (neq, itol, rtol, atol, ycur, ewt)
899
+ c where neq, itol, rtol, and atol are as in the lsoda call sequence,
900
+ c ycur contains the current dependent variable vector, and
901
+ c ewt is the array of weights set by ewset.
902
+ c
903
+ c if the user supplies this subroutine, it must return in ewt(i)
904
+ c (i = 1,...,neq) a positive quantity suitable for comparing errors
905
+ c in y(i) to. the ewt array returned by ewset is passed to the
906
+ c vmnorm routine, and also used by lsoda in the computation
907
+ c of the optional output imxer, and the increments for difference
908
+ c quotient jacobians.
909
+ c
910
+ c in the user-supplied version of ewset, it may be desirable to use
911
+ c the current values of derivatives of y. derivatives up to order nq
912
+ c are available from the history array yh, described above under
913
+ c optional outputs. in ewset, yh is identical to the ycur array,
914
+ c extended to nq + 1 columns with a column length of nyh and scale
915
+ c factors of h**j/factorial(j). on the first call for the problem,
916
+ c given by nst = 0, nq is 1 and h is temporarily set to 1.0.
917
+ c the quantities nq, nyh, h, and nst can be obtained by including
918
+ c in ewset the statements..
919
+ c double precision h, rls
920
+ c common /ls0001/ rls(218),ils(39)
921
+ c nq = ils(35)
922
+ c nyh = ils(14)
923
+ c nst = ils(36)
924
+ c h = rls(212)
925
+ c thus, for example, the current value of dy/dt can be obtained as
926
+ c ycur(nyh+i)/h (i=1,...,neq) (and the division by h is
927
+ c unnecessary when nst = 0).
928
+ c-----------------------------------------------------------------------
929
+ c-----------------------------------------------------------------------
930
+ c other routines in the lsoda package.
931
+ c
932
+ c in addition to subroutine lsoda, the lsoda package includes the
933
+ c following subroutines and function routines..
934
+ c intdy computes an interpolated value of the y vector at t = tout.
935
+ c stoda is the core integrator, which does one step of the
936
+ c integration and the associated error control.
937
+ c cfode sets all method coefficients and test constants.
938
+ c prja computes and preprocesses the jacobian matrix j = df/dy
939
+ c and the newton iteration matrix p = i - h*l0*j.
940
+ c solsy manages solution of linear system in chord iteration.
941
+ c ewset sets the error weight vector ewt before each step.
942
+ c vmnorm computes the weighted max-norm of a vector.
943
+ c fnorm computes the norm of a full matrix consistent with the
944
+ c weighted max-norm on vectors.
945
+ c bnorm computes the norm of a band matrix consistent with the
946
+ c weighted max-norm on vectors.
947
+ c srcma is a user-callable routine to save and restore
948
+ c the contents of the internal common blocks.
949
+ c dgetrf and dgetrs are routines from lapack for solving full
950
+ c systems of linear algebraic equations.
951
+ c dgbtrf and dgbtrs are routines from lapack for solving banded
952
+ c linear systems.
953
+ c daxpy, dscal, idamax, and ddot are basic linear algebra modules
954
+ c (blas) used by the above linpack routines.
955
+ c d1mach computes the unit roundoff in a machine-independent manner.
956
+ c xerrwv, xsetun, and xsetf handle the printing of all error
957
+ c messages and warnings. xerrwv is machine-dependent.
958
+ c note.. vmnorm, fnorm, bnorm, idamax, ddot, and d1mach are function
959
+ c routines. all the others are subroutines.
960
+ c
961
+ c the intrinsic and external routines used by lsoda are..
962
+ c dabs, dmax1, dmin1, dfloat, max0, min0, mod, dsign, dsqrt, and write.
963
+ c
964
+ c a block data subprogram is also included with the package,
965
+ c for loading some of the variables in internal common.
966
+ c
967
+ c-----------------------------------------------------------------------
968
+ c the following card is for optimized compilation on lll compilers.
969
+ clll. optimize
970
+ c-----------------------------------------------------------------------
971
+ external prja, solsy
972
+ integer illin, init, lyh, lewt, lacor, lsavf, lwm, liwm,
973
+ 1 mxstep, mxhnil, nhnil, ntrep, nslast, nyh, iowns
974
+ integer icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter,
975
+ 1 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
976
+ integer insufr, insufi, ixpr, iowns2, jtyp, mused, mxordn, mxords
977
+ integer i, i1, i2, iflag, imxer, kgo, lf0,
978
+ 1 leniw, lenrw, lenwm, ml, mord, mu, mxhnl0, mxstp0
979
+ integer len1, len1c, len1n, len1s, len2, leniwc,
980
+ 1 lenrwc, lenrwn, lenrws
981
+ double precision rowns,
982
+ 1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
983
+ double precision tsw, rowns2, pdnorm
984
+ double precision atoli, ayi, big, ewti, h0, hmax, hmx, rh, rtoli,
985
+ 1 tcrit, tdist, tnext, tol, tolsf, tp, size, sum, w0,
986
+ 2 d1mach, vmnorm
987
+ dimension mord(2)
988
+ logical ihit
989
+ c-----------------------------------------------------------------------
990
+ c the following two internal common blocks contain
991
+ c (a) variables which are local to any subroutine but whose values must
992
+ c be preserved between calls to the routine (own variables), and
993
+ c (b) variables which are communicated between subroutines.
994
+ c the structure of each block is as follows.. all real variables are
995
+ c listed first, followed by all integers. within each type, the
996
+ c variables are grouped with those local to subroutine lsoda first,
997
+ c then those local to subroutine stoda, and finally those used
998
+ c for communication. the block ls0001 is declared in subroutines
999
+ c lsoda, intdy, stoda, prja, and solsy. the block lsa001 is declared
1000
+ c in subroutines lsoda, stoda, and prja. groups of variables are
1001
+ c replaced by dummy arrays in the common declarations in routines
1002
+ c where those variables are not used.
1003
+ c-----------------------------------------------------------------------
1004
+ common /ls0001/ rowns(209),
1005
+ 1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
1006
+ 2 illin, init, lyh, lewt, lacor, lsavf, lwm, liwm,
1007
+ 3 mxstep, mxhnil, nhnil, ntrep, nslast, nyh, iowns(6),
1008
+ 4 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter,
1009
+ 5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
1010
+ common /lsa001/ tsw, rowns2(20), pdnorm,
1011
+ 1 insufr, insufi, ixpr, iowns2(2), jtyp, mused, mxordn, mxords
1012
+ c
1013
+ data mord(1),mord(2)/12,5/, mxstp0/500/, mxhnl0/10/
1014
+ c-----------------------------------------------------------------------
1015
+ c block a.
1016
+ c this code block is executed on every call.
1017
+ c it tests istate and itask for legality and branches appropriately.
1018
+ c if istate .gt. 1 but the flag init shows that initialization has
1019
+ c not yet been done, an error return occurs.
1020
+ c if istate = 1 and tout = t, jump to block g and return immediately.
1021
+ c-----------------------------------------------------------------------
1022
+ if (istate .lt. 1 .or. istate .gt. 3) go to 601
1023
+ if (itask .lt. 1 .or. itask .gt. 5) go to 602
1024
+ if (istate .eq. 1) go to 10
1025
+ if (init .eq. 0) go to 603
1026
+ if (istate .eq. 2) go to 200
1027
+ go to 20
1028
+ 10 init = 0
1029
+ if (tout .eq. t) go to 430
1030
+ 20 ntrep = 0
1031
+ c-----------------------------------------------------------------------
1032
+ c block b.
1033
+ c the next code block is executed for the initial call (istate = 1),
1034
+ c or for a continuation call with parameter changes (istate = 3).
1035
+ c it contains checking of all inputs and various initializations.
1036
+ c
1037
+ c first check legality of the non-optional inputs neq, itol, iopt,
1038
+ c jt, ml, and mu.
1039
+ c-----------------------------------------------------------------------
1040
+ if (neq(1) .le. 0) go to 604
1041
+ if (istate .eq. 1) go to 25
1042
+ if (neq(1) .gt. n) go to 605
1043
+ 25 n = neq(1)
1044
+ if (itol .lt. 1 .or. itol .gt. 4) go to 606
1045
+ if (iopt .lt. 0 .or. iopt .gt. 1) go to 607
1046
+ if (jt .eq. 3 .or. jt .lt. 1 .or. jt .gt. 5) go to 608
1047
+ jtyp = jt
1048
+ if (jt .le. 2) go to 30
1049
+ ml = iwork(1)
1050
+ mu = iwork(2)
1051
+ if (ml .lt. 0 .or. ml .ge. n) go to 609
1052
+ if (mu .lt. 0 .or. mu .ge. n) go to 610
1053
+ 30 continue
1054
+ c next process and check the optional inputs. --------------------------
1055
+ if (iopt .eq. 1) go to 40
1056
+ ixpr = 0
1057
+ mxstep = mxstp0
1058
+ mxhnil = mxhnl0
1059
+ hmxi = 0.0d0
1060
+ hmin = 0.0d0
1061
+ if (istate .ne. 1) go to 60
1062
+ h0 = 0.0d0
1063
+ mxordn = mord(1)
1064
+ mxords = mord(2)
1065
+ go to 60
1066
+ 40 ixpr = iwork(5)
1067
+ if (ixpr .lt. 0 .or. ixpr .gt. 1) go to 611
1068
+ mxstep = iwork(6)
1069
+ if (mxstep .lt. 0) go to 612
1070
+ if (mxstep .eq. 0) mxstep = mxstp0
1071
+ mxhnil = iwork(7)
1072
+ if (mxhnil .lt. 0) go to 613
1073
+ if (mxhnil .eq. 0) mxhnil = mxhnl0
1074
+ if (istate .ne. 1) go to 50
1075
+ h0 = rwork(5)
1076
+ mxordn = iwork(8)
1077
+ if (mxordn .lt. 0) go to 628
1078
+ if (mxordn .eq. 0) mxordn = 100
1079
+ mxordn = min0(mxordn,mord(1))
1080
+ mxords = iwork(9)
1081
+ if (mxords .lt. 0) go to 629
1082
+ if (mxords .eq. 0) mxords = 100
1083
+ mxords = min0(mxords,mord(2))
1084
+ if ((tout - t)*h0 .lt. 0.0d0) go to 614
1085
+ 50 hmax = rwork(6)
1086
+ if (hmax .lt. 0.0d0) go to 615
1087
+ hmxi = 0.0d0
1088
+ if (hmax .gt. 0.0d0) hmxi = 1.0d0/hmax
1089
+ hmin = rwork(7)
1090
+ if (hmin .lt. 0.0d0) go to 616
1091
+ c-----------------------------------------------------------------------
1092
+ c set work array pointers and check lengths lrw and liw.
1093
+ c if istate = 1, meth is initialized to 1 here to facilitate the
1094
+ c checking of work space lengths.
1095
+ c pointers to segments of rwork and iwork are named by prefixing l to
1096
+ c the name of the segment. e.g., the segment yh starts at rwork(lyh).
1097
+ c segments of rwork (in order) are denoted yh, wm, ewt, savf, acor.
1098
+ c if the lengths provided are insufficient for the current method,
1099
+ c an error return occurs. this is treated as illegal input on the
1100
+ c first call, but as a problem interruption with istate = -7 on a
1101
+ c continuation call. if the lengths are sufficient for the current
1102
+ c method but not for both methods, a warning message is sent.
1103
+ c-----------------------------------------------------------------------
1104
+ 60 if (istate .eq. 1) meth = 1
1105
+ if (istate .eq. 1) nyh = n
1106
+ lyh = 21
1107
+ len1n = 20 + (mxordn + 1)*nyh
1108
+ len1s = 20 + (mxords + 1)*nyh
1109
+ lwm = len1s + 1
1110
+ if (jt .le. 2) lenwm = n*n + 2
1111
+ if (jt .ge. 4) lenwm = (2*ml + mu + 1)*n + 2
1112
+ len1s = len1s + lenwm
1113
+ len1c = len1n
1114
+ if (meth .eq. 2) len1c = len1s
1115
+ len1 = max0(len1n,len1s)
1116
+ len2 = 3*n
1117
+ lenrw = len1 + len2
1118
+ lenrwn = len1n + len2
1119
+ lenrws = len1s + len2
1120
+ lenrwc = len1c + len2
1121
+ iwork(17) = lenrw
1122
+ liwm = 1
1123
+ leniw = 20 + n
1124
+ leniwc = 20
1125
+ if (meth .eq. 2) leniwc = leniw
1126
+ iwork(18) = leniw
1127
+ if (istate .eq. 1 .and. lrw .lt. lenrwc) go to 617
1128
+ if (istate .eq. 1 .and. liw .lt. leniwc) go to 618
1129
+ if (istate .eq. 3 .and. lrw .lt. lenrwc) go to 550
1130
+ if (istate .eq. 3 .and. liw .lt. leniwc) go to 555
1131
+ lewt = len1 + 1
1132
+ insufr = 0
1133
+ if (lrw .ge. lenrw) go to 65
1134
+ insufr = 2
1135
+ lewt = len1c + 1
1136
+ call xerrwv(
1137
+ 1 'lsoda-- warning.. rwork length is sufficient for now, but ',
1138
+ 1 60, 103, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1139
+ call xerrwv(
1140
+ 1 ' may not be later. integration will proceed anyway. ',
1141
+ 1 60, 103, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1142
+ call xerrwv(
1143
+ 1 ' length needed is lenrw = i1, while lrw = i2.',
1144
+ 1 50, 103, 0, 2, lenrw, lrw, 0, 0.0d0, 0.0d0)
1145
+ 65 lsavf = lewt + n
1146
+ lacor = lsavf + n
1147
+ insufi = 0
1148
+ if (liw .ge. leniw) go to 70
1149
+ insufi = 2
1150
+ call xerrwv(
1151
+ 1 'lsoda-- warning.. iwork length is sufficient for now, but ',
1152
+ 1 60, 104, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1153
+ call xerrwv(
1154
+ 1 ' may not be later. integration will proceed anyway. ',
1155
+ 1 60, 104, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1156
+ call xerrwv(
1157
+ 1 ' length needed is leniw = i1, while liw = i2.',
1158
+ 1 50, 104, 0, 2, leniw, liw, 0, 0.0d0, 0.0d0)
1159
+ 70 continue
1160
+ c check rtol and atol for legality. ------------------------------------
1161
+ rtoli = rtol(1)
1162
+ atoli = atol(1)
1163
+ do 75 i = 1,n
1164
+ if (itol .ge. 3) rtoli = rtol(i)
1165
+ if (itol .eq. 2 .or. itol .eq. 4) atoli = atol(i)
1166
+ if (rtoli .lt. 0.0d0) go to 619
1167
+ if (atoli .lt. 0.0d0) go to 620
1168
+ 75 continue
1169
+ if (istate .eq. 1) go to 100
1170
+ c if istate = 3, set flag to signal parameter changes to stoda. --------
1171
+ jstart = -1
1172
+ if (n .eq. nyh) go to 200
1173
+ c neq was reduced. zero part of yh to avoid undefined references. -----
1174
+ i1 = lyh + l*nyh
1175
+ i2 = lyh + (maxord + 1)*nyh - 1
1176
+ if (i1 .gt. i2) go to 200
1177
+ do 95 i = i1,i2
1178
+ 95 rwork(i) = 0.0d0
1179
+ go to 200
1180
+ c-----------------------------------------------------------------------
1181
+ c block c.
1182
+ c the next block is for the initial call only (istate = 1).
1183
+ c it contains all remaining initializations, the initial call to f,
1184
+ c and the calculation of the initial step size.
1185
+ c the error weights in ewt are inverted after being loaded.
1186
+ c-----------------------------------------------------------------------
1187
+ 100 uround = d1mach(4)
1188
+ tn = t
1189
+ tsw = t
1190
+ maxord = mxordn
1191
+ if (itask .ne. 4 .and. itask .ne. 5) go to 110
1192
+ tcrit = rwork(1)
1193
+ if ((tcrit - tout)*(tout - t) .lt. 0.0d0) go to 625
1194
+ if (h0 .ne. 0.0d0 .and. (t + h0 - tcrit)*h0 .gt. 0.0d0)
1195
+ 1 h0 = tcrit - t
1196
+ 110 jstart = 0
1197
+ nhnil = 0
1198
+ nst = 0
1199
+ nje = 0
1200
+ nslast = 0
1201
+ hu = 0.0d0
1202
+ nqu = 0
1203
+ mused = 0
1204
+ miter = 0
1205
+ ccmax = 0.3d0
1206
+ maxcor = 3
1207
+ msbp = 20
1208
+ mxncf = 10
1209
+ c initial call to f. (lf0 points to yh(*,2).) -------------------------
1210
+ lf0 = lyh + nyh
1211
+ call srcma(rsav, isav, 1)
1212
+ call f (neq, t, y, rwork(lf0))
1213
+ call srcma(rsav, isav, 2)
1214
+ nfe = 1
1215
+ c load the initial value vector in yh. ---------------------------------
1216
+ do 115 i = 1,n
1217
+ 115 rwork(i+lyh-1) = y(i)
1218
+ c load and invert the ewt array. (h is temporarily set to 1.0.) -------
1219
+ nq = 1
1220
+ h = 1.0d0
1221
+ call ewset (n, itol, rtol, atol, rwork(lyh), rwork(lewt))
1222
+ do 120 i = 1,n
1223
+ if (rwork(i+lewt-1) .le. 0.0d0) go to 621
1224
+ 120 rwork(i+lewt-1) = 1.0d0/rwork(i+lewt-1)
1225
+ c-----------------------------------------------------------------------
1226
+ c the coding below computes the step size, h0, to be attempted on the
1227
+ c first step, unless the user has supplied a value for this.
1228
+ c first check that tout - t differs significantly from zero.
1229
+ c a scalar tolerance quantity tol is computed, as max(rtol(i))
1230
+ c if this is positive, or max(atol(i)/abs(y(i))) otherwise, adjusted
1231
+ c so as to be between 100*uround and 1.0e-3.
1232
+ c then the computed value h0 is given by..
1233
+ c
1234
+ c h0**(-2) = 1./(tol * w0**2) + tol * (norm(f))**2
1235
+ c
1236
+ c where w0 = max ( abs(t), abs(tout) ),
1237
+ c f = the initial value of the vector f(t,y), and
1238
+ c norm() = the weighted vector norm used throughout, given by
1239
+ c the vmnorm function routine, and weighted by the
1240
+ c tolerances initially loaded into the ewt array.
1241
+ c the sign of h0 is inferred from the initial values of tout and t.
1242
+ c abs(h0) is made .le. abs(tout-t) in any case.
1243
+ c-----------------------------------------------------------------------
1244
+ if (h0 .ne. 0.0d0) go to 180
1245
+ tdist = dabs(tout - t)
1246
+ w0 = dmax1(dabs(t),dabs(tout))
1247
+ if (tdist .lt. 2.0d0*uround*w0) go to 622
1248
+ tol = rtol(1)
1249
+ if (itol .le. 2) go to 140
1250
+ do 130 i = 1,n
1251
+ 130 tol = dmax1(tol,rtol(i))
1252
+ 140 if (tol .gt. 0.0d0) go to 160
1253
+ atoli = atol(1)
1254
+ do 150 i = 1,n
1255
+ if (itol .eq. 2 .or. itol .eq. 4) atoli = atol(i)
1256
+ ayi = dabs(y(i))
1257
+ if (ayi .ne. 0.0d0) tol = dmax1(tol,atoli/ayi)
1258
+ 150 continue
1259
+ 160 tol = dmax1(tol,100.0d0*uround)
1260
+ tol = dmin1(tol,0.001d0)
1261
+ sum = vmnorm (n, rwork(lf0), rwork(lewt))
1262
+ sum = 1.0d0/(tol*w0*w0) + tol*sum**2
1263
+ h0 = 1.0d0/dsqrt(sum)
1264
+ h0 = dmin1(h0,tdist)
1265
+ h0 = dsign(h0,tout-t)
1266
+ c adjust h0 if necessary to meet hmax bound. ---------------------------
1267
+ 180 rh = dabs(h0)*hmxi
1268
+ if (rh .gt. 1.0d0) h0 = h0/rh
1269
+ c load h with h0 and scale yh(*,2) by h0. ------------------------------
1270
+ h = h0
1271
+ do 190 i = 1,n
1272
+ 190 rwork(i+lf0-1) = h0*rwork(i+lf0-1)
1273
+ go to 270
1274
+ c-----------------------------------------------------------------------
1275
+ c block d.
1276
+ c the next code block is for continuation calls only (istate = 2 or 3)
1277
+ c and is to check stop conditions before taking a step.
1278
+ c-----------------------------------------------------------------------
1279
+ 200 nslast = nst
1280
+ go to (210, 250, 220, 230, 240), itask
1281
+ 210 if ((tn - tout)*h .lt. 0.0d0) go to 250
1282
+ call intdy (tout, 0, rwork(lyh), nyh, y, iflag)
1283
+ if (iflag .ne. 0) go to 627
1284
+ t = tout
1285
+ go to 420
1286
+ 220 tp = tn - hu*(1.0d0 + 100.0d0*uround)
1287
+ if ((tp - tout)*h .gt. 0.0d0) go to 623
1288
+ if ((tn - tout)*h .lt. 0.0d0) go to 250
1289
+ t = tn
1290
+ go to 400
1291
+ 230 tcrit = rwork(1)
1292
+ if ((tn - tcrit)*h .gt. 0.0d0) go to 624
1293
+ if ((tcrit - tout)*h .lt. 0.0d0) go to 625
1294
+ if ((tn - tout)*h .lt. 0.0d0) go to 245
1295
+ call intdy (tout, 0, rwork(lyh), nyh, y, iflag)
1296
+ if (iflag .ne. 0) go to 627
1297
+ t = tout
1298
+ go to 420
1299
+ 240 tcrit = rwork(1)
1300
+ if ((tn - tcrit)*h .gt. 0.0d0) go to 624
1301
+ 245 hmx = dabs(tn) + dabs(h)
1302
+ ihit = dabs(tn - tcrit) .le. 100.0d0*uround*hmx
1303
+ if (ihit) t = tcrit
1304
+ if (ihit) go to 400
1305
+ tnext = tn + h*(1.0d0 + 4.0d0*uround)
1306
+ if ((tnext - tcrit)*h .le. 0.0d0) go to 250
1307
+ h = (tcrit - tn)*(1.0d0 - 4.0d0*uround)
1308
+ if (istate .eq. 2 .and. jstart .ge. 0) jstart = -2
1309
+ c-----------------------------------------------------------------------
1310
+ c block e.
1311
+ c the next block is normally executed for all calls and contains
1312
+ c the call to the one-step core integrator stoda.
1313
+ c
1314
+ c this is a looping point for the integration steps.
1315
+ c
1316
+ c first check for too many steps being taken, update ewt (if not at
1317
+ c start of problem), check for too much accuracy being requested, and
1318
+ c check for h below the roundoff level in t.
1319
+ c-----------------------------------------------------------------------
1320
+ 250 continue
1321
+ if (meth .eq. mused) go to 255
1322
+ if (insufr .eq. 1) go to 550
1323
+ if (insufi .eq. 1) go to 555
1324
+ 255 if ((nst-nslast) .ge. mxstep) go to 500
1325
+ call ewset (n, itol, rtol, atol, rwork(lyh), rwork(lewt))
1326
+ do 260 i = 1,n
1327
+ if (rwork(i+lewt-1) .le. 0.0d0) go to 510
1328
+ 260 rwork(i+lewt-1) = 1.0d0/rwork(i+lewt-1)
1329
+ 270 tolsf = uround*vmnorm (n, rwork(lyh), rwork(lewt))
1330
+ if (tolsf .le. 0.01d0) go to 280
1331
+ tolsf = tolsf*200.0d0
1332
+ if (nst .eq. 0) go to 626
1333
+ go to 520
1334
+ 280 if ((tn + h) .ne. tn) go to 290
1335
+ nhnil = nhnil + 1
1336
+ if (nhnil .gt. mxhnil) go to 290
1337
+ call xerrwv('lsoda-- warning..internal t (=r1) and h (=r2) are',
1338
+ 1 50, 101, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1339
+ call xerrwv(
1340
+ 1 ' such that in the machine, t + h = t on the next step ',
1341
+ 1 60, 101, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1342
+ call xerrwv(' (h = step size). solver will continue anyway',
1343
+ 1 50, 101, 0, 0, 0, 0, 2, tn, h)
1344
+ if (nhnil .lt. mxhnil) go to 290
1345
+ call xerrwv('lsoda-- above warning has been issued i1 times. ',
1346
+ 1 50, 102, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1347
+ call xerrwv(' it will not be issued again for this problem',
1348
+ 1 50, 102, 0, 1, mxhnil, 0, 0, 0.0d0, 0.0d0)
1349
+ 290 continue
1350
+ c-----------------------------------------------------------------------
1351
+ c call stoda(neq,y,yh,nyh,yh,ewt,savf,acor,wm,iwm,f,jac,prja,solsy)
1352
+ c-----------------------------------------------------------------------
1353
+ call stoda (neq, y, rwork(lyh), nyh, rwork(lyh), rwork(lewt),
1354
+ 1 rwork(lsavf), rwork(lacor), rwork(lwm), iwork(liwm),
1355
+ 2 f, jac, prja, solsy)
1356
+ kgo = 1 - kflag
1357
+ go to (300, 530, 540), kgo
1358
+ c-----------------------------------------------------------------------
1359
+ c block f.
1360
+ c the following block handles the case of a successful return from the
1361
+ c core integrator (kflag = 0).
1362
+ c if a method switch was just made, record tsw, reset maxord,
1363
+ c set jstart to -1 to signal stoda to complete the switch,
1364
+ c and do extra printing of data if ixpr = 1.
1365
+ c then, in any case, check for stop conditions.
1366
+ c-----------------------------------------------------------------------
1367
+ 300 init = 1
1368
+ if (meth .eq. mused) go to 310
1369
+ tsw = tn
1370
+ maxord = mxordn
1371
+ if (meth .eq. 2) maxord = mxords
1372
+ if (meth .eq. 2) rwork(lwm) = dsqrt(uround)
1373
+ insufr = min0(insufr,1)
1374
+ insufi = min0(insufi,1)
1375
+ jstart = -1
1376
+ if (ixpr .eq. 0) go to 310
1377
+ if (meth .eq. 2) call xerrwv(
1378
+ 1 'lsoda-- a switch to the bdf (stiff) method has occurred ',
1379
+ 1 60, 105, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1380
+ if (meth .eq. 1) call xerrwv(
1381
+ 1 'lsoda-- a switch to the adams (nonstiff) method has occurred',
1382
+ 1 60, 106, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1383
+ call xerrwv(
1384
+ 1 ' at t = r1, tentative step size h = r2, step nst = i1 ',
1385
+ 1 60, 107, 0, 1, nst, 0, 2, tn, h)
1386
+ 310 go to (320, 400, 330, 340, 350), itask
1387
+ c itask = 1. if tout has been reached, interpolate. -------------------
1388
+ 320 if ((tn - tout)*h .lt. 0.0d0) go to 250
1389
+ call intdy (tout, 0, rwork(lyh), nyh, y, iflag)
1390
+ t = tout
1391
+ go to 420
1392
+ c itask = 3. jump to exit if tout was reached. ------------------------
1393
+ 330 if ((tn - tout)*h .ge. 0.0d0) go to 400
1394
+ go to 250
1395
+ c itask = 4. see if tout or tcrit was reached. adjust h if necessary.
1396
+ 340 if ((tn - tout)*h .lt. 0.0d0) go to 345
1397
+ call intdy (tout, 0, rwork(lyh), nyh, y, iflag)
1398
+ t = tout
1399
+ go to 420
1400
+ 345 hmx = dabs(tn) + dabs(h)
1401
+ ihit = dabs(tn - tcrit) .le. 100.0d0*uround*hmx
1402
+ if (ihit) go to 400
1403
+ tnext = tn + h*(1.0d0 + 4.0d0*uround)
1404
+ if ((tnext - tcrit)*h .le. 0.0d0) go to 250
1405
+ h = (tcrit - tn)*(1.0d0 - 4.0d0*uround)
1406
+ if (jstart .ge. 0) jstart = -2
1407
+ go to 250
1408
+ c itask = 5. see if tcrit was reached and jump to exit. ---------------
1409
+ 350 hmx = dabs(tn) + dabs(h)
1410
+ ihit = dabs(tn - tcrit) .le. 100.0d0*uround*hmx
1411
+ c-----------------------------------------------------------------------
1412
+ c block g.
1413
+ c the following block handles all successful returns from lsoda.
1414
+ c if itask .ne. 1, y is loaded from yh and t is set accordingly.
1415
+ c istate is set to 2, the illegal input counter is zeroed, and the
1416
+ c optional outputs are loaded into the work arrays before returning.
1417
+ c if istate = 1 and tout = t, there is a return with no action taken,
1418
+ c except that if this has happened repeatedly, the run is terminated.
1419
+ c-----------------------------------------------------------------------
1420
+ 400 do 410 i = 1,n
1421
+ 410 y(i) = rwork(i+lyh-1)
1422
+ t = tn
1423
+ if (itask .ne. 4 .and. itask .ne. 5) go to 420
1424
+ if (ihit) t = tcrit
1425
+ 420 istate = 2
1426
+ illin = 0
1427
+ rwork(11) = hu
1428
+ rwork(12) = h
1429
+ rwork(13) = tn
1430
+ rwork(15) = tsw
1431
+ iwork(11) = nst
1432
+ iwork(12) = nfe
1433
+ iwork(13) = nje
1434
+ iwork(14) = nqu
1435
+ iwork(15) = nq
1436
+ iwork(19) = mused
1437
+ iwork(20) = meth
1438
+ return
1439
+ c
1440
+ 430 ntrep = ntrep + 1
1441
+ if (ntrep .lt. 5) return
1442
+ call xerrwv(
1443
+ 1 'lsoda-- repeated calls with istate = 1 and tout = t (=r1) ',
1444
+ 1 60, 301, 0, 0, 0, 0, 1, t, 0.0d0)
1445
+ go to 800
1446
+ c-----------------------------------------------------------------------
1447
+ c block h.
1448
+ c the following block handles all unsuccessful returns other than
1449
+ c those for illegal input. first the error message routine is called.
1450
+ c if there was an error test or convergence test failure, imxer is set.
1451
+ c then y is loaded from yh, t is set to tn, and the illegal input
1452
+ c counter illin is set to 0. the optional outputs are loaded into
1453
+ c the work arrays before returning.
1454
+ c-----------------------------------------------------------------------
1455
+ c the maximum number of steps was taken before reaching tout. ----------
1456
+ 500 call xerrwv('lsoda-- at current t (=r1), mxstep (=i1) steps ',
1457
+ 1 50, 201, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1458
+ call xerrwv(' taken on this call before reaching tout ',
1459
+ 1 50, 201, 0, 1, mxstep, 0, 1, tn, 0.0d0)
1460
+ istate = -1
1461
+ go to 580
1462
+ c ewt(i) .le. 0.0 for some i (not at start of problem). ----------------
1463
+ 510 ewti = rwork(lewt+i-1)
1464
+ call xerrwv('lsoda-- at t (=r1), ewt(i1) has become r2 .le. 0.',
1465
+ 1 50, 202, 0, 1, i, 0, 2, tn, ewti)
1466
+ istate = -6
1467
+ go to 580
1468
+ c too much accuracy requested for machine precision. -------------------
1469
+ 520 call xerrwv('lsoda-- at t (=r1), too much accuracy requested ',
1470
+ 1 50, 203, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1471
+ call xerrwv(' for precision of machine.. see tolsf (=r2) ',
1472
+ 1 50, 203, 0, 0, 0, 0, 2, tn, tolsf)
1473
+ rwork(14) = tolsf
1474
+ istate = -2
1475
+ go to 580
1476
+ c kflag = -1. error test failed repeatedly or with abs(h) = hmin. -----
1477
+ 530 call xerrwv('lsoda-- at t(=r1) and step size h(=r2), the error',
1478
+ 1 50, 204, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1479
+ call xerrwv(' test failed repeatedly or with abs(h) = hmin',
1480
+ 1 50, 204, 0, 0, 0, 0, 2, tn, h)
1481
+ istate = -4
1482
+ go to 560
1483
+ c kflag = -2. convergence failed repeatedly or with abs(h) = hmin. ----
1484
+ 540 call xerrwv('lsoda-- at t (=r1) and step size h (=r2), the ',
1485
+ 1 50, 205, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1486
+ call xerrwv(' corrector convergence failed repeatedly ',
1487
+ 1 50, 205, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1488
+ call xerrwv(' or with abs(h) = hmin ',
1489
+ 1 30, 205, 0, 0, 0, 0, 2, tn, h)
1490
+ istate = -5
1491
+ go to 560
1492
+ c rwork length too small to proceed. -----------------------------------
1493
+ 550 call xerrwv('lsoda-- at current t(=r1), rwork length too small',
1494
+ 1 50, 206, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1495
+ call xerrwv(
1496
+ 1 ' to proceed. the integration was otherwise successful.',
1497
+ 1 60, 206, 0, 0, 0, 0, 1, tn, 0.0d0)
1498
+ istate = -7
1499
+ go to 580
1500
+ c iwork length too small to proceed. -----------------------------------
1501
+ 555 call xerrwv('lsoda-- at current t(=r1), iwork length too small',
1502
+ 1 50, 207, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1503
+ call xerrwv(
1504
+ 1 ' to proceed. the integration was otherwise successful.',
1505
+ 1 60, 207, 0, 0, 0, 0, 1, tn, 0.0d0)
1506
+ istate = -7
1507
+ go to 580
1508
+ c compute imxer if relevant. -------------------------------------------
1509
+ 560 big = 0.0d0
1510
+ imxer = 1
1511
+ do 570 i = 1,n
1512
+ size = dabs(rwork(i+lacor-1)*rwork(i+lewt-1))
1513
+ if (big .ge. size) go to 570
1514
+ big = size
1515
+ imxer = i
1516
+ 570 continue
1517
+ iwork(16) = imxer
1518
+ c set y vector, t, illin, and optional outputs. ------------------------
1519
+ 580 do 590 i = 1,n
1520
+ 590 y(i) = rwork(i+lyh-1)
1521
+ t = tn
1522
+ illin = 0
1523
+ rwork(11) = hu
1524
+ rwork(12) = h
1525
+ rwork(13) = tn
1526
+ rwork(15) = tsw
1527
+ iwork(11) = nst
1528
+ iwork(12) = nfe
1529
+ iwork(13) = nje
1530
+ iwork(14) = nqu
1531
+ iwork(15) = nq
1532
+ iwork(19) = mused
1533
+ iwork(20) = meth
1534
+ return
1535
+ c-----------------------------------------------------------------------
1536
+ c block i.
1537
+ c the following block handles all error returns due to illegal input
1538
+ c (istate = -3), as detected before calling the core integrator.
1539
+ c first the error message routine is called. then if there have been
1540
+ c 5 consecutive such returns just before this call to the solver,
1541
+ c the run is halted.
1542
+ c-----------------------------------------------------------------------
1543
+ 601 call xerrwv('lsoda-- istate (=i1) illegal ',
1544
+ 1 30, 1, 0, 1, istate, 0, 0, 0.0d0, 0.0d0)
1545
+ go to 700
1546
+ 602 call xerrwv('lsoda-- itask (=i1) illegal ',
1547
+ 1 30, 2, 0, 1, itask, 0, 0, 0.0d0, 0.0d0)
1548
+ go to 700
1549
+ 603 call xerrwv('lsoda-- istate .gt. 1 but lsoda not initialized ',
1550
+ 1 50, 3, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1551
+ go to 700
1552
+ 604 call xerrwv('lsoda-- neq (=i1) .lt. 1 ',
1553
+ 1 30, 4, 0, 1, neq(1), 0, 0, 0.0d0, 0.0d0)
1554
+ go to 700
1555
+ 605 call xerrwv('lsoda-- istate = 3 and neq increased (i1 to i2) ',
1556
+ 1 50, 5, 0, 2, n, neq(1), 0, 0.0d0, 0.0d0)
1557
+ go to 700
1558
+ 606 call xerrwv('lsoda-- itol (=i1) illegal ',
1559
+ 1 30, 6, 0, 1, itol, 0, 0, 0.0d0, 0.0d0)
1560
+ go to 700
1561
+ 607 call xerrwv('lsoda-- iopt (=i1) illegal ',
1562
+ 1 30, 7, 0, 1, iopt, 0, 0, 0.0d0, 0.0d0)
1563
+ go to 700
1564
+ 608 call xerrwv('lsoda-- jt (=i1) illegal ',
1565
+ 1 30, 8, 0, 1, jt, 0, 0, 0.0d0, 0.0d0)
1566
+ go to 700
1567
+ 609 call xerrwv('lsoda-- ml (=i1) illegal.. .lt.0 or .ge.neq (=i2)',
1568
+ 1 50, 9, 0, 2, ml, neq(1), 0, 0.0d0, 0.0d0)
1569
+ go to 700
1570
+ 610 call xerrwv('lsoda-- mu (=i1) illegal.. .lt.0 or .ge.neq (=i2)',
1571
+ 1 50, 10, 0, 2, mu, neq(1), 0, 0.0d0, 0.0d0)
1572
+ go to 700
1573
+ 611 call xerrwv('lsoda-- ixpr (=i1) illegal ',
1574
+ 1 30, 11, 0, 1, ixpr, 0, 0, 0.0d0, 0.0d0)
1575
+ go to 700
1576
+ 612 call xerrwv('lsoda-- mxstep (=i1) .lt. 0 ',
1577
+ 1 30, 12, 0, 1, mxstep, 0, 0, 0.0d0, 0.0d0)
1578
+ go to 700
1579
+ 613 call xerrwv('lsoda-- mxhnil (=i1) .lt. 0 ',
1580
+ 1 30, 13, 0, 1, mxhnil, 0, 0, 0.0d0, 0.0d0)
1581
+ go to 700
1582
+ 614 call xerrwv('lsoda-- tout (=r1) behind t (=r2) ',
1583
+ 1 40, 14, 0, 0, 0, 0, 2, tout, t)
1584
+ call xerrwv(' integration direction is given by h0 (=r1) ',
1585
+ 1 50, 14, 0, 0, 0, 0, 1, h0, 0.0d0)
1586
+ go to 700
1587
+ 615 call xerrwv('lsoda-- hmax (=r1) .lt. 0.0 ',
1588
+ 1 30, 15, 0, 0, 0, 0, 1, hmax, 0.0d0)
1589
+ go to 700
1590
+ 616 call xerrwv('lsoda-- hmin (=r1) .lt. 0.0 ',
1591
+ 1 30, 16, 0, 0, 0, 0, 1, hmin, 0.0d0)
1592
+ go to 700
1593
+ 617 call xerrwv(
1594
+ 1 'lsoda-- rwork length needed, lenrw (=i1), exceeds lrw (=i2)',
1595
+ 1 60, 17, 0, 2, lenrw, lrw, 0, 0.0d0, 0.0d0)
1596
+ go to 700
1597
+ 618 call xerrwv(
1598
+ 1 'lsoda-- iwork length needed, leniw (=i1), exceeds liw (=i2)',
1599
+ 1 60, 18, 0, 2, leniw, liw, 0, 0.0d0, 0.0d0)
1600
+ go to 700
1601
+ 619 call xerrwv('lsoda-- rtol(i1) is r1 .lt. 0.0 ',
1602
+ 1 40, 19, 0, 1, i, 0, 1, rtoli, 0.0d0)
1603
+ go to 700
1604
+ 620 call xerrwv('lsoda-- atol(i1) is r1 .lt. 0.0 ',
1605
+ 1 40, 20, 0, 1, i, 0, 1, atoli, 0.0d0)
1606
+ go to 700
1607
+ 621 ewti = rwork(lewt+i-1)
1608
+ call xerrwv('lsoda-- ewt(i1) is r1 .le. 0.0 ',
1609
+ 1 40, 21, 0, 1, i, 0, 1, ewti, 0.0d0)
1610
+ go to 700
1611
+ 622 call xerrwv(
1612
+ 1 'lsoda-- tout (=r1) too close to t(=r2) to start integration',
1613
+ 1 60, 22, 0, 0, 0, 0, 2, tout, t)
1614
+ go to 700
1615
+ 623 call xerrwv(
1616
+ 1 'lsoda-- itask = i1 and tout (=r1) behind tcur - hu (= r2) ',
1617
+ 1 60, 23, 0, 1, itask, 0, 2, tout, tp)
1618
+ go to 700
1619
+ 624 call xerrwv(
1620
+ 1 'lsoda-- itask = 4 or 5 and tcrit (=r1) behind tcur (=r2) ',
1621
+ 1 60, 24, 0, 0, 0, 0, 2, tcrit, tn)
1622
+ go to 700
1623
+ 625 call xerrwv(
1624
+ 1 'lsoda-- itask = 4 or 5 and tcrit (=r1) behind tout (=r2) ',
1625
+ 1 60, 25, 0, 0, 0, 0, 2, tcrit, tout)
1626
+ go to 700
1627
+ 626 call xerrwv('lsoda-- at start of problem, too much accuracy ',
1628
+ 1 50, 26, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1629
+ call xerrwv(
1630
+ 1 ' requested for precision of machine.. see tolsf (=r1) ',
1631
+ 1 60, 26, 0, 0, 0, 0, 1, tolsf, 0.0d0)
1632
+ rwork(14) = tolsf
1633
+ go to 700
1634
+ 627 call xerrwv('lsoda-- trouble from intdy. itask = i1, tout = r1',
1635
+ 1 50, 27, 0, 1, itask, 0, 1, tout, 0.0d0)
1636
+ go to 700
1637
+ 628 call xerrwv('lsoda-- mxordn (=i1) .lt. 0 ',
1638
+ 1 30, 28, 0, 1, mxordn, 0, 0, 0.0d0, 0.0d0)
1639
+ go to 700
1640
+ 629 call xerrwv('lsoda-- mxords (=i1) .lt. 0 ',
1641
+ 1 30, 29, 0, 1, mxords, 0, 0, 0.0d0, 0.0d0)
1642
+ c
1643
+ 700 if (illin .eq. 5) go to 710
1644
+ illin = illin + 1
1645
+ istate = -3
1646
+ return
1647
+ 710 call xerrwv('lsoda-- repeated occurrences of illegal input ',
1648
+ 1 50, 302, 0, 0, 0, 0, 0, 0.0d0, 0.0d0)
1649
+ c
1650
+ 800 call xerrwv('lsoda-- run aborted.. apparent infinite loop ',
1651
+ 1 50, 303, 2, 0, 0, 0, 0, 0.0d0, 0.0d0)
1652
+ return
1653
+ c----------------------- end of subroutine lsoda -----------------------
1654
+ end