1 |
jscott |
1.1 |
|
2 |
|
|
c===============================================================c |
3 |
|
|
c LSODESRC: Collection of subroutines or functions c |
4 |
|
|
c used in Chien Wang's photochemistry c |
5 |
|
|
c model from ODEPACK c |
6 |
|
|
c ------------------------------------------------ c |
7 |
|
|
c Chien Wang c |
8 |
|
|
c MIT, Rm.E40-269, Cambridge, MA 02139 c |
9 |
|
|
c c |
10 |
|
|
c December 5, 1995 c |
11 |
|
|
c ------------------------------------------------ c |
12 |
|
|
c Table of Contents c |
13 |
|
|
c c |
14 |
|
|
c lsodenew: subroutine -- TC1 c |
15 |
|
|
c stodenew: subroutine -- TC2 c |
16 |
|
|
c ewset: subroutine -- TC3 c |
17 |
|
|
c solsy: subroutine -- TC4 c |
18 |
|
|
c intdy: subroutine -- TC5 c |
19 |
|
|
c cfode: subroutine -- TC6 c |
20 |
|
|
c sgefa: subroutine -- TC7 c |
21 |
|
|
c sgbfa: subroutine -- TC8 c |
22 |
|
|
c sgesl: subroutine -- TC9 c |
23 |
|
|
c sgbsl: subroutine -- TC10 c |
24 |
|
|
c sscal: subroutine -- TC11 c |
25 |
|
|
c saxpysmp: subroutine -- TC12 c |
26 |
|
|
c xerrwv: subroutine -- TC13 c |
27 |
|
|
c r1mach: function -- TC14 c |
28 |
|
|
c vnorm: function -- TC15 c |
29 |
|
|
c isamax: function -- TC16 c |
30 |
|
|
c sdot: function -- TC17 c |
31 |
|
|
c prepj64: subroutine -- TC18 c |
32 |
|
|
c===============================================================c |
33 |
|
|
|
34 |
|
|
! ------------------------------------------------------------ |
35 |
|
|
! |
36 |
|
|
! Revision History: |
37 |
|
|
! |
38 |
|
|
! When Who What |
39 |
|
|
! ---- ---------- ------- |
40 |
|
|
! 092001 Chien Wang rev. of some old style code |
41 |
|
|
! |
42 |
|
|
! ========================================================== |
43 |
|
|
|
44 |
|
|
c=============================================================== |
45 |
|
|
c -- TC1 |
46 |
|
|
c |
47 |
|
|
subroutine lsodenew (f, neq, y, t, tout, itol, rtol, atol, itask, |
48 |
|
|
& istate, iopt, rwork, lrw, iwork, liw, jac, mf) |
49 |
|
|
c ========================================================== |
50 |
|
|
|
51 |
|
|
c===============================================================c |
52 |
|
|
c LSODENEW.F: A simplified version of original lsode.f c |
53 |
|
|
c for cases where c |
54 |
|
|
c ISTATE = 1 & c |
55 |
|
|
c ITASK = 1 initially c |
56 |
|
|
c IOPT = 0 c |
57 |
|
|
c ITOL = 1 c |
58 |
|
|
c ------------------------------------------------ c |
59 |
|
|
c c |
60 |
|
|
c Chien Wang c |
61 |
|
|
c MIT Joint Program for Science and Policy c |
62 |
|
|
c of Global Change c |
63 |
|
|
c c |
64 |
|
|
c March 20, 1995 c |
65 |
|
|
c===============================================================c |
66 |
|
|
|
67 |
|
|
external f, jac |
68 |
|
|
integer neq, itol, itask, istate, iopt, lrw, iwork, liw, mf |
69 |
|
|
real y, t, tout, rtol, atol, rwork |
70 |
|
|
dimension neq(*), y(*), rtol(*), atol(*), rwork(lrw), iwork(liw) |
71 |
|
|
|
72 |
|
|
c----------------------------------------------------------------------- |
73 |
|
|
c this is the march 30, 1987 version of |
74 |
|
|
c lsode.. livermore solver for ordinary differential equations. |
75 |
|
|
c this version is in single precision. |
76 |
|
|
c |
77 |
|
|
c lsode solves the initial value problem for stiff or nonstiff |
78 |
|
|
c systems of first order ode-s, |
79 |
|
|
c dy/dt = f(t,y) , or, in component form, |
80 |
|
|
c dy(i)/dt = f(i) = f(i,t,y(1),y(2),...,y(neq)) (i = 1,...,neq). |
81 |
|
|
c lsode is a package based on the gear and gearb packages, and on the |
82 |
|
|
c october 23, 1978 version of the tentative odepack user interface |
83 |
|
|
c standard, with minor modifications. |
84 |
|
|
c----------------------------------------------------------------------- |
85 |
|
|
c reference.. |
86 |
|
|
c alan c. hindmarsh, odepack, a systematized collection of ode |
87 |
|
|
c solvers, in scientific computing, r. s. stepleman et al. (eds.), |
88 |
|
|
c north-holland, amsterdam, 1983, pp. 55-64. |
89 |
|
|
c----------------------------------------------------------------------- |
90 |
|
|
c author and contact.. alan c. hindmarsh, |
91 |
|
|
c computing and mathematics research div., l-316 |
92 |
|
|
c lawrence livermore national laboratory |
93 |
|
|
c livermore, ca 94550. |
94 |
|
|
c----------------------------------------------------------------------- |
95 |
|
|
|
96 |
|
|
external prepj, solsy |
97 |
|
|
integer illin, init, lyh, lewt, lacor, lsavf, lwm, liwm, |
98 |
|
|
1 mxstep, mxhnil, nhnil, ntrep, nslast, nyh, iowns |
99 |
|
|
integer icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
100 |
|
|
1 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
101 |
|
|
integer i, i1, i2, iflag, imxer, kgo, lf0, |
102 |
|
|
1 leniw, lenrw, lenwm, ml, mord, mu, mxhnl0, mxstp0 |
103 |
|
|
real rowns, |
104 |
|
|
1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround |
105 |
|
|
real atoli, ayi, big, ewti, h0, hmax, hmx, rh, rtoli, |
106 |
|
|
1 tcrit, tdist, tnext, tol, tolsf, tp, size, sum, w0, |
107 |
|
|
2 r1mach, vnorm |
108 |
|
|
dimension mord(2) |
109 |
|
|
logical ihit |
110 |
|
|
c----------------------------------------------------------------------- |
111 |
|
|
c the following internal common block contains |
112 |
|
|
c (a) variables which are local to any subroutine but whose values must |
113 |
|
|
c be preserved between calls to the routine (own variables), and |
114 |
|
|
c (b) variables which are communicated between subroutines. |
115 |
|
|
c the structure of the block is as follows.. all real variables are |
116 |
|
|
c listed first, followed by all integers. within each type, the |
117 |
|
|
c variables are grouped with those local to subroutine lsode first, |
118 |
|
|
c then those local to subroutine stode, and finally those used |
119 |
|
|
c for communication. the block is declared in subroutines |
120 |
|
|
c lsode, intdy, stode, prepj, and solsy. groups of variables are |
121 |
|
|
c replaced by dummy arrays in the common declarations in routines |
122 |
|
|
c where those variables are not used. |
123 |
|
|
c----------------------------------------------------------------------- |
124 |
|
|
common /ls0001/ rowns(209), |
125 |
|
|
1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround, |
126 |
|
|
2 illin, init, lyh, lewt, lacor, lsavf, lwm, liwm, |
127 |
|
|
3 mxstep, mxhnil, nhnil, ntrep, nslast, nyh, iowns(6), |
128 |
|
|
4 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
129 |
|
|
5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
130 |
|
|
c |
131 |
|
|
c data mord(1),mord(2)/12,5/, mxstp0/500/, mxhnl0/10/ |
132 |
|
|
data mord(1),mord(2)/12,5/, mxstp0/260/, mxhnl0/10/ |
133 |
|
|
data illin/0/, ntrep/0/ |
134 |
|
|
c----------------------------------------------------------------------- |
135 |
|
|
c block a. |
136 |
|
|
c this code block is executed on every call. |
137 |
|
|
c it tests istate and itask for legality and branches appropriately. |
138 |
|
|
c if istate .gt. 1 but the flag init shows that initialization has |
139 |
|
|
c not yet been done, an error return occurs. |
140 |
|
|
c if istate = 1 and tout = t, jump to block g and return immediately. |
141 |
|
|
c----------------------------------------------------------------------- |
142 |
|
|
|
143 |
|
|
init = 0 |
144 |
|
|
ntrep = 0 |
145 |
|
|
c----------------------------------------------------------------------- |
146 |
|
|
c block b. |
147 |
|
|
c the next code block is executed for the initial call (istate = 1), |
148 |
|
|
c or for a continuation call with parameter changes (istate = 3). |
149 |
|
|
c it contains checking of all inputs and various initializations. |
150 |
|
|
c |
151 |
|
|
c first check legality of the non-optional inputs neq, itol, iopt, |
152 |
|
|
c mf, ml, and mu. |
153 |
|
|
c----------------------------------------------------------------------- |
154 |
|
|
|
155 |
|
|
n = neq(1) |
156 |
|
|
meth = mf/10 |
157 |
|
|
miter = mf - 10*meth |
158 |
|
|
if (miter .gt. 3)then |
159 |
|
|
ml = iwork(1) |
160 |
|
|
mu = iwork(2) |
161 |
|
|
endif |
162 |
|
|
|
163 |
|
|
c next process and check the optional inputs. -------------------------- |
164 |
|
|
maxord = mord(meth) |
165 |
|
|
mxstep = mxstp0 |
166 |
|
|
mxhnil = mxhnl0 |
167 |
|
|
h0 = 0.0e0 |
168 |
|
|
hmxi = 0.0e0 |
169 |
|
|
hmin = 0.0e0 |
170 |
|
|
|
171 |
|
|
c----------------------------------------------------------------------- |
172 |
|
|
c set work array pointers and check lengths lrw and liw. |
173 |
|
|
c pointers to segments of rwork and iwork are named by prefixing l to |
174 |
|
|
c the name of the segment. e.g., the segment yh starts at rwork(lyh). |
175 |
|
|
c segments of rwork (in order) are denoted yh, wm, ewt, savf, acor. |
176 |
|
|
c----------------------------------------------------------------------- |
177 |
|
|
|
178 |
|
|
lyh = 21 |
179 |
|
|
if (istate .eq. 1) nyh = n |
180 |
|
|
lwm = lyh + (maxord + 1)*nyh |
181 |
|
|
if (miter .eq. 0) lenwm = 0 |
182 |
|
|
if (miter .eq. 1 .or. miter .eq. 2) lenwm = n*n + 2 |
183 |
|
|
if (miter .eq. 3) lenwm = n + 2 |
184 |
|
|
if (miter .ge. 4) lenwm = (2*ml + mu + 1)*n + 2 |
185 |
|
|
lewt = lwm + lenwm |
186 |
|
|
lsavf = lewt + n |
187 |
|
|
lacor = lsavf + n |
188 |
|
|
lenrw = lacor + n - 1 |
189 |
|
|
iwork(17) = lenrw |
190 |
|
|
liwm = 1 |
191 |
|
|
leniw = 20 + n |
192 |
|
|
if (miter .eq. 0 .or. miter .eq. 3) leniw = 20 |
193 |
|
|
iwork(18) = leniw |
194 |
|
|
|
195 |
|
|
c check rtol and atol for legality. ------------------------------------ |
196 |
|
|
rtoli = rtol(1) |
197 |
|
|
atoli = atol(1) |
198 |
|
|
|
199 |
|
|
c if(itol.eq.2)then |
200 |
|
|
c do 70 i = 1,n |
201 |
|
|
c atoli = atol(i) |
202 |
|
|
c70 continue |
203 |
|
|
c endif |
204 |
|
|
|
205 |
|
|
c----------------------------------------------------------------------- |
206 |
|
|
c block c. |
207 |
|
|
c the next block is for the initial call only (istate = 1). |
208 |
|
|
c it contains all remaining initializations, the initial call to f, |
209 |
|
|
c and the calculation of the initial step size. |
210 |
|
|
c the error weights in ewt are inverted after being loaded. |
211 |
|
|
c----------------------------------------------------------------------- |
212 |
|
|
|
213 |
|
|
uround = r1mach(4) |
214 |
|
|
tn = t |
215 |
|
|
jstart = 0 |
216 |
|
|
if (miter .gt. 0) rwork(lwm) = sqrt(uround) |
217 |
|
|
nhnil = 0 |
218 |
|
|
nst = 0 |
219 |
|
|
nje = 0 |
220 |
|
|
nslast = 0 |
221 |
|
|
hu = 0.0 |
222 |
|
|
nqu = 0 |
223 |
|
|
ccmax = 0.3 |
224 |
|
|
maxcor = 3 |
225 |
|
|
msbp = 20 |
226 |
|
|
mxncf = 10 |
227 |
|
|
|
228 |
|
|
c initial call to f. (lf0 points to yh(*,2).) ------------------------- |
229 |
|
|
lf0 = lyh + nyh |
230 |
|
|
call f (neq, t, y, rwork(lf0)) |
231 |
|
|
nfe = 1 |
232 |
|
|
|
233 |
|
|
c load the initial value vector in yh. --------------------------------- |
234 |
|
|
iii = lyh-1 |
235 |
|
|
do 115 i = 1,n |
236 |
|
|
115 rwork(i+iii) = y(i) |
237 |
|
|
|
238 |
|
|
c load and invert the ewt array. (h is temporarily set to 1.0.) ------- |
239 |
|
|
nq = 1 |
240 |
|
|
h = 1.0 |
241 |
|
|
call ewset (n, itol, rtol, atol, rwork(lyh), rwork(lewt)) |
242 |
|
|
|
243 |
|
|
iii = lewt-1 |
244 |
|
|
do 120 i = lewt,iii+n |
245 |
|
|
120 rwork(i) = 1.0/rwork(i) |
246 |
|
|
|
247 |
|
|
c----------------------------------------------------------------------- |
248 |
|
|
c the coding below computes the step size, h0, to be attempted on the |
249 |
|
|
c first step, unless the user has supplied a value for this. |
250 |
|
|
c first check that tout - t differs significantly from zero. |
251 |
|
|
c a scalar tolerance quantity tol is computed, as max(rtol(i)) |
252 |
|
|
c if this is positive, or max(atol(i)/abs(y(i))) otherwise, adjusted |
253 |
|
|
c so as to be between 100*uround and 1.0e-3. |
254 |
|
|
c then the computed value h0 is given by.. |
255 |
|
|
c neq |
256 |
|
|
c h0**2 = tol / ( w0**-2 + (1/neq) * sum ( f(i)/ywt(i) )**2 ) |
257 |
|
|
c 1 |
258 |
|
|
c where w0 = max ( abs(t), abs(tout) ), |
259 |
|
|
c f(i) = i-th component of initial value of f, |
260 |
|
|
c ywt(i) = ewt(i)/tol (a weight for y(i)). |
261 |
|
|
c the sign of h0 is inferred from the initial values of tout and t. |
262 |
|
|
c----------------------------------------------------------------------- |
263 |
|
|
|
264 |
|
|
if (h0 .eq. 0.0e0)then |
265 |
|
|
|
266 |
|
|
tdist = abs(tout - t) |
267 |
|
|
w0 = max(abs(t),abs(tout)) |
268 |
|
|
tol = rtol(1) |
269 |
|
|
|
270 |
|
|
c if (itol .gt. 2)then |
271 |
|
|
c do 130 i = 1,n |
272 |
|
|
c 130 tol = max(tol,rtol(i)) |
273 |
|
|
c endif |
274 |
|
|
|
275 |
|
|
if (tol .le. 0.0e0)then |
276 |
|
|
atoli = atol(1) |
277 |
|
|
do 150 i = 1,n |
278 |
|
|
c if (itol .eq. 2 .or. itol .eq. 4) atoli = atol(i) |
279 |
|
|
ayi = abs(y(i)) |
280 |
|
|
if (ayi .ne. 0.0e0) tol = max(tol,atoli/ayi) |
281 |
|
|
150 continue |
282 |
|
|
endif |
283 |
|
|
|
284 |
|
|
tol = max(tol,100.0e0*uround) |
285 |
|
|
tol = min(tol,0.001e0) |
286 |
|
|
sum = vnorm (n, rwork(lf0), rwork(lewt)) |
287 |
|
|
sum = 1.0e0/(tol*w0*w0) + tol*sum**2 |
288 |
|
|
h0 = 1.0e0/sqrt(sum) |
289 |
|
|
h0 = min(h0,tdist) |
290 |
|
|
h0 = sign(h0,tout-t) |
291 |
|
|
|
292 |
|
|
endif |
293 |
|
|
|
294 |
|
|
c adjust h0 if necessary to meet hmax bound. --------------------------- |
295 |
|
|
rh = abs(h0)*hmxi |
296 |
|
|
if (rh .gt. 1.0e0) h0 = h0/rh |
297 |
|
|
c load h with h0 and scale yh(*,2) by h0. ------------------------------ |
298 |
|
|
h = h0 |
299 |
|
|
do 190 i = 1,n |
300 |
|
|
190 rwork(i+lf0-1) = h0*rwork(i+lf0-1) |
301 |
|
|
|
302 |
|
|
c----------------------------------------------------------------------- |
303 |
|
|
c block e. |
304 |
|
|
c the next block is normally executed for all calls and contains |
305 |
|
|
c the call to the one-step core integrator stode. |
306 |
|
|
c |
307 |
|
|
c this is a looping point for the integration steps. |
308 |
|
|
c |
309 |
|
|
c first check for too many steps being taken, update ewt (if not at |
310 |
|
|
c start of problem), check for too much accuracy being requested, and |
311 |
|
|
c check for h below the roundoff level in t. |
312 |
|
|
c----------------------------------------------------------------------- |
313 |
|
|
|
314 |
|
|
do 270 while ((tn - tout)*h .lt. 0.0) |
315 |
|
|
|
316 |
|
|
tolsf = uround*vnorm (n, rwork(lyh), rwork(lewt)) |
317 |
|
|
|
318 |
|
|
if (tolsf .gt. 1.0)then |
319 |
|
|
tolsf = tolsf*2.0 |
320 |
|
|
go to 580 |
321 |
|
|
endif |
322 |
|
|
|
323 |
|
|
call stodenew (neq, y, rwork(lyh), nyh, |
324 |
|
|
& rwork(lyh), rwork(lewt), |
325 |
|
|
& rwork(lsavf), rwork(lacor), rwork(lwm), iwork(liwm), |
326 |
|
|
& f, jac, prepj, solsy) |
327 |
|
|
|
328 |
|
|
init = 1 |
329 |
|
|
|
330 |
|
|
if ((nst-nslast) .ge. mxstep) go to 580 |
331 |
|
|
|
332 |
|
|
call ewset (n, itol, rtol, atol, rwork(lyh), rwork(lewt)) |
333 |
|
|
|
334 |
|
|
do 260 i = 1,n |
335 |
|
|
if (rwork(i+lewt-1) .le. 0.0e0) go to 580 |
336 |
|
|
260 rwork(i+lewt-1) = 1.0e0/rwork(i+lewt-1) |
337 |
|
|
|
338 |
|
|
270 continue |
339 |
|
|
|
340 |
|
|
call intdy (tout, 0, rwork(lyh), nyh, y, iflag) |
341 |
|
|
t = tout |
342 |
|
|
|
343 |
|
|
istate = 2 |
344 |
|
|
illin = 0 |
345 |
|
|
rwork(11) = hu |
346 |
|
|
rwork(12) = h |
347 |
|
|
rwork(13) = tn |
348 |
|
|
iwork(11) = nst |
349 |
|
|
iwork(12) = nfe |
350 |
|
|
iwork(13) = nje |
351 |
|
|
iwork(14) = nqu |
352 |
|
|
iwork(15) = nq |
353 |
|
|
return |
354 |
|
|
c |
355 |
|
|
|
356 |
|
|
c set y vector, t, illin, and optional outputs. ------------------------ |
357 |
|
|
580 do 590 i = 1,n |
358 |
|
|
590 y(i) = rwork(i+lyh-1) |
359 |
|
|
t = tn |
360 |
|
|
illin = 0 |
361 |
|
|
rwork(11) = hu |
362 |
|
|
rwork(12) = h |
363 |
|
|
rwork(13) = tn |
364 |
|
|
iwork(11) = nst |
365 |
|
|
iwork(12) = nfe |
366 |
|
|
iwork(13) = nje |
367 |
|
|
iwork(14) = nqu |
368 |
|
|
iwork(15) = nq |
369 |
|
|
return |
370 |
|
|
|
371 |
|
|
c----------------------- end of subroutine lsode ----------------------- |
372 |
|
|
end |
373 |
|
|
|
374 |
|
|
|
375 |
|
|
c================================================================ |
376 |
|
|
c -- TC2 |
377 |
|
|
c |
378 |
|
|
subroutine stodenew (neq, y, yh, nyh, yh1, ewt, savf, acor, |
379 |
|
|
& wm, iwm, f, jac, pjac, slvs) |
380 |
|
|
c ========================================================== |
381 |
|
|
|
382 |
|
|
c---------------------------------------------------------------c |
383 |
|
|
c STODENEW.F: A simplified version of STODE.F c |
384 |
|
|
c for JSTART >= 0 c |
385 |
|
|
c -------------------------------------------- c |
386 |
|
|
c c |
387 |
|
|
c Chien Wang c |
388 |
|
|
c c |
389 |
|
|
c Last revised: March 20, 1995 c |
390 |
|
|
c c |
391 |
|
|
c---------------------------------------------------------------c |
392 |
|
|
|
393 |
|
|
clll. optimize |
394 |
|
|
external f, jac, pjac, slvs |
395 |
|
|
integer neq, nyh, iwm |
396 |
|
|
integer iownd, ialth, ipup, lmax, meo, nqnyh, nslp, |
397 |
|
|
1 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
398 |
|
|
2 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
399 |
|
|
integer i, i1, iredo, iret, j, jb, m, ncf, newq |
400 |
|
|
real y, yh, yh1, ewt, savf, acor, wm |
401 |
|
|
real conit, crate, el, elco, hold, rmax, tesco, |
402 |
|
|
2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround |
403 |
|
|
real dcon, ddn, del, delp, dsm, dup, exdn, exsm, exup, |
404 |
|
|
1 r, rh, rhdn, rhsm, rhup, told, vnorm |
405 |
|
|
dimension neq(*), y(*), yh(nyh,*), yh1(*), ewt(*), savf(*), |
406 |
|
|
1 acor(*), wm(*), iwm(*) |
407 |
|
|
common /ls0001/ conit, crate, el(13), elco(13,12), |
408 |
|
|
1 hold, rmax, tesco(3,12), |
409 |
|
|
2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround, iownd(14), |
410 |
|
|
3 ialth, ipup, lmax, meo, nqnyh, nslp, |
411 |
|
|
4 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
412 |
|
|
5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
413 |
|
|
c----------------------------------------------------------------------- |
414 |
|
|
c stode performs one step of the integration of an initial value |
415 |
|
|
c problem for a system of ordinary differential equations. |
416 |
|
|
c note.. stode is independent of the value of the iteration method |
417 |
|
|
c indicator miter, when this is .ne. 0, and hence is independent |
418 |
|
|
c of the type of chord method used, or the jacobian structure. |
419 |
|
|
c communication with stode is done with the following variables.. |
420 |
|
|
c |
421 |
|
|
c neq = integer array containing problem size in neq(1), and |
422 |
|
|
c passed as the neq argument in all calls to f and jac. |
423 |
|
|
c y = an array of length .ge. n used as the y argument in |
424 |
|
|
c all calls to f and jac. |
425 |
|
|
c yh = an nyh by lmax array containing the dependent variables |
426 |
|
|
c and their approximate scaled derivatives, where |
427 |
|
|
c lmax = maxord + 1. yh(i,j+1) contains the approximate |
428 |
|
|
c j-th derivative of y(i), scaled by h**j/factorial(j) |
429 |
|
|
c (j = 0,1,...,nq). on entry for the first step, the first |
430 |
|
|
c two columns of yh must be set from the initial values. |
431 |
|
|
c nyh = a constant integer .ge. n, the first dimension of yh. |
432 |
|
|
c yh1 = a one-dimensional array occupying the same space as yh. |
433 |
|
|
c ewt = an array of length n containing multiplicative weights |
434 |
|
|
c for local error measurements. local errors in y(i) are |
435 |
|
|
c compared to 1.0/ewt(i) in various error tests. |
436 |
|
|
c savf = an array of working storage, of length n. |
437 |
|
|
c also used for input of yh(*,maxord+2) when jstart = -1 |
438 |
|
|
c and maxord .lt. the current order nq. |
439 |
|
|
c acor = a work array of length n, used for the accumulated |
440 |
|
|
c corrections. on a successful return, acor(i) contains |
441 |
|
|
c the estimated one-step local error in y(i). |
442 |
|
|
c wm,iwm = real and integer work arrays associated with matrix |
443 |
|
|
c operations in chord iteration (miter .ne. 0). |
444 |
|
|
c pjac = name of routine to evaluate and preprocess jacobian matrix |
445 |
|
|
c and p = i - h*el0*jac, if a chord method is being used. |
446 |
|
|
c slvs = name of routine to solve linear system in chord iteration. |
447 |
|
|
c ccmax = maximum relative change in h*el0 before pjac is called. |
448 |
|
|
c h = the step size to be attempted on the next step. |
449 |
|
|
c h is altered by the error control algorithm during the |
450 |
|
|
c problem. h can be either positive or negative, but its |
451 |
|
|
c sign must remain constant throughout the problem. |
452 |
|
|
c hmin = the minimum absolute value of the step size h to be used. |
453 |
|
|
c hmxi = inverse of the maximum absolute value of h to be used. |
454 |
|
|
c hmxi = 0.0 is allowed and corresponds to an infinite hmax. |
455 |
|
|
c hmin and hmxi may be changed at any time, but will not |
456 |
|
|
c take effect until the next change of h is considered. |
457 |
|
|
c tn = the independent variable. tn is updated on each step taken. |
458 |
|
|
c jstart = an integer used for input only, with the following |
459 |
|
|
c values and meanings.. |
460 |
|
|
c 0 perform the first step. |
461 |
|
|
c .gt.0 take a new step continuing from the last. |
462 |
|
|
c -1 take the next step with a new value of h, maxord, |
463 |
|
|
c n, meth, miter, and/or matrix parameters. |
464 |
|
|
c -2 take the next step with a new value of h, |
465 |
|
|
c but with other inputs unchanged. |
466 |
|
|
c on return, jstart is set to 1 to facilitate continuation. |
467 |
|
|
c kflag = a completion code with the following meanings.. |
468 |
|
|
c 0 the step was succesful. |
469 |
|
|
c -1 the requested error could not be achieved. |
470 |
|
|
c -2 corrector convergence could not be achieved. |
471 |
|
|
c -3 fatal error in pjac or slvs. |
472 |
|
|
c a return with kflag = -1 or -2 means either |
473 |
|
|
c abs(h) = hmin or 10 consecutive failures occurred. |
474 |
|
|
c on a return with kflag negative, the values of tn and |
475 |
|
|
c the yh array are as of the beginning of the last |
476 |
|
|
c step, and h is the last step size attempted. |
477 |
|
|
c maxord = the maximum order of integration method to be allowed. |
478 |
|
|
c maxcor = the maximum number of corrector iterations allowed. |
479 |
|
|
c msbp = maximum number of steps between pjac calls (miter .gt. 0). |
480 |
|
|
c mxncf = maximum number of convergence failures allowed. |
481 |
|
|
c meth/miter = the method flags. see description in driver. |
482 |
|
|
c n = the number of first-order differential equations. |
483 |
|
|
c----------------------------------------------------------------------- |
484 |
|
|
kflag = 0 |
485 |
|
|
told = tn |
486 |
|
|
ncf = 0 |
487 |
|
|
ierpj = 0 |
488 |
|
|
iersl = 0 |
489 |
|
|
jcur = 0 |
490 |
|
|
icf = 0 |
491 |
|
|
delp = 0.0e0 |
492 |
|
|
c----------------------------------------------------------------------- |
493 |
|
|
c on the first call, the order is set to 1, and other variables are |
494 |
|
|
c initialized. rmax is the maximum ratio by which h can be increased |
495 |
|
|
c in a single step. it is initially 1.e4 to compensate for the small |
496 |
|
|
c initial h, but then is normally equal to 10. if a failure |
497 |
|
|
c occurs (in corrector convergence or error test), rmax is set at 2 |
498 |
|
|
c for the next increase. |
499 |
|
|
c |
500 |
|
|
c cfode is called to get all the integration coefficients for the |
501 |
|
|
c current meth. then the el vector and related constants are reset |
502 |
|
|
c whenever the order nq is changed, or at the start of the problem. |
503 |
|
|
c----------------------------------------------------------------------- |
504 |
|
|
if(jstart.eq.0)then |
505 |
|
|
lmax = maxord + 1 |
506 |
|
|
nq = 1 |
507 |
|
|
l = 2 |
508 |
|
|
ialth = 2 |
509 |
|
|
rmax = 10000.0e0 |
510 |
|
|
rc = 0.0e0 |
511 |
|
|
el0 = 1.0e0 |
512 |
|
|
crate = 0.7e0 |
513 |
|
|
hold = h |
514 |
|
|
meo = meth |
515 |
|
|
nslp = 0 |
516 |
|
|
ipup = miter |
517 |
|
|
iret = 3 |
518 |
|
|
|
519 |
|
|
call cfode (meth, elco, tesco) |
520 |
|
|
|
521 |
|
|
endif |
522 |
|
|
c----------------------------------------------------------------------- |
523 |
|
|
|
524 |
|
|
if (jstart .gt. 0) go to 200 |
525 |
|
|
|
526 |
|
|
150 do 155 i = 1,l |
527 |
|
|
155 el(i) = elco(i,nq) |
528 |
|
|
nqnyh = nq*nyh |
529 |
|
|
rc = rc*el(1)/el0 |
530 |
|
|
el0 = el(1) |
531 |
|
|
conit = 0.5e0/float(nq+2) |
532 |
|
|
|
533 |
|
|
if(iret.eq.3) go to 200 |
534 |
|
|
|
535 |
|
|
c----------------------------------------------------------------------- |
536 |
|
|
c if h is being changed, the h ratio rh is checked against |
537 |
|
|
c rmax, hmin, and hmxi, and the yh array rescaled. ialth is set to |
538 |
|
|
c l = nq + 1 to prevent a change of h for that many steps, unless |
539 |
|
|
c forced by a convergence or error test failure. |
540 |
|
|
c----------------------------------------------------------------------- |
541 |
|
|
|
542 |
|
|
170 rh = max(rh,hmin/abs(h)) |
543 |
|
|
rh = min(rh,rmax) |
544 |
|
|
rh = rh/max(1.0e0,abs(h)*hmxi*rh) |
545 |
|
|
r = 1.0e0 |
546 |
|
|
do 180 j = 2,l |
547 |
|
|
r = r*rh |
548 |
|
|
do 180 i = 1,n |
549 |
|
|
180 yh(i,j) = yh(i,j)*r |
550 |
|
|
h = h*rh |
551 |
|
|
rc = rc*rh |
552 |
|
|
ialth = l |
553 |
|
|
if (iredo .eq. 0) go to 690 |
554 |
|
|
c----------------------------------------------------------------------- |
555 |
|
|
c this section computes the predicted values by effectively |
556 |
|
|
c multiplying the yh array by the pascal triangle matrix. |
557 |
|
|
c rc is the ratio of new to old values of the coefficient h*el(1). |
558 |
|
|
c when rc differs from 1 by more than ccmax, ipup is set to miter |
559 |
|
|
c to force pjac to be called, if a jacobian is involved. |
560 |
|
|
c in any case, pjac is called at least every msbp steps. |
561 |
|
|
c----------------------------------------------------------------------- |
562 |
|
|
200 if (abs(rc-1.0e0) .gt. ccmax) ipup = miter |
563 |
|
|
if (nst .ge. nslp+msbp) ipup = miter |
564 |
|
|
tn = tn + h |
565 |
|
|
i1 = nqnyh + 1 |
566 |
|
|
do 215 jb = 1,nq |
567 |
|
|
i1 = i1 - nyh |
568 |
|
|
cdir$ ivdep |
569 |
|
|
do 210 i = i1,nqnyh |
570 |
|
|
210 yh1(i) = yh1(i) + yh1(i+nyh) |
571 |
|
|
215 continue |
572 |
|
|
c----------------------------------------------------------------------- |
573 |
|
|
c up to maxcor corrector iterations are taken. a convergence test is |
574 |
|
|
c made on the r.m.s. norm of each correction, weighted by the error |
575 |
|
|
c weight vector ewt. the sum of the corrections is accumulated in the |
576 |
|
|
c vector acor(i). the yh array is not altered in the corrector loop. |
577 |
|
|
c----------------------------------------------------------------------- |
578 |
|
|
220 m = 0 |
579 |
|
|
do 230 i = 1,n |
580 |
|
|
230 y(i) = yh(i,1) |
581 |
|
|
call f (neq, tn, y, savf) |
582 |
|
|
nfe = nfe + 1 |
583 |
|
|
c----------------------------------------------------------------------- |
584 |
|
|
c if indicated, the matrix p = i - h*el(1)*j is reevaluated and |
585 |
|
|
c preprocessed before starting the corrector iteration. ipup is set |
586 |
|
|
c to 0 as an indicator that this has been done. |
587 |
|
|
c----------------------------------------------------------------------- |
588 |
|
|
if (ipup .gt. 0)then |
589 |
|
|
|
590 |
|
|
call pjac (neq, y, yh, nyh, ewt, acor, savf, wm, iwm, f, jac) |
591 |
|
|
ipup = 0 |
592 |
|
|
rc = 1.0e0 |
593 |
|
|
nslp = nst |
594 |
|
|
crate = 0.7e0 |
595 |
|
|
if (ierpj .ne. 0) go to 430 |
596 |
|
|
|
597 |
|
|
endif |
598 |
|
|
|
599 |
|
|
do 260 i = 1,n |
600 |
|
|
260 acor(i) = 0.0e0 |
601 |
|
|
270 if (miter .ne. 0) go to 350 |
602 |
|
|
c----------------------------------------------------------------------- |
603 |
|
|
c in the case of functional iteration, update y directly from |
604 |
|
|
c the result of the last function evaluation. |
605 |
|
|
c----------------------------------------------------------------------- |
606 |
|
|
do 290 i = 1,n |
607 |
|
|
savf(i) = h*savf(i) - yh(i,2) |
608 |
|
|
290 y(i) = savf(i) - acor(i) |
609 |
|
|
del = vnorm (n, y, ewt) |
610 |
|
|
do 300 i = 1,n |
611 |
|
|
y(i) = yh(i,1) + el(1)*savf(i) |
612 |
|
|
300 acor(i) = savf(i) |
613 |
|
|
go to 400 |
614 |
|
|
c----------------------------------------------------------------------- |
615 |
|
|
c in the case of the chord method, compute the corrector error, |
616 |
|
|
c and solve the linear system with that as right-hand side and |
617 |
|
|
c p as coefficient matrix. |
618 |
|
|
c----------------------------------------------------------------------- |
619 |
|
|
350 do 360 i = 1,n |
620 |
|
|
360 y(i) = h*savf(i) - (yh(i,2) + acor(i)) |
621 |
|
|
call slvs (wm, iwm, y, savf) |
622 |
|
|
if (iersl .lt. 0) go to 430 |
623 |
|
|
if (iersl .gt. 0) go to 410 |
624 |
|
|
del = vnorm (n, y, ewt) |
625 |
|
|
do 380 i = 1,n |
626 |
|
|
acor(i) = acor(i) + y(i) |
627 |
|
|
380 y(i) = yh(i,1) + el(1)*acor(i) |
628 |
|
|
c----------------------------------------------------------------------- |
629 |
|
|
c test for convergence. if m.gt.0, an estimate of the convergence |
630 |
|
|
c rate constant is stored in crate, and this is used in the test. |
631 |
|
|
c----------------------------------------------------------------------- |
632 |
|
|
400 if (m .ne. 0) crate = max(0.2e0*crate,del/delp) |
633 |
|
|
dcon = del*min(1.0e0,1.5e0*crate)/(tesco(2,nq)*conit) |
634 |
|
|
if (dcon .le. 1.0e0) go to 450 |
635 |
|
|
m = m + 1 |
636 |
|
|
if (m .eq. maxcor) go to 410 |
637 |
|
|
if (m .ge. 2 .and. del .gt. 2.0e0*delp) go to 410 |
638 |
|
|
delp = del |
639 |
|
|
call f (neq, tn, y, savf) |
640 |
|
|
nfe = nfe + 1 |
641 |
|
|
go to 270 |
642 |
|
|
c----------------------------------------------------------------------- |
643 |
|
|
c the corrector iteration failed to converge. |
644 |
|
|
c if miter .ne. 0 and the jacobian is out of date, pjac is called for |
645 |
|
|
c the next try. otherwise the yh array is retracted to its values |
646 |
|
|
c before prediction, and h is reduced, if possible. if h cannot be |
647 |
|
|
c reduced or mxncf failures have occurred, exit with kflag = -2. |
648 |
|
|
c----------------------------------------------------------------------- |
649 |
|
|
410 if (miter .eq. 0 .or. jcur .eq. 1) go to 430 |
650 |
|
|
icf = 1 |
651 |
|
|
ipup = miter |
652 |
|
|
go to 220 |
653 |
|
|
430 icf = 2 |
654 |
|
|
ncf = ncf + 1 |
655 |
|
|
rmax = 2.0e0 |
656 |
|
|
tn = told |
657 |
|
|
i1 = nqnyh + 1 |
658 |
|
|
do 445 jb = 1,nq |
659 |
|
|
i1 = i1 - nyh |
660 |
|
|
cdir$ ivdep |
661 |
|
|
do 440 i = i1,nqnyh |
662 |
|
|
440 yh1(i) = yh1(i) - yh1(i+nyh) |
663 |
|
|
445 continue |
664 |
|
|
if (ierpj .lt. 0 .or. iersl .lt. 0) go to 680 |
665 |
|
|
if (abs(h) .le. hmin*1.00001e0) go to 670 |
666 |
|
|
if (ncf .eq. mxncf) go to 670 |
667 |
|
|
rh = 0.25e0 |
668 |
|
|
ipup = miter |
669 |
|
|
iredo = 1 |
670 |
|
|
go to 170 |
671 |
|
|
c----------------------------------------------------------------------- |
672 |
|
|
c the corrector has converged. jcur is set to 0 |
673 |
|
|
c to signal that the jacobian involved may need updating later. |
674 |
|
|
c the local error test is made and control passes to statement 500 |
675 |
|
|
c if it fails. |
676 |
|
|
c----------------------------------------------------------------------- |
677 |
|
|
450 jcur = 0 |
678 |
|
|
if (m .eq. 0) dsm = del/tesco(2,nq) |
679 |
|
|
if (m .gt. 0) dsm = vnorm (n, acor, ewt)/tesco(2,nq) |
680 |
|
|
if (dsm .gt. 1.0e0) go to 500 |
681 |
|
|
c----------------------------------------------------------------------- |
682 |
|
|
c after a successful step, update the yh array. |
683 |
|
|
c consider changing h if ialth = 1. otherwise decrease ialth by 1. |
684 |
|
|
c if ialth is then 1 and nq .lt. maxord, then acor is saved for |
685 |
|
|
c use in a possible order increase on the next step. |
686 |
|
|
c if a change in h is considered, an increase or decrease in order |
687 |
|
|
c by one is considered also. a change in h is made only if it is by a |
688 |
|
|
c factor of at least 1.1. if not, ialth is set to 3 to prevent |
689 |
|
|
c testing for that many steps. |
690 |
|
|
c----------------------------------------------------------------------- |
691 |
|
|
kflag = 0 |
692 |
|
|
iredo = 0 |
693 |
|
|
nst = nst + 1 |
694 |
|
|
hu = h |
695 |
|
|
nqu = nq |
696 |
|
|
do 470 j = 1,l |
697 |
|
|
do 470 i = 1,n |
698 |
|
|
470 yh(i,j) = yh(i,j) + el(j)*acor(i) |
699 |
|
|
ialth = ialth - 1 |
700 |
|
|
if (ialth .eq. 0) go to 520 |
701 |
|
|
if (ialth .gt. 1) go to 700 |
702 |
|
|
if (l .eq. lmax) go to 700 |
703 |
|
|
do 490 i = 1,n |
704 |
|
|
490 yh(i,lmax) = acor(i) |
705 |
|
|
go to 700 |
706 |
|
|
c----------------------------------------------------------------------- |
707 |
|
|
c the error test failed. kflag keeps track of multiple failures. |
708 |
|
|
c restore tn and the yh array to their previous values, and prepare |
709 |
|
|
c to try the step again. compute the optimum step size for this or |
710 |
|
|
c one lower order. after 2 or more failures, h is forced to decrease |
711 |
|
|
c by a factor of 0.2 or less. |
712 |
|
|
c----------------------------------------------------------------------- |
713 |
|
|
500 kflag = kflag - 1 |
714 |
|
|
tn = told |
715 |
|
|
i1 = nqnyh + 1 |
716 |
|
|
do 515 jb = 1,nq |
717 |
|
|
i1 = i1 - nyh |
718 |
|
|
cdir$ ivdep |
719 |
|
|
do 510 i = i1,nqnyh |
720 |
|
|
510 yh1(i) = yh1(i) - yh1(i+nyh) |
721 |
|
|
515 continue |
722 |
|
|
rmax = 2.0e0 |
723 |
|
|
if (abs(h) .le. hmin*1.00001e0) go to 660 |
724 |
|
|
if (kflag .le. -3) go to 640 |
725 |
|
|
iredo = 2 |
726 |
|
|
rhup = 0.0e0 |
727 |
|
|
go to 540 |
728 |
|
|
c----------------------------------------------------------------------- |
729 |
|
|
c regardless of the success or failure of the step, factors |
730 |
|
|
c rhdn, rhsm, and rhup are computed, by which h could be multiplied |
731 |
|
|
c at order nq - 1, order nq, or order nq + 1, respectively. |
732 |
|
|
c in the case of failure, rhup = 0.0 to avoid an order increase. |
733 |
|
|
c the largest of these is determined and the new order chosen |
734 |
|
|
c accordingly. if the order is to be increased, we compute one |
735 |
|
|
c additional scaled derivative. |
736 |
|
|
c----------------------------------------------------------------------- |
737 |
|
|
520 rhup = 0.0e0 |
738 |
|
|
if (l .eq. lmax) go to 540 |
739 |
|
|
do 530 i = 1,n |
740 |
|
|
530 savf(i) = acor(i) - yh(i,lmax) |
741 |
|
|
dup = vnorm (n, savf, ewt)/tesco(3,nq) |
742 |
|
|
exup = 1.0e0/float(l+1) |
743 |
|
|
rhup = 1.0e0/(1.4e0*dup**exup + 0.0000014e0) |
744 |
|
|
540 exsm = 1.0e0/float(l) |
745 |
|
|
rhsm = 1.0e0/(1.2e0*dsm**exsm + 0.0000012e0) |
746 |
|
|
rhdn = 0.0e0 |
747 |
|
|
if (nq .eq. 1) go to 560 |
748 |
|
|
ddn = vnorm (n, yh(1,l), ewt)/tesco(1,nq) |
749 |
|
|
exdn = 1.0e0/float(nq) |
750 |
|
|
rhdn = 1.0e0/(1.3e0*ddn**exdn + 0.0000013e0) |
751 |
|
|
560 if (rhsm .ge. rhup) go to 570 |
752 |
|
|
if (rhup .gt. rhdn) go to 590 |
753 |
|
|
go to 580 |
754 |
|
|
570 if (rhsm .lt. rhdn) go to 580 |
755 |
|
|
newq = nq |
756 |
|
|
rh = rhsm |
757 |
|
|
go to 620 |
758 |
|
|
580 newq = nq - 1 |
759 |
|
|
rh = rhdn |
760 |
|
|
if (kflag .lt. 0 .and. rh .gt. 1.0e0) rh = 1.0e0 |
761 |
|
|
go to 620 |
762 |
|
|
590 newq = l |
763 |
|
|
rh = rhup |
764 |
|
|
if (rh .lt. 1.1e0) go to 610 |
765 |
|
|
r = el(l)/float(l) |
766 |
|
|
do 600 i = 1,n |
767 |
|
|
600 yh(i,newq+1) = acor(i)*r |
768 |
|
|
go to 630 |
769 |
|
|
610 ialth = 3 |
770 |
|
|
go to 700 |
771 |
|
|
620 if ((kflag .eq. 0) .and. (rh .lt. 1.1e0)) go to 610 |
772 |
|
|
if (kflag .le. -2) rh = min(rh,0.2e0) |
773 |
|
|
c----------------------------------------------------------------------- |
774 |
|
|
c if there is a change of order, reset nq, l, and the coefficients. |
775 |
|
|
c in any case h is reset according to rh and the yh array is rescaled. |
776 |
|
|
c then exit from 690 if the step was ok, or redo the step otherwise. |
777 |
|
|
c----------------------------------------------------------------------- |
778 |
|
|
if (newq .eq. nq) go to 170 |
779 |
|
|
630 nq = newq |
780 |
|
|
l = nq + 1 |
781 |
|
|
iret = 2 |
782 |
|
|
go to 150 |
783 |
|
|
c----------------------------------------------------------------------- |
784 |
|
|
c control reaches this section if 3 or more failures have occured. |
785 |
|
|
c if 10 failures have occurred, exit with kflag = -1. |
786 |
|
|
c it is assumed that the derivatives that have accumulated in the |
787 |
|
|
c yh array have errors of the wrong order. hence the first |
788 |
|
|
c derivative is recomputed, and the order is set to 1. then |
789 |
|
|
c h is reduced by a factor of 10, and the step is retried, |
790 |
|
|
c until it succeeds or h reaches hmin. |
791 |
|
|
c----------------------------------------------------------------------- |
792 |
|
|
640 if (kflag .eq. -10) go to 660 |
793 |
|
|
rh = 0.1e0 |
794 |
|
|
rh = max(hmin/abs(h),rh) |
795 |
|
|
h = h*rh |
796 |
|
|
do 645 i = 1,n |
797 |
|
|
645 y(i) = yh(i,1) |
798 |
|
|
call f (neq, tn, y, savf) |
799 |
|
|
nfe = nfe + 1 |
800 |
|
|
do 650 i = 1,n |
801 |
|
|
650 yh(i,2) = h*savf(i) |
802 |
|
|
ipup = miter |
803 |
|
|
ialth = 5 |
804 |
|
|
if (nq .eq. 1) go to 200 |
805 |
|
|
nq = 1 |
806 |
|
|
l = 2 |
807 |
|
|
iret = 3 |
808 |
|
|
go to 150 |
809 |
|
|
c----------------------------------------------------------------------- |
810 |
|
|
c all returns are made through this section. h is saved in hold |
811 |
|
|
c to allow the caller to change h on the next step. |
812 |
|
|
c----------------------------------------------------------------------- |
813 |
|
|
660 kflag = -1 |
814 |
|
|
go to 720 |
815 |
|
|
670 kflag = -2 |
816 |
|
|
go to 720 |
817 |
|
|
680 kflag = -3 |
818 |
|
|
go to 720 |
819 |
|
|
690 rmax = 10.0e0 |
820 |
|
|
700 r = 1.0e0/tesco(2,nqu) |
821 |
|
|
do 710 i = 1,n |
822 |
|
|
710 acor(i) = acor(i)*r |
823 |
|
|
720 hold = h |
824 |
|
|
jstart = 1 |
825 |
|
|
return |
826 |
|
|
c----------------------- end of subroutine stode ----------------------- |
827 |
|
|
end |
828 |
|
|
|
829 |
|
|
|
830 |
|
|
c=================================================================== |
831 |
|
|
c -- TC3 |
832 |
|
|
c |
833 |
|
|
subroutine ewset (n, itol, rtol, atol, ycur, ewt) |
834 |
|
|
c ================================================= |
835 |
|
|
|
836 |
|
|
clll. optimize |
837 |
|
|
c----------------------------------------------------------------------- |
838 |
|
|
c this subroutine sets the error weight vector ewt according to |
839 |
|
|
c ewt(i) = rtol(i)*abs(ycur(i)) + atol(i), i = 1,...,n, |
840 |
|
|
c with the subscript on rtol and/or atol possibly replaced by 1 above, |
841 |
|
|
c depending on the value of itol. |
842 |
|
|
c----------------------------------------------------------------------- |
843 |
|
|
c |
844 |
|
|
c Chien Wang |
845 |
|
|
c rewritten 031795 |
846 |
|
|
c |
847 |
|
|
integer n, itol |
848 |
|
|
integer i |
849 |
|
|
real rtol, atol, ycur, ewt |
850 |
|
|
dimension rtol(*), atol(*), ycur(n), ewt(n) |
851 |
|
|
c |
852 |
|
|
aaa = rtol(1) |
853 |
|
|
bbb = atol(1) |
854 |
|
|
|
855 |
|
|
do 1 i=1,n |
856 |
|
|
ewt(i) = aaa*abs(ycur(i)) + bbb |
857 |
|
|
1 continue |
858 |
|
|
|
859 |
|
|
return |
860 |
|
|
end |
861 |
|
|
|
862 |
|
|
|
863 |
|
|
c============================================================== |
864 |
|
|
c -- TC4 |
865 |
|
|
c |
866 |
|
|
subroutine solsy (wm, iwm, x, tem) |
867 |
|
|
c ================================= |
868 |
|
|
|
869 |
|
|
c |
870 |
|
|
c Chien Wang |
871 |
|
|
c MIT |
872 |
|
|
c Rewrote 122695 |
873 |
|
|
c |
874 |
|
|
|
875 |
|
|
clll. optimize |
876 |
|
|
integer iwm |
877 |
|
|
integer iownd, iowns, |
878 |
|
|
1 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
879 |
|
|
2 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
880 |
|
|
integer i, meband, ml, mu |
881 |
|
|
real wm, x, tem |
882 |
|
|
real rowns, |
883 |
|
|
1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround |
884 |
|
|
real di, hl0, phl0, r |
885 |
|
|
dimension wm(*), iwm(*), x(*), tem(*) |
886 |
|
|
common /ls0001/ rowns(209), |
887 |
|
|
2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround, |
888 |
|
|
3 iownd(14), iowns(6), |
889 |
|
|
4 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
890 |
|
|
5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
891 |
|
|
c----------------------------------------------------------------------- |
892 |
|
|
c this routine manages the solution of the linear system arising from |
893 |
|
|
c a chord iteration. it is called if miter .ne. 0. |
894 |
|
|
c if miter is 1 or 2, it calls sgesl to accomplish this. |
895 |
|
|
c if miter = 3 it updates the coefficient h*el0 in the diagonal |
896 |
|
|
c matrix, and then computes the solution. |
897 |
|
|
c if miter is 4 or 5, it calls sgbsl. |
898 |
|
|
c communication with solsy uses the following variables.. |
899 |
|
|
c wm = real work space containing the inverse diagonal matrix if |
900 |
|
|
c miter = 3 and the lu decomposition of the matrix otherwise. |
901 |
|
|
c storage of matrix elements starts at wm(3). |
902 |
|
|
c wm also contains the following matrix-related data.. |
903 |
|
|
c wm(1) = sqrt(uround) (not used here), |
904 |
|
|
c wm(2) = hl0, the previous value of h*el0, used if miter = 3. |
905 |
|
|
c iwm = integer work space containing pivot information, starting at |
906 |
|
|
c iwm(21), if miter is 1, 2, 4, or 5. iwm also contains band |
907 |
|
|
c parameters ml = iwm(1) and mu = iwm(2) if miter is 4 or 5. |
908 |
|
|
c x = the right-hand side vector on input, and the solution vector |
909 |
|
|
c on output, of length n. |
910 |
|
|
c tem = vector of work space of length n, not used in this version. |
911 |
|
|
c iersl = output flag (in common). iersl = 0 if no trouble occurred. |
912 |
|
|
c iersl = 1 if a singular matrix arose with miter = 3. |
913 |
|
|
c this routine also uses the common variables el0, h, miter, and n. |
914 |
|
|
c----------------------------------------------------------------------- |
915 |
|
|
iersl = 0 |
916 |
|
|
|
917 |
|
|
if(miter.eq.1.or.miter.eq.2) |
918 |
|
|
& call sgesl (wm(3), n, n, iwm(21), x, 0) |
919 |
|
|
if(miter.eq.3) |
920 |
|
|
& call solsy2(wm, iwm, x, tem) |
921 |
|
|
if(miter.eq.4.or.miter.eq.5)then |
922 |
|
|
ml = iwm(1) |
923 |
|
|
mu = iwm(2) |
924 |
|
|
meband = 2*ml + mu + 1 |
925 |
|
|
call sgbsl (wm(3), meband, n, |
926 |
|
|
& ml, mu, iwm(21), x, 0) |
927 |
|
|
endif |
928 |
|
|
|
929 |
|
|
return |
930 |
|
|
end |
931 |
|
|
|
932 |
|
|
c |
933 |
|
|
subroutine solsy2(wm, iwm, x, tem) |
934 |
|
|
c ================================== |
935 |
|
|
c |
936 |
|
|
c Chien Wang |
937 |
|
|
c MIT |
938 |
|
|
c 122695 |
939 |
|
|
c |
940 |
|
|
integer iwm |
941 |
|
|
integer iownd, iowns, |
942 |
|
|
1 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
943 |
|
|
2 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
944 |
|
|
integer i, meband, ml, mu |
945 |
|
|
real wm, x, tem |
946 |
|
|
real rowns, |
947 |
|
|
1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround |
948 |
|
|
real di, hl0, phl0, r |
949 |
|
|
dimension wm(*), iwm(*), x(*), tem(*) |
950 |
|
|
common /ls0001/ rowns(209), |
951 |
|
|
2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround, |
952 |
|
|
3 iownd(14), iowns(6), |
953 |
|
|
4 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
954 |
|
|
5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
955 |
|
|
|
956 |
|
|
iersl = 0 |
957 |
|
|
phl0 = wm(2) |
958 |
|
|
hl0 = h*el0 |
959 |
|
|
wm(2) = hl0 |
960 |
|
|
|
961 |
|
|
if (hl0 .ne. phl0)then |
962 |
|
|
r = hl0/phl0 |
963 |
|
|
do 320 i = 1,n |
964 |
|
|
di = 1.0e0 - r*(1.0e0 - 1.0e0/wm(i+2)) |
965 |
|
|
if (abs(di) .ne. 0.0e0)then |
966 |
|
|
wm(i+2) = 1.0e0/di |
967 |
|
|
else |
968 |
|
|
iersl = 1 |
969 |
|
|
goto 360 |
970 |
|
|
endif |
971 |
|
|
320 continue |
972 |
|
|
|
973 |
|
|
else |
974 |
|
|
do 340 i = 1,n |
975 |
|
|
x(i) = wm(i+2)*x(i) |
976 |
|
|
340 continue |
977 |
|
|
endif |
978 |
|
|
|
979 |
|
|
360 return |
980 |
|
|
end |
981 |
|
|
|
982 |
|
|
c---- end of subroutine solsy and new solsy2 |
983 |
|
|
|
984 |
|
|
|
985 |
|
|
c============================================================== |
986 |
|
|
c -- TC5 |
987 |
|
|
c |
988 |
|
|
subroutine intdy (t, k, yh, nyh, dky, iflag) |
989 |
|
|
c =========================================== |
990 |
|
|
|
991 |
|
|
clll. optimize |
992 |
|
|
integer k, nyh, iflag |
993 |
|
|
integer iownd, iowns, |
994 |
|
|
1 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
995 |
|
|
2 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
996 |
|
|
integer i, ic, j, jb, jb2, jj, jj1, jp1 |
997 |
|
|
real t, yh, dky |
998 |
|
|
real rowns, |
999 |
|
|
1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround |
1000 |
|
|
real c, r, s, tp |
1001 |
|
|
dimension yh(nyh,*), dky(*) |
1002 |
|
|
common /ls0001/ rowns(209), |
1003 |
|
|
2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround, |
1004 |
|
|
3 iownd(14), iowns(6), |
1005 |
|
|
4 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
1006 |
|
|
5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
1007 |
|
|
c----------------------------------------------------------------------- |
1008 |
|
|
c intdy computes interpolated values of the k-th derivative of the |
1009 |
|
|
c dependent variable vector y, and stores it in dky. this routine |
1010 |
|
|
c is called within the package with k = 0 and t = tout, but may |
1011 |
|
|
c also be called by the user for any k up to the current order. |
1012 |
|
|
c (see detailed instructions in the usage documentation.) |
1013 |
|
|
c----------------------------------------------------------------------- |
1014 |
|
|
c the computed values in dky are gotten by interpolation using the |
1015 |
|
|
c nordsieck history array yh. this array corresponds uniquely to a |
1016 |
|
|
c vector-valued polynomial of degree nqcur or less, and dky is set |
1017 |
|
|
c to the k-th derivative of this polynomial at t. |
1018 |
|
|
c the formula for dky is.. |
1019 |
|
|
c q |
1020 |
|
|
c dky(i) = sum c(j,k) * (t - tn)**(j-k) * h**(-j) * yh(i,j+1) |
1021 |
|
|
c j=k |
1022 |
|
|
c where c(j,k) = j*(j-1)*...*(j-k+1), q = nqcur, tn = tcur, h = hcur. |
1023 |
|
|
c the quantities nq = nqcur, l = nq+1, n = neq, tn, and h are |
1024 |
|
|
c communicated by common. the above sum is done in reverse order. |
1025 |
|
|
c iflag is returned negative if either k or t is out of bounds. |
1026 |
|
|
c----------------------------------------------------------------------- |
1027 |
|
|
iflag = 0 |
1028 |
|
|
if (k .lt. 0 .or. k .gt. nq) go to 80 |
1029 |
|
|
tp = tn - hu - 100.0e0*uround*(tn + hu) |
1030 |
|
|
if ((t-tp)*(t-tn) .gt. 0.0e0) go to 90 |
1031 |
|
|
c |
1032 |
|
|
s = (t - tn)/h |
1033 |
|
|
ic = 1 |
1034 |
|
|
if (k .eq. 0) go to 15 |
1035 |
|
|
jj1 = l - k |
1036 |
|
|
do 10 jj = jj1,nq |
1037 |
|
|
10 ic = ic*jj |
1038 |
|
|
15 c = float(ic) |
1039 |
|
|
do 20 i = 1,n |
1040 |
|
|
20 dky(i) = c*yh(i,l) |
1041 |
|
|
if (k .eq. nq) go to 55 |
1042 |
|
|
jb2 = nq - k |
1043 |
|
|
do 50 jb = 1,jb2 |
1044 |
|
|
j = nq - jb |
1045 |
|
|
jp1 = j + 1 |
1046 |
|
|
ic = 1 |
1047 |
|
|
if (k .eq. 0) go to 35 |
1048 |
|
|
jj1 = jp1 - k |
1049 |
|
|
do 30 jj = jj1,j |
1050 |
|
|
30 ic = ic*jj |
1051 |
|
|
35 c = float(ic) |
1052 |
|
|
do 40 i = 1,n |
1053 |
|
|
40 dky(i) = c*yh(i,jp1) + s*dky(i) |
1054 |
|
|
50 continue |
1055 |
|
|
if (k .eq. 0) return |
1056 |
|
|
55 r = h**(-k) |
1057 |
|
|
do 60 i = 1,n |
1058 |
|
|
60 dky(i) = r*dky(i) |
1059 |
|
|
return |
1060 |
|
|
c |
1061 |
|
|
80 call xerrwv(30hintdy-- k (=i1) illegal , |
1062 |
|
|
1 30, 51, 0, 1, k, 0, 0, 0.0e0, 0.0e0) |
1063 |
|
|
iflag = -1 |
1064 |
|
|
return |
1065 |
|
|
90 call xerrwv(30hintdy-- t (=r1) illegal , |
1066 |
|
|
1 30, 52, 0, 0, 0, 0, 1, t, 0.0e0) |
1067 |
|
|
call xerrwv( |
1068 |
|
|
1 60h t not in interval tcur - hu (= r1) to tcur (=r2) , |
1069 |
|
|
1 60, 52, 0, 0, 0, 0, 2, tp, tn) |
1070 |
|
|
iflag = -2 |
1071 |
|
|
return |
1072 |
|
|
c----------------------- end of subroutine intdy ----------------------- |
1073 |
|
|
end |
1074 |
|
|
|
1075 |
|
|
|
1076 |
|
|
c============================================================= |
1077 |
|
|
c -- TC6 |
1078 |
|
|
c |
1079 |
|
|
subroutine cfode (meth, elco, tesco) |
1080 |
|
|
c =================================== |
1081 |
|
|
|
1082 |
|
|
clll. optimize |
1083 |
|
|
integer meth |
1084 |
|
|
integer i, ib, nq, nqm1, nqp1 |
1085 |
|
|
real elco, tesco |
1086 |
|
|
real agamq, fnq, fnqm1, pc, pint, ragq, |
1087 |
|
|
1 rqfac, rq1fac, tsign, xpin |
1088 |
|
|
dimension elco(13,12), tesco(3,12) |
1089 |
|
|
c----------------------------------------------------------------------- |
1090 |
|
|
c cfode is called by the integrator routine to set coefficients |
1091 |
|
|
c needed there. the coefficients for the current method, as |
1092 |
|
|
c given by the value of meth, are set for all orders and saved. |
1093 |
|
|
c the maximum order assumed here is 12 if meth = 1 and 5 if meth = 2. |
1094 |
|
|
c (a smaller value of the maximum order is also allowed.) |
1095 |
|
|
c cfode is called once at the beginning of the problem, |
1096 |
|
|
c and is not called again unless and until meth is changed. |
1097 |
|
|
c |
1098 |
|
|
c the elco array contains the basic method coefficients. |
1099 |
|
|
c the coefficients el(i), 1 .le. i .le. nq+1, for the method of |
1100 |
|
|
c order nq are stored in elco(i,nq). they are given by a genetrating |
1101 |
|
|
c polynomial, i.e., |
1102 |
|
|
c l(x) = el(1) + el(2)*x + ... + el(nq+1)*x**nq. |
1103 |
|
|
c for the implicit adams methods, l(x) is given by |
1104 |
|
|
c dl/dx = (x+1)*(x+2)*...*(x+nq-1)/factorial(nq-1), l(-1) = 0. |
1105 |
|
|
c for the bdf methods, l(x) is given by |
1106 |
|
|
c l(x) = (x+1)*(x+2)* ... *(x+nq)/k, |
1107 |
|
|
c where k = factorial(nq)*(1 + 1/2 + ... + 1/nq). |
1108 |
|
|
c |
1109 |
|
|
c the tesco array contains test constants used for the |
1110 |
|
|
c local error test and the selection of step size and/or order. |
1111 |
|
|
c at order nq, tesco(k,nq) is used for the selection of step |
1112 |
|
|
c size at order nq - 1 if k = 1, at order nq if k = 2, and at order |
1113 |
|
|
c nq + 1 if k = 3. |
1114 |
|
|
c----------------------------------------------------------------------- |
1115 |
|
|
|
1116 |
|
|
if(meth.eq.1) call cfode1(meth, elco, tesco) |
1117 |
|
|
if(meth.eq.2) call cfode2(meth, elco, tesco) |
1118 |
|
|
|
1119 |
|
|
return |
1120 |
|
|
end |
1121 |
|
|
|
1122 |
|
|
c |
1123 |
|
|
subroutine cfode1(meth,elco,tesco) |
1124 |
|
|
c ================================== |
1125 |
|
|
|
1126 |
|
|
c |
1127 |
|
|
c Chien Wang |
1128 |
|
|
c MIT |
1129 |
|
|
c 122695 |
1130 |
|
|
c |
1131 |
|
|
|
1132 |
|
|
integer meth |
1133 |
|
|
integer i, ib, nq, nqm1, nqp1 |
1134 |
|
|
real elco, tesco |
1135 |
|
|
real agamq, fnq, fnqm1, pc, pint, ragq, |
1136 |
|
|
1 rqfac, rq1fac, tsign, xpin |
1137 |
|
|
dimension elco(13,12), tesco(3,12) |
1138 |
|
|
dimension pc(12) |
1139 |
|
|
|
1140 |
|
|
elco(1,1) = 1.0e0 |
1141 |
|
|
elco(2,1) = 1.0e0 |
1142 |
|
|
tesco(1,1) = 0.0e0 |
1143 |
|
|
tesco(2,1) = 2.0e0 |
1144 |
|
|
tesco(1,2) = 1.0e0 |
1145 |
|
|
tesco(3,12) = 0.0e0 |
1146 |
|
|
pc(1) = 1.0e0 |
1147 |
|
|
rqfac = 1.0e0 |
1148 |
|
|
do 140 nq = 2,12 |
1149 |
|
|
c----------------------------------------------------------------------- |
1150 |
|
|
c the pc array will contain the coefficients of the polynomial |
1151 |
|
|
c p(x) = (x+1)*(x+2)*...*(x+nq-1). |
1152 |
|
|
c initially, p(x) = 1. |
1153 |
|
|
c----------------------------------------------------------------------- |
1154 |
|
|
rq1fac = rqfac |
1155 |
|
|
rqfac = rqfac/float(nq) |
1156 |
|
|
nqm1 = nq - 1 |
1157 |
|
|
fnqm1 = float(nqm1) |
1158 |
|
|
nqp1 = nq + 1 |
1159 |
|
|
c form coefficients of p(x)*(x+nq-1). ---------------------------------- |
1160 |
|
|
pc(nq) = 0.0e0 |
1161 |
|
|
do 110 ib = 1,nqm1 |
1162 |
|
|
i = nqp1 - ib |
1163 |
|
|
110 pc(i) = pc(i-1) + fnqm1*pc(i) |
1164 |
|
|
pc(1) = fnqm1*pc(1) |
1165 |
|
|
c compute integral, -1 to 0, of p(x) and x*p(x). ----------------------- |
1166 |
|
|
pint = pc(1) |
1167 |
|
|
xpin = pc(1)/2.0e0 |
1168 |
|
|
tsign = 1.0e0 |
1169 |
|
|
do 120 i = 2,nq |
1170 |
|
|
tsign = -tsign |
1171 |
|
|
pint = pint + tsign*pc(i)/float(i) |
1172 |
|
|
120 xpin = xpin + tsign*pc(i)/float(i+1) |
1173 |
|
|
c store coefficients in elco and tesco. -------------------------------- |
1174 |
|
|
elco(1,nq) = pint*rq1fac |
1175 |
|
|
elco(2,nq) = 1.0e0 |
1176 |
|
|
do 130 i = 2,nq |
1177 |
|
|
130 elco(i+1,nq) = rq1fac*pc(i)/float(i) |
1178 |
|
|
agamq = rqfac*xpin |
1179 |
|
|
ragq = 1.0e0/agamq |
1180 |
|
|
tesco(2,nq) = ragq |
1181 |
|
|
if (nq .lt. 12) tesco(1,nqp1) = ragq*rqfac/float(nqp1) |
1182 |
|
|
tesco(3,nqm1) = ragq |
1183 |
|
|
140 continue |
1184 |
|
|
return |
1185 |
|
|
end |
1186 |
|
|
|
1187 |
|
|
c |
1188 |
|
|
subroutine cfode2(meth, elco, tesco) |
1189 |
|
|
c ==================================== |
1190 |
|
|
|
1191 |
|
|
c |
1192 |
|
|
c Chien Wang |
1193 |
|
|
c MIT |
1194 |
|
|
c 122695 |
1195 |
|
|
c |
1196 |
|
|
|
1197 |
|
|
integer meth |
1198 |
|
|
integer i, ib, nq, nqm1, nqp1 |
1199 |
|
|
real elco, tesco |
1200 |
|
|
real agamq, fnq, fnqm1, pc, pint, ragq, |
1201 |
|
|
1 rqfac, rq1fac, tsign, xpin |
1202 |
|
|
dimension elco(13,12), tesco(3,12) |
1203 |
|
|
dimension pc(12) |
1204 |
|
|
|
1205 |
|
|
pc(1) = 1.0e0 |
1206 |
|
|
rq1fac = 1.0e0 |
1207 |
|
|
do 230 nq = 1,5 |
1208 |
|
|
c----------------------------------------------------------------------- |
1209 |
|
|
c the pc array will contain the coefficients of the polynomial |
1210 |
|
|
c p(x) = (x+1)*(x+2)*...*(x+nq). |
1211 |
|
|
c initially, p(x) = 1. |
1212 |
|
|
c----------------------------------------------------------------------- |
1213 |
|
|
fnq = float(nq) |
1214 |
|
|
nqp1 = nq + 1 |
1215 |
|
|
c form coefficients of p(x)*(x+nq). ------------------------------------ |
1216 |
|
|
pc(nqp1) = 0.0e0 |
1217 |
|
|
do 210 ib = 1,nq |
1218 |
|
|
i = nq + 2 - ib |
1219 |
|
|
210 pc(i) = pc(i-1) + fnq*pc(i) |
1220 |
|
|
pc(1) = fnq*pc(1) |
1221 |
|
|
c store coefficients in elco and tesco. -------------------------------- |
1222 |
|
|
do 220 i = 1,nqp1 |
1223 |
|
|
220 elco(i,nq) = pc(i)/pc(2) |
1224 |
|
|
elco(2,nq) = 1.0e0 |
1225 |
|
|
tesco(1,nq) = rq1fac |
1226 |
|
|
tesco(2,nq) = float(nqp1)/elco(1,nq) |
1227 |
|
|
tesco(3,nq) = float(nq+2)/elco(1,nq) |
1228 |
|
|
rq1fac = rq1fac/fnq |
1229 |
|
|
230 continue |
1230 |
|
|
return |
1231 |
|
|
end |
1232 |
|
|
|
1233 |
|
|
c---- end of subroutine cfode and new cfode1 & cfode2 |
1234 |
|
|
|
1235 |
|
|
c================================================================ |
1236 |
|
|
c -- TC7 |
1237 |
|
|
c |
1238 |
|
|
subroutine sgefa(a,lda,n,ipvt,info) |
1239 |
|
|
c ================================== |
1240 |
|
|
|
1241 |
|
|
clll. optimize |
1242 |
|
|
integer lda,n,ipvt(*),info |
1243 |
|
|
real a(lda,*) |
1244 |
|
|
c |
1245 |
|
|
c sgefa factors a real matrix by gaussian elimination. |
1246 |
|
|
c |
1247 |
|
|
c sgefa is usually called by sgeco, but it can be called |
1248 |
|
|
c directly with a saving in time if rcond is not needed. |
1249 |
|
|
c (time for sgeco) = (1 + 9/n)*(time for sgefa) . |
1250 |
|
|
c |
1251 |
|
|
c on entry |
1252 |
|
|
c |
1253 |
|
|
c a real(lda, n) |
1254 |
|
|
c the matrix to be factored. |
1255 |
|
|
c |
1256 |
|
|
c lda integer |
1257 |
|
|
c the leading dimension of the array a . |
1258 |
|
|
c |
1259 |
|
|
c n integer |
1260 |
|
|
c the order of the matrix a . |
1261 |
|
|
c |
1262 |
|
|
c on return |
1263 |
|
|
c |
1264 |
|
|
c a an upper triangular matrix and the multipliers |
1265 |
|
|
c which were used to obtain it. |
1266 |
|
|
c the factorization can be written a = l*u where |
1267 |
|
|
c l is a product of permutation and unit lower |
1268 |
|
|
c triangular matrices and u is upper triangular. |
1269 |
|
|
c |
1270 |
|
|
c ipvt integer(n) |
1271 |
|
|
c an integer vector of pivot indices. |
1272 |
|
|
c |
1273 |
|
|
c info integer |
1274 |
|
|
c = 0 normal value. |
1275 |
|
|
c = k if u(k,k) .eq. 0.0 . this is not an error |
1276 |
|
|
c condition for this subroutine, but it does |
1277 |
|
|
c indicate that sgesl or sgedi will divide by zero |
1278 |
|
|
c if called. use rcond in sgeco for a reliable |
1279 |
|
|
c indication of singularity. |
1280 |
|
|
c |
1281 |
|
|
c linpack. this version dated 07/14/77 . |
1282 |
|
|
c cleve moler, university of new mexico, argonne national labs. |
1283 |
|
|
c |
1284 |
|
|
c subroutines and functions |
1285 |
|
|
c |
1286 |
|
|
c blas saxpy,sscal,isamax |
1287 |
|
|
c |
1288 |
|
|
c internal variables |
1289 |
|
|
c |
1290 |
|
|
real t |
1291 |
|
|
integer isamax,j,k,kp1,l,nm1 |
1292 |
|
|
c |
1293 |
|
|
c |
1294 |
|
|
c gaussian elimination with partial pivoting |
1295 |
|
|
c |
1296 |
|
|
info = 0 |
1297 |
|
|
nm1 = n - 1 |
1298 |
|
|
if (nm1 .lt. 1) go to 70 |
1299 |
|
|
do 60 k = 1, nm1 |
1300 |
|
|
kp1 = k + 1 |
1301 |
|
|
c |
1302 |
|
|
c find l = pivot index |
1303 |
|
|
c |
1304 |
|
|
l = isamax(n-k+1,a(k,k),1) + k - 1 |
1305 |
|
|
ipvt(k) = l |
1306 |
|
|
c |
1307 |
|
|
c zero pivot implies this column already triangularized |
1308 |
|
|
c |
1309 |
|
|
if (a(l,k) .eq. 0.0e0) go to 40 |
1310 |
|
|
c |
1311 |
|
|
c interchange if necessary |
1312 |
|
|
c |
1313 |
|
|
if (l .eq. k) go to 10 |
1314 |
|
|
t = a(l,k) |
1315 |
|
|
a(l,k) = a(k,k) |
1316 |
|
|
a(k,k) = t |
1317 |
|
|
10 continue |
1318 |
|
|
c |
1319 |
|
|
c compute multipliers |
1320 |
|
|
c |
1321 |
|
|
t = -1.0e0/a(k,k) |
1322 |
|
|
call sscal(n-k,t,a(k+1,k),1) |
1323 |
|
|
c |
1324 |
|
|
c row elimination with column indexing |
1325 |
|
|
c |
1326 |
|
|
do 30 j = kp1, n |
1327 |
|
|
t = a(l,j) |
1328 |
|
|
if (l .eq. k) go to 20 |
1329 |
|
|
a(l,j) = a(k,j) |
1330 |
|
|
a(k,j) = t |
1331 |
|
|
20 continue |
1332 |
|
|
call saxpysmp(n-k,t,a(k+1,k),a(k+1,j)) |
1333 |
|
|
30 continue |
1334 |
|
|
go to 50 |
1335 |
|
|
40 continue |
1336 |
|
|
info = k |
1337 |
|
|
50 continue |
1338 |
|
|
60 continue |
1339 |
|
|
70 continue |
1340 |
|
|
ipvt(n) = n |
1341 |
|
|
if (a(n,n) .eq. 0.0e0) info = n |
1342 |
|
|
return |
1343 |
|
|
end |
1344 |
|
|
|
1345 |
|
|
c=============================================================== |
1346 |
|
|
c -- TC8 |
1347 |
|
|
c |
1348 |
|
|
subroutine sgbfa(abd,lda,n,ml,mu,ipvt,info) |
1349 |
|
|
c =========================================== |
1350 |
|
|
|
1351 |
|
|
clll. optimize |
1352 |
|
|
integer lda,n,ml,mu,ipvt(*),info |
1353 |
|
|
real abd(lda,*) |
1354 |
|
|
c |
1355 |
|
|
c sgbfa factors a real band matrix by elimination. |
1356 |
|
|
c |
1357 |
|
|
c sgbfa is usually called by sgbco, but it can be called |
1358 |
|
|
c directly with a saving in time if rcond is not needed. |
1359 |
|
|
c |
1360 |
|
|
c on entry |
1361 |
|
|
c |
1362 |
|
|
c abd real(lda, n) |
1363 |
|
|
c contains the matrix in band storage. the columns |
1364 |
|
|
c of the matrix are stored in the columns of abd and |
1365 |
|
|
c the diagonals of the matrix are stored in rows |
1366 |
|
|
c ml+1 through 2*ml+mu+1 of abd . |
1367 |
|
|
c see the comments below for details. |
1368 |
|
|
c |
1369 |
|
|
c lda integer |
1370 |
|
|
c the leading dimension of the array abd . |
1371 |
|
|
c lda must be .ge. 2*ml + mu + 1 . |
1372 |
|
|
c |
1373 |
|
|
c n integer |
1374 |
|
|
c the order of the original matrix. |
1375 |
|
|
c |
1376 |
|
|
c ml integer |
1377 |
|
|
c number of diagonals below the main diagonal. |
1378 |
|
|
c 0 .le. ml .lt. n . |
1379 |
|
|
c |
1380 |
|
|
c mu integer |
1381 |
|
|
c number of diagonals above the main diagonal. |
1382 |
|
|
c 0 .le. mu .lt. n . |
1383 |
|
|
c more efficient if ml .le. mu . |
1384 |
|
|
c on return |
1385 |
|
|
c |
1386 |
|
|
c abd an upper triangular matrix in band storage and |
1387 |
|
|
c the multipliers which were used to obtain it. |
1388 |
|
|
c the factorization can be written a = l*u where |
1389 |
|
|
c l is a product of permutation and unit lower |
1390 |
|
|
c triangular matrices and u is upper triangular. |
1391 |
|
|
c |
1392 |
|
|
c ipvt integer(n) |
1393 |
|
|
c an integer vector of pivot indices. |
1394 |
|
|
c |
1395 |
|
|
c info integer |
1396 |
|
|
c = 0 normal value. |
1397 |
|
|
c = k if u(k,k) .eq. 0.0 . this is not an error |
1398 |
|
|
c condition for this subroutine, but it does |
1399 |
|
|
c indicate that sgbsl will divide by zero if |
1400 |
|
|
c called. use rcond in sgbco for a reliable |
1401 |
|
|
c indication of singularity. |
1402 |
|
|
c |
1403 |
|
|
c band storage |
1404 |
|
|
c |
1405 |
|
|
c if a is a band matrix, the following program segment |
1406 |
|
|
c will set up the input. |
1407 |
|
|
c |
1408 |
|
|
c ml = (band width below the diagonal) |
1409 |
|
|
c mu = (band width above the diagonal) |
1410 |
|
|
c m = ml + mu + 1 |
1411 |
|
|
c do 20 j = 1, n |
1412 |
|
|
c i1 = max0(1, j-mu) |
1413 |
|
|
c i2 = min0(n, j+ml) |
1414 |
|
|
c do 10 i = i1, i2 |
1415 |
|
|
c k = i - j + m |
1416 |
|
|
c abd(k,j) = a(i,j) |
1417 |
|
|
c 10 continue |
1418 |
|
|
c 20 continue |
1419 |
|
|
c |
1420 |
|
|
c this uses rows ml+1 through 2*ml+mu+1 of abd . |
1421 |
|
|
c in addition, the first ml rows in abd are used for |
1422 |
|
|
c elements generated during the triangularization. |
1423 |
|
|
c the total number of rows needed in abd is 2*ml+mu+1 . |
1424 |
|
|
c the ml+mu by ml+mu upper left triangle and the |
1425 |
|
|
c ml by ml lower right triangle are not referenced. |
1426 |
|
|
c |
1427 |
|
|
c linpack. this version dated 07/14/77 . |
1428 |
|
|
c cleve moler, university of new mexico, argonne national labs. |
1429 |
|
|
c |
1430 |
|
|
c subroutines and functions |
1431 |
|
|
c |
1432 |
|
|
c blas saxpy,sscal,isamax |
1433 |
|
|
c fortran max0,min0 |
1434 |
|
|
c |
1435 |
|
|
c internal variables |
1436 |
|
|
c |
1437 |
|
|
real t |
1438 |
|
|
integer i,isamax,i0,j,ju,jz,j0,j1,k,kp1,l,lm,m,mm,nm1 |
1439 |
|
|
c |
1440 |
|
|
c |
1441 |
|
|
m = ml + mu + 1 |
1442 |
|
|
info = 0 |
1443 |
|
|
c |
1444 |
|
|
c zero initial fill-in columns |
1445 |
|
|
c |
1446 |
|
|
j0 = mu + 2 |
1447 |
|
|
j1 = min0(n,m) - 1 |
1448 |
|
|
if (j1 .lt. j0) go to 30 |
1449 |
|
|
do 20 jz = j0, j1 |
1450 |
|
|
i0 = m + 1 - jz |
1451 |
|
|
do 10 i = i0, ml |
1452 |
|
|
abd(i,jz) = 0.0e0 |
1453 |
|
|
10 continue |
1454 |
|
|
20 continue |
1455 |
|
|
30 continue |
1456 |
|
|
jz = j1 |
1457 |
|
|
ju = 0 |
1458 |
|
|
c |
1459 |
|
|
c gaussian elimination with partial pivoting |
1460 |
|
|
c |
1461 |
|
|
nm1 = n - 1 |
1462 |
|
|
if (nm1 .lt. 1) go to 140 |
1463 |
|
|
do 130 k = 1, nm1 |
1464 |
|
|
kp1 = k + 1 |
1465 |
|
|
c |
1466 |
|
|
c zero next fill-in column |
1467 |
|
|
c |
1468 |
|
|
jz = jz + 1 |
1469 |
|
|
if (jz .gt. n) go to 60 |
1470 |
|
|
if (ml .lt. 1) go to 50 |
1471 |
|
|
do 40 i = 1, ml |
1472 |
|
|
abd(i,jz) = 0.0e0 |
1473 |
|
|
40 continue |
1474 |
|
|
50 continue |
1475 |
|
|
60 continue |
1476 |
|
|
c |
1477 |
|
|
c find l = pivot index |
1478 |
|
|
c |
1479 |
|
|
lm = min0(ml,n-k) |
1480 |
|
|
l = isamax(lm+1,abd(m,k),1) + m - 1 |
1481 |
|
|
ipvt(k) = l + k - m |
1482 |
|
|
c |
1483 |
|
|
c zero pivot implies this column already triangularized |
1484 |
|
|
c |
1485 |
|
|
if (abd(l,k) .eq. 0.0e0) go to 110 |
1486 |
|
|
c |
1487 |
|
|
c interchange if necessary |
1488 |
|
|
c |
1489 |
|
|
if (l .eq. m) go to 70 |
1490 |
|
|
t = abd(l,k) |
1491 |
|
|
abd(l,k) = abd(m,k) |
1492 |
|
|
abd(m,k) = t |
1493 |
|
|
70 continue |
1494 |
|
|
c |
1495 |
|
|
c compute multipliers |
1496 |
|
|
c |
1497 |
|
|
t = -1.0e0/abd(m,k) |
1498 |
|
|
call sscal(lm,t,abd(m+1,k),1) |
1499 |
|
|
c |
1500 |
|
|
c row elimination with column indexing |
1501 |
|
|
c |
1502 |
|
|
ju = min0(max0(ju,mu+ipvt(k)),n) |
1503 |
|
|
mm = m |
1504 |
|
|
if (ju .lt. kp1) go to 100 |
1505 |
|
|
do 90 j = kp1, ju |
1506 |
|
|
l = l - 1 |
1507 |
|
|
mm = mm - 1 |
1508 |
|
|
t = abd(l,j) |
1509 |
|
|
if (l .eq. mm) go to 80 |
1510 |
|
|
abd(l,j) = abd(mm,j) |
1511 |
|
|
abd(mm,j) = t |
1512 |
|
|
80 continue |
1513 |
|
|
call saxpysmp(lm,t,abd(m+1,k),abd(mm+1,j)) |
1514 |
|
|
90 continue |
1515 |
|
|
100 continue |
1516 |
|
|
go to 120 |
1517 |
|
|
110 continue |
1518 |
|
|
info = k |
1519 |
|
|
120 continue |
1520 |
|
|
130 continue |
1521 |
|
|
140 continue |
1522 |
|
|
ipvt(n) = n |
1523 |
|
|
if (abd(m,n) .eq. 0.0e0) info = n |
1524 |
|
|
return |
1525 |
|
|
end |
1526 |
|
|
|
1527 |
|
|
|
1528 |
|
|
c=========================================================== |
1529 |
|
|
c -- TC9 |
1530 |
|
|
c |
1531 |
|
|
subroutine sgesl(a,lda,n,ipvt,b,job) |
1532 |
|
|
c =================================== |
1533 |
|
|
|
1534 |
|
|
clll. optimize |
1535 |
|
|
integer lda,n,ipvt(*),job |
1536 |
|
|
real a(lda,*),b(*) |
1537 |
|
|
c |
1538 |
|
|
c sgesl solves the real system |
1539 |
|
|
c a * x = b or trans(a) * x = b |
1540 |
|
|
c using the factors computed by sgeco or sgefa. |
1541 |
|
|
c |
1542 |
|
|
c on entry |
1543 |
|
|
c |
1544 |
|
|
c a real(lda, n) |
1545 |
|
|
c the output from sgeco or sgefa. |
1546 |
|
|
c |
1547 |
|
|
c lda integer |
1548 |
|
|
c the leading dimension of the array a . |
1549 |
|
|
c |
1550 |
|
|
c n integer |
1551 |
|
|
c the order of the matrix a . |
1552 |
|
|
c |
1553 |
|
|
c ipvt integer(n) |
1554 |
|
|
c the pivot vector from sgeco or sgefa. |
1555 |
|
|
c |
1556 |
|
|
c b real(n) |
1557 |
|
|
c the right hand side vector. |
1558 |
|
|
c |
1559 |
|
|
c job integer |
1560 |
|
|
c = 0 to solve a*x = b , |
1561 |
|
|
c = nonzero to solve trans(a)*x = b where |
1562 |
|
|
c trans(a) is the transpose. |
1563 |
|
|
c |
1564 |
|
|
c on return |
1565 |
|
|
c |
1566 |
|
|
c b the solution vector x . |
1567 |
|
|
c |
1568 |
|
|
c error condition |
1569 |
|
|
c |
1570 |
|
|
c a division by zero will occur if the input factor contains a |
1571 |
|
|
c zero on the diagonal. technically this indicates singularity |
1572 |
|
|
c but it is often caused by improper arguments or improper |
1573 |
|
|
c setting of lda . it will not occur if the subroutines are |
1574 |
|
|
c called correctly and if sgeco has set rcond .gt. 0.0 |
1575 |
|
|
c or sgefa has set info .eq. 0 . |
1576 |
|
|
c |
1577 |
|
|
c to compute inverse(a) * c where c is a matrix |
1578 |
|
|
c with p columns |
1579 |
|
|
c call sgeco(a,lda,n,ipvt,rcond,z) |
1580 |
|
|
c if (rcond is too small) go to ... |
1581 |
|
|
c do 10 j = 1, p |
1582 |
|
|
c call sgesl(a,lda,n,ipvt,c(1,j),0) |
1583 |
|
|
c 10 continue |
1584 |
|
|
c |
1585 |
|
|
c linpack. this version dated 07/14/77 . |
1586 |
|
|
c cleve moler, university of new mexico, argonne national labs. |
1587 |
|
|
c |
1588 |
|
|
c subroutines and functions |
1589 |
|
|
c |
1590 |
|
|
c blas saxpy,sdot |
1591 |
|
|
c |
1592 |
|
|
c internal variables |
1593 |
|
|
c |
1594 |
|
|
real sdot,t |
1595 |
|
|
integer k,kb,l,nm1 |
1596 |
|
|
c |
1597 |
|
|
nm1 = n - 1 |
1598 |
|
|
if (job .ne. 0) go to 50 |
1599 |
|
|
c |
1600 |
|
|
c job = 0 , solve a * x = b |
1601 |
|
|
c first solve l*y = b |
1602 |
|
|
c |
1603 |
|
|
if (nm1 .lt. 1) go to 30 |
1604 |
|
|
do 20 k = 1, nm1 |
1605 |
|
|
l = ipvt(k) |
1606 |
|
|
t = b(l) |
1607 |
|
|
if (l .eq. k) go to 10 |
1608 |
|
|
b(l) = b(k) |
1609 |
|
|
b(k) = t |
1610 |
|
|
10 continue |
1611 |
|
|
call saxpysmp(n-k,t,a(k+1,k),b(k+1)) |
1612 |
|
|
20 continue |
1613 |
|
|
30 continue |
1614 |
|
|
c |
1615 |
|
|
c now solve u*x = y |
1616 |
|
|
c |
1617 |
|
|
do 40 kb = 1, n |
1618 |
|
|
k = n + 1 - kb |
1619 |
|
|
b(k) = b(k)/a(k,k) |
1620 |
|
|
t = -b(k) |
1621 |
|
|
call saxpysmp(k-1,t,a(1,k),b(1)) |
1622 |
|
|
40 continue |
1623 |
|
|
go to 100 |
1624 |
|
|
50 continue |
1625 |
|
|
c |
1626 |
|
|
c job = nonzero, solve trans(a) * x = b |
1627 |
|
|
c first solve trans(u)*y = b |
1628 |
|
|
c |
1629 |
|
|
do 60 k = 1, n |
1630 |
|
|
t = sdot(k-1,a(1,k),1,b(1),1) |
1631 |
|
|
b(k) = (b(k) - t)/a(k,k) |
1632 |
|
|
60 continue |
1633 |
|
|
c |
1634 |
|
|
c now solve trans(l)*x = y |
1635 |
|
|
c |
1636 |
|
|
if (nm1 .lt. 1) go to 90 |
1637 |
|
|
do 80 kb = 1, nm1 |
1638 |
|
|
k = n - kb |
1639 |
|
|
b(k) = b(k) + sdot(n-k,a(k+1,k),1,b(k+1),1) |
1640 |
|
|
l = ipvt(k) |
1641 |
|
|
if (l .eq. k) go to 70 |
1642 |
|
|
t = b(l) |
1643 |
|
|
b(l) = b(k) |
1644 |
|
|
b(k) = t |
1645 |
|
|
70 continue |
1646 |
|
|
80 continue |
1647 |
|
|
90 continue |
1648 |
|
|
100 continue |
1649 |
|
|
return |
1650 |
|
|
end |
1651 |
|
|
|
1652 |
|
|
|
1653 |
|
|
c============================================================ |
1654 |
|
|
c -- TC10 |
1655 |
|
|
c |
1656 |
|
|
subroutine sgbsl(abd,lda,n,ml,mu,ipvt,b,job) |
1657 |
|
|
c =========================================== |
1658 |
|
|
|
1659 |
|
|
clll. optimize |
1660 |
|
|
integer lda,n,ml,mu,ipvt(*),job |
1661 |
|
|
real abd(lda,*),b(*) |
1662 |
|
|
c |
1663 |
|
|
c sgbsl solves the real band system |
1664 |
|
|
c a * x = b or trans(a) * x = b |
1665 |
|
|
c using the factors computed by sgbco or sgbfa. |
1666 |
|
|
c |
1667 |
|
|
c on entry |
1668 |
|
|
c |
1669 |
|
|
c abd real(lda, n) |
1670 |
|
|
c the output from sgbco or sgbfa. |
1671 |
|
|
c |
1672 |
|
|
c lda integer |
1673 |
|
|
c the leading dimension of the array abd . |
1674 |
|
|
c |
1675 |
|
|
c n integer |
1676 |
|
|
c the order of the original matrix. |
1677 |
|
|
c |
1678 |
|
|
c ml integer |
1679 |
|
|
c number of diagonals below the main diagonal. |
1680 |
|
|
c |
1681 |
|
|
c mu integer |
1682 |
|
|
c number of diagonals above the main diagonal. |
1683 |
|
|
c |
1684 |
|
|
c ipvt integer(n) |
1685 |
|
|
c the pivot vector from sgbco or sgbfa. |
1686 |
|
|
c |
1687 |
|
|
c b real(n) |
1688 |
|
|
c the right hand side vector. |
1689 |
|
|
c |
1690 |
|
|
c job integer |
1691 |
|
|
c = 0 to solve a*x = b , |
1692 |
|
|
c = nonzero to solve trans(a)*x = b , where |
1693 |
|
|
c trans(a) is the transpose. |
1694 |
|
|
c |
1695 |
|
|
c on return |
1696 |
|
|
c |
1697 |
|
|
c b the solution vector x . |
1698 |
|
|
c |
1699 |
|
|
c error condition |
1700 |
|
|
c |
1701 |
|
|
c a division by zero will occur if the input factor contains a |
1702 |
|
|
c zero on the diagonal. technically this indicates singularity |
1703 |
|
|
c but it is often caused by improper arguments or improper |
1704 |
|
|
c setting of lda . it will not occur if the subroutines are |
1705 |
|
|
c called correctly and if sgbco has set rcond .gt. 0.0 |
1706 |
|
|
c or sgbfa has set info .eq. 0 . |
1707 |
|
|
c |
1708 |
|
|
c to compute inverse(a) * c where c is a matrix |
1709 |
|
|
c with p columns |
1710 |
|
|
c call sgbco(abd,lda,n,ml,mu,ipvt,rcond,z) |
1711 |
|
|
c if (rcond is too small) go to ... |
1712 |
|
|
c do 10 j = 1, p |
1713 |
|
|
c call sgbsl(abd,lda,n,ml,mu,ipvt,c(1,j),0) |
1714 |
|
|
c 10 continue |
1715 |
|
|
c |
1716 |
|
|
c linpack. this version dated 07/14/77 . |
1717 |
|
|
c cleve moler, university of new mexico, argonne national labs. |
1718 |
|
|
c |
1719 |
|
|
c subroutines and functions |
1720 |
|
|
c |
1721 |
|
|
c blas saxpy,sdot |
1722 |
|
|
c fortran min0 |
1723 |
|
|
c |
1724 |
|
|
c internal variables |
1725 |
|
|
c |
1726 |
|
|
real sdot,t |
1727 |
|
|
integer k,kb,l,la,lb,lm,m,nm1 |
1728 |
|
|
c |
1729 |
|
|
m = mu + ml + 1 |
1730 |
|
|
nm1 = n - 1 |
1731 |
|
|
if (job .ne. 0) go to 60 |
1732 |
|
|
c |
1733 |
|
|
c job = 0 , solve a * x = b |
1734 |
|
|
c first solve l*y = b |
1735 |
|
|
c |
1736 |
|
|
if (ml .eq. 0) go to 40 |
1737 |
|
|
if (nm1 .lt. 1) go to 30 |
1738 |
|
|
do 20 k = 1, nm1 |
1739 |
|
|
lm = min0(ml,n-k) |
1740 |
|
|
l = ipvt(k) |
1741 |
|
|
t = b(l) |
1742 |
|
|
if (l .eq. k) go to 10 |
1743 |
|
|
b(l) = b(k) |
1744 |
|
|
b(k) = t |
1745 |
|
|
10 continue |
1746 |
|
|
call saxpysmp(lm,t,abd(m+1,k),b(k+1)) |
1747 |
|
|
20 continue |
1748 |
|
|
30 continue |
1749 |
|
|
40 continue |
1750 |
|
|
c |
1751 |
|
|
c now solve u*x = y |
1752 |
|
|
c |
1753 |
|
|
do 50 kb = 1, n |
1754 |
|
|
k = n + 1 - kb |
1755 |
|
|
b(k) = b(k)/abd(m,k) |
1756 |
|
|
lm = min0(k,m) - 1 |
1757 |
|
|
la = m - lm |
1758 |
|
|
lb = k - lm |
1759 |
|
|
t = -b(k) |
1760 |
|
|
call saxpysmp(lm,t,abd(la,k),b(lb)) |
1761 |
|
|
50 continue |
1762 |
|
|
go to 120 |
1763 |
|
|
60 continue |
1764 |
|
|
c |
1765 |
|
|
c job = nonzero, solve trans(a) * x = b |
1766 |
|
|
c first solve trans(u)*y = b |
1767 |
|
|
c |
1768 |
|
|
do 70 k = 1, n |
1769 |
|
|
lm = min0(k,m) - 1 |
1770 |
|
|
la = m - lm |
1771 |
|
|
lb = k - lm |
1772 |
|
|
t = sdot(lm,abd(la,k),1,b(lb),1) |
1773 |
|
|
b(k) = (b(k) - t)/abd(m,k) |
1774 |
|
|
70 continue |
1775 |
|
|
c |
1776 |
|
|
c now solve trans(l)*x = y |
1777 |
|
|
c |
1778 |
|
|
if (ml .eq. 0) go to 110 |
1779 |
|
|
if (nm1 .lt. 1) go to 100 |
1780 |
|
|
do 90 kb = 1, nm1 |
1781 |
|
|
k = n - kb |
1782 |
|
|
lm = min0(ml,n-k) |
1783 |
|
|
b(k) = b(k) + sdot(lm,abd(m+1,k),1,b(k+1),1) |
1784 |
|
|
l = ipvt(k) |
1785 |
|
|
if (l .eq. k) go to 80 |
1786 |
|
|
t = b(l) |
1787 |
|
|
b(l) = b(k) |
1788 |
|
|
b(k) = t |
1789 |
|
|
80 continue |
1790 |
|
|
90 continue |
1791 |
|
|
100 continue |
1792 |
|
|
110 continue |
1793 |
|
|
120 continue |
1794 |
|
|
return |
1795 |
|
|
end |
1796 |
|
|
|
1797 |
|
|
|
1798 |
|
|
c======================================================== |
1799 |
|
|
c -- TC11 |
1800 |
|
|
c |
1801 |
|
|
subroutine sscal(n,sa,sx,incx) |
1802 |
|
|
c ============================= |
1803 |
|
|
|
1804 |
|
|
clll. optimize |
1805 |
|
|
c |
1806 |
|
|
c scales a vector by a constant. |
1807 |
|
|
c uses unrolled loops for increment equal to 1. |
1808 |
|
|
c jack dongarra, linpack, 6/17/77. |
1809 |
|
|
c |
1810 |
|
|
real sa,sx(*) |
1811 |
|
|
integer i,incx,m,mp1,n,nincx |
1812 |
|
|
c |
1813 |
|
|
if(n.le.0)return |
1814 |
|
|
if(incx.eq.1)go to 20 |
1815 |
|
|
c |
1816 |
|
|
c code for increment not equal to 1 |
1817 |
|
|
c |
1818 |
|
|
nincx = n*incx |
1819 |
|
|
do 10 i = 1,nincx,incx |
1820 |
|
|
sx(i) = sa*sx(i) |
1821 |
|
|
10 continue |
1822 |
|
|
return |
1823 |
|
|
c |
1824 |
|
|
c code for increment equal to 1 |
1825 |
|
|
c |
1826 |
|
|
c |
1827 |
|
|
c clean-up loop |
1828 |
|
|
c |
1829 |
|
|
20 m = mod(n,5) |
1830 |
|
|
if( m .eq. 0 ) go to 40 |
1831 |
|
|
do 30 i = 1,m |
1832 |
|
|
sx(i) = sa*sx(i) |
1833 |
|
|
30 continue |
1834 |
|
|
if( n .lt. 5 ) return |
1835 |
|
|
40 mp1 = m + 1 |
1836 |
|
|
do 50 i = mp1,n,5 |
1837 |
|
|
sx(i) = sa*sx(i) |
1838 |
|
|
sx(i + 1) = sa*sx(i + 1) |
1839 |
|
|
sx(i + 2) = sa*sx(i + 2) |
1840 |
|
|
sx(i + 3) = sa*sx(i + 3) |
1841 |
|
|
sx(i + 4) = sa*sx(i + 4) |
1842 |
|
|
50 continue |
1843 |
|
|
return |
1844 |
|
|
end |
1845 |
|
|
|
1846 |
|
|
|
1847 |
|
|
c===================================================== |
1848 |
|
|
c -- TC12 |
1849 |
|
|
c |
1850 |
|
|
subroutine saxpysmp(n,sa,sx,sy) |
1851 |
|
|
c ===================================== |
1852 |
|
|
|
1853 |
|
|
c===================================================== |
1854 |
|
|
c saxpysmp: a simplified version of saxpy with |
1855 |
|
|
c incx = incy = 1 |
1856 |
|
|
c --------------------------------------------- |
1857 |
|
|
c Chien Wang |
1858 |
|
|
c MIT |
1859 |
|
|
c |
1860 |
|
|
c Creates: 010795 |
1861 |
|
|
c===================================================== |
1862 |
|
|
|
1863 |
|
|
clll. optimize |
1864 |
|
|
c |
1865 |
|
|
c constant times a vector plus a vector. |
1866 |
|
|
c uses unrolled loop for increments equal to one. |
1867 |
|
|
c jack dongarra, linpack, 6/17/77. |
1868 |
|
|
c |
1869 |
|
|
real sx(*),sy(*),sa |
1870 |
|
|
integer i,ix,iy,m,mp1,n |
1871 |
|
|
c |
1872 |
|
|
if(n.le.0)return |
1873 |
|
|
if (sa .eq. 0.0) return |
1874 |
|
|
c |
1875 |
|
|
c code for both increments equal to 1 |
1876 |
|
|
c |
1877 |
|
|
c |
1878 |
|
|
c clean-up loop |
1879 |
|
|
c |
1880 |
|
|
m = mod(n,4) |
1881 |
|
|
if( m .eq. 0 ) go to 40 |
1882 |
|
|
do 30 i = 1,m |
1883 |
|
|
sy(i) = sy(i) + sa*sx(i) |
1884 |
|
|
30 continue |
1885 |
|
|
if( n .lt. 4 ) return |
1886 |
|
|
40 mp1 = m + 1 |
1887 |
|
|
do 50 i = mp1,n,4 |
1888 |
|
|
sy(i) = sy(i) + sa*sx(i) |
1889 |
|
|
sy(i + 1) = sy(i + 1) + sa*sx(i + 1) |
1890 |
|
|
sy(i + 2) = sy(i + 2) + sa*sx(i + 2) |
1891 |
|
|
sy(i + 3) = sy(i + 3) + sa*sx(i + 3) |
1892 |
|
|
50 continue |
1893 |
|
|
return |
1894 |
|
|
end |
1895 |
|
|
|
1896 |
|
|
|
1897 |
|
|
c======================================================================= |
1898 |
|
|
c -- TC13 |
1899 |
|
|
c |
1900 |
|
|
subroutine xerrwv (msg, nmes, nerr, level, ni, i1, i2, nr, r1, r2) |
1901 |
|
|
c ================================================================== |
1902 |
|
|
|
1903 |
|
|
integer msg, nmes, nerr, level, ni, i1, i2, nr, |
1904 |
|
|
1 i, lun, lunit, mesflg, ncpw, nch, nwds |
1905 |
|
|
real r1, r2 |
1906 |
|
|
dimension msg(nmes) |
1907 |
|
|
c----------------------------------------------------------------------- |
1908 |
|
|
c subroutines xerrwv, xsetf, and xsetun, as given here, constitute |
1909 |
|
|
c a simplified version of the slatec error handling package. |
1910 |
|
|
c written by a. c. hindmarsh at llnl. version of march 30, 1987. |
1911 |
|
|
c |
1912 |
|
|
c all arguments are input arguments. |
1913 |
|
|
c |
1914 |
|
|
c msg = the message (hollerith literal or integer array). |
1915 |
|
|
c nmes = the length of msg (number of characters). |
1916 |
|
|
c nerr = the error number (not used). |
1917 |
|
|
c level = the error level.. |
1918 |
|
|
c 0 or 1 means recoverable (control returns to caller). |
1919 |
|
|
c 2 means fatal (run is aborted--see note below). |
1920 |
|
|
c ni = number of integers (0, 1, or 2) to be printed with message. |
1921 |
|
|
c i1,i2 = integers to be printed, depending on ni. |
1922 |
|
|
c nr = number of reals (0, 1, or 2) to be printed with message. |
1923 |
|
|
c r1,r2 = reals to be printed, depending on nr. |
1924 |
|
|
c |
1925 |
|
|
c note.. this routine is machine-dependent and specialized for use |
1926 |
|
|
c in limited context, in the following ways.. |
1927 |
|
|
c 1. the number of hollerith characters stored per word, denoted |
1928 |
|
|
c by ncpw below, is a data-loaded constant. |
1929 |
|
|
c 2. the value of nmes is assumed to be at most 60. |
1930 |
|
|
c (multi-line messages are generated by repeated calls.) |
1931 |
|
|
c 3. if level = 2, control passes to the statement stop |
1932 |
|
|
c to abort the run. this statement may be machine-dependent. |
1933 |
|
|
c 4. r1 and r2 are assumed to be in single precision and are printed |
1934 |
|
|
c in e21.13 format. |
1935 |
|
|
c 5. the common block /eh0001/ below is data-loaded (a machine- |
1936 |
|
|
c dependent feature) with default values. |
1937 |
|
|
c this block is needed for proper retention of parameters used by |
1938 |
|
|
c this routine which the user can reset by calling xsetf or xsetun. |
1939 |
|
|
c the variables in this block are as follows.. |
1940 |
|
|
c mesflg = print control flag.. |
1941 |
|
|
c 1 means print all messages (the default). |
1942 |
|
|
c 0 means no printing. |
1943 |
|
|
c lunit = logical unit number for messages. |
1944 |
|
|
c the default is 6 (machine-dependent). |
1945 |
|
|
c----------------------------------------------------------------------- |
1946 |
|
|
c the following are instructions for installing this routine |
1947 |
|
|
c in different machine environments. |
1948 |
|
|
c |
1949 |
|
|
c to change the default output unit, change the data statement below. |
1950 |
|
|
c |
1951 |
|
|
c for some systems, the data statement below must be replaced |
1952 |
|
|
c by a separate block data subprogram. |
1953 |
|
|
c |
1954 |
|
|
c for a different number of characters per word, change the |
1955 |
|
|
c data statement setting ncpw below, and format 10. alternatives for |
1956 |
|
|
c various computers are shown in comment cards. |
1957 |
|
|
c |
1958 |
|
|
c for a different run-abort command, change the statement following |
1959 |
|
|
c statement 100 at the end. |
1960 |
|
|
c----------------------------------------------------------------------- |
1961 |
|
|
common /eh0001/ mesflg, lunit |
1962 |
|
|
c |
1963 |
|
|
data mesflg/1/, lunit/6/ |
1964 |
|
|
c----------------------------------------------------------------------- |
1965 |
|
|
c the following data-loaded value of ncpw is valid for the cdc-6600 |
1966 |
|
|
c and cdc-7600 computers. |
1967 |
|
|
c data ncpw/10/ |
1968 |
|
|
c the following is valid for the cray-1 computer. |
1969 |
|
|
data ncpw/8/ |
1970 |
|
|
c the following is valid for the burroughs 6700 and 7800 computers. |
1971 |
|
|
c data ncpw/6/ |
1972 |
|
|
c the following is valid for the pdp-10 computer. |
1973 |
|
|
c data ncpw/5/ |
1974 |
|
|
c the following is valid for the vax computer with 4 bytes per integer, |
1975 |
|
|
c and for the ibm-360, ibm-370, ibm-303x, and ibm-43xx computers. |
1976 |
|
|
c data ncpw/4/ |
1977 |
|
|
c the following is valid for the pdp-11, or vax with 2-byte integers. |
1978 |
|
|
c data ncpw/2/ |
1979 |
|
|
c----------------------------------------------------------------------- |
1980 |
|
|
c |
1981 |
|
|
if (mesflg .eq. 0) go to 100 |
1982 |
|
|
c get logical unit number. --------------------------------------------- |
1983 |
|
|
lun = lunit |
1984 |
|
|
c get number of words in message. -------------------------------------- |
1985 |
|
|
nch = min0(nmes,60) |
1986 |
|
|
nwds = nch/ncpw |
1987 |
|
|
if (nch .ne. nwds*ncpw) nwds = nwds + 1 |
1988 |
|
|
c write the message. --------------------------------------------------- |
1989 |
|
|
write (lun, 10) (msg(i),i=1,nwds) |
1990 |
|
|
c----------------------------------------------------------------------- |
1991 |
|
|
c the following format statement is to have the form |
1992 |
|
|
c 10 format(1x,mmann) |
1993 |
|
|
c where nn = ncpw and mm is the smallest integer .ge. 60/ncpw. |
1994 |
|
|
c the following is valid for ncpw = 10. |
1995 |
|
|
c 10 format(1x,6a10) |
1996 |
|
|
c the following is valid for ncpw = 8. |
1997 |
|
|
10 format(1x,8a8) |
1998 |
|
|
c the following is valid for ncpw = 6. |
1999 |
|
|
c 10 format(1x,10a6) |
2000 |
|
|
c the following is valid for ncpw = 5. |
2001 |
|
|
c 10 format(1x,12a5) |
2002 |
|
|
c the following is valid for ncpw = 4. |
2003 |
|
|
c 10 format(1x,15a4) |
2004 |
|
|
c the following is valid for ncpw = 2. |
2005 |
|
|
c 10 format(1x,30a2) |
2006 |
|
|
c----------------------------------------------------------------------- |
2007 |
|
|
if (ni .eq. 1) write (lun, 20) i1 |
2008 |
|
|
20 format(6x,"in above message, i1 =",i10) |
2009 |
|
|
if (ni .eq. 2) write (lun, 30) i1,i2 |
2010 |
|
|
30 format(6x,"in above message, i1 =",i10,3x,"i2 =",i10) |
2011 |
|
|
if (nr .eq. 1) write (lun, 40) r1 |
2012 |
|
|
40 format(6x,"in above message, r1 =",e21.13) |
2013 |
|
|
if (nr .eq. 2) write (lun, 50) r1,r2 |
2014 |
|
|
50 format(6x,"in above, r1 =",e21.13,3x,"r2 =",e21.13) |
2015 |
|
|
c abort the run if level = 2. ------------------------------------------ |
2016 |
|
|
100 if (level .ne. 2) return |
2017 |
|
|
stop |
2018 |
|
|
c----------------------- end of subroutine xerrwv ---------------------- |
2019 |
|
|
end |
2020 |
|
|
|
2021 |
|
|
|
2022 |
|
|
c============================================================= |
2023 |
|
|
c -- TC14 |
2024 |
|
|
c |
2025 |
|
|
real function r1mach (idum) |
2026 |
|
|
c =========================== |
2027 |
|
|
|
2028 |
|
|
integer idum |
2029 |
|
|
c----------------------------------------------------------------------- |
2030 |
|
|
c this routine computes the unit roundoff of the machine. |
2031 |
|
|
c this is defined as the smallest positive machine number |
2032 |
|
|
c u such that 1.0 + u .ne. 1.0 |
2033 |
|
|
c----------------------------------------------------------------------- |
2034 |
|
|
real u, comp |
2035 |
|
|
u = 1.0e0 |
2036 |
|
|
10 u = u*0.5e0 |
2037 |
|
|
comp = 1.0e0 + u |
2038 |
|
|
if (comp .ne. 1.0e0) go to 10 |
2039 |
|
|
r1mach = u*2.0e0 |
2040 |
|
|
return |
2041 |
|
|
c----------------------- end of function r1mach ------------------------ |
2042 |
|
|
end |
2043 |
|
|
|
2044 |
|
|
|
2045 |
|
|
c======================================================== |
2046 |
|
|
c -- TC15 |
2047 |
|
|
c |
2048 |
|
|
real function vnorm (n, v, w) |
2049 |
|
|
c ============================ |
2050 |
|
|
|
2051 |
|
|
clll. optimize |
2052 |
|
|
c----------------------------------------------------------------------- |
2053 |
|
|
c this function routine computes the weighted root-mean-square norm |
2054 |
|
|
c of the vector of length n contained in the array v, with weights |
2055 |
|
|
c contained in the array w of length n.. |
2056 |
|
|
c vnorm = sqrt( (1/n) * sum( v(i)*w(i) )**2 ) |
2057 |
|
|
c----------------------------------------------------------------------- |
2058 |
|
|
integer n, i |
2059 |
|
|
real v, w, sum |
2060 |
|
|
dimension v(n), w(n) |
2061 |
|
|
sum = 0.0e0 |
2062 |
|
|
do 10 i = 1,n |
2063 |
|
|
10 sum = sum + (v(i)*w(i))**2 |
2064 |
|
|
vnorm = sqrt(sum/float(n)) |
2065 |
|
|
return |
2066 |
|
|
c----------------------- end of function vnorm ------------------------- |
2067 |
|
|
end |
2068 |
|
|
|
2069 |
|
|
|
2070 |
|
|
c========================================================= |
2071 |
|
|
c -- TC16 |
2072 |
|
|
c |
2073 |
|
|
integer function isamax(n,sx,incx) |
2074 |
|
|
c ================================= |
2075 |
|
|
|
2076 |
|
|
clll. optimize |
2077 |
|
|
c |
2078 |
|
|
c finds the index of element having max. absolute value. |
2079 |
|
|
c jack dongarra, linpack, 6/17/77. |
2080 |
|
|
c |
2081 |
|
|
real sx(*),smax |
2082 |
|
|
integer i,incx,ix,n |
2083 |
|
|
c |
2084 |
|
|
isamax = 1 |
2085 |
|
|
if(n.le.1)return |
2086 |
|
|
if(incx.eq.1)go to 20 |
2087 |
|
|
c |
2088 |
|
|
c code for increment not equal to 1 |
2089 |
|
|
c |
2090 |
|
|
ix = 1 |
2091 |
|
|
smax = abs(sx(1)) |
2092 |
|
|
ix = ix + incx |
2093 |
|
|
do 10 i = 2,n |
2094 |
|
|
if(abs(sx(ix)).le.smax) go to 5 |
2095 |
|
|
isamax = i |
2096 |
|
|
smax = abs(sx(ix)) |
2097 |
|
|
5 ix = ix + incx |
2098 |
|
|
10 continue |
2099 |
|
|
return |
2100 |
|
|
c |
2101 |
|
|
c code for increment equal to 1 |
2102 |
|
|
c |
2103 |
|
|
20 smax = abs(sx(1)) |
2104 |
|
|
do 30 i = 2,n |
2105 |
|
|
if(abs(sx(i)).le.smax) go to 30 |
2106 |
|
|
isamax = i |
2107 |
|
|
smax = abs(sx(i)) |
2108 |
|
|
30 continue |
2109 |
|
|
return |
2110 |
|
|
end |
2111 |
|
|
|
2112 |
|
|
|
2113 |
|
|
c======================================================= |
2114 |
|
|
c -- TC17 |
2115 |
|
|
c |
2116 |
|
|
real function sdot(n,sx,incx,sy,incy) |
2117 |
|
|
c ===================================== |
2118 |
|
|
|
2119 |
|
|
clll. optimize |
2120 |
|
|
c |
2121 |
|
|
c forms the dot product of a vector. |
2122 |
|
|
c uses unrolled loops for increments equal to one. |
2123 |
|
|
c jack dongarra, linpack, 6/17/77. |
2124 |
|
|
c |
2125 |
|
|
real sx(*),sy(*),stemp |
2126 |
|
|
integer i,incx,incy,ix,iy,m,mp1,n |
2127 |
|
|
c |
2128 |
|
|
stemp = 0.0e0 |
2129 |
|
|
sdot = 0.0e0 |
2130 |
|
|
if(n.le.0)return |
2131 |
|
|
if(incx.eq.1.and.incy.eq.1)go to 20 |
2132 |
|
|
c |
2133 |
|
|
c code for unequal increments or equal increments |
2134 |
|
|
c not equal to 1 |
2135 |
|
|
c |
2136 |
|
|
ix = 1 |
2137 |
|
|
iy = 1 |
2138 |
|
|
if(incx.lt.0)ix = (-n+1)*incx + 1 |
2139 |
|
|
if(incy.lt.0)iy = (-n+1)*incy + 1 |
2140 |
|
|
do 10 i = 1,n |
2141 |
|
|
stemp = stemp + sx(ix)*sy(iy) |
2142 |
|
|
ix = ix + incx |
2143 |
|
|
iy = iy + incy |
2144 |
|
|
10 continue |
2145 |
|
|
sdot = stemp |
2146 |
|
|
return |
2147 |
|
|
c |
2148 |
|
|
c code for both increments equal to 1 |
2149 |
|
|
c |
2150 |
|
|
c |
2151 |
|
|
c clean-up loop |
2152 |
|
|
c |
2153 |
|
|
20 m = mod(n,5) |
2154 |
|
|
if( m .eq. 0 ) go to 40 |
2155 |
|
|
do 30 i = 1,m |
2156 |
|
|
stemp = stemp + sx(i)*sy(i) |
2157 |
|
|
30 continue |
2158 |
|
|
if( n .lt. 5 ) go to 60 |
2159 |
|
|
40 mp1 = m + 1 |
2160 |
|
|
do 50 i = mp1,n,5 |
2161 |
|
|
stemp = stemp + sx(i)*sy(i) + sx(i + 1)*sy(i + 1) + |
2162 |
|
|
* sx(i + 2)*sy(i + 2) + sx(i + 3)*sy(i + 3) + sx(i + 4)*sy(i + 4) |
2163 |
|
|
50 continue |
2164 |
|
|
60 sdot = stemp |
2165 |
|
|
return |
2166 |
|
|
end |
2167 |
|
|
|
2168 |
|
|
|
2169 |
|
|
c================================================================ |
2170 |
|
|
c -- TC18 |
2171 |
|
|
c |
2172 |
|
|
subroutine prepj (neq, y, yh, nyh, ewt, ftem, savf, wm, iwm, |
2173 |
|
|
1 f, jac) |
2174 |
|
|
c =========================================================== |
2175 |
|
|
|
2176 |
|
|
clll. optimize |
2177 |
|
|
external f, jac |
2178 |
|
|
integer neq, nyh, iwm |
2179 |
|
|
integer iownd, iowns, |
2180 |
|
|
1 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
2181 |
|
|
2 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
2182 |
|
|
integer i, i1, i2, ier, ii, j, j1, jj, lenp, |
2183 |
|
|
1 mba, mband, meb1, meband, ml, ml3, mu, np1 |
2184 |
|
|
real y, yh, ewt, ftem, savf, wm |
2185 |
|
|
real rowns, |
2186 |
|
|
1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround |
2187 |
|
|
real con, di, fac, hl0, r, r0, srur, yi, yj, yjj, |
2188 |
|
|
1 vnorm |
2189 |
|
|
dimension neq(*), y(*), yh(nyh,*), ewt(*), ftem(*), savf(*), |
2190 |
|
|
1 wm(*), iwm(*) |
2191 |
|
|
common /ls0001/ rowns(209), |
2192 |
|
|
2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround, |
2193 |
|
|
3 iownd(14), iowns(6), |
2194 |
|
|
4 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter, |
2195 |
|
|
5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu |
2196 |
|
|
c----------------------------------------------------------------------- |
2197 |
|
|
c prepj is called by stode to compute and process the matrix |
2198 |
|
|
c p = i - h*el(1)*j , where j is an approximation to the jacobian. |
2199 |
|
|
c here j is computed by the user-supplied routine jac if |
2200 |
|
|
c miter = 1 or 4, or by finite differencing if miter = 2, 3, or 5. |
2201 |
|
|
c if miter = 3, a diagonal approximation to j is used. |
2202 |
|
|
c j is stored in wm and replaced by p. if miter .ne. 3, p is then |
2203 |
|
|
c subjected to lu decomposition in preparation for later solution |
2204 |
|
|
c of linear systems with p as coefficient matrix. this is done |
2205 |
|
|
c by sgefa if miter = 1 or 2, and by sgbfa if miter = 4 or 5. |
2206 |
|
|
c |
2207 |
|
|
c in addition to variables described previously, communication |
2208 |
|
|
c with prepj uses the following.. |
2209 |
|
|
c y = array containing predicted values on entry. |
2210 |
|
|
c ftem = work array of length n (acor in stode). |
2211 |
|
|
c savf = array containing f evaluated at predicted y. |
2212 |
|
|
c wm = real work space for matrices. on output it contains the |
2213 |
|
|
c inverse diagonal matrix if miter = 3 and the lu decomposition |
2214 |
|
|
c of p if miter is 1, 2 , 4, or 5. |
2215 |
|
|
c storage of matrix elements starts at wm(3). |
2216 |
|
|
c wm also contains the following matrix-related data.. |
2217 |
|
|
c wm(1) = sqrt(uround), used in numerical jacobian increments. |
2218 |
|
|
c wm(2) = h*el0, saved for later use if miter = 3. |
2219 |
|
|
c iwm = integer work space containing pivot information, starting at |
2220 |
|
|
c iwm(21), if miter is 1, 2, 4, or 5. iwm also contains band |
2221 |
|
|
c parameters ml = iwm(1) and mu = iwm(2) if miter is 4 or 5. |
2222 |
|
|
c el0 = el(1) (input). |
2223 |
|
|
c ierpj = output error flag, = 0 if no trouble, .gt. 0 if |
2224 |
|
|
c p matrix found to be singular. |
2225 |
|
|
c jcur = output flag = 1 to indicate that the jacobian matrix |
2226 |
|
|
c (or approximation) is now current. |
2227 |
|
|
c this routine also uses the common variables el0, h, tn, uround, |
2228 |
|
|
c miter, n, nfe, and nje. |
2229 |
|
|
c----------------------------------------------------------------------- |
2230 |
|
|
nje = nje + 1 |
2231 |
|
|
ierpj = 0 |
2232 |
|
|
jcur = 1 |
2233 |
|
|
hl0 = h*el0 |
2234 |
|
|
go to (100, 200, 300, 400, 500), miter |
2235 |
|
|
c if miter = 1, call jac and multiply by scalar. ----------------------- |
2236 |
|
|
100 lenp = n*n |
2237 |
|
|
do 110 i = 1,lenp |
2238 |
|
|
110 wm(i+2) = 0.0e0 |
2239 |
|
|
call jac (neq, tn, y, 0, 0, wm(3), n) |
2240 |
|
|
con = -hl0 |
2241 |
|
|
do 120 i = 1,lenp |
2242 |
|
|
120 wm(i+2) = wm(i+2)*con |
2243 |
|
|
go to 240 |
2244 |
|
|
c if miter = 2, make n calls to f to approximate j. -------------------- |
2245 |
|
|
200 fac = vnorm (n, savf, ewt) |
2246 |
|
|
r0 = 1000.0e0*abs(h)*uround*float(n)*fac |
2247 |
|
|
if (r0 .eq. 0.0e0) r0 = 1.0e0 |
2248 |
|
|
srur = wm(1) |
2249 |
|
|
j1 = 2 |
2250 |
|
|
do 230 j = 1,n |
2251 |
|
|
yj = y(j) |
2252 |
|
|
r = max(srur*abs(yj),r0/ewt(j)) |
2253 |
|
|
y(j) = y(j) + r |
2254 |
|
|
fac = -hl0/r |
2255 |
|
|
call f (neq, tn, y, ftem) |
2256 |
|
|
do 220 i = 1,n |
2257 |
|
|
220 wm(i+j1) = (ftem(i) - savf(i))*fac |
2258 |
|
|
y(j) = yj |
2259 |
|
|
j1 = j1 + n |
2260 |
|
|
230 continue |
2261 |
|
|
nfe = nfe + n |
2262 |
|
|
c add identity matrix. ------------------------------------------------- |
2263 |
|
|
240 j = 3 |
2264 |
|
|
np1 = n + 1 |
2265 |
|
|
do 250 i = 1,n |
2266 |
|
|
wm(j) = wm(j) + 1.0e0 |
2267 |
|
|
250 j = j + np1 |
2268 |
|
|
c do lu decomposition on p. -------------------------------------------- |
2269 |
|
|
call sgefa (wm(3), n, n, iwm(21), ier) |
2270 |
|
|
if (ier .ne. 0) ierpj = 1 |
2271 |
|
|
return |
2272 |
|
|
c if miter = 3, construct a diagonal approximation to j and p. --------- |
2273 |
|
|
300 wm(2) = hl0 |
2274 |
|
|
r = el0*0.1e0 |
2275 |
|
|
do 310 i = 1,n |
2276 |
|
|
310 y(i) = y(i) + r*(h*savf(i) - yh(i,2)) |
2277 |
|
|
call f (neq, tn, y, wm(3)) |
2278 |
|
|
nfe = nfe + 1 |
2279 |
|
|
do 320 i = 1,n |
2280 |
|
|
r0 = h*savf(i) - yh(i,2) |
2281 |
|
|
di = 0.1e0*r0 - h*(wm(i+2) - savf(i)) |
2282 |
|
|
wm(i+2) = 1.0e0 |
2283 |
|
|
if (abs(r0) .lt. uround/ewt(i)) go to 320 |
2284 |
|
|
if (abs(di) .eq. 0.0e0) go to 330 |
2285 |
|
|
wm(i+2) = 0.1e0*r0/di |
2286 |
|
|
320 continue |
2287 |
|
|
return |
2288 |
|
|
330 ierpj = 1 |
2289 |
|
|
return |
2290 |
|
|
c if miter = 4, call jac and multiply by scalar. ----------------------- |
2291 |
|
|
400 ml = iwm(1) |
2292 |
|
|
mu = iwm(2) |
2293 |
|
|
ml3 = ml + 3 |
2294 |
|
|
mband = ml + mu + 1 |
2295 |
|
|
meband = mband + ml |
2296 |
|
|
lenp = meband*n |
2297 |
|
|
do 410 i = 1,lenp |
2298 |
|
|
410 wm(i+2) = 0.0e0 |
2299 |
|
|
call jac (neq, tn, y, ml, mu, wm(ml3), meband) |
2300 |
|
|
con = -hl0 |
2301 |
|
|
do 420 i = 1,lenp |
2302 |
|
|
420 wm(i+2) = wm(i+2)*con |
2303 |
|
|
go to 570 |
2304 |
|
|
c if miter = 5, make mband calls to f to approximate j. ---------------- |
2305 |
|
|
500 ml = iwm(1) |
2306 |
|
|
mu = iwm(2) |
2307 |
|
|
mband = ml + mu + 1 |
2308 |
|
|
mba = min0(mband,n) |
2309 |
|
|
meband = mband + ml |
2310 |
|
|
meb1 = meband - 1 |
2311 |
|
|
srur = wm(1) |
2312 |
|
|
fac = vnorm (n, savf, ewt) |
2313 |
|
|
r0 = 1000.0e0*abs(h)*uround*float(n)*fac |
2314 |
|
|
if (r0 .eq. 0.0e0) r0 = 1.0e0 |
2315 |
|
|
do 560 j = 1,mba |
2316 |
|
|
do 530 i = j,n,mband |
2317 |
|
|
yi = y(i) |
2318 |
|
|
r = max(srur*abs(yi),r0/ewt(i)) |
2319 |
|
|
530 y(i) = y(i) + r |
2320 |
|
|
call f (neq, tn, y, ftem) |
2321 |
|
|
do 550 jj = j,n,mband |
2322 |
|
|
y(jj) = yh(jj,1) |
2323 |
|
|
yjj = y(jj) |
2324 |
|
|
r = max(srur*abs(yjj),r0/ewt(jj)) |
2325 |
|
|
fac = -hl0/r |
2326 |
|
|
i1 = max0(jj-mu,1) |
2327 |
|
|
i2 = min0(jj+ml,n) |
2328 |
|
|
ii = jj*meb1 - ml + 2 |
2329 |
|
|
do 540 i = i1,i2 |
2330 |
|
|
540 wm(ii+i) = (ftem(i) - savf(i))*fac |
2331 |
|
|
550 continue |
2332 |
|
|
560 continue |
2333 |
|
|
nfe = nfe + mba |
2334 |
|
|
c add identity matrix. ------------------------------------------------- |
2335 |
|
|
570 ii = mband + 2 |
2336 |
|
|
do 580 i = 1,n |
2337 |
|
|
wm(ii) = wm(ii) + 1.0e0 |
2338 |
|
|
580 ii = ii + meband |
2339 |
|
|
c do lu decomposition of p. -------------------------------------------- |
2340 |
|
|
call sgbfa (wm(3), meband, n, ml, mu, iwm(21), ier) |
2341 |
|
|
if (ier .ne. 0) ierpj = 1 |
2342 |
|
|
return |
2343 |
|
|
c----------------------- end of subroutine prepj ----------------------- |
2344 |
|
|
end |