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,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
|