MoDeNa  1.0
Software framework facilitating sequential multi-scale modelling
odepack_sub1.f
1 *DECK DUMACH
2  DOUBLE PRECISION FUNCTION dumach ()
3 C***BEGIN PROLOGUE DUMACH
4 C***PURPOSE Compute the unit roundoff of the machine.
5 C***CATEGORY R1
6 C***TYPE DOUBLE PRECISION (RUMACH-S, DUMACH-D)
7 C***KEYWORDS MACHINE CONSTANTS
8 C***AUTHOR Hindmarsh, Alan C., (LLNL)
9 C***DESCRIPTION
10 C *Usage:
11 C DOUBLE PRECISION A, DUMACH
12 C A = DUMACH()
13 C
14 C *Function Return Values:
15 C A : the unit roundoff of the machine.
16 C
17 C *Description:
18 C The unit roundoff is defined as the smallest positive machine
19 C number u such that 1.0 + u .ne. 1.0. This is computed by DUMACH
20 C in a machine-independent manner.
21 C
22 C***REFERENCES (NONE)
23 C***ROUTINES CALLED DUMSUM
24 C***REVISION HISTORY (YYYYMMDD)
25 C 19930216 DATE WRITTEN
26 C 19930818 Added SLATEC-format prologue. (FNF)
27 C 20030707 Added DUMSUM to force normal storage of COMP. (ACH)
28 C***END PROLOGUE DUMACH
29 C
30  DOUBLE PRECISION u, comp
31 C***FIRST EXECUTABLE STATEMENT DUMACH
32  u = 1.0d0
33  10 u = u*0.5d0
34  CALL dumsum(1.0d0, u, comp)
35  IF (comp .NE. 1.0d0) GO TO 10
36  dumach = u*2.0d0
37  RETURN
38 C----------------------- End of Function DUMACH ------------------------
39  END
40  SUBROUTINE dumsum(A,B,C)
41 C Routine to force normal storing of A + B, for DUMACH.
42  DOUBLE PRECISION a, b, c
43  c = a + b
44  RETURN
45  END
46 *DECK DCFODE
47  SUBROUTINE dcfode (METH, ELCO, TESCO)
48 C***BEGIN PROLOGUE DCFODE
49 C***SUBSIDIARY
50 C***PURPOSE Set ODE integrator coefficients.
51 C***TYPE DOUBLE PRECISION (SCFODE-S, DCFODE-D)
52 C***AUTHOR Hindmarsh, Alan C., (LLNL)
53 C***DESCRIPTION
54 C
55 C DCFODE is called by the integrator routine to set coefficients
56 C needed there. The coefficients for the current method, as
57 C given by the value of METH, are set for all orders and saved.
58 C The maximum order assumed here is 12 if METH = 1 and 5 if METH = 2.
59 C (A smaller value of the maximum order is also allowed.)
60 C DCFODE is called once at the beginning of the problem,
61 C and is not called again unless and until METH is changed.
62 C
63 C The ELCO array contains the basic method coefficients.
64 C The coefficients el(i), 1 .le. i .le. nq+1, for the method of
65 C order nq are stored in ELCO(i,nq). They are given by a genetrating
66 C polynomial, i.e.,
67 C l(x) = el(1) + el(2)*x + ... + el(nq+1)*x**nq.
68 C For the implicit Adams methods, l(x) is given by
69 C dl/dx = (x+1)*(x+2)*...*(x+nq-1)/factorial(nq-1), l(-1) = 0.
70 C For the BDF methods, l(x) is given by
71 C l(x) = (x+1)*(x+2)* ... *(x+nq)/K,
72 C where K = factorial(nq)*(1 + 1/2 + ... + 1/nq).
73 C
74 C The TESCO array contains test constants used for the
75 C local error test and the selection of step size and/or order.
76 C At order nq, TESCO(k,nq) is used for the selection of step
77 C size at order nq - 1 if k = 1, at order nq if k = 2, and at order
78 C nq + 1 if k = 3.
79 C
80 C***SEE ALSO DLSODE
81 C***ROUTINES CALLED (NONE)
82 C***REVISION HISTORY (YYMMDD)
83 C 791129 DATE WRITTEN
84 C 890501 Modified prologue to SLATEC/LDOC format. (FNF)
85 C 890503 Minor cosmetic changes. (FNF)
86 C 930809 Renamed to allow single/double precision versions. (ACH)
87 C***END PROLOGUE DCFODE
88 C**End
89  INTEGER meth
90  INTEGER i, ib, nq, nqm1, nqp1
91  DOUBLE PRECISION elco, tesco
92  DOUBLE PRECISION agamq, fnq, fnqm1, pc, pint, ragq,
93  1 rqfac, rq1fac, tsign, xpin
94  dimension elco(13,12), tesco(3,12)
95  dimension pc(12)
96 C
97 C***FIRST EXECUTABLE STATEMENT DCFODE
98  GO TO (100, 200), meth
99 C
100  100 elco(1,1) = 1.0d0
101  elco(2,1) = 1.0d0
102  tesco(1,1) = 0.0d0
103  tesco(2,1) = 2.0d0
104  tesco(1,2) = 1.0d0
105  tesco(3,12) = 0.0d0
106  pc(1) = 1.0d0
107  rqfac = 1.0d0
108  DO 140 nq = 2,12
109 C-----------------------------------------------------------------------
110 C The PC array will contain the coefficients of the polynomial
111 C p(x) = (x+1)*(x+2)*...*(x+nq-1).
112 C Initially, p(x) = 1.
113 C-----------------------------------------------------------------------
114  rq1fac = rqfac
115  rqfac = rqfac/nq
116  nqm1 = nq - 1
117  fnqm1 = nqm1
118  nqp1 = nq + 1
119 C Form coefficients of p(x)*(x+nq-1). ----------------------------------
120  pc(nq) = 0.0d0
121  DO 110 ib = 1,nqm1
122  i = nqp1 - ib
123  110 pc(i) = pc(i-1) + fnqm1*pc(i)
124  pc(1) = fnqm1*pc(1)
125 C Compute integral, -1 to 0, of p(x) and x*p(x). -----------------------
126  pint = pc(1)
127  xpin = pc(1)/2.0d0
128  tsign = 1.0d0
129  DO 120 i = 2,nq
130  tsign = -tsign
131  pint = pint + tsign*pc(i)/i
132  120 xpin = xpin + tsign*pc(i)/(i+1)
133 C Store coefficients in ELCO and TESCO. --------------------------------
134  elco(1,nq) = pint*rq1fac
135  elco(2,nq) = 1.0d0
136  DO 130 i = 2,nq
137  130 elco(i+1,nq) = rq1fac*pc(i)/i
138  agamq = rqfac*xpin
139  ragq = 1.0d0/agamq
140  tesco(2,nq) = ragq
141  IF (nq .LT. 12) tesco(1,nqp1) = ragq*rqfac/nqp1
142  tesco(3,nqm1) = ragq
143  140 CONTINUE
144  RETURN
145 C
146  200 pc(1) = 1.0d0
147  rq1fac = 1.0d0
148  DO 230 nq = 1,5
149 C-----------------------------------------------------------------------
150 C The PC array will contain the coefficients of the polynomial
151 C p(x) = (x+1)*(x+2)*...*(x+nq).
152 C Initially, p(x) = 1.
153 C-----------------------------------------------------------------------
154  fnq = nq
155  nqp1 = nq + 1
156 C Form coefficients of p(x)*(x+nq). ------------------------------------
157  pc(nqp1) = 0.0d0
158  DO 210 ib = 1,nq
159  i = nq + 2 - ib
160  210 pc(i) = pc(i-1) + fnq*pc(i)
161  pc(1) = fnq*pc(1)
162 C Store coefficients in ELCO and TESCO. --------------------------------
163  DO 220 i = 1,nqp1
164  220 elco(i,nq) = pc(i)/pc(2)
165  elco(2,nq) = 1.0d0
166  tesco(1,nq) = rq1fac
167  tesco(2,nq) = nqp1/elco(1,nq)
168  tesco(3,nq) = (nq+2)/elco(1,nq)
169  rq1fac = rq1fac/fnq
170  230 CONTINUE
171  RETURN
172 C----------------------- END OF SUBROUTINE DCFODE ----------------------
173  END
174 *DECK DINTDY
175  SUBROUTINE dintdy (T, K, YH, NYH, DKY, IFLAG)
176 C***BEGIN PROLOGUE DINTDY
177 C***SUBSIDIARY
178 C***PURPOSE Interpolate solution derivatives.
179 C***TYPE DOUBLE PRECISION (SINTDY-S, DINTDY-D)
180 C***AUTHOR Hindmarsh, Alan C., (LLNL)
181 C***DESCRIPTION
182 C
183 C DINTDY computes interpolated values of the K-th derivative of the
184 C dependent variable vector y, and stores it in DKY. This routine
185 C is called within the package with K = 0 and T = TOUT, but may
186 C also be called by the user for any K up to the current order.
187 C (See detailed instructions in the usage documentation.)
188 C
189 C The computed values in DKY are gotten by interpolation using the
190 C Nordsieck history array YH. This array corresponds uniquely to a
191 C vector-valued polynomial of degree NQCUR or less, and DKY is set
192 C to the K-th derivative of this polynomial at T.
193 C The formula for DKY is:
194 C q
195 C DKY(i) = sum c(j,K) * (T - tn)**(j-K) * h**(-j) * YH(i,j+1)
196 C j=K
197 C where c(j,K) = j*(j-1)*...*(j-K+1), q = NQCUR, tn = TCUR, h = HCUR.
198 C The quantities nq = NQCUR, l = nq+1, N = NEQ, tn, and h are
199 C communicated by COMMON. The above sum is done in reverse order.
200 C IFLAG is returned negative if either K or T is out of bounds.
201 C
202 C***SEE ALSO DLSODE
203 C***ROUTINES CALLED XERRWD
204 C***COMMON BLOCKS DLS001
205 C***REVISION HISTORY (YYMMDD)
206 C 791129 DATE WRITTEN
207 C 890501 Modified prologue to SLATEC/LDOC format. (FNF)
208 C 890503 Minor cosmetic changes. (FNF)
209 C 930809 Renamed to allow single/double precision versions. (ACH)
210 C 010418 Reduced size of Common block /DLS001/. (ACH)
211 C 031105 Restored 'own' variables to Common block /DLS001/, to
212 C enable interrupt/restart feature. (ACH)
213 C 050427 Corrected roundoff decrement in TP. (ACH)
214 C***END PROLOGUE DINTDY
215 C**End
216  INTEGER k, nyh, iflag
217  DOUBLE PRECISION t, yh, dky
218  dimension yh(nyh,*), dky(*)
219  INTEGER iownd, iowns,
220  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
221  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
222  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
223  DOUBLE PRECISION rowns,
224  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
225  COMMON /dls001/ rowns(209),
226  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
227  2 iownd(6), iowns(6),
228  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
229  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
230  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
231  INTEGER i, ic, j, jb, jb2, jj, jj1, jp1
232  DOUBLE PRECISION c, r, s, tp
233  CHARACTER*80 msg
234 C
235 C***FIRST EXECUTABLE STATEMENT DINTDY
236  iflag = 0
237  IF (k .LT. 0 .OR. k .GT. nq) GO TO 80
238  tp = tn - hu - 100.0d0*uround*sign(abs(tn) + abs(hu), hu)
239  IF ((t-tp)*(t-tn) .GT. 0.0d0) GO TO 90
240 C
241  s = (t - tn)/h
242  ic = 1
243  IF (k .EQ. 0) GO TO 15
244  jj1 = l - k
245  DO 10 jj = jj1,nq
246  10 ic = ic*jj
247  15 c = ic
248  DO 20 i = 1,n
249  20 dky(i) = c*yh(i,l)
250  IF (k .EQ. nq) GO TO 55
251  jb2 = nq - k
252  DO 50 jb = 1,jb2
253  j = nq - jb
254  jp1 = j + 1
255  ic = 1
256  IF (k .EQ. 0) GO TO 35
257  jj1 = jp1 - k
258  DO 30 jj = jj1,j
259  30 ic = ic*jj
260  35 c = ic
261  DO 40 i = 1,n
262  40 dky(i) = c*yh(i,jp1) + s*dky(i)
263  50 CONTINUE
264  IF (k .EQ. 0) RETURN
265  55 r = h**(-k)
266  DO 60 i = 1,n
267  60 dky(i) = r*dky(i)
268  RETURN
269 C
270  80 msg = 'DINTDY- K (=I1) illegal '
271  CALL xerrwd (msg, 30, 51, 0, 1, k, 0, 0, 0.0d0, 0.0d0)
272  iflag = -1
273  RETURN
274  90 msg = 'DINTDY- T (=R1) illegal '
275  CALL xerrwd (msg, 30, 52, 0, 0, 0, 0, 1, t, 0.0d0)
276  msg=' T not in interval TCUR - HU (= R1) to TCUR (=R2) '
277  CALL xerrwd (msg, 60, 52, 0, 0, 0, 0, 2, tp, tn)
278  iflag = -2
279  RETURN
280 C----------------------- END OF SUBROUTINE DINTDY ----------------------
281  END
282 *DECK DPREPJ
283  SUBROUTINE dprepj (NEQ, Y, YH, NYH, EWT, FTEM, SAVF, WM, IWM,
284  1 F, JAC)
285 C***BEGIN PROLOGUE DPREPJ
286 C***SUBSIDIARY
287 C***PURPOSE Compute and process Newton iteration matrix.
288 C***TYPE DOUBLE PRECISION (SPREPJ-S, DPREPJ-D)
289 C***AUTHOR Hindmarsh, Alan C., (LLNL)
290 C***DESCRIPTION
291 C
292 C DPREPJ is called by DSTODE to compute and process the matrix
293 C P = I - h*el(1)*J , where J is an approximation to the Jacobian.
294 C Here J is computed by the user-supplied routine JAC if
295 C MITER = 1 or 4, or by finite differencing if MITER = 2, 3, or 5.
296 C If MITER = 3, a diagonal approximation to J is used.
297 C J is stored in WM and replaced by P. If MITER .ne. 3, P is then
298 C subjected to LU decomposition in preparation for later solution
299 C of linear systems with P as coefficient matrix. This is done
300 C by DGEFA if MITER = 1 or 2, and by DGBFA if MITER = 4 or 5.
301 C
302 C In addition to variables described in DSTODE and DLSODE prologues,
303 C communication with DPREPJ uses the following:
304 C Y = array containing predicted values on entry.
305 C FTEM = work array of length N (ACOR in DSTODE).
306 C SAVF = array containing f evaluated at predicted y.
307 C WM = real work space for matrices. On output it contains the
308 C inverse diagonal matrix if MITER = 3 and the LU decomposition
309 C of P if MITER is 1, 2 , 4, or 5.
310 C Storage of matrix elements starts at WM(3).
311 C WM also contains the following matrix-related data:
312 C WM(1) = SQRT(UROUND), used in numerical Jacobian increments.
313 C WM(2) = H*EL0, saved for later use if MITER = 3.
314 C IWM = integer work space containing pivot information, starting at
315 C IWM(21), if MITER is 1, 2, 4, or 5. IWM also contains band
316 C parameters ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
317 C EL0 = EL(1) (input).
318 C IERPJ = output error flag, = 0 if no trouble, .gt. 0 if
319 C P matrix found to be singular.
320 C JCUR = output flag = 1 to indicate that the Jacobian matrix
321 C (or approximation) is now current.
322 C This routine also uses the COMMON variables EL0, H, TN, UROUND,
323 C MITER, N, NFE, and NJE.
324 C
325 C***SEE ALSO DLSODE
326 C***ROUTINES CALLED DGBFA, DGEFA, DVNORM
327 C***COMMON BLOCKS DLS001
328 C***REVISION HISTORY (YYMMDD)
329 C 791129 DATE WRITTEN
330 C 890501 Modified prologue to SLATEC/LDOC format. (FNF)
331 C 890504 Minor cosmetic changes. (FNF)
332 C 930809 Renamed to allow single/double precision versions. (ACH)
333 C 010418 Reduced size of Common block /DLS001/. (ACH)
334 C 031105 Restored 'own' variables to Common block /DLS001/, to
335 C enable interrupt/restart feature. (ACH)
336 C***END PROLOGUE DPREPJ
337 C**End
338  EXTERNAL f, jac
339  INTEGER neq, nyh, iwm
340  DOUBLE PRECISION y, yh, ewt, ftem, savf, wm
341  dimension neq(*), y(*), yh(nyh,*), ewt(*), ftem(*), savf(*),
342  1 wm(*), iwm(*)
343  INTEGER iownd, iowns,
344  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
345  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
346  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
347  DOUBLE PRECISION rowns,
348  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
349  COMMON /dls001/ rowns(209),
350  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
351  2 iownd(6), iowns(6),
352  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
353  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
354  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
355  INTEGER i, i1, i2, ier, ii, j, j1, jj, lenp,
356  1 mba, mband, meb1, meband, ml, ml3, mu, np1
357  DOUBLE PRECISION con, di, fac, hl0, r, r0, srur, yi, yj, yjj,
358  1 dvnorm
359 C
360 C***FIRST EXECUTABLE STATEMENT DPREPJ
361  nje = nje + 1
362  ierpj = 0
363  jcur = 1
364  hl0 = h*el0
365  GO TO (100, 200, 300, 400, 500), miter
366 C If MITER = 1, call JAC and multiply by scalar. -----------------------
367  100 lenp = n*n
368  DO 110 i = 1,lenp
369  110 wm(i+2) = 0.0d0
370  CALL jac (neq, tn, y, 0, 0, wm(3), n)
371  con = -hl0
372  DO 120 i = 1,lenp
373  120 wm(i+2) = wm(i+2)*con
374  GO TO 240
375 C If MITER = 2, make N calls to F to approximate J. --------------------
376  200 fac = dvnorm(n, savf, ewt)
377  r0 = 1000.0d0*abs(h)*uround*n*fac
378  IF (r0 .EQ. 0.0d0) r0 = 1.0d0
379  srur = wm(1)
380  j1 = 2
381  DO 230 j = 1,n
382  yj = y(j)
383  r = max(srur*abs(yj),r0/ewt(j))
384  y(j) = y(j) + r
385  fac = -hl0/r
386  CALL f (neq, tn, y, ftem)
387  DO 220 i = 1,n
388  220 wm(i+j1) = (ftem(i) - savf(i))*fac
389  y(j) = yj
390  j1 = j1 + n
391  230 CONTINUE
392  nfe = nfe + n
393 C Add identity matrix. -------------------------------------------------
394  240 j = 3
395  np1 = n + 1
396  DO 250 i = 1,n
397  wm(j) = wm(j) + 1.0d0
398  250 j = j + np1
399 C Do LU decomposition on P. --------------------------------------------
400  CALL dgefa (wm(3), n, n, iwm(21), ier)
401  IF (ier .NE. 0) ierpj = 1
402  RETURN
403 C If MITER = 3, construct a diagonal approximation to J and P. ---------
404  300 wm(2) = hl0
405  r = el0*0.1d0
406  DO 310 i = 1,n
407  310 y(i) = y(i) + r*(h*savf(i) - yh(i,2))
408  CALL f (neq, tn, y, wm(3))
409  nfe = nfe + 1
410  DO 320 i = 1,n
411  r0 = h*savf(i) - yh(i,2)
412  di = 0.1d0*r0 - h*(wm(i+2) - savf(i))
413  wm(i+2) = 1.0d0
414  IF (abs(r0) .LT. uround/ewt(i)) GO TO 320
415  IF (abs(di) .EQ. 0.0d0) GO TO 330
416  wm(i+2) = 0.1d0*r0/di
417  320 CONTINUE
418  RETURN
419  330 ierpj = 1
420  RETURN
421 C If MITER = 4, call JAC and multiply by scalar. -----------------------
422  400 ml = iwm(1)
423  mu = iwm(2)
424  ml3 = ml + 3
425  mband = ml + mu + 1
426  meband = mband + ml
427  lenp = meband*n
428  DO 410 i = 1,lenp
429  410 wm(i+2) = 0.0d0
430  CALL jac (neq, tn, y, ml, mu, wm(ml3), meband)
431  con = -hl0
432  DO 420 i = 1,lenp
433  420 wm(i+2) = wm(i+2)*con
434  GO TO 570
435 C If MITER = 5, make MBAND calls to F to approximate J. ----------------
436  500 ml = iwm(1)
437  mu = iwm(2)
438  mband = ml + mu + 1
439  mba = min(mband,n)
440  meband = mband + ml
441  meb1 = meband - 1
442  srur = wm(1)
443  fac = dvnorm(n, savf, ewt)
444  r0 = 1000.0d0*abs(h)*uround*n*fac
445  IF (r0 .EQ. 0.0d0) r0 = 1.0d0
446  DO 560 j = 1,mba
447  DO 530 i = j,n,mband
448  yi = y(i)
449  r = max(srur*abs(yi),r0/ewt(i))
450  530 y(i) = y(i) + r
451  CALL f (neq, tn, y, ftem)
452  DO 550 jj = j,n,mband
453  y(jj) = yh(jj,1)
454  yjj = y(jj)
455  r = max(srur*abs(yjj),r0/ewt(jj))
456  fac = -hl0/r
457  i1 = max(jj-mu,1)
458  i2 = min(jj+ml,n)
459  ii = jj*meb1 - ml + 2
460  DO 540 i = i1,i2
461  540 wm(ii+i) = (ftem(i) - savf(i))*fac
462  550 CONTINUE
463  560 CONTINUE
464  nfe = nfe + mba
465 C Add identity matrix. -------------------------------------------------
466  570 ii = mband + 2
467  DO 580 i = 1,n
468  wm(ii) = wm(ii) + 1.0d0
469  580 ii = ii + meband
470 C Do LU decomposition of P. --------------------------------------------
471  CALL dgbfa (wm(3), meband, n, ml, mu, iwm(21), ier)
472  IF (ier .NE. 0) ierpj = 1
473  RETURN
474 C----------------------- END OF SUBROUTINE DPREPJ ----------------------
475  END
476 *DECK DSOLSY
477  SUBROUTINE dsolsy (WM, IWM, X, TEM)
478 C***BEGIN PROLOGUE DSOLSY
479 C***SUBSIDIARY
480 C***PURPOSE ODEPACK linear system solver.
481 C***TYPE DOUBLE PRECISION (SSOLSY-S, DSOLSY-D)
482 C***AUTHOR Hindmarsh, Alan C., (LLNL)
483 C***DESCRIPTION
484 C
485 C This routine manages the solution of the linear system arising from
486 C a chord iteration. It is called if MITER .ne. 0.
487 C If MITER is 1 or 2, it calls DGESL to accomplish this.
488 C If MITER = 3 it updates the coefficient h*EL0 in the diagonal
489 C matrix, and then computes the solution.
490 C If MITER is 4 or 5, it calls DGBSL.
491 C Communication with DSOLSY uses the following variables:
492 C WM = real work space containing the inverse diagonal matrix if
493 C MITER = 3 and the LU decomposition of the matrix otherwise.
494 C Storage of matrix elements starts at WM(3).
495 C WM also contains the following matrix-related data:
496 C WM(1) = SQRT(UROUND) (not used here),
497 C WM(2) = HL0, the previous value of h*EL0, used if MITER = 3.
498 C IWM = integer work space containing pivot information, starting at
499 C IWM(21), if MITER is 1, 2, 4, or 5. IWM also contains band
500 C parameters ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
501 C X = the right-hand side vector on input, and the solution vector
502 C on output, of length N.
503 C TEM = vector of work space of length N, not used in this version.
504 C IERSL = output flag (in COMMON). IERSL = 0 if no trouble occurred.
505 C IERSL = 1 if a singular matrix arose with MITER = 3.
506 C This routine also uses the COMMON variables EL0, H, MITER, and N.
507 C
508 C***SEE ALSO DLSODE
509 C***ROUTINES CALLED DGBSL, DGESL
510 C***COMMON BLOCKS DLS001
511 C***REVISION HISTORY (YYMMDD)
512 C 791129 DATE WRITTEN
513 C 890501 Modified prologue to SLATEC/LDOC format. (FNF)
514 C 890503 Minor cosmetic changes. (FNF)
515 C 930809 Renamed to allow single/double precision versions. (ACH)
516 C 010418 Reduced size of Common block /DLS001/. (ACH)
517 C 031105 Restored 'own' variables to Common block /DLS001/, to
518 C enable interrupt/restart feature. (ACH)
519 C***END PROLOGUE DSOLSY
520 C**End
521  INTEGER iwm
522  DOUBLE PRECISION wm, x, tem
523  dimension wm(*), iwm(*), x(*), tem(*)
524  INTEGER iownd, iowns,
525  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
526  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
527  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
528  DOUBLE PRECISION rowns,
529  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
530  COMMON /dls001/ rowns(209),
531  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
532  2 iownd(6), iowns(6),
533  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
534  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
535  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
536  INTEGER i, meband, ml, mu
537  DOUBLE PRECISION di, hl0, phl0, r
538 C
539 C***FIRST EXECUTABLE STATEMENT DSOLSY
540  iersl = 0
541  GO TO (100, 100, 300, 400, 400), miter
542  100 CALL dgesl (wm(3), n, n, iwm(21), x, 0)
543  RETURN
544 C
545  300 phl0 = wm(2)
546  hl0 = h*el0
547  wm(2) = hl0
548  IF (hl0 .EQ. phl0) GO TO 330
549  r = hl0/phl0
550  DO 320 i = 1,n
551  di = 1.0d0 - r*(1.0d0 - 1.0d0/wm(i+2))
552  IF (abs(di) .EQ. 0.0d0) GO TO 390
553  320 wm(i+2) = 1.0d0/di
554  330 DO 340 i = 1,n
555  340 x(i) = wm(i+2)*x(i)
556  RETURN
557  390 iersl = 1
558  RETURN
559 C
560  400 ml = iwm(1)
561  mu = iwm(2)
562  meband = 2*ml + mu + 1
563  CALL dgbsl (wm(3), meband, n, ml, mu, iwm(21), x, 0)
564  RETURN
565 C----------------------- END OF SUBROUTINE DSOLSY ----------------------
566  END
567 *DECK DSRCOM
568  SUBROUTINE dsrcom (RSAV, ISAV, JOB)
569 C***BEGIN PROLOGUE DSRCOM
570 C***SUBSIDIARY
571 C***PURPOSE Save/restore ODEPACK COMMON blocks.
572 C***TYPE DOUBLE PRECISION (SSRCOM-S, DSRCOM-D)
573 C***AUTHOR Hindmarsh, Alan C., (LLNL)
574 C***DESCRIPTION
575 C
576 C This routine saves or restores (depending on JOB) the contents of
577 C the COMMON block DLS001, which is used internally
578 C by one or more ODEPACK solvers.
579 C
580 C RSAV = real array of length 218 or more.
581 C ISAV = integer array of length 37 or more.
582 C JOB = flag indicating to save or restore the COMMON blocks:
583 C JOB = 1 if COMMON is to be saved (written to RSAV/ISAV)
584 C JOB = 2 if COMMON is to be restored (read from RSAV/ISAV)
585 C A call with JOB = 2 presumes a prior call with JOB = 1.
586 C
587 C***SEE ALSO DLSODE
588 C***ROUTINES CALLED (NONE)
589 C***COMMON BLOCKS DLS001
590 C***REVISION HISTORY (YYMMDD)
591 C 791129 DATE WRITTEN
592 C 890501 Modified prologue to SLATEC/LDOC format. (FNF)
593 C 890503 Minor cosmetic changes. (FNF)
594 C 921116 Deleted treatment of block /EH0001/. (ACH)
595 C 930801 Reduced Common block length by 2. (ACH)
596 C 930809 Renamed to allow single/double precision versions. (ACH)
597 C 010418 Reduced Common block length by 209+12. (ACH)
598 C 031105 Restored 'own' variables to Common block /DLS001/, to
599 C enable interrupt/restart feature. (ACH)
600 C 031112 Added SAVE statement for data-loaded constants.
601 C***END PROLOGUE DSRCOM
602 C**End
603  INTEGER isav, job
604  INTEGER ils
605  INTEGER i, lenils, lenrls
606  DOUBLE PRECISION rsav, rls
607  dimension rsav(*), isav(*)
608  SAVE lenrls, lenils
609  COMMON /dls001/ rls(218), ils(37)
610  DATA lenrls/218/, lenils/37/
611 C
612 C***FIRST EXECUTABLE STATEMENT DSRCOM
613  IF (job .EQ. 2) GO TO 100
614 C
615  DO 10 i = 1,lenrls
616  10 rsav(i) = rls(i)
617  DO 20 i = 1,lenils
618  20 isav(i) = ils(i)
619  RETURN
620 C
621  100 CONTINUE
622  DO 110 i = 1,lenrls
623  110 rls(i) = rsav(i)
624  DO 120 i = 1,lenils
625  120 ils(i) = isav(i)
626  RETURN
627 C----------------------- END OF SUBROUTINE DSRCOM ----------------------
628  END
629 *DECK DSTODE
630  SUBROUTINE dstode (NEQ, Y, YH, NYH, YH1, EWT, SAVF, ACOR,
631  1 WM, IWM, F, JAC, PJAC, SLVS)
632 C***BEGIN PROLOGUE DSTODE
633 C***SUBSIDIARY
634 C***PURPOSE Performs one step of an ODEPACK integration.
635 C***TYPE DOUBLE PRECISION (SSTODE-S, DSTODE-D)
636 C***AUTHOR Hindmarsh, Alan C., (LLNL)
637 C***DESCRIPTION
638 C
639 C DSTODE performs one step of the integration of an initial value
640 C problem for a system of ordinary differential equations.
641 C Note: DSTODE is independent of the value of the iteration method
642 C indicator MITER, when this is .ne. 0, and hence is independent
643 C of the type of chord method used, or the Jacobian structure.
644 C Communication with DSTODE is done with the following variables:
645 C
646 C NEQ = integer array containing problem size in NEQ(1), and
647 C passed as the NEQ argument in all calls to F and JAC.
648 C Y = an array of length .ge. N used as the Y argument in
649 C all calls to F and JAC.
650 C YH = an NYH by LMAX array containing the dependent variables
651 C and their approximate scaled derivatives, where
652 C LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
653 C j-th derivative of y(i), scaled by h**j/factorial(j)
654 C (j = 0,1,...,NQ). on entry for the first step, the first
655 C two columns of YH must be set from the initial values.
656 C NYH = a constant integer .ge. N, the first dimension of YH.
657 C YH1 = a one-dimensional array occupying the same space as YH.
658 C EWT = an array of length N containing multiplicative weights
659 C for local error measurements. Local errors in Y(i) are
660 C compared to 1.0/EWT(i) in various error tests.
661 C SAVF = an array of working storage, of length N.
662 C Also used for input of YH(*,MAXORD+2) when JSTART = -1
663 C and MAXORD .lt. the current order NQ.
664 C ACOR = a work array of length N, used for the accumulated
665 C corrections. On a successful return, ACOR(i) contains
666 C the estimated one-step local error in Y(i).
667 C WM,IWM = real and integer work arrays associated with matrix
668 C operations in chord iteration (MITER .ne. 0).
669 C PJAC = name of routine to evaluate and preprocess Jacobian matrix
670 C and P = I - h*el0*JAC, if a chord method is being used.
671 C SLVS = name of routine to solve linear system in chord iteration.
672 C CCMAX = maximum relative change in h*el0 before PJAC is called.
673 C H = the step size to be attempted on the next step.
674 C H is altered by the error control algorithm during the
675 C problem. H can be either positive or negative, but its
676 C sign must remain constant throughout the problem.
677 C HMIN = the minimum absolute value of the step size h to be used.
678 C HMXI = inverse of the maximum absolute value of h to be used.
679 C HMXI = 0.0 is allowed and corresponds to an infinite hmax.
680 C HMIN and HMXI may be changed at any time, but will not
681 C take effect until the next change of h is considered.
682 C TN = the independent variable. TN is updated on each step taken.
683 C JSTART = an integer used for input only, with the following
684 C values and meanings:
685 C 0 perform the first step.
686 C .gt.0 take a new step continuing from the last.
687 C -1 take the next step with a new value of H, MAXORD,
688 C N, METH, MITER, and/or matrix parameters.
689 C -2 take the next step with a new value of H,
690 C but with other inputs unchanged.
691 C On return, JSTART is set to 1 to facilitate continuation.
692 C KFLAG = a completion code with the following meanings:
693 C 0 the step was succesful.
694 C -1 the requested error could not be achieved.
695 C -2 corrector convergence could not be achieved.
696 C -3 fatal error in PJAC or SLVS.
697 C A return with KFLAG = -1 or -2 means either
698 C abs(H) = HMIN or 10 consecutive failures occurred.
699 C On a return with KFLAG negative, the values of TN and
700 C the YH array are as of the beginning of the last
701 C step, and H is the last step size attempted.
702 C MAXORD = the maximum order of integration method to be allowed.
703 C MAXCOR = the maximum number of corrector iterations allowed.
704 C MSBP = maximum number of steps between PJAC calls (MITER .gt. 0).
705 C MXNCF = maximum number of convergence failures allowed.
706 C METH/MITER = the method flags. See description in driver.
707 C N = the number of first-order differential equations.
708 C The values of CCMAX, H, HMIN, HMXI, TN, JSTART, KFLAG, MAXORD,
709 C MAXCOR, MSBP, MXNCF, METH, MITER, and N are communicated via COMMON.
710 C
711 C***SEE ALSO DLSODE
712 C***ROUTINES CALLED DCFODE, DVNORM
713 C***COMMON BLOCKS DLS001
714 C***REVISION HISTORY (YYMMDD)
715 C 791129 DATE WRITTEN
716 C 890501 Modified prologue to SLATEC/LDOC format. (FNF)
717 C 890503 Minor cosmetic changes. (FNF)
718 C 930809 Renamed to allow single/double precision versions. (ACH)
719 C 010418 Reduced size of Common block /DLS001/. (ACH)
720 C 031105 Restored 'own' variables to Common block /DLS001/, to
721 C enable interrupt/restart feature. (ACH)
722 C***END PROLOGUE DSTODE
723 C**End
724  EXTERNAL f, jac, pjac, slvs
725  INTEGER neq, nyh, iwm
726  DOUBLE PRECISION y, yh, yh1, ewt, savf, acor, wm
727  dimension neq(*), y(*), yh(nyh,*), yh1(*), ewt(*), savf(*),
728  1 acor(*), wm(*), iwm(*)
729  INTEGER iownd, ialth, ipup, lmax, meo, nqnyh, nslp,
730  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
731  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
732  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
733  INTEGER i, i1, iredo, iret, j, jb, m, ncf, newq
734  DOUBLE PRECISION conit, crate, el, elco, hold, rmax, tesco,
735  2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
736  DOUBLE PRECISION dcon, ddn, del, delp, dsm, dup, exdn, exsm, exup,
737  1 r, rh, rhdn, rhsm, rhup, told, dvnorm
738  COMMON /dls001/ conit, crate, el(13), elco(13,12),
739  1 hold, rmax, tesco(3,12),
740  2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
741  3 iownd(6), ialth, ipup, lmax, meo, nqnyh, nslp,
742  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
743  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
744  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
745 C
746 C***FIRST EXECUTABLE STATEMENT DSTODE
747  kflag = 0
748  told = tn
749  ncf = 0
750  ierpj = 0
751  iersl = 0
752  jcur = 0
753  icf = 0
754  delp = 0.0d0
755  IF (jstart .GT. 0) GO TO 200
756  IF (jstart .EQ. -1) GO TO 100
757  IF (jstart .EQ. -2) GO TO 160
758 C-----------------------------------------------------------------------
759 C On the first call, the order is set to 1, and other variables are
760 C initialized. RMAX is the maximum ratio by which H can be increased
761 C in a single step. It is initially 1.E4 to compensate for the small
762 C initial H, but then is normally equal to 10. If a failure
763 C occurs (in corrector convergence or error test), RMAX is set to 2
764 C for the next increase.
765 C-----------------------------------------------------------------------
766  lmax = maxord + 1
767  nq = 1
768  l = 2
769  ialth = 2
770  rmax = 10000.0d0
771  rc = 0.0d0
772  el0 = 1.0d0
773  crate = 0.7d0
774  hold = h
775  meo = meth
776  nslp = 0
777  ipup = miter
778  iret = 3
779  GO TO 140
780 C-----------------------------------------------------------------------
781 C The following block handles preliminaries needed when JSTART = -1.
782 C IPUP is set to MITER to force a matrix update.
783 C If an order increase is about to be considered (IALTH = 1),
784 C IALTH is reset to 2 to postpone consideration one more step.
785 C If the caller has changed METH, DCFODE is called to reset
786 C the coefficients of the method.
787 C If the caller has changed MAXORD to a value less than the current
788 C order NQ, NQ is reduced to MAXORD, and a new H chosen accordingly.
789 C If H is to be changed, YH must be rescaled.
790 C If H or METH is being changed, IALTH is reset to L = NQ + 1
791 C to prevent further changes in H for that many steps.
792 C-----------------------------------------------------------------------
793  100 ipup = miter
794  lmax = maxord + 1
795  IF (ialth .EQ. 1) ialth = 2
796  IF (meth .EQ. meo) GO TO 110
797  CALL dcfode (meth, elco, tesco)
798  meo = meth
799  IF (nq .GT. maxord) GO TO 120
800  ialth = l
801  iret = 1
802  GO TO 150
803  110 IF (nq .LE. maxord) GO TO 160
804  120 nq = maxord
805  l = lmax
806  DO 125 i = 1,l
807  125 el(i) = elco(i,nq)
808  nqnyh = nq*nyh
809  rc = rc*el(1)/el0
810  el0 = el(1)
811  conit = 0.5d0/(nq+2)
812  ddn = dvnorm(n, savf, ewt)/tesco(1,l)
813  exdn = 1.0d0/l
814  rhdn = 1.0d0/(1.3d0*ddn**exdn + 0.0000013d0)
815  rh = min(rhdn,1.0d0)
816  iredo = 3
817  IF (h .EQ. hold) GO TO 170
818  rh = min(rh,abs(h/hold))
819  h = hold
820  GO TO 175
821 C-----------------------------------------------------------------------
822 C DCFODE is called to get all the integration coefficients for the
823 C current METH. Then the EL vector and related constants are reset
824 C whenever the order NQ is changed, or at the start of the problem.
825 C-----------------------------------------------------------------------
826  140 CALL dcfode (meth, elco, tesco)
827  150 DO 155 i = 1,l
828  155 el(i) = elco(i,nq)
829  nqnyh = nq*nyh
830  rc = rc*el(1)/el0
831  el0 = el(1)
832  conit = 0.5d0/(nq+2)
833  GO TO (160, 170, 200), iret
834 C-----------------------------------------------------------------------
835 C If H is being changed, the H ratio RH is checked against
836 C RMAX, HMIN, and HMXI, and the YH array rescaled. IALTH is set to
837 C L = NQ + 1 to prevent a change of H for that many steps, unless
838 C forced by a convergence or error test failure.
839 C-----------------------------------------------------------------------
840  160 IF (h .EQ. hold) GO TO 200
841  rh = h/hold
842  h = hold
843  iredo = 3
844  GO TO 175
845  170 rh = max(rh,hmin/abs(h))
846  175 rh = min(rh,rmax)
847  rh = rh/max(1.0d0,abs(h)*hmxi*rh)
848  r = 1.0d0
849  DO 180 j = 2,l
850  r = r*rh
851  DO 180 i = 1,n
852  180 yh(i,j) = yh(i,j)*r
853  h = h*rh
854  rc = rc*rh
855  ialth = l
856  IF (iredo .EQ. 0) GO TO 690
857 C-----------------------------------------------------------------------
858 C This section computes the predicted values by effectively
859 C multiplying the YH array by the Pascal Triangle matrix.
860 C RC is the ratio of new to old values of the coefficient H*EL(1).
861 C When RC differs from 1 by more than CCMAX, IPUP is set to MITER
862 C to force PJAC to be called, if a Jacobian is involved.
863 C In any case, PJAC is called at least every MSBP steps.
864 C-----------------------------------------------------------------------
865  200 IF (abs(rc-1.0d0) .GT. ccmax) ipup = miter
866  IF (nst .GE. nslp+msbp) ipup = miter
867  tn = tn + h
868  i1 = nqnyh + 1
869  DO 215 jb = 1,nq
870  i1 = i1 - nyh
871 Cdir$ ivdep
872  DO 210 i = i1,nqnyh
873  210 yh1(i) = yh1(i) + yh1(i+nyh)
874  215 CONTINUE
875 C-----------------------------------------------------------------------
876 C Up to MAXCOR corrector iterations are taken. A convergence test is
877 C made on the R.M.S. norm of each correction, weighted by the error
878 C weight vector EWT. The sum of the corrections is accumulated in the
879 C vector ACOR(i). The YH array is not altered in the corrector loop.
880 C-----------------------------------------------------------------------
881  220 m = 0
882  DO 230 i = 1,n
883  230 y(i) = yh(i,1)
884  CALL f (neq, tn, y, savf)
885  nfe = nfe + 1
886  IF (ipup .LE. 0) GO TO 250
887 C-----------------------------------------------------------------------
888 C If indicated, the matrix P = I - h*el(1)*J is reevaluated and
889 C preprocessed before starting the corrector iteration. IPUP is set
890 C to 0 as an indicator that this has been done.
891 C-----------------------------------------------------------------------
892  CALL pjac (neq, y, yh, nyh, ewt, acor, savf, wm, iwm, f, jac)
893  ipup = 0
894  rc = 1.0d0
895  nslp = nst
896  crate = 0.7d0
897  IF (ierpj .NE. 0) GO TO 430
898  250 DO 260 i = 1,n
899  260 acor(i) = 0.0d0
900  270 IF (miter .NE. 0) GO TO 350
901 C-----------------------------------------------------------------------
902 C In the case of functional iteration, update Y directly from
903 C the result of the last function evaluation.
904 C-----------------------------------------------------------------------
905  DO 290 i = 1,n
906  savf(i) = h*savf(i) - yh(i,2)
907  290 y(i) = savf(i) - acor(i)
908  del = dvnorm(n, y, ewt)
909  DO 300 i = 1,n
910  y(i) = yh(i,1) + el(1)*savf(i)
911  300 acor(i) = savf(i)
912  GO TO 400
913 C-----------------------------------------------------------------------
914 C In the case of the chord method, compute the corrector error,
915 C and solve the linear system with that as right-hand side and
916 C P as coefficient matrix.
917 C-----------------------------------------------------------------------
918  350 DO 360 i = 1,n
919  360 y(i) = h*savf(i) - (yh(i,2) + acor(i))
920  CALL slvs (wm, iwm, y, savf)
921  IF (iersl .LT. 0) GO TO 430
922  IF (iersl .GT. 0) GO TO 410
923  del = dvnorm(n, y, ewt)
924  DO 380 i = 1,n
925  acor(i) = acor(i) + y(i)
926  380 y(i) = yh(i,1) + el(1)*acor(i)
927 C-----------------------------------------------------------------------
928 C Test for convergence. If M.gt.0, an estimate of the convergence
929 C rate constant is stored in CRATE, and this is used in the test.
930 C-----------------------------------------------------------------------
931  400 IF (m .NE. 0) crate = max(0.2d0*crate,del/delp)
932  dcon = del*min(1.0d0,1.5d0*crate)/(tesco(2,nq)*conit)
933  IF (dcon .LE. 1.0d0) GO TO 450
934  m = m + 1
935  IF (m .EQ. maxcor) GO TO 410
936  IF (m .GE. 2 .AND. del .GT. 2.0d0*delp) GO TO 410
937  delp = del
938  CALL f (neq, tn, y, savf)
939  nfe = nfe + 1
940  GO TO 270
941 C-----------------------------------------------------------------------
942 C The corrector iteration failed to converge.
943 C If MITER .ne. 0 and the Jacobian is out of date, PJAC is called for
944 C the next try. Otherwise the YH array is retracted to its values
945 C before prediction, and H is reduced, if possible. If H cannot be
946 C reduced or MXNCF failures have occurred, exit with KFLAG = -2.
947 C-----------------------------------------------------------------------
948  410 IF (miter .EQ. 0 .OR. jcur .EQ. 1) GO TO 430
949  icf = 1
950  ipup = miter
951  GO TO 220
952  430 icf = 2
953  ncf = ncf + 1
954  rmax = 2.0d0
955  tn = told
956  i1 = nqnyh + 1
957  DO 445 jb = 1,nq
958  i1 = i1 - nyh
959 Cdir$ ivdep
960  DO 440 i = i1,nqnyh
961  440 yh1(i) = yh1(i) - yh1(i+nyh)
962  445 CONTINUE
963  IF (ierpj .LT. 0 .OR. iersl .LT. 0) GO TO 680
964  IF (abs(h) .LE. hmin*1.00001d0) GO TO 670
965  IF (ncf .EQ. mxncf) GO TO 670
966  rh = 0.25d0
967  ipup = miter
968  iredo = 1
969  GO TO 170
970 C-----------------------------------------------------------------------
971 C The corrector has converged. JCUR is set to 0
972 C to signal that the Jacobian involved may need updating later.
973 C The local error test is made and control passes to statement 500
974 C if it fails.
975 C-----------------------------------------------------------------------
976  450 jcur = 0
977  IF (m .EQ. 0) dsm = del/tesco(2,nq)
978  IF (m .GT. 0) dsm = dvnorm(n, acor, ewt)/tesco(2,nq)
979  IF (dsm .GT. 1.0d0) GO TO 500
980 C-----------------------------------------------------------------------
981 C After a successful step, update the YH array.
982 C Consider changing H if IALTH = 1. Otherwise decrease IALTH by 1.
983 C If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
984 C use in a possible order increase on the next step.
985 C If a change in H is considered, an increase or decrease in order
986 C by one is considered also. A change in H is made only if it is by a
987 C factor of at least 1.1. If not, IALTH is set to 3 to prevent
988 C testing for that many steps.
989 C-----------------------------------------------------------------------
990  kflag = 0
991  iredo = 0
992  nst = nst + 1
993  hu = h
994  nqu = nq
995  DO 470 j = 1,l
996  DO 470 i = 1,n
997  470 yh(i,j) = yh(i,j) + el(j)*acor(i)
998  ialth = ialth - 1
999  IF (ialth .EQ. 0) GO TO 520
1000  IF (ialth .GT. 1) GO TO 700
1001  IF (l .EQ. lmax) GO TO 700
1002  DO 490 i = 1,n
1003  490 yh(i,lmax) = acor(i)
1004  GO TO 700
1005 C-----------------------------------------------------------------------
1006 C The error test failed. KFLAG keeps track of multiple failures.
1007 C Restore TN and the YH array to their previous values, and prepare
1008 C to try the step again. Compute the optimum step size for this or
1009 C one lower order. After 2 or more failures, H is forced to decrease
1010 C by a factor of 0.2 or less.
1011 C-----------------------------------------------------------------------
1012  500 kflag = kflag - 1
1013  tn = told
1014  i1 = nqnyh + 1
1015  DO 515 jb = 1,nq
1016  i1 = i1 - nyh
1017 Cdir$ ivdep
1018  DO 510 i = i1,nqnyh
1019  510 yh1(i) = yh1(i) - yh1(i+nyh)
1020  515 CONTINUE
1021  rmax = 2.0d0
1022  IF (abs(h) .LE. hmin*1.00001d0) GO TO 660
1023  IF (kflag .LE. -3) GO TO 640
1024  iredo = 2
1025  rhup = 0.0d0
1026  GO TO 540
1027 C-----------------------------------------------------------------------
1028 C Regardless of the success or failure of the step, factors
1029 C RHDN, RHSM, and RHUP are computed, by which H could be multiplied
1030 C at order NQ - 1, order NQ, or order NQ + 1, respectively.
1031 C In the case of failure, RHUP = 0.0 to avoid an order increase.
1032 C The largest of these is determined and the new order chosen
1033 C accordingly. If the order is to be increased, we compute one
1034 C additional scaled derivative.
1035 C-----------------------------------------------------------------------
1036  520 rhup = 0.0d0
1037  IF (l .EQ. lmax) GO TO 540
1038  DO 530 i = 1,n
1039  530 savf(i) = acor(i) - yh(i,lmax)
1040  dup = dvnorm(n, savf, ewt)/tesco(3,nq)
1041  exup = 1.0d0/(l+1)
1042  rhup = 1.0d0/(1.4d0*dup**exup + 0.0000014d0)
1043  540 exsm = 1.0d0/l
1044  rhsm = 1.0d0/(1.2d0*dsm**exsm + 0.0000012d0)
1045  rhdn = 0.0d0
1046  IF (nq .EQ. 1) GO TO 560
1047  ddn = dvnorm(n, yh(1,l), ewt)/tesco(1,nq)
1048  exdn = 1.0d0/nq
1049  rhdn = 1.0d0/(1.3d0*ddn**exdn + 0.0000013d0)
1050  560 IF (rhsm .GE. rhup) GO TO 570
1051  IF (rhup .GT. rhdn) GO TO 590
1052  GO TO 580
1053  570 IF (rhsm .LT. rhdn) GO TO 580
1054  newq = nq
1055  rh = rhsm
1056  GO TO 620
1057  580 newq = nq - 1
1058  rh = rhdn
1059  IF (kflag .LT. 0 .AND. rh .GT. 1.0d0) rh = 1.0d0
1060  GO TO 620
1061  590 newq = l
1062  rh = rhup
1063  IF (rh .LT. 1.1d0) GO TO 610
1064  r = el(l)/l
1065  DO 600 i = 1,n
1066  600 yh(i,newq+1) = acor(i)*r
1067  GO TO 630
1068  610 ialth = 3
1069  GO TO 700
1070  620 IF ((kflag .EQ. 0) .AND. (rh .LT. 1.1d0)) GO TO 610
1071  IF (kflag .LE. -2) rh = min(rh,0.2d0)
1072 C-----------------------------------------------------------------------
1073 C If there is a change of order, reset NQ, l, and the coefficients.
1074 C In any case H is reset according to RH and the YH array is rescaled.
1075 C Then exit from 690 if the step was OK, or redo the step otherwise.
1076 C-----------------------------------------------------------------------
1077  IF (newq .EQ. nq) GO TO 170
1078  630 nq = newq
1079  l = nq + 1
1080  iret = 2
1081  GO TO 150
1082 C-----------------------------------------------------------------------
1083 C Control reaches this section if 3 or more failures have occured.
1084 C If 10 failures have occurred, exit with KFLAG = -1.
1085 C It is assumed that the derivatives that have accumulated in the
1086 C YH array have errors of the wrong order. Hence the first
1087 C derivative is recomputed, and the order is set to 1. Then
1088 C H is reduced by a factor of 10, and the step is retried,
1089 C until it succeeds or H reaches HMIN.
1090 C-----------------------------------------------------------------------
1091  640 IF (kflag .EQ. -10) GO TO 660
1092  rh = 0.1d0
1093  rh = max(hmin/abs(h),rh)
1094  h = h*rh
1095  DO 645 i = 1,n
1096  645 y(i) = yh(i,1)
1097  CALL f (neq, tn, y, savf)
1098  nfe = nfe + 1
1099  DO 650 i = 1,n
1100  650 yh(i,2) = h*savf(i)
1101  ipup = miter
1102  ialth = 5
1103  IF (nq .EQ. 1) GO TO 200
1104  nq = 1
1105  l = 2
1106  iret = 3
1107  GO TO 150
1108 C-----------------------------------------------------------------------
1109 C All returns are made through this section. H is saved in HOLD
1110 C to allow the caller to change H on the next step.
1111 C-----------------------------------------------------------------------
1112  660 kflag = -1
1113  GO TO 720
1114  670 kflag = -2
1115  GO TO 720
1116  680 kflag = -3
1117  GO TO 720
1118  690 rmax = 10.0d0
1119  700 r = 1.0d0/tesco(2,nqu)
1120  DO 710 i = 1,n
1121  710 acor(i) = acor(i)*r
1122  720 hold = h
1123  jstart = 1
1124  RETURN
1125 C----------------------- END OF SUBROUTINE DSTODE ----------------------
1126  END
1127 *DECK DEWSET
1128  SUBROUTINE dewset (N, ITOL, RTOL, ATOL, YCUR, EWT)
1129 C***BEGIN PROLOGUE DEWSET
1130 C***SUBSIDIARY
1131 C***PURPOSE Set error weight vector.
1132 C***TYPE DOUBLE PRECISION (SEWSET-S, DEWSET-D)
1133 C***AUTHOR Hindmarsh, Alan C., (LLNL)
1134 C***DESCRIPTION
1135 C
1136 C This subroutine sets the error weight vector EWT according to
1137 C EWT(i) = RTOL(i)*ABS(YCUR(i)) + ATOL(i), i = 1,...,N,
1138 C with the subscript on RTOL and/or ATOL possibly replaced by 1 above,
1139 C depending on the value of ITOL.
1140 C
1141 C***SEE ALSO DLSODE
1142 C***ROUTINES CALLED (NONE)
1143 C***REVISION HISTORY (YYMMDD)
1144 C 791129 DATE WRITTEN
1145 C 890501 Modified prologue to SLATEC/LDOC format. (FNF)
1146 C 890503 Minor cosmetic changes. (FNF)
1147 C 930809 Renamed to allow single/double precision versions. (ACH)
1148 C***END PROLOGUE DEWSET
1149 C**End
1150  INTEGER n, itol
1151  INTEGER i
1152  DOUBLE PRECISION rtol, atol, ycur, ewt
1153  dimension rtol(*), atol(*), ycur(n), ewt(n)
1154 C
1155 C***FIRST EXECUTABLE STATEMENT DEWSET
1156  GO TO (10, 20, 30, 40), itol
1157  10 CONTINUE
1158  DO 15 i = 1,n
1159  15 ewt(i) = rtol(1)*abs(ycur(i)) + atol(1)
1160  RETURN
1161  20 CONTINUE
1162  DO 25 i = 1,n
1163  25 ewt(i) = rtol(1)*abs(ycur(i)) + atol(i)
1164  RETURN
1165  30 CONTINUE
1166  DO 35 i = 1,n
1167  35 ewt(i) = rtol(i)*abs(ycur(i)) + atol(1)
1168  RETURN
1169  40 CONTINUE
1170  DO 45 i = 1,n
1171  45 ewt(i) = rtol(i)*abs(ycur(i)) + atol(i)
1172  RETURN
1173 C----------------------- END OF SUBROUTINE DEWSET ----------------------
1174  END
1175 *DECK DVNORM
1176  DOUBLE PRECISION FUNCTION dvnorm (N, V, W)
1177 C***BEGIN PROLOGUE DVNORM
1178 C***SUBSIDIARY
1179 C***PURPOSE Weighted root-mean-square vector norm.
1180 C***TYPE DOUBLE PRECISION (SVNORM-S, DVNORM-D)
1181 C***AUTHOR Hindmarsh, Alan C., (LLNL)
1182 C***DESCRIPTION
1183 C
1184 C This function routine computes the weighted root-mean-square norm
1185 C of the vector of length N contained in the array V, with weights
1186 C contained in the array W of length N:
1187 C DVNORM = SQRT( (1/N) * SUM( V(i)*W(i) )**2 )
1188 C
1189 C***SEE ALSO DLSODE
1190 C***ROUTINES CALLED (NONE)
1191 C***REVISION HISTORY (YYMMDD)
1192 C 791129 DATE WRITTEN
1193 C 890501 Modified prologue to SLATEC/LDOC format. (FNF)
1194 C 890503 Minor cosmetic changes. (FNF)
1195 C 930809 Renamed to allow single/double precision versions. (ACH)
1196 C***END PROLOGUE DVNORM
1197 C**End
1198  INTEGER n, i
1199  DOUBLE PRECISION v, w, sum
1200  dimension v(n), w(n)
1201 C
1202 C***FIRST EXECUTABLE STATEMENT DVNORM
1203  sum = 0.0d0
1204  DO 10 i = 1,n
1205  10 sum = sum + (v(i)*w(i))**2
1206  dvnorm = sqrt(sum/n)
1207  RETURN
1208 C----------------------- END OF FUNCTION DVNORM ------------------------
1209  END
1210 *DECK DIPREP
1211  SUBROUTINE diprep (NEQ, Y, RWORK, IA, JA, IPFLAG, F, JAC)
1212  EXTERNAL f, jac
1213  INTEGER neq, ia, ja, ipflag
1214  DOUBLE PRECISION y, rwork
1215  dimension neq(*), y(*), rwork(*), ia(*), ja(*)
1216  INTEGER iownd, iowns,
1217  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
1218  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
1219  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
1220  INTEGER iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
1221  1 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
1222  2 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
1223  3 nslj, ngp, nlu, nnz, nsp, nzl, nzu
1224  DOUBLE PRECISION rowns,
1225  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
1226  DOUBLE PRECISION rlss
1227  COMMON /dls001/ rowns(209),
1228  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
1229  2 iownd(6), iowns(6),
1230  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
1231  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
1232  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
1233  COMMON /dlss01/ rlss(6),
1234  1 iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
1235  2 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
1236  3 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
1237  4 nslj, ngp, nlu, nnz, nsp, nzl, nzu
1238  INTEGER i, imax, lewtn, lyhd, lyhn
1239 C-----------------------------------------------------------------------
1240 C This routine serves as an interface between the driver and
1241 C Subroutine DPREP. It is called only if MITER is 1 or 2.
1242 C Tasks performed here are:
1243 C * call DPREP,
1244 C * reset the required WM segment length LENWK,
1245 C * move YH back to its final location (following WM in RWORK),
1246 C * reset pointers for YH, SAVF, EWT, and ACOR, and
1247 C * move EWT to its new position if ISTATE = 1.
1248 C IPFLAG is an output error indication flag. IPFLAG = 0 if there was
1249 C no trouble, and IPFLAG is the value of the DPREP error flag IPPER
1250 C if there was trouble in Subroutine DPREP.
1251 C-----------------------------------------------------------------------
1252  ipflag = 0
1253 C Call DPREP to do matrix preprocessing operations. --------------------
1254  CALL dprep (neq, y, rwork(lyh), rwork(lsavf), rwork(lewt),
1255  1 rwork(lacor), ia, ja, rwork(lwm), rwork(lwm), ipflag, f, jac)
1256  lenwk = max(lreq,lwmin)
1257  IF (ipflag .LT. 0) RETURN
1258 C If DPREP was successful, move YH to end of required space for WM. ----
1259  lyhn = lwm + lenwk
1260  IF (lyhn .GT. lyh) RETURN
1261  lyhd = lyh - lyhn
1262  IF (lyhd .EQ. 0) GO TO 20
1263  imax = lyhn - 1 + lenyhm
1264  DO 10 i = lyhn,imax
1265  10 rwork(i) = rwork(i+lyhd)
1266  lyh = lyhn
1267 C Reset pointers for SAVF, EWT, and ACOR. ------------------------------
1268  20 lsavf = lyh + lenyh
1269  lewtn = lsavf + n
1270  lacor = lewtn + n
1271  IF (istatc .EQ. 3) GO TO 40
1272 C If ISTATE = 1, move EWT (left) to its new position. ------------------
1273  IF (lewtn .GT. lewt) RETURN
1274  DO 30 i = 1,n
1275  30 rwork(i+lewtn-1) = rwork(i+lewt-1)
1276  40 lewt = lewtn
1277  RETURN
1278 C----------------------- End of Subroutine DIPREP ----------------------
1279  END
1280 *DECK DPREP
1281  SUBROUTINE dprep (NEQ, Y, YH, SAVF, EWT, FTEM, IA, JA,
1282  1 WK, IWK, IPPER, F, JAC)
1283  EXTERNAL f,jac
1284  INTEGER neq, ia, ja, iwk, ipper
1285  DOUBLE PRECISION y, yh, savf, ewt, ftem, wk
1286  dimension neq(*), y(*), yh(*), savf(*), ewt(*), ftem(*),
1287  1 ia(*), ja(*), wk(*), iwk(*)
1288  INTEGER iownd, iowns,
1289  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
1290  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
1291  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
1292  INTEGER iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
1293  1 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
1294  2 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
1295  3 nslj, ngp, nlu, nnz, nsp, nzl, nzu
1296  DOUBLE PRECISION rowns,
1297  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
1298  DOUBLE PRECISION con0, conmin, ccmxj, psmall, rbig, seth
1299  COMMON /dls001/ rowns(209),
1300  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
1301  2 iownd(6), iowns(6),
1302  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
1303  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
1304  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
1305  COMMON /dlss01/ con0, conmin, ccmxj, psmall, rbig, seth,
1306  1 iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
1307  2 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
1308  3 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
1309  4 nslj, ngp, nlu, nnz, nsp, nzl, nzu
1310  INTEGER i, ibr, ier, ipil, ipiu, iptt1, iptt2, j, jfound, k,
1311  1 knew, kmax, kmin, ldif, lenigp, liwk, maxg, np1, nzsut
1312  DOUBLE PRECISION dq, dyj, erwt, fac, yj
1313 C-----------------------------------------------------------------------
1314 C This routine performs preprocessing related to the sparse linear
1315 C systems that must be solved if MITER = 1 or 2.
1316 C The operations that are performed here are:
1317 C * compute sparseness structure of Jacobian according to MOSS,
1318 C * compute grouping of column indices (MITER = 2),
1319 C * compute a new ordering of rows and columns of the matrix,
1320 C * reorder JA corresponding to the new ordering,
1321 C * perform a symbolic LU factorization of the matrix, and
1322 C * set pointers for segments of the IWK/WK array.
1323 C In addition to variables described previously, DPREP uses the
1324 C following for communication:
1325 C YH = the history array. Only the first column, containing the
1326 C current Y vector, is used. Used only if MOSS .ne. 0.
1327 C SAVF = a work array of length NEQ, used only if MOSS .ne. 0.
1328 C EWT = array of length NEQ containing (inverted) error weights.
1329 C Used only if MOSS = 2 or if ISTATE = MOSS = 1.
1330 C FTEM = a work array of length NEQ, identical to ACOR in the driver,
1331 C used only if MOSS = 2.
1332 C WK = a real work array of length LENWK, identical to WM in
1333 C the driver.
1334 C IWK = integer work array, assumed to occupy the same space as WK.
1335 C LENWK = the length of the work arrays WK and IWK.
1336 C ISTATC = a copy of the driver input argument ISTATE (= 1 on the
1337 C first call, = 3 on a continuation call).
1338 C IYS = flag value from ODRV or CDRV.
1339 C IPPER = output error flag with the following values and meanings:
1340 C 0 no error.
1341 C -1 insufficient storage for internal structure pointers.
1342 C -2 insufficient storage for JGROUP.
1343 C -3 insufficient storage for ODRV.
1344 C -4 other error flag from ODRV (should never occur).
1345 C -5 insufficient storage for CDRV.
1346 C -6 other error flag from CDRV.
1347 C-----------------------------------------------------------------------
1348  ibian = lrat*2
1349  ipian = ibian + 1
1350  np1 = n + 1
1351  ipjan = ipian + np1
1352  ibjan = ipjan - 1
1353  liwk = lenwk*lrat
1354  IF (ipjan+n-1 .GT. liwk) GO TO 210
1355  IF (moss .EQ. 0) GO TO 30
1356 C
1357  IF (istatc .EQ. 3) GO TO 20
1358 C ISTATE = 1 and MOSS .ne. 0. Perturb Y for structure determination. --
1359  DO 10 i = 1,n
1360  erwt = 1.0d0/ewt(i)
1361  fac = 1.0d0 + 1.0d0/(i + 1.0d0)
1362  y(i) = y(i) + fac*sign(erwt,y(i))
1363  10 CONTINUE
1364  GO TO (70, 100), moss
1365 C
1366  20 CONTINUE
1367 C ISTATE = 3 and MOSS .ne. 0. Load Y from YH(*,1). --------------------
1368  DO 25 i = 1,n
1369  25 y(i) = yh(i)
1370  GO TO (70, 100), moss
1371 C
1372 C MOSS = 0. Process user's IA,JA. Add diagonal entries if necessary. -
1373  30 knew = ipjan
1374  kmin = ia(1)
1375  iwk(ipian) = 1
1376  DO 60 j = 1,n
1377  jfound = 0
1378  kmax = ia(j+1) - 1
1379  IF (kmin .GT. kmax) GO TO 45
1380  DO 40 k = kmin,kmax
1381  i = ja(k)
1382  IF (i .EQ. j) jfound = 1
1383  IF (knew .GT. liwk) GO TO 210
1384  iwk(knew) = i
1385  knew = knew + 1
1386  40 CONTINUE
1387  IF (jfound .EQ. 1) GO TO 50
1388  45 IF (knew .GT. liwk) GO TO 210
1389  iwk(knew) = j
1390  knew = knew + 1
1391  50 iwk(ipian+j) = knew + 1 - ipjan
1392  kmin = kmax + 1
1393  60 CONTINUE
1394  GO TO 140
1395 C
1396 C MOSS = 1. Compute structure from user-supplied Jacobian routine JAC.
1397  70 CONTINUE
1398 C A dummy call to F allows user to create temporaries for use in JAC. --
1399  CALL f (neq, tn, y, savf)
1400  k = ipjan
1401  iwk(ipian) = 1
1402  DO 90 j = 1,n
1403  IF (k .GT. liwk) GO TO 210
1404  iwk(k) = j
1405  k = k + 1
1406  DO 75 i = 1,n
1407  75 savf(i) = 0.0d0
1408  CALL jac (neq, tn, y, j, iwk(ipian), iwk(ipjan), savf)
1409  DO 80 i = 1,n
1410  IF (abs(savf(i)) .LE. seth) GO TO 80
1411  IF (i .EQ. j) GO TO 80
1412  IF (k .GT. liwk) GO TO 210
1413  iwk(k) = i
1414  k = k + 1
1415  80 CONTINUE
1416  iwk(ipian+j) = k + 1 - ipjan
1417  90 CONTINUE
1418  GO TO 140
1419 C
1420 C MOSS = 2. Compute structure from results of N + 1 calls to F. -------
1421  100 k = ipjan
1422  iwk(ipian) = 1
1423  CALL f (neq, tn, y, savf)
1424  DO 120 j = 1,n
1425  IF (k .GT. liwk) GO TO 210
1426  iwk(k) = j
1427  k = k + 1
1428  yj = y(j)
1429  erwt = 1.0d0/ewt(j)
1430  dyj = sign(erwt,yj)
1431  y(j) = yj + dyj
1432  CALL f (neq, tn, y, ftem)
1433  y(j) = yj
1434  DO 110 i = 1,n
1435  dq = (ftem(i) - savf(i))/dyj
1436  IF (abs(dq) .LE. seth) GO TO 110
1437  IF (i .EQ. j) GO TO 110
1438  IF (k .GT. liwk) GO TO 210
1439  iwk(k) = i
1440  k = k + 1
1441  110 CONTINUE
1442  iwk(ipian+j) = k + 1 - ipjan
1443  120 CONTINUE
1444 C
1445  140 CONTINUE
1446  IF (moss .EQ. 0 .OR. istatc .NE. 1) GO TO 150
1447 C If ISTATE = 1 and MOSS .ne. 0, restore Y from YH. --------------------
1448  DO 145 i = 1,n
1449  145 y(i) = yh(i)
1450  150 nnz = iwk(ipian+n) - 1
1451  lenigp = 0
1452  ipigp = ipjan + nnz
1453  IF (miter .NE. 2) GO TO 160
1454 C
1455 C Compute grouping of column indices (MITER = 2). ----------------------
1456  maxg = np1
1457  ipjgp = ipjan + nnz
1458  ibjgp = ipjgp - 1
1459  ipigp = ipjgp + n
1460  iptt1 = ipigp + np1
1461  iptt2 = iptt1 + n
1462  lreq = iptt2 + n - 1
1463  IF (lreq .GT. liwk) GO TO 220
1464  CALL jgroup (n, iwk(ipian), iwk(ipjan), maxg, ngp, iwk(ipigp),
1465  1 iwk(ipjgp), iwk(iptt1), iwk(iptt2), ier)
1466  IF (ier .NE. 0) GO TO 220
1467  lenigp = ngp + 1
1468 C
1469 C Compute new ordering of rows/columns of Jacobian. --------------------
1470  160 ipr = ipigp + lenigp
1471  ipc = ipr
1472  ipic = ipc + n
1473  ipisp = ipic + n
1474  iprsp = (ipisp - 2)/lrat + 2
1475  iesp = lenwk + 1 - iprsp
1476  IF (iesp .LT. 0) GO TO 230
1477  ibr = ipr - 1
1478  DO 170 i = 1,n
1479  170 iwk(ibr+i) = i
1480  nsp = liwk + 1 - ipisp
1481  CALL odrv (n, iwk(ipian), iwk(ipjan), wk, iwk(ipr), iwk(ipic),
1482  1 nsp, iwk(ipisp), 1, iys)
1483  IF (iys .EQ. 11*n+1) GO TO 240
1484  IF (iys .NE. 0) GO TO 230
1485 C
1486 C Reorder JAN and do symbolic LU factorization of matrix. --------------
1487  ipa = lenwk + 1 - nnz
1488  nsp = ipa - iprsp
1489  lreq = max(12*n/lrat, 6*n/lrat+2*n+nnz) + 3
1490  lreq = lreq + iprsp - 1 + nnz
1491  IF (lreq .GT. lenwk) GO TO 250
1492  iba = ipa - 1
1493  DO 180 i = 1,nnz
1494  180 wk(iba+i) = 0.0d0
1495  ipisp = lrat*(iprsp - 1) + 1
1496  CALL cdrv (n,iwk(ipr),iwk(ipc),iwk(ipic),iwk(ipian),iwk(ipjan),
1497  1 wk(ipa),wk(ipa),wk(ipa),nsp,iwk(ipisp),wk(iprsp),iesp,5,iys)
1498  lreq = lenwk - iesp
1499  IF (iys .EQ. 10*n+1) GO TO 250
1500  IF (iys .NE. 0) GO TO 260
1501  ipil = ipisp
1502  ipiu = ipil + 2*n + 1
1503  nzu = iwk(ipil+n) - iwk(ipil)
1504  nzl = iwk(ipiu+n) - iwk(ipiu)
1505  IF (lrat .GT. 1) GO TO 190
1506  CALL adjlr (n, iwk(ipisp), ldif)
1507  lreq = lreq + ldif
1508  190 CONTINUE
1509  IF (lrat .EQ. 2 .AND. nnz .EQ. n) lreq = lreq + 1
1510  nsp = nsp + lreq - lenwk
1511  ipa = lreq + 1 - nnz
1512  iba = ipa - 1
1513  ipper = 0
1514  RETURN
1515 C
1516  210 ipper = -1
1517  lreq = 2 + (2*n + 1)/lrat
1518  lreq = max(lenwk+1,lreq)
1519  RETURN
1520 C
1521  220 ipper = -2
1522  lreq = (lreq - 1)/lrat + 1
1523  RETURN
1524 C
1525  230 ipper = -3
1526  CALL cntnzu (n, iwk(ipian), iwk(ipjan), nzsut)
1527  lreq = lenwk - iesp + (3*n + 4*nzsut - 1)/lrat + 1
1528  RETURN
1529 C
1530  240 ipper = -4
1531  RETURN
1532 C
1533  250 ipper = -5
1534  RETURN
1535 C
1536  260 ipper = -6
1537  lreq = lenwk
1538  RETURN
1539 C----------------------- End of Subroutine DPREP -----------------------
1540  END
1541 *DECK JGROUP
1542  SUBROUTINE jgroup (N,IA,JA,MAXG,NGRP,IGP,JGP,INCL,JDONE,IER)
1543  INTEGER n, ia, ja, maxg, ngrp, igp, jgp, incl, jdone, ier
1544  dimension ia(*), ja(*), igp(*), jgp(*), incl(*), jdone(*)
1545 C-----------------------------------------------------------------------
1546 C This subroutine constructs groupings of the column indices of
1547 C the Jacobian matrix, used in the numerical evaluation of the
1548 C Jacobian by finite differences.
1549 C
1550 C Input:
1551 C N = the order of the matrix.
1552 C IA,JA = sparse structure descriptors of the matrix by rows.
1553 C MAXG = length of available storage in the IGP array.
1554 C
1555 C Output:
1556 C NGRP = number of groups.
1557 C JGP = array of length N containing the column indices by groups.
1558 C IGP = pointer array of length NGRP + 1 to the locations in JGP
1559 C of the beginning of each group.
1560 C IER = error indicator. IER = 0 if no error occurred, or 1 if
1561 C MAXG was insufficient.
1562 C
1563 C INCL and JDONE are working arrays of length N.
1564 C-----------------------------------------------------------------------
1565  INTEGER i, j, k, kmin, kmax, ncol, ng
1566 C
1567  ier = 0
1568  DO 10 j = 1,n
1569  10 jdone(j) = 0
1570  ncol = 1
1571  DO 60 ng = 1,maxg
1572  igp(ng) = ncol
1573  DO 20 i = 1,n
1574  20 incl(i) = 0
1575  DO 50 j = 1,n
1576 C Reject column J if it is already in a group.--------------------------
1577  IF (jdone(j) .EQ. 1) GO TO 50
1578  kmin = ia(j)
1579  kmax = ia(j+1) - 1
1580  DO 30 k = kmin,kmax
1581 C Reject column J if it overlaps any column already in this group.------
1582  i = ja(k)
1583  IF (incl(i) .EQ. 1) GO TO 50
1584  30 CONTINUE
1585 C Accept column J into group NG.----------------------------------------
1586  jgp(ncol) = j
1587  ncol = ncol + 1
1588  jdone(j) = 1
1589  DO 40 k = kmin,kmax
1590  i = ja(k)
1591  40 incl(i) = 1
1592  50 CONTINUE
1593 C Stop if this group is empty (grouping is complete).-------------------
1594  IF (ncol .EQ. igp(ng)) GO TO 70
1595  60 CONTINUE
1596 C Error return if not all columns were chosen (MAXG too small).---------
1597  IF (ncol .LE. n) GO TO 80
1598  ng = maxg
1599  70 ngrp = ng - 1
1600  RETURN
1601  80 ier = 1
1602  RETURN
1603 C----------------------- End of Subroutine JGROUP ----------------------
1604  END
1605 *DECK ADJLR
1606  SUBROUTINE adjlr (N, ISP, LDIF)
1607  INTEGER n, isp, ldif
1608  dimension isp(*)
1609 C-----------------------------------------------------------------------
1610 C This routine computes an adjustment, LDIF, to the required
1611 C integer storage space in IWK (sparse matrix work space).
1612 C It is called only if the word length ratio is LRAT = 1.
1613 C This is to account for the possibility that the symbolic LU phase
1614 C may require more storage than the numerical LU and solution phases.
1615 C-----------------------------------------------------------------------
1616  INTEGER ip, jlmax, jumax, lnfc, lsfc, nzlu
1617 C
1618  ip = 2*n + 1
1619 C Get JLMAX = IJL(N) and JUMAX = IJU(N) (sizes of JL and JU). ----------
1620  jlmax = isp(ip)
1621  jumax = isp(ip+ip)
1622 C NZLU = (size of L) + (size of U) = (IL(N+1)-IL(1)) + (IU(N+1)-IU(1)).
1623  nzlu = isp(n+1) - isp(1) + isp(ip+n+1) - isp(ip+1)
1624  lsfc = 12*n + 3 + 2*max(jlmax,jumax)
1625  lnfc = 9*n + 2 + jlmax + jumax + nzlu
1626  ldif = max(0, lsfc - lnfc)
1627  RETURN
1628 C----------------------- End of Subroutine ADJLR -----------------------
1629  END
1630 *DECK CNTNZU
1631  SUBROUTINE cntnzu (N, IA, JA, NZSUT)
1632  INTEGER n, ia, ja, nzsut
1633  dimension ia(*), ja(*)
1634 C-----------------------------------------------------------------------
1635 C This routine counts the number of nonzero elements in the strict
1636 C upper triangle of the matrix M + M(transpose), where the sparsity
1637 C structure of M is given by pointer arrays IA and JA.
1638 C This is needed to compute the storage requirements for the
1639 C sparse matrix reordering operation in ODRV.
1640 C-----------------------------------------------------------------------
1641  INTEGER ii, jj, j, jmin, jmax, k, kmin, kmax, num
1642 C
1643  num = 0
1644  DO 50 ii = 1,n
1645  jmin = ia(ii)
1646  jmax = ia(ii+1) - 1
1647  IF (jmin .GT. jmax) GO TO 50
1648  DO 40 j = jmin,jmax
1649  IF (ja(j) - ii) 10, 40, 30
1650  10 jj =ja(j)
1651  kmin = ia(jj)
1652  kmax = ia(jj+1) - 1
1653  IF (kmin .GT. kmax) GO TO 30
1654  DO 20 k = kmin,kmax
1655  IF (ja(k) .EQ. ii) GO TO 40
1656  20 CONTINUE
1657  30 num = num + 1
1658  40 CONTINUE
1659  50 CONTINUE
1660  nzsut = num
1661  RETURN
1662 C----------------------- End of Subroutine CNTNZU ----------------------
1663  END
1664 *DECK DPRJS
1665  SUBROUTINE dprjs (NEQ,Y,YH,NYH,EWT,FTEM,SAVF,WK,IWK,F,JAC)
1666  EXTERNAL f,jac
1667  INTEGER neq, nyh, iwk
1668  DOUBLE PRECISION y, yh, ewt, ftem, savf, wk
1669  dimension neq(*), y(*), yh(nyh,*), ewt(*), ftem(*), savf(*),
1670  1 wk(*), iwk(*)
1671  INTEGER iownd, iowns,
1672  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
1673  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
1674  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
1675  INTEGER iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
1676  1 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
1677  2 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
1678  3 nslj, ngp, nlu, nnz, nsp, nzl, nzu
1679  DOUBLE PRECISION rowns,
1680  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
1681  DOUBLE PRECISION con0, conmin, ccmxj, psmall, rbig, seth
1682  COMMON /dls001/ rowns(209),
1683  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
1684  2 iownd(6), iowns(6),
1685  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
1686  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
1687  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
1688  COMMON /dlss01/ con0, conmin, ccmxj, psmall, rbig, seth,
1689  1 iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
1690  2 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
1691  3 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
1692  4 nslj, ngp, nlu, nnz, nsp, nzl, nzu
1693  INTEGER i, imul, j, jj, jok, jmax, jmin, k, kmax, kmin, ng
1694  DOUBLE PRECISION con, di, fac, hl0, pij, r, r0, rcon, rcont,
1695  1 srur, dvnorm
1696 C-----------------------------------------------------------------------
1697 C DPRJS is called to compute and process the matrix
1698 C P = I - H*EL(1)*J , where J is an approximation to the Jacobian.
1699 C J is computed by columns, either by the user-supplied routine JAC
1700 C if MITER = 1, or by finite differencing if MITER = 2.
1701 C if MITER = 3, a diagonal approximation to J is used.
1702 C if MITER = 1 or 2, and if the existing value of the Jacobian
1703 C (as contained in P) is considered acceptable, then a new value of
1704 C P is reconstructed from the old value. In any case, when MITER
1705 C is 1 or 2, the P matrix is subjected to LU decomposition in CDRV.
1706 C P and its LU decomposition are stored (separately) in WK.
1707 C
1708 C In addition to variables described previously, communication
1709 C with DPRJS uses the following:
1710 C Y = array containing predicted values on entry.
1711 C FTEM = work array of length N (ACOR in DSTODE).
1712 C SAVF = array containing f evaluated at predicted y.
1713 C WK = real work space for matrices. On output it contains the
1714 C inverse diagonal matrix if MITER = 3, and P and its sparse
1715 C LU decomposition if MITER is 1 or 2.
1716 C Storage of matrix elements starts at WK(3).
1717 C WK also contains the following matrix-related data:
1718 C WK(1) = SQRT(UROUND), used in numerical Jacobian increments.
1719 C WK(2) = H*EL0, saved for later use if MITER = 3.
1720 C IWK = integer work space for matrix-related data, assumed to
1721 C be equivalenced to WK. In addition, WK(IPRSP) and IWK(IPISP)
1722 C are assumed to have identical locations.
1723 C EL0 = EL(1) (input).
1724 C IERPJ = output error flag (in Common).
1725 C = 0 if no error.
1726 C = 1 if zero pivot found in CDRV.
1727 C = 2 if a singular matrix arose with MITER = 3.
1728 C = -1 if insufficient storage for CDRV (should not occur here).
1729 C = -2 if other error found in CDRV (should not occur here).
1730 C JCUR = output flag showing status of (approximate) Jacobian matrix:
1731 C = 1 to indicate that the Jacobian is now current, or
1732 C = 0 to indicate that a saved value was used.
1733 C This routine also uses other variables in Common.
1734 C-----------------------------------------------------------------------
1735  hl0 = h*el0
1736  con = -hl0
1737  IF (miter .EQ. 3) GO TO 300
1738 C See whether J should be reevaluated (JOK = 0) or not (JOK = 1). ------
1739  jok = 1
1740  IF (nst .EQ. 0 .OR. nst .GE. nslj+msbj) jok = 0
1741  IF (icf .EQ. 1 .AND. abs(rc - 1.0d0) .LT. ccmxj) jok = 0
1742  IF (icf .EQ. 2) jok = 0
1743  IF (jok .EQ. 1) GO TO 250
1744 C
1745 C MITER = 1 or 2, and the Jacobian is to be reevaluated. ---------------
1746  20 jcur = 1
1747  nje = nje + 1
1748  nslj = nst
1749  iplost = 0
1750  conmin = abs(con)
1751  GO TO (100, 200), miter
1752 C
1753 C If MITER = 1, call JAC, multiply by scalar, and add identity. --------
1754  100 CONTINUE
1755  kmin = iwk(ipian)
1756  DO 130 j = 1, n
1757  kmax = iwk(ipian+j) - 1
1758  DO 110 i = 1,n
1759  110 ftem(i) = 0.0d0
1760  CALL jac (neq, tn, y, j, iwk(ipian), iwk(ipjan), ftem)
1761  DO 120 k = kmin, kmax
1762  i = iwk(ibjan+k)
1763  wk(iba+k) = ftem(i)*con
1764  IF (i .EQ. j) wk(iba+k) = wk(iba+k) + 1.0d0
1765  120 CONTINUE
1766  kmin = kmax + 1
1767  130 CONTINUE
1768  GO TO 290
1769 C
1770 C If MITER = 2, make NGP calls to F to approximate J and P. ------------
1771  200 CONTINUE
1772  fac = dvnorm(n, savf, ewt)
1773  r0 = 1000.0d0 * abs(h) * uround * n * fac
1774  IF (r0 .EQ. 0.0d0) r0 = 1.0d0
1775  srur = wk(1)
1776  jmin = iwk(ipigp)
1777  DO 240 ng = 1,ngp
1778  jmax = iwk(ipigp+ng) - 1
1779  DO 210 j = jmin,jmax
1780  jj = iwk(ibjgp+j)
1781  r = max(srur*abs(y(jj)),r0/ewt(jj))
1782  210 y(jj) = y(jj) + r
1783  CALL f (neq, tn, y, ftem)
1784  DO 230 j = jmin,jmax
1785  jj = iwk(ibjgp+j)
1786  y(jj) = yh(jj,1)
1787  r = max(srur*abs(y(jj)),r0/ewt(jj))
1788  fac = -hl0/r
1789  kmin =iwk(ibian+jj)
1790  kmax =iwk(ibian+jj+1) - 1
1791  DO 220 k = kmin,kmax
1792  i = iwk(ibjan+k)
1793  wk(iba+k) = (ftem(i) - savf(i))*fac
1794  IF (i .EQ. jj) wk(iba+k) = wk(iba+k) + 1.0d0
1795  220 CONTINUE
1796  230 CONTINUE
1797  jmin = jmax + 1
1798  240 CONTINUE
1799  nfe = nfe + ngp
1800  GO TO 290
1801 C
1802 C If JOK = 1, reconstruct new P from old P. ----------------------------
1803  250 jcur = 0
1804  rcon = con/con0
1805  rcont = abs(con)/conmin
1806  IF (rcont .GT. rbig .AND. iplost .EQ. 1) GO TO 20
1807  kmin = iwk(ipian)
1808  DO 275 j = 1,n
1809  kmax = iwk(ipian+j) - 1
1810  DO 270 k = kmin,kmax
1811  i = iwk(ibjan+k)
1812  pij = wk(iba+k)
1813  IF (i .NE. j) GO TO 260
1814  pij = pij - 1.0d0
1815  IF (abs(pij) .GE. psmall) GO TO 260
1816  iplost = 1
1817  conmin = min(abs(con0),conmin)
1818  260 pij = pij*rcon
1819  IF (i .EQ. j) pij = pij + 1.0d0
1820  wk(iba+k) = pij
1821  270 CONTINUE
1822  kmin = kmax + 1
1823  275 CONTINUE
1824 C
1825 C Do numerical factorization of P matrix. ------------------------------
1826  290 nlu = nlu + 1
1827  con0 = con
1828  ierpj = 0
1829  DO 295 i = 1,n
1830  295 ftem(i) = 0.0d0
1831  CALL cdrv (n,iwk(ipr),iwk(ipc),iwk(ipic),iwk(ipian),iwk(ipjan),
1832  1 wk(ipa),ftem,ftem,nsp,iwk(ipisp),wk(iprsp),iesp,2,iys)
1833  IF (iys .EQ. 0) RETURN
1834  imul = (iys - 1)/n
1835  ierpj = -2
1836  IF (imul .EQ. 8) ierpj = 1
1837  IF (imul .EQ. 10) ierpj = -1
1838  RETURN
1839 C
1840 C If MITER = 3, construct a diagonal approximation to J and P. ---------
1841  300 CONTINUE
1842  jcur = 1
1843  nje = nje + 1
1844  wk(2) = hl0
1845  ierpj = 0
1846  r = el0*0.1d0
1847  DO 310 i = 1,n
1848  310 y(i) = y(i) + r*(h*savf(i) - yh(i,2))
1849  CALL f (neq, tn, y, wk(3))
1850  nfe = nfe + 1
1851  DO 320 i = 1,n
1852  r0 = h*savf(i) - yh(i,2)
1853  di = 0.1d0*r0 - h*(wk(i+2) - savf(i))
1854  wk(i+2) = 1.0d0
1855  IF (abs(r0) .LT. uround/ewt(i)) GO TO 320
1856  IF (abs(di) .EQ. 0.0d0) GO TO 330
1857  wk(i+2) = 0.1d0*r0/di
1858  320 CONTINUE
1859  RETURN
1860  330 ierpj = 2
1861  RETURN
1862 C----------------------- End of Subroutine DPRJS -----------------------
1863  END
1864 *DECK DSOLSS
1865  SUBROUTINE dsolss (WK, IWK, X, TEM)
1866  INTEGER iwk
1867  DOUBLE PRECISION wk, x, tem
1868  dimension wk(*), iwk(*), x(*), tem(*)
1869  INTEGER iownd, iowns,
1870  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
1871  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
1872  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
1873  INTEGER iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
1874  1 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
1875  2 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
1876  3 nslj, ngp, nlu, nnz, nsp, nzl, nzu
1877  DOUBLE PRECISION rowns,
1878  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
1879  DOUBLE PRECISION rlss
1880  COMMON /dls001/ rowns(209),
1881  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
1882  2 iownd(6), iowns(6),
1883  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
1884  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
1885  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
1886  COMMON /dlss01/ rlss(6),
1887  1 iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
1888  2 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
1889  3 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
1890  4 nslj, ngp, nlu, nnz, nsp, nzl, nzu
1891  INTEGER i
1892  DOUBLE PRECISION di, hl0, phl0, r
1893 C-----------------------------------------------------------------------
1894 C This routine manages the solution of the linear system arising from
1895 C a chord iteration. It is called if MITER .ne. 0.
1896 C If MITER is 1 or 2, it calls CDRV to accomplish this.
1897 C If MITER = 3 it updates the coefficient H*EL0 in the diagonal
1898 C matrix, and then computes the solution.
1899 C communication with DSOLSS uses the following variables:
1900 C WK = real work space containing the inverse diagonal matrix if
1901 C MITER = 3 and the LU decomposition of the matrix otherwise.
1902 C Storage of matrix elements starts at WK(3).
1903 C WK also contains the following matrix-related data:
1904 C WK(1) = SQRT(UROUND) (not used here),
1905 C WK(2) = HL0, the previous value of H*EL0, used if MITER = 3.
1906 C IWK = integer work space for matrix-related data, assumed to
1907 C be equivalenced to WK. In addition, WK(IPRSP) and IWK(IPISP)
1908 C are assumed to have identical locations.
1909 C X = the right-hand side vector on input, and the solution vector
1910 C on output, of length N.
1911 C TEM = vector of work space of length N, not used in this version.
1912 C IERSL = output flag (in Common).
1913 C IERSL = 0 if no trouble occurred.
1914 C IERSL = -1 if CDRV returned an error flag (MITER = 1 or 2).
1915 C This should never occur and is considered fatal.
1916 C IERSL = 1 if a singular matrix arose with MITER = 3.
1917 C This routine also uses other variables in Common.
1918 C-----------------------------------------------------------------------
1919  iersl = 0
1920  GO TO (100, 100, 300), miter
1921  100 CALL cdrv (n,iwk(ipr),iwk(ipc),iwk(ipic),iwk(ipian),iwk(ipjan),
1922  1 wk(ipa),x,x,nsp,iwk(ipisp),wk(iprsp),iesp,4,iersl)
1923  IF (iersl .NE. 0) iersl = -1
1924  RETURN
1925 C
1926  300 phl0 = wk(2)
1927  hl0 = h*el0
1928  wk(2) = hl0
1929  IF (hl0 .EQ. phl0) GO TO 330
1930  r = hl0/phl0
1931  DO 320 i = 1,n
1932  di = 1.0d0 - r*(1.0d0 - 1.0d0/wk(i+2))
1933  IF (abs(di) .EQ. 0.0d0) GO TO 390
1934  320 wk(i+2) = 1.0d0/di
1935  330 DO 340 i = 1,n
1936  340 x(i) = wk(i+2)*x(i)
1937  RETURN
1938  390 iersl = 1
1939  RETURN
1940 C
1941 C----------------------- End of Subroutine DSOLSS ----------------------
1942  END
1943 *DECK DSRCMS
1944  SUBROUTINE dsrcms (RSAV, ISAV, JOB)
1945 C-----------------------------------------------------------------------
1946 C This routine saves or restores (depending on JOB) the contents of
1947 C the Common blocks DLS001, DLSS01, which are used
1948 C internally by one or more ODEPACK solvers.
1949 C
1950 C RSAV = real array of length 224 or more.
1951 C ISAV = integer array of length 71 or more.
1952 C JOB = flag indicating to save or restore the Common blocks:
1953 C JOB = 1 if Common is to be saved (written to RSAV/ISAV)
1954 C JOB = 2 if Common is to be restored (read from RSAV/ISAV)
1955 C A call with JOB = 2 presumes a prior call with JOB = 1.
1956 C-----------------------------------------------------------------------
1957  INTEGER isav, job
1958  INTEGER ils, ilss
1959  INTEGER i, lenils, leniss, lenrls, lenrss
1960  DOUBLE PRECISION rsav, rls, rlss
1961  dimension rsav(*), isav(*)
1962  SAVE lenrls, lenils, lenrss, leniss
1963  COMMON /dls001/ rls(218), ils(37)
1964  COMMON /dlss01/ rlss(6), ilss(34)
1965  DATA lenrls/218/, lenils/37/, lenrss/6/, leniss/34/
1966 C
1967  IF (job .EQ. 2) GO TO 100
1968  DO 10 i = 1,lenrls
1969  10 rsav(i) = rls(i)
1970  DO 15 i = 1,lenrss
1971  15 rsav(lenrls+i) = rlss(i)
1972 C
1973  DO 20 i = 1,lenils
1974  20 isav(i) = ils(i)
1975  DO 25 i = 1,leniss
1976  25 isav(lenils+i) = ilss(i)
1977 C
1978  RETURN
1979 C
1980  100 CONTINUE
1981  DO 110 i = 1,lenrls
1982  110 rls(i) = rsav(i)
1983  DO 115 i = 1,lenrss
1984  115 rlss(i) = rsav(lenrls+i)
1985 C
1986  DO 120 i = 1,lenils
1987  120 ils(i) = isav(i)
1988  DO 125 i = 1,leniss
1989  125 ilss(i) = isav(lenils+i)
1990 C
1991  RETURN
1992 C----------------------- End of Subroutine DSRCMS ----------------------
1993  END
1994 *DECK ODRV
1995  subroutine odrv
1996  * (n, ia,ja,a, p,ip, nsp,isp, path, flag)
1997 c 5/2/83
1998 c***********************************************************************
1999 c odrv -- driver for sparse matrix reordering routines
2000 c***********************************************************************
2001 c
2002 c description
2003 c
2004 c odrv finds a minimum degree ordering of the rows and columns
2005 c of a matrix m stored in (ia,ja,a) format (see below). for the
2006 c reordered matrix, the work and storage required to perform
2007 c gaussian elimination is (usually) significantly less.
2008 c
2009 c note.. odrv and its subordinate routines have been modified to
2010 c compute orderings for general matrices, not necessarily having any
2011 c symmetry. the miminum degree ordering is computed for the
2012 c structure of the symmetric matrix m + m-transpose.
2013 c modifications to the original odrv module have been made in
2014 c the coding in subroutine mdi, and in the initial comments in
2015 c subroutines odrv and md.
2016 c
2017 c if only the nonzero entries in the upper triangle of m are being
2018 c stored, then odrv symmetrically reorders (ia,ja,a), (optionally)
2019 c with the diagonal entries placed first in each row. this is to
2020 c ensure that if m(i,j) will be in the upper triangle of m with
2021 c respect to the new ordering, then m(i,j) is stored in row i (and
2022 c thus m(j,i) is not stored), whereas if m(i,j) will be in the
2023 c strict lower triangle of m, then m(j,i) is stored in row j (and
2024 c thus m(i,j) is not stored).
2025 c
2026 c
2027 c storage of sparse matrices
2028 c
2029 c the nonzero entries of the matrix m are stored row-by-row in the
2030 c array a. to identify the individual nonzero entries in each row,
2031 c we need to know in which column each entry lies. these column
2032 c indices are stored in the array ja. i.e., if a(k) = m(i,j), then
2033 c ja(k) = j. to identify the individual rows, we need to know where
2034 c each row starts. these row pointers are stored in the array ia.
2035 c i.e., if m(i,j) is the first nonzero entry (stored) in the i-th row
2036 c and a(k) = m(i,j), then ia(i) = k. moreover, ia(n+1) points to
2037 c the first location following the last element in the last row.
2038 c thus, the number of entries in the i-th row is ia(i+1) - ia(i),
2039 c the nonzero entries in the i-th row are stored consecutively in
2040 c
2041 c a(ia(i)), a(ia(i)+1), ..., a(ia(i+1)-1),
2042 c
2043 c and the corresponding column indices are stored consecutively in
2044 c
2045 c ja(ia(i)), ja(ia(i)+1), ..., ja(ia(i+1)-1).
2046 c
2047 c when the coefficient matrix is symmetric, only the nonzero entries
2048 c in the upper triangle need be stored. for example, the matrix
2049 c
2050 c ( 1 0 2 3 0 )
2051 c ( 0 4 0 0 0 )
2052 c m = ( 2 0 5 6 0 )
2053 c ( 3 0 6 7 8 )
2054 c ( 0 0 0 8 9 )
2055 c
2056 c could be stored as
2057 c
2058 c - 1 2 3 4 5 6 7 8 9 10 11 12 13
2059 c ---+--------------------------------------
2060 c ia - 1 4 5 8 12 14
2061 c ja - 1 3 4 2 1 3 4 1 3 4 5 4 5
2062 c a - 1 2 3 4 2 5 6 3 6 7 8 8 9
2063 c
2064 c or (symmetrically) as
2065 c
2066 c - 1 2 3 4 5 6 7 8 9
2067 c ---+--------------------------
2068 c ia - 1 4 5 7 9 10
2069 c ja - 1 3 4 2 3 4 4 5 5
2070 c a - 1 2 3 4 5 6 7 8 9 .
2071 c
2072 c
2073 c parameters
2074 c
2075 c n - order of the matrix
2076 c
2077 c ia - integer one-dimensional array containing pointers to delimit
2078 c rows in ja and a. dimension = n+1
2079 c
2080 c ja - integer one-dimensional array containing the column indices
2081 c corresponding to the elements of a. dimension = number of
2082 c nonzero entries in (the upper triangle of) m
2083 c
2084 c a - real one-dimensional array containing the nonzero entries in
2085 c (the upper triangle of) m, stored by rows. dimension =
2086 c number of nonzero entries in (the upper triangle of) m
2087 c
2088 c p - integer one-dimensional array used to return the permutation
2089 c of the rows and columns of m corresponding to the minimum
2090 c degree ordering. dimension = n
2091 c
2092 c ip - integer one-dimensional array used to return the inverse of
2093 c the permutation returned in p. dimension = n
2094 c
2095 c nsp - declared dimension of the one-dimensional array isp. nsp
2096 c must be at least 3n+4k, where k is the number of nonzeroes
2097 c in the strict upper triangle of m
2098 c
2099 c isp - integer one-dimensional array used for working storage.
2100 c dimension = nsp
2101 c
2102 c path - integer path specification. values and their meanings are -
2103 c 1 find minimum degree ordering only
2104 c 2 find minimum degree ordering and reorder symmetrically
2105 c stored matrix (used when only the nonzero entries in
2106 c the upper triangle of m are being stored)
2107 c 3 reorder symmetrically stored matrix as specified by
2108 c input permutation (used when an ordering has already
2109 c been determined and only the nonzero entries in the
2110 c upper triangle of m are being stored)
2111 c 4 same as 2 but put diagonal entries at start of each row
2112 c 5 same as 3 but put diagonal entries at start of each row
2113 c
2114 c flag - integer error flag. values and their meanings are -
2115 c 0 no errors detected
2116 c 9n+k insufficient storage in md
2117 c 10n+1 insufficient storage in odrv
2118 c 11n+1 illegal path specification
2119 c
2120 c
2121 c conversion from real to double precision
2122 c
2123 c change the real declarations in odrv and sro to double precision
2124 c declarations.
2125 c
2126 c-----------------------------------------------------------------------
2127 c
2128  integer ia(*), ja(*), p(*), ip(*), isp(*), path, flag,
2129  * v, l, head, tmp, q
2130 c... real a(*)
2131  double precision a(*)
2132  logical dflag
2133 c
2134 c----initialize error flag and validate path specification
2135  flag = 0
2136  if (path.lt.1 .or. 5.lt.path) go to 111
2137 c
2138 c----allocate storage and find minimum degree ordering
2139  if ((path-1) * (path-2) * (path-4) .ne. 0) go to 1
2140  max = (nsp-n)/2
2141  v = 1
2142  l = v + max
2143  head = l + max
2144  next = head + n
2145  if (max.lt.n) go to 110
2146 c
2147  call md
2148  * (n, ia,ja, max,isp(v),isp(l), isp(head),p,ip, isp(v), flag)
2149  if (flag.ne.0) go to 100
2150 c
2151 c----allocate storage and symmetrically reorder matrix
2152  1 if ((path-2) * (path-3) * (path-4) * (path-5) .ne. 0) go to 2
2153  tmp = (nsp+1) - n
2154  q = tmp - (ia(n+1)-1)
2155  if (q.lt.1) go to 110
2156 c
2157  dflag = path.eq.4 .or. path.eq.5
2158  call sro
2159  * (n, ip, ia, ja, a, isp(tmp), isp(q), dflag)
2160 c
2161  2 return
2162 c
2163 c ** error -- error detected in md
2164  100 return
2165 c ** error -- insufficient storage
2166  110 flag = 10*n + 1
2167  return
2168 c ** error -- illegal path specified
2169  111 flag = 11*n + 1
2170  return
2171  end
2172  subroutine md
2173  * (n, ia,ja, max, v,l, head,last,next, mark, flag)
2174 c***********************************************************************
2175 c md -- minimum degree algorithm (based on element model)
2176 c***********************************************************************
2177 c
2178 c description
2179 c
2180 c md finds a minimum degree ordering of the rows and columns of a
2181 c general sparse matrix m stored in (ia,ja,a) format.
2182 c when the structure of m is nonsymmetric, the ordering is that
2183 c obtained for the symmetric matrix m + m-transpose.
2184 c
2185 c
2186 c additional parameters
2187 c
2188 c max - declared dimension of the one-dimensional arrays v and l.
2189 c max must be at least n+2k, where k is the number of
2190 c nonzeroes in the strict upper triangle of m + m-transpose
2191 c
2192 c v - integer one-dimensional work array. dimension = max
2193 c
2194 c l - integer one-dimensional work array. dimension = max
2195 c
2196 c head - integer one-dimensional work array. dimension = n
2197 c
2198 c last - integer one-dimensional array used to return the permutation
2199 c of the rows and columns of m corresponding to the minimum
2200 c degree ordering. dimension = n
2201 c
2202 c next - integer one-dimensional array used to return the inverse of
2203 c the permutation returned in last. dimension = n
2204 c
2205 c mark - integer one-dimensional work array (may be the same as v).
2206 c dimension = n
2207 c
2208 c flag - integer error flag. values and their meanings are -
2209 c 0 no errors detected
2210 c 9n+k insufficient storage in md
2211 c
2212 c
2213 c definitions of internal parameters
2214 c
2215 c ---------+---------------------------------------------------------
2216 c v(s) - value field of list entry
2217 c ---------+---------------------------------------------------------
2218 c l(s) - link field of list entry (0 =) end of list)
2219 c ---------+---------------------------------------------------------
2220 c l(vi) - pointer to element list of uneliminated vertex vi
2221 c ---------+---------------------------------------------------------
2222 c l(ej) - pointer to boundary list of active element ej
2223 c ---------+---------------------------------------------------------
2224 c head(d) - vj =) vj head of d-list d
2225 c - 0 =) no vertex in d-list d
2226 c
2227 c
2228 c - vi uneliminated vertex
2229 c - vi in ek - vi not in ek
2230 c ---------+-----------------------------+---------------------------
2231 c next(vi) - undefined but nonnegative - vj =) vj next in d-list
2232 c - - 0 =) vi tail of d-list
2233 c ---------+-----------------------------+---------------------------
2234 c last(vi) - (not set until mdp) - -d =) vi head of d-list d
2235 c --vk =) compute degree - vj =) vj last in d-list
2236 c - ej =) vi prototype of ej - 0 =) vi not in any d-list
2237 c - 0 =) do not compute degree -
2238 c ---------+-----------------------------+---------------------------
2239 c mark(vi) - mark(vk) - nonneg. tag .lt. mark(vk)
2240 c
2241 c
2242 c - vi eliminated vertex
2243 c - ei active element - otherwise
2244 c ---------+-----------------------------+---------------------------
2245 c next(vi) - -j =) vi was j-th vertex - -j =) vi was j-th vertex
2246 c - to be eliminated - to be eliminated
2247 c ---------+-----------------------------+---------------------------
2248 c last(vi) - m =) size of ei = m - undefined
2249 c ---------+-----------------------------+---------------------------
2250 c mark(vi) - -m =) overlap count of ei - undefined
2251 c - with ek = m -
2252 c - otherwise nonnegative tag -
2253 c - .lt. mark(vk) -
2254 c
2255 c-----------------------------------------------------------------------
2256 c
2257  integer ia(*), ja(*), v(*), l(*), head(*), last(*), next(*),
2258  * mark(*), flag, tag, dmin, vk,ek, tail
2259  equivalence(vk,ek)
2260 c
2261 c----initialization
2262  tag = 0
2263  call mdi
2264  * (n, ia,ja, max,v,l, head,last,next, mark,tag, flag)
2265  if (flag.ne.0) return
2266 c
2267  k = 0
2268  dmin = 1
2269 c
2270 c----while k .lt. n do
2271  1 if (k.ge.n) go to 4
2272 c
2273 c------search for vertex of minimum degree
2274  2 if (head(dmin).gt.0) go to 3
2275  dmin = dmin + 1
2276  go to 2
2277 c
2278 c------remove vertex vk of minimum degree from degree list
2279  3 vk = head(dmin)
2280  head(dmin) = next(vk)
2281  if (head(dmin).gt.0) last(head(dmin)) = -dmin
2282 c
2283 c------number vertex vk, adjust tag, and tag vk
2284  k = k+1
2285  next(vk) = -k
2286  last(ek) = dmin - 1
2287  tag = tag + last(ek)
2288  mark(vk) = tag
2289 c
2290 c------form element ek from uneliminated neighbors of vk
2291  call mdm
2292  * (vk,tail, v,l, last,next, mark)
2293 c
2294 c------purge inactive elements and do mass elimination
2295  call mdp
2296  * (k,ek,tail, v,l, head,last,next, mark)
2297 c
2298 c------update degrees of uneliminated vertices in ek
2299  call mdu
2300  * (ek,dmin, v,l, head,last,next, mark)
2301 c
2302  go to 1
2303 c
2304 c----generate inverse permutation from permutation
2305  4 do 5 k=1,n
2306  next(k) = -next(k)
2307  5 last(next(k)) = k
2308 c
2309  return
2310  end
2311  subroutine mdi
2312  * (n, ia,ja, max,v,l, head,last,next, mark,tag, flag)
2313 c***********************************************************************
2314 c mdi -- initialization
2315 c***********************************************************************
2316  integer ia(*), ja(*), v(*), l(*), head(*), last(*), next(*),
2317  * mark(*), tag, flag, sfs, vi,dvi, vj
2318 c
2319 c----initialize degrees, element lists, and degree lists
2320  do 1 vi=1,n
2321  mark(vi) = 1
2322  l(vi) = 0
2323  1 head(vi) = 0
2324  sfs = n+1
2325 c
2326 c----create nonzero structure
2327 c----for each nonzero entry a(vi,vj)
2328  do 6 vi=1,n
2329  jmin = ia(vi)
2330  jmax = ia(vi+1) - 1
2331  if (jmin.gt.jmax) go to 6
2332  do 5 j=jmin,jmax
2333  vj = ja(j)
2334  if (vj-vi) 2, 5, 4
2335 c
2336 c------if a(vi,vj) is in strict lower triangle
2337 c------check for previous occurrence of a(vj,vi)
2338  2 lvk = vi
2339  kmax = mark(vi) - 1
2340  if (kmax .eq. 0) go to 4
2341  do 3 k=1,kmax
2342  lvk = l(lvk)
2343  if (v(lvk).eq.vj) go to 5
2344  3 continue
2345 c----for unentered entries a(vi,vj)
2346  4 if (sfs.ge.max) go to 101
2347 c
2348 c------enter vj in element list for vi
2349  mark(vi) = mark(vi) + 1
2350  v(sfs) = vj
2351  l(sfs) = l(vi)
2352  l(vi) = sfs
2353  sfs = sfs+1
2354 c
2355 c------enter vi in element list for vj
2356  mark(vj) = mark(vj) + 1
2357  v(sfs) = vi
2358  l(sfs) = l(vj)
2359  l(vj) = sfs
2360  sfs = sfs+1
2361  5 continue
2362  6 continue
2363 c
2364 c----create degree lists and initialize mark vector
2365  do 7 vi=1,n
2366  dvi = mark(vi)
2367  next(vi) = head(dvi)
2368  head(dvi) = vi
2369  last(vi) = -dvi
2370  nextvi = next(vi)
2371  if (nextvi.gt.0) last(nextvi) = vi
2372  7 mark(vi) = tag
2373 c
2374  return
2375 c
2376 c ** error- insufficient storage
2377  101 flag = 9*n + vi
2378  return
2379  end
2380  subroutine mdm
2381  * (vk,tail, v,l, last,next, mark)
2382 c***********************************************************************
2383 c mdm -- form element from uneliminated neighbors of vk
2384 c***********************************************************************
2385  integer vk, tail, v(*), l(*), last(*), next(*), mark(*),
2386  * tag, s,ls,vs,es, b,lb,vb, blp,blpmax
2387  equivalence(vs, es)
2388 c
2389 c----initialize tag and list of uneliminated neighbors
2390  tag = mark(vk)
2391  tail = vk
2392 c
2393 c----for each vertex/element vs/es in element list of vk
2394  ls = l(vk)
2395  1 s = ls
2396  if (s.eq.0) go to 5
2397  ls = l(s)
2398  vs = v(s)
2399  if (next(vs).lt.0) go to 2
2400 c
2401 c------if vs is uneliminated vertex, then tag and append to list of
2402 c------uneliminated neighbors
2403  mark(vs) = tag
2404  l(tail) = s
2405  tail = s
2406  go to 4
2407 c
2408 c------if es is active element, then ...
2409 c--------for each vertex vb in boundary list of element es
2410  2 lb = l(es)
2411  blpmax = last(es)
2412  do 3 blp=1,blpmax
2413  b = lb
2414  lb = l(b)
2415  vb = v(b)
2416 c
2417 c----------if vb is untagged vertex, then tag and append to list of
2418 c----------uneliminated neighbors
2419  if (mark(vb).ge.tag) go to 3
2420  mark(vb) = tag
2421  l(tail) = b
2422  tail = b
2423  3 continue
2424 c
2425 c--------mark es inactive
2426  mark(es) = tag
2427 c
2428  4 go to 1
2429 c
2430 c----terminate list of uneliminated neighbors
2431  5 l(tail) = 0
2432 c
2433  return
2434  end
2435  subroutine mdp
2436  * (k,ek,tail, v,l, head,last,next, mark)
2437 c***********************************************************************
2438 c mdp -- purge inactive elements and do mass elimination
2439 c***********************************************************************
2440  integer ek, tail, v(*), l(*), head(*), last(*), next(*),
2441  * mark(*), tag, free, li,vi,lvi,evi, s,ls,es, ilp,ilpmax
2442 c
2443 c----initialize tag
2444  tag = mark(ek)
2445 c
2446 c----for each vertex vi in ek
2447  li = ek
2448  ilpmax = last(ek)
2449  if (ilpmax.le.0) go to 12
2450  do 11 ilp=1,ilpmax
2451  i = li
2452  li = l(i)
2453  vi = v(li)
2454 c
2455 c------remove vi from degree list
2456  if (last(vi).eq.0) go to 3
2457  if (last(vi).gt.0) go to 1
2458  head(-last(vi)) = next(vi)
2459  go to 2
2460  1 next(last(vi)) = next(vi)
2461  2 if (next(vi).gt.0) last(next(vi)) = last(vi)
2462 c
2463 c------remove inactive items from element list of vi
2464  3 ls = vi
2465  4 s = ls
2466  ls = l(s)
2467  if (ls.eq.0) go to 6
2468  es = v(ls)
2469  if (mark(es).lt.tag) go to 5
2470  free = ls
2471  l(s) = l(ls)
2472  ls = s
2473  5 go to 4
2474 c
2475 c------if vi is interior vertex, then remove from list and eliminate
2476  6 lvi = l(vi)
2477  if (lvi.ne.0) go to 7
2478  l(i) = l(li)
2479  li = i
2480 c
2481  k = k+1
2482  next(vi) = -k
2483  last(ek) = last(ek) - 1
2484  go to 11
2485 c
2486 c------else ...
2487 c--------classify vertex vi
2488  7 if (l(lvi).ne.0) go to 9
2489  evi = v(lvi)
2490  if (next(evi).ge.0) go to 9
2491  if (mark(evi).lt.0) go to 8
2492 c
2493 c----------if vi is prototype vertex, then mark as such, initialize
2494 c----------overlap count for corresponding element, and move vi to end
2495 c----------of boundary list
2496  last(vi) = evi
2497  mark(evi) = -1
2498  l(tail) = li
2499  tail = li
2500  l(i) = l(li)
2501  li = i
2502  go to 10
2503 c
2504 c----------else if vi is duplicate vertex, then mark as such and adjust
2505 c----------overlap count for corresponding element
2506  8 last(vi) = 0
2507  mark(evi) = mark(evi) - 1
2508  go to 10
2509 c
2510 c----------else mark vi to compute degree
2511  9 last(vi) = -ek
2512 c
2513 c--------insert ek in element list of vi
2514  10 v(free) = ek
2515  l(free) = l(vi)
2516  l(vi) = free
2517  11 continue
2518 c
2519 c----terminate boundary list
2520  12 l(tail) = 0
2521 c
2522  return
2523  end
2524  subroutine mdu
2525  * (ek,dmin, v,l, head,last,next, mark)
2526 c***********************************************************************
2527 c mdu -- update degrees of uneliminated vertices in ek
2528 c***********************************************************************
2529  integer ek, dmin, v(*), l(*), head(*), last(*), next(*),
2530  * mark(*), tag, vi,evi,dvi, s,vs,es, b,vb, ilp,ilpmax,
2531  * blp,blpmax
2532  equivalence(vs, es)
2533 c
2534 c----initialize tag
2535  tag = mark(ek) - last(ek)
2536 c
2537 c----for each vertex vi in ek
2538  i = ek
2539  ilpmax = last(ek)
2540  if (ilpmax.le.0) go to 11
2541  do 10 ilp=1,ilpmax
2542  i = l(i)
2543  vi = v(i)
2544  if (last(vi)) 1, 10, 8
2545 c
2546 c------if vi neither prototype nor duplicate vertex, then merge elements
2547 c------to compute degree
2548  1 tag = tag + 1
2549  dvi = last(ek)
2550 c
2551 c--------for each vertex/element vs/es in element list of vi
2552  s = l(vi)
2553  2 s = l(s)
2554  if (s.eq.0) go to 9
2555  vs = v(s)
2556  if (next(vs).lt.0) go to 3
2557 c
2558 c----------if vs is uneliminated vertex, then tag and adjust degree
2559  mark(vs) = tag
2560  dvi = dvi + 1
2561  go to 5
2562 c
2563 c----------if es is active element, then expand
2564 c------------check for outmatched vertex
2565  3 if (mark(es).lt.0) go to 6
2566 c
2567 c------------for each vertex vb in es
2568  b = es
2569  blpmax = last(es)
2570  do 4 blp=1,blpmax
2571  b = l(b)
2572  vb = v(b)
2573 c
2574 c--------------if vb is untagged, then tag and adjust degree
2575  if (mark(vb).ge.tag) go to 4
2576  mark(vb) = tag
2577  dvi = dvi + 1
2578  4 continue
2579 c
2580  5 go to 2
2581 c
2582 c------else if vi is outmatched vertex, then adjust overlaps but do not
2583 c------compute degree
2584  6 last(vi) = 0
2585  mark(es) = mark(es) - 1
2586  7 s = l(s)
2587  if (s.eq.0) go to 10
2588  es = v(s)
2589  if (mark(es).lt.0) mark(es) = mark(es) - 1
2590  go to 7
2591 c
2592 c------else if vi is prototype vertex, then calculate degree by
2593 c------inclusion/exclusion and reset overlap count
2594  8 evi = last(vi)
2595  dvi = last(ek) + last(evi) + mark(evi)
2596  mark(evi) = 0
2597 c
2598 c------insert vi in appropriate degree list
2599  9 next(vi) = head(dvi)
2600  head(dvi) = vi
2601  last(vi) = -dvi
2602  if (next(vi).gt.0) last(next(vi)) = vi
2603  if (dvi.lt.dmin) dmin = dvi
2604 c
2605  10 continue
2606 c
2607  11 return
2608  end
2609  subroutine sro
2610  * (n, ip, ia,ja,a, q, r, dflag)
2611 c***********************************************************************
2612 c sro -- symmetric reordering of sparse symmetric matrix
2613 c***********************************************************************
2614 c
2615 c description
2616 c
2617 c the nonzero entries of the matrix m are assumed to be stored
2618 c symmetrically in (ia,ja,a) format (i.e., not both m(i,j) and m(j,i)
2619 c are stored if i ne j).
2620 c
2621 c sro does not rearrange the order of the rows, but does move
2622 c nonzeroes from one row to another to ensure that if m(i,j) will be
2623 c in the upper triangle of m with respect to the new ordering, then
2624 c m(i,j) is stored in row i (and thus m(j,i) is not stored), whereas
2625 c if m(i,j) will be in the strict lower triangle of m, then m(j,i) is
2626 c stored in row j (and thus m(i,j) is not stored).
2627 c
2628 c
2629 c additional parameters
2630 c
2631 c q - integer one-dimensional work array. dimension = n
2632 c
2633 c r - integer one-dimensional work array. dimension = number of
2634 c nonzero entries in the upper triangle of m
2635 c
2636 c dflag - logical variable. if dflag = .true., then store nonzero
2637 c diagonal elements at the beginning of the row
2638 c
2639 c-----------------------------------------------------------------------
2640 c
2641  integer ip(*), ia(*), ja(*), q(*), r(*)
2642 c... real a(*), ak
2643  double precision a(*), ak
2644  logical dflag
2645 c
2646 c
2647 c--phase 1 -- find row in which to store each nonzero
2648 c----initialize count of nonzeroes to be stored in each row
2649  do 1 i=1,n
2650  1 q(i) = 0
2651 c
2652 c----for each nonzero element a(j)
2653  do 3 i=1,n
2654  jmin = ia(i)
2655  jmax = ia(i+1) - 1
2656  if (jmin.gt.jmax) go to 3
2657  do 2 j=jmin,jmax
2658 c
2659 c--------find row (=r(j)) and column (=ja(j)) in which to store a(j) ...
2660  k = ja(j)
2661  if (ip(k).lt.ip(i)) ja(j) = i
2662  if (ip(k).ge.ip(i)) k = i
2663  r(j) = k
2664 c
2665 c--------... and increment count of nonzeroes (=q(r(j)) in that row
2666  2 q(k) = q(k) + 1
2667  3 continue
2668 c
2669 c
2670 c--phase 2 -- find new ia and permutation to apply to (ja,a)
2671 c----determine pointers to delimit rows in permuted (ja,a)
2672  do 4 i=1,n
2673  ia(i+1) = ia(i) + q(i)
2674  4 q(i) = ia(i+1)
2675 c
2676 c----determine where each (ja(j),a(j)) is stored in permuted (ja,a)
2677 c----for each nonzero element (in reverse order)
2678  ilast = 0
2679  jmin = ia(1)
2680  jmax = ia(n+1) - 1
2681  j = jmax
2682  do 6 jdummy=jmin,jmax
2683  i = r(j)
2684  if (.not.dflag .or. ja(j).ne.i .or. i.eq.ilast) go to 5
2685 c
2686 c------if dflag, then put diagonal nonzero at beginning of row
2687  r(j) = ia(i)
2688  ilast = i
2689  go to 6
2690 c
2691 c------put (off-diagonal) nonzero in last unused location in row
2692  5 q(i) = q(i) - 1
2693  r(j) = q(i)
2694 c
2695  6 j = j-1
2696 c
2697 c
2698 c--phase 3 -- permute (ja,a) to upper triangular form (wrt new ordering)
2699  do 8 j=jmin,jmax
2700  7 if (r(j).eq.j) go to 8
2701  k = r(j)
2702  r(j) = r(k)
2703  r(k) = k
2704  jak = ja(k)
2705  ja(k) = ja(j)
2706  ja(j) = jak
2707  ak = a(k)
2708  a(k) = a(j)
2709  a(j) = ak
2710  go to 7
2711  8 continue
2712 c
2713  return
2714  end
2715 *DECK CDRV
2716  subroutine cdrv
2717  * (n, r,c,ic, ia,ja,a, b, z, nsp,isp,rsp,esp, path, flag)
2718 c*** subroutine cdrv
2719 c*** driver for subroutines for solving sparse nonsymmetric systems of
2720 c linear equations (compressed pointer storage)
2721 c
2722 c
2723 c parameters
2724 c class abbreviations are--
2725 c n - integer variable
2726 c f - real variable
2727 c v - supplies a value to the driver
2728 c r - returns a result from the driver
2729 c i - used internally by the driver
2730 c a - array
2731 c
2732 c class - parameter
2733 c ------+----------
2734 c -
2735 c the nonzero entries of the coefficient matrix m are stored
2736 c row-by-row in the array a. to identify the individual nonzero
2737 c entries in each row, we need to know in which column each entry
2738 c lies. the column indices which correspond to the nonzero entries
2739 c of m are stored in the array ja. i.e., if a(k) = m(i,j), then
2740 c ja(k) = j. in addition, we need to know where each row starts and
2741 c how long it is. the index positions in ja and a where the rows of
2742 c m begin are stored in the array ia. i.e., if m(i,j) is the first
2743 c nonzero entry (stored) in the i-th row and a(k) = m(i,j), then
2744 c ia(i) = k. moreover, the index in ja and a of the first location
2745 c following the last element in the last row is stored in ia(n+1).
2746 c thus, the number of entries in the i-th row is given by
2747 c ia(i+1) - ia(i), the nonzero entries of the i-th row are stored
2748 c consecutively in
2749 c a(ia(i)), a(ia(i)+1), ..., a(ia(i+1)-1),
2750 c and the corresponding column indices are stored consecutively in
2751 c ja(ia(i)), ja(ia(i)+1), ..., ja(ia(i+1)-1).
2752 c for example, the 5 by 5 matrix
2753 c ( 1. 0. 2. 0. 0.)
2754 c ( 0. 3. 0. 0. 0.)
2755 c m = ( 0. 4. 5. 6. 0.)
2756 c ( 0. 0. 0. 7. 0.)
2757 c ( 0. 0. 0. 8. 9.)
2758 c would be stored as
2759 c - 1 2 3 4 5 6 7 8 9
2760 c ---+--------------------------
2761 c ia - 1 3 4 7 8 10
2762 c ja - 1 3 2 2 3 4 4 4 5
2763 c a - 1. 2. 3. 4. 5. 6. 7. 8. 9. .
2764 c
2765 c nv - n - number of variables/equations.
2766 c fva - a - nonzero entries of the coefficient matrix m, stored
2767 c - by rows.
2768 c - size = number of nonzero entries in m.
2769 c nva - ia - pointers to delimit the rows in a.
2770 c - size = n+1.
2771 c nva - ja - column numbers corresponding to the elements of a.
2772 c - size = size of a.
2773 c fva - b - right-hand side b. b and z can the same array.
2774 c - size = n.
2775 c fra - z - solution x. b and z can be the same array.
2776 c - size = n.
2777 c
2778 c the rows and columns of the original matrix m can be
2779 c reordered (e.g., to reduce fillin or ensure numerical stability)
2780 c before calling the driver. if no reordering is done, then set
2781 c r(i) = c(i) = ic(i) = i for i=1,...,n. the solution z is returned
2782 c in the original order.
2783 c if the columns have been reordered (i.e., c(i).ne.i for some
2784 c i), then the driver will call a subroutine (nroc) which rearranges
2785 c each row of ja and a, leaving the rows in the original order, but
2786 c placing the elements of each row in increasing order with respect
2787 c to the new ordering. if path.ne.1, then nroc is assumed to have
2788 c been called already.
2789 c
2790 c nva - r - ordering of the rows of m.
2791 c - size = n.
2792 c nva - c - ordering of the columns of m.
2793 c - size = n.
2794 c nva - ic - inverse of the ordering of the columns of m. i.e.,
2795 c - ic(c(i)) = i for i=1,...,n.
2796 c - size = n.
2797 c
2798 c the solution of the system of linear equations is divided into
2799 c three stages --
2800 c nsfc -- the matrix m is processed symbolically to determine where
2801 c fillin will occur during the numeric factorization.
2802 c nnfc -- the matrix m is factored numerically into the product ldu
2803 c of a unit lower triangular matrix l, a diagonal matrix
2804 c d, and a unit upper triangular matrix u, and the system
2805 c mx = b is solved.
2806 c nnsc -- the linear system mx = b is solved using the ldu
2807 c or factorization from nnfc.
2808 c nntc -- the transposed linear system mt x = b is solved using
2809 c the ldu factorization from nnf.
2810 c for several systems whose coefficient matrices have the same
2811 c nonzero structure, nsfc need be done only once (for the first
2812 c system). then nnfc is done once for each additional system. for
2813 c several systems with the same coefficient matrix, nsfc and nnfc
2814 c need be done only once (for the first system). then nnsc or nntc
2815 c is done once for each additional right-hand side.
2816 c
2817 c nv - path - path specification. values and their meanings are --
2818 c - 1 perform nroc, nsfc, and nnfc.
2819 c - 2 perform nnfc only (nsfc is assumed to have been
2820 c - done in a manner compatible with the storage
2821 c - allocation used in the driver).
2822 c - 3 perform nnsc only (nsfc and nnfc are assumed to
2823 c - have been done in a manner compatible with the
2824 c - storage allocation used in the driver).
2825 c - 4 perform nntc only (nsfc and nnfc are assumed to
2826 c - have been done in a manner compatible with the
2827 c - storage allocation used in the driver).
2828 c - 5 perform nroc and nsfc.
2829 c
2830 c various errors are detected by the driver and the individual
2831 c subroutines.
2832 c
2833 c nr - flag - error flag. values and their meanings are --
2834 c - 0 no errors detected
2835 c - n+k null row in a -- row = k
2836 c - 2n+k duplicate entry in a -- row = k
2837 c - 3n+k insufficient storage in nsfc -- row = k
2838 c - 4n+1 insufficient storage in nnfc
2839 c - 5n+k null pivot -- row = k
2840 c - 6n+k insufficient storage in nsfc -- row = k
2841 c - 7n+1 insufficient storage in nnfc
2842 c - 8n+k zero pivot -- row = k
2843 c - 10n+1 insufficient storage in cdrv
2844 c - 11n+1 illegal path specification
2845 c
2846 c working storage is needed for the factored form of the matrix
2847 c m plus various temporary vectors. the arrays isp and rsp should be
2848 c equivalenced. integer storage is allocated from the beginning of
2849 c isp and real storage from the end of rsp.
2850 c
2851 c nv - nsp - declared dimension of rsp. nsp generally must
2852 c - be larger than 8n+2 + 2k (where k = (number of
2853 c - nonzero entries in m)).
2854 c nvira - isp - integer working storage divided up into various arrays
2855 c - needed by the subroutines. isp and rsp should be
2856 c - equivalenced.
2857 c - size = lratio*nsp.
2858 c fvira - rsp - real working storage divided up into various arrays
2859 c - needed by the subroutines. isp and rsp should be
2860 c - equivalenced.
2861 c - size = nsp.
2862 c nr - esp - if sufficient storage was available to perform the
2863 c - symbolic factorization (nsfc), then esp is set to
2864 c - the amount of excess storage provided (negative if
2865 c - insufficient storage was available to perform the
2866 c - numeric factorization (nnfc)).
2867 c
2868 c
2869 c conversion to double precision
2870 c
2871 c to convert these routines for double precision arrays..
2872 c (1) use the double precision declarations in place of the real
2873 c declarations in each subprogram, as given in comment cards.
2874 c (2) change the data-loaded value of the integer lratio
2875 c in subroutine cdrv, as indicated below.
2876 c (3) change e0 to d0 in the constants in statement number 10
2877 c in subroutine nnfc and the line following that.
2878 c
2879  integer r(*), c(*), ic(*), ia(*), ja(*), isp(*), esp, path,
2880  * flag, d, u, q, row, tmp, ar, umax
2881 c real a(*), b(*), z(*), rsp(*)
2882  double precision a(*), b(*), z(*), rsp(*)
2883 c
2884 c set lratio equal to the ratio between the length of floating point
2885 c and integer array data. e. g., lratio = 1 for (real, integer),
2886 c lratio = 2 for (double precision, integer)
2887 c
2888  data lratio/2/
2889 c
2890  if (path.lt.1 .or. 5.lt.path) go to 111
2891 c******initialize and divide up temporary storage *******************
2892  il = 1
2893  ijl = il + (n+1)
2894  iu = ijl + n
2895  iju = iu + (n+1)
2896  irl = iju + n
2897  jrl = irl + n
2898  jl = jrl + n
2899 c
2900 c ****** reorder a if necessary, call nsfc if flag is set ***********
2901  if ((path-1) * (path-5) .ne. 0) go to 5
2902  max = (lratio*nsp + 1 - jl) - (n+1) - 5*n
2903  jlmax = max/2
2904  q = jl + jlmax
2905  ira = q + (n+1)
2906  jra = ira + n
2907  irac = jra + n
2908  iru = irac + n
2909  jru = iru + n
2910  jutmp = jru + n
2911  jumax = lratio*nsp + 1 - jutmp
2912  esp = max/lratio
2913  if (jlmax.le.0 .or. jumax.le.0) go to 110
2914 c
2915  do 1 i=1,n
2916  if (c(i).ne.i) go to 2
2917  1 continue
2918  go to 3
2919  2 ar = nsp + 1 - n
2920  call nroc
2921  * (n, ic, ia,ja,a, isp(il), rsp(ar), isp(iu), flag)
2922  if (flag.ne.0) go to 100
2923 c
2924  3 call nsfc
2925  * (n, r, ic, ia,ja,
2926  * jlmax, isp(il), isp(jl), isp(ijl),
2927  * jumax, isp(iu), isp(jutmp), isp(iju),
2928  * isp(q), isp(ira), isp(jra), isp(irac),
2929  * isp(irl), isp(jrl), isp(iru), isp(jru), flag)
2930  if(flag .ne. 0) go to 100
2931 c ****** move ju next to jl *****************************************
2932  jlmax = isp(ijl+n-1)
2933  ju = jl + jlmax
2934  jumax = isp(iju+n-1)
2935  if (jumax.le.0) go to 5
2936  do 4 j=1,jumax
2937  4 isp(ju+j-1) = isp(jutmp+j-1)
2938 c
2939 c ****** call remaining subroutines *********************************
2940  5 jlmax = isp(ijl+n-1)
2941  ju = jl + jlmax
2942  jumax = isp(iju+n-1)
2943  l = (ju + jumax - 2 + lratio) / lratio + 1
2944  lmax = isp(il+n) - 1
2945  d = l + lmax
2946  u = d + n
2947  row = nsp + 1 - n
2948  tmp = row - n
2949  umax = tmp - u
2950  esp = umax - (isp(iu+n) - 1)
2951 c
2952  if ((path-1) * (path-2) .ne. 0) go to 6
2953  if (umax.lt.0) go to 110
2954  call nnfc
2955  * (n, r, c, ic, ia, ja, a, z, b,
2956  * lmax, isp(il), isp(jl), isp(ijl), rsp(l), rsp(d),
2957  * umax, isp(iu), isp(ju), isp(iju), rsp(u),
2958  * rsp(row), rsp(tmp), isp(irl), isp(jrl), flag)
2959  if(flag .ne. 0) go to 100
2960 c
2961  6 if ((path-3) .ne. 0) go to 7
2962  call nnsc
2963  * (n, r, c, isp(il), isp(jl), isp(ijl), rsp(l),
2964  * rsp(d), isp(iu), isp(ju), isp(iju), rsp(u),
2965  * z, b, rsp(tmp))
2966 c
2967  7 if ((path-4) .ne. 0) go to 8
2968  call nntc
2969  * (n, r, c, isp(il), isp(jl), isp(ijl), rsp(l),
2970  * rsp(d), isp(iu), isp(ju), isp(iju), rsp(u),
2971  * z, b, rsp(tmp))
2972  8 return
2973 c
2974 c ** error.. error detected in nroc, nsfc, nnfc, or nnsc
2975  100 return
2976 c ** error.. insufficient storage
2977  110 flag = 10*n + 1
2978  return
2979 c ** error.. illegal path specification
2980  111 flag = 11*n + 1
2981  return
2982  end
2983  subroutine nroc (n, ic, ia, ja, a, jar, ar, p, flag)
2984 c
2985 c ----------------------------------------------------------------
2986 c
2987 c yale sparse matrix package - nonsymmetric codes
2988 c solving the system of equations mx = b
2989 c
2990 c i. calling sequences
2991 c the coefficient matrix can be processed by an ordering routine
2992 c (e.g., to reduce fillin or ensure numerical stability) before using
2993 c the remaining subroutines. if no reordering is done, then set
2994 c r(i) = c(i) = ic(i) = i for i=1,...,n. if an ordering subroutine
2995 c is used, then nroc should be used to reorder the coefficient matrix
2996 c the calling sequence is --
2997 c ( (matrix ordering))
2998 c (nroc (matrix reordering))
2999 c nsfc (symbolic factorization to determine where fillin will
3000 c occur during numeric factorization)
3001 c nnfc (numeric factorization into product ldu of unit lower
3002 c triangular matrix l, diagonal matrix d, and unit
3003 c upper triangular matrix u, and solution of linear
3004 c system)
3005 c nnsc (solution of linear system for additional right-hand
3006 c side using ldu factorization from nnfc)
3007 c (if only one system of equations is to be solved, then the
3008 c subroutine trk should be used.)
3009 c
3010 c ii. storage of sparse matrices
3011 c the nonzero entries of the coefficient matrix m are stored
3012 c row-by-row in the array a. to identify the individual nonzero
3013 c entries in each row, we need to know in which column each entry
3014 c lies. the column indices which correspond to the nonzero entries
3015 c of m are stored in the array ja. i.e., if a(k) = m(i,j), then
3016 c ja(k) = j. in addition, we need to know where each row starts and
3017 c how long it is. the index positions in ja and a where the rows of
3018 c m begin are stored in the array ia. i.e., if m(i,j) is the first
3019 c (leftmost) entry in the i-th row and a(k) = m(i,j), then
3020 c ia(i) = k. moreover, the index in ja and a of the first location
3021 c following the last element in the last row is stored in ia(n+1).
3022 c thus, the number of entries in the i-th row is given by
3023 c ia(i+1) - ia(i), the nonzero entries of the i-th row are stored
3024 c consecutively in
3025 c a(ia(i)), a(ia(i)+1), ..., a(ia(i+1)-1),
3026 c and the corresponding column indices are stored consecutively in
3027 c ja(ia(i)), ja(ia(i)+1), ..., ja(ia(i+1)-1).
3028 c for example, the 5 by 5 matrix
3029 c ( 1. 0. 2. 0. 0.)
3030 c ( 0. 3. 0. 0. 0.)
3031 c m = ( 0. 4. 5. 6. 0.)
3032 c ( 0. 0. 0. 7. 0.)
3033 c ( 0. 0. 0. 8. 9.)
3034 c would be stored as
3035 c - 1 2 3 4 5 6 7 8 9
3036 c ---+--------------------------
3037 c ia - 1 3 4 7 8 10
3038 c ja - 1 3 2 2 3 4 4 4 5
3039 c a - 1. 2. 3. 4. 5. 6. 7. 8. 9. .
3040 c
3041 c the strict upper (lower) triangular portion of the matrix
3042 c u (l) is stored in a similar fashion using the arrays iu, ju, u
3043 c (il, jl, l) except that an additional array iju (ijl) is used to
3044 c compress storage of ju (jl) by allowing some sequences of column
3045 c (row) indices to used for more than one row (column) (n.b., l is
3046 c stored by columns). iju(k) (ijl(k)) points to the starting
3047 c location in ju (jl) of entries for the kth row (column).
3048 c compression in ju (jl) occurs in two ways. first, if a row
3049 c (column) i was merged into the current row (column) k, and the
3050 c number of elements merged in from (the tail portion of) row
3051 c (column) i is the same as the final length of row (column) k, then
3052 c the kth row (column) and the tail of row (column) i are identical
3053 c and iju(k) (ijl(k)) points to the start of the tail. second, if
3054 c some tail portion of the (k-1)st row (column) is identical to the
3055 c head of the kth row (column), then iju(k) (ijl(k)) points to the
3056 c start of that tail portion. for example, the nonzero structure of
3057 c the strict upper triangular part of the matrix
3058 c d 0 x x x
3059 c 0 d 0 x x
3060 c 0 0 d x 0
3061 c 0 0 0 d x
3062 c 0 0 0 0 d
3063 c would be represented as
3064 c - 1 2 3 4 5 6
3065 c ----+------------
3066 c iu - 1 4 6 7 8 8
3067 c ju - 3 4 5 4
3068 c iju - 1 2 4 3 .
3069 c the diagonal entries of l and u are assumed to be equal to one and
3070 c are not stored. the array d contains the reciprocals of the
3071 c diagonal entries of the matrix d.
3072 c
3073 c iii. additional storage savings
3074 c in nsfc, r and ic can be the same array in the calling
3075 c sequence if no reordering of the coefficient matrix has been done.
3076 c in nnfc, r, c, and ic can all be the same array if no
3077 c reordering has been done. if only the rows have been reordered,
3078 c then c and ic can be the same array. if the row and column
3079 c orderings are the same, then r and c can be the same array. z and
3080 c row can be the same array.
3081 c in nnsc or nntc, r and c can be the same array if no
3082 c reordering has been done or if the row and column orderings are the
3083 c same. z and b can be the same array. however, then b will be
3084 c destroyed.
3085 c
3086 c iv. parameters
3087 c following is a list of parameters to the programs. names are
3088 c uniform among the various subroutines. class abbreviations are --
3089 c n - integer variable
3090 c f - real variable
3091 c v - supplies a value to a subroutine
3092 c r - returns a result from a subroutine
3093 c i - used internally by a subroutine
3094 c a - array
3095 c
3096 c class - parameter
3097 c ------+----------
3098 c fva - a - nonzero entries of the coefficient matrix m, stored
3099 c - by rows.
3100 c - size = number of nonzero entries in m.
3101 c fva - b - right-hand side b.
3102 c - size = n.
3103 c nva - c - ordering of the columns of m.
3104 c - size = n.
3105 c fvra - d - reciprocals of the diagonal entries of the matrix d.
3106 c - size = n.
3107 c nr - flag - error flag. values and their meanings are --
3108 c - 0 no errors detected
3109 c - n+k null row in a -- row = k
3110 c - 2n+k duplicate entry in a -- row = k
3111 c - 3n+k insufficient storage for jl -- row = k
3112 c - 4n+1 insufficient storage for l
3113 c - 5n+k null pivot -- row = k
3114 c - 6n+k insufficient storage for ju -- row = k
3115 c - 7n+1 insufficient storage for u
3116 c - 8n+k zero pivot -- row = k
3117 c nva - ia - pointers to delimit the rows of a.
3118 c - size = n+1.
3119 c nvra - ijl - pointers to the first element in each column in jl,
3120 c - used to compress storage in jl.
3121 c - size = n.
3122 c nvra - iju - pointers to the first element in each row in ju, used
3123 c - to compress storage in ju.
3124 c - size = n.
3125 c nvra - il - pointers to delimit the columns of l.
3126 c - size = n+1.
3127 c nvra - iu - pointers to delimit the rows of u.
3128 c - size = n+1.
3129 c nva - ja - column numbers corresponding to the elements of a.
3130 c - size = size of a.
3131 c nvra - jl - row numbers corresponding to the elements of l.
3132 c - size = jlmax.
3133 c nv - jlmax - declared dimension of jl. jlmax must be larger than
3134 c - the number of nonzeros in the strict lower triangle
3135 c - of m plus fillin minus compression.
3136 c nvra - ju - column numbers corresponding to the elements of u.
3137 c - size = jumax.
3138 c nv - jumax - declared dimension of ju. jumax must be larger than
3139 c - the number of nonzeros in the strict upper triangle
3140 c - of m plus fillin minus compression.
3141 c fvra - l - nonzero entries in the strict lower triangular portion
3142 c - of the matrix l, stored by columns.
3143 c - size = lmax.
3144 c nv - lmax - declared dimension of l. lmax must be larger than
3145 c - the number of nonzeros in the strict lower triangle
3146 c - of m plus fillin (il(n+1)-1 after nsfc).
3147 c nv - n - number of variables/equations.
3148 c nva - r - ordering of the rows of m.
3149 c - size = n.
3150 c fvra - u - nonzero entries in the strict upper triangular portion
3151 c - of the matrix u, stored by rows.
3152 c - size = umax.
3153 c nv - umax - declared dimension of u. umax must be larger than
3154 c - the number of nonzeros in the strict upper triangle
3155 c - of m plus fillin (iu(n+1)-1 after nsfc).
3156 c fra - z - solution x.
3157 c - size = n.
3158 c
3159 c ----------------------------------------------------------------
3160 c
3161 c*** subroutine nroc
3162 c*** reorders rows of a, leaving row order unchanged
3163 c
3164 c
3165 c input parameters.. n, ic, ia, ja, a
3166 c output parameters.. ja, a, flag
3167 c
3168 c parameters used internally..
3169 c nia - p - at the kth step, p is a linked list of the reordered
3170 c - column indices of the kth row of a. p(n+1) points
3171 c - to the first entry in the list.
3172 c - size = n+1.
3173 c nia - jar - at the kth step,jar contains the elements of the
3174 c - reordered column indices of a.
3175 c - size = n.
3176 c fia - ar - at the kth step, ar contains the elements of the
3177 c - reordered row of a.
3178 c - size = n.
3179 c
3180  integer ic(*), ia(*), ja(*), jar(*), p(*), flag
3181 c real a(*), ar(*)
3182  double precision a(*), ar(*)
3183 c
3184 c ****** for each nonempty row *******************************
3185  do 5 k=1,n
3186  jmin = ia(k)
3187  jmax = ia(k+1) - 1
3188  if(jmin .gt. jmax) go to 5
3189  p(n+1) = n + 1
3190 c ****** insert each element in the list *********************
3191  do 3 j=jmin,jmax
3192  newj = ic(ja(j))
3193  i = n + 1
3194  1 if(p(i) .ge. newj) go to 2
3195  i = p(i)
3196  go to 1
3197  2 if(p(i) .eq. newj) go to 102
3198  p(newj) = p(i)
3199  p(i) = newj
3200  jar(newj) = ja(j)
3201  ar(newj) = a(j)
3202  3 continue
3203 c ****** replace old row in ja and a *************************
3204  i = n + 1
3205  do 4 j=jmin,jmax
3206  i = p(i)
3207  ja(j) = jar(i)
3208  4 a(j) = ar(i)
3209  5 continue
3210  flag = 0
3211  return
3212 c
3213 c ** error.. duplicate entry in a
3214  102 flag = n + k
3215  return
3216  end
3217  subroutine nsfc
3218  * (n, r, ic, ia,ja, jlmax,il,jl,ijl, jumax,iu,ju,iju,
3219  * q, ira,jra, irac, irl,jrl, iru,jru, flag)
3220 c*** subroutine nsfc
3221 c*** symbolic ldu-factorization of nonsymmetric sparse matrix
3222 c (compressed pointer storage)
3223 c
3224 c
3225 c input variables.. n, r, ic, ia, ja, jlmax, jumax.
3226 c output variables.. il, jl, ijl, iu, ju, iju, flag.
3227 c
3228 c parameters used internally..
3229 c nia - q - suppose m* is the result of reordering m. if
3230 c - processing of the ith row of m* (hence the ith
3231 c - row of u) is being done, q(j) is initially
3232 c - nonzero if m*(i,j) is nonzero (j.ge.i). since
3233 c - values need not be stored, each entry points to the
3234 c - next nonzero and q(n+1) points to the first. n+1
3235 c - indicates the end of the list. for example, if n=9
3236 c - and the 5th row of m* is
3237 c - 0 x x 0 x 0 0 x 0
3238 c - then q will initially be
3239 c - a a a a 8 a a 10 5 (a - arbitrary).
3240 c - as the algorithm proceeds, other elements of q
3241 c - are inserted in the list because of fillin.
3242 c - q is used in an analogous manner to compute the
3243 c - ith column of l.
3244 c - size = n+1.
3245 c nia - ira, - vectors used to find the columns of m. at the kth
3246 c nia - jra, step of the factorization, irac(k) points to the
3247 c nia - irac head of a linked list in jra of row indices i
3248 c - such that i .ge. k and m(i,k) is nonzero. zero
3249 c - indicates the end of the list. ira(i) (i.ge.k)
3250 c - points to the smallest j such that j .ge. k and
3251 c - m(i,j) is nonzero.
3252 c - size of each = n.
3253 c nia - irl, - vectors used to find the rows of l. at the kth step
3254 c nia - jrl of the factorization, jrl(k) points to the head
3255 c - of a linked list in jrl of column indices j
3256 c - such j .lt. k and l(k,j) is nonzero. zero
3257 c - indicates the end of the list. irl(j) (j.lt.k)
3258 c - points to the smallest i such that i .ge. k and
3259 c - l(i,j) is nonzero.
3260 c - size of each = n.
3261 c nia - iru, - vectors used in a manner analogous to irl and jrl
3262 c nia - jru to find the columns of u.
3263 c - size of each = n.
3264 c
3265 c internal variables..
3266 c jlptr - points to the last position used in jl.
3267 c juptr - points to the last position used in ju.
3268 c jmin,jmax - are the indices in a or u of the first and last
3269 c elements to be examined in a given row.
3270 c for example, jmin=ia(k), jmax=ia(k+1)-1.
3271 c
3272  integer cend, qm, rend, rk, vj
3273  integer ia(*), ja(*), ira(*), jra(*), il(*), jl(*), ijl(*)
3274  integer iu(*), ju(*), iju(*), irl(*), jrl(*), iru(*), jru(*)
3275  integer r(*), ic(*), q(*), irac(*), flag
3276 c
3277 c ****** initialize pointers ****************************************
3278  np1 = n + 1
3279  jlmin = 1
3280  jlptr = 0
3281  il(1) = 1
3282  jumin = 1
3283  juptr = 0
3284  iu(1) = 1
3285  do 1 k=1,n
3286  irac(k) = 0
3287  jra(k) = 0
3288  jrl(k) = 0
3289  1 jru(k) = 0
3290 c ****** initialize column pointers for a ***************************
3291  do 2 k=1,n
3292  rk = r(k)
3293  iak = ia(rk)
3294  if (iak .ge. ia(rk+1)) go to 101
3295  jaiak = ic(ja(iak))
3296  if (jaiak .gt. k) go to 105
3297  jra(k) = irac(jaiak)
3298  irac(jaiak) = k
3299  2 ira(k) = iak
3300 c
3301 c ****** for each column of l and row of u **************************
3302  do 41 k=1,n
3303 c
3304 c ****** initialize q for computing kth column of l *****************
3305  q(np1) = np1
3306  luk = -1
3307 c ****** by filling in kth column of a ******************************
3308  vj = irac(k)
3309  if (vj .eq. 0) go to 5
3310  3 qm = np1
3311  4 m = qm
3312  qm = q(m)
3313  if (qm .lt. vj) go to 4
3314  if (qm .eq. vj) go to 102
3315  luk = luk + 1
3316  q(m) = vj
3317  q(vj) = qm
3318  vj = jra(vj)
3319  if (vj .ne. 0) go to 3
3320 c ****** link through jru *******************************************
3321  5 lastid = 0
3322  lasti = 0
3323  ijl(k) = jlptr
3324  i = k
3325  6 i = jru(i)
3326  if (i .eq. 0) go to 10
3327  qm = np1
3328  jmin = irl(i)
3329  jmax = ijl(i) + il(i+1) - il(i) - 1
3330  long = jmax - jmin
3331  if (long .lt. 0) go to 6
3332  jtmp = jl(jmin)
3333  if (jtmp .ne. k) long = long + 1
3334  if (jtmp .eq. k) r(i) = -r(i)
3335  if (lastid .ge. long) go to 7
3336  lasti = i
3337  lastid = long
3338 c ****** and merge the corresponding columns into the kth column ****
3339  7 do 9 j=jmin,jmax
3340  vj = jl(j)
3341  8 m = qm
3342  qm = q(m)
3343  if (qm .lt. vj) go to 8
3344  if (qm .eq. vj) go to 9
3345  luk = luk + 1
3346  q(m) = vj
3347  q(vj) = qm
3348  qm = vj
3349  9 continue
3350  go to 6
3351 c ****** lasti is the longest column merged into the kth ************
3352 c ****** see if it equals the entire kth column *********************
3353  10 qm = q(np1)
3354  if (qm .ne. k) go to 105
3355  if (luk .eq. 0) go to 17
3356  if (lastid .ne. luk) go to 11
3357 c ****** if so, jl can be compressed ********************************
3358  irll = irl(lasti)
3359  ijl(k) = irll + 1
3360  if (jl(irll) .ne. k) ijl(k) = ijl(k) - 1
3361  go to 17
3362 c ****** if not, see if kth column can overlap the previous one *****
3363  11 if (jlmin .gt. jlptr) go to 15
3364  qm = q(qm)
3365  do 12 j=jlmin,jlptr
3366  if (jl(j) - qm) 12, 13, 15
3367  12 continue
3368  go to 15
3369  13 ijl(k) = j
3370  do 14 i=j,jlptr
3371  if (jl(i) .ne. qm) go to 15
3372  qm = q(qm)
3373  if (qm .gt. n) go to 17
3374  14 continue
3375  jlptr = j - 1
3376 c ****** move column indices from q to jl, update vectors ***********
3377  15 jlmin = jlptr + 1
3378  ijl(k) = jlmin
3379  if (luk .eq. 0) go to 17
3380  jlptr = jlptr + luk
3381  if (jlptr .gt. jlmax) go to 103
3382  qm = q(np1)
3383  do 16 j=jlmin,jlptr
3384  qm = q(qm)
3385  16 jl(j) = qm
3386  17 irl(k) = ijl(k)
3387  il(k+1) = il(k) + luk
3388 c
3389 c ****** initialize q for computing kth row of u ********************
3390  q(np1) = np1
3391  luk = -1
3392 c ****** by filling in kth row of reordered a ***********************
3393  rk = r(k)
3394  jmin = ira(k)
3395  jmax = ia(rk+1) - 1
3396  if (jmin .gt. jmax) go to 20
3397  do 19 j=jmin,jmax
3398  vj = ic(ja(j))
3399  qm = np1
3400  18 m = qm
3401  qm = q(m)
3402  if (qm .lt. vj) go to 18
3403  if (qm .eq. vj) go to 102
3404  luk = luk + 1
3405  q(m) = vj
3406  q(vj) = qm
3407  19 continue
3408 c ****** link through jrl, ******************************************
3409  20 lastid = 0
3410  lasti = 0
3411  iju(k) = juptr
3412  i = k
3413  i1 = jrl(k)
3414  21 i = i1
3415  if (i .eq. 0) go to 26
3416  i1 = jrl(i)
3417  qm = np1
3418  jmin = iru(i)
3419  jmax = iju(i) + iu(i+1) - iu(i) - 1
3420  long = jmax - jmin
3421  if (long .lt. 0) go to 21
3422  jtmp = ju(jmin)
3423  if (jtmp .eq. k) go to 22
3424 c ****** update irl and jrl, *****************************************
3425  long = long + 1
3426  cend = ijl(i) + il(i+1) - il(i)
3427  irl(i) = irl(i) + 1
3428  if (irl(i) .ge. cend) go to 22
3429  j = jl(irl(i))
3430  jrl(i) = jrl(j)
3431  jrl(j) = i
3432  22 if (lastid .ge. long) go to 23
3433  lasti = i
3434  lastid = long
3435 c ****** and merge the corresponding rows into the kth row **********
3436  23 do 25 j=jmin,jmax
3437  vj = ju(j)
3438  24 m = qm
3439  qm = q(m)
3440  if (qm .lt. vj) go to 24
3441  if (qm .eq. vj) go to 25
3442  luk = luk + 1
3443  q(m) = vj
3444  q(vj) = qm
3445  qm = vj
3446  25 continue
3447  go to 21
3448 c ****** update jrl(k) and irl(k) ***********************************
3449  26 if (il(k+1) .le. il(k)) go to 27
3450  j = jl(irl(k))
3451  jrl(k) = jrl(j)
3452  jrl(j) = k
3453 c ****** lasti is the longest row merged into the kth ***************
3454 c ****** see if it equals the entire kth row ************************
3455  27 qm = q(np1)
3456  if (qm .ne. k) go to 105
3457  if (luk .eq. 0) go to 34
3458  if (lastid .ne. luk) go to 28
3459 c ****** if so, ju can be compressed ********************************
3460  irul = iru(lasti)
3461  iju(k) = irul + 1
3462  if (ju(irul) .ne. k) iju(k) = iju(k) - 1
3463  go to 34
3464 c ****** if not, see if kth row can overlap the previous one ********
3465  28 if (jumin .gt. juptr) go to 32
3466  qm = q(qm)
3467  do 29 j=jumin,juptr
3468  if (ju(j) - qm) 29, 30, 32
3469  29 continue
3470  go to 32
3471  30 iju(k) = j
3472  do 31 i=j,juptr
3473  if (ju(i) .ne. qm) go to 32
3474  qm = q(qm)
3475  if (qm .gt. n) go to 34
3476  31 continue
3477  juptr = j - 1
3478 c ****** move row indices from q to ju, update vectors **************
3479  32 jumin = juptr + 1
3480  iju(k) = jumin
3481  if (luk .eq. 0) go to 34
3482  juptr = juptr + luk
3483  if (juptr .gt. jumax) go to 106
3484  qm = q(np1)
3485  do 33 j=jumin,juptr
3486  qm = q(qm)
3487  33 ju(j) = qm
3488  34 iru(k) = iju(k)
3489  iu(k+1) = iu(k) + luk
3490 c
3491 c ****** update iru, jru ********************************************
3492  i = k
3493  35 i1 = jru(i)
3494  if (r(i) .lt. 0) go to 36
3495  rend = iju(i) + iu(i+1) - iu(i)
3496  if (iru(i) .ge. rend) go to 37
3497  j = ju(iru(i))
3498  jru(i) = jru(j)
3499  jru(j) = i
3500  go to 37
3501  36 r(i) = -r(i)
3502  37 i = i1
3503  if (i .eq. 0) go to 38
3504  iru(i) = iru(i) + 1
3505  go to 35
3506 c
3507 c ****** update ira, jra, irac **************************************
3508  38 i = irac(k)
3509  if (i .eq. 0) go to 41
3510  39 i1 = jra(i)
3511  ira(i) = ira(i) + 1
3512  if (ira(i) .ge. ia(r(i)+1)) go to 40
3513  irai = ira(i)
3514  jairai = ic(ja(irai))
3515  if (jairai .gt. i) go to 40
3516  jra(i) = irac(jairai)
3517  irac(jairai) = i
3518  40 i = i1
3519  if (i .ne. 0) go to 39
3520  41 continue
3521 c
3522  ijl(n) = jlptr
3523  iju(n) = juptr
3524  flag = 0
3525  return
3526 c
3527 c ** error.. null row in a
3528  101 flag = n + rk
3529  return
3530 c ** error.. duplicate entry in a
3531  102 flag = 2*n + rk
3532  return
3533 c ** error.. insufficient storage for jl
3534  103 flag = 3*n + k
3535  return
3536 c ** error.. null pivot
3537  105 flag = 5*n + k
3538  return
3539 c ** error.. insufficient storage for ju
3540  106 flag = 6*n + k
3541  return
3542  end
3543  subroutine nnfc
3544  * (n, r,c,ic, ia,ja,a, z, b,
3545  * lmax,il,jl,ijl,l, d, umax,iu,ju,iju,u,
3546  * row, tmp, irl,jrl, flag)
3547 c*** subroutine nnfc
3548 c*** numerical ldu-factorization of sparse nonsymmetric matrix and
3549 c solution of system of linear equations (compressed pointer
3550 c storage)
3551 c
3552 c
3553 c input variables.. n, r, c, ic, ia, ja, a, b,
3554 c il, jl, ijl, lmax, iu, ju, iju, umax
3555 c output variables.. z, l, d, u, flag
3556 c
3557 c parameters used internally..
3558 c nia - irl, - vectors used to find the rows of l. at the kth step
3559 c nia - jrl of the factorization, jrl(k) points to the head
3560 c - of a linked list in jrl of column indices j
3561 c - such j .lt. k and l(k,j) is nonzero. zero
3562 c - indicates the end of the list. irl(j) (j.lt.k)
3563 c - points to the smallest i such that i .ge. k and
3564 c - l(i,j) is nonzero.
3565 c - size of each = n.
3566 c fia - row - holds intermediate values in calculation of u and l.
3567 c - size = n.
3568 c fia - tmp - holds new right-hand side b* for solution of the
3569 c - equation ux = b*.
3570 c - size = n.
3571 c
3572 c internal variables..
3573 c jmin, jmax - indices of the first and last positions in a row to
3574 c be examined.
3575 c sum - used in calculating tmp.
3576 c
3577  integer rk,umax
3578  integer r(*), c(*), ic(*), ia(*), ja(*), il(*), jl(*), ijl(*)
3579  integer iu(*), ju(*), iju(*), irl(*), jrl(*), flag
3580 c real a(*), l(*), d(*), u(*), z(*), b(*), row(*)
3581 c real tmp(*), lki, sum, dk
3582  double precision a(*), l(*), d(*), u(*), z(*), b(*), row(*)
3583  double precision tmp(*), lki, sum, dk
3584 c
3585 c ****** initialize pointers and test storage ***********************
3586  if(il(n+1)-1 .gt. lmax) go to 104
3587  if(iu(n+1)-1 .gt. umax) go to 107
3588  do 1 k=1,n
3589  irl(k) = il(k)
3590  jrl(k) = 0
3591  1 continue
3592 c
3593 c ****** for each row ***********************************************
3594  do 19 k=1,n
3595 c ****** reverse jrl and zero row where kth row of l will fill in ***
3596  row(k) = 0
3597  i1 = 0
3598  if (jrl(k) .eq. 0) go to 3
3599  i = jrl(k)
3600  2 i2 = jrl(i)
3601  jrl(i) = i1
3602  i1 = i
3603  row(i) = 0
3604  i = i2
3605  if (i .ne. 0) go to 2
3606 c ****** set row to zero where u will fill in ***********************
3607  3 jmin = iju(k)
3608  jmax = jmin + iu(k+1) - iu(k) - 1
3609  if (jmin .gt. jmax) go to 5
3610  do 4 j=jmin,jmax
3611  4 row(ju(j)) = 0
3612 c ****** place kth row of a in row **********************************
3613  5 rk = r(k)
3614  jmin = ia(rk)
3615  jmax = ia(rk+1) - 1
3616  do 6 j=jmin,jmax
3617  row(ic(ja(j))) = a(j)
3618  6 continue
3619 c ****** initialize sum, and link through jrl ***********************
3620  sum = b(rk)
3621  i = i1
3622  if (i .eq. 0) go to 10
3623 c ****** assign the kth row of l and adjust row, sum ****************
3624  7 lki = -row(i)
3625 c ****** if l is not required, then comment out the following line **
3626  l(irl(i)) = -lki
3627  sum = sum + lki * tmp(i)
3628  jmin = iu(i)
3629  jmax = iu(i+1) - 1
3630  if (jmin .gt. jmax) go to 9
3631  mu = iju(i) - jmin
3632  do 8 j=jmin,jmax
3633  8 row(ju(mu+j)) = row(ju(mu+j)) + lki * u(j)
3634  9 i = jrl(i)
3635  if (i .ne. 0) go to 7
3636 c
3637 c ****** assign kth row of u and diagonal d, set tmp(k) *************
3638  10 if (row(k) .eq. 0.0d0) go to 108
3639  dk = 1.0d0 / row(k)
3640  d(k) = dk
3641  tmp(k) = sum * dk
3642  if (k .eq. n) go to 19
3643  jmin = iu(k)
3644  jmax = iu(k+1) - 1
3645  if (jmin .gt. jmax) go to 12
3646  mu = iju(k) - jmin
3647  do 11 j=jmin,jmax
3648  11 u(j) = row(ju(mu+j)) * dk
3649  12 continue
3650 c
3651 c ****** update irl and jrl, keeping jrl in decreasing order ********
3652  i = i1
3653  if (i .eq. 0) go to 18
3654  14 irl(i) = irl(i) + 1
3655  i1 = jrl(i)
3656  if (irl(i) .ge. il(i+1)) go to 17
3657  ijlb = irl(i) - il(i) + ijl(i)
3658  j = jl(ijlb)
3659  15 if (i .gt. jrl(j)) go to 16
3660  j = jrl(j)
3661  go to 15
3662  16 jrl(i) = jrl(j)
3663  jrl(j) = i
3664  17 i = i1
3665  if (i .ne. 0) go to 14
3666  18 if (irl(k) .ge. il(k+1)) go to 19
3667  j = jl(ijl(k))
3668  jrl(k) = jrl(j)
3669  jrl(j) = k
3670  19 continue
3671 c
3672 c ****** solve ux = tmp by back substitution **********************
3673  k = n
3674  do 22 i=1,n
3675  sum = tmp(k)
3676  jmin = iu(k)
3677  jmax = iu(k+1) - 1
3678  if (jmin .gt. jmax) go to 21
3679  mu = iju(k) - jmin
3680  do 20 j=jmin,jmax
3681  20 sum = sum - u(j) * tmp(ju(mu+j))
3682  21 tmp(k) = sum
3683  z(c(k)) = sum
3684  22 k = k-1
3685  flag = 0
3686  return
3687 c
3688 c ** error.. insufficient storage for l
3689  104 flag = 4*n + 1
3690  return
3691 c ** error.. insufficient storage for u
3692  107 flag = 7*n + 1
3693  return
3694 c ** error.. zero pivot
3695  108 flag = 8*n + k
3696  return
3697  end
3698  subroutine nnsc
3699  * (n, r, c, il, jl, ijl, l, d, iu, ju, iju, u, z, b, tmp)
3700 c*** subroutine nnsc
3701 c*** numerical solution of sparse nonsymmetric system of linear
3702 c equations given ldu-factorization (compressed pointer storage)
3703 c
3704 c
3705 c input variables.. n, r, c, il, jl, ijl, l, d, iu, ju, iju, u, b
3706 c output variables.. z
3707 c
3708 c parameters used internally..
3709 c fia - tmp - temporary vector which gets result of solving ly = b.
3710 c - size = n.
3711 c
3712 c internal variables..
3713 c jmin, jmax - indices of the first and last positions in a row of
3714 c u or l to be used.
3715 c
3716  integer r(*), c(*), il(*), jl(*), ijl(*), iu(*), ju(*), iju(*)
3717 c real l(*), d(*), u(*), b(*), z(*), tmp(*), tmpk, sum
3718  double precision l(*), d(*), u(*), b(*), z(*), tmp(*), tmpk,sum
3719 c
3720 c ****** set tmp to reordered b *************************************
3721  do 1 k=1,n
3722  1 tmp(k) = b(r(k))
3723 c ****** solve ly = b by forward substitution *********************
3724  do 3 k=1,n
3725  jmin = il(k)
3726  jmax = il(k+1) - 1
3727  tmpk = -d(k) * tmp(k)
3728  tmp(k) = -tmpk
3729  if (jmin .gt. jmax) go to 3
3730  ml = ijl(k) - jmin
3731  do 2 j=jmin,jmax
3732  2 tmp(jl(ml+j)) = tmp(jl(ml+j)) + tmpk * l(j)
3733  3 continue
3734 c ****** solve ux = y by back substitution ************************
3735  k = n
3736  do 6 i=1,n
3737  sum = -tmp(k)
3738  jmin = iu(k)
3739  jmax = iu(k+1) - 1
3740  if (jmin .gt. jmax) go to 5
3741  mu = iju(k) - jmin
3742  do 4 j=jmin,jmax
3743  4 sum = sum + u(j) * tmp(ju(mu+j))
3744  5 tmp(k) = -sum
3745  z(c(k)) = -sum
3746  k = k - 1
3747  6 continue
3748  return
3749  end
3750  subroutine nntc
3751  * (n, r, c, il, jl, ijl, l, d, iu, ju, iju, u, z, b, tmp)
3752 c*** subroutine nntc
3753 c*** numeric solution of the transpose of a sparse nonsymmetric system
3754 c of linear equations given lu-factorization (compressed pointer
3755 c storage)
3756 c
3757 c
3758 c input variables.. n, r, c, il, jl, ijl, l, d, iu, ju, iju, u, b
3759 c output variables.. z
3760 c
3761 c parameters used internally..
3762 c fia - tmp - temporary vector which gets result of solving ut y = b
3763 c - size = n.
3764 c
3765 c internal variables..
3766 c jmin, jmax - indices of the first and last positions in a row of
3767 c u or l to be used.
3768 c
3769  integer r(*), c(*), il(*), jl(*), ijl(*), iu(*), ju(*), iju(*)
3770 c real l(*), d(*), u(*), b(*), z(*), tmp(*), tmpk,sum
3771  double precision l(*), d(*), u(*), b(*), z(*), tmp(*), tmpk,sum
3772 c
3773 c ****** set tmp to reordered b *************************************
3774  do 1 k=1,n
3775  1 tmp(k) = b(c(k))
3776 c ****** solve ut y = b by forward substitution *******************
3777  do 3 k=1,n
3778  jmin = iu(k)
3779  jmax = iu(k+1) - 1
3780  tmpk = -tmp(k)
3781  if (jmin .gt. jmax) go to 3
3782  mu = iju(k) - jmin
3783  do 2 j=jmin,jmax
3784  2 tmp(ju(mu+j)) = tmp(ju(mu+j)) + tmpk * u(j)
3785  3 continue
3786 c ****** solve lt x = y by back substitution **********************
3787  k = n
3788  do 6 i=1,n
3789  sum = -tmp(k)
3790  jmin = il(k)
3791  jmax = il(k+1) - 1
3792  if (jmin .gt. jmax) go to 5
3793  ml = ijl(k) - jmin
3794  do 4 j=jmin,jmax
3795  4 sum = sum + l(j) * tmp(jl(ml+j))
3796  5 tmp(k) = -sum * d(k)
3797  z(r(k)) = tmp(k)
3798  k = k - 1
3799  6 continue
3800  return
3801  end
3802 *DECK DSTODA
3803  SUBROUTINE dstoda (NEQ, Y, YH, NYH, YH1, EWT, SAVF, ACOR,
3804  1 WM, IWM, F, JAC, PJAC, SLVS)
3805  EXTERNAL f, jac, pjac, slvs
3806  INTEGER neq, nyh, iwm
3807  DOUBLE PRECISION y, yh, yh1, ewt, savf, acor, wm
3808  dimension neq(*), y(*), yh(nyh,*), yh1(*), ewt(*), savf(*),
3809  1 acor(*), wm(*), iwm(*)
3810  INTEGER iownd, ialth, ipup, lmax, meo, nqnyh, nslp,
3811  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
3812  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
3813  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
3814  INTEGER iownd2, icount, irflag, jtyp, mused, mxordn, mxords
3815  DOUBLE PRECISION conit, crate, el, elco, hold, rmax, tesco,
3816  2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
3817  DOUBLE PRECISION rownd2, cm1, cm2, pdest, pdlast, ratio,
3818  1 pdnorm
3819  COMMON /dls001/ conit, crate, el(13), elco(13,12),
3820  1 hold, rmax, tesco(3,12),
3821  2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
3822  3 iownd(6), ialth, ipup, lmax, meo, nqnyh, nslp,
3823  4 icf, ierpj, iersl, jcur, jstart, kflag, l,
3824  5 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
3825  6 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
3826  COMMON /dlsa01/ rownd2, cm1(12), cm2(5), pdest, pdlast, ratio,
3827  1 pdnorm,
3828  2 iownd2(3), icount, irflag, jtyp, mused, mxordn, mxords
3829  INTEGER i, i1, iredo, iret, j, jb, m, ncf, newq
3830  INTEGER lm1, lm1p1, lm2, lm2p1, nqm1, nqm2
3831  DOUBLE PRECISION dcon, ddn, del, delp, dsm, dup, exdn, exsm, exup,
3832  1 r, rh, rhdn, rhsm, rhup, told, dmnorm
3833  DOUBLE PRECISION alpha, dm1,dm2, exm1,exm2,
3834  1 pdh, pnorm, rate, rh1, rh1it, rh2, rm, sm1(12)
3835  SAVE sm1
3836  DATA sm1/0.5d0, 0.575d0, 0.55d0, 0.45d0, 0.35d0, 0.25d0,
3837  1 0.20d0, 0.15d0, 0.10d0, 0.075d0, 0.050d0, 0.025d0/
3838 C-----------------------------------------------------------------------
3839 C DSTODA performs one step of the integration of an initial value
3840 C problem for a system of ordinary differential equations.
3841 C Note: DSTODA is independent of the value of the iteration method
3842 C indicator MITER, when this is .ne. 0, and hence is independent
3843 C of the type of chord method used, or the Jacobian structure.
3844 C Communication with DSTODA is done with the following variables:
3845 C
3846 C Y = an array of length .ge. N used as the Y argument in
3847 C all calls to F and JAC.
3848 C NEQ = integer array containing problem size in NEQ(1), and
3849 C passed as the NEQ argument in all calls to F and JAC.
3850 C YH = an NYH by LMAX array containing the dependent variables
3851 C and their approximate scaled derivatives, where
3852 C LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
3853 C j-th derivative of y(i), scaled by H**j/factorial(j)
3854 C (j = 0,1,...,NQ). On entry for the first step, the first
3855 C two columns of YH must be set from the initial values.
3856 C NYH = a constant integer .ge. N, the first dimension of YH.
3857 C YH1 = a one-dimensional array occupying the same space as YH.
3858 C EWT = an array of length N containing multiplicative weights
3859 C for local error measurements. Local errors in y(i) are
3860 C compared to 1.0/EWT(i) in various error tests.
3861 C SAVF = an array of working storage, of length N.
3862 C ACOR = a work array of length N, used for the accumulated
3863 C corrections. On a successful return, ACOR(i) contains
3864 C the estimated one-step local error in y(i).
3865 C WM,IWM = real and integer work arrays associated with matrix
3866 C operations in chord iteration (MITER .ne. 0).
3867 C PJAC = name of routine to evaluate and preprocess Jacobian matrix
3868 C and P = I - H*EL0*Jac, if a chord method is being used.
3869 C It also returns an estimate of norm(Jac) in PDNORM.
3870 C SLVS = name of routine to solve linear system in chord iteration.
3871 C CCMAX = maximum relative change in H*EL0 before PJAC is called.
3872 C H = the step size to be attempted on the next step.
3873 C H is altered by the error control algorithm during the
3874 C problem. H can be either positive or negative, but its
3875 C sign must remain constant throughout the problem.
3876 C HMIN = the minimum absolute value of the step size H to be used.
3877 C HMXI = inverse of the maximum absolute value of H to be used.
3878 C HMXI = 0.0 is allowed and corresponds to an infinite HMAX.
3879 C HMIN and HMXI may be changed at any time, but will not
3880 C take effect until the next change of H is considered.
3881 C TN = the independent variable. TN is updated on each step taken.
3882 C JSTART = an integer used for input only, with the following
3883 C values and meanings:
3884 C 0 perform the first step.
3885 C .gt.0 take a new step continuing from the last.
3886 C -1 take the next step with a new value of H,
3887 C N, METH, MITER, and/or matrix parameters.
3888 C -2 take the next step with a new value of H,
3889 C but with other inputs unchanged.
3890 C On return, JSTART is set to 1 to facilitate continuation.
3891 C KFLAG = a completion code with the following meanings:
3892 C 0 the step was succesful.
3893 C -1 the requested error could not be achieved.
3894 C -2 corrector convergence could not be achieved.
3895 C -3 fatal error in PJAC or SLVS.
3896 C A return with KFLAG = -1 or -2 means either
3897 C ABS(H) = HMIN or 10 consecutive failures occurred.
3898 C On a return with KFLAG negative, the values of TN and
3899 C the YH array are as of the beginning of the last
3900 C step, and H is the last step size attempted.
3901 C MAXORD = the maximum order of integration method to be allowed.
3902 C MAXCOR = the maximum number of corrector iterations allowed.
3903 C MSBP = maximum number of steps between PJAC calls (MITER .gt. 0).
3904 C MXNCF = maximum number of convergence failures allowed.
3905 C METH = current method.
3906 C METH = 1 means Adams method (nonstiff)
3907 C METH = 2 means BDF method (stiff)
3908 C METH may be reset by DSTODA.
3909 C MITER = corrector iteration method.
3910 C MITER = 0 means functional iteration.
3911 C MITER = JT .gt. 0 means a chord iteration corresponding
3912 C to Jacobian type JT. (The DLSODA/DLSODAR argument JT is
3913 C communicated here as JTYP, but is not used in DSTODA
3914 C except to load MITER following a method switch.)
3915 C MITER may be reset by DSTODA.
3916 C N = the number of first-order differential equations.
3917 C-----------------------------------------------------------------------
3918  kflag = 0
3919  told = tn
3920  ncf = 0
3921  ierpj = 0
3922  iersl = 0
3923  jcur = 0
3924  icf = 0
3925  delp = 0.0d0
3926  IF (jstart .GT. 0) GO TO 200
3927  IF (jstart .EQ. -1) GO TO 100
3928  IF (jstart .EQ. -2) GO TO 160
3929 C-----------------------------------------------------------------------
3930 C On the first call, the order is set to 1, and other variables are
3931 C initialized. RMAX is the maximum ratio by which H can be increased
3932 C in a single step. It is initially 1.E4 to compensate for the small
3933 C initial H, but then is normally equal to 10. If a failure
3934 C occurs (in corrector convergence or error test), RMAX is set at 2
3935 C for the next increase.
3936 C DCFODE is called to get the needed coefficients for both methods.
3937 C-----------------------------------------------------------------------
3938  lmax = maxord + 1
3939  nq = 1
3940  l = 2
3941  ialth = 2
3942  rmax = 10000.0d0
3943  rc = 0.0d0
3944  el0 = 1.0d0
3945  crate = 0.7d0
3946  hold = h
3947  nslp = 0
3948  ipup = miter
3949  iret = 3
3950 C Initialize switching parameters. METH = 1 is assumed initially. -----
3951  icount = 20
3952  irflag = 0
3953  pdest = 0.0d0
3954  pdlast = 0.0d0
3955  ratio = 5.0d0
3956  CALL dcfode (2, elco, tesco)
3957  DO 10 i = 1,5
3958  10 cm2(i) = tesco(2,i)*elco(i+1,i)
3959  CALL dcfode (1, elco, tesco)
3960  DO 20 i = 1,12
3961  20 cm1(i) = tesco(2,i)*elco(i+1,i)
3962  GO TO 150
3963 C-----------------------------------------------------------------------
3964 C The following block handles preliminaries needed when JSTART = -1.
3965 C IPUP is set to MITER to force a matrix update.
3966 C If an order increase is about to be considered (IALTH = 1),
3967 C IALTH is reset to 2 to postpone consideration one more step.
3968 C If the caller has changed METH, DCFODE is called to reset
3969 C the coefficients of the method.
3970 C If H is to be changed, YH must be rescaled.
3971 C If H or METH is being changed, IALTH is reset to L = NQ + 1
3972 C to prevent further changes in H for that many steps.
3973 C-----------------------------------------------------------------------
3974  100 ipup = miter
3975  lmax = maxord + 1
3976  IF (ialth .EQ. 1) ialth = 2
3977  IF (meth .EQ. mused) GO TO 160
3978  CALL dcfode (meth, elco, tesco)
3979  ialth = l
3980  iret = 1
3981 C-----------------------------------------------------------------------
3982 C The el vector and related constants are reset
3983 C whenever the order NQ is changed, or at the start of the problem.
3984 C-----------------------------------------------------------------------
3985  150 DO 155 i = 1,l
3986  155 el(i) = elco(i,nq)
3987  nqnyh = nq*nyh
3988  rc = rc*el(1)/el0
3989  el0 = el(1)
3990  conit = 0.5d0/(nq+2)
3991  GO TO (160, 170, 200), iret
3992 C-----------------------------------------------------------------------
3993 C If H is being changed, the H ratio RH is checked against
3994 C RMAX, HMIN, and HMXI, and the YH array rescaled. IALTH is set to
3995 C L = NQ + 1 to prevent a change of H for that many steps, unless
3996 C forced by a convergence or error test failure.
3997 C-----------------------------------------------------------------------
3998  160 IF (h .EQ. hold) GO TO 200
3999  rh = h/hold
4000  h = hold
4001  iredo = 3
4002  GO TO 175
4003  170 rh = max(rh,hmin/abs(h))
4004  175 rh = min(rh,rmax)
4005  rh = rh/max(1.0d0,abs(h)*hmxi*rh)
4006 C-----------------------------------------------------------------------
4007 C If METH = 1, also restrict the new step size by the stability region.
4008 C If this reduces H, set IRFLAG to 1 so that if there are roundoff
4009 C problems later, we can assume that is the cause of the trouble.
4010 C-----------------------------------------------------------------------
4011  IF (meth .EQ. 2) GO TO 178
4012  irflag = 0
4013  pdh = max(abs(h)*pdlast,0.000001d0)
4014  IF (rh*pdh*1.00001d0 .LT. sm1(nq)) GO TO 178
4015  rh = sm1(nq)/pdh
4016  irflag = 1
4017  178 CONTINUE
4018  r = 1.0d0
4019  DO 180 j = 2,l
4020  r = r*rh
4021  DO 180 i = 1,n
4022  180 yh(i,j) = yh(i,j)*r
4023  h = h*rh
4024  rc = rc*rh
4025  ialth = l
4026  IF (iredo .EQ. 0) GO TO 690
4027 C-----------------------------------------------------------------------
4028 C This section computes the predicted values by effectively
4029 C multiplying the YH array by the Pascal triangle matrix.
4030 C RC is the ratio of new to old values of the coefficient H*EL(1).
4031 C When RC differs from 1 by more than CCMAX, IPUP is set to MITER
4032 C to force PJAC to be called, if a Jacobian is involved.
4033 C In any case, PJAC is called at least every MSBP steps.
4034 C-----------------------------------------------------------------------
4035  200 IF (abs(rc-1.0d0) .GT. ccmax) ipup = miter
4036  IF (nst .GE. nslp+msbp) ipup = miter
4037  tn = tn + h
4038  i1 = nqnyh + 1
4039  DO 215 jb = 1,nq
4040  i1 = i1 - nyh
4041 CDIR$ IVDEP
4042  DO 210 i = i1,nqnyh
4043  210 yh1(i) = yh1(i) + yh1(i+nyh)
4044  215 CONTINUE
4045  pnorm = dmnorm(n, yh1, ewt)
4046 C-----------------------------------------------------------------------
4047 C Up to MAXCOR corrector iterations are taken. A convergence test is
4048 C made on the RMS-norm of each correction, weighted by the error
4049 C weight vector EWT. The sum of the corrections is accumulated in the
4050 C vector ACOR(i). The YH array is not altered in the corrector loop.
4051 C-----------------------------------------------------------------------
4052  220 m = 0
4053  rate = 0.0d0
4054  del = 0.0d0
4055  DO 230 i = 1,n
4056  230 y(i) = yh(i,1)
4057  CALL f (neq, tn, y, savf)
4058  nfe = nfe + 1
4059  IF (ipup .LE. 0) GO TO 250
4060 C-----------------------------------------------------------------------
4061 C If indicated, the matrix P = I - H*EL(1)*J is reevaluated and
4062 C preprocessed before starting the corrector iteration. IPUP is set
4063 C to 0 as an indicator that this has been done.
4064 C-----------------------------------------------------------------------
4065  CALL pjac (neq, y, yh, nyh, ewt, acor, savf, wm, iwm, f, jac)
4066  ipup = 0
4067  rc = 1.0d0
4068  nslp = nst
4069  crate = 0.7d0
4070  IF (ierpj .NE. 0) GO TO 430
4071  250 DO 260 i = 1,n
4072  260 acor(i) = 0.0d0
4073  270 IF (miter .NE. 0) GO TO 350
4074 C-----------------------------------------------------------------------
4075 C In the case of functional iteration, update Y directly from
4076 C the result of the last function evaluation.
4077 C-----------------------------------------------------------------------
4078  DO 290 i = 1,n
4079  savf(i) = h*savf(i) - yh(i,2)
4080  290 y(i) = savf(i) - acor(i)
4081  del = dmnorm(n, y, ewt)
4082  DO 300 i = 1,n
4083  y(i) = yh(i,1) + el(1)*savf(i)
4084  300 acor(i) = savf(i)
4085  GO TO 400
4086 C-----------------------------------------------------------------------
4087 C In the case of the chord method, compute the corrector error,
4088 C and solve the linear system with that as right-hand side and
4089 C P as coefficient matrix.
4090 C-----------------------------------------------------------------------
4091  350 DO 360 i = 1,n
4092  360 y(i) = h*savf(i) - (yh(i,2) + acor(i))
4093  CALL slvs (wm, iwm, y, savf)
4094  IF (iersl .LT. 0) GO TO 430
4095  IF (iersl .GT. 0) GO TO 410
4096  del = dmnorm(n, y, ewt)
4097  DO 380 i = 1,n
4098  acor(i) = acor(i) + y(i)
4099  380 y(i) = yh(i,1) + el(1)*acor(i)
4100 C-----------------------------------------------------------------------
4101 C Test for convergence. If M .gt. 0, an estimate of the convergence
4102 C rate constant is stored in CRATE, and this is used in the test.
4103 C
4104 C We first check for a change of iterates that is the size of
4105 C roundoff error. If this occurs, the iteration has converged, and a
4106 C new rate estimate is not formed.
4107 C In all other cases, force at least two iterations to estimate a
4108 C local Lipschitz constant estimate for Adams methods.
4109 C On convergence, form PDEST = local maximum Lipschitz constant
4110 C estimate. PDLAST is the most recent nonzero estimate.
4111 C-----------------------------------------------------------------------
4112  400 CONTINUE
4113  IF (del .LE. 100.0d0*pnorm*uround) GO TO 450
4114  IF (m .EQ. 0 .AND. meth .EQ. 1) GO TO 405
4115  IF (m .EQ. 0) GO TO 402
4116  rm = 1024.0d0
4117  IF (del .LE. 1024.0d0*delp) rm = del/delp
4118  rate = max(rate,rm)
4119  crate = max(0.2d0*crate,rm)
4120  402 dcon = del*min(1.0d0,1.5d0*crate)/(tesco(2,nq)*conit)
4121  IF (dcon .GT. 1.0d0) GO TO 405
4122  pdest = max(pdest,rate/abs(h*el(1)))
4123  IF (pdest .NE. 0.0d0) pdlast = pdest
4124  GO TO 450
4125  405 CONTINUE
4126  m = m + 1
4127  IF (m .EQ. maxcor) GO TO 410
4128  IF (m .GE. 2 .AND. del .GT. 2.0d0*delp) GO TO 410
4129  delp = del
4130  CALL f (neq, tn, y, savf)
4131  nfe = nfe + 1
4132  GO TO 270
4133 C-----------------------------------------------------------------------
4134 C The corrector iteration failed to converge.
4135 C If MITER .ne. 0 and the Jacobian is out of date, PJAC is called for
4136 C the next try. Otherwise the YH array is retracted to its values
4137 C before prediction, and H is reduced, if possible. If H cannot be
4138 C reduced or MXNCF failures have occurred, exit with KFLAG = -2.
4139 C-----------------------------------------------------------------------
4140  410 IF (miter .EQ. 0 .OR. jcur .EQ. 1) GO TO 430
4141  icf = 1
4142  ipup = miter
4143  GO TO 220
4144  430 icf = 2
4145  ncf = ncf + 1
4146  rmax = 2.0d0
4147  tn = told
4148  i1 = nqnyh + 1
4149  DO 445 jb = 1,nq
4150  i1 = i1 - nyh
4151 CDIR$ IVDEP
4152  DO 440 i = i1,nqnyh
4153  440 yh1(i) = yh1(i) - yh1(i+nyh)
4154  445 CONTINUE
4155  IF (ierpj .LT. 0 .OR. iersl .LT. 0) GO TO 680
4156  IF (abs(h) .LE. hmin*1.00001d0) GO TO 670
4157  IF (ncf .EQ. mxncf) GO TO 670
4158  rh = 0.25d0
4159  ipup = miter
4160  iredo = 1
4161  GO TO 170
4162 C-----------------------------------------------------------------------
4163 C The corrector has converged. JCUR is set to 0
4164 C to signal that the Jacobian involved may need updating later.
4165 C The local error test is made and control passes to statement 500
4166 C if it fails.
4167 C-----------------------------------------------------------------------
4168  450 jcur = 0
4169  IF (m .EQ. 0) dsm = del/tesco(2,nq)
4170  IF (m .GT. 0) dsm = dmnorm(n, acor, ewt)/tesco(2,nq)
4171  IF (dsm .GT. 1.0d0) GO TO 500
4172 C-----------------------------------------------------------------------
4173 C After a successful step, update the YH array.
4174 C Decrease ICOUNT by 1, and if it is -1, consider switching methods.
4175 C If a method switch is made, reset various parameters,
4176 C rescale the YH array, and exit. If there is no switch,
4177 C consider changing H if IALTH = 1. Otherwise decrease IALTH by 1.
4178 C If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
4179 C use in a possible order increase on the next step.
4180 C If a change in H is considered, an increase or decrease in order
4181 C by one is considered also. A change in H is made only if it is by a
4182 C factor of at least 1.1. If not, IALTH is set to 3 to prevent
4183 C testing for that many steps.
4184 C-----------------------------------------------------------------------
4185  kflag = 0
4186  iredo = 0
4187  nst = nst + 1
4188  hu = h
4189  nqu = nq
4190  mused = meth
4191  DO 460 j = 1,l
4192  DO 460 i = 1,n
4193  460 yh(i,j) = yh(i,j) + el(j)*acor(i)
4194  icount = icount - 1
4195  IF (icount .GE. 0) GO TO 488
4196  IF (meth .EQ. 2) GO TO 480
4197 C-----------------------------------------------------------------------
4198 C We are currently using an Adams method. Consider switching to BDF.
4199 C If the current order is greater than 5, assume the problem is
4200 C not stiff, and skip this section.
4201 C If the Lipschitz constant and error estimate are not polluted
4202 C by roundoff, go to 470 and perform the usual test.
4203 C Otherwise, switch to the BDF methods if the last step was
4204 C restricted to insure stability (irflag = 1), and stay with Adams
4205 C method if not. When switching to BDF with polluted error estimates,
4206 C in the absence of other information, double the step size.
4207 C
4208 C When the estimates are OK, we make the usual test by computing
4209 C the step size we could have (ideally) used on this step,
4210 C with the current (Adams) method, and also that for the BDF.
4211 C If NQ .gt. MXORDS, we consider changing to order MXORDS on switching.
4212 C Compare the two step sizes to decide whether to switch.
4213 C The step size advantage must be at least RATIO = 5 to switch.
4214 C-----------------------------------------------------------------------
4215  IF (nq .GT. 5) GO TO 488
4216  IF (dsm .GT. 100.0d0*pnorm*uround .AND. pdest .NE. 0.0d0)
4217  1 GO TO 470
4218  IF (irflag .EQ. 0) GO TO 488
4219  rh2 = 2.0d0
4220  nqm2 = min(nq,mxords)
4221  GO TO 478
4222  470 CONTINUE
4223  exsm = 1.0d0/l
4224  rh1 = 1.0d0/(1.2d0*dsm**exsm + 0.0000012d0)
4225  rh1it = 2.0d0*rh1
4226  pdh = pdlast*abs(h)
4227  IF (pdh*rh1 .GT. 0.00001d0) rh1it = sm1(nq)/pdh
4228  rh1 = min(rh1,rh1it)
4229  IF (nq .LE. mxords) GO TO 474
4230  nqm2 = mxords
4231  lm2 = mxords + 1
4232  exm2 = 1.0d0/lm2
4233  lm2p1 = lm2 + 1
4234  dm2 = dmnorm(n, yh(1,lm2p1), ewt)/cm2(mxords)
4235  rh2 = 1.0d0/(1.2d0*dm2**exm2 + 0.0000012d0)
4236  GO TO 476
4237  474 dm2 = dsm*(cm1(nq)/cm2(nq))
4238  rh2 = 1.0d0/(1.2d0*dm2**exsm + 0.0000012d0)
4239  nqm2 = nq
4240  476 CONTINUE
4241  IF (rh2 .LT. ratio*rh1) GO TO 488
4242 C THE SWITCH TEST PASSED. RESET RELEVANT QUANTITIES FOR BDF. ----------
4243  478 rh = rh2
4244  icount = 20
4245  meth = 2
4246  miter = jtyp
4247  pdlast = 0.0d0
4248  nq = nqm2
4249  l = nq + 1
4250  GO TO 170
4251 C-----------------------------------------------------------------------
4252 C We are currently using a BDF method. Consider switching to Adams.
4253 C Compute the step size we could have (ideally) used on this step,
4254 C with the current (BDF) method, and also that for the Adams.
4255 C If NQ .gt. MXORDN, we consider changing to order MXORDN on switching.
4256 C Compare the two step sizes to decide whether to switch.
4257 C The step size advantage must be at least 5/RATIO = 1 to switch.
4258 C If the step size for Adams would be so small as to cause
4259 C roundoff pollution, we stay with BDF.
4260 C-----------------------------------------------------------------------
4261  480 CONTINUE
4262  exsm = 1.0d0/l
4263  IF (mxordn .GE. nq) GO TO 484
4264  nqm1 = mxordn
4265  lm1 = mxordn + 1
4266  exm1 = 1.0d0/lm1
4267  lm1p1 = lm1 + 1
4268  dm1 = dmnorm(n, yh(1,lm1p1), ewt)/cm1(mxordn)
4269  rh1 = 1.0d0/(1.2d0*dm1**exm1 + 0.0000012d0)
4270  GO TO 486
4271  484 dm1 = dsm*(cm2(nq)/cm1(nq))
4272  rh1 = 1.0d0/(1.2d0*dm1**exsm + 0.0000012d0)
4273  nqm1 = nq
4274  exm1 = exsm
4275  486 rh1it = 2.0d0*rh1
4276  pdh = pdnorm*abs(h)
4277  IF (pdh*rh1 .GT. 0.00001d0) rh1it = sm1(nqm1)/pdh
4278  rh1 = min(rh1,rh1it)
4279  rh2 = 1.0d0/(1.2d0*dsm**exsm + 0.0000012d0)
4280  IF (rh1*ratio .LT. 5.0d0*rh2) GO TO 488
4281  alpha = max(0.001d0,rh1)
4282  dm1 = (alpha**exm1)*dm1
4283  IF (dm1 .LE. 1000.0d0*uround*pnorm) GO TO 488
4284 C The switch test passed. Reset relevant quantities for Adams. --------
4285  rh = rh1
4286  icount = 20
4287  meth = 1
4288  miter = 0
4289  pdlast = 0.0d0
4290  nq = nqm1
4291  l = nq + 1
4292  GO TO 170
4293 C
4294 C No method switch is being made. Do the usual step/order selection. --
4295  488 CONTINUE
4296  ialth = ialth - 1
4297  IF (ialth .EQ. 0) GO TO 520
4298  IF (ialth .GT. 1) GO TO 700
4299  IF (l .EQ. lmax) GO TO 700
4300  DO 490 i = 1,n
4301  490 yh(i,lmax) = acor(i)
4302  GO TO 700
4303 C-----------------------------------------------------------------------
4304 C The error test failed. KFLAG keeps track of multiple failures.
4305 C Restore TN and the YH array to their previous values, and prepare
4306 C to try the step again. Compute the optimum step size for this or
4307 C one lower order. After 2 or more failures, H is forced to decrease
4308 C by a factor of 0.2 or less.
4309 C-----------------------------------------------------------------------
4310  500 kflag = kflag - 1
4311  tn = told
4312  i1 = nqnyh + 1
4313  DO 515 jb = 1,nq
4314  i1 = i1 - nyh
4315 CDIR$ IVDEP
4316  DO 510 i = i1,nqnyh
4317  510 yh1(i) = yh1(i) - yh1(i+nyh)
4318  515 CONTINUE
4319  rmax = 2.0d0
4320  IF (abs(h) .LE. hmin*1.00001d0) GO TO 660
4321  IF (kflag .LE. -3) GO TO 640
4322  iredo = 2
4323  rhup = 0.0d0
4324  GO TO 540
4325 C-----------------------------------------------------------------------
4326 C Regardless of the success or failure of the step, factors
4327 C RHDN, RHSM, and RHUP are computed, by which H could be multiplied
4328 C at order NQ - 1, order NQ, or order NQ + 1, respectively.
4329 C In the case of failure, RHUP = 0.0 to avoid an order increase.
4330 C The largest of these is determined and the new order chosen
4331 C accordingly. If the order is to be increased, we compute one
4332 C additional scaled derivative.
4333 C-----------------------------------------------------------------------
4334  520 rhup = 0.0d0
4335  IF (l .EQ. lmax) GO TO 540
4336  DO 530 i = 1,n
4337  530 savf(i) = acor(i) - yh(i,lmax)
4338  dup = dmnorm(n, savf, ewt)/tesco(3,nq)
4339  exup = 1.0d0/(l+1)
4340  rhup = 1.0d0/(1.4d0*dup**exup + 0.0000014d0)
4341  540 exsm = 1.0d0/l
4342  rhsm = 1.0d0/(1.2d0*dsm**exsm + 0.0000012d0)
4343  rhdn = 0.0d0
4344  IF (nq .EQ. 1) GO TO 550
4345  ddn = dmnorm(n, yh(1,l), ewt)/tesco(1,nq)
4346  exdn = 1.0d0/nq
4347  rhdn = 1.0d0/(1.3d0*ddn**exdn + 0.0000013d0)
4348 C If METH = 1, limit RH according to the stability region also. --------
4349  550 IF (meth .EQ. 2) GO TO 560
4350  pdh = max(abs(h)*pdlast,0.000001d0)
4351  IF (l .LT. lmax) rhup = min(rhup,sm1(l)/pdh)
4352  rhsm = min(rhsm,sm1(nq)/pdh)
4353  IF (nq .GT. 1) rhdn = min(rhdn,sm1(nq-1)/pdh)
4354  pdest = 0.0d0
4355  560 IF (rhsm .GE. rhup) GO TO 570
4356  IF (rhup .GT. rhdn) GO TO 590
4357  GO TO 580
4358  570 IF (rhsm .LT. rhdn) GO TO 580
4359  newq = nq
4360  rh = rhsm
4361  GO TO 620
4362  580 newq = nq - 1
4363  rh = rhdn
4364  IF (kflag .LT. 0 .AND. rh .GT. 1.0d0) rh = 1.0d0
4365  GO TO 620
4366  590 newq = l
4367  rh = rhup
4368  IF (rh .LT. 1.1d0) GO TO 610
4369  r = el(l)/l
4370  DO 600 i = 1,n
4371  600 yh(i,newq+1) = acor(i)*r
4372  GO TO 630
4373  610 ialth = 3
4374  GO TO 700
4375 C If METH = 1 and H is restricted by stability, bypass 10 percent test.
4376  620 IF (meth .EQ. 2) GO TO 622
4377  IF (rh*pdh*1.00001d0 .GE. sm1(newq)) GO TO 625
4378  622 IF (kflag .EQ. 0 .AND. rh .LT. 1.1d0) GO TO 610
4379  625 IF (kflag .LE. -2) rh = min(rh,0.2d0)
4380 C-----------------------------------------------------------------------
4381 C If there is a change of order, reset NQ, L, and the coefficients.
4382 C In any case H is reset according to RH and the YH array is rescaled.
4383 C Then exit from 690 if the step was OK, or redo the step otherwise.
4384 C-----------------------------------------------------------------------
4385  IF (newq .EQ. nq) GO TO 170
4386  630 nq = newq
4387  l = nq + 1
4388  iret = 2
4389  GO TO 150
4390 C-----------------------------------------------------------------------
4391 C Control reaches this section if 3 or more failures have occured.
4392 C If 10 failures have occurred, exit with KFLAG = -1.
4393 C It is assumed that the derivatives that have accumulated in the
4394 C YH array have errors of the wrong order. Hence the first
4395 C derivative is recomputed, and the order is set to 1. Then
4396 C H is reduced by a factor of 10, and the step is retried,
4397 C until it succeeds or H reaches HMIN.
4398 C-----------------------------------------------------------------------
4399  640 IF (kflag .EQ. -10) GO TO 660
4400  rh = 0.1d0
4401  rh = max(hmin/abs(h),rh)
4402  h = h*rh
4403  DO 645 i = 1,n
4404  645 y(i) = yh(i,1)
4405  CALL f (neq, tn, y, savf)
4406  nfe = nfe + 1
4407  DO 650 i = 1,n
4408  650 yh(i,2) = h*savf(i)
4409  ipup = miter
4410  ialth = 5
4411  IF (nq .EQ. 1) GO TO 200
4412  nq = 1
4413  l = 2
4414  iret = 3
4415  GO TO 150
4416 C-----------------------------------------------------------------------
4417 C All returns are made through this section. H is saved in HOLD
4418 C to allow the caller to change H on the next step.
4419 C-----------------------------------------------------------------------
4420  660 kflag = -1
4421  GO TO 720
4422  670 kflag = -2
4423  GO TO 720
4424  680 kflag = -3
4425  GO TO 720
4426  690 rmax = 10.0d0
4427  700 r = 1.0d0/tesco(2,nqu)
4428  DO 710 i = 1,n
4429  710 acor(i) = acor(i)*r
4430  720 hold = h
4431  jstart = 1
4432  RETURN
4433 C----------------------- End of Subroutine DSTODA ----------------------
4434  END
4435 *DECK DPRJA
4436  SUBROUTINE dprja (NEQ, Y, YH, NYH, EWT, FTEM, SAVF, WM, IWM,
4437  1 F, JAC)
4438  EXTERNAL f, jac
4439  INTEGER neq, nyh, iwm
4440  DOUBLE PRECISION y, yh, ewt, ftem, savf, wm
4441  dimension neq(*), y(*), yh(nyh,*), ewt(*), ftem(*), savf(*),
4442  1 wm(*), iwm(*)
4443  INTEGER iownd, iowns,
4444  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
4445  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
4446  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
4447  INTEGER iownd2, iowns2, jtyp, mused, mxordn, mxords
4448  DOUBLE PRECISION rowns,
4449  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
4450  DOUBLE PRECISION rownd2, rowns2, pdnorm
4451  COMMON /dls001/ rowns(209),
4452  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
4453  2 iownd(6), iowns(6),
4454  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
4455  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
4456  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
4457  COMMON /dlsa01/ rownd2, rowns2(20), pdnorm,
4458  1 iownd2(3), iowns2(2), jtyp, mused, mxordn, mxords
4459  INTEGER i, i1, i2, ier, ii, j, j1, jj, lenp,
4460  1 mba, mband, meb1, meband, ml, ml3, mu, np1
4461  DOUBLE PRECISION con, fac, hl0, r, r0, srur, yi, yj, yjj,
4462  1 dmnorm, dfnorm, dbnorm
4463 C-----------------------------------------------------------------------
4464 C DPRJA is called by DSTODA to compute and process the matrix
4465 C P = I - H*EL(1)*J , where J is an approximation to the Jacobian.
4466 C Here J is computed by the user-supplied routine JAC if
4467 C MITER = 1 or 4 or by finite differencing if MITER = 2 or 5.
4468 C J, scaled by -H*EL(1), is stored in WM. Then the norm of J (the
4469 C matrix norm consistent with the weighted max-norm on vectors given
4470 C by DMNORM) is computed, and J is overwritten by P. P is then
4471 C subjected to LU decomposition in preparation for later solution
4472 C of linear systems with P as coefficient matrix. This is done
4473 C by DGEFA if MITER = 1 or 2, and by DGBFA if MITER = 4 or 5.
4474 C
4475 C In addition to variables described previously, communication
4476 C with DPRJA uses the following:
4477 C Y = array containing predicted values on entry.
4478 C FTEM = work array of length N (ACOR in DSTODA).
4479 C SAVF = array containing f evaluated at predicted y.
4480 C WM = real work space for matrices. On output it contains the
4481 C LU decomposition of P.
4482 C Storage of matrix elements starts at WM(3).
4483 C WM also contains the following matrix-related data:
4484 C WM(1) = SQRT(UROUND), used in numerical Jacobian increments.
4485 C IWM = integer work space containing pivot information, starting at
4486 C IWM(21). IWM also contains the band parameters
4487 C ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
4488 C EL0 = EL(1) (input).
4489 C PDNORM= norm of Jacobian matrix. (Output).
4490 C IERPJ = output error flag, = 0 if no trouble, .gt. 0 if
4491 C P matrix found to be singular.
4492 C JCUR = output flag = 1 to indicate that the Jacobian matrix
4493 C (or approximation) is now current.
4494 C This routine also uses the Common variables EL0, H, TN, UROUND,
4495 C MITER, N, NFE, and NJE.
4496 C-----------------------------------------------------------------------
4497  nje = nje + 1
4498  ierpj = 0
4499  jcur = 1
4500  hl0 = h*el0
4501  GO TO (100, 200, 300, 400, 500), miter
4502 C If MITER = 1, call JAC and multiply by scalar. -----------------------
4503  100 lenp = n*n
4504  DO 110 i = 1,lenp
4505  110 wm(i+2) = 0.0d0
4506  CALL jac (neq, tn, y, 0, 0, wm(3), n)
4507  con = -hl0
4508  DO 120 i = 1,lenp
4509  120 wm(i+2) = wm(i+2)*con
4510  GO TO 240
4511 C If MITER = 2, make N calls to F to approximate J. --------------------
4512  200 fac = dmnorm(n, savf, ewt)
4513  r0 = 1000.0d0*abs(h)*uround*n*fac
4514  IF (r0 .EQ. 0.0d0) r0 = 1.0d0
4515  srur = wm(1)
4516  j1 = 2
4517  DO 230 j = 1,n
4518  yj = y(j)
4519  r = max(srur*abs(yj),r0/ewt(j))
4520  y(j) = y(j) + r
4521  fac = -hl0/r
4522  CALL f (neq, tn, y, ftem)
4523  DO 220 i = 1,n
4524  220 wm(i+j1) = (ftem(i) - savf(i))*fac
4525  y(j) = yj
4526  j1 = j1 + n
4527  230 CONTINUE
4528  nfe = nfe + n
4529  240 CONTINUE
4530 C Compute norm of Jacobian. --------------------------------------------
4531  pdnorm = dfnorm(n, wm(3), ewt)/abs(hl0)
4532 C Add identity matrix. -------------------------------------------------
4533  j = 3
4534  np1 = n + 1
4535  DO 250 i = 1,n
4536  wm(j) = wm(j) + 1.0d0
4537  250 j = j + np1
4538 C Do LU decomposition on P. --------------------------------------------
4539  CALL dgefa (wm(3), n, n, iwm(21), ier)
4540  IF (ier .NE. 0) ierpj = 1
4541  RETURN
4542 C Dummy block only, since MITER is never 3 in this routine. ------------
4543  300 RETURN
4544 C If MITER = 4, call JAC and multiply by scalar. -----------------------
4545  400 ml = iwm(1)
4546  mu = iwm(2)
4547  ml3 = ml + 3
4548  mband = ml + mu + 1
4549  meband = mband + ml
4550  lenp = meband*n
4551  DO 410 i = 1,lenp
4552  410 wm(i+2) = 0.0d0
4553  CALL jac (neq, tn, y, ml, mu, wm(ml3), meband)
4554  con = -hl0
4555  DO 420 i = 1,lenp
4556  420 wm(i+2) = wm(i+2)*con
4557  GO TO 570
4558 C If MITER = 5, make MBAND calls to F to approximate J. ----------------
4559  500 ml = iwm(1)
4560  mu = iwm(2)
4561  mband = ml + mu + 1
4562  mba = min(mband,n)
4563  meband = mband + ml
4564  meb1 = meband - 1
4565  srur = wm(1)
4566  fac = dmnorm(n, savf, ewt)
4567  r0 = 1000.0d0*abs(h)*uround*n*fac
4568  IF (r0 .EQ. 0.0d0) r0 = 1.0d0
4569  DO 560 j = 1,mba
4570  DO 530 i = j,n,mband
4571  yi = y(i)
4572  r = max(srur*abs(yi),r0/ewt(i))
4573  530 y(i) = y(i) + r
4574  CALL f (neq, tn, y, ftem)
4575  DO 550 jj = j,n,mband
4576  y(jj) = yh(jj,1)
4577  yjj = y(jj)
4578  r = max(srur*abs(yjj),r0/ewt(jj))
4579  fac = -hl0/r
4580  i1 = max(jj-mu,1)
4581  i2 = min(jj+ml,n)
4582  ii = jj*meb1 - ml + 2
4583  DO 540 i = i1,i2
4584  540 wm(ii+i) = (ftem(i) - savf(i))*fac
4585  550 CONTINUE
4586  560 CONTINUE
4587  nfe = nfe + mba
4588  570 CONTINUE
4589 C Compute norm of Jacobian. --------------------------------------------
4590  pdnorm = dbnorm(n, wm(ml+3), meband, ml, mu, ewt)/abs(hl0)
4591 C Add identity matrix. -------------------------------------------------
4592  ii = mband + 2
4593  DO 580 i = 1,n
4594  wm(ii) = wm(ii) + 1.0d0
4595  580 ii = ii + meband
4596 C Do LU decomposition of P. --------------------------------------------
4597  CALL dgbfa (wm(3), meband, n, ml, mu, iwm(21), ier)
4598  IF (ier .NE. 0) ierpj = 1
4599  RETURN
4600 C----------------------- End of Subroutine DPRJA -----------------------
4601  END
4602 *DECK DMNORM
4603  DOUBLE PRECISION FUNCTION dmnorm (N, V, W)
4604 C-----------------------------------------------------------------------
4605 C This function routine computes the weighted max-norm
4606 C of the vector of length N contained in the array V, with weights
4607 C contained in the array w of length N:
4608 C DMNORM = MAX(i=1,...,N) ABS(V(i))*W(i)
4609 C-----------------------------------------------------------------------
4610  INTEGER n, i
4611  DOUBLE PRECISION v, w, vm
4612  dimension v(n), w(n)
4613  vm = 0.0d0
4614  DO 10 i = 1,n
4615  10 vm = max(vm,abs(v(i))*w(i))
4616  dmnorm = vm
4617  RETURN
4618 C----------------------- End of Function DMNORM ------------------------
4619  END
4620 *DECK DFNORM
4621  DOUBLE PRECISION FUNCTION dfnorm (N, A, W)
4622 C-----------------------------------------------------------------------
4623 C This function computes the norm of a full N by N matrix,
4624 C stored in the array A, that is consistent with the weighted max-norm
4625 C on vectors, with weights stored in the array W:
4626 C DFNORM = MAX(i=1,...,N) ( W(i) * Sum(j=1,...,N) ABS(a(i,j))/W(j) )
4627 C-----------------------------------------------------------------------
4628  INTEGER n, i, j
4629  DOUBLE PRECISION a, w, an, sum
4630  dimension a(n,n), w(n)
4631  an = 0.0d0
4632  DO 20 i = 1,n
4633  sum = 0.0d0
4634  DO 10 j = 1,n
4635  10 sum = sum + abs(a(i,j))/w(j)
4636  an = max(an,sum*w(i))
4637  20 CONTINUE
4638  dfnorm = an
4639  RETURN
4640 C----------------------- End of Function DFNORM ------------------------
4641  END
4642 *DECK DBNORM
4643  DOUBLE PRECISION FUNCTION dbnorm (N, A, NRA, ML, MU, W)
4644 C-----------------------------------------------------------------------
4645 C This function computes the norm of a banded N by N matrix,
4646 C stored in the array A, that is consistent with the weighted max-norm
4647 C on vectors, with weights stored in the array W.
4648 C ML and MU are the lower and upper half-bandwidths of the matrix.
4649 C NRA is the first dimension of the A array, NRA .ge. ML+MU+1.
4650 C In terms of the matrix elements a(i,j), the norm is given by:
4651 C DBNORM = MAX(i=1,...,N) ( W(i) * Sum(j=1,...,N) ABS(a(i,j))/W(j) )
4652 C-----------------------------------------------------------------------
4653  INTEGER n, nra, ml, mu
4654  INTEGER i, i1, jlo, jhi, j
4655  DOUBLE PRECISION a, w
4656  DOUBLE PRECISION an, sum
4657  dimension a(nra,n), w(n)
4658  an = 0.0d0
4659  DO 20 i = 1,n
4660  sum = 0.0d0
4661  i1 = i + mu + 1
4662  jlo = max(i-ml,1)
4663  jhi = min(i+mu,n)
4664  DO 10 j = jlo,jhi
4665  10 sum = sum + abs(a(i1-j,j))/w(j)
4666  an = max(an,sum*w(i))
4667  20 CONTINUE
4668  dbnorm = an
4669  RETURN
4670 C----------------------- End of Function DBNORM ------------------------
4671  END
4672 *DECK DSRCMA
4673  SUBROUTINE dsrcma (RSAV, ISAV, JOB)
4674 C-----------------------------------------------------------------------
4675 C This routine saves or restores (depending on JOB) the contents of
4676 C the Common blocks DLS001, DLSA01, which are used
4677 C internally by one or more ODEPACK solvers.
4678 C
4679 C RSAV = real array of length 240 or more.
4680 C ISAV = integer array of length 46 or more.
4681 C JOB = flag indicating to save or restore the Common blocks:
4682 C JOB = 1 if Common is to be saved (written to RSAV/ISAV)
4683 C JOB = 2 if Common is to be restored (read from RSAV/ISAV)
4684 C A call with JOB = 2 presumes a prior call with JOB = 1.
4685 C-----------------------------------------------------------------------
4686  INTEGER isav, job
4687  INTEGER ils, ilsa
4688  INTEGER i, lenrls, lenils, lenrla, lenila
4689  DOUBLE PRECISION rsav
4690  DOUBLE PRECISION rls, rlsa
4691  dimension rsav(*), isav(*)
4692  SAVE lenrls, lenils, lenrla, lenila
4693  COMMON /dls001/ rls(218), ils(37)
4694  COMMON /dlsa01/ rlsa(22), ilsa(9)
4695  DATA lenrls/218/, lenils/37/, lenrla/22/, lenila/9/
4696 C
4697  IF (job .EQ. 2) GO TO 100
4698  DO 10 i = 1,lenrls
4699  10 rsav(i) = rls(i)
4700  DO 15 i = 1,lenrla
4701  15 rsav(lenrls+i) = rlsa(i)
4702 C
4703  DO 20 i = 1,lenils
4704  20 isav(i) = ils(i)
4705  DO 25 i = 1,lenila
4706  25 isav(lenils+i) = ilsa(i)
4707 C
4708  RETURN
4709 C
4710  100 CONTINUE
4711  DO 110 i = 1,lenrls
4712  110 rls(i) = rsav(i)
4713  DO 115 i = 1,lenrla
4714  115 rlsa(i) = rsav(lenrls+i)
4715 C
4716  DO 120 i = 1,lenils
4717  120 ils(i) = isav(i)
4718  DO 125 i = 1,lenila
4719  125 ilsa(i) = isav(lenils+i)
4720 C
4721  RETURN
4722 C----------------------- End of Subroutine DSRCMA ----------------------
4723  END
4724 *DECK DRCHEK
4725  SUBROUTINE drchek (JOB, G, NEQ, Y, YH,NYH, G0, G1, GX, JROOT, IRT)
4726  EXTERNAL g
4727  INTEGER job, neq, nyh, jroot, irt
4728  DOUBLE PRECISION y, yh, g0, g1, gx
4729  dimension neq(*), y(*), yh(nyh,*), g0(*), g1(*), gx(*), jroot(*)
4730  INTEGER iownd, iowns,
4731  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
4732  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
4733  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
4734  INTEGER iownd3, iownr3, irfnd, itaskc, ngc, nge
4735  DOUBLE PRECISION rowns,
4736  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
4737  DOUBLE PRECISION rownr3, t0, tlast, toutc
4738  COMMON /dls001/ rowns(209),
4739  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
4740  2 iownd(6), iowns(6),
4741  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
4742  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
4743  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
4744  COMMON /dlsr01/ rownr3(2), t0, tlast, toutc,
4745  1 iownd3(3), iownr3(2), irfnd, itaskc, ngc, nge
4746  INTEGER i, iflag, jflag
4747  DOUBLE PRECISION hming, t1, temp1, temp2, x
4748  LOGICAL zroot
4749 C-----------------------------------------------------------------------
4750 C This routine checks for the presence of a root in the vicinity of
4751 C the current T, in a manner depending on the input flag JOB. It calls
4752 C Subroutine DROOTS to locate the root as precisely as possible.
4753 C
4754 C In addition to variables described previously, DRCHEK
4755 C uses the following for communication:
4756 C JOB = integer flag indicating type of call:
4757 C JOB = 1 means the problem is being initialized, and DRCHEK
4758 C is to look for a root at or very near the initial T.
4759 C JOB = 2 means a continuation call to the solver was just
4760 C made, and DRCHEK is to check for a root in the
4761 C relevant part of the step last taken.
4762 C JOB = 3 means a successful step was just taken, and DRCHEK
4763 C is to look for a root in the interval of the step.
4764 C G0 = array of length NG, containing the value of g at T = T0.
4765 C G0 is input for JOB .ge. 2, and output in all cases.
4766 C G1,GX = arrays of length NG for work space.
4767 C IRT = completion flag:
4768 C IRT = 0 means no root was found.
4769 C IRT = -1 means JOB = 1 and a root was found too near to T.
4770 C IRT = 1 means a legitimate root was found (JOB = 2 or 3).
4771 C On return, T0 is the root location, and Y is the
4772 C corresponding solution vector.
4773 C T0 = value of T at one endpoint of interval of interest. Only
4774 C roots beyond T0 in the direction of integration are sought.
4775 C T0 is input if JOB .ge. 2, and output in all cases.
4776 C T0 is updated by DRCHEK, whether a root is found or not.
4777 C TLAST = last value of T returned by the solver (input only).
4778 C TOUTC = copy of TOUT (input only).
4779 C IRFND = input flag showing whether the last step taken had a root.
4780 C IRFND = 1 if it did, = 0 if not.
4781 C ITASKC = copy of ITASK (input only).
4782 C NGC = copy of NG (input only).
4783 C-----------------------------------------------------------------------
4784  irt = 0
4785  DO 10 i = 1,ngc
4786  10 jroot(i) = 0
4787  hming = (abs(tn) + abs(h))*uround*100.0d0
4788 C
4789  GO TO (100, 200, 300), job
4790 C
4791 C Evaluate g at initial T, and check for zero values. ------------------
4792  100 CONTINUE
4793  t0 = tn
4794  CALL g (neq, t0, y, ngc, g0)
4795  nge = 1
4796  zroot = .false.
4797  DO 110 i = 1,ngc
4798  110 IF (abs(g0(i)) .LE. 0.0d0) zroot = .true.
4799  IF (.NOT. zroot) GO TO 190
4800 C g has a zero at T. Look at g at T + (small increment). --------------
4801  temp2 = max(hming/abs(h), 0.1d0)
4802  temp1 = temp2*h
4803  t0 = t0 + temp1
4804  DO 120 i = 1,n
4805  120 y(i) = y(i) + temp2*yh(i,2)
4806  CALL g (neq, t0, y, ngc, g0)
4807  nge = nge + 1
4808  zroot = .false.
4809  DO 130 i = 1,ngc
4810  130 IF (abs(g0(i)) .LE. 0.0d0) zroot = .true.
4811  IF (.NOT. zroot) GO TO 190
4812 C g has a zero at T and also close to T. Take error return. -----------
4813  irt = -1
4814  RETURN
4815 C
4816  190 CONTINUE
4817  RETURN
4818 C
4819 C
4820  200 CONTINUE
4821  IF (irfnd .EQ. 0) GO TO 260
4822 C If a root was found on the previous step, evaluate G0 = g(T0). -------
4823  CALL dintdy (t0, 0, yh, nyh, y, iflag)
4824  CALL g (neq, t0, y, ngc, g0)
4825  nge = nge + 1
4826  zroot = .false.
4827  DO 210 i = 1,ngc
4828  210 IF (abs(g0(i)) .LE. 0.0d0) zroot = .true.
4829  IF (.NOT. zroot) GO TO 260
4830 C g has a zero at T0. Look at g at T + (small increment). -------------
4831  temp1 = sign(hming,h)
4832  t0 = t0 + temp1
4833  IF ((t0 - tn)*h .LT. 0.0d0) GO TO 230
4834  temp2 = temp1/h
4835  DO 220 i = 1,n
4836  220 y(i) = y(i) + temp2*yh(i,2)
4837  GO TO 240
4838  230 CALL dintdy (t0, 0, yh, nyh, y, iflag)
4839  240 CALL g (neq, t0, y, ngc, g0)
4840  nge = nge + 1
4841  zroot = .false.
4842  DO 250 i = 1,ngc
4843  IF (abs(g0(i)) .GT. 0.0d0) GO TO 250
4844  jroot(i) = 1
4845  zroot = .true.
4846  250 CONTINUE
4847  IF (.NOT. zroot) GO TO 260
4848 C g has a zero at T0 and also close to T0. Return root. ---------------
4849  irt = 1
4850  RETURN
4851 C G0 has no zero components. Proceed to check relevant interval. ------
4852  260 IF (tn .EQ. tlast) GO TO 390
4853 C
4854  300 CONTINUE
4855 C Set T1 to TN or TOUTC, whichever comes first, and get g at T1. -------
4856  IF (itaskc.EQ.2 .OR. itaskc.EQ.3 .OR. itaskc.EQ.5) GO TO 310
4857  IF ((toutc - tn)*h .GE. 0.0d0) GO TO 310
4858  t1 = toutc
4859  IF ((t1 - t0)*h .LE. 0.0d0) GO TO 390
4860  CALL dintdy (t1, 0, yh, nyh, y, iflag)
4861  GO TO 330
4862  310 t1 = tn
4863  DO 320 i = 1,n
4864  320 y(i) = yh(i,1)
4865  330 CALL g (neq, t1, y, ngc, g1)
4866  nge = nge + 1
4867 C Call DROOTS to search for root in interval from T0 to T1. ------------
4868  jflag = 0
4869  350 CONTINUE
4870  CALL droots (ngc, hming, jflag, t0, t1, g0, g1, gx, x, jroot)
4871  IF (jflag .GT. 1) GO TO 360
4872  CALL dintdy (x, 0, yh, nyh, y, iflag)
4873  CALL g (neq, x, y, ngc, gx)
4874  nge = nge + 1
4875  GO TO 350
4876  360 t0 = x
4877  CALL dcopy (ngc, gx, 1, g0, 1)
4878  IF (jflag .EQ. 4) GO TO 390
4879 C Found a root. Interpolate to X and return. --------------------------
4880  CALL dintdy (x, 0, yh, nyh, y, iflag)
4881  irt = 1
4882  RETURN
4883 C
4884  390 CONTINUE
4885  RETURN
4886 C----------------------- End of Subroutine DRCHEK ----------------------
4887  END
4888 *DECK DROOTS
4889  SUBROUTINE droots (NG, HMIN, JFLAG, X0, X1, G0, G1, GX, X, JROOT)
4890  INTEGER ng, jflag, jroot
4891  DOUBLE PRECISION hmin, x0, x1, g0, g1, gx, x
4892  dimension g0(ng), g1(ng), gx(ng), jroot(ng)
4893  INTEGER iownd3, imax, last, idum3
4894  DOUBLE PRECISION alpha, x2, rdum3
4895  COMMON /dlsr01/ alpha, x2, rdum3(3),
4896  1 iownd3(3), imax, last, idum3(4)
4897 C-----------------------------------------------------------------------
4898 C This subroutine finds the leftmost root of a set of arbitrary
4899 C functions gi(x) (i = 1,...,NG) in an interval (X0,X1). Only roots
4900 C of odd multiplicity (i.e. changes of sign of the gi) are found.
4901 C Here the sign of X1 - X0 is arbitrary, but is constant for a given
4902 C problem, and -leftmost- means nearest to X0.
4903 C The values of the vector-valued function g(x) = (gi, i=1...NG)
4904 C are communicated through the call sequence of DROOTS.
4905 C The method used is the Illinois algorithm.
4906 C
4907 C Reference:
4908 C Kathie L. Hiebert and Lawrence F. Shampine, Implicitly Defined
4909 C Output Points for Solutions of ODEs, Sandia Report SAND80-0180,
4910 C February 1980.
4911 C
4912 C Description of parameters.
4913 C
4914 C NG = number of functions gi, or the number of components of
4915 C the vector valued function g(x). Input only.
4916 C
4917 C HMIN = resolution parameter in X. Input only. When a root is
4918 C found, it is located only to within an error of HMIN in X.
4919 C Typically, HMIN should be set to something on the order of
4920 C 100 * UROUND * MAX(ABS(X0),ABS(X1)),
4921 C where UROUND is the unit roundoff of the machine.
4922 C
4923 C JFLAG = integer flag for input and output communication.
4924 C
4925 C On input, set JFLAG = 0 on the first call for the problem,
4926 C and leave it unchanged until the problem is completed.
4927 C (The problem is completed when JFLAG .ge. 2 on return.)
4928 C
4929 C On output, JFLAG has the following values and meanings:
4930 C JFLAG = 1 means DROOTS needs a value of g(x). Set GX = g(X)
4931 C and call DROOTS again.
4932 C JFLAG = 2 means a root has been found. The root is
4933 C at X, and GX contains g(X). (Actually, X is the
4934 C rightmost approximation to the root on an interval
4935 C (X0,X1) of size HMIN or less.)
4936 C JFLAG = 3 means X = X1 is a root, with one or more of the gi
4937 C being zero at X1 and no sign changes in (X0,X1).
4938 C GX contains g(X) on output.
4939 C JFLAG = 4 means no roots (of odd multiplicity) were
4940 C found in (X0,X1) (no sign changes).
4941 C
4942 C X0,X1 = endpoints of the interval where roots are sought.
4943 C X1 and X0 are input when JFLAG = 0 (first call), and
4944 C must be left unchanged between calls until the problem is
4945 C completed. X0 and X1 must be distinct, but X1 - X0 may be
4946 C of either sign. However, the notion of -left- and -right-
4947 C will be used to mean nearer to X0 or X1, respectively.
4948 C When JFLAG .ge. 2 on return, X0 and X1 are output, and
4949 C are the endpoints of the relevant interval.
4950 C
4951 C G0,G1 = arrays of length NG containing the vectors g(X0) and g(X1),
4952 C respectively. When JFLAG = 0, G0 and G1 are input and
4953 C none of the G0(i) should be zero.
4954 C When JFLAG .ge. 2 on return, G0 and G1 are output.
4955 C
4956 C GX = array of length NG containing g(X). GX is input
4957 C when JFLAG = 1, and output when JFLAG .ge. 2.
4958 C
4959 C X = independent variable value. Output only.
4960 C When JFLAG = 1 on output, X is the point at which g(x)
4961 C is to be evaluated and loaded into GX.
4962 C When JFLAG = 2 or 3, X is the root.
4963 C When JFLAG = 4, X is the right endpoint of the interval, X1.
4964 C
4965 C JROOT = integer array of length NG. Output only.
4966 C When JFLAG = 2 or 3, JROOT indicates which components
4967 C of g(x) have a root at X. JROOT(i) is 1 if the i-th
4968 C component has a root, and JROOT(i) = 0 otherwise.
4969 C-----------------------------------------------------------------------
4970  INTEGER i, imxold, nxlast
4971  DOUBLE PRECISION t2, tmax, fracint, fracsub, zero,half,tenth,five
4972  LOGICAL zroot, sgnchg, xroot
4973  SAVE zero, half, tenth, five
4974  DATA zero/0.0d0/, half/0.5d0/, tenth/0.1d0/, five/5.0d0/
4975 C
4976  IF (jflag .EQ. 1) GO TO 200
4977 C JFLAG .ne. 1. Check for change in sign of g or zero at X1. ----------
4978  imax = 0
4979  tmax = zero
4980  zroot = .false.
4981  DO 120 i = 1,ng
4982  IF (abs(g1(i)) .GT. zero) GO TO 110
4983  zroot = .true.
4984  GO TO 120
4985 C At this point, G0(i) has been checked and cannot be zero. ------------
4986  110 IF (sign(1.0d0,g0(i)) .EQ. sign(1.0d0,g1(i))) GO TO 120
4987  t2 = abs(g1(i)/(g1(i)-g0(i)))
4988  IF (t2 .LE. tmax) GO TO 120
4989  tmax = t2
4990  imax = i
4991  120 CONTINUE
4992  IF (imax .GT. 0) GO TO 130
4993  sgnchg = .false.
4994  GO TO 140
4995  130 sgnchg = .true.
4996  140 IF (.NOT. sgnchg) GO TO 400
4997 C There is a sign change. Find the first root in the interval. --------
4998  xroot = .false.
4999  nxlast = 0
5000  last = 1
5001 C
5002 C Repeat until the first root in the interval is found. Loop point. ---
5003  150 CONTINUE
5004  IF (xroot) GO TO 300
5005  IF (nxlast .EQ. last) GO TO 160
5006  alpha = 1.0d0
5007  GO TO 180
5008  160 IF (last .EQ. 0) GO TO 170
5009  alpha = 0.5d0*alpha
5010  GO TO 180
5011  170 alpha = 2.0d0*alpha
5012  180 x2 = x1 - (x1 - x0)*g1(imax) / (g1(imax) - alpha*g0(imax))
5013 C If X2 is too close to X0 or X1, adjust it inward, by a fractional ----
5014 C distance that is between 0.1 and 0.5. --------------------------------
5015  IF (abs(x2 - x0) < half*hmin) THEN
5016  fracint = abs(x1 - x0)/hmin
5017  fracsub = tenth
5018  IF (fracint .LE. five) fracsub = half/fracint
5019  x2 = x0 + fracsub*(x1 - x0)
5020  ENDIF
5021  IF (abs(x1 - x2) < half*hmin) THEN
5022  fracint = abs(x1 - x0)/hmin
5023  fracsub = tenth
5024  IF (fracint .LE. five) fracsub = half/fracint
5025  x2 = x1 - fracsub*(x1 - x0)
5026  ENDIF
5027  jflag = 1
5028  x = x2
5029 C Return to the calling routine to get a value of GX = g(X). -----------
5030  RETURN
5031 C Check to see in which interval g changes sign. -----------------------
5032  200 imxold = imax
5033  imax = 0
5034  tmax = zero
5035  zroot = .false.
5036  DO 220 i = 1,ng
5037  IF (abs(gx(i)) .GT. zero) GO TO 210
5038  zroot = .true.
5039  GO TO 220
5040 C Neither G0(i) nor GX(i) can be zero at this point. -------------------
5041  210 IF (sign(1.0d0,g0(i)) .EQ. sign(1.0d0,gx(i))) GO TO 220
5042  t2 = abs(gx(i)/(gx(i) - g0(i)))
5043  IF (t2 .LE. tmax) GO TO 220
5044  tmax = t2
5045  imax = i
5046  220 CONTINUE
5047  IF (imax .GT. 0) GO TO 230
5048  sgnchg = .false.
5049  imax = imxold
5050  GO TO 240
5051  230 sgnchg = .true.
5052  240 nxlast = last
5053  IF (.NOT. sgnchg) GO TO 250
5054 C Sign change between X0 and X2, so replace X1 with X2. ----------------
5055  x1 = x2
5056  CALL dcopy (ng, gx, 1, g1, 1)
5057  last = 1
5058  xroot = .false.
5059  GO TO 270
5060  250 IF (.NOT. zroot) GO TO 260
5061 C Zero value at X2 and no sign change in (X0,X2), so X2 is a root. -----
5062  x1 = x2
5063  CALL dcopy (ng, gx, 1, g1, 1)
5064  xroot = .true.
5065  GO TO 270
5066 C No sign change between X0 and X2. Replace X0 with X2. ---------------
5067  260 CONTINUE
5068  CALL dcopy (ng, gx, 1, g0, 1)
5069  x0 = x2
5070  last = 0
5071  xroot = .false.
5072  270 IF (abs(x1-x0) .LE. hmin) xroot = .true.
5073  GO TO 150
5074 C
5075 C Return with X1 as the root. Set JROOT. Set X = X1 and GX = G1. -----
5076  300 jflag = 2
5077  x = x1
5078  CALL dcopy (ng, g1, 1, gx, 1)
5079  DO 320 i = 1,ng
5080  jroot(i) = 0
5081  IF (abs(g1(i)) .GT. zero) GO TO 310
5082  jroot(i) = 1
5083  GO TO 320
5084  310 IF (sign(1.0d0,g0(i)) .NE. sign(1.0d0,g1(i))) jroot(i) = 1
5085  320 CONTINUE
5086  RETURN
5087 C
5088 C No sign change in the interval. Check for zero at right endpoint. ---
5089  400 IF (.NOT. zroot) GO TO 420
5090 C
5091 C Zero value at X1 and no sign change in (X0,X1). Return JFLAG = 3. ---
5092  x = x1
5093  CALL dcopy (ng, g1, 1, gx, 1)
5094  DO 410 i = 1,ng
5095  jroot(i) = 0
5096  IF (abs(g1(i)) .LE. zero) jroot(i) = 1
5097  410 CONTINUE
5098  jflag = 3
5099  RETURN
5100 C
5101 C No sign changes in this interval. Set X = X1, return JFLAG = 4. -----
5102  420 CALL dcopy (ng, g1, 1, gx, 1)
5103  x = x1
5104  jflag = 4
5105  RETURN
5106 C----------------------- End of Subroutine DROOTS ----------------------
5107  END
5108 *DECK DSRCAR
5109  SUBROUTINE dsrcar (RSAV, ISAV, JOB)
5110 C-----------------------------------------------------------------------
5111 C This routine saves or restores (depending on JOB) the contents of
5112 C the Common blocks DLS001, DLSA01, DLSR01, which are used
5113 C internally by one or more ODEPACK solvers.
5114 C
5115 C RSAV = real array of length 245 or more.
5116 C ISAV = integer array of length 55 or more.
5117 C JOB = flag indicating to save or restore the Common blocks:
5118 C JOB = 1 if Common is to be saved (written to RSAV/ISAV)
5119 C JOB = 2 if Common is to be restored (read from RSAV/ISAV)
5120 C A call with JOB = 2 presumes a prior call with JOB = 1.
5121 C-----------------------------------------------------------------------
5122  INTEGER isav, job
5123  INTEGER ils, ilsa, ilsr
5124  INTEGER i, ioff, lenrls, lenils, lenrla, lenila, lenrlr, lenilr
5125  DOUBLE PRECISION rsav
5126  DOUBLE PRECISION rls, rlsa, rlsr
5127  dimension rsav(*), isav(*)
5128  SAVE lenrls, lenils, lenrla, lenila, lenrlr, lenilr
5129  COMMON /dls001/ rls(218), ils(37)
5130  COMMON /dlsa01/ rlsa(22), ilsa(9)
5131  COMMON /dlsr01/ rlsr(5), ilsr(9)
5132  DATA lenrls/218/, lenils/37/, lenrla/22/, lenila/9/
5133  DATA lenrlr/5/, lenilr/9/
5134 C
5135  IF (job .EQ. 2) GO TO 100
5136  DO 10 i = 1,lenrls
5137  10 rsav(i) = rls(i)
5138  DO 15 i = 1,lenrla
5139  15 rsav(lenrls+i) = rlsa(i)
5140  ioff = lenrls + lenrla
5141  DO 20 i = 1,lenrlr
5142  20 rsav(ioff+i) = rlsr(i)
5143 C
5144  DO 30 i = 1,lenils
5145  30 isav(i) = ils(i)
5146  DO 35 i = 1,lenila
5147  35 isav(lenils+i) = ilsa(i)
5148  ioff = lenils + lenila
5149  DO 40 i = 1,lenilr
5150  40 isav(ioff+i) = ilsr(i)
5151 C
5152  RETURN
5153 C
5154  100 CONTINUE
5155  DO 110 i = 1,lenrls
5156  110 rls(i) = rsav(i)
5157  DO 115 i = 1,lenrla
5158  115 rlsa(i) = rsav(lenrls+i)
5159  ioff = lenrls + lenrla
5160  DO 120 i = 1,lenrlr
5161  120 rlsr(i) = rsav(ioff+i)
5162 C
5163  DO 130 i = 1,lenils
5164  130 ils(i) = isav(i)
5165  DO 135 i = 1,lenila
5166  135 ilsa(i) = isav(lenils+i)
5167  ioff = lenils + lenila
5168  DO 140 i = 1,lenilr
5169  140 ilsr(i) = isav(ioff+i)
5170 C
5171  RETURN
5172 C----------------------- End of Subroutine DSRCAR ----------------------
5173  END
5174 *DECK DSTODPK
5175  SUBROUTINE dstodpk (NEQ, Y, YH, NYH, YH1, EWT, SAVF, SAVX, ACOR,
5176  1 WM, IWM, F, JAC, PSOL)
5177  EXTERNAL f, jac, psol
5178  INTEGER neq, nyh, iwm
5179  DOUBLE PRECISION y, yh, yh1, ewt, savf, savx, acor, wm
5180  dimension neq(*), y(*), yh(nyh,*), yh1(*), ewt(*), savf(*),
5181  1 savx(*), acor(*), wm(*), iwm(*)
5182  INTEGER iownd, ialth, ipup, lmax, meo, nqnyh, nslp,
5183  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
5184  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
5185  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
5186  INTEGER jpre, jacflg, locwp, lociwp, lsavx, kmp, maxl, mnewt,
5187  1 nni, nli, nps, ncfn, ncfl
5188  DOUBLE PRECISION conit, crate, el, elco, hold, rmax, tesco,
5189  2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
5190  DOUBLE PRECISION delt, epcon, sqrtn, rsqrtn
5191  COMMON /dls001/ conit, crate, el(13), elco(13,12),
5192  1 hold, rmax, tesco(3,12),
5193  2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
5194  3 iownd(6), ialth, ipup, lmax, meo, nqnyh, nslp,
5195  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
5196  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
5197  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
5198  COMMON /dlpk01/ delt, epcon, sqrtn, rsqrtn,
5199  1 jpre, jacflg, locwp, lociwp, lsavx, kmp, maxl, mnewt,
5200  2 nni, nli, nps, ncfn, ncfl
5201 C-----------------------------------------------------------------------
5202 C DSTODPK performs one step of the integration of an initial value
5203 C problem for a system of Ordinary Differential Equations.
5204 C-----------------------------------------------------------------------
5205 C The following changes were made to generate Subroutine DSTODPK
5206 C from Subroutine DSTODE:
5207 C 1. The array SAVX was added to the call sequence.
5208 C 2. PJAC and SLVS were replaced by PSOL in the call sequence.
5209 C 3. The Common block /DLPK01/ was added for communication.
5210 C 4. The test constant EPCON is loaded into Common below statement
5211 C numbers 125 and 155, and used below statement 400.
5212 C 5. The Newton iteration counter MNEWT is set below 220 and 400.
5213 C 6. The call to PJAC was replaced with a call to DPKSET (fixed name),
5214 C with a longer call sequence, called depending on JACFLG.
5215 C 7. The corrector residual is stored in SAVX (not Y) at 360,
5216 C and the solution vector is in SAVX in the 380 loop.
5217 C 8. SLVS was renamed DSOLPK and includes NEQ, SAVX, EWT, F, and JAC.
5218 C SAVX was added because DSOLPK now needs Y and SAVF undisturbed.
5219 C 9. The nonlinear convergence failure count NCFN is set at 430.
5220 C-----------------------------------------------------------------------
5221 C Note: DSTODPK is independent of the value of the iteration method
5222 C indicator MITER, when this is .ne. 0, and hence is independent
5223 C of the type of chord method used, or the Jacobian structure.
5224 C Communication with DSTODPK is done with the following variables:
5225 C
5226 C NEQ = integer array containing problem size in NEQ(1), and
5227 C passed as the NEQ argument in all calls to F and JAC.
5228 C Y = an array of length .ge. N used as the Y argument in
5229 C all calls to F and JAC.
5230 C YH = an NYH by LMAX array containing the dependent variables
5231 C and their approximate scaled derivatives, where
5232 C LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
5233 C j-th derivative of y(i), scaled by H**j/factorial(j)
5234 C (j = 0,1,...,NQ). On entry for the first step, the first
5235 C two columns of YH must be set from the initial values.
5236 C NYH = a constant integer .ge. N, the first dimension of YH.
5237 C YH1 = a one-dimensional array occupying the same space as YH.
5238 C EWT = an array of length N containing multiplicative weights
5239 C for local error measurements. Local errors in y(i) are
5240 C compared to 1.0/EWT(i) in various error tests.
5241 C SAVF = an array of working storage, of length N.
5242 C Also used for input of YH(*,MAXORD+2) when JSTART = -1
5243 C and MAXORD .lt. the current order NQ.
5244 C SAVX = an array of working storage, of length N.
5245 C ACOR = a work array of length N, used for the accumulated
5246 C corrections. On a successful return, ACOR(i) contains
5247 C the estimated one-step local error in y(i).
5248 C WM,IWM = real and integer work arrays associated with matrix
5249 C operations in chord iteration (MITER .ne. 0).
5250 C CCMAX = maximum relative change in H*EL0 before DPKSET is called.
5251 C H = the step size to be attempted on the next step.
5252 C H is altered by the error control algorithm during the
5253 C problem. H can be either positive or negative, but its
5254 C sign must remain constant throughout the problem.
5255 C HMIN = the minimum absolute value of the step size H to be used.
5256 C HMXI = inverse of the maximum absolute value of H to be used.
5257 C HMXI = 0.0 is allowed and corresponds to an infinite HMAX.
5258 C HMIN and HMXI may be changed at any time, but will not
5259 C take effect until the next change of H is considered.
5260 C TN = the independent variable. TN is updated on each step taken.
5261 C JSTART = an integer used for input only, with the following
5262 C values and meanings:
5263 C 0 perform the first step.
5264 C .gt.0 take a new step continuing from the last.
5265 C -1 take the next step with a new value of H, MAXORD,
5266 C N, METH, MITER, and/or matrix parameters.
5267 C -2 take the next step with a new value of H,
5268 C but with other inputs unchanged.
5269 C On return, JSTART is set to 1 to facilitate continuation.
5270 C KFLAG = a completion code with the following meanings:
5271 C 0 the step was succesful.
5272 C -1 the requested error could not be achieved.
5273 C -2 corrector convergence could not be achieved.
5274 C -3 fatal error in DPKSET or DSOLPK.
5275 C A return with KFLAG = -1 or -2 means either
5276 C ABS(H) = HMIN or 10 consecutive failures occurred.
5277 C On a return with KFLAG negative, the values of TN and
5278 C the YH array are as of the beginning of the last
5279 C step, and H is the last step size attempted.
5280 C MAXORD = the maximum order of integration method to be allowed.
5281 C MAXCOR = the maximum number of corrector iterations allowed.
5282 C MSBP = maximum number of steps between DPKSET calls (MITER .gt. 0).
5283 C MXNCF = maximum number of convergence failures allowed.
5284 C METH/MITER = the method flags. See description in driver.
5285 C N = the number of first-order differential equations.
5286 C-----------------------------------------------------------------------
5287  INTEGER i, i1, iredo, iret, j, jb, m, ncf, newq
5288  DOUBLE PRECISION dcon, ddn, del, delp, dsm, dup, exdn, exsm, exup,
5289  1 r, rh, rhdn, rhsm, rhup, told, dvnorm
5290 C
5291  kflag = 0
5292  told = tn
5293  ncf = 0
5294  ierpj = 0
5295  iersl = 0
5296  jcur = 0
5297  icf = 0
5298  delp = 0.0d0
5299  IF (jstart .GT. 0) GO TO 200
5300  IF (jstart .EQ. -1) GO TO 100
5301  IF (jstart .EQ. -2) GO TO 160
5302 C-----------------------------------------------------------------------
5303 C On the first call, the order is set to 1, and other variables are
5304 C initialized. RMAX is the maximum ratio by which H can be increased
5305 C in a single step. It is initially 1.E4 to compensate for the small
5306 C initial H, but then is normally equal to 10. If a failure
5307 C occurs (in corrector convergence or error test), RMAX is set at 2
5308 C for the next increase.
5309 C-----------------------------------------------------------------------
5310  lmax = maxord + 1
5311  nq = 1
5312  l = 2
5313  ialth = 2
5314  rmax = 10000.0d0
5315  rc = 0.0d0
5316  el0 = 1.0d0
5317  crate = 0.7d0
5318  hold = h
5319  meo = meth
5320  nslp = 0
5321  ipup = miter
5322  iret = 3
5323  GO TO 140
5324 C-----------------------------------------------------------------------
5325 C The following block handles preliminaries needed when JSTART = -1.
5326 C IPUP is set to MITER to force a matrix update.
5327 C If an order increase is about to be considered (IALTH = 1),
5328 C IALTH is reset to 2 to postpone consideration one more step.
5329 C If the caller has changed METH, DCFODE is called to reset
5330 C the coefficients of the method.
5331 C If the caller has changed MAXORD to a value less than the current
5332 C order NQ, NQ is reduced to MAXORD, and a new H chosen accordingly.
5333 C If H is to be changed, YH must be rescaled.
5334 C If H or METH is being changed, IALTH is reset to L = NQ + 1
5335 C to prevent further changes in H for that many steps.
5336 C-----------------------------------------------------------------------
5337  100 ipup = miter
5338  lmax = maxord + 1
5339  IF (ialth .EQ. 1) ialth = 2
5340  IF (meth .EQ. meo) GO TO 110
5341  CALL dcfode (meth, elco, tesco)
5342  meo = meth
5343  IF (nq .GT. maxord) GO TO 120
5344  ialth = l
5345  iret = 1
5346  GO TO 150
5347  110 IF (nq .LE. maxord) GO TO 160
5348  120 nq = maxord
5349  l = lmax
5350  DO 125 i = 1,l
5351  125 el(i) = elco(i,nq)
5352  nqnyh = nq*nyh
5353  rc = rc*el(1)/el0
5354  el0 = el(1)
5355  conit = 0.5d0/(nq+2)
5356  epcon = conit*tesco(2,nq)
5357  ddn = dvnorm(n, savf, ewt)/tesco(1,l)
5358  exdn = 1.0d0/l
5359  rhdn = 1.0d0/(1.3d0*ddn**exdn + 0.0000013d0)
5360  rh = min(rhdn,1.0d0)
5361  iredo = 3
5362  IF (h .EQ. hold) GO TO 170
5363  rh = min(rh,abs(h/hold))
5364  h = hold
5365  GO TO 175
5366 C-----------------------------------------------------------------------
5367 C DCFODE is called to get all the integration coefficients for the
5368 C current METH. Then the EL vector and related constants are reset
5369 C whenever the order NQ is changed, or at the start of the problem.
5370 C-----------------------------------------------------------------------
5371  140 CALL dcfode (meth, elco, tesco)
5372  150 DO 155 i = 1,l
5373  155 el(i) = elco(i,nq)
5374  nqnyh = nq*nyh
5375  rc = rc*el(1)/el0
5376  el0 = el(1)
5377  conit = 0.5d0/(nq+2)
5378  epcon = conit*tesco(2,nq)
5379  GO TO (160, 170, 200), iret
5380 C-----------------------------------------------------------------------
5381 C If H is being changed, the H ratio RH is checked against
5382 C RMAX, HMIN, and HMXI, and the YH array rescaled. IALTH is set to
5383 C L = NQ + 1 to prevent a change of H for that many steps, unless
5384 C forced by a convergence or error test failure.
5385 C-----------------------------------------------------------------------
5386  160 IF (h .EQ. hold) GO TO 200
5387  rh = h/hold
5388  h = hold
5389  iredo = 3
5390  GO TO 175
5391  170 rh = max(rh,hmin/abs(h))
5392  175 rh = min(rh,rmax)
5393  rh = rh/max(1.0d0,abs(h)*hmxi*rh)
5394  r = 1.0d0
5395  DO 180 j = 2,l
5396  r = r*rh
5397  DO 180 i = 1,n
5398  180 yh(i,j) = yh(i,j)*r
5399  h = h*rh
5400  rc = rc*rh
5401  ialth = l
5402  IF (iredo .EQ. 0) GO TO 690
5403 C-----------------------------------------------------------------------
5404 C This section computes the predicted values by effectively
5405 C multiplying the YH array by the Pascal triangle matrix.
5406 C The flag IPUP is set according to whether matrix data is involved
5407 C (JACFLG .ne. 0) or not (JACFLG = 0), to trigger a call to DPKSET.
5408 C IPUP is set to MITER when RC differs from 1 by more than CCMAX,
5409 C and at least every MSBP steps, when JACFLG = 1.
5410 C RC is the ratio of new to old values of the coefficient H*EL(1).
5411 C-----------------------------------------------------------------------
5412  200 IF (jacflg .NE. 0) GO TO 202
5413  ipup = 0
5414  crate = 0.7d0
5415  GO TO 205
5416  202 IF (abs(rc-1.0d0) .GT. ccmax) ipup = miter
5417  IF (nst .GE. nslp+msbp) ipup = miter
5418  205 tn = tn + h
5419  i1 = nqnyh + 1
5420  DO 215 jb = 1,nq
5421  i1 = i1 - nyh
5422 CDIR$ IVDEP
5423  DO 210 i = i1,nqnyh
5424  210 yh1(i) = yh1(i) + yh1(i+nyh)
5425  215 CONTINUE
5426 C-----------------------------------------------------------------------
5427 C Up to MAXCOR corrector iterations are taken. A convergence test is
5428 C made on the RMS-norm of each correction, weighted by the error
5429 C weight vector EWT. The sum of the corrections is accumulated in the
5430 C vector ACOR(i). The YH array is not altered in the corrector loop.
5431 C-----------------------------------------------------------------------
5432  220 m = 0
5433  mnewt = 0
5434  DO 230 i = 1,n
5435  230 y(i) = yh(i,1)
5436  CALL f (neq, tn, y, savf)
5437  nfe = nfe + 1
5438  IF (ipup .LE. 0) GO TO 250
5439 C-----------------------------------------------------------------------
5440 C If indicated, DPKSET is called to update any matrix data needed,
5441 C before starting the corrector iteration.
5442 C IPUP is set to 0 as an indicator that this has been done.
5443 C-----------------------------------------------------------------------
5444  CALL dpkset (neq, y, yh1, ewt, acor, savf, wm, iwm, f, jac)
5445  ipup = 0
5446  rc = 1.0d0
5447  nslp = nst
5448  crate = 0.7d0
5449  IF (ierpj .NE. 0) GO TO 430
5450  250 DO 260 i = 1,n
5451  260 acor(i) = 0.0d0
5452  270 IF (miter .NE. 0) GO TO 350
5453 C-----------------------------------------------------------------------
5454 C In the case of functional iteration, update Y directly from
5455 C the result of the last function evaluation.
5456 C-----------------------------------------------------------------------
5457  DO 290 i = 1,n
5458  savf(i) = h*savf(i) - yh(i,2)
5459  290 y(i) = savf(i) - acor(i)
5460  del = dvnorm(n, y, ewt)
5461  DO 300 i = 1,n
5462  y(i) = yh(i,1) + el(1)*savf(i)
5463  300 acor(i) = savf(i)
5464  GO TO 400
5465 C-----------------------------------------------------------------------
5466 C In the case of the chord method, compute the corrector error,
5467 C and solve the linear system with that as right-hand side and
5468 C P as coefficient matrix.
5469 C-----------------------------------------------------------------------
5470  350 DO 360 i = 1,n
5471  360 savx(i) = h*savf(i) - (yh(i,2) + acor(i))
5472  CALL dsolpk (neq, y, savf, savx, ewt, wm, iwm, f, psol)
5473  IF (iersl .LT. 0) GO TO 430
5474  IF (iersl .GT. 0) GO TO 410
5475  del = dvnorm(n, savx, ewt)
5476  DO 380 i = 1,n
5477  acor(i) = acor(i) + savx(i)
5478  380 y(i) = yh(i,1) + el(1)*acor(i)
5479 C-----------------------------------------------------------------------
5480 C Test for convergence. If M .gt. 0, an estimate of the convergence
5481 C rate constant is stored in CRATE, and this is used in the test.
5482 C-----------------------------------------------------------------------
5483  400 IF (m .NE. 0) crate = max(0.2d0*crate,del/delp)
5484  dcon = del*min(1.0d0,1.5d0*crate)/epcon
5485  IF (dcon .LE. 1.0d0) GO TO 450
5486  m = m + 1
5487  IF (m .EQ. maxcor) GO TO 410
5488  IF (m .GE. 2 .AND. del .GT. 2.0d0*delp) GO TO 410
5489  mnewt = m
5490  delp = del
5491  CALL f (neq, tn, y, savf)
5492  nfe = nfe + 1
5493  GO TO 270
5494 C-----------------------------------------------------------------------
5495 C The corrector iteration failed to converge.
5496 C If MITER .ne. 0 and the Jacobian is out of date, DPKSET is called for
5497 C the next try. Otherwise the YH array is retracted to its values
5498 C before prediction, and H is reduced, if possible. If H cannot be
5499 C reduced or MXNCF failures have occurred, exit with KFLAG = -2.
5500 C-----------------------------------------------------------------------
5501  410 IF (miter.EQ.0 .OR. jcur.EQ.1 .OR. jacflg.EQ.0) GO TO 430
5502  icf = 1
5503  ipup = miter
5504  GO TO 220
5505  430 icf = 2
5506  ncf = ncf + 1
5507  ncfn = ncfn + 1
5508  rmax = 2.0d0
5509  tn = told
5510  i1 = nqnyh + 1
5511  DO 445 jb = 1,nq
5512  i1 = i1 - nyh
5513 CDIR$ IVDEP
5514  DO 440 i = i1,nqnyh
5515  440 yh1(i) = yh1(i) - yh1(i+nyh)
5516  445 CONTINUE
5517  IF (ierpj .LT. 0 .OR. iersl .LT. 0) GO TO 680
5518  IF (abs(h) .LE. hmin*1.00001d0) GO TO 670
5519  IF (ncf .EQ. mxncf) GO TO 670
5520  rh = 0.5d0
5521  ipup = miter
5522  iredo = 1
5523  GO TO 170
5524 C-----------------------------------------------------------------------
5525 C The corrector has converged. JCUR is set to 0
5526 C to signal that the Jacobian involved may need updating later.
5527 C The local error test is made and control passes to statement 500
5528 C if it fails.
5529 C-----------------------------------------------------------------------
5530  450 jcur = 0
5531  IF (m .EQ. 0) dsm = del/tesco(2,nq)
5532  IF (m .GT. 0) dsm = dvnorm(n, acor, ewt)/tesco(2,nq)
5533  IF (dsm .GT. 1.0d0) GO TO 500
5534 C-----------------------------------------------------------------------
5535 C After a successful step, update the YH array.
5536 C Consider changing H if IALTH = 1. Otherwise decrease IALTH by 1.
5537 C If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
5538 C use in a possible order increase on the next step.
5539 C If a change in H is considered, an increase or decrease in order
5540 C by one is considered also. A change in H is made only if it is by a
5541 C factor of at least 1.1. If not, IALTH is set to 3 to prevent
5542 C testing for that many steps.
5543 C-----------------------------------------------------------------------
5544  kflag = 0
5545  iredo = 0
5546  nst = nst + 1
5547  hu = h
5548  nqu = nq
5549  DO 470 j = 1,l
5550  DO 470 i = 1,n
5551  470 yh(i,j) = yh(i,j) + el(j)*acor(i)
5552  ialth = ialth - 1
5553  IF (ialth .EQ. 0) GO TO 520
5554  IF (ialth .GT. 1) GO TO 700
5555  IF (l .EQ. lmax) GO TO 700
5556  DO 490 i = 1,n
5557  490 yh(i,lmax) = acor(i)
5558  GO TO 700
5559 C-----------------------------------------------------------------------
5560 C The error test failed. KFLAG keeps track of multiple failures.
5561 C Restore TN and the YH array to their previous values, and prepare
5562 C to try the step again. Compute the optimum step size for this or
5563 C one lower order. After 2 or more failures, H is forced to decrease
5564 C by a factor of 0.2 or less.
5565 C-----------------------------------------------------------------------
5566  500 kflag = kflag - 1
5567  tn = told
5568  i1 = nqnyh + 1
5569  DO 515 jb = 1,nq
5570  i1 = i1 - nyh
5571 CDIR$ IVDEP
5572  DO 510 i = i1,nqnyh
5573  510 yh1(i) = yh1(i) - yh1(i+nyh)
5574  515 CONTINUE
5575  rmax = 2.0d0
5576  IF (abs(h) .LE. hmin*1.00001d0) GO TO 660
5577  IF (kflag .LE. -3) GO TO 640
5578  iredo = 2
5579  rhup = 0.0d0
5580  GO TO 540
5581 C-----------------------------------------------------------------------
5582 C Regardless of the success or failure of the step, factors
5583 C RHDN, RHSM, and RHUP are computed, by which H could be multiplied
5584 C at order NQ - 1, order NQ, or order NQ + 1, respectively.
5585 C In the case of failure, RHUP = 0.0 to avoid an order increase.
5586 C the largest of these is determined and the new order chosen
5587 C accordingly. If the order is to be increased, we compute one
5588 C additional scaled derivative.
5589 C-----------------------------------------------------------------------
5590  520 rhup = 0.0d0
5591  IF (l .EQ. lmax) GO TO 540
5592  DO 530 i = 1,n
5593  530 savf(i) = acor(i) - yh(i,lmax)
5594  dup = dvnorm(n, savf, ewt)/tesco(3,nq)
5595  exup = 1.0d0/(l+1)
5596  rhup = 1.0d0/(1.4d0*dup**exup + 0.0000014d0)
5597  540 exsm = 1.0d0/l
5598  rhsm = 1.0d0/(1.2d0*dsm**exsm + 0.0000012d0)
5599  rhdn = 0.0d0
5600  IF (nq .EQ. 1) GO TO 560
5601  ddn = dvnorm(n, yh(1,l), ewt)/tesco(1,nq)
5602  exdn = 1.0d0/nq
5603  rhdn = 1.0d0/(1.3d0*ddn**exdn + 0.0000013d0)
5604  560 IF (rhsm .GE. rhup) GO TO 570
5605  IF (rhup .GT. rhdn) GO TO 590
5606  GO TO 580
5607  570 IF (rhsm .LT. rhdn) GO TO 580
5608  newq = nq
5609  rh = rhsm
5610  GO TO 620
5611  580 newq = nq - 1
5612  rh = rhdn
5613  IF (kflag .LT. 0 .AND. rh .GT. 1.0d0) rh = 1.0d0
5614  GO TO 620
5615  590 newq = l
5616  rh = rhup
5617  IF (rh .LT. 1.1d0) GO TO 610
5618  r = el(l)/l
5619  DO 600 i = 1,n
5620  600 yh(i,newq+1) = acor(i)*r
5621  GO TO 630
5622  610 ialth = 3
5623  GO TO 700
5624  620 IF ((kflag .EQ. 0) .AND. (rh .LT. 1.1d0)) GO TO 610
5625  IF (kflag .LE. -2) rh = min(rh,0.2d0)
5626 C-----------------------------------------------------------------------
5627 C If there is a change of order, reset NQ, L, and the coefficients.
5628 C In any case H is reset according to RH and the YH array is rescaled.
5629 C Then exit from 690 if the step was OK, or redo the step otherwise.
5630 C-----------------------------------------------------------------------
5631  IF (newq .EQ. nq) GO TO 170
5632  630 nq = newq
5633  l = nq + 1
5634  iret = 2
5635  GO TO 150
5636 C-----------------------------------------------------------------------
5637 C Control reaches this section if 3 or more failures have occured.
5638 C If 10 failures have occurred, exit with KFLAG = -1.
5639 C It is assumed that the derivatives that have accumulated in the
5640 C YH array have errors of the wrong order. Hence the first
5641 C derivative is recomputed, and the order is set to 1. Then
5642 C H is reduced by a factor of 10, and the step is retried,
5643 C until it succeeds or H reaches HMIN.
5644 C-----------------------------------------------------------------------
5645  640 IF (kflag .EQ. -10) GO TO 660
5646  rh = 0.1d0
5647  rh = max(hmin/abs(h),rh)
5648  h = h*rh
5649  DO 645 i = 1,n
5650  645 y(i) = yh(i,1)
5651  CALL f (neq, tn, y, savf)
5652  nfe = nfe + 1
5653  DO 650 i = 1,n
5654  650 yh(i,2) = h*savf(i)
5655  ipup = miter
5656  ialth = 5
5657  IF (nq .EQ. 1) GO TO 200
5658  nq = 1
5659  l = 2
5660  iret = 3
5661  GO TO 150
5662 C-----------------------------------------------------------------------
5663 C All returns are made through this section. H is saved in HOLD
5664 C to allow the caller to change H on the next step.
5665 C-----------------------------------------------------------------------
5666  660 kflag = -1
5667  GO TO 720
5668  670 kflag = -2
5669  GO TO 720
5670  680 kflag = -3
5671  GO TO 720
5672  690 rmax = 10.0d0
5673  700 r = 1.0d0/tesco(2,nqu)
5674  DO 710 i = 1,n
5675  710 acor(i) = acor(i)*r
5676  720 hold = h
5677  jstart = 1
5678  RETURN
5679 C----------------------- End of Subroutine DSTODPK ---------------------
5680  END
5681 *DECK DPKSET
5682  SUBROUTINE dpkset (NEQ, Y, YSV, EWT, FTEM, SAVF, WM, IWM, F, JAC)
5683  EXTERNAL f, jac
5684  INTEGER neq, iwm
5685  DOUBLE PRECISION y, ysv, ewt, ftem, savf, wm
5686  dimension neq(*), y(*), ysv(*), ewt(*), ftem(*), savf(*),
5687  1 wm(*), iwm(*)
5688  INTEGER iownd, iowns,
5689  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
5690  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
5691  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
5692  INTEGER jpre, jacflg, locwp, lociwp, lsavx, kmp, maxl, mnewt,
5693  1 nni, nli, nps, ncfn, ncfl
5694  DOUBLE PRECISION rowns,
5695  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
5696  DOUBLE PRECISION delt, epcon, sqrtn, rsqrtn
5697  COMMON /dls001/ rowns(209),
5698  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
5699  2 iownd(6), iowns(6),
5700  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
5701  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
5702  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
5703  COMMON /dlpk01/ delt, epcon, sqrtn, rsqrtn,
5704  1 jpre, jacflg, locwp, lociwp, lsavx, kmp, maxl, mnewt,
5705  2 nni, nli, nps, ncfn, ncfl
5706 C-----------------------------------------------------------------------
5707 C DPKSET is called by DSTODPK to interface with the user-supplied
5708 C routine JAC, to compute and process relevant parts of
5709 C the matrix P = I - H*EL(1)*J , where J is the Jacobian df/dy,
5710 C as need for preconditioning matrix operations later.
5711 C
5712 C In addition to variables described previously, communication
5713 C with DPKSET uses the following:
5714 C Y = array containing predicted values on entry.
5715 C YSV = array containing predicted y, to be saved (YH1 in DSTODPK).
5716 C FTEM = work array of length N (ACOR in DSTODPK).
5717 C SAVF = array containing f evaluated at predicted y.
5718 C WM = real work space for matrices.
5719 C Space for preconditioning data starts at WM(LOCWP).
5720 C IWM = integer work space.
5721 C Space for preconditioning data starts at IWM(LOCIWP).
5722 C IERPJ = output error flag, = 0 if no trouble, .gt. 0 if
5723 C JAC returned an error flag.
5724 C JCUR = output flag = 1 to indicate that the Jacobian matrix
5725 C (or approximation) is now current.
5726 C This routine also uses Common variables EL0, H, TN, IERPJ, JCUR, NJE.
5727 C-----------------------------------------------------------------------
5728  INTEGER ier
5729  DOUBLE PRECISION hl0
5730 C
5731  ierpj = 0
5732  jcur = 1
5733  hl0 = el0*h
5734  CALL jac (f, neq, tn, y, ysv, ewt, savf, ftem, hl0,
5735  1 wm(locwp), iwm(lociwp), ier)
5736  nje = nje + 1
5737  IF (ier .EQ. 0) RETURN
5738  ierpj = 1
5739  RETURN
5740 C----------------------- End of Subroutine DPKSET ----------------------
5741  END
5742 *DECK DSOLPK
5743  SUBROUTINE dsolpk (NEQ, Y, SAVF, X, EWT, WM, IWM, F, PSOL)
5744  EXTERNAL f, psol
5745  INTEGER neq, iwm
5746  DOUBLE PRECISION y, savf, x, ewt, wm
5747  dimension neq(*), y(*), savf(*), x(*), ewt(*), wm(*), iwm(*)
5748  INTEGER iownd, iowns,
5749  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
5750  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
5751  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
5752  INTEGER jpre, jacflg, locwp, lociwp, lsavx, kmp, maxl, mnewt,
5753  1 nni, nli, nps, ncfn, ncfl
5754  DOUBLE PRECISION rowns,
5755  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
5756  DOUBLE PRECISION delt, epcon, sqrtn, rsqrtn
5757  COMMON /dls001/ rowns(209),
5758  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
5759  2 iownd(6), iowns(6),
5760  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
5761  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
5762  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
5763  COMMON /dlpk01/ delt, epcon, sqrtn, rsqrtn,
5764  1 jpre, jacflg, locwp, lociwp, lsavx, kmp, maxl, mnewt,
5765  2 nni, nli, nps, ncfn, ncfl
5766 C-----------------------------------------------------------------------
5767 C This routine interfaces to one of DSPIOM, DSPIGMR, DPCG, DPCGS, or
5768 C DUSOL, for the solution of the linear system arising from a Newton
5769 C iteration. It is called if MITER .ne. 0.
5770 C In addition to variables described elsewhere,
5771 C communication with DSOLPK uses the following variables:
5772 C WM = real work space containing data for the algorithm
5773 C (Krylov basis vectors, Hessenberg matrix, etc.)
5774 C IWM = integer work space containing data for the algorithm
5775 C X = the right-hand side vector on input, and the solution vector
5776 C on output, of length N.
5777 C IERSL = output flag (in Common):
5778 C IERSL = 0 means no trouble occurred.
5779 C IERSL = 1 means the iterative method failed to converge.
5780 C If the preconditioner is out of date, the step
5781 C is repeated with a new preconditioner.
5782 C Otherwise, the stepsize is reduced (forcing a
5783 C new evaluation of the preconditioner) and the
5784 C step is repeated.
5785 C IERSL = -1 means there was a nonrecoverable error in the
5786 C iterative solver, and an error exit occurs.
5787 C This routine also uses the Common variables TN, EL0, H, N, MITER,
5788 C DELT, EPCON, SQRTN, RSQRTN, MAXL, KMP, MNEWT, NNI, NLI, NPS, NCFL,
5789 C LOCWP, LOCIWP.
5790 C-----------------------------------------------------------------------
5791  INTEGER iflag, lb, ldl, lhes, liom, lgmr, lpcg, lp, lq, lr,
5792  1 lv, lw, lwk, lz, maxlp1, npsl
5793  DOUBLE PRECISION delta, hl0
5794 C
5795  iersl = 0
5796  hl0 = h*el0
5797  delta = delt*epcon
5798  GO TO (100, 200, 300, 400, 900, 900, 900, 900, 900), miter
5799 C-----------------------------------------------------------------------
5800 C Use the SPIOM algorithm to solve the linear system P*x = -f.
5801 C-----------------------------------------------------------------------
5802  100 CONTINUE
5803  lv = 1
5804  lb = lv + n*maxl
5805  lhes = lb + n
5806  lwk = lhes + maxl*maxl
5807  CALL dcopy (n, x, 1, wm(lb), 1)
5808  CALL dscal (n, rsqrtn, ewt, 1)
5809  CALL dspiom (neq, tn, y, savf, wm(lb), ewt, n, maxl, kmp, delta,
5810  1 hl0, jpre, mnewt, f, psol, npsl, x, wm(lv), wm(lhes), iwm,
5811  2 liom, wm(locwp), iwm(lociwp), wm(lwk), iflag)
5812  nni = nni + 1
5813  nli = nli + liom
5814  nps = nps + npsl
5815  CALL dscal (n, sqrtn, ewt, 1)
5816  IF (iflag .NE. 0) ncfl = ncfl + 1
5817  IF (iflag .GE. 2) iersl = 1
5818  IF (iflag .LT. 0) iersl = -1
5819  RETURN
5820 C-----------------------------------------------------------------------
5821 C Use the SPIGMR algorithm to solve the linear system P*x = -f.
5822 C-----------------------------------------------------------------------
5823  200 CONTINUE
5824  maxlp1 = maxl + 1
5825  lv = 1
5826  lb = lv + n*maxl
5827  lhes = lb + n + 1
5828  lq = lhes + maxl*maxlp1
5829  lwk = lq + 2*maxl
5830  ldl = lwk + min(1,maxl-kmp)*n
5831  CALL dcopy (n, x, 1, wm(lb), 1)
5832  CALL dscal (n, rsqrtn, ewt, 1)
5833  CALL dspigmr (neq, tn, y, savf, wm(lb), ewt, n, maxl, maxlp1, kmp,
5834  1 delta, hl0, jpre, mnewt, f, psol, npsl, x, wm(lv), wm(lhes),
5835  2 wm(lq), lgmr, wm(locwp), iwm(lociwp), wm(lwk), wm(ldl), iflag)
5836  nni = nni + 1
5837  nli = nli + lgmr
5838  nps = nps + npsl
5839  CALL dscal (n, sqrtn, ewt, 1)
5840  IF (iflag .NE. 0) ncfl = ncfl + 1
5841  IF (iflag .GE. 2) iersl = 1
5842  IF (iflag .LT. 0) iersl = -1
5843  RETURN
5844 C-----------------------------------------------------------------------
5845 C Use DPCG to solve the linear system P*x = -f
5846 C-----------------------------------------------------------------------
5847  300 CONTINUE
5848  lr = 1
5849  lp = lr + n
5850  lw = lp + n
5851  lz = lw + n
5852  lwk = lz + n
5853  CALL dcopy (n, x, 1, wm(lr), 1)
5854  CALL dpcg (neq, tn, y, savf, wm(lr), ewt, n, maxl, delta, hl0,
5855  1 jpre, mnewt, f, psol, npsl, x, wm(lp), wm(lw), wm(lz),
5856  2 lpcg, wm(locwp), iwm(lociwp), wm(lwk), iflag)
5857  nni = nni + 1
5858  nli = nli + lpcg
5859  nps = nps + npsl
5860  IF (iflag .NE. 0) ncfl = ncfl + 1
5861  IF (iflag .GE. 2) iersl = 1
5862  IF (iflag .LT. 0) iersl = -1
5863  RETURN
5864 C-----------------------------------------------------------------------
5865 C Use DPCGS to solve the linear system P*x = -f
5866 C-----------------------------------------------------------------------
5867  400 CONTINUE
5868  lr = 1
5869  lp = lr + n
5870  lw = lp + n
5871  lz = lw + n
5872  lwk = lz + n
5873  CALL dcopy (n, x, 1, wm(lr), 1)
5874  CALL dpcgs (neq, tn, y, savf, wm(lr), ewt, n, maxl, delta, hl0,
5875  1 jpre, mnewt, f, psol, npsl, x, wm(lp), wm(lw), wm(lz),
5876  2 lpcg, wm(locwp), iwm(lociwp), wm(lwk), iflag)
5877  nni = nni + 1
5878  nli = nli + lpcg
5879  nps = nps + npsl
5880  IF (iflag .NE. 0) ncfl = ncfl + 1
5881  IF (iflag .GE. 2) iersl = 1
5882  IF (iflag .LT. 0) iersl = -1
5883  RETURN
5884 C-----------------------------------------------------------------------
5885 C Use DUSOL, which interfaces to PSOL, to solve the linear system
5886 C (no Krylov iteration).
5887 C-----------------------------------------------------------------------
5888  900 CONTINUE
5889  lb = 1
5890  lwk = lb + n
5891  CALL dcopy (n, x, 1, wm(lb), 1)
5892  CALL dusol (neq, tn, y, savf, wm(lb), ewt, n, delta, hl0, mnewt,
5893  1 psol, npsl, x, wm(locwp), iwm(lociwp), wm(lwk), iflag)
5894  nni = nni + 1
5895  nps = nps + npsl
5896  IF (iflag .NE. 0) ncfl = ncfl + 1
5897  IF (iflag .EQ. 3) iersl = 1
5898  IF (iflag .LT. 0) iersl = -1
5899  RETURN
5900 C----------------------- End of Subroutine DSOLPK ----------------------
5901  END
5902 *DECK DSPIOM
5903  SUBROUTINE dspiom (NEQ, TN, Y, SAVF, B, WGHT, N, MAXL, KMP, DELTA,
5904  1 HL0, JPRE, MNEWT, F, PSOL, NPSL, X, V, HES, IPVT,
5905  2 LIOM, WP, IWP, WK, IFLAG)
5906  EXTERNAL f, psol
5907  INTEGER neq,n,maxl,kmp,jpre,mnewt,npsl,ipvt,liom,iwp,iflag
5908  DOUBLE PRECISION tn,y,savf,b,wght,delta,hl0,x,v,hes,wp,wk
5909  dimension neq(*), y(*), savf(*), b(*), wght(*), x(*), v(n,*),
5910  1 hes(maxl,maxl), ipvt(*), wp(*), iwp(*), wk(*)
5911 C-----------------------------------------------------------------------
5912 C This routine solves the linear system A * x = b using a scaled
5913 C preconditioned version of the Incomplete Orthogonalization Method.
5914 C An initial guess of x = 0 is assumed.
5915 C-----------------------------------------------------------------------
5916 C
5917 C On entry
5918 C
5919 C NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
5920 C
5921 C TN = current value of t.
5922 C
5923 C Y = array containing current dependent variable vector.
5924 C
5925 C SAVF = array containing current value of f(t,y).
5926 C
5927 C B = the right hand side of the system A*x = b.
5928 C B is also used as work space when computing the
5929 C final approximation.
5930 C (B is the same as V(*,MAXL+1) in the call to DSPIOM.)
5931 C
5932 C WGHT = array of length N containing scale factors.
5933 C 1/WGHT(i) are the diagonal elements of the diagonal
5934 C scaling matrix D.
5935 C
5936 C N = the order of the matrix A, and the lengths
5937 C of the vectors Y, SAVF, B, WGHT, and X.
5938 C
5939 C MAXL = the maximum allowable order of the matrix HES.
5940 C
5941 C KMP = the number of previous vectors the new vector VNEW
5942 C must be made orthogonal to. KMP .le. MAXL.
5943 C
5944 C DELTA = tolerance on residuals b - A*x in weighted RMS-norm.
5945 C
5946 C HL0 = current value of (step size h) * (coefficient l0).
5947 C
5948 C JPRE = preconditioner type flag.
5949 C
5950 C MNEWT = Newton iteration counter (.ge. 0).
5951 C
5952 C WK = real work array of length N used by DATV and PSOL.
5953 C
5954 C WP = real work array used by preconditioner PSOL.
5955 C
5956 C IWP = integer work array used by preconditioner PSOL.
5957 C
5958 C On return
5959 C
5960 C X = the final computed approximation to the solution
5961 C of the system A*x = b.
5962 C
5963 C V = the N by (LIOM+1) array containing the LIOM
5964 C orthogonal vectors V(*,1) to V(*,LIOM).
5965 C
5966 C HES = the LU factorization of the LIOM by LIOM upper
5967 C Hessenberg matrix whose entries are the
5968 C scaled inner products of A*V(*,k) and V(*,i).
5969 C
5970 C IPVT = an integer array containg pivoting information.
5971 C It is loaded in DHEFA and used in DHESL.
5972 C
5973 C LIOM = the number of iterations performed, and current
5974 C order of the upper Hessenberg matrix HES.
5975 C
5976 C NPSL = the number of calls to PSOL.
5977 C
5978 C IFLAG = integer error flag:
5979 C 0 means convergence in LIOM iterations, LIOM.le.MAXL.
5980 C 1 means the convergence test did not pass in MAXL
5981 C iterations, but the residual norm is .lt. 1,
5982 C or .lt. norm(b) if MNEWT = 0, and so X is computed.
5983 C 2 means the convergence test did not pass in MAXL
5984 C iterations, residual .gt. 1, and X is undefined.
5985 C 3 means there was a recoverable error in PSOL
5986 C caused by the preconditioner being out of date.
5987 C -1 means there was a nonrecoverable error in PSOL.
5988 C
5989 C-----------------------------------------------------------------------
5990  INTEGER i, ier, info, j, k, ll, lm1
5991  DOUBLE PRECISION bnrm, bnrm0, prod, rho, snormw, dnrm2, tem
5992 C
5993  iflag = 0
5994  liom = 0
5995  npsl = 0
5996 C-----------------------------------------------------------------------
5997 C The initial residual is the vector b. Apply scaling to b, and test
5998 C for an immediate return with X = 0 or X = b.
5999 C-----------------------------------------------------------------------
6000  DO 10 i = 1,n
6001  10 v(i,1) = b(i)*wght(i)
6002  bnrm0 = dnrm2(n, v, 1)
6003  bnrm = bnrm0
6004  IF (bnrm0 .GT. delta) GO TO 30
6005  IF (mnewt .GT. 0) GO TO 20
6006  CALL dcopy (n, b, 1, x, 1)
6007  RETURN
6008  20 DO 25 i = 1,n
6009  25 x(i) = 0.0d0
6010  RETURN
6011  30 CONTINUE
6012 C Apply inverse of left preconditioner to vector b. --------------------
6013  ier = 0
6014  IF (jpre .EQ. 0 .OR. jpre .EQ. 2) GO TO 55
6015  CALL psol (neq, tn, y, savf, wk, hl0, wp, iwp, b, 1, ier)
6016  npsl = 1
6017  IF (ier .NE. 0) GO TO 300
6018 C Calculate norm of scaled vector V(*,1) and normalize it. -------------
6019  DO 50 i = 1,n
6020  50 v(i,1) = b(i)*wght(i)
6021  bnrm = dnrm2(n, v, 1)
6022  delta = delta*(bnrm/bnrm0)
6023  55 tem = 1.0d0/bnrm
6024  CALL dscal (n, tem, v(1,1), 1)
6025 C Zero out the HES array. ----------------------------------------------
6026  DO 65 j = 1,maxl
6027  DO 60 i = 1,maxl
6028  60 hes(i,j) = 0.0d0
6029  65 CONTINUE
6030 C-----------------------------------------------------------------------
6031 C Main loop on LL = l to compute the vectors V(*,2) to V(*,MAXL).
6032 C The running product PROD is needed for the convergence test.
6033 C-----------------------------------------------------------------------
6034  prod = 1.0d0
6035  DO 90 ll = 1,maxl
6036  liom = ll
6037 C-----------------------------------------------------------------------
6038 C Call routine DATV to compute VNEW = Abar*v(l), where Abar is
6039 C the matrix A with scaling and inverse preconditioner factors applied.
6040 C Call routine DORTHOG to orthogonalize the new vector vnew = V(*,l+1).
6041 C Call routine DHEFA to update the factors of HES.
6042 C-----------------------------------------------------------------------
6043  CALL datv (neq, y, savf, v(1,ll), wght, x, f, psol, v(1,ll+1),
6044  1 wk, wp, iwp, hl0, jpre, ier, npsl)
6045  IF (ier .NE. 0) GO TO 300
6046  CALL dorthog (v(1,ll+1), v, hes, n, ll, maxl, kmp, snormw)
6047  CALL dhefa (hes, maxl, ll, ipvt, info, ll)
6048  lm1 = ll - 1
6049  IF (ll .GT. 1 .AND. ipvt(lm1) .EQ. lm1) prod = prod*hes(ll,lm1)
6050  IF (info .NE. ll) GO TO 70
6051 C-----------------------------------------------------------------------
6052 C The last pivot in HES was found to be zero.
6053 C If vnew = 0 or l = MAXL, take an error return with IFLAG = 2.
6054 C otherwise, continue the iteration without a convergence test.
6055 C-----------------------------------------------------------------------
6056  IF (snormw .EQ. 0.0d0) GO TO 120
6057  IF (ll .EQ. maxl) GO TO 120
6058  GO TO 80
6059 C-----------------------------------------------------------------------
6060 C Update RHO, the estimate of the norm of the residual b - A*x(l).
6061 C test for convergence. If passed, compute approximation x(l).
6062 C If failed and l .lt. MAXL, then continue iterating.
6063 C-----------------------------------------------------------------------
6064  70 CONTINUE
6065  rho = bnrm*snormw*abs(prod/hes(ll,ll))
6066  IF (rho .LE. delta) GO TO 200
6067  IF (ll .EQ. maxl) GO TO 100
6068 C If l .lt. MAXL, store HES(l+1,l) and normalize the vector v(*,l+1).
6069  80 CONTINUE
6070  hes(ll+1,ll) = snormw
6071  tem = 1.0d0/snormw
6072  CALL dscal (n, tem, v(1,ll+1), 1)
6073  90 CONTINUE
6074 C-----------------------------------------------------------------------
6075 C l has reached MAXL without passing the convergence test:
6076 C If RHO is not too large, compute a solution anyway and return with
6077 C IFLAG = 1. Otherwise return with IFLAG = 2.
6078 C-----------------------------------------------------------------------
6079  100 CONTINUE
6080  IF (rho .LE. 1.0d0) GO TO 150
6081  IF (rho .LE. bnrm .AND. mnewt .EQ. 0) GO TO 150
6082  120 CONTINUE
6083  iflag = 2
6084  RETURN
6085  150 iflag = 1
6086 C-----------------------------------------------------------------------
6087 C Compute the approximation x(l) to the solution.
6088 C Since the vector X was used as work space, and the initial guess
6089 C of the Newton correction is zero, X must be reset to zero.
6090 C-----------------------------------------------------------------------
6091  200 CONTINUE
6092  ll = liom
6093  DO 210 k = 1,ll
6094  210 b(k) = 0.0d0
6095  b(1) = bnrm
6096  CALL dhesl (hes, maxl, ll, ipvt, b)
6097  DO 220 k = 1,n
6098  220 x(k) = 0.0d0
6099  DO 230 i = 1,ll
6100  CALL daxpy (n, b(i), v(1,i), 1, x, 1)
6101  230 CONTINUE
6102  DO 240 i = 1,n
6103  240 x(i) = x(i)/wght(i)
6104  IF (jpre .LE. 1) RETURN
6105  CALL psol (neq, tn, y, savf, wk, hl0, wp, iwp, x, 2, ier)
6106  npsl = npsl + 1
6107  IF (ier .NE. 0) GO TO 300
6108  RETURN
6109 C-----------------------------------------------------------------------
6110 C This block handles error returns forced by routine PSOL.
6111 C-----------------------------------------------------------------------
6112  300 CONTINUE
6113  IF (ier .LT. 0) iflag = -1
6114  IF (ier .GT. 0) iflag = 3
6115  RETURN
6116 C----------------------- End of Subroutine DSPIOM ----------------------
6117  END
6118 *DECK DATV
6119  SUBROUTINE datv (NEQ, Y, SAVF, V, WGHT, FTEM, F, PSOL, Z, VTEM,
6120  1 WP, IWP, HL0, JPRE, IER, NPSL)
6121  EXTERNAL f, psol
6122  INTEGER neq, iwp, jpre, ier, npsl
6123  DOUBLE PRECISION y, savf, v, wght, ftem, z, vtem, wp, hl0
6124  dimension neq(*), y(*), savf(*), v(*), wght(*), ftem(*), z(*),
6125  1 vtem(*), wp(*), iwp(*)
6126  INTEGER iownd, iowns,
6127  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
6128  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
6129  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
6130  DOUBLE PRECISION rowns,
6131  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
6132  COMMON /dls001/ rowns(209),
6133  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
6134  2 iownd(6), iowns(6),
6135  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
6136  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
6137  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
6138 C-----------------------------------------------------------------------
6139 C This routine computes the product
6140 C
6141 C (D-inverse)*(P1-inverse)*(I - hl0*df/dy)*(P2-inverse)*(D*v),
6142 C
6143 C where D is a diagonal scaling matrix, and P1 and P2 are the
6144 C left and right preconditioning matrices, respectively.
6145 C v is assumed to have WRMS norm equal to 1.
6146 C The product is stored in z. This is computed by a
6147 C difference quotient, a call to F, and two calls to PSOL.
6148 C-----------------------------------------------------------------------
6149 C
6150 C On entry
6151 C
6152 C NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6153 C
6154 C Y = array containing current dependent variable vector.
6155 C
6156 C SAVF = array containing current value of f(t,y).
6157 C
6158 C V = real array of length N (can be the same array as Z).
6159 C
6160 C WGHT = array of length N containing scale factors.
6161 C 1/WGHT(i) are the diagonal elements of the matrix D.
6162 C
6163 C FTEM = work array of length N.
6164 C
6165 C VTEM = work array of length N used to store the
6166 C unscaled version of V.
6167 C
6168 C WP = real work array used by preconditioner PSOL.
6169 C
6170 C IWP = integer work array used by preconditioner PSOL.
6171 C
6172 C HL0 = current value of (step size h) * (coefficient l0).
6173 C
6174 C JPRE = preconditioner type flag.
6175 C
6176 C
6177 C On return
6178 C
6179 C Z = array of length N containing desired scaled
6180 C matrix-vector product.
6181 C
6182 C IER = error flag from PSOL.
6183 C
6184 C NPSL = the number of calls to PSOL.
6185 C
6186 C In addition, this routine uses the Common variables TN, N, NFE.
6187 C-----------------------------------------------------------------------
6188  INTEGER i
6189  DOUBLE PRECISION fac, rnorm, dnrm2, tempn
6190 C
6191 C Set VTEM = D * V.
6192  DO 10 i = 1,n
6193  10 vtem(i) = v(i)/wght(i)
6194  ier = 0
6195  IF (jpre .GE. 2) GO TO 30
6196 C
6197 C JPRE = 0 or 1. Save Y in Z and increment Y by VTEM.
6198  CALL dcopy (n, y, 1, z, 1)
6199  DO 20 i = 1,n
6200  20 y(i) = z(i) + vtem(i)
6201  fac = hl0
6202  GO TO 60
6203 C
6204 C JPRE = 2 or 3. Apply inverse of right preconditioner to VTEM.
6205  30 CONTINUE
6206  CALL psol (neq, tn, y, savf, ftem, hl0, wp, iwp, vtem, 2, ier)
6207  npsl = npsl + 1
6208  IF (ier .NE. 0) RETURN
6209 C Calculate L-2 norm of (D-inverse) * VTEM.
6210  DO 40 i = 1,n
6211  40 z(i) = vtem(i)*wght(i)
6212  tempn = dnrm2(n, z, 1)
6213  rnorm = 1.0d0/tempn
6214 C Save Y in Z and increment Y by VTEM/norm.
6215  CALL dcopy (n, y, 1, z, 1)
6216  DO 50 i = 1,n
6217  50 y(i) = z(i) + vtem(i)*rnorm
6218  fac = hl0*tempn
6219 C
6220 C For all JPRE, call F with incremented Y argument, and restore Y.
6221  60 CONTINUE
6222  CALL f (neq, tn, y, ftem)
6223  nfe = nfe + 1
6224  CALL dcopy (n, z, 1, y, 1)
6225 C Set Z = (identity - hl0*Jacobian) * VTEM, using difference quotient.
6226  DO 70 i = 1,n
6227  70 z(i) = ftem(i) - savf(i)
6228  DO 80 i = 1,n
6229  80 z(i) = vtem(i) - fac*z(i)
6230 C Apply inverse of left preconditioner to Z, if nontrivial.
6231  IF (jpre .EQ. 0 .OR. jpre .EQ. 2) GO TO 85
6232  CALL psol (neq, tn, y, savf, ftem, hl0, wp, iwp, z, 1, ier)
6233  npsl = npsl + 1
6234  IF (ier .NE. 0) RETURN
6235  85 CONTINUE
6236 C Apply D-inverse to Z and return.
6237  DO 90 i = 1,n
6238  90 z(i) = z(i)*wght(i)
6239  RETURN
6240 C----------------------- End of Subroutine DATV ------------------------
6241  END
6242 *DECK DORTHOG
6243  SUBROUTINE dorthog (VNEW, V, HES, N, LL, LDHES, KMP, SNORMW)
6244  INTEGER n, ll, ldhes, kmp
6245  DOUBLE PRECISION vnew, v, hes, snormw
6246  dimension vnew(*), v(n,*), hes(ldhes,*)
6247 C-----------------------------------------------------------------------
6248 C This routine orthogonalizes the vector VNEW against the previous
6249 C KMP vectors in the V array. It uses a modified Gram-Schmidt
6250 C orthogonalization procedure with conditional reorthogonalization.
6251 C This is the version of 28 may 1986.
6252 C-----------------------------------------------------------------------
6253 C
6254 C On entry
6255 C
6256 C VNEW = the vector of length N containing a scaled product
6257 C of the Jacobian and the vector V(*,LL).
6258 C
6259 C V = the N x l array containing the previous LL
6260 C orthogonal vectors v(*,1) to v(*,LL).
6261 C
6262 C HES = an LL x LL upper Hessenberg matrix containing,
6263 C in HES(i,k), k.lt.LL, scaled inner products of
6264 C A*V(*,k) and V(*,i).
6265 C
6266 C LDHES = the leading dimension of the HES array.
6267 C
6268 C N = the order of the matrix A, and the length of VNEW.
6269 C
6270 C LL = the current order of the matrix HES.
6271 C
6272 C KMP = the number of previous vectors the new vector VNEW
6273 C must be made orthogonal to (KMP .le. MAXL).
6274 C
6275 C
6276 C On return
6277 C
6278 C VNEW = the new vector orthogonal to V(*,i0) to V(*,LL),
6279 C where i0 = MAX(1, LL-KMP+1).
6280 C
6281 C HES = upper Hessenberg matrix with column LL filled in with
6282 C scaled inner products of A*V(*,LL) and V(*,i).
6283 C
6284 C SNORMW = L-2 norm of VNEW.
6285 C
6286 C-----------------------------------------------------------------------
6287  INTEGER i, i0
6288  DOUBLE PRECISION arg, ddot, dnrm2, sumdsq, tem, vnrm
6289 C
6290 C Get norm of unaltered VNEW for later use. ----------------------------
6291  vnrm = dnrm2(n, vnew, 1)
6292 C-----------------------------------------------------------------------
6293 C Do modified Gram-Schmidt on VNEW = A*v(LL).
6294 C Scaled inner products give new column of HES.
6295 C Projections of earlier vectors are subtracted from VNEW.
6296 C-----------------------------------------------------------------------
6297  i0 = max(1,ll-kmp+1)
6298  DO 10 i = i0,ll
6299  hes(i,ll) = ddot(n, v(1,i), 1, vnew, 1)
6300  tem = -hes(i,ll)
6301  CALL daxpy (n, tem, v(1,i), 1, vnew, 1)
6302  10 CONTINUE
6303 C-----------------------------------------------------------------------
6304 C Compute SNORMW = norm of VNEW.
6305 C If VNEW is small compared to its input value (in norm), then
6306 C reorthogonalize VNEW to V(*,1) through V(*,LL).
6307 C Correct if relative correction exceeds 1000*(unit roundoff).
6308 C finally, correct SNORMW using the dot products involved.
6309 C-----------------------------------------------------------------------
6310  snormw = dnrm2(n, vnew, 1)
6311  IF (vnrm + 0.001d0*snormw .NE. vnrm) RETURN
6312  sumdsq = 0.0d0
6313  DO 30 i = i0,ll
6314  tem = -ddot(n, v(1,i), 1, vnew, 1)
6315  IF (hes(i,ll) + 0.001d0*tem .EQ. hes(i,ll)) GO TO 30
6316  hes(i,ll) = hes(i,ll) - tem
6317  CALL daxpy (n, tem, v(1,i), 1, vnew, 1)
6318  sumdsq = sumdsq + tem**2
6319  30 CONTINUE
6320  IF (sumdsq .EQ. 0.0d0) RETURN
6321  arg = max(0.0d0,snormw**2 - sumdsq)
6322  snormw = sqrt(arg)
6323 C
6324  RETURN
6325 C----------------------- End of Subroutine DORTHOG ---------------------
6326  END
6327 *DECK DSPIGMR
6328  SUBROUTINE dspigmr (NEQ, TN, Y, SAVF, B, WGHT, N, MAXL, MAXLP1,
6329  1 KMP, DELTA, HL0, JPRE, MNEWT, F, PSOL, NPSL, X, V, HES, Q,
6330  2 LGMR, WP, IWP, WK, DL, IFLAG)
6331  EXTERNAL f, psol
6332  INTEGER neq,n,maxl,maxlp1,kmp,jpre,mnewt,npsl,lgmr,iwp,iflag
6333  DOUBLE PRECISION tn,y,savf,b,wght,delta,hl0,x,v,hes,q,wp,wk,dl
6334  dimension neq(*), y(*), savf(*), b(*), wght(*), x(*), v(n,*),
6335  1 hes(maxlp1,*), q(*), wp(*), iwp(*), wk(*), dl(*)
6336 C-----------------------------------------------------------------------
6337 C This routine solves the linear system A * x = b using a scaled
6338 C preconditioned version of the Generalized Minimal Residual method.
6339 C An initial guess of x = 0 is assumed.
6340 C-----------------------------------------------------------------------
6341 C
6342 C On entry
6343 C
6344 C NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6345 C
6346 C TN = current value of t.
6347 C
6348 C Y = array containing current dependent variable vector.
6349 C
6350 C SAVF = array containing current value of f(t,y).
6351 C
6352 C B = the right hand side of the system A*x = b.
6353 C B is also used as work space when computing
6354 C the final approximation.
6355 C (B is the same as V(*,MAXL+1) in the call to DSPIGMR.)
6356 C
6357 C WGHT = the vector of length N containing the nonzero
6358 C elements of the diagonal scaling matrix.
6359 C
6360 C N = the order of the matrix A, and the lengths
6361 C of the vectors WGHT, B and X.
6362 C
6363 C MAXL = the maximum allowable order of the matrix HES.
6364 C
6365 C MAXLP1 = MAXL + 1, used for dynamic dimensioning of HES.
6366 C
6367 C KMP = the number of previous vectors the new vector VNEW
6368 C must be made orthogonal to. KMP .le. MAXL.
6369 C
6370 C DELTA = tolerance on residuals b - A*x in weighted RMS-norm.
6371 C
6372 C HL0 = current value of (step size h) * (coefficient l0).
6373 C
6374 C JPRE = preconditioner type flag.
6375 C
6376 C MNEWT = Newton iteration counter (.ge. 0).
6377 C
6378 C WK = real work array used by routine DATV and PSOL.
6379 C
6380 C DL = real work array used for calculation of the residual
6381 C norm RHO when the method is incomplete (KMP .lt. MAXL).
6382 C Not needed or referenced in complete case (KMP = MAXL).
6383 C
6384 C WP = real work array used by preconditioner PSOL.
6385 C
6386 C IWP = integer work array used by preconditioner PSOL.
6387 C
6388 C On return
6389 C
6390 C X = the final computed approximation to the solution
6391 C of the system A*x = b.
6392 C
6393 C LGMR = the number of iterations performed and
6394 C the current order of the upper Hessenberg
6395 C matrix HES.
6396 C
6397 C NPSL = the number of calls to PSOL.
6398 C
6399 C V = the N by (LGMR+1) array containing the LGMR
6400 C orthogonal vectors V(*,1) to V(*,LGMR).
6401 C
6402 C HES = the upper triangular factor of the QR decomposition
6403 C of the (LGMR+1) by lgmr upper Hessenberg matrix whose
6404 C entries are the scaled inner-products of A*V(*,i)
6405 C and V(*,k).
6406 C
6407 C Q = real array of length 2*MAXL containing the components
6408 C of the Givens rotations used in the QR decomposition
6409 C of HES. It is loaded in DHEQR and used in DHELS.
6410 C
6411 C IFLAG = integer error flag:
6412 C 0 means convergence in LGMR iterations, LGMR .le. MAXL.
6413 C 1 means the convergence test did not pass in MAXL
6414 C iterations, but the residual norm is .lt. 1,
6415 C or .lt. norm(b) if MNEWT = 0, and so x is computed.
6416 C 2 means the convergence test did not pass in MAXL
6417 C iterations, residual .gt. 1, and X is undefined.
6418 C 3 means there was a recoverable error in PSOL
6419 C caused by the preconditioner being out of date.
6420 C -1 means there was a nonrecoverable error in PSOL.
6421 C
6422 C-----------------------------------------------------------------------
6423  INTEGER i, ier, info, ip1, i2, j, k, ll, llp1
6424  DOUBLE PRECISION bnrm,bnrm0,c,dlnrm,prod,rho,s,snormw,dnrm2,tem
6425 C
6426  iflag = 0
6427  lgmr = 0
6428  npsl = 0
6429 C-----------------------------------------------------------------------
6430 C The initial residual is the vector b. Apply scaling to b, and test
6431 C for an immediate return with X = 0 or X = b.
6432 C-----------------------------------------------------------------------
6433  DO 10 i = 1,n
6434  10 v(i,1) = b(i)*wght(i)
6435  bnrm0 = dnrm2(n, v, 1)
6436  bnrm = bnrm0
6437  IF (bnrm0 .GT. delta) GO TO 30
6438  IF (mnewt .GT. 0) GO TO 20
6439  CALL dcopy (n, b, 1, x, 1)
6440  RETURN
6441  20 DO 25 i = 1,n
6442  25 x(i) = 0.0d0
6443  RETURN
6444  30 CONTINUE
6445 C Apply inverse of left preconditioner to vector b. --------------------
6446  ier = 0
6447  IF (jpre .EQ. 0 .OR. jpre .EQ. 2) GO TO 55
6448  CALL psol (neq, tn, y, savf, wk, hl0, wp, iwp, b, 1, ier)
6449  npsl = 1
6450  IF (ier .NE. 0) GO TO 300
6451 C Calculate norm of scaled vector V(*,1) and normalize it. -------------
6452  DO 50 i = 1,n
6453  50 v(i,1) = b(i)*wght(i)
6454  bnrm = dnrm2(n, v, 1)
6455  delta = delta*(bnrm/bnrm0)
6456  55 tem = 1.0d0/bnrm
6457  CALL dscal (n, tem, v(1,1), 1)
6458 C Zero out the HES array. ----------------------------------------------
6459  DO 65 j = 1,maxl
6460  DO 60 i = 1,maxlp1
6461  60 hes(i,j) = 0.0d0
6462  65 CONTINUE
6463 C-----------------------------------------------------------------------
6464 C Main loop to compute the vectors V(*,2) to V(*,MAXL).
6465 C The running product PROD is needed for the convergence test.
6466 C-----------------------------------------------------------------------
6467  prod = 1.0d0
6468  DO 90 ll = 1,maxl
6469  lgmr = ll
6470 C-----------------------------------------------------------------------
6471 C Call routine DATV to compute VNEW = Abar*v(ll), where Abar is
6472 C the matrix A with scaling and inverse preconditioner factors applied.
6473 C Call routine DORTHOG to orthogonalize the new vector VNEW = V(*,LL+1).
6474 C Call routine DHEQR to update the factors of HES.
6475 C-----------------------------------------------------------------------
6476  CALL datv (neq, y, savf, v(1,ll), wght, x, f, psol, v(1,ll+1),
6477  1 wk, wp, iwp, hl0, jpre, ier, npsl)
6478  IF (ier .NE. 0) GO TO 300
6479  CALL dorthog (v(1,ll+1), v, hes, n, ll, maxlp1, kmp, snormw)
6480  hes(ll+1,ll) = snormw
6481  CALL dheqr (hes, maxlp1, ll, q, info, ll)
6482  IF (info .EQ. ll) GO TO 120
6483 C-----------------------------------------------------------------------
6484 C Update RHO, the estimate of the norm of the residual b - A*xl.
6485 C If KMP .lt. MAXL, then the vectors V(*,1),...,V(*,LL+1) are not
6486 C necessarily orthogonal for LL .gt. KMP. The vector DL must then
6487 C be computed, and its norm used in the calculation of RHO.
6488 C-----------------------------------------------------------------------
6489  prod = prod*q(2*ll)
6490  rho = abs(prod*bnrm)
6491  IF ((ll.GT.kmp) .AND. (kmp.LT.maxl)) THEN
6492  IF (ll .EQ. kmp+1) THEN
6493  CALL dcopy (n, v(1,1), 1, dl, 1)
6494  DO 75 i = 1,kmp
6495  ip1 = i + 1
6496  i2 = i*2
6497  s = q(i2)
6498  c = q(i2-1)
6499  DO 70 k = 1,n
6500  70 dl(k) = s*dl(k) + c*v(k,ip1)
6501  75 CONTINUE
6502  ENDIF
6503  s = q(2*ll)
6504  c = q(2*ll-1)/snormw
6505  llp1 = ll + 1
6506  DO 80 k = 1,n
6507  80 dl(k) = s*dl(k) + c*v(k,llp1)
6508  dlnrm = dnrm2(n, dl, 1)
6509  rho = rho*dlnrm
6510  ENDIF
6511 C-----------------------------------------------------------------------
6512 C Test for convergence. If passed, compute approximation xl.
6513 C if failed and LL .lt. MAXL, then continue iterating.
6514 C-----------------------------------------------------------------------
6515  IF (rho .LE. delta) GO TO 200
6516  IF (ll .EQ. maxl) GO TO 100
6517 C-----------------------------------------------------------------------
6518 C Rescale so that the norm of V(1,LL+1) is one.
6519 C-----------------------------------------------------------------------
6520  tem = 1.0d0/snormw
6521  CALL dscal (n, tem, v(1,ll+1), 1)
6522  90 CONTINUE
6523  100 CONTINUE
6524  IF (rho .LE. 1.0d0) GO TO 150
6525  IF (rho .LE. bnrm .AND. mnewt .EQ. 0) GO TO 150
6526  120 CONTINUE
6527  iflag = 2
6528  RETURN
6529  150 iflag = 1
6530 C-----------------------------------------------------------------------
6531 C Compute the approximation xl to the solution.
6532 C Since the vector X was used as work space, and the initial guess
6533 C of the Newton correction is zero, X must be reset to zero.
6534 C-----------------------------------------------------------------------
6535  200 CONTINUE
6536  ll = lgmr
6537  llp1 = ll + 1
6538  DO 210 k = 1,llp1
6539  210 b(k) = 0.0d0
6540  b(1) = bnrm
6541  CALL dhels (hes, maxlp1, ll, q, b)
6542  DO 220 k = 1,n
6543  220 x(k) = 0.0d0
6544  DO 230 i = 1,ll
6545  CALL daxpy (n, b(i), v(1,i), 1, x, 1)
6546  230 CONTINUE
6547  DO 240 i = 1,n
6548  240 x(i) = x(i)/wght(i)
6549  IF (jpre .LE. 1) RETURN
6550  CALL psol (neq, tn, y, savf, wk, hl0, wp, iwp, x, 2, ier)
6551  npsl = npsl + 1
6552  IF (ier .NE. 0) GO TO 300
6553  RETURN
6554 C-----------------------------------------------------------------------
6555 C This block handles error returns forced by routine PSOL.
6556 C-----------------------------------------------------------------------
6557  300 CONTINUE
6558  IF (ier .LT. 0) iflag = -1
6559  IF (ier .GT. 0) iflag = 3
6560 C
6561  RETURN
6562 C----------------------- End of Subroutine DSPIGMR ---------------------
6563  END
6564 *DECK DPCG
6565  SUBROUTINE dpcg (NEQ, TN, Y, SAVF, R, WGHT, N, MAXL, DELTA, HL0,
6566  1 JPRE, MNEWT, F, PSOL, NPSL, X, P, W, Z, LPCG, WP, IWP, WK, IFLAG)
6567  EXTERNAL f, psol
6568  INTEGER neq, n, maxl, jpre, mnewt, npsl, lpcg, iwp, iflag
6569  DOUBLE PRECISION tn,y,savf,r,wght,delta,hl0,x,p,w,z,wp,wk
6570  dimension neq(*), y(*), savf(*), r(*), wght(*), x(*), p(*), w(*),
6571  1 z(*), wp(*), iwp(*), wk(*)
6572 C-----------------------------------------------------------------------
6573 C This routine computes the solution to the system A*x = b using a
6574 C preconditioned version of the Conjugate Gradient algorithm.
6575 C It is assumed here that the matrix A and the preconditioner
6576 C matrix M are symmetric positive definite or nearly so.
6577 C-----------------------------------------------------------------------
6578 C
6579 C On entry
6580 C
6581 C NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6582 C
6583 C TN = current value of t.
6584 C
6585 C Y = array containing current dependent variable vector.
6586 C
6587 C SAVF = array containing current value of f(t,y).
6588 C
6589 C R = the right hand side of the system A*x = b.
6590 C
6591 C WGHT = array of length N containing scale factors.
6592 C 1/WGHT(i) are the diagonal elements of the diagonal
6593 C scaling matrix D.
6594 C
6595 C N = the order of the matrix A, and the lengths
6596 C of the vectors Y, SAVF, R, WGHT, P, W, Z, WK, and X.
6597 C
6598 C MAXL = the maximum allowable number of iterates.
6599 C
6600 C DELTA = tolerance on residuals b - A*x in weighted RMS-norm.
6601 C
6602 C HL0 = current value of (step size h) * (coefficient l0).
6603 C
6604 C JPRE = preconditioner type flag.
6605 C
6606 C MNEWT = Newton iteration counter (.ge. 0).
6607 C
6608 C WK = real work array used by routine DATP.
6609 C
6610 C WP = real work array used by preconditioner PSOL.
6611 C
6612 C IWP = integer work array used by preconditioner PSOL.
6613 C
6614 C On return
6615 C
6616 C X = the final computed approximation to the solution
6617 C of the system A*x = b.
6618 C
6619 C LPCG = the number of iterations performed, and current
6620 C order of the upper Hessenberg matrix HES.
6621 C
6622 C NPSL = the number of calls to PSOL.
6623 C
6624 C IFLAG = integer error flag:
6625 C 0 means convergence in LPCG iterations, LPCG .le. MAXL.
6626 C 1 means the convergence test did not pass in MAXL
6627 C iterations, but the residual norm is .lt. 1,
6628 C or .lt. norm(b) if MNEWT = 0, and so X is computed.
6629 C 2 means the convergence test did not pass in MAXL
6630 C iterations, residual .gt. 1, and X is undefined.
6631 C 3 means there was a recoverable error in PSOL
6632 C caused by the preconditioner being out of date.
6633 C 4 means there was a zero denominator in the algorithm.
6634 C The system matrix or preconditioner matrix is not
6635 C sufficiently close to being symmetric pos. definite.
6636 C -1 means there was a nonrecoverable error in PSOL.
6637 C
6638 C-----------------------------------------------------------------------
6639  INTEGER i, ier
6640  DOUBLE PRECISION alpha,beta,bnrm,ptw,rnrm,ddot,dvnorm,ztr,ztr0
6641 C
6642  iflag = 0
6643  npsl = 0
6644  lpcg = 0
6645  DO 10 i = 1,n
6646  10 x(i) = 0.0d0
6647  bnrm = dvnorm(n, r, wght)
6648 C Test for immediate return with X = 0 or X = b. -----------------------
6649  IF (bnrm .GT. delta) GO TO 20
6650  IF (mnewt .GT. 0) RETURN
6651  CALL dcopy (n, r, 1, x, 1)
6652  RETURN
6653 C
6654  20 ztr = 0.0d0
6655 C Loop point for PCG iterations. ---------------------------------------
6656  30 CONTINUE
6657  lpcg = lpcg + 1
6658  CALL dcopy (n, r, 1, z, 1)
6659  ier = 0
6660  IF (jpre .EQ. 0) GO TO 40
6661  CALL psol (neq, tn, y, savf, wk, hl0, wp, iwp, z, 3, ier)
6662  npsl = npsl + 1
6663  IF (ier .NE. 0) GO TO 100
6664  40 CONTINUE
6665  ztr0 = ztr
6666  ztr = ddot(n, z, 1, r, 1)
6667  IF (lpcg .NE. 1) GO TO 50
6668  CALL dcopy (n, z, 1, p, 1)
6669  GO TO 70
6670  50 CONTINUE
6671  IF (ztr0 .EQ. 0.0d0) GO TO 200
6672  beta = ztr/ztr0
6673  DO 60 i = 1,n
6674  60 p(i) = z(i) + beta*p(i)
6675  70 CONTINUE
6676 C-----------------------------------------------------------------------
6677 C Call DATP to compute A*p and return the answer in W.
6678 C-----------------------------------------------------------------------
6679  CALL datp (neq, y, savf, p, wght, hl0, wk, f, w)
6680 C
6681  ptw = ddot(n, p, 1, w, 1)
6682  IF (ptw .EQ. 0.0d0) GO TO 200
6683  alpha = ztr/ptw
6684  CALL daxpy (n, alpha, p, 1, x, 1)
6685  alpha = -alpha
6686  CALL daxpy (n, alpha, w, 1, r, 1)
6687  rnrm = dvnorm(n, r, wght)
6688  IF (rnrm .LE. delta) RETURN
6689  IF (lpcg .LT. maxl) GO TO 30
6690  iflag = 2
6691  IF (rnrm .LE. 1.0d0) iflag = 1
6692  IF (rnrm .LE. bnrm .AND. mnewt .EQ. 0) iflag = 1
6693  RETURN
6694 C-----------------------------------------------------------------------
6695 C This block handles error returns from PSOL.
6696 C-----------------------------------------------------------------------
6697  100 CONTINUE
6698  IF (ier .LT. 0) iflag = -1
6699  IF (ier .GT. 0) iflag = 3
6700  RETURN
6701 C-----------------------------------------------------------------------
6702 C This block handles division by zero errors.
6703 C-----------------------------------------------------------------------
6704  200 CONTINUE
6705  iflag = 4
6706  RETURN
6707 C----------------------- End of Subroutine DPCG ------------------------
6708  END
6709 *DECK DPCGS
6710  SUBROUTINE dpcgs (NEQ, TN, Y, SAVF, R, WGHT, N, MAXL, DELTA, HL0,
6711  1 JPRE, MNEWT, F, PSOL, NPSL, X, P, W, Z, LPCG, WP, IWP, WK, IFLAG)
6712  EXTERNAL f, psol
6713  INTEGER neq, n, maxl, jpre, mnewt, npsl, lpcg, iwp, iflag
6714  DOUBLE PRECISION tn,y,savf,r,wght,delta,hl0,x,p,w,z,wp,wk
6715  dimension neq(*), y(*), savf(*), r(*), wght(*), x(*), p(*), w(*),
6716  1 z(*), wp(*), iwp(*), wk(*)
6717 C-----------------------------------------------------------------------
6718 C This routine computes the solution to the system A*x = b using a
6719 C scaled preconditioned version of the Conjugate Gradient algorithm.
6720 C It is assumed here that the scaled matrix D**-1 * A * D and the
6721 C scaled preconditioner D**-1 * M * D are close to being
6722 C symmetric positive definite.
6723 C-----------------------------------------------------------------------
6724 C
6725 C On entry
6726 C
6727 C NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6728 C
6729 C TN = current value of t.
6730 C
6731 C Y = array containing current dependent variable vector.
6732 C
6733 C SAVF = array containing current value of f(t,y).
6734 C
6735 C R = the right hand side of the system A*x = b.
6736 C
6737 C WGHT = array of length N containing scale factors.
6738 C 1/WGHT(i) are the diagonal elements of the diagonal
6739 C scaling matrix D.
6740 C
6741 C N = the order of the matrix A, and the lengths
6742 C of the vectors Y, SAVF, R, WGHT, P, W, Z, WK, and X.
6743 C
6744 C MAXL = the maximum allowable number of iterates.
6745 C
6746 C DELTA = tolerance on residuals b - A*x in weighted RMS-norm.
6747 C
6748 C HL0 = current value of (step size h) * (coefficient l0).
6749 C
6750 C JPRE = preconditioner type flag.
6751 C
6752 C MNEWT = Newton iteration counter (.ge. 0).
6753 C
6754 C WK = real work array used by routine DATP.
6755 C
6756 C WP = real work array used by preconditioner PSOL.
6757 C
6758 C IWP = integer work array used by preconditioner PSOL.
6759 C
6760 C On return
6761 C
6762 C X = the final computed approximation to the solution
6763 C of the system A*x = b.
6764 C
6765 C LPCG = the number of iterations performed, and current
6766 C order of the upper Hessenberg matrix HES.
6767 C
6768 C NPSL = the number of calls to PSOL.
6769 C
6770 C IFLAG = integer error flag:
6771 C 0 means convergence in LPCG iterations, LPCG .le. MAXL.
6772 C 1 means the convergence test did not pass in MAXL
6773 C iterations, but the residual norm is .lt. 1,
6774 C or .lt. norm(b) if MNEWT = 0, and so X is computed.
6775 C 2 means the convergence test did not pass in MAXL
6776 C iterations, residual .gt. 1, and X is undefined.
6777 C 3 means there was a recoverable error in PSOL
6778 C caused by the preconditioner being out of date.
6779 C 4 means there was a zero denominator in the algorithm.
6780 C the scaled matrix or scaled preconditioner is not
6781 C sufficiently close to being symmetric pos. definite.
6782 C -1 means there was a nonrecoverable error in PSOL.
6783 C
6784 C-----------------------------------------------------------------------
6785  INTEGER i, ier
6786  DOUBLE PRECISION alpha, beta, bnrm, ptw, rnrm, dvnorm, ztr, ztr0
6787 C
6788  iflag = 0
6789  npsl = 0
6790  lpcg = 0
6791  DO 10 i = 1,n
6792  10 x(i) = 0.0d0
6793  bnrm = dvnorm(n, r, wght)
6794 C Test for immediate return with X = 0 or X = b. -----------------------
6795  IF (bnrm .GT. delta) GO TO 20
6796  IF (mnewt .GT. 0) RETURN
6797  CALL dcopy (n, r, 1, x, 1)
6798  RETURN
6799 C
6800  20 ztr = 0.0d0
6801 C Loop point for PCG iterations. ---------------------------------------
6802  30 CONTINUE
6803  lpcg = lpcg + 1
6804  CALL dcopy (n, r, 1, z, 1)
6805  ier = 0
6806  IF (jpre .EQ. 0) GO TO 40
6807  CALL psol (neq, tn, y, savf, wk, hl0, wp, iwp, z, 3, ier)
6808  npsl = npsl + 1
6809  IF (ier .NE. 0) GO TO 100
6810  40 CONTINUE
6811  ztr0 = ztr
6812  ztr = 0.0d0
6813  DO 45 i = 1,n
6814  45 ztr = ztr + z(i)*r(i)*wght(i)**2
6815  IF (lpcg .NE. 1) GO TO 50
6816  CALL dcopy (n, z, 1, p, 1)
6817  GO TO 70
6818  50 CONTINUE
6819  IF (ztr0 .EQ. 0.0d0) GO TO 200
6820  beta = ztr/ztr0
6821  DO 60 i = 1,n
6822  60 p(i) = z(i) + beta*p(i)
6823  70 CONTINUE
6824 C-----------------------------------------------------------------------
6825 C Call DATP to compute A*p and return the answer in W.
6826 C-----------------------------------------------------------------------
6827  CALL datp (neq, y, savf, p, wght, hl0, wk, f, w)
6828 C
6829  ptw = 0.0d0
6830  DO 80 i = 1,n
6831  80 ptw = ptw + p(i)*w(i)*wght(i)**2
6832  IF (ptw .EQ. 0.0d0) GO TO 200
6833  alpha = ztr/ptw
6834  CALL daxpy (n, alpha, p, 1, x, 1)
6835  alpha = -alpha
6836  CALL daxpy (n, alpha, w, 1, r, 1)
6837  rnrm = dvnorm(n, r, wght)
6838  IF (rnrm .LE. delta) RETURN
6839  IF (lpcg .LT. maxl) GO TO 30
6840  iflag = 2
6841  IF (rnrm .LE. 1.0d0) iflag = 1
6842  IF (rnrm .LE. bnrm .AND. mnewt .EQ. 0) iflag = 1
6843  RETURN
6844 C-----------------------------------------------------------------------
6845 C This block handles error returns from PSOL.
6846 C-----------------------------------------------------------------------
6847  100 CONTINUE
6848  IF (ier .LT. 0) iflag = -1
6849  IF (ier .GT. 0) iflag = 3
6850  RETURN
6851 C-----------------------------------------------------------------------
6852 C This block handles division by zero errors.
6853 C-----------------------------------------------------------------------
6854  200 CONTINUE
6855  iflag = 4
6856  RETURN
6857 C----------------------- End of Subroutine DPCGS -----------------------
6858  END
6859 *DECK DATP
6860  SUBROUTINE datp (NEQ, Y, SAVF, P, WGHT, HL0, WK, F, W)
6861  EXTERNAL f
6862  INTEGER neq
6863  DOUBLE PRECISION y, savf, p, wght, hl0, wk, w
6864  dimension neq(*), y(*), savf(*), p(*), wght(*), wk(*), w(*)
6865  INTEGER iownd, iowns,
6866  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
6867  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
6868  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
6869  DOUBLE PRECISION rowns,
6870  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
6871  COMMON /dls001/ rowns(209),
6872  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
6873  2 iownd(6), iowns(6),
6874  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
6875  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
6876  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
6877 C-----------------------------------------------------------------------
6878 C This routine computes the product
6879 C
6880 C w = (I - hl0*df/dy)*p
6881 C
6882 C This is computed by a call to F and a difference quotient.
6883 C-----------------------------------------------------------------------
6884 C
6885 C On entry
6886 C
6887 C NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6888 C
6889 C Y = array containing current dependent variable vector.
6890 C
6891 C SAVF = array containing current value of f(t,y).
6892 C
6893 C P = real array of length N.
6894 C
6895 C WGHT = array of length N containing scale factors.
6896 C 1/WGHT(i) are the diagonal elements of the matrix D.
6897 C
6898 C WK = work array of length N.
6899 C
6900 C On return
6901 C
6902 C
6903 C W = array of length N containing desired
6904 C matrix-vector product.
6905 C
6906 C In addition, this routine uses the Common variables TN, N, NFE.
6907 C-----------------------------------------------------------------------
6908  INTEGER i
6909  DOUBLE PRECISION fac, pnrm, rpnrm, dvnorm
6910 C
6911  pnrm = dvnorm(n, p, wght)
6912  rpnrm = 1.0d0/pnrm
6913  CALL dcopy (n, y, 1, w, 1)
6914  DO 20 i = 1,n
6915  20 y(i) = w(i) + p(i)*rpnrm
6916  CALL f (neq, tn, y, wk)
6917  nfe = nfe + 1
6918  CALL dcopy (n, w, 1, y, 1)
6919  fac = hl0*pnrm
6920  DO 40 i = 1,n
6921  40 w(i) = p(i) - fac*(wk(i) - savf(i))
6922  RETURN
6923 C----------------------- End of Subroutine DATP ------------------------
6924  END
6925 *DECK DUSOL
6926  SUBROUTINE dusol (NEQ, TN, Y, SAVF, B, WGHT, N, DELTA, HL0, MNEWT,
6927  1 PSOL, NPSL, X, WP, IWP, WK, IFLAG)
6928  EXTERNAL psol
6929  INTEGER neq, n, mnewt, npsl, iwp, iflag
6930  DOUBLE PRECISION tn, y, savf, b, wght, delta, hl0, x, wp, wk
6931  dimension neq(*), y(*), savf(*), b(*), wght(*), x(*),
6932  1 wp(*), iwp(*), wk(*)
6933 C-----------------------------------------------------------------------
6934 C This routine solves the linear system A * x = b using only a call
6935 C to the user-supplied routine PSOL (no Krylov iteration).
6936 C If the norm of the right-hand side vector b is smaller than DELTA,
6937 C the vector X returned is X = b (if MNEWT = 0) or X = 0 otherwise.
6938 C PSOL is called with an LR argument of 0.
6939 C-----------------------------------------------------------------------
6940 C
6941 C On entry
6942 C
6943 C NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6944 C
6945 C TN = current value of t.
6946 C
6947 C Y = array containing current dependent variable vector.
6948 C
6949 C SAVF = array containing current value of f(t,y).
6950 C
6951 C B = the right hand side of the system A*x = b.
6952 C
6953 C WGHT = the vector of length N containing the nonzero
6954 C elements of the diagonal scaling matrix.
6955 C
6956 C N = the order of the matrix A, and the lengths
6957 C of the vectors WGHT, B and X.
6958 C
6959 C DELTA = tolerance on residuals b - A*x in weighted RMS-norm.
6960 C
6961 C HL0 = current value of (step size h) * (coefficient l0).
6962 C
6963 C MNEWT = Newton iteration counter (.ge. 0).
6964 C
6965 C WK = real work array used by PSOL.
6966 C
6967 C WP = real work array used by preconditioner PSOL.
6968 C
6969 C IWP = integer work array used by preconditioner PSOL.
6970 C
6971 C On return
6972 C
6973 C X = the final computed approximation to the solution
6974 C of the system A*x = b.
6975 C
6976 C NPSL = the number of calls to PSOL.
6977 C
6978 C IFLAG = integer error flag:
6979 C 0 means no trouble occurred.
6980 C 3 means there was a recoverable error in PSOL
6981 C caused by the preconditioner being out of date.
6982 C -1 means there was a nonrecoverable error in PSOL.
6983 C
6984 C-----------------------------------------------------------------------
6985  INTEGER i, ier
6986  DOUBLE PRECISION bnrm, dvnorm
6987 C
6988  iflag = 0
6989  npsl = 0
6990 C-----------------------------------------------------------------------
6991 C Test for an immediate return with X = 0 or X = b.
6992 C-----------------------------------------------------------------------
6993  bnrm = dvnorm(n, b, wght)
6994  IF (bnrm .GT. delta) GO TO 30
6995  IF (mnewt .GT. 0) GO TO 10
6996  CALL dcopy (n, b, 1, x, 1)
6997  RETURN
6998  10 DO 20 i = 1,n
6999  20 x(i) = 0.0d0
7000  RETURN
7001 C Make call to PSOL and copy result from B to X. -----------------------
7002  30 ier = 0
7003  CALL psol (neq, tn, y, savf, wk, hl0, wp, iwp, b, 0, ier)
7004  npsl = 1
7005  IF (ier .NE. 0) GO TO 100
7006  CALL dcopy (n, b, 1, x, 1)
7007  RETURN
7008 C-----------------------------------------------------------------------
7009 C This block handles error returns forced by routine PSOL.
7010 C-----------------------------------------------------------------------
7011  100 CONTINUE
7012  IF (ier .LT. 0) iflag = -1
7013  IF (ier .GT. 0) iflag = 3
7014  RETURN
7015 C----------------------- End of Subroutine DUSOL -----------------------
7016  END
7017 *DECK DSRCPK
7018  SUBROUTINE dsrcpk (RSAV, ISAV, JOB)
7019 C-----------------------------------------------------------------------
7020 C This routine saves or restores (depending on JOB) the contents of
7021 C the Common blocks DLS001, DLPK01, which are used
7022 C internally by the DLSODPK solver.
7023 C
7024 C RSAV = real array of length 222 or more.
7025 C ISAV = integer array of length 50 or more.
7026 C JOB = flag indicating to save or restore the Common blocks:
7027 C JOB = 1 if Common is to be saved (written to RSAV/ISAV)
7028 C JOB = 2 if Common is to be restored (read from RSAV/ISAV)
7029 C A call with JOB = 2 presumes a prior call with JOB = 1.
7030 C-----------------------------------------------------------------------
7031  INTEGER isav, job
7032  INTEGER ils, ilsp
7033  INTEGER i, lenilp, lenrlp, lenils, lenrls
7034  DOUBLE PRECISION rsav, rls, rlsp
7035  dimension rsav(*), isav(*)
7036  SAVE lenrls, lenils, lenrlp, lenilp
7037  COMMON /dls001/ rls(218), ils(37)
7038  COMMON /dlpk01/ rlsp(4), ilsp(13)
7039  DATA lenrls/218/, lenils/37/, lenrlp/4/, lenilp/13/
7040 C
7041  IF (job .EQ. 2) GO TO 100
7042  CALL dcopy (lenrls, rls, 1, rsav, 1)
7043  CALL dcopy (lenrlp, rlsp, 1, rsav(lenrls+1), 1)
7044  DO 20 i = 1,lenils
7045  20 isav(i) = ils(i)
7046  DO 40 i = 1,lenilp
7047  40 isav(lenils+i) = ilsp(i)
7048  RETURN
7049 C
7050  100 CONTINUE
7051  CALL dcopy (lenrls, rsav, 1, rls, 1)
7052  CALL dcopy (lenrlp, rsav(lenrls+1), 1, rlsp, 1)
7053  DO 120 i = 1,lenils
7054  120 ils(i) = isav(i)
7055  DO 140 i = 1,lenilp
7056  140 ilsp(i) = isav(lenils+i)
7057  RETURN
7058 C----------------------- End of Subroutine DSRCPK ----------------------
7059  END
7060 *DECK DHEFA
7061  SUBROUTINE dhefa (A, LDA, N, IPVT, INFO, JOB)
7062  INTEGER lda, n, ipvt(*), info, job
7063  DOUBLE PRECISION a(lda,*)
7064 C-----------------------------------------------------------------------
7065 C This routine is a modification of the LINPACK routine DGEFA and
7066 C performs an LU decomposition of an upper Hessenberg matrix A.
7067 C There are two options available:
7068 C
7069 C (1) performing a fresh factorization
7070 C (2) updating the LU factors by adding a row and a
7071 C column to the matrix A.
7072 C-----------------------------------------------------------------------
7073 C DHEFA factors an upper Hessenberg matrix by elimination.
7074 C
7075 C On entry
7076 C
7077 C A DOUBLE PRECISION(LDA, N)
7078 C the matrix to be factored.
7079 C
7080 C LDA INTEGER
7081 C the leading dimension of the array A .
7082 C
7083 C N INTEGER
7084 C the order of the matrix A .
7085 C
7086 C JOB INTEGER
7087 C JOB = 1 means that a fresh factorization of the
7088 C matrix A is desired.
7089 C JOB .ge. 2 means that the current factorization of A
7090 C will be updated by the addition of a row
7091 C and a column.
7092 C
7093 C On return
7094 C
7095 C A an upper triangular matrix and the multipliers
7096 C which were used to obtain it.
7097 C The factorization can be written A = L*U where
7098 C L is a product of permutation and unit lower
7099 C triangular matrices and U is upper triangular.
7100 C
7101 C IPVT INTEGER(N)
7102 C an integer vector of pivot indices.
7103 C
7104 C INFO INTEGER
7105 C = 0 normal value.
7106 C = k if U(k,k) .eq. 0.0 . This is not an error
7107 C condition for this subroutine, but it does
7108 C indicate that DHESL will divide by zero if called.
7109 C
7110 C Modification of LINPACK, by Peter Brown, LLNL.
7111 C Written 7/20/83. This version dated 6/20/01.
7112 C
7113 C BLAS called: DAXPY, IDAMAX
7114 C-----------------------------------------------------------------------
7115  INTEGER idamax, j, k, km1, kp1, l, nm1
7116  DOUBLE PRECISION t
7117 C
7118  IF (job .GT. 1) GO TO 80
7119 C
7120 C A new facorization is desired. This is essentially the LINPACK
7121 C code with the exception that we know there is only one nonzero
7122 C element below the main diagonal.
7123 C
7124 C Gaussian elimination with partial pivoting
7125 C
7126  info = 0
7127  nm1 = n - 1
7128  IF (nm1 .LT. 1) GO TO 70
7129  DO 60 k = 1, nm1
7130  kp1 = k + 1
7131 C
7132 C Find L = pivot index
7133 C
7134  l = idamax(2, a(k,k), 1) + k - 1
7135  ipvt(k) = l
7136 C
7137 C Zero pivot implies this column already triangularized
7138 C
7139  IF (a(l,k) .EQ. 0.0d0) GO TO 40
7140 C
7141 C Interchange if necessary
7142 C
7143  IF (l .EQ. k) GO TO 10
7144  t = a(l,k)
7145  a(l,k) = a(k,k)
7146  a(k,k) = t
7147  10 CONTINUE
7148 C
7149 C Compute multipliers
7150 C
7151  t = -1.0d0/a(k,k)
7152  a(k+1,k) = a(k+1,k)*t
7153 C
7154 C Row elimination with column indexing
7155 C
7156  DO 30 j = kp1, n
7157  t = a(l,j)
7158  IF (l .EQ. k) GO TO 20
7159  a(l,j) = a(k,j)
7160  a(k,j) = t
7161  20 CONTINUE
7162  CALL daxpy (n-k, t, a(k+1,k), 1, a(k+1,j), 1)
7163  30 CONTINUE
7164  GO TO 50
7165  40 CONTINUE
7166  info = k
7167  50 CONTINUE
7168  60 CONTINUE
7169  70 CONTINUE
7170  ipvt(n) = n
7171  IF (a(n,n) .EQ. 0.0d0) info = n
7172  RETURN
7173 C
7174 C The old factorization of A will be updated. A row and a column
7175 C has been added to the matrix A.
7176 C N-1 is now the old order of the matrix.
7177 C
7178  80 CONTINUE
7179  nm1 = n - 1
7180 C
7181 C Perform row interchanges on the elements of the new column, and
7182 C perform elimination operations on the elements using the multipliers.
7183 C
7184  IF (nm1 .LE. 1) GO TO 105
7185  DO 100 k = 2,nm1
7186  km1 = k - 1
7187  l = ipvt(km1)
7188  t = a(l,n)
7189  IF (l .EQ. km1) GO TO 90
7190  a(l,n) = a(km1,n)
7191  a(km1,n) = t
7192  90 CONTINUE
7193  a(k,n) = a(k,n) + a(k,km1)*t
7194  100 CONTINUE
7195  105 CONTINUE
7196 C
7197 C Complete update of factorization by decomposing last 2x2 block.
7198 C
7199  info = 0
7200 C
7201 C Find L = pivot index
7202 C
7203  l = idamax(2, a(nm1,nm1), 1) + nm1 - 1
7204  ipvt(nm1) = l
7205 C
7206 C Zero pivot implies this column already triangularized
7207 C
7208  IF (a(l,nm1) .EQ. 0.0d0) GO TO 140
7209 C
7210 C Interchange if necessary
7211 C
7212  IF (l .EQ. nm1) GO TO 110
7213  t = a(l,nm1)
7214  a(l,nm1) = a(nm1,nm1)
7215  a(nm1,nm1) = t
7216  110 CONTINUE
7217 C
7218 C Compute multipliers
7219 C
7220  t = -1.0d0/a(nm1,nm1)
7221  a(n,nm1) = a(n,nm1)*t
7222 C
7223 C Row elimination with column indexing
7224 C
7225  t = a(l,n)
7226  IF (l .EQ. nm1) GO TO 120
7227  a(l,n) = a(nm1,n)
7228  a(nm1,n) = t
7229  120 CONTINUE
7230  a(n,n) = a(n,n) + t*a(n,nm1)
7231  GO TO 150
7232  140 CONTINUE
7233  info = nm1
7234  150 CONTINUE
7235  ipvt(n) = n
7236  IF (a(n,n) .EQ. 0.0d0) info = n
7237  RETURN
7238 C----------------------- End of Subroutine DHEFA -----------------------
7239  END
7240 *DECK DHESL
7241  SUBROUTINE dhesl (A, LDA, N, IPVT, B)
7242  INTEGER lda, n, ipvt(*)
7243  DOUBLE PRECISION a(lda,*), b(*)
7244 C-----------------------------------------------------------------------
7245 C This is essentially the LINPACK routine DGESL except for changes
7246 C due to the fact that A is an upper Hessenberg matrix.
7247 C-----------------------------------------------------------------------
7248 C DHESL solves the real system A * x = b
7249 C using the factors computed by DHEFA.
7250 C
7251 C On entry
7252 C
7253 C A DOUBLE PRECISION(LDA, N)
7254 C the output from DHEFA.
7255 C
7256 C LDA INTEGER
7257 C the leading dimension of the array A .
7258 C
7259 C N INTEGER
7260 C the order of the matrix A .
7261 C
7262 C IPVT INTEGER(N)
7263 C the pivot vector from DHEFA.
7264 C
7265 C B DOUBLE PRECISION(N)
7266 C the right hand side vector.
7267 C
7268 C On return
7269 C
7270 C B the solution vector x .
7271 C
7272 C Modification of LINPACK, by Peter Brown, LLNL.
7273 C Written 7/20/83. This version dated 6/20/01.
7274 C
7275 C BLAS called: DAXPY
7276 C-----------------------------------------------------------------------
7277  INTEGER k, kb, l, nm1
7278  DOUBLE PRECISION t
7279 C
7280  nm1 = n - 1
7281 C
7282 C Solve A * x = b
7283 C First solve L*y = b
7284 C
7285  IF (nm1 .LT. 1) GO TO 30
7286  DO 20 k = 1, nm1
7287  l = ipvt(k)
7288  t = b(l)
7289  IF (l .EQ. k) GO TO 10
7290  b(l) = b(k)
7291  b(k) = t
7292  10 CONTINUE
7293  b(k+1) = b(k+1) + t*a(k+1,k)
7294  20 CONTINUE
7295  30 CONTINUE
7296 C
7297 C Now solve U*x = y
7298 C
7299  DO 40 kb = 1, n
7300  k = n + 1 - kb
7301  b(k) = b(k)/a(k,k)
7302  t = -b(k)
7303  CALL daxpy (k-1, t, a(1,k), 1, b(1), 1)
7304  40 CONTINUE
7305  RETURN
7306 C----------------------- End of Subroutine DHESL -----------------------
7307  END
7308 *DECK DHEQR
7309  SUBROUTINE dheqr (A, LDA, N, Q, INFO, IJOB)
7310  INTEGER lda, n, info, ijob
7311  DOUBLE PRECISION a(lda,*), q(*)
7312 C-----------------------------------------------------------------------
7313 C This routine performs a QR decomposition of an upper
7314 C Hessenberg matrix A. There are two options available:
7315 C
7316 C (1) performing a fresh decomposition
7317 C (2) updating the QR factors by adding a row and a
7318 C column to the matrix A.
7319 C-----------------------------------------------------------------------
7320 C DHEQR decomposes an upper Hessenberg matrix by using Givens
7321 C rotations.
7322 C
7323 C On entry
7324 C
7325 C A DOUBLE PRECISION(LDA, N)
7326 C the matrix to be decomposed.
7327 C
7328 C LDA INTEGER
7329 C the leading dimension of the array A .
7330 C
7331 C N INTEGER
7332 C A is an (N+1) by N Hessenberg matrix.
7333 C
7334 C IJOB INTEGER
7335 C = 1 means that a fresh decomposition of the
7336 C matrix A is desired.
7337 C .ge. 2 means that the current decomposition of A
7338 C will be updated by the addition of a row
7339 C and a column.
7340 C On return
7341 C
7342 C A the upper triangular matrix R.
7343 C The factorization can be written Q*A = R, where
7344 C Q is a product of Givens rotations and R is upper
7345 C triangular.
7346 C
7347 C Q DOUBLE PRECISION(2*N)
7348 C the factors c and s of each Givens rotation used
7349 C in decomposing A.
7350 C
7351 C INFO INTEGER
7352 C = 0 normal value.
7353 C = k if A(k,k) .eq. 0.0 . This is not an error
7354 C condition for this subroutine, but it does
7355 C indicate that DHELS will divide by zero
7356 C if called.
7357 C
7358 C Modification of LINPACK, by Peter Brown, LLNL.
7359 C Written 1/13/86. This version dated 6/20/01.
7360 C-----------------------------------------------------------------------
7361  INTEGER i, iq, j, k, km1, kp1, nm1
7362  DOUBLE PRECISION c, s, t, t1, t2
7363 C
7364  IF (ijob .GT. 1) GO TO 70
7365 C
7366 C A new facorization is desired.
7367 C
7368 C QR decomposition without pivoting
7369 C
7370  info = 0
7371  DO 60 k = 1, n
7372  km1 = k - 1
7373  kp1 = k + 1
7374 C
7375 C Compute kth column of R.
7376 C First, multiply the kth column of A by the previous
7377 C k-1 Givens rotations.
7378 C
7379  IF (km1 .LT. 1) GO TO 20
7380  DO 10 j = 1, km1
7381  i = 2*(j-1) + 1
7382  t1 = a(j,k)
7383  t2 = a(j+1,k)
7384  c = q(i)
7385  s = q(i+1)
7386  a(j,k) = c*t1 - s*t2
7387  a(j+1,k) = s*t1 + c*t2
7388  10 CONTINUE
7389 C
7390 C Compute Givens components c and s
7391 C
7392  20 CONTINUE
7393  iq = 2*km1 + 1
7394  t1 = a(k,k)
7395  t2 = a(kp1,k)
7396  IF (t2 .NE. 0.0d0) GO TO 30
7397  c = 1.0d0
7398  s = 0.0d0
7399  GO TO 50
7400  30 CONTINUE
7401  IF (abs(t2) .LT. abs(t1)) GO TO 40
7402  t = t1/t2
7403  s = -1.0d0/sqrt(1.0d0+t*t)
7404  c = -s*t
7405  GO TO 50
7406  40 CONTINUE
7407  t = t2/t1
7408  c = 1.0d0/sqrt(1.0d0+t*t)
7409  s = -c*t
7410  50 CONTINUE
7411  q(iq) = c
7412  q(iq+1) = s
7413  a(k,k) = c*t1 - s*t2
7414  IF (a(k,k) .EQ. 0.0d0) info = k
7415  60 CONTINUE
7416  RETURN
7417 C
7418 C The old factorization of A will be updated. A row and a column
7419 C has been added to the matrix A.
7420 C N by N-1 is now the old size of the matrix.
7421 C
7422  70 CONTINUE
7423  nm1 = n - 1
7424 C
7425 C Multiply the new column by the N previous Givens rotations.
7426 C
7427  DO 100 k = 1,nm1
7428  i = 2*(k-1) + 1
7429  t1 = a(k,n)
7430  t2 = a(k+1,n)
7431  c = q(i)
7432  s = q(i+1)
7433  a(k,n) = c*t1 - s*t2
7434  a(k+1,n) = s*t1 + c*t2
7435  100 CONTINUE
7436 C
7437 C Complete update of decomposition by forming last Givens rotation,
7438 C and multiplying it times the column vector (A(N,N), A(N+1,N)).
7439 C
7440  info = 0
7441  t1 = a(n,n)
7442  t2 = a(n+1,n)
7443  IF (t2 .NE. 0.0d0) GO TO 110
7444  c = 1.0d0
7445  s = 0.0d0
7446  GO TO 130
7447  110 CONTINUE
7448  IF (abs(t2) .LT. abs(t1)) GO TO 120
7449  t = t1/t2
7450  s = -1.0d0/sqrt(1.0d0+t*t)
7451  c = -s*t
7452  GO TO 130
7453  120 CONTINUE
7454  t = t2/t1
7455  c = 1.0d0/sqrt(1.0d0+t*t)
7456  s = -c*t
7457  130 CONTINUE
7458  iq = 2*n - 1
7459  q(iq) = c
7460  q(iq+1) = s
7461  a(n,n) = c*t1 - s*t2
7462  IF (a(n,n) .EQ. 0.0d0) info = n
7463  RETURN
7464 C----------------------- End of Subroutine DHEQR -----------------------
7465  END
7466 *DECK DHELS
7467  SUBROUTINE dhels (A, LDA, N, Q, B)
7468  INTEGER lda, n
7469  DOUBLE PRECISION a(lda,*), b(*), q(*)
7470 C-----------------------------------------------------------------------
7471 C This is part of the LINPACK routine DGESL with changes
7472 C due to the fact that A is an upper Hessenberg matrix.
7473 C-----------------------------------------------------------------------
7474 C DHELS solves the least squares problem
7475 C
7476 C min (b-A*x, b-A*x)
7477 C
7478 C using the factors computed by DHEQR.
7479 C
7480 C On entry
7481 C
7482 C A DOUBLE PRECISION(LDA, N)
7483 C the output from DHEQR which contains the upper
7484 C triangular factor R in the QR decomposition of A.
7485 C
7486 C LDA INTEGER
7487 C the leading dimension of the array A .
7488 C
7489 C N INTEGER
7490 C A is originally an (N+1) by N matrix.
7491 C
7492 C Q DOUBLE PRECISION(2*N)
7493 C The coefficients of the N givens rotations
7494 C used in the QR factorization of A.
7495 C
7496 C B DOUBLE PRECISION(N+1)
7497 C the right hand side vector.
7498 C
7499 C On return
7500 C
7501 C B the solution vector x .
7502 C
7503 C Modification of LINPACK, by Peter Brown, LLNL.
7504 C Written 1/13/86. This version dated 6/20/01.
7505 C
7506 C BLAS called: DAXPY
7507 C-----------------------------------------------------------------------
7508  INTEGER iq, k, kb, kp1
7509  DOUBLE PRECISION c, s, t, t1, t2
7510 C
7511 C Minimize (b-A*x, b-A*x)
7512 C First form Q*b.
7513 C
7514  DO 20 k = 1, n
7515  kp1 = k + 1
7516  iq = 2*(k-1) + 1
7517  c = q(iq)
7518  s = q(iq+1)
7519  t1 = b(k)
7520  t2 = b(kp1)
7521  b(k) = c*t1 - s*t2
7522  b(kp1) = s*t1 + c*t2
7523  20 CONTINUE
7524 C
7525 C Now solve R*x = Q*b.
7526 C
7527  DO 40 kb = 1, n
7528  k = n + 1 - kb
7529  b(k) = b(k)/a(k,k)
7530  t = -b(k)
7531  CALL daxpy (k-1, t, a(1,k), 1, b(1), 1)
7532  40 CONTINUE
7533  RETURN
7534 C----------------------- End of Subroutine DHELS -----------------------
7535  END
7536 *DECK DLHIN
7537  SUBROUTINE dlhin (NEQ, N, T0, Y0, YDOT, F, TOUT, UROUND,
7538  1 EWT, ITOL, ATOL, Y, TEMP, H0, NITER, IER)
7539  EXTERNAL f
7540  DOUBLE PRECISION t0, y0, ydot, tout, uround, ewt, atol, y,
7541  1 temp, h0
7542  INTEGER neq, n, itol, niter, ier
7543  dimension neq(*), y0(*), ydot(*), ewt(*), atol(*), y(*), temp(*)
7544 C-----------------------------------------------------------------------
7545 C Call sequence input -- NEQ, N, T0, Y0, YDOT, F, TOUT, UROUND,
7546 C EWT, ITOL, ATOL, Y, TEMP
7547 C Call sequence output -- H0, NITER, IER
7548 C Common block variables accessed -- None
7549 C
7550 C Subroutines called by DLHIN: F, DCOPY
7551 C Function routines called by DLHIN: DVNORM
7552 C-----------------------------------------------------------------------
7553 C This routine computes the step size, H0, to be attempted on the
7554 C first step, when the user has not supplied a value for this.
7555 C
7556 C First we check that TOUT - T0 differs significantly from zero. Then
7557 C an iteration is done to approximate the initial second derivative
7558 C and this is used to define H from WRMS-norm(H**2 * yddot / 2) = 1.
7559 C A bias factor of 1/2 is applied to the resulting h.
7560 C The sign of H0 is inferred from the initial values of TOUT and T0.
7561 C
7562 C Communication with DLHIN is done with the following variables:
7563 C
7564 C NEQ = NEQ array of solver, passed to F.
7565 C N = size of ODE system, input.
7566 C T0 = initial value of independent variable, input.
7567 C Y0 = vector of initial conditions, input.
7568 C YDOT = vector of initial first derivatives, input.
7569 C F = name of subroutine for right-hand side f(t,y), input.
7570 C TOUT = first output value of independent variable
7571 C UROUND = machine unit roundoff
7572 C EWT, ITOL, ATOL = error weights and tolerance parameters
7573 C as described in the driver routine, input.
7574 C Y, TEMP = work arrays of length N.
7575 C H0 = step size to be attempted, output.
7576 C NITER = number of iterations (and of f evaluations) to compute H0,
7577 C output.
7578 C IER = the error flag, returned with the value
7579 C IER = 0 if no trouble occurred, or
7580 C IER = -1 if TOUT and t0 are considered too close to proceed.
7581 C-----------------------------------------------------------------------
7582 C
7583 C Type declarations for local variables --------------------------------
7584 C
7585  DOUBLE PRECISION afi, atoli, delyi, half, hg, hlb, hnew, hrat,
7586  1 hub, hun, pt1, t1, tdist, tround, two, dvnorm, yddnrm
7587  INTEGER i, iter
7588 C-----------------------------------------------------------------------
7589 C The following Fortran-77 declaration is to cause the values of the
7590 C listed (local) variables to be saved between calls to this integrator.
7591 C-----------------------------------------------------------------------
7592  SAVE half, hun, pt1, two
7593  DATA half /0.5d0/, hun /100.0d0/, pt1 /0.1d0/, two /2.0d0/
7594 C
7595  niter = 0
7596  tdist = abs(tout - t0)
7597  tround = uround*max(abs(t0),abs(tout))
7598  IF (tdist .LT. two*tround) GO TO 100
7599 C
7600 C Set a lower bound on H based on the roundoff level in T0 and TOUT. ---
7601  hlb = hun*tround
7602 C Set an upper bound on H based on TOUT-T0 and the initial Y and YDOT. -
7603  hub = pt1*tdist
7604  atoli = atol(1)
7605  DO 10 i = 1,n
7606  IF (itol .EQ. 2 .OR. itol .EQ. 4) atoli = atol(i)
7607  delyi = pt1*abs(y0(i)) + atoli
7608  afi = abs(ydot(i))
7609  IF (afi*hub .GT. delyi) hub = delyi/afi
7610  10 CONTINUE
7611 C
7612 C Set initial guess for H as geometric mean of upper and lower bounds. -
7613  iter = 0
7614  hg = sqrt(hlb*hub)
7615 C If the bounds have crossed, exit with the mean value. ----------------
7616  IF (hub .LT. hlb) THEN
7617  h0 = hg
7618  GO TO 90
7619  ENDIF
7620 C
7621 C Looping point for iteration. -----------------------------------------
7622  50 CONTINUE
7623 C Estimate the second derivative as a difference quotient in f. --------
7624  t1 = t0 + hg
7625  DO 60 i = 1,n
7626  60 y(i) = y0(i) + hg*ydot(i)
7627  CALL f (neq, t1, y, temp)
7628  DO 70 i = 1,n
7629  70 temp(i) = (temp(i) - ydot(i))/hg
7630  yddnrm = dvnorm(n, temp, ewt)
7631 C Get the corresponding new value of H. --------------------------------
7632  IF (yddnrm*hub*hub .GT. two) THEN
7633  hnew = sqrt(two/yddnrm)
7634  ELSE
7635  hnew = sqrt(hg*hub)
7636  ENDIF
7637  iter = iter + 1
7638 C-----------------------------------------------------------------------
7639 C Test the stopping conditions.
7640 C Stop if the new and previous H values differ by a factor of .lt. 2.
7641 C Stop if four iterations have been done. Also, stop with previous H
7642 C if hnew/hg .gt. 2 after first iteration, as this probably means that
7643 C the second derivative value is bad because of cancellation error.
7644 C-----------------------------------------------------------------------
7645  IF (iter .GE. 4) GO TO 80
7646  hrat = hnew/hg
7647  IF ( (hrat .GT. half) .AND. (hrat .LT. two) ) GO TO 80
7648  IF ( (iter .GE. 2) .AND. (hnew .GT. two*hg) ) THEN
7649  hnew = hg
7650  GO TO 80
7651  ENDIF
7652  hg = hnew
7653  GO TO 50
7654 C
7655 C Iteration done. Apply bounds, bias factor, and sign. ----------------
7656  80 h0 = hnew*half
7657  IF (h0 .LT. hlb) h0 = hlb
7658  IF (h0 .GT. hub) h0 = hub
7659  90 h0 = sign(h0, tout - t0)
7660 C Restore Y array from Y0, then exit. ----------------------------------
7661  CALL dcopy (n, y0, 1, y, 1)
7662  niter = iter
7663  ier = 0
7664  RETURN
7665 C Error return for TOUT - T0 too small. --------------------------------
7666  100 ier = -1
7667  RETURN
7668 C----------------------- End of Subroutine DLHIN -----------------------
7669  END
7670 *DECK DSTOKA
7671  SUBROUTINE dstoka (NEQ, Y, YH, NYH, YH1, EWT, SAVF, SAVX, ACOR,
7672  1 WM, IWM, F, JAC, PSOL)
7673  EXTERNAL f, jac, psol
7674  INTEGER neq, nyh, iwm
7675  DOUBLE PRECISION y, yh, yh1, ewt, savf, savx, acor, wm
7676  dimension neq(*), y(*), yh(nyh,*), yh1(*), ewt(*), savf(*),
7677  1 savx(*), acor(*), wm(*), iwm(*)
7678  INTEGER iownd, ialth, ipup, lmax, meo, nqnyh, nslp,
7679  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
7680  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
7681  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
7682  INTEGER newt, nsfi, nslj, njev
7683  INTEGER jpre, jacflg, locwp, lociwp, lsavx, kmp, maxl, mnewt,
7684  1 nni, nli, nps, ncfn, ncfl
7685  DOUBLE PRECISION conit, crate, el, elco, hold, rmax, tesco,
7686  2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
7687  DOUBLE PRECISION stifr
7688  DOUBLE PRECISION delt, epcon, sqrtn, rsqrtn
7689  COMMON /dls001/ conit, crate, el(13), elco(13,12),
7690  1 hold, rmax, tesco(3,12),
7691  2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
7692  3 iownd(6), ialth, ipup, lmax, meo, nqnyh, nslp,
7693  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
7694  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
7695  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
7696  COMMON /dls002/ stifr, newt, nsfi, nslj, njev
7697  COMMON /dlpk01/ delt, epcon, sqrtn, rsqrtn,
7698  1 jpre, jacflg, locwp, lociwp, lsavx, kmp, maxl, mnewt,
7699  2 nni, nli, nps, ncfn, ncfl
7700 C-----------------------------------------------------------------------
7701 C DSTOKA performs one step of the integration of an initial value
7702 C problem for a system of Ordinary Differential Equations.
7703 C
7704 C This routine was derived from Subroutine DSTODPK in the DLSODPK
7705 C package by the addition of automatic functional/Newton iteration
7706 C switching and logic for re-use of Jacobian data.
7707 C-----------------------------------------------------------------------
7708 C Note: DSTOKA is independent of the value of the iteration method
7709 C indicator MITER, when this is .ne. 0, and hence is independent
7710 C of the type of chord method used, or the Jacobian structure.
7711 C Communication with DSTOKA is done with the following variables:
7712 C
7713 C NEQ = integer array containing problem size in NEQ(1), and
7714 C passed as the NEQ argument in all calls to F and JAC.
7715 C Y = an array of length .ge. N used as the Y argument in
7716 C all calls to F and JAC.
7717 C YH = an NYH by LMAX array containing the dependent variables
7718 C and their approximate scaled derivatives, where
7719 C LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
7720 C j-th derivative of y(i), scaled by H**j/factorial(j)
7721 C (j = 0,1,...,NQ). On entry for the first step, the first
7722 C two columns of YH must be set from the initial values.
7723 C NYH = a constant integer .ge. N, the first dimension of YH.
7724 C YH1 = a one-dimensional array occupying the same space as YH.
7725 C EWT = an array of length N containing multiplicative weights
7726 C for local error measurements. Local errors in y(i) are
7727 C compared to 1.0/EWT(i) in various error tests.
7728 C SAVF = an array of working storage, of length N.
7729 C Also used for input of YH(*,MAXORD+2) when JSTART = -1
7730 C and MAXORD .lt. the current order NQ.
7731 C SAVX = an array of working storage, of length N.
7732 C ACOR = a work array of length N, used for the accumulated
7733 C corrections. On a successful return, ACOR(i) contains
7734 C the estimated one-step local error in y(i).
7735 C WM,IWM = real and integer work arrays associated with matrix
7736 C operations in chord iteration (MITER .ne. 0).
7737 C CCMAX = maximum relative change in H*EL0 before DSETPK is called.
7738 C H = the step size to be attempted on the next step.
7739 C H is altered by the error control algorithm during the
7740 C problem. H can be either positive or negative, but its
7741 C sign must remain constant throughout the problem.
7742 C HMIN = the minimum absolute value of the step size H to be used.
7743 C HMXI = inverse of the maximum absolute value of H to be used.
7744 C HMXI = 0.0 is allowed and corresponds to an infinite HMAX.
7745 C HMIN and HMXI may be changed at any time, but will not
7746 C take effect until the next change of H is considered.
7747 C TN = the independent variable. TN is updated on each step taken.
7748 C JSTART = an integer used for input only, with the following
7749 C values and meanings:
7750 C 0 perform the first step.
7751 C .gt.0 take a new step continuing from the last.
7752 C -1 take the next step with a new value of H, MAXORD,
7753 C N, METH, MITER, and/or matrix parameters.
7754 C -2 take the next step with a new value of H,
7755 C but with other inputs unchanged.
7756 C On return, JSTART is set to 1 to facilitate continuation.
7757 C KFLAG = a completion code with the following meanings:
7758 C 0 the step was succesful.
7759 C -1 the requested error could not be achieved.
7760 C -2 corrector convergence could not be achieved.
7761 C -3 fatal error in DSETPK or DSOLPK.
7762 C A return with KFLAG = -1 or -2 means either
7763 C ABS(H) = HMIN or 10 consecutive failures occurred.
7764 C On a return with KFLAG negative, the values of TN and
7765 C the YH array are as of the beginning of the last
7766 C step, and H is the last step size attempted.
7767 C MAXORD = the maximum order of integration method to be allowed.
7768 C MAXCOR = the maximum number of corrector iterations allowed.
7769 C MSBP = maximum number of steps between DSETPK calls (MITER .gt. 0).
7770 C MXNCF = maximum number of convergence failures allowed.
7771 C METH/MITER = the method flags. See description in driver.
7772 C N = the number of first-order differential equations.
7773 C-----------------------------------------------------------------------
7774  INTEGER i, i1, iredo, iret, j, jb, jok, m, ncf, newq, nslow
7775  DOUBLE PRECISION dcon, ddn, del, delp, drc, dsm, dup, exdn, exsm,
7776  1 exup, dfnorm, r, rh, rhdn, rhsm, rhup, roc, stiff, told, dvnorm
7777 C
7778  kflag = 0
7779  told = tn
7780  ncf = 0
7781  ierpj = 0
7782  iersl = 0
7783  jcur = 0
7784  icf = 0
7785  delp = 0.0d0
7786  IF (jstart .GT. 0) GO TO 200
7787  IF (jstart .EQ. -1) GO TO 100
7788  IF (jstart .EQ. -2) GO TO 160
7789 C-----------------------------------------------------------------------
7790 C On the first call, the order is set to 1, and other variables are
7791 C initialized. RMAX is the maximum ratio by which H can be increased
7792 C in a single step. It is initially 1.E4 to compensate for the small
7793 C initial H, but then is normally equal to 10. If a failure
7794 C occurs (in corrector convergence or error test), RMAX is set at 2
7795 C for the next increase.
7796 C-----------------------------------------------------------------------
7797  lmax = maxord + 1
7798  nq = 1
7799  l = 2
7800  ialth = 2
7801  rmax = 10000.0d0
7802  rc = 0.0d0
7803  el0 = 1.0d0
7804  crate = 0.7d0
7805  hold = h
7806  meo = meth
7807  nslp = 0
7808  nslj = 0
7809  ipup = 0
7810  iret = 3
7811  newt = 0
7812  stifr = 0.0d0
7813  GO TO 140
7814 C-----------------------------------------------------------------------
7815 C The following block handles preliminaries needed when JSTART = -1.
7816 C IPUP is set to MITER to force a matrix update.
7817 C If an order increase is about to be considered (IALTH = 1),
7818 C IALTH is reset to 2 to postpone consideration one more step.
7819 C If the caller has changed METH, DCFODE is called to reset
7820 C the coefficients of the method.
7821 C If the caller has changed MAXORD to a value less than the current
7822 C order NQ, NQ is reduced to MAXORD, and a new H chosen accordingly.
7823 C If H is to be changed, YH must be rescaled.
7824 C If H or METH is being changed, IALTH is reset to L = NQ + 1
7825 C to prevent further changes in H for that many steps.
7826 C-----------------------------------------------------------------------
7827  100 ipup = miter
7828  lmax = maxord + 1
7829  IF (ialth .EQ. 1) ialth = 2
7830  IF (meth .EQ. meo) GO TO 110
7831  CALL dcfode (meth, elco, tesco)
7832  meo = meth
7833  IF (nq .GT. maxord) GO TO 120
7834  ialth = l
7835  iret = 1
7836  GO TO 150
7837  110 IF (nq .LE. maxord) GO TO 160
7838  120 nq = maxord
7839  l = lmax
7840  DO 125 i = 1,l
7841  125 el(i) = elco(i,nq)
7842  nqnyh = nq*nyh
7843  rc = rc*el(1)/el0
7844  el0 = el(1)
7845  conit = 0.5d0/(nq+2)
7846  epcon = conit*tesco(2,nq)
7847  ddn = dvnorm(n, savf, ewt)/tesco(1,l)
7848  exdn = 1.0d0/l
7849  rhdn = 1.0d0/(1.3d0*ddn**exdn + 0.0000013d0)
7850  rh = min(rhdn,1.0d0)
7851  iredo = 3
7852  IF (h .EQ. hold) GO TO 170
7853  rh = min(rh,abs(h/hold))
7854  h = hold
7855  GO TO 175
7856 C-----------------------------------------------------------------------
7857 C DCFODE is called to get all the integration coefficients for the
7858 C current METH. Then the EL vector and related constants are reset
7859 C whenever the order NQ is changed, or at the start of the problem.
7860 C-----------------------------------------------------------------------
7861  140 CALL dcfode (meth, elco, tesco)
7862  150 DO 155 i = 1,l
7863  155 el(i) = elco(i,nq)
7864  nqnyh = nq*nyh
7865  rc = rc*el(1)/el0
7866  el0 = el(1)
7867  conit = 0.5d0/(nq+2)
7868  epcon = conit*tesco(2,nq)
7869  GO TO (160, 170, 200), iret
7870 C-----------------------------------------------------------------------
7871 C If H is being changed, the H ratio RH is checked against
7872 C RMAX, HMIN, and HMXI, and the YH array rescaled. IALTH is set to
7873 C L = NQ + 1 to prevent a change of H for that many steps, unless
7874 C forced by a convergence or error test failure.
7875 C-----------------------------------------------------------------------
7876  160 IF (h .EQ. hold) GO TO 200
7877  rh = h/hold
7878  h = hold
7879  iredo = 3
7880  GO TO 175
7881  170 rh = max(rh,hmin/abs(h))
7882  175 rh = min(rh,rmax)
7883  rh = rh/max(1.0d0,abs(h)*hmxi*rh)
7884  r = 1.0d0
7885  DO 180 j = 2,l
7886  r = r*rh
7887  DO 180 i = 1,n
7888  180 yh(i,j) = yh(i,j)*r
7889  h = h*rh
7890  rc = rc*rh
7891  ialth = l
7892  IF (iredo .EQ. 0) GO TO 690
7893 C-----------------------------------------------------------------------
7894 C This section computes the predicted values by effectively
7895 C multiplying the YH array by the Pascal triangle matrix.
7896 C The flag IPUP is set according to whether matrix data is involved
7897 C (NEWT .gt. 0 .and. JACFLG .ne. 0) or not, to trigger a call to DSETPK.
7898 C IPUP is set to MITER when RC differs from 1 by more than CCMAX,
7899 C and at least every MSBP steps, when JACFLG = 1.
7900 C RC is the ratio of new to old values of the coefficient H*EL(1).
7901 C-----------------------------------------------------------------------
7902  200 IF (newt .EQ. 0 .OR. jacflg .EQ. 0) THEN
7903  drc = 0.0d0
7904  ipup = 0
7905  crate = 0.7d0
7906  ELSE
7907  drc = abs(rc - 1.0d0)
7908  IF (drc .GT. ccmax) ipup = miter
7909  IF (nst .GE. nslp+msbp) ipup = miter
7910  ENDIF
7911  tn = tn + h
7912  i1 = nqnyh + 1
7913  DO 215 jb = 1,nq
7914  i1 = i1 - nyh
7915 CDIR$ IVDEP
7916  DO 210 i = i1,nqnyh
7917  210 yh1(i) = yh1(i) + yh1(i+nyh)
7918  215 CONTINUE
7919 C-----------------------------------------------------------------------
7920 C Up to MAXCOR corrector iterations are taken. A convergence test is
7921 C made on the RMS-norm of each correction, weighted by the error
7922 C weight vector EWT. The sum of the corrections is accumulated in the
7923 C vector ACOR(i). The YH array is not altered in the corrector loop.
7924 C Within the corrector loop, an estimated rate of convergence (ROC)
7925 C and a stiffness ratio estimate (STIFF) are kept. Corresponding
7926 C global estimates are kept as CRATE and stifr.
7927 C-----------------------------------------------------------------------
7928  220 m = 0
7929  mnewt = 0
7930  stiff = 0.0d0
7931  roc = 0.05d0
7932  nslow = 0
7933  DO 230 i = 1,n
7934  230 y(i) = yh(i,1)
7935  CALL f (neq, tn, y, savf)
7936  nfe = nfe + 1
7937  IF (newt .EQ. 0 .OR. ipup .LE. 0) GO TO 250
7938 C-----------------------------------------------------------------------
7939 C If indicated, DSETPK is called to update any matrix data needed,
7940 C before starting the corrector iteration.
7941 C JOK is set to indicate if the matrix data need not be recomputed.
7942 C IPUP is set to 0 as an indicator that the matrix data is up to date.
7943 C-----------------------------------------------------------------------
7944  jok = 1
7945  IF (nst .EQ. 0 .OR. nst .GT. nslj+50) jok = -1
7946  IF (icf .EQ. 1 .AND. drc .LT. 0.2d0) jok = -1
7947  IF (icf .EQ. 2) jok = -1
7948  IF (jok .EQ. -1) THEN
7949  nslj = nst
7950  njev = njev + 1
7951  ENDIF
7952  CALL dsetpk (neq, y, yh1, ewt, acor, savf, jok, wm, iwm, f, jac)
7953  ipup = 0
7954  rc = 1.0d0
7955  drc = 0.0d0
7956  nslp = nst
7957  crate = 0.7d0
7958  IF (ierpj .NE. 0) GO TO 430
7959  250 DO 260 i = 1,n
7960  260 acor(i) = 0.0d0
7961  270 IF (newt .NE. 0) GO TO 350
7962 C-----------------------------------------------------------------------
7963 C In the case of functional iteration, update Y directly from
7964 C the result of the last function evaluation, and STIFF is set to 1.0.
7965 C-----------------------------------------------------------------------
7966  DO 290 i = 1,n
7967  savf(i) = h*savf(i) - yh(i,2)
7968  290 y(i) = savf(i) - acor(i)
7969  del = dvnorm(n, y, ewt)
7970  DO 300 i = 1,n
7971  y(i) = yh(i,1) + el(1)*savf(i)
7972  300 acor(i) = savf(i)
7973  stiff = 1.0d0
7974  GO TO 400
7975 C-----------------------------------------------------------------------
7976 C In the case of the chord method, compute the corrector error,
7977 C and solve the linear system with that as right-hand side and
7978 C P as coefficient matrix. STIFF is set to the ratio of the norms
7979 C of the residual and the correction vector.
7980 C-----------------------------------------------------------------------
7981  350 DO 360 i = 1,n
7982  360 savx(i) = h*savf(i) - (yh(i,2) + acor(i))
7983  dfnorm = dvnorm(n, savx, ewt)
7984  CALL dsolpk (neq, y, savf, savx, ewt, wm, iwm, f, psol)
7985  IF (iersl .LT. 0) GO TO 430
7986  IF (iersl .GT. 0) GO TO 410
7987  del = dvnorm(n, savx, ewt)
7988  IF (del .GT. 1.0d-8) stiff = max(stiff, dfnorm/del)
7989  DO 380 i = 1,n
7990  acor(i) = acor(i) + savx(i)
7991  380 y(i) = yh(i,1) + el(1)*acor(i)
7992 C-----------------------------------------------------------------------
7993 C Test for convergence. If M .gt. 0, an estimate of the convergence
7994 C rate constant is made for the iteration switch, and is also used
7995 C in the convergence test. If the iteration seems to be diverging or
7996 C converging at a slow rate (.gt. 0.8 more than once), it is stopped.
7997 C-----------------------------------------------------------------------
7998  400 IF (m .NE. 0) THEN
7999  roc = max(0.05d0, del/delp)
8000  crate = max(0.2d0*crate,roc)
8001  ENDIF
8002  dcon = del*min(1.0d0,1.5d0*crate)/epcon
8003  IF (dcon .LE. 1.0d0) GO TO 450
8004  m = m + 1
8005  IF (m .EQ. maxcor) GO TO 410
8006  IF (m .GE. 2 .AND. del .GT. 2.0d0*delp) GO TO 410
8007  IF (roc .GT. 10.0d0) GO TO 410
8008  IF (roc .GT. 0.8d0) nslow = nslow + 1
8009  IF (nslow .GE. 2) GO TO 410
8010  mnewt = m
8011  delp = del
8012  CALL f (neq, tn, y, savf)
8013  nfe = nfe + 1
8014  GO TO 270
8015 C-----------------------------------------------------------------------
8016 C The corrector iteration failed to converge.
8017 C If functional iteration is being done (NEWT = 0) and MITER .gt. 0
8018 C (and this is not the first step), then switch to Newton
8019 C (NEWT = MITER), and retry the step. (Setting STIFR = 1023 insures
8020 C that a switch back will not occur for 10 step attempts.)
8021 C If Newton iteration is being done, but using a preconditioner that
8022 C is out of date (JACFLG .ne. 0 .and. JCUR = 0), then signal for a
8023 C re-evalutation of the preconditioner, and retry the step.
8024 C In all other cases, the YH array is retracted to its values
8025 C before prediction, and H is reduced, if possible. If H cannot be
8026 C reduced or MXNCF failures have occurred, exit with KFLAG = -2.
8027 C-----------------------------------------------------------------------
8028  410 icf = 1
8029  IF (newt .EQ. 0) THEN
8030  IF (nst .EQ. 0) GO TO 430
8031  IF (miter .EQ. 0) GO TO 430
8032  newt = miter
8033  stifr = 1023.0d0
8034  ipup = miter
8035  GO TO 220
8036  ENDIF
8037  IF (jcur.EQ.1 .OR. jacflg.EQ.0) GO TO 430
8038  ipup = miter
8039  GO TO 220
8040  430 icf = 2
8041  ncf = ncf + 1
8042  ncfn = ncfn + 1
8043  rmax = 2.0d0
8044  tn = told
8045  i1 = nqnyh + 1
8046  DO 445 jb = 1,nq
8047  i1 = i1 - nyh
8048 CDIR$ IVDEP
8049  DO 440 i = i1,nqnyh
8050  440 yh1(i) = yh1(i) - yh1(i+nyh)
8051  445 CONTINUE
8052  IF (ierpj .LT. 0 .OR. iersl .LT. 0) GO TO 680
8053  IF (abs(h) .LE. hmin*1.00001d0) GO TO 670
8054  IF (ncf .EQ. mxncf) GO TO 670
8055  rh = 0.5d0
8056  ipup = miter
8057  iredo = 1
8058  GO TO 170
8059 C-----------------------------------------------------------------------
8060 C The corrector has converged. JCUR is set to 0 to signal that the
8061 C preconditioner involved may need updating later.
8062 C The stiffness ratio STIFR is updated using the latest STIFF value.
8063 C The local error test is made and control passes to statement 500
8064 C if it fails.
8065 C-----------------------------------------------------------------------
8066  450 jcur = 0
8067  IF (newt .GT. 0) stifr = 0.5d0*(stifr + stiff)
8068  IF (m .EQ. 0) dsm = del/tesco(2,nq)
8069  IF (m .GT. 0) dsm = dvnorm(n, acor, ewt)/tesco(2,nq)
8070  IF (dsm .GT. 1.0d0) GO TO 500
8071 C-----------------------------------------------------------------------
8072 C After a successful step, update the YH array.
8073 C If Newton iteration is being done and STIFR is less than 1.5,
8074 C then switch to functional iteration.
8075 C Consider changing H if IALTH = 1. Otherwise decrease IALTH by 1.
8076 C If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
8077 C use in a possible order increase on the next step.
8078 C If a change in H is considered, an increase or decrease in order
8079 C by one is considered also. A change in H is made only if it is by a
8080 C factor of at least 1.1. If not, IALTH is set to 3 to prevent
8081 C testing for that many steps.
8082 C-----------------------------------------------------------------------
8083  kflag = 0
8084  iredo = 0
8085  nst = nst + 1
8086  IF (newt .EQ. 0) nsfi = nsfi + 1
8087  IF (newt .GT. 0 .AND. stifr .LT. 1.5d0) newt = 0
8088  hu = h
8089  nqu = nq
8090  DO 470 j = 1,l
8091  DO 470 i = 1,n
8092  470 yh(i,j) = yh(i,j) + el(j)*acor(i)
8093  ialth = ialth - 1
8094  IF (ialth .EQ. 0) GO TO 520
8095  IF (ialth .GT. 1) GO TO 700
8096  IF (l .EQ. lmax) GO TO 700
8097  DO 490 i = 1,n
8098  490 yh(i,lmax) = acor(i)
8099  GO TO 700
8100 C-----------------------------------------------------------------------
8101 C The error test failed. KFLAG keeps track of multiple failures.
8102 C Restore TN and the YH array to their previous values, and prepare
8103 C to try the step again. Compute the optimum step size for this or
8104 C one lower order. After 2 or more failures, H is forced to decrease
8105 C by a factor of 0.2 or less.
8106 C-----------------------------------------------------------------------
8107  500 kflag = kflag - 1
8108  tn = told
8109  i1 = nqnyh + 1
8110  DO 515 jb = 1,nq
8111  i1 = i1 - nyh
8112 CDIR$ IVDEP
8113  DO 510 i = i1,nqnyh
8114  510 yh1(i) = yh1(i) - yh1(i+nyh)
8115  515 CONTINUE
8116  rmax = 2.0d0
8117  IF (abs(h) .LE. hmin*1.00001d0) GO TO 660
8118  IF (kflag .LE. -3) GO TO 640
8119  iredo = 2
8120  rhup = 0.0d0
8121  GO TO 540
8122 C-----------------------------------------------------------------------
8123 C Regardless of the success or failure of the step, factors
8124 C RHDN, RHSM, and RHUP are computed, by which H could be multiplied
8125 C at order NQ - 1, order NQ, or order NQ + 1, respectively.
8126 C in the case of failure, RHUP = 0.0 to avoid an order increase.
8127 C the largest of these is determined and the new order chosen
8128 C accordingly. If the order is to be increased, we compute one
8129 C additional scaled derivative.
8130 C-----------------------------------------------------------------------
8131  520 rhup = 0.0d0
8132  IF (l .EQ. lmax) GO TO 540
8133  DO 530 i = 1,n
8134  530 savf(i) = acor(i) - yh(i,lmax)
8135  dup = dvnorm(n, savf, ewt)/tesco(3,nq)
8136  exup = 1.0d0/(l+1)
8137  rhup = 1.0d0/(1.4d0*dup**exup + 0.0000014d0)
8138  540 exsm = 1.0d0/l
8139  rhsm = 1.0d0/(1.2d0*dsm**exsm + 0.0000012d0)
8140  rhdn = 0.0d0
8141  IF (nq .EQ. 1) GO TO 560
8142  ddn = dvnorm(n, yh(1,l), ewt)/tesco(1,nq)
8143  exdn = 1.0d0/nq
8144  rhdn = 1.0d0/(1.3d0*ddn**exdn + 0.0000013d0)
8145  560 IF (rhsm .GE. rhup) GO TO 570
8146  IF (rhup .GT. rhdn) GO TO 590
8147  GO TO 580
8148  570 IF (rhsm .LT. rhdn) GO TO 580
8149  newq = nq
8150  rh = rhsm
8151  GO TO 620
8152  580 newq = nq - 1
8153  rh = rhdn
8154  IF (kflag .LT. 0 .AND. rh .GT. 1.0d0) rh = 1.0d0
8155  GO TO 620
8156  590 newq = l
8157  rh = rhup
8158  IF (rh .LT. 1.1d0) GO TO 610
8159  r = el(l)/l
8160  DO 600 i = 1,n
8161  600 yh(i,newq+1) = acor(i)*r
8162  GO TO 630
8163  610 ialth = 3
8164  GO TO 700
8165  620 IF ((kflag .EQ. 0) .AND. (rh .LT. 1.1d0)) GO TO 610
8166  IF (kflag .LE. -2) rh = min(rh,0.2d0)
8167 C-----------------------------------------------------------------------
8168 C If there is a change of order, reset NQ, L, and the coefficients.
8169 C In any case H is reset according to RH and the YH array is rescaled.
8170 C Then exit from 690 if the step was OK, or redo the step otherwise.
8171 C-----------------------------------------------------------------------
8172  IF (newq .EQ. nq) GO TO 170
8173  630 nq = newq
8174  l = nq + 1
8175  iret = 2
8176  GO TO 150
8177 C-----------------------------------------------------------------------
8178 C Control reaches this section if 3 or more failures have occured.
8179 C If 10 failures have occurred, exit with KFLAG = -1.
8180 C It is assumed that the derivatives that have accumulated in the
8181 C YH array have errors of the wrong order. Hence the first
8182 C derivative is recomputed, and the order is set to 1. Then
8183 C H is reduced by a factor of 10, and the step is retried,
8184 C until it succeeds or H reaches HMIN.
8185 C-----------------------------------------------------------------------
8186  640 IF (kflag .EQ. -10) GO TO 660
8187  rh = 0.1d0
8188  rh = max(hmin/abs(h),rh)
8189  h = h*rh
8190  DO 645 i = 1,n
8191  645 y(i) = yh(i,1)
8192  CALL f (neq, tn, y, savf)
8193  nfe = nfe + 1
8194  DO 650 i = 1,n
8195  650 yh(i,2) = h*savf(i)
8196  ipup = miter
8197  ialth = 5
8198  IF (nq .EQ. 1) GO TO 200
8199  nq = 1
8200  l = 2
8201  iret = 3
8202  GO TO 150
8203 C-----------------------------------------------------------------------
8204 C All returns are made through this section. H is saved in HOLD
8205 C to allow the caller to change H on the next step.
8206 C-----------------------------------------------------------------------
8207  660 kflag = -1
8208  GO TO 720
8209  670 kflag = -2
8210  GO TO 720
8211  680 kflag = -3
8212  GO TO 720
8213  690 rmax = 10.0d0
8214  700 r = 1.0d0/tesco(2,nqu)
8215  DO 710 i = 1,n
8216  710 acor(i) = acor(i)*r
8217  720 hold = h
8218  jstart = 1
8219  RETURN
8220 C----------------------- End of Subroutine DSTOKA ----------------------
8221  END
8222 *DECK DSETPK
8223  SUBROUTINE dsetpk (NEQ, Y, YSV, EWT, FTEM, SAVF, JOK, WM, IWM,
8224  1 F, JAC)
8225  EXTERNAL f, jac
8226  INTEGER neq, jok, iwm
8227  DOUBLE PRECISION y, ysv, ewt, ftem, savf, wm
8228  dimension neq(*), y(*), ysv(*), ewt(*), ftem(*), savf(*),
8229  1 wm(*), iwm(*)
8230  INTEGER iownd, iowns,
8231  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
8232  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
8233  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
8234  INTEGER jpre, jacflg, locwp, lociwp, lsavx, kmp, maxl, mnewt,
8235  1 nni, nli, nps, ncfn, ncfl
8236  DOUBLE PRECISION rowns,
8237  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
8238  DOUBLE PRECISION delt, epcon, sqrtn, rsqrtn
8239  COMMON /dls001/ rowns(209),
8240  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
8241  2 iownd(6), iowns(6),
8242  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
8243  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
8244  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
8245  COMMON /dlpk01/ delt, epcon, sqrtn, rsqrtn,
8246  1 jpre, jacflg, locwp, lociwp, lsavx, kmp, maxl, mnewt,
8247  2 nni, nli, nps, ncfn, ncfl
8248 C-----------------------------------------------------------------------
8249 C DSETPK is called by DSTOKA to interface with the user-supplied
8250 C routine JAC, to compute and process relevant parts of
8251 C the matrix P = I - H*EL(1)*J , where J is the Jacobian df/dy,
8252 C as need for preconditioning matrix operations later.
8253 C
8254 C In addition to variables described previously, communication
8255 C with DSETPK uses the following:
8256 C Y = array containing predicted values on entry.
8257 C YSV = array containing predicted y, to be saved (YH1 in DSTOKA).
8258 C FTEM = work array of length N (ACOR in DSTOKA).
8259 C SAVF = array containing f evaluated at predicted y.
8260 C JOK = input flag showing whether it was judged that Jacobian matrix
8261 C data need not be recomputed (JOK = 1) or needs to be
8262 C (JOK = -1).
8263 C WM = real work space for matrices.
8264 C Space for preconditioning data starts at WM(LOCWP).
8265 C IWM = integer work space.
8266 C Space for preconditioning data starts at IWM(LOCIWP).
8267 C IERPJ = output error flag, = 0 if no trouble, .gt. 0 if
8268 C JAC returned an error flag.
8269 C JCUR = output flag to indicate whether the matrix data involved
8270 C is now current (JCUR = 1) or not (JCUR = 0).
8271 C This routine also uses Common variables EL0, H, TN, IERPJ, JCUR, NJE.
8272 C-----------------------------------------------------------------------
8273  INTEGER ier
8274  DOUBLE PRECISION hl0
8275 C
8276  ierpj = 0
8277  jcur = 0
8278  IF (jok .EQ. -1) jcur = 1
8279  hl0 = el0*h
8280  CALL jac (f, neq, tn, y, ysv, ewt, savf, ftem, hl0, jok,
8281  1 wm(locwp), iwm(lociwp), ier)
8282  nje = nje + 1
8283  IF (ier .EQ. 0) RETURN
8284  ierpj = 1
8285  RETURN
8286 C----------------------- End of Subroutine DSETPK ----------------------
8287  END
8288 *DECK DSRCKR
8289  SUBROUTINE dsrckr (RSAV, ISAV, JOB)
8290 C-----------------------------------------------------------------------
8291 C This routine saves or restores (depending on JOB) the contents of
8292 C the Common blocks DLS001, DLS002, DLSR01, DLPK01, which
8293 C are used internally by the DLSODKR solver.
8294 C
8295 C RSAV = real array of length 228 or more.
8296 C ISAV = integer array of length 63 or more.
8297 C JOB = flag indicating to save or restore the Common blocks:
8298 C JOB = 1 if Common is to be saved (written to RSAV/ISAV)
8299 C JOB = 2 if Common is to be restored (read from RSAV/ISAV)
8300 C A call with JOB = 2 presumes a prior call with JOB = 1.
8301 C-----------------------------------------------------------------------
8302  INTEGER isav, job
8303  INTEGER ils, ils2, ilsr, ilsp
8304  INTEGER i, ioff, lenilp, lenrlp, lenils, lenrls, lenilr, lenrlr
8305  DOUBLE PRECISION rsav, rls, rls2, rlsr, rlsp
8306  dimension rsav(*), isav(*)
8307  SAVE lenrls, lenils, lenrlp, lenilp, lenrlr, lenilr
8308  COMMON /dls001/ rls(218), ils(37)
8309  COMMON /dls002/ rls2, ils2(4)
8310  COMMON /dlsr01/ rlsr(5), ilsr(9)
8311  COMMON /dlpk01/ rlsp(4), ilsp(13)
8312  DATA lenrls/218/, lenils/37/, lenrlp/4/, lenilp/13/
8313  DATA lenrlr/5/, lenilr/9/
8314 C
8315  IF (job .EQ. 2) GO TO 100
8316  CALL dcopy (lenrls, rls, 1, rsav, 1)
8317  rsav(lenrls+1) = rls2
8318  CALL dcopy (lenrlr, rlsr, 1, rsav(lenrls+2), 1)
8319  CALL dcopy (lenrlp, rlsp, 1, rsav(lenrls+lenrlr+2), 1)
8320  DO 20 i = 1,lenils
8321  20 isav(i) = ils(i)
8322  isav(lenils+1) = ils2(1)
8323  isav(lenils+2) = ils2(2)
8324  isav(lenils+3) = ils2(3)
8325  isav(lenils+4) = ils2(4)
8326  ioff = lenils + 2
8327  DO 30 i = 1,lenilr
8328  30 isav(ioff+i) = ilsr(i)
8329  ioff = ioff + lenilr
8330  DO 40 i = 1,lenilp
8331  40 isav(ioff+i) = ilsp(i)
8332  RETURN
8333 C
8334  100 CONTINUE
8335  CALL dcopy (lenrls, rsav, 1, rls, 1)
8336  rls2 = rsav(lenrls+1)
8337  CALL dcopy (lenrlr, rsav(lenrls+2), 1, rlsr, 1)
8338  CALL dcopy (lenrlp, rsav(lenrls+lenrlr+2), 1, rlsp, 1)
8339  DO 120 i = 1,lenils
8340  120 ils(i) = isav(i)
8341  ils2(1) = isav(lenils+1)
8342  ils2(2) = isav(lenils+2)
8343  ils2(3) = isav(lenils+3)
8344  ils2(4) = isav(lenils+4)
8345  ioff = lenils + 2
8346  DO 130 i = 1,lenilr
8347  130 ilsr(i) = isav(ioff+i)
8348  ioff = ioff + lenilr
8349  DO 140 i = 1,lenilp
8350  140 ilsp(i) = isav(ioff+i)
8351  RETURN
8352 C----------------------- End of Subroutine DSRCKR ----------------------
8353  END
8354 *DECK DAINVG
8355  SUBROUTINE dainvg (RES, ADDA, NEQ, T, Y, YDOT, MITER,
8356  1 ML, MU, PW, IPVT, IER )
8357  EXTERNAL res, adda
8358  INTEGER neq, miter, ml, mu, ipvt, ier
8359  INTEGER i, lenpw, mlp1, nrowpw
8360  DOUBLE PRECISION t, y, ydot, pw
8361  dimension y(*), ydot(*), pw(*), ipvt(*)
8362 C-----------------------------------------------------------------------
8363 C This subroutine computes the initial value
8364 C of the vector YDOT satisfying
8365 C A * YDOT = g(t,y)
8366 C when A is nonsingular. It is called by DLSODI for
8367 C initialization only, when ISTATE = 0 .
8368 C DAINVG returns an error flag IER:
8369 C IER = 0 means DAINVG was successful.
8370 C IER .ge. 2 means RES returned an error flag IRES = IER.
8371 C IER .lt. 0 means the a-matrix was found to be singular.
8372 C-----------------------------------------------------------------------
8373 C
8374  IF (miter .GE. 4) GO TO 100
8375 C
8376 C Full matrix case -----------------------------------------------------
8377 C
8378  lenpw = neq*neq
8379  DO 10 i = 1, lenpw
8380  10 pw(i) = 0.0d0
8381 C
8382  ier = 1
8383  CALL res ( neq, t, y, pw, ydot, ier )
8384  IF (ier .GT. 1) RETURN
8385 C
8386  CALL adda ( neq, t, y, 0, 0, pw, neq )
8387  CALL dgefa ( pw, neq, neq, ipvt, ier )
8388  IF (ier .EQ. 0) GO TO 20
8389  ier = -ier
8390  RETURN
8391  20 CALL dgesl ( pw, neq, neq, ipvt, ydot, 0 )
8392  RETURN
8393 C
8394 C Band matrix case -----------------------------------------------------
8395 C
8396  100 CONTINUE
8397  nrowpw = 2*ml + mu + 1
8398  lenpw = neq * nrowpw
8399  DO 110 i = 1, lenpw
8400  110 pw(i) = 0.0d0
8401 C
8402  ier = 1
8403  CALL res ( neq, t, y, pw, ydot, ier )
8404  IF (ier .GT. 1) RETURN
8405 C
8406  mlp1 = ml + 1
8407  CALL adda ( neq, t, y, ml, mu, pw(mlp1), nrowpw )
8408  CALL dgbfa ( pw, nrowpw, neq, ml, mu, ipvt, ier )
8409  IF (ier .EQ. 0) GO TO 120
8410  ier = -ier
8411  RETURN
8412  120 CALL dgbsl ( pw, nrowpw, neq, ml, mu, ipvt, ydot, 0 )
8413  RETURN
8414 C----------------------- End of Subroutine DAINVG ----------------------
8415  END
8416 *DECK DSTODI
8417  SUBROUTINE dstodi (NEQ, Y, YH, NYH, YH1, EWT, SAVF, SAVR,
8418  1 ACOR, WM, IWM, RES, ADDA, JAC, PJAC, SLVS )
8419  EXTERNAL res, adda, jac, pjac, slvs
8420  INTEGER neq, nyh, iwm
8421  DOUBLE PRECISION y, yh, yh1, ewt, savf, savr, acor, wm
8422  dimension neq(*), y(*), yh(nyh,*), yh1(*), ewt(*), savf(*),
8423  1 savr(*), acor(*), wm(*), iwm(*)
8424  INTEGER iownd, ialth, ipup, lmax, meo, nqnyh, nslp,
8425  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
8426  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
8427  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
8428  DOUBLE PRECISION conit, crate, el, elco, hold, rmax, tesco,
8429  2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
8430  COMMON /dls001/ conit, crate, el(13), elco(13,12),
8431  1 hold, rmax, tesco(3,12),
8432  2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
8433  3 iownd(6), ialth, ipup, lmax, meo, nqnyh, nslp,
8434  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
8435  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
8436  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
8437  INTEGER i, i1, iredo, ires, iret, j, jb, kgo, m, ncf, newq
8438  DOUBLE PRECISION dcon, ddn, del, delp, dsm, dup,
8439  1 eljh, el1h, exdn, exsm, exup,
8440  2 r, rh, rhdn, rhsm, rhup, told, dvnorm
8441 C-----------------------------------------------------------------------
8442 C DSTODI performs one step of the integration of an initial value
8443 C problem for a system of Ordinary Differential Equations.
8444 C Note: DSTODI is independent of the value of the iteration method
8445 C indicator MITER, and hence is independent
8446 C of the type of chord method used, or the Jacobian structure.
8447 C Communication with DSTODI is done with the following variables:
8448 C
8449 C NEQ = integer array containing problem size in NEQ(1), and
8450 C passed as the NEQ argument in all calls to RES, ADDA,
8451 C and JAC.
8452 C Y = an array of length .ge. N used as the Y argument in
8453 C all calls to RES, JAC, and ADDA.
8454 C NEQ = integer array containing problem size in NEQ(1), and
8455 C passed as the NEQ argument in all calls tO RES, G, ADDA,
8456 C and JAC.
8457 C YH = an NYH by LMAX array containing the dependent variables
8458 C and their approximate scaled derivatives, where
8459 C LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
8460 C j-th derivative of y(i), scaled by H**j/factorial(j)
8461 C (j = 0,1,...,NQ). On entry for the first step, the first
8462 C two columns of YH must be set from the initial values.
8463 C NYH = a constant integer .ge. N, the first dimension of YH.
8464 C YH1 = a one-dimensional array occupying the same space as YH.
8465 C EWT = an array of length N containing multiplicative weights
8466 C for local error measurements. Local errors in y(i) are
8467 C compared to 1.0/EWT(i) in various error tests.
8468 C SAVF = an array of working storage, of length N. also used for
8469 C input of YH(*,MAXORD+2) when JSTART = -1 and MAXORD is less
8470 C than the current order NQ.
8471 C Same as YDOTI in the driver.
8472 C SAVR = an array of working storage, of length N.
8473 C ACOR = a work array of length N used for the accumulated
8474 C corrections. On a succesful return, ACOR(i) contains
8475 C the estimated one-step local error in y(i).
8476 C WM,IWM = real and integer work arrays associated with matrix
8477 C operations in chord iteration.
8478 C PJAC = name of routine to evaluate and preprocess Jacobian matrix.
8479 C SLVS = name of routine to solve linear system in chord iteration.
8480 C CCMAX = maximum relative change in H*EL0 before PJAC is called.
8481 C H = the step size to be attempted on the next step.
8482 C H is altered by the error control algorithm during the
8483 C problem. H can be either positive or negative, but its
8484 C sign must remain constant throughout the problem.
8485 C HMIN = the minimum absolute value of the step size H to be used.
8486 C HMXI = inverse of the maximum absolute value of H to be used.
8487 C HMXI = 0.0 is allowed and corresponds to an infinite HMAX.
8488 C HMIN and HMXI may be changed at any time, but will not
8489 C take effect until the next change of H is considered.
8490 C TN = the independent variable. TN is updated on each step taken.
8491 C JSTART = an integer used for input only, with the following
8492 C values and meanings:
8493 C 0 perform the first step.
8494 C .gt.0 take a new step continuing from the last.
8495 C -1 take the next step with a new value of H, MAXORD,
8496 C N, METH, MITER, and/or matrix parameters.
8497 C -2 take the next step with a new value of H,
8498 C but with other inputs unchanged.
8499 C On return, JSTART is set to 1 to facilitate continuation.
8500 C KFLAG = a completion code with the following meanings:
8501 C 0 the step was succesful.
8502 C -1 the requested error could not be achieved.
8503 C -2 corrector convergence could not be achieved.
8504 C -3 RES ordered immediate return.
8505 C -4 error condition from RES could not be avoided.
8506 C -5 fatal error in PJAC or SLVS.
8507 C A return with KFLAG = -1, -2, or -4 means either
8508 C ABS(H) = HMIN or 10 consecutive failures occurred.
8509 C On a return with KFLAG negative, the values of TN and
8510 C the YH array are as of the beginning of the last
8511 C step, and H is the last step size attempted.
8512 C MAXORD = the maximum order of integration method to be allowed.
8513 C MAXCOR = the maximum number of corrector iterations allowed.
8514 C MSBP = maximum number of steps between PJAC calls.
8515 C MXNCF = maximum number of convergence failures allowed.
8516 C METH/MITER = the method flags. See description in driver.
8517 C N = the number of first-order differential equations.
8518 C-----------------------------------------------------------------------
8519  kflag = 0
8520  told = tn
8521  ncf = 0
8522  ierpj = 0
8523  iersl = 0
8524  jcur = 0
8525  icf = 0
8526  delp = 0.0d0
8527  IF (jstart .GT. 0) GO TO 200
8528  IF (jstart .EQ. -1) GO TO 100
8529  IF (jstart .EQ. -2) GO TO 160
8530 C-----------------------------------------------------------------------
8531 C On the first call, the order is set to 1, and other variables are
8532 C initialized. RMAX is the maximum ratio by which H can be increased
8533 C in a single step. It is initially 1.E4 to compensate for the small
8534 C initial H, but then is normally equal to 10. If a failure
8535 C occurs (in corrector convergence or error test), RMAX is set at 2
8536 C for the next increase.
8537 C-----------------------------------------------------------------------
8538  lmax = maxord + 1
8539  nq = 1
8540  l = 2
8541  ialth = 2
8542  rmax = 10000.0d0
8543  rc = 0.0d0
8544  el0 = 1.0d0
8545  crate = 0.7d0
8546  hold = h
8547  meo = meth
8548  nslp = 0
8549  ipup = miter
8550  iret = 3
8551  GO TO 140
8552 C-----------------------------------------------------------------------
8553 C The following block handles preliminaries needed when JSTART = -1.
8554 C IPUP is set to MITER to force a matrix update.
8555 C If an order increase is about to be considered (IALTH = 1),
8556 C IALTH is reset to 2 to postpone consideration one more step.
8557 C If the caller has changed METH, DCFODE is called to reset
8558 C the coefficients of the method.
8559 C If the caller has changed MAXORD to a value less than the current
8560 C order NQ, NQ is reduced to MAXORD, and a new H chosen accordingly.
8561 C If H is to be changed, YH must be rescaled.
8562 C If H or METH is being changed, IALTH is reset to L = NQ + 1
8563 C to prevent further changes in H for that many steps.
8564 C-----------------------------------------------------------------------
8565  100 ipup = miter
8566  lmax = maxord + 1
8567  IF (ialth .EQ. 1) ialth = 2
8568  IF (meth .EQ. meo) GO TO 110
8569  CALL dcfode (meth, elco, tesco)
8570  meo = meth
8571  IF (nq .GT. maxord) GO TO 120
8572  ialth = l
8573  iret = 1
8574  GO TO 150
8575  110 IF (nq .LE. maxord) GO TO 160
8576  120 nq = maxord
8577  l = lmax
8578  DO 125 i = 1,l
8579  125 el(i) = elco(i,nq)
8580  nqnyh = nq*nyh
8581  rc = rc*el(1)/el0
8582  el0 = el(1)
8583  conit = 0.5d0/(nq+2)
8584  ddn = dvnorm(n, savf, ewt)/tesco(1,l)
8585  exdn = 1.0d0/l
8586  rhdn = 1.0d0/(1.3d0*ddn**exdn + 0.0000013d0)
8587  rh = min(rhdn,1.0d0)
8588  iredo = 3
8589  IF (h .EQ. hold) GO TO 170
8590  rh = min(rh,abs(h/hold))
8591  h = hold
8592  GO TO 175
8593 C-----------------------------------------------------------------------
8594 C DCFODE is called to get all the integration coefficients for the
8595 C current METH. Then the EL vector and related constants are reset
8596 C whenever the order NQ is changed, or at the start of the problem.
8597 C-----------------------------------------------------------------------
8598  140 CALL dcfode (meth, elco, tesco)
8599  150 DO 155 i = 1,l
8600  155 el(i) = elco(i,nq)
8601  nqnyh = nq*nyh
8602  rc = rc*el(1)/el0
8603  el0 = el(1)
8604  conit = 0.5d0/(nq+2)
8605  GO TO (160, 170, 200), iret
8606 C-----------------------------------------------------------------------
8607 C If H is being changed, the H ratio RH is checked against
8608 C RMAX, HMIN, and HMXI, and the YH array rescaled. IALTH is set to
8609 C L = NQ + 1 to prevent a change of H for that many steps, unless
8610 C forced by a convergence or error test failure.
8611 C-----------------------------------------------------------------------
8612  160 IF (h .EQ. hold) GO TO 200
8613  rh = h/hold
8614  h = hold
8615  iredo = 3
8616  GO TO 175
8617  170 rh = max(rh,hmin/abs(h))
8618  175 rh = min(rh,rmax)
8619  rh = rh/max(1.0d0,abs(h)*hmxi*rh)
8620  r = 1.0d0
8621  DO 180 j = 2,l
8622  r = r*rh
8623  DO 180 i = 1,n
8624  180 yh(i,j) = yh(i,j)*r
8625  h = h*rh
8626  rc = rc*rh
8627  ialth = l
8628  IF (iredo .EQ. 0) GO TO 690
8629 C-----------------------------------------------------------------------
8630 C This section computes the predicted values by effectively
8631 C multiplying the YH array by the Pascal triangle matrix.
8632 C RC is the ratio of new to old values of the coefficient H*EL(1).
8633 C When RC differs from 1 by more than CCMAX, IPUP is set to MITER
8634 C to force PJAC to be called.
8635 C In any case, PJAC is called at least every MSBP steps.
8636 C-----------------------------------------------------------------------
8637  200 IF (abs(rc-1.0d0) .GT. ccmax) ipup = miter
8638  IF (nst .GE. nslp+msbp) ipup = miter
8639  tn = tn + h
8640  i1 = nqnyh + 1
8641  DO 215 jb = 1,nq
8642  i1 = i1 - nyh
8643 CDIR$ IVDEP
8644  DO 210 i = i1,nqnyh
8645  210 yh1(i) = yh1(i) + yh1(i+nyh)
8646  215 CONTINUE
8647 C-----------------------------------------------------------------------
8648 C Up to MAXCOR corrector iterations are taken. A convergence test is
8649 C made on the RMS-norm of each correction, weighted by H and the
8650 C error weight vector EWT. The sum of the corrections is accumulated
8651 C in ACOR(i). The YH array is not altered in the corrector loop.
8652 C-----------------------------------------------------------------------
8653  220 m = 0
8654  DO 230 i = 1,n
8655  savf(i) = yh(i,2) / h
8656  230 y(i) = yh(i,1)
8657  IF (ipup .LE. 0) GO TO 240
8658 C-----------------------------------------------------------------------
8659 C If indicated, the matrix P = A - H*EL(1)*dr/dy is reevaluated and
8660 C preprocessed before starting the corrector iteration. IPUP is set
8661 C to 0 as an indicator that this has been done.
8662 C-----------------------------------------------------------------------
8663  CALL pjac (neq, y, yh, nyh, ewt, acor, savr, savf, wm, iwm,
8664  1 res, jac, adda )
8665  ipup = 0
8666  rc = 1.0d0
8667  nslp = nst
8668  crate = 0.7d0
8669  IF (ierpj .EQ. 0) GO TO 250
8670  IF (ierpj .LT. 0) GO TO 435
8671  ires = ierpj
8672  GO TO (430, 435, 430), ires
8673 C Get residual at predicted values, if not already done in PJAC. -------
8674  240 ires = 1
8675  CALL res ( neq, tn, y, savf, savr, ires )
8676  nfe = nfe + 1
8677  kgo = abs(ires)
8678  GO TO ( 250, 435, 430 ) , kgo
8679  250 DO 260 i = 1,n
8680  260 acor(i) = 0.0d0
8681 C-----------------------------------------------------------------------
8682 C Solve the linear system with the current residual as
8683 C right-hand side and P as coefficient matrix.
8684 C-----------------------------------------------------------------------
8685  270 CONTINUE
8686  CALL slvs (wm, iwm, savr, savf)
8687  IF (iersl .LT. 0) GO TO 430
8688  IF (iersl .GT. 0) GO TO 410
8689  el1h = el(1) * h
8690  del = dvnorm(n, savr, ewt) * abs(h)
8691  DO 380 i = 1,n
8692  acor(i) = acor(i) + savr(i)
8693  savf(i) = acor(i) + yh(i,2)/h
8694  380 y(i) = yh(i,1) + el1h*acor(i)
8695 C-----------------------------------------------------------------------
8696 C Test for convergence. If M .gt. 0, an estimate of the convergence
8697 C rate constant is stored in CRATE, and this is used in the test.
8698 C-----------------------------------------------------------------------
8699  IF (m .NE. 0) crate = max(0.2d0*crate,del/delp)
8700  dcon = del*min(1.0d0,1.5d0*crate)/(tesco(2,nq)*conit)
8701  IF (dcon .LE. 1.0d0) GO TO 460
8702  m = m + 1
8703  IF (m .EQ. maxcor) GO TO 410
8704  IF (m .GE. 2 .AND. del .GT. 2.0d0*delp) GO TO 410
8705  delp = del
8706  ires = 1
8707  CALL res ( neq, tn, y, savf, savr, ires )
8708  nfe = nfe + 1
8709  kgo = abs(ires)
8710  GO TO ( 270, 435, 410 ) , kgo
8711 C-----------------------------------------------------------------------
8712 C The correctors failed to converge, or RES has returned abnormally.
8713 C on a convergence failure, if the Jacobian is out of date, PJAC is
8714 C called for the next try. Otherwise the YH array is retracted to its
8715 C values before prediction, and H is reduced, if possible.
8716 C take an error exit if IRES = 2, or H cannot be reduced, or MXNCF
8717 C failures have occurred, or a fatal error occurred in PJAC or SLVS.
8718 C-----------------------------------------------------------------------
8719  410 icf = 1
8720  IF (jcur .EQ. 1) GO TO 430
8721  ipup = miter
8722  GO TO 220
8723  430 icf = 2
8724  ncf = ncf + 1
8725  rmax = 2.0d0
8726  435 tn = told
8727  i1 = nqnyh + 1
8728  DO 445 jb = 1,nq
8729  i1 = i1 - nyh
8730 CDIR$ IVDEP
8731  DO 440 i = i1,nqnyh
8732  440 yh1(i) = yh1(i) - yh1(i+nyh)
8733  445 CONTINUE
8734  IF (ires .EQ. 2) GO TO 680
8735  IF (ierpj .LT. 0 .OR. iersl .LT. 0) GO TO 685
8736  IF (abs(h) .LE. hmin*1.00001d0) GO TO 450
8737  IF (ncf .EQ. mxncf) GO TO 450
8738  rh = 0.25d0
8739  ipup = miter
8740  iredo = 1
8741  GO TO 170
8742  450 IF (ires .EQ. 3) GO TO 680
8743  GO TO 670
8744 C-----------------------------------------------------------------------
8745 C The corrector has converged. JCUR is set to 0
8746 C to signal that the Jacobian involved may need updating later.
8747 C The local error test is made and control passes to statement 500
8748 C if it fails.
8749 C-----------------------------------------------------------------------
8750  460 jcur = 0
8751  IF (m .EQ. 0) dsm = del/tesco(2,nq)
8752  IF (m .GT. 0) dsm = abs(h) * dvnorm(n, acor, ewt)/tesco(2,nq)
8753  IF (dsm .GT. 1.0d0) GO TO 500
8754 C-----------------------------------------------------------------------
8755 C After a successful step, update the YH array.
8756 C Consider changing H if IALTH = 1. Otherwise decrease IALTH by 1.
8757 C If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
8758 C use in a possible order increase on the next step.
8759 C If a change in H is considered, an increase or decrease in order
8760 C by one is considered also. A change in H is made only if it is by a
8761 C factor of at least 1.1. If not, IALTH is set to 3 to prevent
8762 C testing for that many steps.
8763 C-----------------------------------------------------------------------
8764  kflag = 0
8765  iredo = 0
8766  nst = nst + 1
8767  hu = h
8768  nqu = nq
8769  DO 470 j = 1,l
8770  eljh = el(j)*h
8771  DO 470 i = 1,n
8772  470 yh(i,j) = yh(i,j) + eljh*acor(i)
8773  ialth = ialth - 1
8774  IF (ialth .EQ. 0) GO TO 520
8775  IF (ialth .GT. 1) GO TO 700
8776  IF (l .EQ. lmax) GO TO 700
8777  DO 490 i = 1,n
8778  490 yh(i,lmax) = acor(i)
8779  GO TO 700
8780 C-----------------------------------------------------------------------
8781 C The error test failed. KFLAG keeps track of multiple failures.
8782 C restore TN and the YH array to their previous values, and prepare
8783 C to try the step again. Compute the optimum step size for this or
8784 C one lower order. After 2 or more failures, H is forced to decrease
8785 C by a factor of 0.1 or less.
8786 C-----------------------------------------------------------------------
8787  500 kflag = kflag - 1
8788  tn = told
8789  i1 = nqnyh + 1
8790  DO 515 jb = 1,nq
8791  i1 = i1 - nyh
8792 CDIR$ IVDEP
8793  DO 510 i = i1,nqnyh
8794  510 yh1(i) = yh1(i) - yh1(i+nyh)
8795  515 CONTINUE
8796  rmax = 2.0d0
8797  IF (abs(h) .LE. hmin*1.00001d0) GO TO 660
8798  IF (kflag .LE. -7) GO TO 660
8799  iredo = 2
8800  rhup = 0.0d0
8801  GO TO 540
8802 C-----------------------------------------------------------------------
8803 C Regardless of the success or failure of the step, factors
8804 C RHDN, RHSM, and RHUP are computed, by which H could be multiplied
8805 C at order NQ - 1, order NQ, or order NQ + 1, respectively.
8806 C In the case of failure, RHUP = 0.0 to avoid an order increase.
8807 C The largest of these is determined and the new order chosen
8808 C accordingly. If the order is to be increased, we compute one
8809 C additional scaled derivative.
8810 C-----------------------------------------------------------------------
8811  520 rhup = 0.0d0
8812  IF (l .EQ. lmax) GO TO 540
8813  DO 530 i = 1,n
8814  530 savf(i) = acor(i) - yh(i,lmax)
8815  dup = abs(h) * dvnorm(n, savf, ewt)/tesco(3,nq)
8816  exup = 1.0d0/(l+1)
8817  rhup = 1.0d0/(1.4d0*dup**exup + 0.0000014d0)
8818  540 exsm = 1.0d0/l
8819  rhsm = 1.0d0/(1.2d0*dsm**exsm + 0.0000012d0)
8820  rhdn = 0.0d0
8821  IF (nq .EQ. 1) GO TO 560
8822  ddn = dvnorm(n, yh(1,l), ewt)/tesco(1,nq)
8823  exdn = 1.0d0/nq
8824  rhdn = 1.0d0/(1.3d0*ddn**exdn + 0.0000013d0)
8825  560 IF (rhsm .GE. rhup) GO TO 570
8826  IF (rhup .GT. rhdn) GO TO 590
8827  GO TO 580
8828  570 IF (rhsm .LT. rhdn) GO TO 580
8829  newq = nq
8830  rh = rhsm
8831  GO TO 620
8832  580 newq = nq - 1
8833  rh = rhdn
8834  IF (kflag .LT. 0 .AND. rh .GT. 1.0d0) rh = 1.0d0
8835  GO TO 620
8836  590 newq = l
8837  rh = rhup
8838  IF (rh .LT. 1.1d0) GO TO 610
8839  r = h*el(l)/l
8840  DO 600 i = 1,n
8841  600 yh(i,newq+1) = acor(i)*r
8842  GO TO 630
8843  610 ialth = 3
8844  GO TO 700
8845  620 IF ((kflag .EQ. 0) .AND. (rh .LT. 1.1d0)) GO TO 610
8846  IF (kflag .LE. -2) rh = min(rh,0.1d0)
8847 C-----------------------------------------------------------------------
8848 C If there is a change of order, reset NQ, L, and the coefficients.
8849 C In any case H is reset according to RH and the YH array is rescaled.
8850 C Then exit from 690 if the step was OK, or redo the step otherwise.
8851 C-----------------------------------------------------------------------
8852  IF (newq .EQ. nq) GO TO 170
8853  630 nq = newq
8854  l = nq + 1
8855  iret = 2
8856  GO TO 150
8857 C-----------------------------------------------------------------------
8858 C All returns are made through this section. H is saved in HOLD
8859 C to allow the caller to change H on the next step.
8860 C-----------------------------------------------------------------------
8861  660 kflag = -1
8862  GO TO 720
8863  670 kflag = -2
8864  GO TO 720
8865  680 kflag = -1 - ires
8866  GO TO 720
8867  685 kflag = -5
8868  GO TO 720
8869  690 rmax = 10.0d0
8870  700 r = h/tesco(2,nqu)
8871  DO 710 i = 1,n
8872  710 acor(i) = acor(i)*r
8873  720 hold = h
8874  jstart = 1
8875  RETURN
8876 C----------------------- End of Subroutine DSTODI ----------------------
8877  END
8878 *DECK DPREPJI
8879  SUBROUTINE dprepji (NEQ, Y, YH, NYH, EWT, RTEM, SAVR, S, WM, IWM,
8880  1 RES, JAC, ADDA)
8881  EXTERNAL res, jac, adda
8882  INTEGER neq, nyh, iwm
8883  DOUBLE PRECISION y, yh, ewt, rtem, savr, s, wm
8884  dimension neq(*), y(*), yh(nyh,*), ewt(*), rtem(*),
8885  1 s(*), savr(*), wm(*), iwm(*)
8886  INTEGER iownd, iowns,
8887  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
8888  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
8889  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
8890  DOUBLE PRECISION rowns,
8891  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
8892  COMMON /dls001/ rowns(209),
8893  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
8894  2 iownd(6), iowns(6),
8895  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
8896  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
8897  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
8898  INTEGER i, i1, i2, ier, ii, ires, j, j1, jj, lenp,
8899  1 mba, mband, meb1, meband, ml, ml3, mu
8900  DOUBLE PRECISION con, fac, hl0, r, srur, yi, yj, yjj
8901 C-----------------------------------------------------------------------
8902 C DPREPJI is called by DSTODI to compute and process the matrix
8903 C P = A - H*EL(1)*J , where J is an approximation to the Jacobian dr/dy,
8904 C where r = g(t,y) - A(t,y)*s. Here J is computed by the user-supplied
8905 C routine JAC if MITER = 1 or 4, or by finite differencing if MITER =
8906 C 2 or 5. J is stored in WM, rescaled, and ADDA is called to generate
8907 C P. P is then subjected to LU decomposition in preparation
8908 C for later solution of linear systems with P as coefficient
8909 C matrix. This is done by DGEFA if MITER = 1 or 2, and by
8910 C DGBFA if MITER = 4 or 5.
8911 C
8912 C In addition to variables described previously, communication
8913 C with DPREPJI uses the following:
8914 C Y = array containing predicted values on entry.
8915 C RTEM = work array of length N (ACOR in DSTODI).
8916 C SAVR = array used for output only. On output it contains the
8917 C residual evaluated at current values of t and y.
8918 C S = array containing predicted values of dy/dt (SAVF in DSTODI).
8919 C WM = real work space for matrices. On output it contains the
8920 C LU decomposition of P.
8921 C Storage of matrix elements starts at WM(3).
8922 C WM also contains the following matrix-related data:
8923 C WM(1) = SQRT(UROUND), used in numerical Jacobian increments.
8924 C IWM = integer work space containing pivot information, starting at
8925 C IWM(21). IWM also contains the band parameters
8926 C ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
8927 C EL0 = el(1) (input).
8928 C IERPJ = output error flag.
8929 C = 0 if no trouble occurred,
8930 C = 1 if the P matrix was found to be singular,
8931 C = IRES (= 2 or 3) if RES returned IRES = 2 or 3.
8932 C JCUR = output flag = 1 to indicate that the Jacobian matrix
8933 C (or approximation) is now current.
8934 C This routine also uses the Common variables EL0, H, TN, UROUND,
8935 C MITER, N, NFE, and NJE.
8936 C-----------------------------------------------------------------------
8937  nje = nje + 1
8938  hl0 = h*el0
8939  ierpj = 0
8940  jcur = 1
8941  GO TO (100, 200, 300, 400, 500), miter
8942 C If MITER = 1, call RES, then JAC, and multiply by scalar. ------------
8943  100 ires = 1
8944  CALL res (neq, tn, y, s, savr, ires)
8945  nfe = nfe + 1
8946  IF (ires .GT. 1) GO TO 600
8947  lenp = n*n
8948  DO 110 i = 1,lenp
8949  110 wm(i+2) = 0.0d0
8950  CALL jac ( neq, tn, y, s, 0, 0, wm(3), n )
8951  con = -hl0
8952  DO 120 i = 1,lenp
8953  120 wm(i+2) = wm(i+2)*con
8954  GO TO 240
8955 C If MITER = 2, make N + 1 calls to RES to approximate J. --------------
8956  200 CONTINUE
8957  ires = -1
8958  CALL res (neq, tn, y, s, savr, ires)
8959  nfe = nfe + 1
8960  IF (ires .GT. 1) GO TO 600
8961  srur = wm(1)
8962  j1 = 2
8963  DO 230 j = 1,n
8964  yj = y(j)
8965  r = max(srur*abs(yj),0.01d0/ewt(j))
8966  y(j) = y(j) + r
8967  fac = -hl0/r
8968  CALL res ( neq, tn, y, s, rtem, ires )
8969  nfe = nfe + 1
8970  IF (ires .GT. 1) GO TO 600
8971  DO 220 i = 1,n
8972  220 wm(i+j1) = (rtem(i) - savr(i))*fac
8973  y(j) = yj
8974  j1 = j1 + n
8975  230 CONTINUE
8976  ires = 1
8977  CALL res (neq, tn, y, s, savr, ires)
8978  nfe = nfe + 1
8979  IF (ires .GT. 1) GO TO 600
8980 C Add matrix A. --------------------------------------------------------
8981  240 CONTINUE
8982  CALL adda(neq, tn, y, 0, 0, wm(3), n)
8983 C Do LU decomposition on P. --------------------------------------------
8984  CALL dgefa (wm(3), n, n, iwm(21), ier)
8985  IF (ier .NE. 0) ierpj = 1
8986  RETURN
8987 C Dummy section for MITER = 3
8988  300 RETURN
8989 C If MITER = 4, call RES, then JAC, and multiply by scalar. ------------
8990  400 ires = 1
8991  CALL res (neq, tn, y, s, savr, ires)
8992  nfe = nfe + 1
8993  IF (ires .GT. 1) GO TO 600
8994  ml = iwm(1)
8995  mu = iwm(2)
8996  ml3 = ml + 3
8997  mband = ml + mu + 1
8998  meband = mband + ml
8999  lenp = meband*n
9000  DO 410 i = 1,lenp
9001  410 wm(i+2) = 0.0d0
9002  CALL jac ( neq, tn, y, s, ml, mu, wm(ml3), meband)
9003  con = -hl0
9004  DO 420 i = 1,lenp
9005  420 wm(i+2) = wm(i+2)*con
9006  GO TO 570
9007 C If MITER = 5, make ML + MU + 2 calls to RES to approximate J. --------
9008  500 CONTINUE
9009  ires = -1
9010  CALL res (neq, tn, y, s, savr, ires)
9011  nfe = nfe + 1
9012  IF (ires .GT. 1) GO TO 600
9013  ml = iwm(1)
9014  mu = iwm(2)
9015  ml3 = ml + 3
9016  mband = ml + mu + 1
9017  mba = min(mband,n)
9018  meband = mband + ml
9019  meb1 = meband - 1
9020  srur = wm(1)
9021  DO 560 j = 1,mba
9022  DO 530 i = j,n,mband
9023  yi = y(i)
9024  r = max(srur*abs(yi),0.01d0/ewt(i))
9025  530 y(i) = y(i) + r
9026  CALL res ( neq, tn, y, s, rtem, ires)
9027  nfe = nfe + 1
9028  IF (ires .GT. 1) GO TO 600
9029  DO 550 jj = j,n,mband
9030  y(jj) = yh(jj,1)
9031  yjj = y(jj)
9032  r = max(srur*abs(yjj),0.01d0/ewt(jj))
9033  fac = -hl0/r
9034  i1 = max(jj-mu,1)
9035  i2 = min(jj+ml,n)
9036  ii = jj*meb1 - ml + 2
9037  DO 540 i = i1,i2
9038  540 wm(ii+i) = (rtem(i) - savr(i))*fac
9039  550 CONTINUE
9040  560 CONTINUE
9041  ires = 1
9042  CALL res (neq, tn, y, s, savr, ires)
9043  nfe = nfe + 1
9044  IF (ires .GT. 1) GO TO 600
9045 C Add matrix A. --------------------------------------------------------
9046  570 CONTINUE
9047  CALL adda(neq, tn, y, ml, mu, wm(ml3), meband)
9048 C Do LU decomposition of P. --------------------------------------------
9049  CALL dgbfa (wm(3), meband, n, ml, mu, iwm(21), ier)
9050  IF (ier .NE. 0) ierpj = 1
9051  RETURN
9052 C Error return for IRES = 2 or IRES = 3 return from RES. ---------------
9053  600 ierpj = ires
9054  RETURN
9055 C----------------------- End of Subroutine DPREPJI ---------------------
9056  END
9057 *DECK DAIGBT
9058  SUBROUTINE daigbt (RES, ADDA, NEQ, T, Y, YDOT,
9059  1 MB, NB, PW, IPVT, IER )
9060  EXTERNAL res, adda
9061  INTEGER neq, mb, nb, ipvt, ier
9062  INTEGER i, lenpw, lblox, lpb, lpc
9063  DOUBLE PRECISION t, y, ydot, pw
9064  dimension y(*), ydot(*), pw(*), ipvt(*), neq(*)
9065 C-----------------------------------------------------------------------
9066 C This subroutine computes the initial value
9067 C of the vector YDOT satisfying
9068 C A * YDOT = g(t,y)
9069 C when A is nonsingular. It is called by DLSOIBT for
9070 C initialization only, when ISTATE = 0 .
9071 C DAIGBT returns an error flag IER:
9072 C IER = 0 means DAIGBT was successful.
9073 C IER .ge. 2 means RES returned an error flag IRES = IER.
9074 C IER .lt. 0 means the A matrix was found to have a singular
9075 C diagonal block (hence YDOT could not be solved for).
9076 C-----------------------------------------------------------------------
9077  lblox = mb*mb*nb
9078  lpb = 1 + lblox
9079  lpc = lpb + lblox
9080  lenpw = 3*lblox
9081  DO 10 i = 1,lenpw
9082  10 pw(i) = 0.0d0
9083  ier = 1
9084  CALL res (neq, t, y, pw, ydot, ier)
9085  IF (ier .GT. 1) RETURN
9086  CALL adda (neq, t, y, mb, nb, pw(1), pw(lpb), pw(lpc) )
9087  CALL ddecbt (mb, nb, pw, pw(lpb), pw(lpc), ipvt, ier)
9088  IF (ier .EQ. 0) GO TO 20
9089  ier = -ier
9090  RETURN
9091  20 CALL dsolbt (mb, nb, pw, pw(lpb), pw(lpc), ydot, ipvt)
9092  RETURN
9093 C----------------------- End of Subroutine DAIGBT ----------------------
9094  END
9095 *DECK DPJIBT
9096  SUBROUTINE dpjibt (NEQ, Y, YH, NYH, EWT, RTEM, SAVR, S, WM, IWM,
9097  1 RES, JAC, ADDA)
9098  EXTERNAL res, jac, adda
9099  INTEGER neq, nyh, iwm
9100  DOUBLE PRECISION y, yh, ewt, rtem, savr, s, wm
9101  dimension neq(*), y(*), yh(nyh,*), ewt(*), rtem(*),
9102  1 s(*), savr(*), wm(*), iwm(*)
9103  INTEGER iownd, iowns,
9104  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
9105  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
9106  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
9107  DOUBLE PRECISION rowns,
9108  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
9109  COMMON /dls001/ rowns(209),
9110  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
9111  2 iownd(6), iowns(6),
9112  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
9113  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
9114  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
9115  INTEGER i, ier, iia, iib, iic, ipa, ipb, ipc, ires, j, j1, j2,
9116  1 k, k1, lenp, lblox, lpb, lpc, mb, mbsq, mwid, nb
9117  DOUBLE PRECISION con, fac, hl0, r, srur
9118 C-----------------------------------------------------------------------
9119 C DPJIBT is called by DSTODI to compute and process the matrix
9120 C P = A - H*EL(1)*J , where J is an approximation to the Jacobian dr/dy,
9121 C and r = g(t,y) - A(t,y)*s. Here J is computed by the user-supplied
9122 C routine JAC if MITER = 1, or by finite differencing if MITER = 2.
9123 C J is stored in WM, rescaled, and ADDA is called to generate P.
9124 C P is then subjected to LU decomposition by DDECBT in preparation
9125 C for later solution of linear systems with P as coefficient matrix.
9126 C
9127 C In addition to variables described previously, communication
9128 C with DPJIBT uses the following:
9129 C Y = array containing predicted values on entry.
9130 C RTEM = work array of length N (ACOR in DSTODI).
9131 C SAVR = array used for output only. On output it contains the
9132 C residual evaluated at current values of t and y.
9133 C S = array containing predicted values of dy/dt (SAVF in DSTODI).
9134 C WM = real work space for matrices. On output it contains the
9135 C LU decomposition of P.
9136 C Storage of matrix elements starts at WM(3).
9137 C WM also contains the following matrix-related data:
9138 C WM(1) = SQRT(UROUND), used in numerical Jacobian increments.
9139 C IWM = integer work space containing pivot information, starting at
9140 C IWM(21). IWM also contains block structure parameters
9141 C MB = IWM(1) and NB = IWM(2).
9142 C EL0 = EL(1) (input).
9143 C IERPJ = output error flag.
9144 C = 0 if no trouble occurred,
9145 C = 1 if the P matrix was found to be unfactorable,
9146 C = IRES (= 2 or 3) if RES returned IRES = 2 or 3.
9147 C JCUR = output flag = 1 to indicate that the Jacobian matrix
9148 C (or approximation) is now current.
9149 C This routine also uses the Common variables EL0, H, TN, UROUND,
9150 C MITER, N, NFE, and NJE.
9151 C-----------------------------------------------------------------------
9152  nje = nje + 1
9153  hl0 = h*el0
9154  ierpj = 0
9155  jcur = 1
9156  mb = iwm(1)
9157  nb = iwm(2)
9158  mbsq = mb*mb
9159  lblox = mbsq*nb
9160  lpb = 3 + lblox
9161  lpc = lpb + lblox
9162  lenp = 3*lblox
9163  GO TO (100, 200), miter
9164 C If MITER = 1, call RES, then JAC, and multiply by scalar. ------------
9165  100 ires = 1
9166  CALL res (neq, tn, y, s, savr, ires)
9167  nfe = nfe + 1
9168  IF (ires .GT. 1) GO TO 600
9169  DO 110 i = 1,lenp
9170  110 wm(i+2) = 0.0d0
9171  CALL jac (neq, tn, y, s, mb, nb, wm(3), wm(lpb), wm(lpc))
9172  con = -hl0
9173  DO 120 i = 1,lenp
9174  120 wm(i+2) = wm(i+2)*con
9175  GO TO 260
9176 C
9177 C If MITER = 2, make 3*MB + 1 calls to RES to approximate J. -----------
9178  200 CONTINUE
9179  ires = -1
9180  CALL res (neq, tn, y, s, savr, ires)
9181  nfe = nfe + 1
9182  IF (ires .GT. 1) GO TO 600
9183  mwid = 3*mb
9184  srur = wm(1)
9185  DO 205 i = 1,lenp
9186  205 wm(2+i) = 0.0d0
9187  DO 250 k = 1,3
9188  DO 240 j = 1,mb
9189 C Increment Y(I) for group of column indices, and call RES. ----
9190  j1 = j+(k-1)*mb
9191  DO 210 i = j1,n,mwid
9192  r = max(srur*abs(y(i)),0.01d0/ewt(i))
9193  y(i) = y(i) + r
9194  210 CONTINUE
9195  CALL res (neq, tn, y, s, rtem, ires)
9196  nfe = nfe + 1
9197  IF (ires .GT. 1) GO TO 600
9198  DO 215 i = 1,n
9199  215 rtem(i) = rtem(i) - savr(i)
9200  k1 = k
9201  DO 230 i = j1,n,mwid
9202 C Get Jacobian elements in column I (block-column K1). -------
9203  y(i) = yh(i,1)
9204  r = max(srur*abs(y(i)),0.01d0/ewt(i))
9205  fac = -hl0/r
9206 C Compute and load elements PA(*,J,K1). ----------------------
9207  iia = i - j
9208  ipa = 2 + (j-1)*mb + (k1-1)*mbsq
9209  DO 221 j2 = 1,mb
9210  221 wm(ipa+j2) = rtem(iia+j2)*fac
9211  IF (k1 .LE. 1) GO TO 223
9212 C Compute and load elements PB(*,J,K1-1). --------------------
9213  iib = iia - mb
9214  ipb = ipa + lblox - mbsq
9215  DO 222 j2 = 1,mb
9216  222 wm(ipb+j2) = rtem(iib+j2)*fac
9217  223 CONTINUE
9218  IF (k1 .GE. nb) GO TO 225
9219 C Compute and load elements PC(*,J,K1+1). --------------------
9220  iic = iia + mb
9221  ipc = ipa + 2*lblox + mbsq
9222  DO 224 j2 = 1,mb
9223  224 wm(ipc+j2) = rtem(iic+j2)*fac
9224  225 CONTINUE
9225  IF (k1 .NE. 3) GO TO 227
9226 C Compute and load elements PC(*,J,1). -----------------------
9227  ipc = ipa - 2*mbsq + 2*lblox
9228  DO 226 j2 = 1,mb
9229  226 wm(ipc+j2) = rtem(j2)*fac
9230  227 CONTINUE
9231  IF (k1 .NE. nb-2) GO TO 229
9232 C Compute and load elements PB(*,J,NB). ----------------------
9233  iib = n - mb
9234  ipb = ipa + 2*mbsq + lblox
9235  DO 228 j2 = 1,mb
9236  228 wm(ipb+j2) = rtem(iib+j2)*fac
9237  229 k1 = k1 + 3
9238  230 CONTINUE
9239  240 CONTINUE
9240  250 CONTINUE
9241 C RES call for first corrector iteration. ------------------------------
9242  ires = 1
9243  CALL res (neq, tn, y, s, savr, ires)
9244  nfe = nfe + 1
9245  IF (ires .GT. 1) GO TO 600
9246 C Add matrix A. --------------------------------------------------------
9247  260 CONTINUE
9248  CALL adda (neq, tn, y, mb, nb, wm(3), wm(lpb), wm(lpc))
9249 C Do LU decomposition on P. --------------------------------------------
9250  CALL ddecbt (mb, nb, wm(3), wm(lpb), wm(lpc), iwm(21), ier)
9251  IF (ier .NE. 0) ierpj = 1
9252  RETURN
9253 C Error return for IRES = 2 or IRES = 3 return from RES. ---------------
9254  600 ierpj = ires
9255  RETURN
9256 C----------------------- End of Subroutine DPJIBT ----------------------
9257  END
9258 *DECK DSLSBT
9259  SUBROUTINE dslsbt (WM, IWM, X, TEM)
9260  INTEGER iwm
9261  INTEGER lblox, lpb, lpc, mb, nb
9262  DOUBLE PRECISION wm, x, tem
9263  dimension wm(*), iwm(*), x(*), tem(*)
9264 C-----------------------------------------------------------------------
9265 C This routine acts as an interface between the core integrator
9266 C routine and the DSOLBT routine for the solution of the linear system
9267 C arising from chord iteration.
9268 C Communication with DSLSBT uses the following variables:
9269 C WM = real work space containing the LU decomposition,
9270 C starting at WM(3).
9271 C IWM = integer work space containing pivot information, starting at
9272 C IWM(21). IWM also contains block structure parameters
9273 C MB = IWM(1) and NB = IWM(2).
9274 C X = the right-hand side vector on input, and the solution vector
9275 C on output, of length N.
9276 C TEM = vector of work space of length N, not used in this version.
9277 C-----------------------------------------------------------------------
9278  mb = iwm(1)
9279  nb = iwm(2)
9280  lblox = mb*mb*nb
9281  lpb = 3 + lblox
9282  lpc = lpb + lblox
9283  CALL dsolbt (mb, nb, wm(3), wm(lpb), wm(lpc), x, iwm(21))
9284  RETURN
9285 C----------------------- End of Subroutine DSLSBT ----------------------
9286  END
9287 *DECK DDECBT
9288  SUBROUTINE ddecbt (M, N, A, B, C, IP, IER)
9289  INTEGER m, n, ip(m,n), ier
9290  DOUBLE PRECISION a(m,m,n), b(m,m,n), c(m,m,n)
9291 C-----------------------------------------------------------------------
9292 C Block-tridiagonal matrix decomposition routine.
9293 C Written by A. C. Hindmarsh.
9294 C Latest revision: November 10, 1983 (ACH)
9295 C Reference: UCID-30150
9296 C Solution of Block-Tridiagonal Systems of Linear
9297 C Algebraic Equations
9298 C A.C. Hindmarsh
9299 C February 1977
9300 C The input matrix contains three blocks of elements in each block-row,
9301 C including blocks in the (1,3) and (N,N-2) block positions.
9302 C DDECBT uses block Gauss elimination and Subroutines DGEFA and DGESL
9303 C for solution of blocks. Partial pivoting is done within
9304 C block-rows only.
9305 C
9306 C Note: this version uses LINPACK routines DGEFA/DGESL instead of
9307 C of dec/sol for solution of blocks, and it uses the BLAS routine DDOT
9308 C for dot product calculations.
9309 C
9310 C Input:
9311 C M = order of each block.
9312 C N = number of blocks in each direction of the matrix.
9313 C N must be 4 or more. The complete matrix has order M*N.
9314 C A = M by M by N array containing diagonal blocks.
9315 C A(i,j,k) contains the (i,j) element of the k-th block.
9316 C B = M by M by N array containing the super-diagonal blocks
9317 C (in B(*,*,k) for k = 1,...,N-1) and the block in the (N,N-2)
9318 C block position (in B(*,*,N)).
9319 C C = M by M by N array containing the subdiagonal blocks
9320 C (in C(*,*,k) for k = 2,3,...,N) and the block in the
9321 C (1,3) block position (in C(*,*,1)).
9322 C IP = integer array of length M*N for working storage.
9323 C Output:
9324 C A,B,C = M by M by N arrays containing the block-LU decomposition
9325 C of the input matrix.
9326 C IP = M by N array of pivot information. IP(*,k) contains
9327 C information for the k-th digonal block.
9328 C IER = 0 if no trouble occurred, or
9329 C = -1 if the input value of M or N was illegal, or
9330 C = k if a singular matrix was found in the k-th diagonal block.
9331 C Use DSOLBT to solve the associated linear system.
9332 C
9333 C External routines required: DGEFA and DGESL (from LINPACK) and
9334 C DDOT (from the BLAS, or Basic Linear Algebra package).
9335 C-----------------------------------------------------------------------
9336  INTEGER nm1, nm2, km1, i, j, k
9337  DOUBLE PRECISION dp, ddot
9338  IF (m .LT. 1 .OR. n .LT. 4) GO TO 210
9339  nm1 = n - 1
9340  nm2 = n - 2
9341 C Process the first block-row. -----------------------------------------
9342  CALL dgefa (a, m, m, ip, ier)
9343  k = 1
9344  IF (ier .NE. 0) GO TO 200
9345  DO 10 j = 1,m
9346  CALL dgesl (a, m, m, ip, b(1,j,1), 0)
9347  CALL dgesl (a, m, m, ip, c(1,j,1), 0)
9348  10 CONTINUE
9349 C Adjust B(*,*,2). -----------------------------------------------------
9350  DO 40 j = 1,m
9351  DO 30 i = 1,m
9352  dp = ddot(m, c(i,1,2), m, c(1,j,1), 1)
9353  b(i,j,2) = b(i,j,2) - dp
9354  30 CONTINUE
9355  40 CONTINUE
9356 C Main loop. Process block-rows 2 to N-1. -----------------------------
9357  DO 100 k = 2,nm1
9358  km1 = k - 1
9359  DO 70 j = 1,m
9360  DO 60 i = 1,m
9361  dp = ddot(m, c(i,1,k), m, b(1,j,km1), 1)
9362  a(i,j,k) = a(i,j,k) - dp
9363  60 CONTINUE
9364  70 CONTINUE
9365  CALL dgefa (a(1,1,k), m, m, ip(1,k), ier)
9366  IF (ier .NE. 0) GO TO 200
9367  DO 80 j = 1,m
9368  80 CALL dgesl (a(1,1,k), m, m, ip(1,k), b(1,j,k), 0)
9369  100 CONTINUE
9370 C Process last block-row and return. -----------------------------------
9371  DO 130 j = 1,m
9372  DO 120 i = 1,m
9373  dp = ddot(m, b(i,1,n), m, b(1,j,nm2), 1)
9374  c(i,j,n) = c(i,j,n) - dp
9375  120 CONTINUE
9376  130 CONTINUE
9377  DO 160 j = 1,m
9378  DO 150 i = 1,m
9379  dp = ddot(m, c(i,1,n), m, b(1,j,nm1), 1)
9380  a(i,j,n) = a(i,j,n) - dp
9381  150 CONTINUE
9382  160 CONTINUE
9383  CALL dgefa (a(1,1,n), m, m, ip(1,n), ier)
9384  k = n
9385  IF (ier .NE. 0) GO TO 200
9386  RETURN
9387 C Error returns. -------------------------------------------------------
9388  200 ier = k
9389  RETURN
9390  210 ier = -1
9391  RETURN
9392 C----------------------- End of Subroutine DDECBT ----------------------
9393  END
9394 *DECK DSOLBT
9395  SUBROUTINE dsolbt (M, N, A, B, C, Y, IP)
9396  INTEGER m, n, ip(m,n)
9397  DOUBLE PRECISION a(m,m,n), b(m,m,n), c(m,m,n), y(m,n)
9398 C-----------------------------------------------------------------------
9399 C Solution of block-tridiagonal linear system.
9400 C Coefficient matrix must have been previously processed by DDECBT.
9401 C M, N, A,B,C, and IP must not have been changed since call to DDECBT.
9402 C Written by A. C. Hindmarsh.
9403 C Input:
9404 C M = order of each block.
9405 C N = number of blocks in each direction of matrix.
9406 C A,B,C = M by M by N arrays containing block LU decomposition
9407 C of coefficient matrix from DDECBT.
9408 C IP = M by N integer array of pivot information from DDECBT.
9409 C Y = array of length M*N containg the right-hand side vector
9410 C (treated as an M by N array here).
9411 C Output:
9412 C Y = solution vector, of length M*N.
9413 C
9414 C External routines required: DGESL (LINPACK) and DDOT (BLAS).
9415 C-----------------------------------------------------------------------
9416 C
9417  INTEGER nm1, nm2, i, k, kb, km1, kp1
9418  DOUBLE PRECISION dp, ddot
9419  nm1 = n - 1
9420  nm2 = n - 2
9421 C Forward solution sweep. ----------------------------------------------
9422  CALL dgesl (a, m, m, ip, y, 0)
9423  DO 30 k = 2,nm1
9424  km1 = k - 1
9425  DO 20 i = 1,m
9426  dp = ddot(m, c(i,1,k), m, y(1,km1), 1)
9427  y(i,k) = y(i,k) - dp
9428  20 CONTINUE
9429  CALL dgesl (a(1,1,k), m, m, ip(1,k), y(1,k), 0)
9430  30 CONTINUE
9431  DO 50 i = 1,m
9432  dp = ddot(m, c(i,1,n), m, y(1,nm1), 1)
9433  1 + ddot(m, b(i,1,n), m, y(1,nm2), 1)
9434  y(i,n) = y(i,n) - dp
9435  50 CONTINUE
9436  CALL dgesl (a(1,1,n), m, m, ip(1,n), y(1,n), 0)
9437 C Backward solution sweep. ---------------------------------------------
9438  DO 80 kb = 1,nm1
9439  k = n - kb
9440  kp1 = k + 1
9441  DO 70 i = 1,m
9442  dp = ddot(m, b(i,1,k), m, y(1,kp1), 1)
9443  y(i,k) = y(i,k) - dp
9444  70 CONTINUE
9445  80 CONTINUE
9446  DO 100 i = 1,m
9447  dp = ddot(m, c(i,1,1), m, y(1,3), 1)
9448  y(i,1) = y(i,1) - dp
9449  100 CONTINUE
9450  RETURN
9451 C----------------------- End of Subroutine DSOLBT ----------------------
9452  END
9453 *DECK DIPREPI
9454  SUBROUTINE diprepi (NEQ, Y, S, RWORK, IA, JA, IC, JC, IPFLAG,
9455  1 RES, JAC, ADDA)
9456  EXTERNAL res, jac, adda
9457  INTEGER neq, ia, ja, ic, jc, ipflag
9458  DOUBLE PRECISION y, s, rwork
9459  dimension neq(*), y(*), s(*), rwork(*), ia(*), ja(*), ic(*), jc(*)
9460  INTEGER iownd, iowns,
9461  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
9462  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
9463  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
9464  INTEGER iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
9465  1 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
9466  2 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
9467  3 nslj, ngp, nlu, nnz, nsp, nzl, nzu
9468  DOUBLE PRECISION rowns,
9469  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
9470  DOUBLE PRECISION rlss
9471  COMMON /dls001/ rowns(209),
9472  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
9473  2 iownd(6), iowns(6),
9474  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
9475  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
9476  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
9477  COMMON /dlss01/ rlss(6),
9478  1 iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
9479  2 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
9480  3 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
9481  4 nslj, ngp, nlu, nnz, nsp, nzl, nzu
9482  INTEGER i, imax, lewtn, lyhd, lyhn
9483 C-----------------------------------------------------------------------
9484 C This routine serves as an interface between the driver and
9485 C Subroutine DPREPI. Tasks performed here are:
9486 C * call DPREPI,
9487 C * reset the required WM segment length LENWK,
9488 C * move YH back to its final location (following WM in RWORK),
9489 C * reset pointers for YH, SAVR, EWT, and ACOR, and
9490 C * move EWT to its new position if ISTATE = 0 or 1.
9491 C IPFLAG is an output error indication flag. IPFLAG = 0 if there was
9492 C no trouble, and IPFLAG is the value of the DPREPI error flag IPPER
9493 C if there was trouble in Subroutine DPREPI.
9494 C-----------------------------------------------------------------------
9495  ipflag = 0
9496 C Call DPREPI to do matrix preprocessing operations. -------------------
9497  CALL dprepi (neq, y, s, rwork(lyh), rwork(lsavf), rwork(lewt),
9498  1 rwork(lacor), ia, ja, ic, jc, rwork(lwm), rwork(lwm), ipflag,
9499  2 res, jac, adda)
9500  lenwk = max(lreq,lwmin)
9501  IF (ipflag .LT. 0) RETURN
9502 C If DPREPI was successful, move YH to end of required space for WM. ---
9503  lyhn = lwm + lenwk
9504  IF (lyhn .GT. lyh) RETURN
9505  lyhd = lyh - lyhn
9506  IF (lyhd .EQ. 0) GO TO 20
9507  imax = lyhn - 1 + lenyhm
9508  DO 10 i=lyhn,imax
9509  10 rwork(i) = rwork(i+lyhd)
9510  lyh = lyhn
9511 C Reset pointers for SAVR, EWT, and ACOR. ------------------------------
9512  20 lsavf = lyh + lenyh
9513  lewtn = lsavf + n
9514  lacor = lewtn + n
9515  IF (istatc .EQ. 3) GO TO 40
9516 C If ISTATE = 1, move EWT (left) to its new position. ------------------
9517  IF (lewtn .GT. lewt) RETURN
9518  DO 30 i=1,n
9519  30 rwork(i+lewtn-1) = rwork(i+lewt-1)
9520  40 lewt = lewtn
9521  RETURN
9522 C----------------------- End of Subroutine DIPREPI ---------------------
9523  END
9524 *DECK DPREPI
9525  SUBROUTINE dprepi (NEQ, Y, S, YH, SAVR, EWT, RTEM, IA, JA, IC, JC,
9526  1 WK, IWK, IPPER, RES, JAC, ADDA)
9527  EXTERNAL res, jac, adda
9528  INTEGER neq, ia, ja, ic, jc, iwk, ipper
9529  DOUBLE PRECISION y, s, yh, savr, ewt, rtem, wk
9530  dimension neq(*), y(*), s(*), yh(*), savr(*), ewt(*), rtem(*),
9531  1 ia(*), ja(*), ic(*), jc(*), wk(*), iwk(*)
9532  INTEGER iownd, iowns,
9533  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
9534  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
9535  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
9536  INTEGER iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
9537  1 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
9538  2 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
9539  3 nslj, ngp, nlu, nnz, nsp, nzl, nzu
9540  DOUBLE PRECISION rowns,
9541  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
9542  DOUBLE PRECISION rlss
9543  COMMON /dls001/ rowns(209),
9544  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
9545  2 iownd(6), iowns(6),
9546  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
9547  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
9548  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
9549  COMMON /dlss01/ rlss(6),
9550  1 iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
9551  2 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
9552  3 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
9553  4 nslj, ngp, nlu, nnz, nsp, nzl, nzu
9554  INTEGER i, ibr, ier, ipil, ipiu, iptt1, iptt2, j, k, knew, kamax,
9555  1 kamin, kcmax, kcmin, ldif, lenigp, lenwk1, liwk, ljfo, maxg,
9556  2 np1, nzsut
9557  DOUBLE PRECISION erwt, fac, yj
9558 C-----------------------------------------------------------------------
9559 C This routine performs preprocessing related to the sparse linear
9560 C systems that must be solved.
9561 C The operations that are performed here are:
9562 C * compute sparseness structure of the iteration matrix
9563 C P = A - con*J according to MOSS,
9564 C * compute grouping of column indices (MITER = 2),
9565 C * compute a new ordering of rows and columns of the matrix,
9566 C * reorder JA corresponding to the new ordering,
9567 C * perform a symbolic LU factorization of the matrix, and
9568 C * set pointers for segments of the IWK/WK array.
9569 C In addition to variables described previously, DPREPI uses the
9570 C following for communication:
9571 C YH = the history array. Only the first column, containing the
9572 C current Y vector, is used. Used only if MOSS .ne. 0.
9573 C S = array of length NEQ, identical to YDOTI in the driver, used
9574 C only if MOSS .ne. 0.
9575 C SAVR = a work array of length NEQ, used only if MOSS .ne. 0.
9576 C EWT = array of length NEQ containing (inverted) error weights.
9577 C Used only if MOSS = 2 or 4 or if ISTATE = MOSS = 1.
9578 C RTEM = a work array of length NEQ, identical to ACOR in the driver,
9579 C used only if MOSS = 2 or 4.
9580 C WK = a real work array of length LENWK, identical to WM in
9581 C the driver.
9582 C IWK = integer work array, assumed to occupy the same space as WK.
9583 C LENWK = the length of the work arrays WK and IWK.
9584 C ISTATC = a copy of the driver input argument ISTATE (= 1 on the
9585 C first call, = 3 on a continuation call).
9586 C IYS = flag value from ODRV or CDRV.
9587 C IPPER = output error flag , with the following values and meanings:
9588 C = 0 no error.
9589 C = -1 insufficient storage for internal structure pointers.
9590 C = -2 insufficient storage for JGROUP.
9591 C = -3 insufficient storage for ODRV.
9592 C = -4 other error flag from ODRV (should never occur).
9593 C = -5 insufficient storage for CDRV.
9594 C = -6 other error flag from CDRV.
9595 C = -7 if the RES routine returned error flag IRES = IER = 2.
9596 C = -8 if the RES routine returned error flag IRES = IER = 3.
9597 C-----------------------------------------------------------------------
9598  ibian = lrat*2
9599  ipian = ibian + 1
9600  np1 = n + 1
9601  ipjan = ipian + np1
9602  ibjan = ipjan - 1
9603  lenwk1 = lenwk - n
9604  liwk = lenwk*lrat
9605  IF (moss .EQ. 0) liwk = liwk - n
9606  IF (moss .EQ. 1 .OR. moss .EQ. 2) liwk = lenwk1*lrat
9607  IF (ipjan+n-1 .GT. liwk) GO TO 310
9608  IF (moss .EQ. 0) GO TO 30
9609 C
9610  IF (istatc .EQ. 3) GO TO 20
9611 C ISTATE = 1 and MOSS .ne. 0. Perturb Y for structure determination.
9612 C Initialize S with random nonzero elements for structure determination.
9613  DO 10 i=1,n
9614  erwt = 1.0d0/ewt(i)
9615  fac = 1.0d0 + 1.0d0/(i + 1.0d0)
9616  y(i) = y(i) + fac*sign(erwt,y(i))
9617  s(i) = 1.0d0 + fac*erwt
9618  10 CONTINUE
9619  GO TO (70, 100, 150, 200), moss
9620 C
9621  20 CONTINUE
9622 C ISTATE = 3 and MOSS .ne. 0. Load Y from YH(*,1) and S from YH(*,2). --
9623  DO 25 i = 1,n
9624  y(i) = yh(i)
9625  25 s(i) = yh(n+i)
9626  GO TO (70, 100, 150, 200), moss
9627 C
9628 C MOSS = 0. Process user's IA,JA and IC,JC. ----------------------------
9629  30 knew = ipjan
9630  kamin = ia(1)
9631  kcmin = ic(1)
9632  iwk(ipian) = 1
9633  DO 60 j = 1,n
9634  DO 35 i = 1,n
9635  35 iwk(liwk+i) = 0
9636  kamax = ia(j+1) - 1
9637  IF (kamin .GT. kamax) GO TO 45
9638  DO 40 k = kamin,kamax
9639  i = ja(k)
9640  iwk(liwk+i) = 1
9641  IF (knew .GT. liwk) GO TO 310
9642  iwk(knew) = i
9643  knew = knew + 1
9644  40 CONTINUE
9645  45 kamin = kamax + 1
9646  kcmax = ic(j+1) - 1
9647  IF (kcmin .GT. kcmax) GO TO 55
9648  DO 50 k = kcmin,kcmax
9649  i = jc(k)
9650  IF (iwk(liwk+i) .NE. 0) GO TO 50
9651  IF (knew .GT. liwk) GO TO 310
9652  iwk(knew) = i
9653  knew = knew + 1
9654  50 CONTINUE
9655  55 iwk(ipian+j) = knew + 1 - ipjan
9656  kcmin = kcmax + 1
9657  60 CONTINUE
9658  GO TO 240
9659 C
9660 C MOSS = 1. Compute structure from user-supplied Jacobian routine JAC. -
9661  70 CONTINUE
9662 C A dummy call to RES allows user to create temporaries for use in JAC.
9663  ier = 1
9664  CALL res (neq, tn, y, s, savr, ier)
9665  IF (ier .GT. 1) GO TO 370
9666  DO 75 i = 1,n
9667  savr(i) = 0.0d0
9668  75 wk(lenwk1+i) = 0.0d0
9669  k = ipjan
9670  iwk(ipian) = 1
9671  DO 95 j = 1,n
9672  CALL adda (neq, tn, y, j, iwk(ipian), iwk(ipjan), wk(lenwk1+1))
9673  CALL jac (neq, tn, y, s, j, iwk(ipian), iwk(ipjan), savr)
9674  DO 90 i = 1,n
9675  ljfo = lenwk1 + i
9676  IF (wk(ljfo) .EQ. 0.0d0) GO TO 80
9677  wk(ljfo) = 0.0d0
9678  savr(i) = 0.0d0
9679  GO TO 85
9680  80 IF (savr(i) .EQ. 0.0d0) GO TO 90
9681  savr(i) = 0.0d0
9682  85 IF (k .GT. liwk) GO TO 310
9683  iwk(k) = i
9684  k = k+1
9685  90 CONTINUE
9686  iwk(ipian+j) = k + 1 - ipjan
9687  95 CONTINUE
9688  GO TO 240
9689 C
9690 C MOSS = 2. Compute structure from results of N + 1 calls to RES. ------
9691  100 DO 105 i = 1,n
9692  105 wk(lenwk1+i) = 0.0d0
9693  k = ipjan
9694  iwk(ipian) = 1
9695  ier = -1
9696  IF (miter .EQ. 1) ier = 1
9697  CALL res (neq, tn, y, s, savr, ier)
9698  IF (ier .GT. 1) GO TO 370
9699  DO 130 j = 1,n
9700  CALL adda (neq, tn, y, j, iwk(ipian), iwk(ipjan), wk(lenwk1+1))
9701  yj = y(j)
9702  erwt = 1.0d0/ewt(j)
9703  y(j) = yj + sign(erwt,yj)
9704  CALL res (neq, tn, y, s, rtem, ier)
9705  IF (ier .GT. 1) RETURN
9706  y(j) = yj
9707  DO 120 i = 1,n
9708  ljfo = lenwk1 + i
9709  IF (wk(ljfo) .EQ. 0.0d0) GO TO 110
9710  wk(ljfo) = 0.0d0
9711  GO TO 115
9712  110 IF (rtem(i) .EQ. savr(i)) GO TO 120
9713  115 IF (k .GT. liwk) GO TO 310
9714  iwk(k) = i
9715  k = k + 1
9716  120 CONTINUE
9717  iwk(ipian+j) = k + 1 - ipjan
9718  130 CONTINUE
9719  GO TO 240
9720 C
9721 C MOSS = 3. Compute structure from the user's IA/JA and JAC routine. ---
9722  150 CONTINUE
9723 C A dummy call to RES allows user to create temporaries for use in JAC.
9724  ier = 1
9725  CALL res (neq, tn, y, s, savr, ier)
9726  IF (ier .GT. 1) GO TO 370
9727  DO 155 i = 1,n
9728  155 savr(i) = 0.0d0
9729  knew = ipjan
9730  kamin = ia(1)
9731  iwk(ipian) = 1
9732  DO 190 j = 1,n
9733  CALL jac (neq, tn, y, s, j, iwk(ipian), iwk(ipjan), savr)
9734  kamax = ia(j+1) - 1
9735  IF (kamin .GT. kamax) GO TO 170
9736  DO 160 k = kamin,kamax
9737  i = ja(k)
9738  savr(i) = 0.0d0
9739  IF (knew .GT. liwk) GO TO 310
9740  iwk(knew) = i
9741  knew = knew + 1
9742  160 CONTINUE
9743  170 kamin = kamax + 1
9744  DO 180 i = 1,n
9745  IF (savr(i) .EQ. 0.0d0) GO TO 180
9746  savr(i) = 0.0d0
9747  IF (knew .GT. liwk) GO TO 310
9748  iwk(knew) = i
9749  knew = knew + 1
9750  180 CONTINUE
9751  iwk(ipian+j) = knew + 1 - ipjan
9752  190 CONTINUE
9753  GO TO 240
9754 C
9755 C MOSS = 4. Compute structure from user's IA/JA and N + 1 RES calls. ---
9756  200 knew = ipjan
9757  kamin = ia(1)
9758  iwk(ipian) = 1
9759  ier = -1
9760  IF (miter .EQ. 1) ier = 1
9761  CALL res (neq, tn, y, s, savr, ier)
9762  IF (ier .GT. 1) GO TO 370
9763  DO 235 j = 1,n
9764  yj = y(j)
9765  erwt = 1.0d0/ewt(j)
9766  y(j) = yj + sign(erwt,yj)
9767  CALL res (neq, tn, y, s, rtem, ier)
9768  IF (ier .GT. 1) RETURN
9769  y(j) = yj
9770  kamax = ia(j+1) - 1
9771  IF (kamin .GT. kamax) GO TO 225
9772  DO 220 k = kamin,kamax
9773  i = ja(k)
9774  rtem(i) = savr(i)
9775  IF (knew .GT. liwk) GO TO 310
9776  iwk(knew) = i
9777  knew = knew + 1
9778  220 CONTINUE
9779  225 kamin = kamax + 1
9780  DO 230 i = 1,n
9781  IF (rtem(i) .EQ. savr(i)) GO TO 230
9782  IF (knew .GT. liwk) GO TO 310
9783  iwk(knew) = i
9784  knew = knew + 1
9785  230 CONTINUE
9786  iwk(ipian+j) = knew + 1 - ipjan
9787  235 CONTINUE
9788 C
9789  240 CONTINUE
9790  IF (moss .EQ. 0 .OR. istatc .EQ. 3) GO TO 250
9791 C If ISTATE = 0 or 1 and MOSS .ne. 0, restore Y from YH. ---------------
9792  DO 245 i = 1,n
9793  245 y(i) = yh(i)
9794  250 nnz = iwk(ipian+n) - 1
9795  ipper = 0
9796  ngp = 0
9797  lenigp = 0
9798  ipigp = ipjan + nnz
9799  IF (miter .NE. 2) GO TO 260
9800 C
9801 C Compute grouping of column indices (MITER = 2). ----------------------
9802 C
9803  maxg = np1
9804  ipjgp = ipjan + nnz
9805  ibjgp = ipjgp - 1
9806  ipigp = ipjgp + n
9807  iptt1 = ipigp + np1
9808  iptt2 = iptt1 + n
9809  lreq = iptt2 + n - 1
9810  IF (lreq .GT. liwk) GO TO 320
9811  CALL jgroup (n, iwk(ipian), iwk(ipjan), maxg, ngp, iwk(ipigp),
9812  1 iwk(ipjgp), iwk(iptt1), iwk(iptt2), ier)
9813  IF (ier .NE. 0) GO TO 320
9814  lenigp = ngp + 1
9815 C
9816 C Compute new ordering of rows/columns of Jacobian. --------------------
9817  260 ipr = ipigp + lenigp
9818  ipc = ipr
9819  ipic = ipc + n
9820  ipisp = ipic + n
9821  iprsp = (ipisp-2)/lrat + 2
9822  iesp = lenwk + 1 - iprsp
9823  IF (iesp .LT. 0) GO TO 330
9824  ibr = ipr - 1
9825  DO 270 i = 1,n
9826  270 iwk(ibr+i) = i
9827  nsp = liwk + 1 - ipisp
9828  CALL odrv(n, iwk(ipian), iwk(ipjan), wk, iwk(ipr), iwk(ipic), nsp,
9829  1 iwk(ipisp), 1, iys)
9830  IF (iys .EQ. 11*n+1) GO TO 340
9831  IF (iys .NE. 0) GO TO 330
9832 C
9833 C Reorder JAN and do symbolic LU factorization of matrix. --------------
9834  ipa = lenwk + 1 - nnz
9835  nsp = ipa - iprsp
9836  lreq = max(12*n/lrat, 6*n/lrat+2*n+nnz) + 3
9837  lreq = lreq + iprsp - 1 + nnz
9838  IF (lreq .GT. lenwk) GO TO 350
9839  iba = ipa - 1
9840  DO 280 i = 1,nnz
9841  280 wk(iba+i) = 0.0d0
9842  ipisp = lrat*(iprsp - 1) + 1
9843  CALL cdrv(n,iwk(ipr),iwk(ipc),iwk(ipic),iwk(ipian),iwk(ipjan),
9844  1 wk(ipa),wk(ipa),wk(ipa),nsp,iwk(ipisp),wk(iprsp),iesp,5,iys)
9845  lreq = lenwk - iesp
9846  IF (iys .EQ. 10*n+1) GO TO 350
9847  IF (iys .NE. 0) GO TO 360
9848  ipil = ipisp
9849  ipiu = ipil + 2*n + 1
9850  nzu = iwk(ipil+n) - iwk(ipil)
9851  nzl = iwk(ipiu+n) - iwk(ipiu)
9852  IF (lrat .GT. 1) GO TO 290
9853  CALL adjlr (n, iwk(ipisp), ldif)
9854  lreq = lreq + ldif
9855  290 CONTINUE
9856  IF (lrat .EQ. 2 .AND. nnz .EQ. n) lreq = lreq + 1
9857  nsp = nsp + lreq - lenwk
9858  ipa = lreq + 1 - nnz
9859  iba = ipa - 1
9860  ipper = 0
9861  RETURN
9862 C
9863  310 ipper = -1
9864  lreq = 2 + (2*n + 1)/lrat
9865  lreq = max(lenwk+1,lreq)
9866  RETURN
9867 C
9868  320 ipper = -2
9869  lreq = (lreq - 1)/lrat + 1
9870  RETURN
9871 C
9872  330 ipper = -3
9873  CALL cntnzu (n, iwk(ipian), iwk(ipjan), nzsut)
9874  lreq = lenwk - iesp + (3*n + 4*nzsut - 1)/lrat + 1
9875  RETURN
9876 C
9877  340 ipper = -4
9878  RETURN
9879 C
9880  350 ipper = -5
9881  RETURN
9882 C
9883  360 ipper = -6
9884  lreq = lenwk
9885  RETURN
9886 C
9887  370 ipper = -ier - 5
9888  lreq = 2 + (2*n + 1)/lrat
9889  RETURN
9890 C----------------------- End of Subroutine DPREPI ----------------------
9891  END
9892 *DECK DAINVGS
9893  SUBROUTINE dainvgs (NEQ, T, Y, WK, IWK, TEM, YDOT, IER, RES, ADDA)
9894  EXTERNAL res, adda
9895  INTEGER neq, iwk, ier
9896  INTEGER iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
9897  1 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
9898  2 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
9899  3 nslj, ngp, nlu, nnz, nsp, nzl, nzu
9900  INTEGER i, imul, j, k, kmin, kmax
9901  DOUBLE PRECISION t, y, wk, tem, ydot
9902  DOUBLE PRECISION rlss
9903  dimension y(*), wk(*), iwk(*), tem(*), ydot(*)
9904  COMMON /dlss01/ rlss(6),
9905  1 iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
9906  2 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
9907  3 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
9908  4 nslj, ngp, nlu, nnz, nsp, nzl, nzu
9909 C-----------------------------------------------------------------------
9910 C This subroutine computes the initial value of the vector YDOT
9911 C satisfying
9912 C A * YDOT = g(t,y)
9913 C when A is nonsingular. It is called by DLSODIS for initialization
9914 C only, when ISTATE = 0. The matrix A is subjected to LU
9915 C decomposition in CDRV. Then the system A*YDOT = g(t,y) is solved
9916 C in CDRV.
9917 C In addition to variables described previously, communication
9918 C with DAINVGS uses the following:
9919 C Y = array of initial values.
9920 C WK = real work space for matrices. On output it contains A and
9921 C its LU decomposition. The LU decomposition is not entirely
9922 C sparse unless the structure of the matrix A is identical to
9923 C the structure of the Jacobian matrix dr/dy.
9924 C Storage of matrix elements starts at WK(3).
9925 C WK(1) = SQRT(UROUND), not used here.
9926 C IWK = integer work space for matrix-related data, assumed to
9927 C be equivalenced to WK. In addition, WK(IPRSP) and WK(IPISP)
9928 C are assumed to have identical locations.
9929 C TEM = vector of work space of length N (ACOR in DSTODI).
9930 C YDOT = output vector containing the initial dy/dt. YDOT(i) contains
9931 C dy(i)/dt when the matrix A is non-singular.
9932 C IER = output error flag with the following values and meanings:
9933 C = 0 if DAINVGS was successful.
9934 C = 1 if the A-matrix was found to be singular.
9935 C = 2 if RES returned an error flag IRES = IER = 2.
9936 C = 3 if RES returned an error flag IRES = IER = 3.
9937 C = 4 if insufficient storage for CDRV (should not occur here).
9938 C = 5 if other error found in CDRV (should not occur here).
9939 C-----------------------------------------------------------------------
9940 C
9941  DO 10 i = 1,nnz
9942  10 wk(iba+i) = 0.0d0
9943 C
9944  ier = 1
9945  CALL res (neq, t, y, wk(ipa), ydot, ier)
9946  IF (ier .GT. 1) RETURN
9947 C
9948  kmin = iwk(ipian)
9949  DO 30 j = 1,neq
9950  kmax = iwk(ipian+j) - 1
9951  DO 15 k = kmin,kmax
9952  i = iwk(ibjan+k)
9953  15 tem(i) = 0.0d0
9954  CALL adda (neq, t, y, j, iwk(ipian), iwk(ipjan), tem)
9955  DO 20 k = kmin,kmax
9956  i = iwk(ibjan+k)
9957  20 wk(iba+k) = tem(i)
9958  kmin = kmax + 1
9959  30 CONTINUE
9960  nlu = nlu + 1
9961  ier = 0
9962  DO 40 i = 1,neq
9963  40 tem(i) = 0.0d0
9964 C
9965 C Numerical factorization of matrix A. ---------------------------------
9966  CALL cdrv (neq,iwk(ipr),iwk(ipc),iwk(ipic),iwk(ipian),iwk(ipjan),
9967  1 wk(ipa),tem,tem,nsp,iwk(ipisp),wk(iprsp),iesp,2,iys)
9968  IF (iys .EQ. 0) GO TO 50
9969  imul = (iys - 1)/neq
9970  ier = 5
9971  IF (imul .EQ. 8) ier = 1
9972  IF (imul .EQ. 10) ier = 4
9973  RETURN
9974 C
9975 C Solution of the linear system. ---------------------------------------
9976  50 CALL cdrv (neq,iwk(ipr),iwk(ipc),iwk(ipic),iwk(ipian),iwk(ipjan),
9977  1 wk(ipa),ydot,ydot,nsp,iwk(ipisp),wk(iprsp),iesp,4,iys)
9978  IF (iys .NE. 0) ier = 5
9979  RETURN
9980 C----------------------- End of Subroutine DAINVGS ---------------------
9981  END
9982 *DECK DPRJIS
9983  SUBROUTINE dprjis (NEQ, Y, YH, NYH, EWT, RTEM, SAVR, S, WK, IWK,
9984  1 RES, JAC, ADDA)
9985  EXTERNAL res, jac, adda
9986  INTEGER neq, nyh, iwk
9987  DOUBLE PRECISION y, yh, ewt, rtem, savr, s, wk
9988  dimension neq(*), y(*), yh(nyh,*), ewt(*), rtem(*),
9989  1 s(*), savr(*), wk(*), iwk(*)
9990  INTEGER iownd, iowns,
9991  1 icf, ierpj, iersl, jcur, jstart, kflag, l,
9992  2 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
9993  3 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
9994  INTEGER iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
9995  1 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
9996  2 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
9997  3 nslj, ngp, nlu, nnz, nsp, nzl, nzu
9998  DOUBLE PRECISION rowns,
9999  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
10000  DOUBLE PRECISION rlss
10001  COMMON /dls001/ rowns(209),
10002  1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
10003  2 iownd(6), iowns(6),
10004  3 icf, ierpj, iersl, jcur, jstart, kflag, l,
10005  4 lyh, lewt, lacor, lsavf, lwm, liwm, meth, miter,
10006  5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
10007  COMMON /dlss01/ rlss(6),
10008  1 iplost, iesp, istatc, iys, iba, ibian, ibjan, ibjgp,
10009  2 ipian, ipjan, ipjgp, ipigp, ipr, ipc, ipic, ipisp, iprsp, ipa,
10010  3 lenyh, lenyhm, lenwk, lreq, lrat, lrest, lwmin, moss, msbj,
10011  4 nslj, ngp, nlu, nnz, nsp, nzl, nzu
10012  INTEGER i, imul, ires, j, jj, jmax, jmin, k, kmax, kmin, ng
10013  DOUBLE PRECISION con, fac, hl0, r, srur
10014 C-----------------------------------------------------------------------
10015 C DPRJIS is called to compute and process the matrix
10016 C P = A - H*EL(1)*J, where J is an approximation to the Jacobian dr/dy,
10017 C where r = g(t,y) - A(t,y)*s. J is computed by columns, either by
10018 C the user-supplied routine JAC if MITER = 1, or by finite differencing
10019 C if MITER = 2. J is stored in WK, rescaled, and ADDA is called to
10020 C generate P. The matrix P is subjected to LU decomposition in CDRV.
10021 C P and its LU decomposition are stored separately in WK.
10022 C
10023 C In addition to variables described previously, communication
10024 C with DPRJIS uses the following:
10025 C Y = array containing predicted values on entry.
10026 C RTEM = work array of length N (ACOR in DSTODI).
10027 C SAVR = array containing r evaluated at predicted y. On output it
10028 C contains the residual evaluated at current values of t and y.
10029 C S = array containing predicted values of dy/dt (SAVF in DSTODI).
10030 C WK = real work space for matrices. On output it contains P and
10031 C its sparse LU decomposition. Storage of matrix elements
10032 C starts at WK(3).
10033 C WK also contains the following matrix-related data.
10034 C WK(1) = SQRT(UROUND), used in numerical Jacobian increments.
10035 C IWK = integer work space for matrix-related data, assumed to be
10036 C equivalenced to WK. In addition, WK(IPRSP) and IWK(IPISP)
10037 C are assumed to have identical locations.
10038 C EL0 = EL(1) (input).
10039 C IERPJ = output error flag (in COMMON).
10040 C = 0 if no error.
10041 C = 1 if zero pivot found in CDRV.
10042 C = IRES (= 2 or 3) if RES returned IRES = 2 or 3.
10043 C = -1 if insufficient storage for CDRV (should not occur).
10044 C = -2 if other error found in CDRV (should not occur here).
10045 C JCUR = output flag = 1 to indicate that the Jacobian matrix
10046 C (or approximation) is now current.
10047 C This routine also uses other variables in Common.
10048 C-----------------------------------------------------------------------
10049  hl0 = h*el0
10050  con = -hl0
10051  jcur = 1
10052  nje = nje + 1
10053  GO TO (100, 200), miter
10054 C
10055 C If MITER = 1, call RES, then call JAC and ADDA for each column. ------
10056  100 ires = 1
10057  CALL res (neq, tn, y, s, savr, ires)
10058  nfe = nfe + 1
10059  IF (ires .GT. 1) GO TO 600
10060  kmin = iwk(ipian)
10061  DO 130 j = 1,n
10062  kmax = iwk(ipian+j)-1
10063  DO 110 i = 1,n
10064  110 rtem(i) = 0.0d0
10065  CALL jac (neq, tn, y, s, j, iwk(ipian), iwk(ipjan), rtem)
10066  DO 120 i = 1,n
10067  120 rtem(i) = rtem(i)*con
10068  CALL adda (neq, tn, y, j, iwk(ipian), iwk(ipjan), rtem)
10069  DO 125 k = kmin,kmax
10070  i = iwk(ibjan+k)
10071  wk(iba+k) = rtem(i)
10072  125 CONTINUE
10073  kmin = kmax + 1
10074  130 CONTINUE
10075  GO TO 290
10076 C
10077 C If MITER = 2, make NGP + 1 calls to RES to approximate J and P. ------
10078  200 CONTINUE
10079  ires = -1
10080  CALL res (neq, tn, y, s, savr, ires)
10081  nfe = nfe + 1
10082  IF (ires .GT. 1) GO TO 600
10083  srur = wk(1)
10084  jmin = iwk(ipigp)
10085  DO 240 ng = 1,ngp
10086  jmax = iwk(ipigp+ng) - 1
10087  DO 210 j = jmin,jmax
10088  jj = iwk(ibjgp+j)
10089  r = max(srur*abs(y(jj)),0.01d0/ewt(jj))
10090  210 y(jj) = y(jj) + r
10091  CALL res (neq,tn,y,s,rtem,ires)
10092  nfe = nfe + 1
10093  IF (ires .GT. 1) GO TO 600
10094  DO 230 j = jmin,jmax
10095  jj = iwk(ibjgp+j)
10096  y(jj) = yh(jj,1)
10097  r = max(srur*abs(y(jj)),0.01d0/ewt(jj))
10098  fac = -hl0/r
10099  kmin = iwk(ibian+jj)
10100  kmax = iwk(ibian+jj+1) - 1
10101  DO 220 k = kmin,kmax
10102  i = iwk(ibjan+k)
10103  rtem(i) = (rtem(i) - savr(i))*fac
10104  220 CONTINUE
10105  CALL adda (neq, tn, y, jj, iwk(ipian), iwk(ipjan), rtem)
10106  DO 225 k = kmin,kmax
10107  i = iwk(ibjan+k)
10108  wk(iba+k) = rtem(i)
10109  225 CONTINUE
10110  230 CONTINUE
10111  jmin = jmax + 1
10112  240 CONTINUE
10113  ires = 1
10114  CALL res (neq, tn, y, s, savr, ires)
10115  nfe = nfe + 1
10116  IF (ires .GT. 1) GO TO 600
10117 C
10118 C Do numerical factorization of P matrix. ------------------------------
10119  290 nlu = nlu + 1
10120  ierpj = 0
10121  DO 295 i = 1,n
10122  295 rtem(i) = 0.0d0
10123  CALL cdrv (n,iwk(ipr),iwk(ipc),iwk(ipic),iwk(ipian),iwk(ipjan),
10124  1 wk(ipa),rtem,rtem,nsp,iwk(ipisp),wk(iprsp),iesp,2,iys)
10125  IF (iys .EQ. 0) RETURN
10126  imul = (iys - 1)/n
10127  ierpj = -2
10128  IF (imul .EQ. 8) ierpj = 1
10129  IF (imul .EQ. 10) ierpj = -1
10130  RETURN
10131 C Error return for IRES = 2 or IRES = 3 return from RES. ---------------
10132  600 ierpj = ires
10133  RETURN
10134 C----------------------- End of Subroutine DPRJIS ----------------------
10135  END
10136