f2kodepack  Reference documentation for version 0.0
02_odepack_add_1.f90
Go to the documentation of this file.
1 ! ECK DUMACH
2 ! DOUBLE PRECISION :: FUNCTION DUMACH ()
3 !***BEGIN PROLOGUE DUMACH
4 !***PURPOSE Compute the unit roundoff of the machine.
5 !***CATEGORY R1
6 !***TYPE DOUBLE PRECISION (RUMACH-S, DUMACH-D)
7 !***KEYWORDS MACHINE CONSTANTS
8 !***AUTHOR Hindmarsh, Alan C., (LLNL)
9 !***DESCRIPTION
10 ! *Usage:
11 ! DOUBLE PRECISION A, DUMACH
12 ! A = DUMACH()
13 ! *Function Return Values:
14 ! A : the unit roundoff of the machine.
15 ! *Description:
16 ! The unit roundoff is defined as the smallest positive machine
17 ! number u such that 1.0 + u .ne. 1.0. This is computed by DUMACH
18 ! in a machine-independent manner.
19 !***REFERENCES (NONE)
20 !***ROUTINES CALLED DUMSUM
21 !***REVISION HISTORY (YYYYMMDD)
22 ! 19930216 DATE WRITTEN
23 ! 19930818 Added SLATEC-format prologue. (FNF)
24 ! 20030707 Added DUMSUM to force normal storage of COMP. (ACH)
25 !***END PROLOGUE DUMACH
26 ! DOUBLE PRECISION :: U, COMP
27 !***FIRST EXECUTABLE STATEMENT DUMACH
28 ! U = 1.0D0
29 ! 10 U = U*0.5D0
30 ! CALL DUMSUM(1.0D0, U, COMP)
31 ! IF (COMP /= 1.0D0) GO TO 10
32 ! DUMACH = U*2.0D0
33 ! RETURN
34 !----------------------- End of Function DUMACH ------------------------
35 ! END PROGRAM
36 ! SUBROUTINE DUMSUM(A,B,C)
37 ! Routine to force normal storing of A + B, for DUMACH.
38 ! DOUBLE PRECISION :: A, B, C
39 ! C = A + B
40 ! RETURN
41 ! END SUBROUTINE DUMSUM
42 ! ECK DCFODE
43 ! SUBROUTINE DCFODE (METH, ELCO, TESCO)
44 !***BEGIN PROLOGUE DCFODE
45 !***SUBSIDIARY
46 !***PURPOSE Set ODE integrator coefficients.
47 !***TYPE DOUBLE PRECISION (SCFODE-S, DCFODE-D)
48 !***AUTHOR Hindmarsh, Alan C., (LLNL)
49 !***DESCRIPTION
50 ! DCFODE is called by the integrator routine to set coefficients
51 ! needed there. The coefficients for the current method, as
52 ! given by the value of METH, are set for all orders and saved.
53 ! The maximum order assumed here is 12 if METH = 1 and 5 if METH = 2.
54 ! (A smaller value of the maximum order is also allowed.)
55 ! DCFODE is called once at the beginning of the problem,
56 ! and is not called again unless and until METH is changed.
57 ! The ELCO array contains the basic method coefficients.
58 ! The coefficients el(i), 1 .le. i .le. nq+1, for the method of
59 ! order nq are stored in ELCO(i,nq). They are given by a genetrating
60 ! polynomial, i.e.,
61 ! l(x) = el(1) + el(2)*x + ... + el(nq+1)*x**nq.
62 ! For the implicit Adams methods, l(x) is given by
63 ! dl/dx = (x+1)*(x+2)*...*(x+nq-1)/factorial(nq-1), l(-1) = 0.
64 ! For the BDF methods, l(x) is given by
65 ! l(x) = (x+1)*(x+2)* ... *(x+nq)/K,
66 ! where K = factorial(nq)*(1 + 1/2 + ... + 1/nq).
67 ! The TESCO array contains test constants used for the
68 ! local error test and the selection of step size and/or order.
69 ! At order nq, TESCO(k,nq) is used for the selection of step
70 ! size at order nq - 1 if k = 1, at order nq if k = 2, and at order
71 ! nq + 1 if k = 3.
72 !***SEE ALSO DLSODE
73 !***ROUTINES CALLED (NONE)
74 !***REVISION HISTORY (YYMMDD)
75 ! 791129 DATE WRITTEN
76 ! 890501 Modified prologue to SLATEC/LDOC format. (FNF)
77 ! 890503 Minor cosmetic changes. (FNF)
78 ! 930809 Renamed to allow single/double precision versions. (ACH)
79 !***END PROLOGUE DCFODE
80 !**End
81 ! INTEGER :: METH
82 ! INTEGER :: I, IB, NQ, NQM1, NQP1
83 ! DOUBLE PRECISION :: ELCO, TESCO
84 ! DOUBLE PRECISION :: AGAMQ, FNQ, FNQM1, PC, PINT, RAGQ, &
85 ! RQFAC, RQ1FAC, TSIGN, XPIN
86 ! DIMENSION ELCO(13,12), TESCO(3,12)
87 ! DIMENSION PC(12)
88 !***FIRST EXECUTABLE STATEMENT DCFODE
89 ! GO TO (100, 200), METH
90 ! 100 ELCO(1,1) = 1.0D0
91 ! ELCO(2,1) = 1.0D0
92 ! TESCO(1,1) = 0.0D0
93 ! TESCO(2,1) = 2.0D0
94 ! TESCO(1,2) = 1.0D0
95 ! TESCO(3,12) = 0.0D0
96 ! PC(1) = 1.0D0
97 ! RQFAC = 1.0D0
98 ! DO 140 NQ = 2,12
99 ! !-----------------------------------------------------------------------
100 ! ! The PC array will contain the coefficients of the polynomial
101 ! ! p(x) = (x+1)*(x+2)*...*(x+nq-1).
102 ! ! Initially, p(x) = 1.
103 ! !-----------------------------------------------------------------------
104 ! RQ1FAC = RQFAC
105 ! RQFAC = RQFAC/NQ
106 ! NQM1 = NQ - 1
107 ! FNQM1 = NQM1
108 ! NQP1 = NQ + 1
109 ! ! Form coefficients of p(x)*(x+nq-1). ----------------------------------
110 ! PC(NQ) = 0.0D0
111 ! DO 110 IB = 1,NQM1
112 ! I = NQP1 - IB
113 ! PC(I) = PC(I-1) + FNQM1*PC(I)
114 ! 110 END DO
115 ! PC(1) = FNQM1*PC(1)
116 ! ! Compute integral, -1 to 0, of p(x) and x*p(x). -----------------------
117 ! PINT = PC(1)
118 ! XPIN = PC(1)/2.0D0
119 ! TSIGN = 1.0D0
120 ! DO 120 I = 2,NQ
121 ! TSIGN = -TSIGN
122 ! PINT = PINT + TSIGN*PC(I)/I
123 ! XPIN = XPIN + TSIGN*PC(I)/(I+1)
124 ! 120 END DO
125 ! ! Store coefficients in ELCO and TESCO. --------------------------------
126 ! ELCO(1,NQ) = PINT*RQ1FAC
127 ! ELCO(2,NQ) = 1.0D0
128 ! DO 130 I = 2,NQ
129 ! ELCO(I+1,NQ) = RQ1FAC*PC(I)/I
130 ! 130 END DO
131 ! AGAMQ = RQFAC*XPIN
132 ! RAGQ = 1.0D0/AGAMQ
133 ! TESCO(2,NQ) = RAGQ
134 ! IF (NQ < 12) TESCO(1,NQP1) = RAGQ*RQFAC/NQP1
135 ! TESCO(3,NQM1) = RAGQ
136 ! 140 END DO
137 ! RETURN
138 ! 200 PC(1) = 1.0D0
139 ! RQ1FAC = 1.0D0
140 ! DO 230 NQ = 1,5
141 ! !-----------------------------------------------------------------------
142 ! ! The PC array will contain the coefficients of the polynomial
143 ! ! p(x) = (x+1)*(x+2)*...*(x+nq).
144 ! ! Initially, p(x) = 1.
145 ! !-----------------------------------------------------------------------
146 ! FNQ = NQ
147 ! NQP1 = NQ + 1
148 ! ! Form coefficients of p(x)*(x+nq). ------------------------------------
149 ! PC(NQP1) = 0.0D0
150 ! DO 210 IB = 1,NQ
151 ! I = NQ + 2 - IB
152 ! PC(I) = PC(I-1) + FNQ*PC(I)
153 ! 210 END DO
154 ! PC(1) = FNQ*PC(1)
155 ! ! Store coefficients in ELCO and TESCO. --------------------------------
156 ! DO 220 I = 1,NQP1
157 ! ELCO(I,NQ) = PC(I)/PC(2)
158 ! 220 END DO
159 ! ELCO(2,NQ) = 1.0D0
160 ! TESCO(1,NQ) = RQ1FAC
161 ! TESCO(2,NQ) = NQP1/ELCO(1,NQ)
162 ! TESCO(3,NQ) = (NQ+2)/ELCO(1,NQ)
163 ! RQ1FAC = RQ1FAC/FNQ
164 ! 230 END DO
165 ! RETURN
166 !----------------------- END OF SUBROUTINE DCFODE ----------------------
167 ! END SUBROUTINE DCFODE
168 ! ECK DINTDY
169 ! SUBROUTINE DINTDY (T, K, YH, NYH, DKY, IFLAG)
170 !***BEGIN PROLOGUE DINTDY
171 !***SUBSIDIARY
172 !***PURPOSE Interpolate solution derivatives.
173 !***TYPE DOUBLE PRECISION (SINTDY-S, DINTDY-D)
174 !***AUTHOR Hindmarsh, Alan C., (LLNL)
175 !***DESCRIPTION
176 ! DINTDY computes interpolated values of the K-th derivative of the
177 ! dependent variable vector y, and stores it in DKY. This routine
178 ! is called within the package with K = 0 and T = TOUT, but may
179 ! also be called by the user for any K up to the current order.
180 ! (See detailed instructions in the usage documentation.)
181 ! The computed values in DKY are gotten by interpolation using the
182 ! Nordsieck history array YH. This array corresponds uniquely to a
183 ! vector-valued polynomial of degree NQCUR or less, and DKY is set
184 ! to the K-th derivative of this polynomial at T.
185 ! The formula for DKY is:
186 ! q
187 ! DKY(i) = sum c(j,K) * (T - tn)**(j-K) * h**(-j) * YH(i,j+1)
188 ! j=K
189 ! where c(j,K) = j*(j-1)*...*(j-K+1), q = NQCUR, tn = TCUR, h = HCUR.
190 ! The quantities nq = NQCUR, l = nq+1, N = NEQ, tn, and h are
191 ! communicated by COMMON. The above sum is done in reverse order.
192 ! IFLAG is returned negative if either K or T is out of bounds.
193 !***SEE ALSO DLSODE
194 !***ROUTINES CALLED XERRWD
195 !***COMMON BLOCKS DLS001
196 !***REVISION HISTORY (YYMMDD)
197 ! 791129 DATE WRITTEN
198 ! 890501 Modified prologue to SLATEC/LDOC format. (FNF)
199 ! 890503 Minor cosmetic changes. (FNF)
200 ! 930809 Renamed to allow single/double precision versions. (ACH)
201 ! 010418 Reduced size of Common block /DLS001/. (ACH)
202 ! 031105 Restored 'own' variables to Common block /DLS001/, to
203 ! enable interrupt/restart feature. (ACH)
204 ! 050427 Corrected roundoff decrement in TP. (ACH)
205 !***END PROLOGUE DINTDY
206 !**End
207 ! INTEGER :: K, NYH, IFLAG
208 ! DOUBLE PRECISION :: T, YH, DKY
209 ! DIMENSION YH(NYH,*), DKY(*)
210 ! INTEGER :: IOWND, IOWNS, &
211 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
212 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
213 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
214 ! DOUBLE PRECISION :: ROWNS, &
215 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
216 ! COMMON /DLS001/ ROWNS(209), &
217 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
218 ! IOWND(6), IOWNS(6), &
219 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
220 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
221 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
222 ! INTEGER :: I, IC, J, JB, JB2, JJ, JJ1, JP1
223 ! DOUBLE PRECISION :: C, R, S, TP
224 ! CHARACTER(80) :: MSG
225 !***FIRST EXECUTABLE STATEMENT DINTDY
226 ! IFLAG = 0
227 ! IF (K < 0 .OR. K > NQ) GO TO 80
228 ! TP = TN - HU - 100.0D0*UROUND*SIGN(ABS(TN) + ABS(HU), HU)
229 ! IF ((T-TP)*(T-TN) > 0.0D0) GO TO 90
230 ! S = (T - TN)/H
231 ! IC = 1
232 ! IF (K == 0) GO TO 15
233 ! JJ1 = L - K
234 ! DO 10 JJ = JJ1,NQ
235 ! IC = IC*JJ
236 ! 10 END DO
237 ! 15 C = IC
238 ! DO 20 I = 1,N
239 ! DKY(I) = C*YH(I,L)
240 ! 20 END DO
241 ! IF (K == NQ) GO TO 55
242 ! JB2 = NQ - K
243 ! DO 50 JB = 1,JB2
244 ! J = NQ - JB
245 ! JP1 = J + 1
246 ! IC = 1
247 ! IF (K == 0) GO TO 35
248 ! JJ1 = JP1 - K
249 ! DO 30 JJ = JJ1,J
250 ! IC = IC*JJ
251 ! 30 END DO
252 ! 35 C = IC
253 ! DO 40 I = 1,N
254 ! DKY(I) = C*YH(I,JP1) + S*DKY(I)
255 ! 40 END DO
256 ! 50 END DO
257 ! IF (K == 0) RETURN
258 ! 55 R = H**(-K)
259 ! DO 60 I = 1,N
260 ! DKY(I) = R*DKY(I)
261 ! 60 END DO
262 ! RETURN
263 ! 80 MSG = 'DINTDY- K (=I1) illegal '
264 ! CALL XERRWD (MSG, 30, 51, 0, 1, K, 0, 0, 0.0D0, 0.0D0)
265 ! IFLAG = -1
266 ! RETURN
267 ! 90 MSG = 'DINTDY- T (=R1) illegal '
268 ! CALL XERRWD (MSG, 30, 52, 0, 0, 0, 0, 1, T, 0.0D0)
269 ! MSG=' T not in interval TCUR - HU (= R1) to TCUR (=R2) '
270 ! CALL XERRWD (MSG, 60, 52, 0, 0, 0, 0, 2, TP, TN)
271 ! IFLAG = -2
272 ! RETURN
273 !----------------------- END OF SUBROUTINE DINTDY ----------------------
274 ! END SUBROUTINE DINTDY
275 ! ECK DPREPJ
276 ! SUBROUTINE DPREPJ (NEQ, Y, YH, NYH, EWT, FTEM, SAVF, WM, IWM, &
277 ! F, JAC)
278 !***BEGIN PROLOGUE DPREPJ
279 !***SUBSIDIARY
280 !***PURPOSE Compute and process Newton iteration matrix.
281 !***TYPE DOUBLE PRECISION (SPREPJ-S, DPREPJ-D)
282 !***AUTHOR Hindmarsh, Alan C., (LLNL)
283 !***DESCRIPTION
284 ! DPREPJ is called by DSTODE to compute and process the matrix
285 ! P = I - h*el(1)*J , where J is an approximation to the Jacobian.
286 ! Here J is computed by the user-supplied routine JAC if
287 ! MITER = 1 or 4, or by finite differencing if MITER = 2, 3, or 5.
288 ! If MITER = 3, a diagonal approximation to J is used.
289 ! J is stored in WM and replaced by P. If MITER .ne. 3, P is then
290 ! subjected to LU decomposition in preparation for later solution
291 ! of linear systems with P as coefficient matrix. This is done
292 ! by DGEFA if MITER = 1 or 2, and by DGBFA if MITER = 4 or 5.
293 ! In addition to variables described in DSTODE and DLSODE prologues,
294 ! communication with DPREPJ uses the following:
295 ! Y = array containing predicted values on entry.
296 ! FTEM = work array of length N (ACOR in DSTODE).
297 ! SAVF = array containing f evaluated at predicted y.
298 ! WM = real work space for matrices. On output it contains the
299 ! inverse diagonal matrix if MITER = 3 and the LU decomposition
300 ! of P if MITER is 1, 2 , 4, or 5.
301 ! Storage of matrix elements starts at WM(3).
302 ! WM also contains the following matrix-related data:
303 ! WM(1) = SQRT(UROUND), used in numerical Jacobian increments.
304 ! WM(2) = H*EL0, saved for later use if MITER = 3.
305 ! IWM = integer work space containing pivot information, starting at
306 ! IWM(21), if MITER is 1, 2, 4, or 5. IWM also contains band
307 ! parameters ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
308 ! EL0 = EL(1) (input).
309 ! IERPJ = output error flag, = 0 if no trouble, .gt. 0 if
310 ! P matrix found to be singular.
311 ! JCUR = output flag = 1 to indicate that the Jacobian matrix
312 ! (or approximation) is now current.
313 ! This routine also uses the COMMON variables EL0, H, TN, UROUND,
314 ! MITER, N, NFE, and NJE.
315 !***SEE ALSO DLSODE
316 !***ROUTINES CALLED DGBFA, DGEFA, DVNORM
317 !***COMMON BLOCKS DLS001
318 !***REVISION HISTORY (YYMMDD)
319 ! 791129 DATE WRITTEN
320 ! 890501 Modified prologue to SLATEC/LDOC format. (FNF)
321 ! 890504 Minor cosmetic changes. (FNF)
322 ! 930809 Renamed to allow single/double precision versions. (ACH)
323 ! 010418 Reduced size of Common block /DLS001/. (ACH)
324 ! 031105 Restored 'own' variables to Common block /DLS001/, to
325 ! enable interrupt/restart feature. (ACH)
326 !***END PROLOGUE DPREPJ
327 !**End
328 ! EXTERNAL F, JAC
329 ! INTEGER :: NEQ, NYH, IWM
330 ! DOUBLE PRECISION :: Y, YH, EWT, FTEM, SAVF, WM
331 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), EWT(*), FTEM(*), SAVF(*), &
332 ! WM(*), IWM(*)
333 ! INTEGER :: IOWND, IOWNS, &
334 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
335 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
336 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
337 ! DOUBLE PRECISION :: ROWNS, &
338 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
339 ! COMMON /DLS001/ ROWNS(209), &
340 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
341 ! IOWND(6), IOWNS(6), &
342 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
343 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
344 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
345 ! INTEGER :: I, I1, I2, IER, II, J, J1, JJ, LENP, &
346 ! MBA, MBAND, MEB1, MEBAND, ML, ML3, MU, NP1
347 ! DOUBLE PRECISION :: CON, DI, FAC, HL0, R, R0, SRUR, YI, YJ, YJJ, &
348 ! DVNORM
349 !***FIRST EXECUTABLE STATEMENT DPREPJ
350 ! NJE = NJE + 1
351 ! IERPJ = 0
352 ! JCUR = 1
353 ! HL0 = H*EL0
354 ! GO TO (100, 200, 300, 400, 500), MITER
355 ! If MITER = 1, call JAC and multiply by scalar. -----------------------
356 ! 100 LENP = N*N
357 ! DO 110 I = 1,LENP
358 ! WM(I+2) = 0.0D0
359 ! 110 END DO
360 ! CALL JAC (NEQ, TN, Y, 0, 0, WM(3), N)
361 ! CON = -HL0
362 ! DO 120 I = 1,LENP
363 ! WM(I+2) = WM(I+2)*CON
364 ! 120 END DO
365 ! GO TO 240
366 ! If MITER = 2, make N calls to F to approximate J. --------------------
367 ! 200 FAC = DVNORM (N, SAVF, EWT)
368 ! R0 = 1000.0D0*ABS(H)*UROUND*N*FAC
369 ! IF (R0 == 0.0D0) R0 = 1.0D0
370 ! SRUR = WM(1)
371 ! J1 = 2
372 ! DO 230 J = 1,N
373 ! YJ = Y(J)
374 ! R = MAX(SRUR*ABS(YJ),R0/EWT(J))
375 ! Y(J) = Y(J) + R
376 ! FAC = -HL0/R
377 ! CALL F (NEQ, TN, Y, FTEM)
378 ! DO 220 I = 1,N
379 ! WM(I+J1) = (FTEM(I) - SAVF(I))*FAC
380 ! 220 END DO
381 ! Y(J) = YJ
382 ! J1 = J1 + N
383 ! 230 END DO
384 ! NFE = NFE + N
385 ! Add identity matrix. -------------------------------------------------
386 ! 240 J = 3
387 ! NP1 = N + 1
388 ! DO 250 I = 1,N
389 ! WM(J) = WM(J) + 1.0D0
390 ! J = J + NP1
391 ! 250 END DO
392 ! Do LU decomposition on P. --------------------------------------------
393 ! CALL DGEFA (WM(3), N, N, IWM(21), IER)
394 ! IF (IER /= 0) IERPJ = 1
395 ! RETURN
396 ! If MITER = 3, construct a diagonal approximation to J and P. ---------
397 ! 300 WM(2) = HL0
398 ! R = EL0*0.1D0
399 ! DO 310 I = 1,N
400 ! Y(I) = Y(I) + R*(H*SAVF(I) - YH(I,2))
401 ! 310 END DO
402 ! CALL F (NEQ, TN, Y, WM(3))
403 ! NFE = NFE + 1
404 ! DO 320 I = 1,N
405 ! R0 = H*SAVF(I) - YH(I,2)
406 ! DI = 0.1D0*R0 - H*(WM(I+2) - SAVF(I))
407 ! WM(I+2) = 1.0D0
408 ! IF (ABS(R0) < UROUND/EWT(I)) GO TO 320
409 ! IF (ABS(DI) == 0.0D0) GO TO 330
410 ! WM(I+2) = 0.1D0*R0/DI
411 ! 320 END DO
412 ! RETURN
413 ! 330 IERPJ = 1
414 ! RETURN
415 ! If MITER = 4, call JAC and multiply by scalar. -----------------------
416 ! 400 ML = IWM(1)
417 ! MU = IWM(2)
418 ! ML3 = ML + 3
419 ! MBAND = ML + MU + 1
420 ! MEBAND = MBAND + ML
421 ! LENP = MEBAND*N
422 ! DO 410 I = 1,LENP
423 ! WM(I+2) = 0.0D0
424 ! 410 END DO
425 ! CALL JAC (NEQ, TN, Y, ML, MU, WM(ML3), MEBAND)
426 ! CON = -HL0
427 ! DO 420 I = 1,LENP
428 ! WM(I+2) = WM(I+2)*CON
429 ! 420 END DO
430 ! GO TO 570
431 ! If MITER = 5, make MBAND calls to F to approximate J. ----------------
432 ! 500 ML = IWM(1)
433 ! MU = IWM(2)
434 ! MBAND = ML + MU + 1
435 ! MBA = MIN(MBAND,N)
436 ! MEBAND = MBAND + ML
437 ! MEB1 = MEBAND - 1
438 ! SRUR = WM(1)
439 ! FAC = DVNORM (N, SAVF, EWT)
440 ! R0 = 1000.0D0*ABS(H)*UROUND*N*FAC
441 ! IF (R0 == 0.0D0) R0 = 1.0D0
442 ! DO 560 J = 1,MBA
443 ! DO 530 I = J,N,MBAND
444 ! YI = Y(I)
445 ! R = MAX(SRUR*ABS(YI),R0/EWT(I))
446 ! Y(I) = Y(I) + R
447 ! 530 END DO
448 ! CALL F (NEQ, TN, Y, FTEM)
449 ! DO 550 JJ = J,N,MBAND
450 ! Y(JJ) = YH(JJ,1)
451 ! YJJ = Y(JJ)
452 ! R = MAX(SRUR*ABS(YJJ),R0/EWT(JJ))
453 ! FAC = -HL0/R
454 ! I1 = MAX(JJ-MU,1)
455 ! I2 = MIN(JJ+ML,N)
456 ! II = JJ*MEB1 - ML + 2
457 ! DO 540 I = I1,I2
458 ! WM(II+I) = (FTEM(I) - SAVF(I))*FAC
459 ! 540 END DO
460 ! 550 END DO
461 ! 560 END DO
462 ! NFE = NFE + MBA
463 ! Add identity matrix. -------------------------------------------------
464 ! 570 II = MBAND + 2
465 ! DO 580 I = 1,N
466 ! WM(II) = WM(II) + 1.0D0
467 ! II = II + MEBAND
468 ! 580 END DO
469 ! Do LU decomposition of P. --------------------------------------------
470 ! CALL DGBFA (WM(3), MEBAND, N, ML, MU, IWM(21), IER)
471 ! IF (IER /= 0) IERPJ = 1
472 ! RETURN
473 !----------------------- END OF SUBROUTINE DPREPJ ----------------------
474 ! END SUBROUTINE DPREPJ
475 ! ECK DSOLSY
476 ! SUBROUTINE DSOLSY (WM, IWM, X, TEM)
477 !***BEGIN PROLOGUE DSOLSY
478 !***SUBSIDIARY
479 !***PURPOSE ODEPACK linear system solver.
480 !***TYPE DOUBLE PRECISION (SSOLSY-S, DSOLSY-D)
481 !***AUTHOR Hindmarsh, Alan C., (LLNL)
482 !***DESCRIPTION
483 ! This routine manages the solution of the linear system arising from
484 ! a chord iteration. It is called if MITER .ne. 0.
485 ! If MITER is 1 or 2, it calls DGESL to accomplish this.
486 ! If MITER = 3 it updates the coefficient h*EL0 in the diagonal
487 ! matrix, and then computes the solution.
488 ! If MITER is 4 or 5, it calls DGBSL.
489 ! Communication with DSOLSY uses the following variables:
490 ! WM = real work space containing the inverse diagonal matrix if
491 ! MITER = 3 and the LU decomposition of the matrix otherwise.
492 ! Storage of matrix elements starts at WM(3).
493 ! WM also contains the following matrix-related data:
494 ! WM(1) = SQRT(UROUND) (not used here),
495 ! WM(2) = HL0, the previous value of h*EL0, used if MITER = 3.
496 ! IWM = integer work space containing pivot information, starting at
497 ! IWM(21), if MITER is 1, 2, 4, or 5. IWM also contains band
498 ! parameters ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
499 ! X = the right-hand side vector on input, and the solution vector
500 ! on output, of length N.
501 ! TEM = vector of work space of length N, not used in this version.
502 ! IERSL = output flag (in COMMON). IERSL = 0 if no trouble occurred.
503 ! IERSL = 1 if a singular matrix arose with MITER = 3.
504 ! This routine also uses the COMMON variables EL0, H, MITER, and N.
505 !***SEE ALSO DLSODE
506 !***ROUTINES CALLED DGBSL, DGESL
507 !***COMMON BLOCKS DLS001
508 !***REVISION HISTORY (YYMMDD)
509 ! 791129 DATE WRITTEN
510 ! 890501 Modified prologue to SLATEC/LDOC format. (FNF)
511 ! 890503 Minor cosmetic changes. (FNF)
512 ! 930809 Renamed to allow single/double precision versions. (ACH)
513 ! 010418 Reduced size of Common block /DLS001/. (ACH)
514 ! 031105 Restored 'own' variables to Common block /DLS001/, to
515 ! enable interrupt/restart feature. (ACH)
516 !***END PROLOGUE DSOLSY
517 !**End
518 ! INTEGER :: IWM
519 ! DOUBLE PRECISION :: WM, X, TEM
520 ! DIMENSION WM(*), IWM(*), X(*), TEM(*)
521 ! INTEGER :: IOWND, IOWNS, &
522 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
523 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
524 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
525 ! DOUBLE PRECISION :: ROWNS, &
526 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
527 ! COMMON /DLS001/ ROWNS(209), &
528 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
529 ! IOWND(6), IOWNS(6), &
530 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
531 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
532 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
533 ! INTEGER :: I, MEBAND, ML, MU
534 ! DOUBLE PRECISION :: DI, HL0, PHL0, R
535 !***FIRST EXECUTABLE STATEMENT DSOLSY
536 ! IERSL = 0
537 ! GO TO (100, 100, 300, 400, 400), MITER
538 ! 100 CALL DGESL (WM(3), N, N, IWM(21), X, 0)
539 ! RETURN
540 ! 300 PHL0 = WM(2)
541 ! HL0 = H*EL0
542 ! WM(2) = HL0
543 ! IF (HL0 == PHL0) GO TO 330
544 ! R = HL0/PHL0
545 ! DO 320 I = 1,N
546 ! DI = 1.0D0 - R*(1.0D0 - 1.0D0/WM(I+2))
547 ! IF (ABS(DI) == 0.0D0) GO TO 390
548 ! WM(I+2) = 1.0D0/DI
549 ! 320 END DO
550 ! 330 DO 340 I = 1,N
551 ! X(I) = WM(I+2)*X(I)
552 ! 340 END DO
553 ! RETURN
554 ! 390 IERSL = 1
555 ! RETURN
556 ! 400 ML = IWM(1)
557 ! MU = IWM(2)
558 ! MEBAND = 2*ML + MU + 1
559 ! CALL DGBSL (WM(3), MEBAND, N, ML, MU, IWM(21), X, 0)
560 ! RETURN
561 !----------------------- END OF SUBROUTINE DSOLSY ----------------------
562 ! END SUBROUTINE DSOLSY
563 ! ECK DSRCOM
564 ! SUBROUTINE DSRCOM (RSAV, ISAV, JOB)
565 !***BEGIN PROLOGUE DSRCOM
566 !***SUBSIDIARY
567 !***PURPOSE Save/restore ODEPACK COMMON blocks.
568 !***TYPE DOUBLE PRECISION (SSRCOM-S, DSRCOM-D)
569 !***AUTHOR Hindmarsh, Alan C., (LLNL)
570 !***DESCRIPTION
571 ! This routine saves or restores (depending on JOB) the contents of
572 ! the COMMON block DLS001, which is used internally
573 ! by one or more ODEPACK solvers.
574 ! RSAV = real array of length 218 or more.
575 ! ISAV = integer array of length 37 or more.
576 ! JOB = flag indicating to save or restore the COMMON blocks:
577 ! JOB = 1 if COMMON is to be saved (written to RSAV/ISAV)
578 ! JOB = 2 if COMMON is to be restored (read from RSAV/ISAV)
579 ! A call with JOB = 2 presumes a prior call with JOB = 1.
580 !***SEE ALSO DLSODE
581 !***ROUTINES CALLED (NONE)
582 !***COMMON BLOCKS DLS001
583 !***REVISION HISTORY (YYMMDD)
584 ! 791129 DATE WRITTEN
585 ! 890501 Modified prologue to SLATEC/LDOC format. (FNF)
586 ! 890503 Minor cosmetic changes. (FNF)
587 ! 921116 Deleted treatment of block /EH0001/. (ACH)
588 ! 930801 Reduced Common block length by 2. (ACH)
589 ! 930809 Renamed to allow single/double precision versions. (ACH)
590 ! 010418 Reduced Common block length by 209+12. (ACH)
591 ! 031105 Restored 'own' variables to Common block /DLS001/, to
592 ! enable interrupt/restart feature. (ACH)
593 ! 031112 Added SAVE statement for data-loaded constants.
594 !***END PROLOGUE DSRCOM
595 !**End
596 ! INTEGER :: ISAV, JOB
597 ! INTEGER :: ILS
598 ! INTEGER :: I, LENILS, LENRLS
599 ! DOUBLE PRECISION :: RSAV, RLS
600 ! DIMENSION RSAV(*), ISAV(*)
601 ! SAVE LENRLS, LENILS
602 ! COMMON /DLS001/ RLS(218), ILS(37)
603 ! DATA LENRLS/218/, LENILS/37/
604 !***FIRST EXECUTABLE STATEMENT DSRCOM
605 ! IF (JOB == 2) GO TO 100
606 ! DO 10 I = 1,LENRLS
607 ! RSAV(I) = RLS(I)
608 ! 10 END DO
609 ! DO 20 I = 1,LENILS
610 ! ISAV(I) = ILS(I)
611 ! 20 END DO
612 ! RETURN
613 ! 100 CONTINUE
614 ! DO 110 I = 1,LENRLS
615 ! RLS(I) = RSAV(I)
616 ! 110 END DO
617 ! DO 120 I = 1,LENILS
618 ! ILS(I) = ISAV(I)
619 ! 120 END DO
620 ! RETURN
621 !----------------------- END OF SUBROUTINE DSRCOM ----------------------
622 ! END SUBROUTINE DSRCOM
623 ! ECK DSTODE
624 ! SUBROUTINE DSTODE (NEQ, Y, YH, NYH, YH1, EWT, SAVF, ACOR, &
625 ! WM, IWM, F, JAC, PJAC, SLVS)
626 !***BEGIN PROLOGUE DSTODE
627 !***SUBSIDIARY
628 !***PURPOSE Performs one step of an ODEPACK integration.
629 !***TYPE DOUBLE PRECISION (SSTODE-S, DSTODE-D)
630 !***AUTHOR Hindmarsh, Alan C., (LLNL)
631 !***DESCRIPTION
632 ! DSTODE performs one step of the integration of an initial value
633 ! problem for a system of ordinary differential equations.
634 ! Note: DSTODE is independent of the value of the iteration method
635 ! indicator MITER, when this is .ne. 0, and hence is independent
636 ! of the type of chord method used, or the Jacobian structure.
637 ! Communication with DSTODE is done with the following variables:
638 ! NEQ = integer array containing problem size in NEQ(1), and
639 ! passed as the NEQ argument in all calls to F and JAC.
640 ! Y = an array of length .ge. N used as the Y argument in
641 ! all calls to F and JAC.
642 ! YH = an NYH by LMAX array containing the dependent variables
643 ! and their approximate scaled derivatives, where
644 ! LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
645 ! j-th derivative of y(i), scaled by h**j/factorial(j)
646 ! (j = 0,1,...,NQ). on entry for the first step, the first
647 ! two columns of YH must be set from the initial values.
648 ! NYH = a constant integer .ge. N, the first dimension of YH.
649 ! YH1 = a one-dimensional array occupying the same space as YH.
650 ! EWT = an array of length N containing multiplicative weights
651 ! for local error measurements. Local errors in Y(i) are
652 ! compared to 1.0/EWT(i) in various error tests.
653 ! SAVF = an array of working storage, of length N.
654 ! Also used for input of YH(*,MAXORD+2) when JSTART = -1
655 ! and MAXORD .lt. the current order NQ.
656 ! ACOR = a work array of length N, used for the accumulated
657 ! corrections. On a successful return, ACOR(i) contains
658 ! the estimated one-step local error in Y(i).
659 ! WM,IWM = real and integer work arrays associated with matrix
660 ! operations in chord iteration (MITER .ne. 0).
661 ! PJAC = name of routine to evaluate and preprocess Jacobian matrix
662 ! and P = I - h*el0*JAC, if a chord method is being used.
663 ! SLVS = name of routine to solve linear system in chord iteration.
664 ! CCMAX = maximum relative change in h*el0 before PJAC is called.
665 ! H = the step size to be attempted on the next step.
666 ! H is altered by the error control algorithm during the
667 ! problem. H can be either positive or negative, but its
668 ! sign must remain constant throughout the problem.
669 ! HMIN = the minimum absolute value of the step size h to be used.
670 ! HMXI = inverse of the maximum absolute value of h to be used.
671 ! HMXI = 0.0 is allowed and corresponds to an infinite hmax.
672 ! HMIN and HMXI may be changed at any time, but will not
673 ! take effect until the next change of h is considered.
674 ! TN = the independent variable. TN is updated on each step taken.
675 ! JSTART = an integer used for input only, with the following
676 ! values and meanings:
677 ! 0 perform the first step.
678 ! .gt.0 take a new step continuing from the last.
679 ! -1 take the next step with a new value of H, MAXORD,
680 ! N, METH, MITER, and/or matrix parameters.
681 ! -2 take the next step with a new value of H,
682 ! but with other inputs unchanged.
683 ! On return, JSTART is set to 1 to facilitate continuation.
684 ! KFLAG = a completion code with the following meanings:
685 ! 0 the step was succesful.
686 ! -1 the requested error could not be achieved.
687 ! -2 corrector convergence could not be achieved.
688 ! -3 fatal error in PJAC or SLVS.
689 ! A return with KFLAG = -1 or -2 means either
690 ! abs(H) = HMIN or 10 consecutive failures occurred.
691 ! On a return with KFLAG negative, the values of TN and
692 ! the YH array are as of the beginning of the last
693 ! step, and H is the last step size attempted.
694 ! MAXORD = the maximum order of integration method to be allowed.
695 ! MAXCOR = the maximum number of corrector iterations allowed.
696 ! MSBP = maximum number of steps between PJAC calls (MITER .gt. 0).
697 ! MXNCF = maximum number of convergence failures allowed.
698 ! METH/MITER = the method flags. See description in driver.
699 ! N = the number of first-order differential equations.
700 ! The values of CCMAX, H, HMIN, HMXI, TN, JSTART, KFLAG, MAXORD,
701 ! MAXCOR, MSBP, MXNCF, METH, MITER, and N are communicated via COMMON.
702 !***SEE ALSO DLSODE
703 !***ROUTINES CALLED DCFODE, DVNORM
704 !***COMMON BLOCKS DLS001
705 !***REVISION HISTORY (YYMMDD)
706 ! 791129 DATE WRITTEN
707 ! 890501 Modified prologue to SLATEC/LDOC format. (FNF)
708 ! 890503 Minor cosmetic changes. (FNF)
709 ! 930809 Renamed to allow single/double precision versions. (ACH)
710 ! 010418 Reduced size of Common block /DLS001/. (ACH)
711 ! 031105 Restored 'own' variables to Common block /DLS001/, to
712 ! enable interrupt/restart feature. (ACH)
713 !***END PROLOGUE DSTODE
714 !**End
715 ! EXTERNAL F, JAC, PJAC, SLVS
716 ! INTEGER :: NEQ, NYH, IWM
717 ! DOUBLE PRECISION :: Y, YH, YH1, EWT, SAVF, ACOR, WM
718 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), YH1(*), EWT(*), SAVF(*), &
719 ! ACOR(*), WM(*), IWM(*)
720 ! INTEGER :: IOWND, IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, &
721 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
722 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
723 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
724 ! INTEGER :: I, I1, IREDO, IRET, J, JB, M, NCF, NEWQ
725 ! DOUBLE PRECISION :: CONIT, CRATE, EL, ELCO, HOLD, RMAX, TESCO, &
726 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
727 ! DOUBLE PRECISION :: DCON, DDN, DEL, DELP, DSM, DUP, EXDN, EXSM, EXUP, &
728 ! R, RH, RHDN, RHSM, RHUP, TOLD, DVNORM
729 ! COMMON /DLS001/ CONIT, CRATE, EL(13), ELCO(13,12), &
730 ! HOLD, RMAX, TESCO(3,12), &
731 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
732 ! IOWND(6), IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, &
733 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
734 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
735 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
736 !***FIRST EXECUTABLE STATEMENT DSTODE
737 ! KFLAG = 0
738 ! TOLD = TN
739 ! NCF = 0
740 ! IERPJ = 0
741 ! IERSL = 0
742 ! JCUR = 0
743 ! ICF = 0
744 ! DELP = 0.0D0
745 ! IF (JSTART > 0) GO TO 200
746 ! IF (JSTART == -1) GO TO 100
747 ! IF (JSTART == -2) GO TO 160
748 !-----------------------------------------------------------------------
749 ! On the first call, the order is set to 1, and other variables are
750 ! initialized. RMAX is the maximum ratio by which H can be increased
751 ! in a single step. It is initially 1.E4 to compensate for the small
752 ! initial H, but then is normally equal to 10. If a failure
753 ! occurs (in corrector convergence or error test), RMAX is set to 2
754 ! for the next increase.
755 !-----------------------------------------------------------------------
756 ! LMAX = MAXORD + 1
757 ! NQ = 1
758 ! L = 2
759 ! IALTH = 2
760 ! RMAX = 10000.0D0
761 ! RC = 0.0D0
762 ! EL0 = 1.0D0
763 ! CRATE = 0.7D0
764 ! HOLD = H
765 ! MEO = METH
766 ! NSLP = 0
767 ! IPUP = MITER
768 ! IRET = 3
769 ! GO TO 140
770 !-----------------------------------------------------------------------
771 ! The following block handles preliminaries needed when JSTART = -1.
772 ! IPUP is set to MITER to force a matrix update.
773 ! If an order increase is about to be considered (IALTH = 1),
774 ! IALTH is reset to 2 to postpone consideration one more step.
775 ! If the caller has changed METH, DCFODE is called to reset
776 ! the coefficients of the method.
777 ! If the caller has changed MAXORD to a value less than the current
778 ! order NQ, NQ is reduced to MAXORD, and a new H chosen accordingly.
779 ! If H is to be changed, YH must be rescaled.
780 ! If H or METH is being changed, IALTH is reset to L = NQ + 1
781 ! to prevent further changes in H for that many steps.
782 !-----------------------------------------------------------------------
783 ! 100 IPUP = MITER
784 ! LMAX = MAXORD + 1
785 ! IF (IALTH == 1) IALTH = 2
786 ! IF (METH == MEO) GO TO 110
787 ! CALL DCFODE (METH, ELCO, TESCO)
788 ! MEO = METH
789 ! IF (NQ > MAXORD) GO TO 120
790 ! IALTH = L
791 ! IRET = 1
792 ! GO TO 150
793 ! 110 IF (NQ <= MAXORD) GO TO 160
794 ! 120 NQ = MAXORD
795 ! L = LMAX
796 ! DO 125 I = 1,L
797 ! EL(I) = ELCO(I,NQ)
798 ! 125 END DO
799 ! NQNYH = NQ*NYH
800 ! RC = RC*EL(1)/EL0
801 ! EL0 = EL(1)
802 ! CONIT = 0.5D0/(NQ+2)
803 ! DDN = DVNORM (N, SAVF, EWT)/TESCO(1,L)
804 ! EXDN = 1.0D0/L
805 ! RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
806 ! RH = MIN(RHDN,1.0D0)
807 ! IREDO = 3
808 ! IF (H == HOLD) GO TO 170
809 ! RH = MIN(RH,ABS(H/HOLD))
810 ! H = HOLD
811 ! GO TO 175
812 !-----------------------------------------------------------------------
813 ! DCFODE is called to get all the integration coefficients for the
814 ! current METH. Then the EL vector and related constants are reset
815 ! whenever the order NQ is changed, or at the start of the problem.
816 !-----------------------------------------------------------------------
817 ! 140 CALL DCFODE (METH, ELCO, TESCO)
818 ! 150 DO 155 I = 1,L
819 ! EL(I) = ELCO(I,NQ)
820 ! 155 END DO
821 ! NQNYH = NQ*NYH
822 ! RC = RC*EL(1)/EL0
823 ! EL0 = EL(1)
824 ! CONIT = 0.5D0/(NQ+2)
825 ! GO TO (160, 170, 200), IRET
826 !-----------------------------------------------------------------------
827 ! If H is being changed, the H ratio RH is checked against
828 ! RMAX, HMIN, and HMXI, and the YH array rescaled. IALTH is set to
829 ! L = NQ + 1 to prevent a change of H for that many steps, unless
830 ! forced by a convergence or error test failure.
831 !-----------------------------------------------------------------------
832 ! 160 IF (H == HOLD) GO TO 200
833 ! RH = H/HOLD
834 ! H = HOLD
835 ! IREDO = 3
836 ! GO TO 175
837 ! 170 RH = MAX(RH,HMIN/ABS(H))
838 ! 175 RH = MIN(RH,RMAX)
839 ! RH = RH/MAX(1.0D0,ABS(H)*HMXI*RH)
840 ! R = 1.0D0
841 ! DO 180 J = 2,L
842 ! R = R*RH
843 ! DO 180 I = 1,N
844 ! YH(I,J) = YH(I,J)*R
845 ! 180 END DO
846 ! H = H*RH
847 ! RC = RC*RH
848 ! IALTH = L
849 ! IF (IREDO == 0) GO TO 690
850 !-----------------------------------------------------------------------
851 ! This section computes the predicted values by effectively
852 ! multiplying the YH array by the Pascal Triangle matrix.
853 ! RC is the ratio of new to old values of the coefficient H*EL(1).
854 ! When RC differs from 1 by more than CCMAX, IPUP is set to MITER
855 ! to force PJAC to be called, if a Jacobian is involved.
856 ! In any case, PJAC is called at least every MSBP steps.
857 !-----------------------------------------------------------------------
858 ! 200 IF (ABS(RC-1.0D0) > CCMAX) IPUP = MITER
859 ! IF (NST >= NSLP+MSBP) IPUP = MITER
860 ! TN = TN + H
861 ! I1 = NQNYH + 1
862 ! DO 215 JB = 1,NQ
863 ! I1 = I1 - NYH
864 ! ! ir$ ivdep
865 ! DO 210 I = I1,NQNYH
866 ! YH1(I) = YH1(I) + YH1(I+NYH)
867 ! 210 END DO
868 ! 215 END DO
869 !-----------------------------------------------------------------------
870 ! Up to MAXCOR corrector iterations are taken. A convergence test is
871 ! made on the R.M.S. norm of each correction, weighted by the error
872 ! weight vector EWT. The sum of the corrections is accumulated in the
873 ! vector ACOR(i). The YH array is not altered in the corrector loop.
874 !-----------------------------------------------------------------------
875 ! 220 M = 0
876 ! DO 230 I = 1,N
877 ! Y(I) = YH(I,1)
878 ! 230 END DO
879 ! CALL F (NEQ, TN, Y, SAVF)
880 ! NFE = NFE + 1
881 ! IF (IPUP <= 0) GO TO 250
882 !-----------------------------------------------------------------------
883 ! If indicated, the matrix P = I - h*el(1)*J is reevaluated and
884 ! preprocessed before starting the corrector iteration. IPUP is set
885 ! to 0 as an indicator that this has been done.
886 !-----------------------------------------------------------------------
887 ! CALL PJAC (NEQ, Y, YH, NYH, EWT, ACOR, SAVF, WM, IWM, F, JAC)
888 ! IPUP = 0
889 ! RC = 1.0D0
890 ! NSLP = NST
891 ! CRATE = 0.7D0
892 ! IF (IERPJ /= 0) GO TO 430
893 ! 250 DO 260 I = 1,N
894 ! ACOR(I) = 0.0D0
895 ! 260 END DO
896 ! 270 IF (MITER /= 0) GO TO 350
897 !-----------------------------------------------------------------------
898 ! In the case of functional iteration, update Y directly from
899 ! the result of the last function evaluation.
900 !-----------------------------------------------------------------------
901 ! DO 290 I = 1,N
902 ! SAVF(I) = H*SAVF(I) - YH(I,2)
903 ! Y(I) = SAVF(I) - ACOR(I)
904 ! 290 END DO
905 ! DEL = DVNORM (N, Y, EWT)
906 ! DO 300 I = 1,N
907 ! Y(I) = YH(I,1) + EL(1)*SAVF(I)
908 ! ACOR(I) = SAVF(I)
909 ! 300 END DO
910 ! GO TO 400
911 !-----------------------------------------------------------------------
912 ! In the case of the chord method, compute the corrector error,
913 ! and solve the linear system with that as right-hand side and
914 ! P as coefficient matrix.
915 !-----------------------------------------------------------------------
916 ! 350 DO 360 I = 1,N
917 ! Y(I) = H*SAVF(I) - (YH(I,2) + ACOR(I))
918 ! 360 END DO
919 ! CALL SLVS (WM, IWM, Y, SAVF)
920 ! IF (IERSL < 0) GO TO 430
921 ! IF (IERSL > 0) GO TO 410
922 ! DEL = DVNORM (N, Y, EWT)
923 ! DO 380 I = 1,N
924 ! ACOR(I) = ACOR(I) + Y(I)
925 ! Y(I) = YH(I,1) + EL(1)*ACOR(I)
926 ! 380 END DO
927 !-----------------------------------------------------------------------
928 ! Test for convergence. If M.gt.0, an estimate of the convergence
929 ! rate constant is stored in CRATE, and this is used in the test.
930 !-----------------------------------------------------------------------
931 ! 400 IF (M /= 0) CRATE = MAX(0.2D0*CRATE,DEL/DELP)
932 ! DCON = DEL*MIN(1.0D0,1.5D0*CRATE)/(TESCO(2,NQ)*CONIT)
933 ! IF (DCON <= 1.0D0) GO TO 450
934 ! M = M + 1
935 ! IF (M == MAXCOR) GO TO 410
936 ! IF (M >= 2 .AND. DEL > 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 !-----------------------------------------------------------------------
942 ! The corrector iteration failed to converge.
943 ! If MITER .ne. 0 and the Jacobian is out of date, PJAC is called for
944 ! the next try. Otherwise the YH array is retracted to its values
945 ! before prediction, and H is reduced, if possible. If H cannot be
946 ! reduced or MXNCF failures have occurred, exit with KFLAG = -2.
947 !-----------------------------------------------------------------------
948 ! 410 IF (MITER == 0 .OR. JCUR == 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 ! ! ir$ ivdep
960 ! DO 440 I = I1,NQNYH
961 ! YH1(I) = YH1(I) - YH1(I+NYH)
962 ! 440 END DO
963 ! 445 END DO
964 ! IF (IERPJ < 0 .OR. IERSL < 0) GO TO 680
965 ! IF (ABS(H) <= HMIN*1.00001D0) GO TO 670
966 ! IF (NCF == MXNCF) GO TO 670
967 ! RH = 0.25D0
968 ! IPUP = MITER
969 ! IREDO = 1
970 ! GO TO 170
971 !-----------------------------------------------------------------------
972 ! The corrector has converged. JCUR is set to 0
973 ! to signal that the Jacobian involved may need updating later.
974 ! The local error test is made and control passes to statement 500
975 ! if it fails.
976 !-----------------------------------------------------------------------
977 ! 450 JCUR = 0
978 ! IF (M == 0) DSM = DEL/TESCO(2,NQ)
979 ! IF (M > 0) DSM = DVNORM (N, ACOR, EWT)/TESCO(2,NQ)
980 ! IF (DSM > 1.0D0) GO TO 500
981 !-----------------------------------------------------------------------
982 ! After a successful step, update the YH array.
983 ! Consider changing H if IALTH = 1. Otherwise decrease IALTH by 1.
984 ! If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
985 ! use in a possible order increase on the next step.
986 ! If a change in H is considered, an increase or decrease in order
987 ! by one is considered also. A change in H is made only if it is by a
988 ! factor of at least 1.1. If not, IALTH is set to 3 to prevent
989 ! testing for that many steps.
990 !-----------------------------------------------------------------------
991 ! KFLAG = 0
992 ! IREDO = 0
993 ! NST = NST + 1
994 ! HU = H
995 ! NQU = NQ
996 ! DO 470 J = 1,L
997 ! DO 470 I = 1,N
998 ! YH(I,J) = YH(I,J) + EL(J)*ACOR(I)
999 ! 470 END DO
1000 ! IALTH = IALTH - 1
1001 ! IF (IALTH == 0) GO TO 520
1002 ! IF (IALTH > 1) GO TO 700
1003 ! IF (L == LMAX) GO TO 700
1004 ! DO 490 I = 1,N
1005 ! YH(I,LMAX) = ACOR(I)
1006 ! 490 END DO
1007 ! GO TO 700
1008 !-----------------------------------------------------------------------
1009 ! The error test failed. KFLAG keeps track of multiple failures.
1010 ! Restore TN and the YH array to their previous values, and prepare
1011 ! to try the step again. Compute the optimum step size for this or
1012 ! one lower order. After 2 or more failures, H is forced to decrease
1013 ! by a factor of 0.2 or less.
1014 !-----------------------------------------------------------------------
1015 ! 500 KFLAG = KFLAG - 1
1016 ! TN = TOLD
1017 ! I1 = NQNYH + 1
1018 ! DO 515 JB = 1,NQ
1019 ! I1 = I1 - NYH
1020 ! ! ir$ ivdep
1021 ! DO 510 I = I1,NQNYH
1022 ! YH1(I) = YH1(I) - YH1(I+NYH)
1023 ! 510 END DO
1024 ! 515 END DO
1025 ! RMAX = 2.0D0
1026 ! IF (ABS(H) <= HMIN*1.00001D0) GO TO 660
1027 ! IF (KFLAG <= -3) GO TO 640
1028 ! IREDO = 2
1029 ! RHUP = 0.0D0
1030 ! GO TO 540
1031 !-----------------------------------------------------------------------
1032 ! Regardless of the success or failure of the step, factors
1033 ! RHDN, RHSM, and RHUP are computed, by which H could be multiplied
1034 ! at order NQ - 1, order NQ, or order NQ + 1, respectively.
1035 ! In the case of failure, RHUP = 0.0 to avoid an order increase.
1036 ! The largest of these is determined and the new order chosen
1037 ! accordingly. If the order is to be increased, we compute one
1038 ! additional scaled derivative.
1039 !-----------------------------------------------------------------------
1040 ! 520 RHUP = 0.0D0
1041 ! IF (L == LMAX) GO TO 540
1042 ! DO 530 I = 1,N
1043 ! SAVF(I) = ACOR(I) - YH(I,LMAX)
1044 ! 530 END DO
1045 ! DUP = DVNORM (N, SAVF, EWT)/TESCO(3,NQ)
1046 ! EXUP = 1.0D0/(L+1)
1047 ! RHUP = 1.0D0/(1.4D0*DUP**EXUP + 0.0000014D0)
1048 ! 540 EXSM = 1.0D0/L
1049 ! RHSM = 1.0D0/(1.2D0*DSM**EXSM + 0.0000012D0)
1050 ! RHDN = 0.0D0
1051 ! IF (NQ == 1) GO TO 560
1052 ! DDN = DVNORM (N, YH(1,L), EWT)/TESCO(1,NQ)
1053 ! EXDN = 1.0D0/NQ
1054 ! RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
1055 ! 560 IF (RHSM >= RHUP) GO TO 570
1056 ! IF (RHUP > RHDN) GO TO 590
1057 ! GO TO 580
1058 ! 570 IF (RHSM < RHDN) GO TO 580
1059 ! NEWQ = NQ
1060 ! RH = RHSM
1061 ! GO TO 620
1062 ! 580 NEWQ = NQ - 1
1063 ! RH = RHDN
1064 ! IF (KFLAG < 0 .AND. RH > 1.0D0) RH = 1.0D0
1065 ! GO TO 620
1066 ! 590 NEWQ = L
1067 ! RH = RHUP
1068 ! IF (RH < 1.1D0) GO TO 610
1069 ! R = EL(L)/L
1070 ! DO 600 I = 1,N
1071 ! YH(I,NEWQ+1) = ACOR(I)*R
1072 ! 600 END DO
1073 ! GO TO 630
1074 ! 610 IALTH = 3
1075 ! GO TO 700
1076 ! 620 IF ((KFLAG == 0) .AND. (RH < 1.1D0)) GO TO 610
1077 ! IF (KFLAG <= -2) RH = MIN(RH,0.2D0)
1078 !-----------------------------------------------------------------------
1079 ! If there is a change of order, reset NQ, l, and the coefficients.
1080 ! In any case H is reset according to RH and the YH array is rescaled.
1081 ! Then exit from 690 if the step was OK, or redo the step otherwise.
1082 !-----------------------------------------------------------------------
1083 ! IF (NEWQ == NQ) GO TO 170
1084 ! 630 NQ = NEWQ
1085 ! L = NQ + 1
1086 ! IRET = 2
1087 ! GO TO 150
1088 !-----------------------------------------------------------------------
1089 ! Control reaches this section if 3 or more failures have occured.
1090 ! If 10 failures have occurred, exit with KFLAG = -1.
1091 ! It is assumed that the derivatives that have accumulated in the
1092 ! YH array have errors of the wrong order. Hence the first
1093 ! derivative is recomputed, and the order is set to 1. Then
1094 ! H is reduced by a factor of 10, and the step is retried,
1095 ! until it succeeds or H reaches HMIN.
1096 !-----------------------------------------------------------------------
1097 ! 640 IF (KFLAG == -10) GO TO 660
1098 ! RH = 0.1D0
1099 ! RH = MAX(HMIN/ABS(H),RH)
1100 ! H = H*RH
1101 ! DO 645 I = 1,N
1102 ! Y(I) = YH(I,1)
1103 ! 645 END DO
1104 ! CALL F (NEQ, TN, Y, SAVF)
1105 ! NFE = NFE + 1
1106 ! DO 650 I = 1,N
1107 ! YH(I,2) = H*SAVF(I)
1108 ! 650 END DO
1109 ! IPUP = MITER
1110 ! IALTH = 5
1111 ! IF (NQ == 1) GO TO 200
1112 ! NQ = 1
1113 ! L = 2
1114 ! IRET = 3
1115 ! GO TO 150
1116 !-----------------------------------------------------------------------
1117 ! All returns are made through this section. H is saved in HOLD
1118 ! to allow the caller to change H on the next step.
1119 !-----------------------------------------------------------------------
1120 ! 660 KFLAG = -1
1121 ! GO TO 720
1122 ! 670 KFLAG = -2
1123 ! GO TO 720
1124 ! 680 KFLAG = -3
1125 ! GO TO 720
1126 ! 690 RMAX = 10.0D0
1127 ! 700 R = 1.0D0/TESCO(2,NQU)
1128 ! DO 710 I = 1,N
1129 ! ACOR(I) = ACOR(I)*R
1130 ! 710 END DO
1131 ! 720 HOLD = H
1132 ! JSTART = 1
1133 ! RETURN
1134 !----------------------- END OF SUBROUTINE DSTODE ----------------------
1135 ! END SUBROUTINE DSTODE
1136 ! ECK DEWSET
1137 ! SUBROUTINE DEWSET (N, ITOL, RTOL, ATOL, YCUR, EWT)
1138 !***BEGIN PROLOGUE DEWSET
1139 !***SUBSIDIARY
1140 !***PURPOSE Set error weight vector.
1141 !***TYPE DOUBLE PRECISION (SEWSET-S, DEWSET-D)
1142 !***AUTHOR Hindmarsh, Alan C., (LLNL)
1143 !***DESCRIPTION
1144 ! This subroutine sets the error weight vector EWT according to
1145 ! EWT(i) = RTOL(i)*ABS(YCUR(i)) + ATOL(i), i = 1,...,N,
1146 ! with the subscript on RTOL and/or ATOL possibly replaced by 1 above,
1147 ! depending on the value of ITOL.
1148 !***SEE ALSO DLSODE
1149 !***ROUTINES CALLED (NONE)
1150 !***REVISION HISTORY (YYMMDD)
1151 ! 791129 DATE WRITTEN
1152 ! 890501 Modified prologue to SLATEC/LDOC format. (FNF)
1153 ! 890503 Minor cosmetic changes. (FNF)
1154 ! 930809 Renamed to allow single/double precision versions. (ACH)
1155 !***END PROLOGUE DEWSET
1156 !**End
1157 ! INTEGER :: N, ITOL
1158 ! INTEGER :: I
1159 ! DOUBLE PRECISION :: RTOL, ATOL, YCUR, EWT
1160 ! DIMENSION RTOL(*), ATOL(*), YCUR(N), EWT(N)
1161 !***FIRST EXECUTABLE STATEMENT DEWSET
1162 ! GO TO (10, 20, 30, 40), ITOL
1163 ! 10 CONTINUE
1164 ! DO 15 I = 1,N
1165 ! EWT(I) = RTOL(1)*ABS(YCUR(I)) + ATOL(1)
1166 ! 15 END DO
1167 ! RETURN
1168 ! 20 CONTINUE
1169 ! DO 25 I = 1,N
1170 ! EWT(I) = RTOL(1)*ABS(YCUR(I)) + ATOL(I)
1171 ! 25 END DO
1172 ! RETURN
1173 ! 30 CONTINUE
1174 ! DO 35 I = 1,N
1175 ! EWT(I) = RTOL(I)*ABS(YCUR(I)) + ATOL(1)
1176 ! 35 END DO
1177 ! RETURN
1178 ! 40 CONTINUE
1179 ! DO 45 I = 1,N
1180 ! EWT(I) = RTOL(I)*ABS(YCUR(I)) + ATOL(I)
1181 ! 45 END DO
1182 ! RETURN
1183 !----------------------- END OF SUBROUTINE DEWSET ----------------------
1184 ! END SUBROUTINE DEWSET
1185 ! ECK DVNORM
1186 ! DOUBLE PRECISION :: FUNCTION DVNORM (N, V, W)
1187 !***BEGIN PROLOGUE DVNORM
1188 !***SUBSIDIARY
1189 !***PURPOSE Weighted root-mean-square vector norm.
1190 !***TYPE DOUBLE PRECISION (SVNORM-S, DVNORM-D)
1191 !***AUTHOR Hindmarsh, Alan C., (LLNL)
1192 !***DESCRIPTION
1193 ! This function routine computes the weighted root-mean-square norm
1194 ! of the vector of length N contained in the array V, with weights
1195 ! contained in the array W of length N:
1196 ! DVNORM = SQRT( (1/N) * SUM( V(i)*W(i) )**2 )
1197 !***SEE ALSO DLSODE
1198 !***ROUTINES CALLED (NONE)
1199 !***REVISION HISTORY (YYMMDD)
1200 ! 791129 DATE WRITTEN
1201 ! 890501 Modified prologue to SLATEC/LDOC format. (FNF)
1202 ! 890503 Minor cosmetic changes. (FNF)
1203 ! 930809 Renamed to allow single/double precision versions. (ACH)
1204 !***END PROLOGUE DVNORM
1205 !**End
1206 ! INTEGER :: N, I
1207 ! DOUBLE PRECISION :: V, W, SUM
1208 ! DIMENSION V(N), W(N)
1209 !***FIRST EXECUTABLE STATEMENT DVNORM
1210 ! SUM = 0.0D0
1211 ! DO 10 I = 1,N
1212 ! SUM = SUM + (V(I)*W(I))**2
1213 ! 10 END DO
1214 ! DVNORM = SQRT(SUM/N)
1215 ! RETURN
1216 !----------------------- END OF FUNCTION DVNORM ------------------------
1217 ! END PROGRAM
1218 ! ECK DIPREP
1219 ! SUBROUTINE DIPREP (NEQ, Y, RWORK, IA, JA, IPFLAG, F, JAC)
1220 ! EXTERNAL F, JAC
1221 ! INTEGER :: NEQ, IA, JA, IPFLAG
1222 ! DOUBLE PRECISION :: Y, RWORK
1223 ! DIMENSION NEQ(*), Y(*), RWORK(*), IA(*), JA(*)
1224 ! INTEGER :: IOWND, IOWNS, &
1225 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
1226 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
1227 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
1228 ! INTEGER :: IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
1229 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
1230 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
1231 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
1232 ! DOUBLE PRECISION :: ROWNS, &
1233 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
1234 ! DOUBLE PRECISION :: RLSS
1235 ! COMMON /DLS001/ ROWNS(209), &
1236 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
1237 ! IOWND(6), IOWNS(6), &
1238 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
1239 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
1240 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
1241 ! COMMON /DLSS01/ RLSS(6), &
1242 ! IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
1243 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
1244 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
1245 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
1246 ! INTEGER :: I, IMAX, LEWTN, LYHD, LYHN
1247 !-----------------------------------------------------------------------
1248 ! This routine serves as an interface between the driver and
1249 ! Subroutine DPREP. It is called only if MITER is 1 or 2.
1250 ! Tasks performed here are:
1251 ! * call DPREP,
1252 ! * reset the required WM segment length LENWK,
1253 ! * move YH back to its final location (following WM in RWORK),
1254 ! * reset pointers for YH, SAVF, EWT, and ACOR, and
1255 ! * move EWT to its new position if ISTATE = 1.
1256 ! IPFLAG is an output error indication flag. IPFLAG = 0 if there was
1257 ! no trouble, and IPFLAG is the value of the DPREP error flag IPPER
1258 ! if there was trouble in Subroutine DPREP.
1259 !-----------------------------------------------------------------------
1260 ! IPFLAG = 0
1261 ! Call DPREP to do matrix preprocessing operations. --------------------
1262 ! CALL DPREP (NEQ, Y, RWORK(LYH), RWORK(LSAVF), RWORK(LEWT), &
1263 ! RWORK(LACOR), IA, JA, RWORK(LWM), RWORK(LWM), IPFLAG, F, JAC)
1264 ! LENWK = MAX(LREQ,LWMIN)
1265 ! IF (IPFLAG < 0) RETURN
1266 ! If DPREP was successful, move YH to end of required space for WM. ----
1267 ! LYHN = LWM + LENWK
1268 ! IF (LYHN > LYH) RETURN
1269 ! LYHD = LYH - LYHN
1270 ! IF (LYHD == 0) GO TO 20
1271 ! IMAX = LYHN - 1 + LENYHM
1272 ! DO 10 I = LYHN,IMAX
1273 ! RWORK(I) = RWORK(I+LYHD)
1274 ! 10 END DO
1275 ! LYH = LYHN
1276 ! Reset pointers for SAVF, EWT, and ACOR. ------------------------------
1277 ! 20 LSAVF = LYH + LENYH
1278 ! LEWTN = LSAVF + N
1279 ! LACOR = LEWTN + N
1280 ! IF (ISTATC == 3) GO TO 40
1281 ! If ISTATE = 1, move EWT (left) to its new position. ------------------
1282 ! IF (LEWTN > LEWT) RETURN
1283 ! DO 30 I = 1,N
1284 ! RWORK(I+LEWTN-1) = RWORK(I+LEWT-1)
1285 ! 30 END DO
1286 ! 40 LEWT = LEWTN
1287 ! RETURN
1288 !----------------------- End of Subroutine DIPREP ----------------------
1289 ! END SUBROUTINE DIPREP
1290 ! ECK DPREP
1291 ! SUBROUTINE DPREP (NEQ, Y, YH, SAVF, EWT, FTEM, IA, JA, &
1292 ! WK, IWK, IPPER, F, JAC)
1293 ! EXTERNAL F,JAC
1294 ! INTEGER :: NEQ, IA, JA, IWK, IPPER
1295 ! DOUBLE PRECISION :: Y, YH, SAVF, EWT, FTEM, WK
1296 ! DIMENSION NEQ(*), Y(*), YH(*), SAVF(*), EWT(*), FTEM(*), &
1297 ! IA(*), JA(*), WK(*), IWK(*)
1298 ! INTEGER :: IOWND, IOWNS, &
1299 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
1300 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
1301 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
1302 ! INTEGER :: IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
1303 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
1304 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
1305 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
1306 ! DOUBLE PRECISION :: ROWNS, &
1307 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
1308 ! DOUBLE PRECISION :: CON0, CONMIN, CCMXJ, PSMALL, RBIG, SETH
1309 ! COMMON /DLS001/ ROWNS(209), &
1310 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
1311 ! IOWND(6), IOWNS(6), &
1312 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
1313 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
1314 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
1315 ! COMMON /DLSS01/ CON0, CONMIN, CCMXJ, PSMALL, RBIG, SETH, &
1316 ! IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
1317 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
1318 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
1319 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
1320 ! INTEGER :: I, IBR, IER, IPIL, IPIU, IPTT1, IPTT2, J, JFOUND, K, &
1321 ! KNEW, KMAX, KMIN, LDIF, LENIGP, LIWK, MAXG, NP1, NZSUT
1322 ! DOUBLE PRECISION :: DQ, DYJ, ERWT, FAC, YJ
1323 !-----------------------------------------------------------------------
1324 ! This routine performs preprocessing related to the sparse linear
1325 ! systems that must be solved if MITER = 1 or 2.
1326 ! The operations that are performed here are:
1327 ! * compute sparseness structure of Jacobian according to MOSS,
1328 ! * compute grouping of column indices (MITER = 2),
1329 ! * compute a new ordering of rows and columns of the matrix,
1330 ! * reorder JA corresponding to the new ordering,
1331 ! * perform a symbolic LU factorization of the matrix, and
1332 ! * set pointers for segments of the IWK/WK array.
1333 ! In addition to variables described previously, DPREP uses the
1334 ! following for communication:
1335 ! YH = the history array. Only the first column, containing the
1336 ! current Y vector, is used. Used only if MOSS .ne. 0.
1337 ! SAVF = a work array of length NEQ, used only if MOSS .ne. 0.
1338 ! EWT = array of length NEQ containing (inverted) error weights.
1339 ! Used only if MOSS = 2 or if ISTATE = MOSS = 1.
1340 ! FTEM = a work array of length NEQ, identical to ACOR in the driver,
1341 ! used only if MOSS = 2.
1342 ! WK = a real work array of length LENWK, identical to WM in
1343 ! the driver.
1344 ! IWK = integer work array, assumed to occupy the same space as WK.
1345 ! LENWK = the length of the work arrays WK and IWK.
1346 ! ISTATC = a copy of the driver input argument ISTATE (= 1 on the
1347 ! first call, = 3 on a continuation call).
1348 ! IYS = flag value from ODRV or CDRV.
1349 ! IPPER = output error flag with the following values and meanings:
1350 ! 0 no error.
1351 ! -1 insufficient storage for internal structure pointers.
1352 ! -2 insufficient storage for JGROUP.
1353 ! -3 insufficient storage for ODRV.
1354 ! -4 other error flag from ODRV (should never occur).
1355 ! -5 insufficient storage for CDRV.
1356 ! -6 other error flag from CDRV.
1357 !-----------------------------------------------------------------------
1358 ! IBIAN = LRAT*2
1359 ! IPIAN = IBIAN + 1
1360 ! NP1 = N + 1
1361 ! IPJAN = IPIAN + NP1
1362 ! IBJAN = IPJAN - 1
1363 ! LIWK = LENWK*LRAT
1364 ! IF (IPJAN+N-1 > LIWK) GO TO 210
1365 ! IF (MOSS == 0) GO TO 30
1366 ! IF (ISTATC == 3) GO TO 20
1367 ! ISTATE = 1 and MOSS .ne. 0. Perturb Y for structure determination. --
1368 ! DO 10 I = 1,N
1369 ! ERWT = 1.0D0/EWT(I)
1370 ! FAC = 1.0D0 + 1.0D0/(I + 1.0D0)
1371 ! Y(I) = Y(I) + FAC*SIGN(ERWT,Y(I))
1372 ! 10 END DO
1373 ! GO TO (70, 100), MOSS
1374 ! 20 CONTINUE
1375 ! ISTATE = 3 and MOSS .ne. 0. Load Y from YH(*,1). --------------------
1376 ! DO 25 I = 1,N
1377 ! Y(I) = YH(I)
1378 ! 25 END DO
1379 ! GO TO (70, 100), MOSS
1380 ! MOSS = 0. Process user's IA,JA. Add diagonal entries if necessary. -
1381 ! 30 KNEW = IPJAN
1382 ! KMIN = IA(1)
1383 ! IWK(IPIAN) = 1
1384 ! DO 60 J = 1,N
1385 ! JFOUND = 0
1386 ! KMAX = IA(J+1) - 1
1387 ! IF (KMIN > KMAX) GO TO 45
1388 ! DO 40 K = KMIN,KMAX
1389 ! I = JA(K)
1390 ! IF (I == J) JFOUND = 1
1391 ! IF (KNEW > LIWK) GO TO 210
1392 ! IWK(KNEW) = I
1393 ! KNEW = KNEW + 1
1394 ! 40 END DO
1395 ! IF (JFOUND == 1) GO TO 50
1396 ! 45 IF (KNEW > LIWK) GO TO 210
1397 ! IWK(KNEW) = J
1398 ! KNEW = KNEW + 1
1399 ! 50 IWK(IPIAN+J) = KNEW + 1 - IPJAN
1400 ! KMIN = KMAX + 1
1401 ! 60 END DO
1402 ! GO TO 140
1403 ! MOSS = 1. Compute structure from user-supplied Jacobian routine JAC.
1404 ! 70 CONTINUE
1405 ! A dummy call to F allows user to create temporaries for use in JAC. --
1406 ! CALL F (NEQ, TN, Y, SAVF)
1407 ! K = IPJAN
1408 ! IWK(IPIAN) = 1
1409 ! DO 90 J = 1,N
1410 ! IF (K > LIWK) GO TO 210
1411 ! IWK(K) = J
1412 ! K = K + 1
1413 ! DO 75 I = 1,N
1414 ! SAVF(I) = 0.0D0
1415 ! 75 END DO
1416 ! CALL JAC (NEQ, TN, Y, J, IWK(IPIAN), IWK(IPJAN), SAVF)
1417 ! DO 80 I = 1,N
1418 ! IF (ABS(SAVF(I)) <= SETH) GO TO 80
1419 ! IF (I == J) GO TO 80
1420 ! IF (K > LIWK) GO TO 210
1421 ! IWK(K) = I
1422 ! K = K + 1
1423 ! 80 END DO
1424 ! IWK(IPIAN+J) = K + 1 - IPJAN
1425 ! 90 END DO
1426 ! GO TO 140
1427 ! MOSS = 2. Compute structure from results of N + 1 calls to F. -------
1428 ! 100 K = IPJAN
1429 ! IWK(IPIAN) = 1
1430 ! CALL F (NEQ, TN, Y, SAVF)
1431 ! DO 120 J = 1,N
1432 ! IF (K > LIWK) GO TO 210
1433 ! IWK(K) = J
1434 ! K = K + 1
1435 ! YJ = Y(J)
1436 ! ERWT = 1.0D0/EWT(J)
1437 ! DYJ = SIGN(ERWT,YJ)
1438 ! Y(J) = YJ + DYJ
1439 ! CALL F (NEQ, TN, Y, FTEM)
1440 ! Y(J) = YJ
1441 ! DO 110 I = 1,N
1442 ! DQ = (FTEM(I) - SAVF(I))/DYJ
1443 ! IF (ABS(DQ) <= SETH) GO TO 110
1444 ! IF (I == J) GO TO 110
1445 ! IF (K > LIWK) GO TO 210
1446 ! IWK(K) = I
1447 ! K = K + 1
1448 ! 110 END DO
1449 ! IWK(IPIAN+J) = K + 1 - IPJAN
1450 ! 120 END DO
1451 ! 140 CONTINUE
1452 ! IF (MOSS == 0 .OR. ISTATC /= 1) GO TO 150
1453 ! If ISTATE = 1 and MOSS .ne. 0, restore Y from YH. --------------------
1454 ! DO 145 I = 1,N
1455 ! Y(I) = YH(I)
1456 ! 145 END DO
1457 ! 150 NNZ = IWK(IPIAN+N) - 1
1458 ! LENIGP = 0
1459 ! IPIGP = IPJAN + NNZ
1460 ! IF (MITER /= 2) GO TO 160
1461 ! Compute grouping of column indices (MITER = 2). ----------------------
1462 ! MAXG = NP1
1463 ! IPJGP = IPJAN + NNZ
1464 ! IBJGP = IPJGP - 1
1465 ! IPIGP = IPJGP + N
1466 ! IPTT1 = IPIGP + NP1
1467 ! IPTT2 = IPTT1 + N
1468 ! LREQ = IPTT2 + N - 1
1469 ! IF (LREQ > LIWK) GO TO 220
1470 ! CALL JGROUP (N, IWK(IPIAN), IWK(IPJAN), MAXG, NGP, IWK(IPIGP), &
1471 ! IWK(IPJGP), IWK(IPTT1), IWK(IPTT2), IER)
1472 ! IF (IER /= 0) GO TO 220
1473 ! LENIGP = NGP + 1
1474 ! Compute new ordering of rows/columns of Jacobian. --------------------
1475 ! 160 IPR = IPIGP + LENIGP
1476 ! IPC = IPR
1477 ! IPIC = IPC + N
1478 ! IPISP = IPIC + N
1479 ! IPRSP = (IPISP - 2)/LRAT + 2
1480 ! IESP = LENWK + 1 - IPRSP
1481 ! IF (IESP < 0) GO TO 230
1482 ! IBR = IPR - 1
1483 ! DO 170 I = 1,N
1484 ! IWK(IBR+I) = I
1485 ! 170 END DO
1486 ! NSP = LIWK + 1 - IPISP
1487 ! CALL ODRV (N, IWK(IPIAN), IWK(IPJAN), WK, IWK(IPR), IWK(IPIC), &
1488 ! NSP, IWK(IPISP), 1, IYS)
1489 ! IF (IYS == 11*N+1) GO TO 240
1490 ! IF (IYS /= 0) GO TO 230
1491 ! Reorder JAN and do symbolic LU factorization of matrix. --------------
1492 ! IPA = LENWK + 1 - NNZ
1493 ! NSP = IPA - IPRSP
1494 ! LREQ = MAX(12*N/LRAT, 6*N/LRAT+2*N+NNZ) + 3
1495 ! LREQ = LREQ + IPRSP - 1 + NNZ
1496 ! IF (LREQ > LENWK) GO TO 250
1497 ! IBA = IPA - 1
1498 ! DO 180 I = 1,NNZ
1499 ! WK(IBA+I) = 0.0D0
1500 ! 180 END DO
1501 ! IPISP = LRAT*(IPRSP - 1) + 1
1502 ! CALL CDRV (N,IWK(IPR),IWK(IPC),IWK(IPIC),IWK(IPIAN),IWK(IPJAN), &
1503 ! WK(IPA),WK(IPA),WK(IPA),NSP,IWK(IPISP),WK(IPRSP),IESP,5,IYS)
1504 ! LREQ = LENWK - IESP
1505 ! IF (IYS == 10*N+1) GO TO 250
1506 ! IF (IYS /= 0) GO TO 260
1507 ! IPIL = IPISP
1508 ! IPIU = IPIL + 2*N + 1
1509 ! NZU = IWK(IPIL+N) - IWK(IPIL)
1510 ! NZL = IWK(IPIU+N) - IWK(IPIU)
1511 ! IF (LRAT > 1) GO TO 190
1512 ! CALL ADJLR (N, IWK(IPISP), LDIF)
1513 ! LREQ = LREQ + LDIF
1514 ! 190 CONTINUE
1515 ! IF (LRAT == 2 .AND. NNZ == N) LREQ = LREQ + 1
1516 ! NSP = NSP + LREQ - LENWK
1517 ! IPA = LREQ + 1 - NNZ
1518 ! IBA = IPA - 1
1519 ! IPPER = 0
1520 ! RETURN
1521 ! 210 IPPER = -1
1522 ! LREQ = 2 + (2*N + 1)/LRAT
1523 ! LREQ = MAX(LENWK+1,LREQ)
1524 ! RETURN
1525 ! 220 IPPER = -2
1526 ! LREQ = (LREQ - 1)/LRAT + 1
1527 ! RETURN
1528 ! 230 IPPER = -3
1529 ! CALL CNTNZU (N, IWK(IPIAN), IWK(IPJAN), NZSUT)
1530 ! LREQ = LENWK - IESP + (3*N + 4*NZSUT - 1)/LRAT + 1
1531 ! RETURN
1532 ! 240 IPPER = -4
1533 ! RETURN
1534 ! 250 IPPER = -5
1535 ! RETURN
1536 ! 260 IPPER = -6
1537 ! LREQ = LENWK
1538 ! RETURN
1539 !----------------------- End of Subroutine DPREP -----------------------
1540 ! END SUBROUTINE DPREP
1541 ! ECK 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 !-----------------------------------------------------------------------
1546 ! This subroutine constructs groupings of the column indices of
1547 ! the Jacobian matrix, used in the numerical evaluation of the
1548 ! Jacobian by finite differences.
1549 ! Input:
1550 ! N = the order of the matrix.
1551 ! IA,JA = sparse structure descriptors of the matrix by rows.
1552 ! MAXG = length of available storage in the IGP array.
1553 ! Output:
1554 ! NGRP = number of groups.
1555 ! JGP = array of length N containing the column indices by groups.
1556 ! IGP = pointer array of length NGRP + 1 to the locations in JGP
1557 ! of the beginning of each group.
1558 ! IER = error indicator. IER = 0 if no error occurred, or 1 if
1559 ! MAXG was insufficient.
1560 ! INCL and JDONE are working arrays of length N.
1561 !-----------------------------------------------------------------------
1562 ! INTEGER :: I, J, K, KMIN, KMAX, NCOL, NG
1563 ! IER = 0
1564 ! DO 10 J = 1,N
1565 ! JDONE(J) = 0
1566 ! 10 END DO
1567 ! NCOL = 1
1568 ! DO 60 NG = 1,MAXG
1569 ! IGP(NG) = NCOL
1570 ! DO 20 I = 1,N
1571 ! INCL(I) = 0
1572 ! 20 END DO
1573 ! DO 50 J = 1,N
1574 ! ! Reject column J if it is already in a group.--------------------------
1575 ! IF (JDONE(J) == 1) GO TO 50
1576 ! KMIN = IA(J)
1577 ! KMAX = IA(J+1) - 1
1578 ! DO 30 K = KMIN,KMAX
1579 ! ! Reject column J if it overlaps any column already in this group.------
1580 ! I = JA(K)
1581 ! IF (INCL(I) == 1) GO TO 50
1582 ! 30 END DO
1583 ! ! Accept column J into group NG.----------------------------------------
1584 ! JGP(NCOL) = J
1585 ! NCOL = NCOL + 1
1586 ! JDONE(J) = 1
1587 ! DO 40 K = KMIN,KMAX
1588 ! I = JA(K)
1589 ! INCL(I) = 1
1590 ! 40 END DO
1591 ! 50 END DO
1592 ! ! Stop if this group is empty (grouping is complete).-------------------
1593 ! IF (NCOL == IGP(NG)) GO TO 70
1594 ! 60 END DO
1595 ! Error return if not all columns were chosen (MAXG too small).---------
1596 ! IF (NCOL <= N) GO TO 80
1597 ! NG = MAXG
1598 ! 70 NGRP = NG - 1
1599 ! RETURN
1600 ! 80 IER = 1
1601 ! RETURN
1602 !----------------------- End of Subroutine JGROUP ----------------------
1603 ! END SUBROUTINE JGROUP
1604 ! ECK ADJLR
1605 ! SUBROUTINE ADJLR (N, ISP, LDIF)
1606 ! INTEGER :: N, ISP, LDIF
1607 ! DIMENSION ISP(*)
1608 !-----------------------------------------------------------------------
1609 ! This routine computes an adjustment, LDIF, to the required
1610 ! integer storage space in IWK (sparse matrix work space).
1611 ! It is called only if the word length ratio is LRAT = 1.
1612 ! This is to account for the possibility that the symbolic LU phase
1613 ! may require more storage than the numerical LU and solution phases.
1614 !-----------------------------------------------------------------------
1615 ! INTEGER :: IP, JLMAX, JUMAX, LNFC, LSFC, NZLU
1616 ! IP = 2*N + 1
1617 ! Get JLMAX = IJL(N) and JUMAX = IJU(N) (sizes of JL and JU). ----------
1618 ! JLMAX = ISP(IP)
1619 ! JUMAX = ISP(IP+IP)
1620 ! NZLU = (size of L) + (size of U) = (IL(N+1)-IL(1)) + (IU(N+1)-IU(1)).
1621 ! NZLU = ISP(N+1) - ISP(1) + ISP(IP+N+1) - ISP(IP+1)
1622 ! LSFC = 12*N + 3 + 2*MAX(JLMAX,JUMAX)
1623 ! LNFC = 9*N + 2 + JLMAX + JUMAX + NZLU
1624 ! LDIF = MAX(0, LSFC - LNFC)
1625 ! RETURN
1626 !----------------------- End of Subroutine ADJLR -----------------------
1627 ! END SUBROUTINE ADJLR
1628 ! ECK CNTNZU
1629 ! SUBROUTINE CNTNZU (N, IA, JA, NZSUT)
1630 ! INTEGER :: N, IA, JA, NZSUT
1631 ! DIMENSION IA(*), JA(*)
1632 !-----------------------------------------------------------------------
1633 ! This routine counts the number of nonzero elements in the strict
1634 ! upper triangle of the matrix M + M(transpose), where the sparsity
1635 ! structure of M is given by pointer arrays IA and JA.
1636 ! This is needed to compute the storage requirements for the
1637 ! sparse matrix reordering operation in ODRV.
1638 !-----------------------------------------------------------------------
1639 ! INTEGER :: II, JJ, J, JMIN, JMAX, K, KMIN, KMAX, NUM
1640 ! NUM = 0
1641 ! DO 50 II = 1,N
1642 ! JMIN = IA(II)
1643 ! JMAX = IA(II+1) - 1
1644 ! IF (JMIN > JMAX) GO TO 50
1645 ! DO 40 J = JMIN,JMAX
1646 ! IF (JA(J) - II) 10, 40, 30
1647 ! 10 JJ =JA(J)
1648 ! KMIN = IA(JJ)
1649 ! KMAX = IA(JJ+1) - 1
1650 ! IF (KMIN > KMAX) GO TO 30
1651 ! DO 20 K = KMIN,KMAX
1652 ! IF (JA(K) == II) GO TO 40
1653 ! 20 END DO
1654 ! 30 NUM = NUM + 1
1655 ! 40 END DO
1656 ! 50 END DO
1657 ! NZSUT = NUM
1658 ! RETURN
1659 !----------------------- End of Subroutine CNTNZU ----------------------
1660 ! END SUBROUTINE CNTNZU
1661 ! ECK DPRJS
1662 ! SUBROUTINE DPRJS (NEQ,Y,YH,NYH,EWT,FTEM,SAVF,WK,IWK,F,JAC)
1663 ! EXTERNAL F,JAC
1664 ! INTEGER :: NEQ, NYH, IWK
1665 ! DOUBLE PRECISION :: Y, YH, EWT, FTEM, SAVF, WK
1666 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), EWT(*), FTEM(*), SAVF(*), &
1667 ! WK(*), IWK(*)
1668 ! INTEGER :: IOWND, IOWNS, &
1669 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
1670 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
1671 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
1672 ! INTEGER :: IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
1673 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
1674 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
1675 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
1676 ! DOUBLE PRECISION :: ROWNS, &
1677 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
1678 ! DOUBLE PRECISION :: CON0, CONMIN, CCMXJ, PSMALL, RBIG, SETH
1679 ! COMMON /DLS001/ ROWNS(209), &
1680 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
1681 ! IOWND(6), IOWNS(6), &
1682 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
1683 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
1684 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
1685 ! COMMON /DLSS01/ CON0, CONMIN, CCMXJ, PSMALL, RBIG, SETH, &
1686 ! IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
1687 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
1688 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
1689 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
1690 ! INTEGER :: I, IMUL, J, JJ, JOK, JMAX, JMIN, K, KMAX, KMIN, NG
1691 ! DOUBLE PRECISION :: CON, DI, FAC, HL0, PIJ, R, R0, RCON, RCONT, &
1692 ! SRUR, DVNORM
1693 !-----------------------------------------------------------------------
1694 ! DPRJS is called to compute and process the matrix
1695 ! P = I - H*EL(1)*J , where J is an approximation to the Jacobian.
1696 ! J is computed by columns, either by the user-supplied routine JAC
1697 ! if MITER = 1, or by finite differencing if MITER = 2.
1698 ! if MITER = 3, a diagonal approximation to J is used.
1699 ! if MITER = 1 or 2, and if the existing value of the Jacobian
1700 ! (as contained in P) is considered acceptable, then a new value of
1701 ! P is reconstructed from the old value. In any case, when MITER
1702 ! is 1 or 2, the P matrix is subjected to LU decomposition in CDRV.
1703 ! P and its LU decomposition are stored (separately) in WK.
1704 ! In addition to variables described previously, communication
1705 ! with DPRJS uses the following:
1706 ! Y = array containing predicted values on entry.
1707 ! FTEM = work array of length N (ACOR in DSTODE).
1708 ! SAVF = array containing f evaluated at predicted y.
1709 ! WK = real work space for matrices. On output it contains the
1710 ! inverse diagonal matrix if MITER = 3, and P and its sparse
1711 ! LU decomposition if MITER is 1 or 2.
1712 ! Storage of matrix elements starts at WK(3).
1713 ! WK also contains the following matrix-related data:
1714 ! WK(1) = SQRT(UROUND), used in numerical Jacobian increments.
1715 ! WK(2) = H*EL0, saved for later use if MITER = 3.
1716 ! IWK = integer work space for matrix-related data, assumed to
1717 ! be equivalenced to WK. In addition, WK(IPRSP) and IWK(IPISP)
1718 ! are assumed to have identical locations.
1719 ! EL0 = EL(1) (input).
1720 ! IERPJ = output error flag (in Common).
1721 ! = 0 if no error.
1722 ! = 1 if zero pivot found in CDRV.
1723 ! = 2 if a singular matrix arose with MITER = 3.
1724 ! = -1 if insufficient storage for CDRV (should not occur here).
1725 ! = -2 if other error found in CDRV (should not occur here).
1726 ! JCUR = output flag showing status of (approximate) Jacobian matrix:
1727 ! = 1 to indicate that the Jacobian is now current, or
1728 ! = 0 to indicate that a saved value was used.
1729 ! This routine also uses other variables in Common.
1730 !-----------------------------------------------------------------------
1731 ! HL0 = H*EL0
1732 ! CON = -HL0
1733 ! IF (MITER == 3) GO TO 300
1734 ! See whether J should be reevaluated (JOK = 0) or not (JOK = 1). ------
1735 ! JOK = 1
1736 ! IF (NST == 0 .OR. NST >= NSLJ+MSBJ) JOK = 0
1737 ! IF (ICF == 1 .AND. ABS(RC - 1.0D0) < CCMXJ) JOK = 0
1738 ! IF (ICF == 2) JOK = 0
1739 ! IF (JOK == 1) GO TO 250
1740 ! MITER = 1 or 2, and the Jacobian is to be reevaluated. ---------------
1741 ! 20 JCUR = 1
1742 ! NJE = NJE + 1
1743 ! NSLJ = NST
1744 ! IPLOST = 0
1745 ! CONMIN = ABS(CON)
1746 ! GO TO (100, 200), MITER
1747 ! If MITER = 1, call JAC, multiply by scalar, and add identity. --------
1748 ! 100 CONTINUE
1749 ! KMIN = IWK(IPIAN)
1750 ! DO 130 J = 1, N
1751 ! KMAX = IWK(IPIAN+J) - 1
1752 ! DO 110 I = 1,N
1753 ! FTEM(I) = 0.0D0
1754 ! 110 END DO
1755 ! CALL JAC (NEQ, TN, Y, J, IWK(IPIAN), IWK(IPJAN), FTEM)
1756 ! DO 120 K = KMIN, KMAX
1757 ! I = IWK(IBJAN+K)
1758 ! WK(IBA+K) = FTEM(I)*CON
1759 ! IF (I == J) WK(IBA+K) = WK(IBA+K) + 1.0D0
1760 ! 120 END DO
1761 ! KMIN = KMAX + 1
1762 ! 130 END DO
1763 ! GO TO 290
1764 ! If MITER = 2, make NGP calls to F to approximate J and P. ------------
1765 ! 200 CONTINUE
1766 ! FAC = DVNORM(N, SAVF, EWT)
1767 ! R0 = 1000.0D0 * ABS(H) * UROUND * N * FAC
1768 ! IF (R0 == 0.0D0) R0 = 1.0D0
1769 ! SRUR = WK(1)
1770 ! JMIN = IWK(IPIGP)
1771 ! DO 240 NG = 1,NGP
1772 ! JMAX = IWK(IPIGP+NG) - 1
1773 ! DO 210 J = JMIN,JMAX
1774 ! JJ = IWK(IBJGP+J)
1775 ! R = MAX(SRUR*ABS(Y(JJ)),R0/EWT(JJ))
1776 ! Y(JJ) = Y(JJ) + R
1777 ! 210 END DO
1778 ! CALL F (NEQ, TN, Y, FTEM)
1779 ! DO 230 J = JMIN,JMAX
1780 ! JJ = IWK(IBJGP+J)
1781 ! Y(JJ) = YH(JJ,1)
1782 ! R = MAX(SRUR*ABS(Y(JJ)),R0/EWT(JJ))
1783 ! FAC = -HL0/R
1784 ! KMIN =IWK(IBIAN+JJ)
1785 ! KMAX =IWK(IBIAN+JJ+1) - 1
1786 ! DO 220 K = KMIN,KMAX
1787 ! I = IWK(IBJAN+K)
1788 ! WK(IBA+K) = (FTEM(I) - SAVF(I))*FAC
1789 ! IF (I == JJ) WK(IBA+K) = WK(IBA+K) + 1.0D0
1790 ! 220 END DO
1791 ! 230 END DO
1792 ! JMIN = JMAX + 1
1793 ! 240 END DO
1794 ! NFE = NFE + NGP
1795 ! GO TO 290
1796 ! If JOK = 1, reconstruct new P from old P. ----------------------------
1797 ! 250 JCUR = 0
1798 ! RCON = CON/CON0
1799 ! RCONT = ABS(CON)/CONMIN
1800 ! IF (RCONT > RBIG .AND. IPLOST == 1) GO TO 20
1801 ! KMIN = IWK(IPIAN)
1802 ! DO 275 J = 1,N
1803 ! KMAX = IWK(IPIAN+J) - 1
1804 ! DO 270 K = KMIN,KMAX
1805 ! I = IWK(IBJAN+K)
1806 ! PIJ = WK(IBA+K)
1807 ! IF (I /= J) GO TO 260
1808 ! PIJ = PIJ - 1.0D0
1809 ! IF (ABS(PIJ) >= PSMALL) GO TO 260
1810 ! IPLOST = 1
1811 ! CONMIN = MIN(ABS(CON0),CONMIN)
1812 ! 260 PIJ = PIJ*RCON
1813 ! IF (I == J) PIJ = PIJ + 1.0D0
1814 ! WK(IBA+K) = PIJ
1815 ! 270 END DO
1816 ! KMIN = KMAX + 1
1817 ! 275 END DO
1818 ! Do numerical factorization of P matrix. ------------------------------
1819 ! 290 NLU = NLU + 1
1820 ! CON0 = CON
1821 ! IERPJ = 0
1822 ! DO 295 I = 1,N
1823 ! FTEM(I) = 0.0D0
1824 ! 295 END DO
1825 ! CALL CDRV (N,IWK(IPR),IWK(IPC),IWK(IPIC),IWK(IPIAN),IWK(IPJAN), &
1826 ! WK(IPA),FTEM,FTEM,NSP,IWK(IPISP),WK(IPRSP),IESP,2,IYS)
1827 ! IF (IYS == 0) RETURN
1828 ! IMUL = (IYS - 1)/N
1829 ! IERPJ = -2
1830 ! IF (IMUL == 8) IERPJ = 1
1831 ! IF (IMUL == 10) IERPJ = -1
1832 ! RETURN
1833 ! If MITER = 3, construct a diagonal approximation to J and P. ---------
1834 ! 300 CONTINUE
1835 ! JCUR = 1
1836 ! NJE = NJE + 1
1837 ! WK(2) = HL0
1838 ! IERPJ = 0
1839 ! R = EL0*0.1D0
1840 ! DO 310 I = 1,N
1841 ! Y(I) = Y(I) + R*(H*SAVF(I) - YH(I,2))
1842 ! 310 END DO
1843 ! CALL F (NEQ, TN, Y, WK(3))
1844 ! NFE = NFE + 1
1845 ! DO 320 I = 1,N
1846 ! R0 = H*SAVF(I) - YH(I,2)
1847 ! DI = 0.1D0*R0 - H*(WK(I+2) - SAVF(I))
1848 ! WK(I+2) = 1.0D0
1849 ! IF (ABS(R0) < UROUND/EWT(I)) GO TO 320
1850 ! IF (ABS(DI) == 0.0D0) GO TO 330
1851 ! WK(I+2) = 0.1D0*R0/DI
1852 ! 320 END DO
1853 ! RETURN
1854 ! 330 IERPJ = 2
1855 ! RETURN
1856 !----------------------- End of Subroutine DPRJS -----------------------
1857 ! END SUBROUTINE DPRJS
1858 ! ECK DSOLSS
1859 ! SUBROUTINE DSOLSS (WK, IWK, X, TEM)
1860 ! INTEGER :: IWK
1861 ! DOUBLE PRECISION :: WK, X, TEM
1862 ! DIMENSION WK(*), IWK(*), X(*), TEM(*)
1863 ! INTEGER :: IOWND, IOWNS, &
1864 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
1865 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
1866 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
1867 ! INTEGER :: IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
1868 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
1869 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
1870 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
1871 ! DOUBLE PRECISION :: ROWNS, &
1872 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
1873 ! DOUBLE PRECISION :: RLSS
1874 ! COMMON /DLS001/ ROWNS(209), &
1875 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
1876 ! IOWND(6), IOWNS(6), &
1877 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
1878 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
1879 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
1880 ! COMMON /DLSS01/ RLSS(6), &
1881 ! IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
1882 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
1883 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
1884 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
1885 ! INTEGER :: I
1886 ! DOUBLE PRECISION :: DI, HL0, PHL0, R
1887 !-----------------------------------------------------------------------
1888 ! This routine manages the solution of the linear system arising from
1889 ! a chord iteration. It is called if MITER .ne. 0.
1890 ! If MITER is 1 or 2, it calls CDRV to accomplish this.
1891 ! If MITER = 3 it updates the coefficient H*EL0 in the diagonal
1892 ! matrix, and then computes the solution.
1893 ! communication with DSOLSS uses the following variables:
1894 ! WK = real work space containing the inverse diagonal matrix if
1895 ! MITER = 3 and the LU decomposition of the matrix otherwise.
1896 ! Storage of matrix elements starts at WK(3).
1897 ! WK also contains the following matrix-related data:
1898 ! WK(1) = SQRT(UROUND) (not used here),
1899 ! WK(2) = HL0, the previous value of H*EL0, used if MITER = 3.
1900 ! IWK = integer work space for matrix-related data, assumed to
1901 ! be equivalenced to WK. In addition, WK(IPRSP) and IWK(IPISP)
1902 ! are assumed to have identical locations.
1903 ! X = the right-hand side vector on input, and the solution vector
1904 ! on output, of length N.
1905 ! TEM = vector of work space of length N, not used in this version.
1906 ! IERSL = output flag (in Common).
1907 ! IERSL = 0 if no trouble occurred.
1908 ! IERSL = -1 if CDRV returned an error flag (MITER = 1 or 2).
1909 ! This should never occur and is considered fatal.
1910 ! IERSL = 1 if a singular matrix arose with MITER = 3.
1911 ! This routine also uses other variables in Common.
1912 !-----------------------------------------------------------------------
1913 ! IERSL = 0
1914 ! GO TO (100, 100, 300), MITER
1915 ! 100 CALL CDRV (N,IWK(IPR),IWK(IPC),IWK(IPIC),IWK(IPIAN),IWK(IPJAN), &
1916 ! WK(IPA),X,X,NSP,IWK(IPISP),WK(IPRSP),IESP,4,IERSL)
1917 ! IF (IERSL /= 0) IERSL = -1
1918 ! RETURN
1919 ! 300 PHL0 = WK(2)
1920 ! HL0 = H*EL0
1921 ! WK(2) = HL0
1922 ! IF (HL0 == PHL0) GO TO 330
1923 ! R = HL0/PHL0
1924 ! DO 320 I = 1,N
1925 ! DI = 1.0D0 - R*(1.0D0 - 1.0D0/WK(I+2))
1926 ! IF (ABS(DI) == 0.0D0) GO TO 390
1927 ! WK(I+2) = 1.0D0/DI
1928 ! 320 END DO
1929 ! 330 DO 340 I = 1,N
1930 ! X(I) = WK(I+2)*X(I)
1931 ! 340 END DO
1932 ! RETURN
1933 ! 390 IERSL = 1
1934 ! RETURN
1935 !----------------------- End of Subroutine DSOLSS ----------------------
1936 ! END SUBROUTINE DSOLSS
1937 ! ECK DSRCMS
1938 ! SUBROUTINE DSRCMS (RSAV, ISAV, JOB)
1939 !-----------------------------------------------------------------------
1940 ! This routine saves or restores (depending on JOB) the contents of
1941 ! the Common blocks DLS001, DLSS01, which are used
1942 ! internally by one or more ODEPACK solvers.
1943 ! RSAV = real array of length 224 or more.
1944 ! ISAV = integer array of length 71 or more.
1945 ! JOB = flag indicating to save or restore the Common blocks:
1946 ! JOB = 1 if Common is to be saved (written to RSAV/ISAV)
1947 ! JOB = 2 if Common is to be restored (read from RSAV/ISAV)
1948 ! A call with JOB = 2 presumes a prior call with JOB = 1.
1949 !-----------------------------------------------------------------------
1950 ! INTEGER :: ISAV, JOB
1951 ! INTEGER :: ILS, ILSS
1952 ! INTEGER :: I, LENILS, LENISS, LENRLS, LENRSS
1953 ! DOUBLE PRECISION :: RSAV, RLS, RLSS
1954 ! DIMENSION RSAV(*), ISAV(*)
1955 ! SAVE LENRLS, LENILS, LENRSS, LENISS
1956 ! COMMON /DLS001/ RLS(218), ILS(37)
1957 ! COMMON /DLSS01/ RLSS(6), ILSS(34)
1958 ! DATA LENRLS/218/, LENILS/37/, LENRSS/6/, LENISS/34/
1959 ! IF (JOB == 2) GO TO 100
1960 ! DO 10 I = 1,LENRLS
1961 ! RSAV(I) = RLS(I)
1962 ! 10 END DO
1963 ! DO 15 I = 1,LENRSS
1964 ! RSAV(LENRLS+I) = RLSS(I)
1965 ! 15 END DO
1966 ! DO 20 I = 1,LENILS
1967 ! ISAV(I) = ILS(I)
1968 ! 20 END DO
1969 ! DO 25 I = 1,LENISS
1970 ! ISAV(LENILS+I) = ILSS(I)
1971 ! 25 END DO
1972 ! RETURN
1973 ! 100 CONTINUE
1974 ! DO 110 I = 1,LENRLS
1975 ! RLS(I) = RSAV(I)
1976 ! 110 END DO
1977 ! DO 115 I = 1,LENRSS
1978 ! RLSS(I) = RSAV(LENRLS+I)
1979 ! 115 END DO
1980 ! DO 120 I = 1,LENILS
1981 ! ILS(I) = ISAV(I)
1982 ! 120 END DO
1983 ! DO 125 I = 1,LENISS
1984 ! ILSS(I) = ISAV(LENILS+I)
1985 ! 125 END DO
1986 ! RETURN
1987 !----------------------- End of Subroutine DSRCMS ----------------------
1988 ! END SUBROUTINE DSRCMS
1989 ! ECK ODRV
1990 ! subroutine odrv &
1991 ! (n, ia,ja,a, p,ip, nsp,isp, path, flag)
1992 ! 5/2/83
1993 !***********************************************************************
1994 ! odrv -- driver for sparse matrix reordering routines
1995 !***********************************************************************
1996 ! description
1997 ! odrv finds a minimum degree ordering of the rows and columns
1998 ! of a matrix m stored in (ia,ja,a) format (see below). for the
1999 ! reordered matrix, the work and storage required to perform
2000 ! gaussian elimination is (usually) significantly less.
2001 ! note.. odrv and its subordinate routines have been modified to
2002 ! compute orderings for general matrices, not necessarily having any
2003 ! symmetry. the miminum degree ordering is computed for the
2004 ! structure of the symmetric matrix m + m-transpose.
2005 ! modifications to the original odrv module have been made in
2006 ! the coding in subroutine mdi, and in the initial comments in
2007 ! subroutines odrv and md.
2008 ! if only the nonzero entries in the upper triangle of m are being
2009 ! stored, then odrv symmetrically reorders (ia,ja,a), (optionally)
2010 ! with the diagonal entries placed first in each row. this is to
2011 ! ensure that if m(i,j) will be in the upper triangle of m with
2012 ! respect to the new ordering, then m(i,j) is stored in row i (and
2013 ! thus m(j,i) is not stored), whereas if m(i,j) will be in the
2014 ! strict lower triangle of m, then m(j,i) is stored in row j (and
2015 ! thus m(i,j) is not stored).
2016 ! storage of sparse matrices
2017 ! the nonzero entries of the matrix m are stored row-by-row in the
2018 ! array a. to identify the individual nonzero entries in each row,
2019 ! we need to know in which column each entry lies. these column
2020 ! indices are stored in the array ja. i.e., if a(k) = m(i,j), then
2021 ! ja(k) = j. to identify the individual rows, we need to know where
2022 ! each row starts. these row pointers are stored in the array ia.
2023 ! i.e., if m(i,j) is the first nonzero entry (stored) in the i-th row
2024 ! and a(k) = m(i,j), then ia(i) = k. moreover, ia(n+1) points to
2025 ! the first location following the last element in the last row.
2026 ! thus, the number of entries in the i-th row is ia(i+1) - ia(i),
2027 ! the nonzero entries in the i-th row are stored consecutively in
2028 ! a(ia(i)), a(ia(i)+1), ..., a(ia(i+1)-1),
2029 ! and the corresponding column indices are stored consecutively in
2030 ! ja(ia(i)), ja(ia(i)+1), ..., ja(ia(i+1)-1).
2031 ! when the coefficient matrix is symmetric, only the nonzero entries
2032 ! in the upper triangle need be stored. for example, the matrix
2033 ! ( 1 0 2 3 0 )
2034 ! ( 0 4 0 0 0 )
2035 ! m = ( 2 0 5 6 0 )
2036 ! ( 3 0 6 7 8 )
2037 ! ( 0 0 0 8 9 )
2038 ! could be stored as
2039 ! - 1 2 3 4 5 6 7 8 9 10 11 12 13
2040 ! ---+--------------------------------------
2041 ! ia - 1 4 5 8 12 14
2042 ! ja - 1 3 4 2 1 3 4 1 3 4 5 4 5
2043 ! a - 1 2 3 4 2 5 6 3 6 7 8 8 9
2044 ! or (symmetrically) as
2045 ! - 1 2 3 4 5 6 7 8 9
2046 ! ---+--------------------------
2047 ! ia - 1 4 5 7 9 10
2048 ! ja - 1 3 4 2 3 4 4 5 5
2049 ! a - 1 2 3 4 5 6 7 8 9 .
2050 ! parameters
2051 ! n - order of the matrix
2052 ! ia - integer one-dimensional array containing pointers to delimit
2053 ! rows in ja and a. dimension = n+1
2054 ! ja - integer one-dimensional array containing the column indices
2055 ! corresponding to the elements of a. dimension = number of
2056 ! nonzero entries in (the upper triangle of) m
2057 ! a - real one-dimensional array containing the nonzero entries in
2058 ! (the upper triangle of) m, stored by rows. dimension =
2059 ! number of nonzero entries in (the upper triangle of) m
2060 ! p - integer one-dimensional array used to return the permutation
2061 ! of the rows and columns of m corresponding to the minimum
2062 ! degree ordering. dimension = n
2063 ! ip - integer one-dimensional array used to return the inverse of
2064 ! the permutation returned in p. dimension = n
2065 ! nsp - declared dimension of the one-dimensional array isp. nsp
2066 ! must be at least 3n+4k, where k is the number of nonzeroes
2067 ! in the strict upper triangle of m
2068 ! isp - integer one-dimensional array used for working storage.
2069 ! dimension = nsp
2070 ! path - integer path specification. values and their meanings are -
2071 ! 1 find minimum degree ordering only
2072 ! 2 find minimum degree ordering and reorder symmetrically
2073 ! stored matrix (used when only the nonzero entries in
2074 ! the upper triangle of m are being stored)
2075 ! 3 reorder symmetrically stored matrix as specified by
2076 ! input permutation (used when an ordering has already
2077 ! been determined and only the nonzero entries in the
2078 ! upper triangle of m are being stored)
2079 ! 4 same as 2 but put diagonal entries at start of each row
2080 ! 5 same as 3 but put diagonal entries at start of each row
2081 ! flag - integer error flag. values and their meanings are -
2082 ! 0 no errors detected
2083 ! 9n+k insufficient storage in md
2084 ! 10n+1 insufficient storage in odrv
2085 ! 11n+1 illegal path specification
2086 ! conversion from real to double precision
2087 ! change the real declarations in odrv and sro to double precision
2088 ! declarations.
2089 !-----------------------------------------------------------------------
2090 ! integer :: ia(*), ja(*), p(*), ip(*), isp(*), path, flag, &
2091 ! v, l, head, tmp, q
2092 !... real a(*)
2093 ! double precision :: a(*)
2094 ! logical :: dflag
2095 !----initialize error flag and validate path specification
2096 ! flag = 0
2097 ! if (path < 1 .OR. 5 < path) go to 111
2098 !----allocate storage and find minimum degree ordering
2099 ! if ((path-1) * (path-2) * (path-4) /= 0) go to 1
2100 ! max = (nsp-n)/2
2101 ! v = 1
2102 ! l = v + max
2103 ! head = l + max
2104 ! next = head + n
2105 ! if (max < n) go to 110
2106 ! call md &
2107 ! (n, ia,ja, max,isp(v),isp(l), isp(head),p,ip, isp(v), flag)
2108 ! if (flag /= 0) go to 100
2109 !----allocate storage and symmetrically reorder matrix
2110 ! 1 if ((path-2) * (path-3) * (path-4) * (path-5) /= 0) go to 2
2111 ! tmp = (nsp+1) - n
2112 ! q = tmp - (ia(n+1)-1)
2113 ! if (q < 1) go to 110
2114 ! dflag = path == 4 .OR. path == 5
2115 ! call sro &
2116 ! (n, ip, ia, ja, a, isp(tmp), isp(q), dflag)
2117 ! 2 return
2118 ! ** error -- error detected in md
2119 ! 100 return
2120 ! ** error -- insufficient storage
2121 ! 110 flag = 10*n + 1
2122 ! return
2123 ! ** error -- illegal path specified
2124 ! 111 flag = 11*n + 1
2125 ! return
2126 ! end subroutine odrv
2127 ! subroutine md &
2128 ! (n, ia,ja, max, v,l, head,last,next, mark, flag)
2129 !***********************************************************************
2130 ! md -- minimum degree algorithm (based on element model)
2131 !***********************************************************************
2132 ! description
2133 ! md finds a minimum degree ordering of the rows and columns of a
2134 ! general sparse matrix m stored in (ia,ja,a) format.
2135 ! when the structure of m is nonsymmetric, the ordering is that
2136 ! obtained for the symmetric matrix m + m-transpose.
2137 ! additional parameters
2138 ! max - declared dimension of the one-dimensional arrays v and l.
2139 ! max must be at least n+2k, where k is the number of
2140 ! nonzeroes in the strict upper triangle of m + m-transpose
2141 ! v - integer one-dimensional work array. dimension = max
2142 ! l - integer one-dimensional work array. dimension = max
2143 ! head - integer one-dimensional work array. dimension = n
2144 ! last - integer one-dimensional array used to return the permutation
2145 ! of the rows and columns of m corresponding to the minimum
2146 ! degree ordering. dimension = n
2147 ! next - integer one-dimensional array used to return the inverse of
2148 ! the permutation returned in last. dimension = n
2149 ! mark - integer one-dimensional work array (may be the same as v).
2150 ! dimension = n
2151 ! flag - integer error flag. values and their meanings are -
2152 ! 0 no errors detected
2153 ! 9n+k insufficient storage in md
2154 ! definitions of internal parameters
2155 ! ---------+---------------------------------------------------------
2156 ! v(s) - value field of list entry
2157 ! ---------+---------------------------------------------------------
2158 ! l(s) - link field of list entry (0 =) end of list)
2159 ! ---------+---------------------------------------------------------
2160 ! l(vi) - pointer to element list of uneliminated vertex vi
2161 ! ---------+---------------------------------------------------------
2162 ! l(ej) - pointer to boundary list of active element ej
2163 ! ---------+---------------------------------------------------------
2164 ! head(d) - vj =) vj head of d-list d
2165 ! - 0 =) no vertex in d-list d
2166 ! - vi uneliminated vertex
2167 ! - vi in ek - vi not in ek
2168 ! ---------+-----------------------------+---------------------------
2169 ! next(vi) - undefined but nonnegative - vj =) vj next in d-list
2170 ! - - 0 =) vi tail of d-list
2171 ! ---------+-----------------------------+---------------------------
2172 ! last(vi) - (not set until mdp) - -d =) vi head of d-list d
2173 ! --vk =) compute degree - vj =) vj last in d-list
2174 ! - ej =) vi prototype of ej - 0 =) vi not in any d-list
2175 ! - 0 =) do not compute degree -
2176 ! ---------+-----------------------------+---------------------------
2177 ! mark(vi) - mark(vk) - nonneg. tag .lt. mark(vk)
2178 ! - vi eliminated vertex
2179 ! - ei active element - otherwise
2180 ! ---------+-----------------------------+---------------------------
2181 ! next(vi) - -j =) vi was j-th vertex - -j =) vi was j-th vertex
2182 ! - to be eliminated - to be eliminated
2183 ! ---------+-----------------------------+---------------------------
2184 ! last(vi) - m =) size of ei = m - undefined
2185 ! ---------+-----------------------------+---------------------------
2186 ! mark(vi) - -m =) overlap count of ei - undefined
2187 ! - with ek = m -
2188 ! - otherwise nonnegative tag -
2189 ! - .lt. mark(vk) -
2190 !-----------------------------------------------------------------------
2191 ! integer :: ia(*), ja(*), v(*), l(*), head(*), last(*), next(*), &
2192 ! mark(*), flag, tag, dmin, vk,ek, tail
2193 ! equivalence (vk,ek)
2194 !----initialization
2195 ! tag = 0
2196 ! call mdi &
2197 ! (n, ia,ja, max,v,l, head,last,next, mark,tag, flag)
2198 ! if (flag /= 0) return
2199 ! k = 0
2200 ! dmin = 1
2201 !----while k .lt. n do
2202 ! 1 if (k >= n) go to 4
2203 !------search for vertex of minimum degree
2204 ! 2 if (head(dmin) > 0) go to 3
2205 ! dmin = dmin + 1
2206 ! go to 2
2207 !------remove vertex vk of minimum degree from degree list
2208 ! 3 vk = head(dmin)
2209 ! head(dmin) = next(vk)
2210 ! if (head(dmin) > 0) last(head(dmin)) = -dmin
2211 !------number vertex vk, adjust tag, and tag vk
2212 ! k = k+1
2213 ! next(vk) = -k
2214 ! last(ek) = dmin - 1
2215 ! tag = tag + last(ek)
2216 ! mark(vk) = tag
2217 !------form element ek from uneliminated neighbors of vk
2218 ! call mdm &
2219 ! (vk,tail, v,l, last,next, mark)
2220 !------purge inactive elements and do mass elimination
2221 ! call mdp &
2222 ! (k,ek,tail, v,l, head,last,next, mark)
2223 !------update degrees of uneliminated vertices in ek
2224 ! call mdu &
2225 ! (ek,dmin, v,l, head,last,next, mark)
2226 ! go to 1
2227 !----generate inverse permutation from permutation
2228 ! 4 do 5 k=1,n
2229 ! next(k) = -next(k)
2230 ! last(next(k)) = k
2231 ! 5 END DO
2232 ! return
2233 ! end subroutine md
2234 ! subroutine mdi &
2235 ! (n, ia,ja, max,v,l, head,last,next, mark,tag, flag)
2236 !***********************************************************************
2237 ! mdi -- initialization
2238 !***********************************************************************
2239 ! integer :: ia(*), ja(*), v(*), l(*), head(*), last(*), next(*), &
2240 ! mark(*), tag, flag, sfs, vi,dvi, vj
2241 !----initialize degrees, element lists, and degree lists
2242 ! do 1 vi=1,n
2243 ! mark(vi) = 1
2244 ! l(vi) = 0
2245 ! head(vi) = 0
2246 ! 1 END DO
2247 ! sfs = n+1
2248 !----create nonzero structure
2249 !----for each nonzero entry a(vi,vj)
2250 ! do 6 vi=1,n
2251 ! jmin = ia(vi)
2252 ! jmax = ia(vi+1) - 1
2253 ! if (jmin > jmax) go to 6
2254 ! do 5 j=jmin,jmax
2255 ! vj = ja(j)
2256 ! if (vj-vi) 2, 5, 4
2257 !
2258 ! !------if a(vi,vj) is in strict lower triangle
2259 ! !------check for previous occurrence of a(vj,vi)
2260 ! 2 lvk = vi
2261 ! kmax = mark(vi) - 1
2262 ! if (kmax == 0) go to 4
2263 ! do 3 k=1,kmax
2264 ! lvk = l(lvk)
2265 ! if (v(lvk) == vj) go to 5
2266 ! 3 END DO
2267 ! !----for unentered entries a(vi,vj)
2268 ! 4 if (sfs >= max) go to 101
2269 !
2270 ! !------enter vj in element list for vi
2271 ! mark(vi) = mark(vi) + 1
2272 ! v(sfs) = vj
2273 ! l(sfs) = l(vi)
2274 ! l(vi) = sfs
2275 ! sfs = sfs+1
2276 !
2277 ! !------enter vi in element list for vj
2278 ! mark(vj) = mark(vj) + 1
2279 ! v(sfs) = vi
2280 ! l(sfs) = l(vj)
2281 ! l(vj) = sfs
2282 ! sfs = sfs+1
2283 ! 5 END DO
2284 ! 6 END DO
2285 !----create degree lists and initialize mark vector
2286 ! do 7 vi=1,n
2287 ! dvi = mark(vi)
2288 ! next(vi) = head(dvi)
2289 ! head(dvi) = vi
2290 ! last(vi) = -dvi
2291 ! nextvi = next(vi)
2292 ! if (nextvi > 0) last(nextvi) = vi
2293 ! mark(vi) = tag
2294 ! 7 END DO
2295 ! return
2296 ! ** error- insufficient storage
2297 ! 101 flag = 9*n + vi
2298 ! return
2299 ! end subroutine mdi
2300 ! subroutine mdm &
2301 ! (vk,tail, v,l, last,next, mark)
2302 !***********************************************************************
2303 ! mdm -- form element from uneliminated neighbors of vk
2304 !***********************************************************************
2305 ! integer :: vk, tail, v(*), l(*), last(*), next(*), mark(*), &
2306 ! tag, s,ls,vs,es, b,lb,vb, blp,blpmax
2307 ! equivalence (vs, es)
2308 !----initialize tag and list of uneliminated neighbors
2309 ! tag = mark(vk)
2310 ! tail = vk
2311 !----for each vertex/element vs/es in element list of vk
2312 ! ls = l(vk)
2313 ! 1 s = ls
2314 ! if (s == 0) go to 5
2315 ! ls = l(s)
2316 ! vs = v(s)
2317 ! if (next(vs) < 0) go to 2
2318 !------if vs is uneliminated vertex, then tag and append to list of
2319 !------uneliminated neighbors
2320 ! mark(vs) = tag
2321 ! l(tail) = s
2322 ! tail = s
2323 ! go to 4
2324 !------if es is active element, then ...
2325 !--------for each vertex vb in boundary list of element es
2326 ! 2 lb = l(es)
2327 ! blpmax = last(es)
2328 ! do 3 blp=1,blpmax
2329 ! b = lb
2330 ! lb = l(b)
2331 ! vb = v(b)
2332 !
2333 ! !----------if vb is untagged vertex, then tag and append to list of
2334 ! !----------uneliminated neighbors
2335 ! if (mark(vb) >= tag) go to 3
2336 ! mark(vb) = tag
2337 ! l(tail) = b
2338 ! tail = b
2339 ! 3 END DO
2340 !--------mark es inactive
2341 ! mark(es) = tag
2342 ! 4 go to 1
2343 !----terminate list of uneliminated neighbors
2344 ! 5 l(tail) = 0
2345 ! return
2346 ! end subroutine mdm
2347 ! subroutine mdp &
2348 ! (k,ek,tail, v,l, head,last,next, mark)
2349 !***********************************************************************
2350 ! mdp -- purge inactive elements and do mass elimination
2351 !***********************************************************************
2352 ! integer :: ek, tail, v(*), l(*), head(*), last(*), next(*), &
2353 ! mark(*), tag, free, li,vi,lvi,evi, s,ls,es, ilp,ilpmax
2354 !----initialize tag
2355 ! tag = mark(ek)
2356 !----for each vertex vi in ek
2357 ! li = ek
2358 ! ilpmax = last(ek)
2359 ! if (ilpmax <= 0) go to 12
2360 ! do 11 ilp=1,ilpmax
2361 ! i = li
2362 ! li = l(i)
2363 ! vi = v(li)
2364 !
2365 ! !------remove vi from degree list
2366 ! if (last(vi) == 0) go to 3
2367 ! if (last(vi) > 0) go to 1
2368 ! head(-last(vi)) = next(vi)
2369 ! go to 2
2370 ! 1 next(last(vi)) = next(vi)
2371 ! 2 if (next(vi) > 0) last(next(vi)) = last(vi)
2372 !
2373 ! !------remove inactive items from element list of vi
2374 ! 3 ls = vi
2375 ! 4 s = ls
2376 ! ls = l(s)
2377 ! if (ls == 0) go to 6
2378 ! es = v(ls)
2379 ! if (mark(es) < tag) go to 5
2380 ! free = ls
2381 ! l(s) = l(ls)
2382 ! ls = s
2383 ! 5 go to 4
2384 !
2385 ! !------if vi is interior vertex, then remove from list and eliminate
2386 ! 6 lvi = l(vi)
2387 ! if (lvi /= 0) go to 7
2388 ! l(i) = l(li)
2389 ! li = i
2390 !
2391 ! k = k+1
2392 ! next(vi) = -k
2393 ! last(ek) = last(ek) - 1
2394 ! go to 11
2395 !
2396 ! !------else ...
2397 ! !--------classify vertex vi
2398 ! 7 if (l(lvi) /= 0) go to 9
2399 ! evi = v(lvi)
2400 ! if (next(evi) >= 0) go to 9
2401 ! if (mark(evi) < 0) go to 8
2402 !
2403 ! !----------if vi is prototype vertex, then mark as such, initialize
2404 ! !----------overlap count for corresponding element, and move vi to end
2405 ! !----------of boundary list
2406 ! last(vi) = evi
2407 ! mark(evi) = -1
2408 ! l(tail) = li
2409 ! tail = li
2410 ! l(i) = l(li)
2411 ! li = i
2412 ! go to 10
2413 !
2414 ! !----------else if vi is duplicate vertex, then mark as such and adjust
2415 ! !----------overlap count for corresponding element
2416 ! 8 last(vi) = 0
2417 ! mark(evi) = mark(evi) - 1
2418 ! go to 10
2419 !
2420 ! !----------else mark vi to compute degree
2421 ! 9 last(vi) = -ek
2422 !
2423 ! !--------insert ek in element list of vi
2424 ! 10 v(free) = ek
2425 ! l(free) = l(vi)
2426 ! l(vi) = free
2427 ! 11 END DO
2428 !----terminate boundary list
2429 ! 12 l(tail) = 0
2430 ! return
2431 ! end subroutine mdp
2432 ! subroutine mdu &
2433 ! (ek,dmin, v,l, head,last,next, mark)
2434 !***********************************************************************
2435 ! mdu -- update degrees of uneliminated vertices in ek
2436 !***********************************************************************
2437 ! integer :: ek, dmin, v(*), l(*), head(*), last(*), next(*), &
2438 ! mark(*), tag, vi,evi,dvi, s,vs,es, b,vb, ilp,ilpmax, &
2439 ! blp,blpmax
2440 ! equivalence (vs, es)
2441 !----initialize tag
2442 ! tag = mark(ek) - last(ek)
2443 !----for each vertex vi in ek
2444 ! i = ek
2445 ! ilpmax = last(ek)
2446 ! if (ilpmax <= 0) go to 11
2447 ! do 10 ilp=1,ilpmax
2448 ! i = l(i)
2449 ! vi = v(i)
2450 ! if (last(vi)) 1, 10, 8
2451 !
2452 ! !------if vi neither prototype nor duplicate vertex, then merge elements
2453 ! !------to compute degree
2454 ! 1 tag = tag + 1
2455 ! dvi = last(ek)
2456 !
2457 ! !--------for each vertex/element vs/es in element list of vi
2458 ! s = l(vi)
2459 ! 2 s = l(s)
2460 ! if (s == 0) go to 9
2461 ! vs = v(s)
2462 ! if (next(vs) < 0) go to 3
2463 !
2464 ! !----------if vs is uneliminated vertex, then tag and adjust degree
2465 ! mark(vs) = tag
2466 ! dvi = dvi + 1
2467 ! go to 5
2468 !
2469 ! !----------if es is active element, then expand
2470 ! !------------check for outmatched vertex
2471 ! 3 if (mark(es) < 0) go to 6
2472 !
2473 ! !------------for each vertex vb in es
2474 ! b = es
2475 ! blpmax = last(es)
2476 ! do 4 blp=1,blpmax
2477 ! b = l(b)
2478 ! vb = v(b)
2479 !
2480 ! !--------------if vb is untagged, then tag and adjust degree
2481 ! if (mark(vb) >= tag) go to 4
2482 ! mark(vb) = tag
2483 ! dvi = dvi + 1
2484 ! 4 END DO
2485 !
2486 ! 5 go to 2
2487 !
2488 ! !------else if vi is outmatched vertex, then adjust overlaps but do not
2489 ! !------compute degree
2490 ! 6 last(vi) = 0
2491 ! mark(es) = mark(es) - 1
2492 ! 7 s = l(s)
2493 ! if (s == 0) go to 10
2494 ! es = v(s)
2495 ! if (mark(es) < 0) mark(es) = mark(es) - 1
2496 ! go to 7
2497 !
2498 ! !------else if vi is prototype vertex, then calculate degree by
2499 ! !------inclusion/exclusion and reset overlap count
2500 ! 8 evi = last(vi)
2501 ! dvi = last(ek) + last(evi) + mark(evi)
2502 ! mark(evi) = 0
2503 !
2504 ! !------insert vi in appropriate degree list
2505 ! 9 next(vi) = head(dvi)
2506 ! head(dvi) = vi
2507 ! last(vi) = -dvi
2508 ! if (next(vi) > 0) last(next(vi)) = vi
2509 ! if (dvi < dmin) dmin = dvi
2510 !
2511 ! 10 END DO
2512 ! 11 return
2513 ! end subroutine mdu
2514 ! subroutine sro &
2515 ! (n, ip, ia,ja,a, q, r, dflag)
2516 !***********************************************************************
2517 ! sro -- symmetric reordering of sparse symmetric matrix
2518 !***********************************************************************
2519 ! description
2520 ! the nonzero entries of the matrix m are assumed to be stored
2521 ! symmetrically in (ia,ja,a) format (i.e., not both m(i,j) and m(j,i)
2522 ! are stored if i ne j).
2523 ! sro does not rearrange the order of the rows, but does move
2524 ! nonzeroes from one row to another to ensure that if m(i,j) will be
2525 ! in the upper triangle of m with respect to the new ordering, then
2526 ! m(i,j) is stored in row i (and thus m(j,i) is not stored), whereas
2527 ! if m(i,j) will be in the strict lower triangle of m, then m(j,i) is
2528 ! stored in row j (and thus m(i,j) is not stored).
2529 ! additional parameters
2530 ! q - integer one-dimensional work array. dimension = n
2531 ! r - integer one-dimensional work array. dimension = number of
2532 ! nonzero entries in the upper triangle of m
2533 ! dflag - logical variable. if dflag = .true., then store nonzero
2534 ! diagonal elements at the beginning of the row
2535 !-----------------------------------------------------------------------
2536 ! integer :: ip(*), ia(*), ja(*), q(*), r(*)
2537 !... real a(*), ak
2538 ! double precision :: a(*), ak
2539 ! logical :: dflag
2540 !--phase 1 -- find row in which to store each nonzero
2541 !----initialize count of nonzeroes to be stored in each row
2542 ! do 1 i=1,n
2543 ! q(i) = 0
2544 ! 1 END DO
2545 !----for each nonzero element a(j)
2546 ! do 3 i=1,n
2547 ! jmin = ia(i)
2548 ! jmax = ia(i+1) - 1
2549 ! if (jmin > jmax) go to 3
2550 ! do 2 j=jmin,jmax
2551 !
2552 ! !--------find row (=r(j)) and column (=ja(j)) in which to store a(j) ...
2553 ! k = ja(j)
2554 ! if (ip(k) < ip(i)) ja(j) = i
2555 ! if (ip(k) >= ip(i)) k = i
2556 ! r(j) = k
2557 !
2558 ! !--------... and increment count of nonzeroes (=q(r(j)) in that row
2559 ! q(k) = q(k) + 1
2560 ! 2 END DO
2561 ! 3 END DO
2562 !--phase 2 -- find new ia and permutation to apply to (ja,a)
2563 !----determine pointers to delimit rows in permuted (ja,a)
2564 ! do 4 i=1,n
2565 ! ia(i+1) = ia(i) + q(i)
2566 ! q(i) = ia(i+1)
2567 ! 4 END DO
2568 !----determine where each (ja(j),a(j)) is stored in permuted (ja,a)
2569 !----for each nonzero element (in reverse order)
2570 ! ilast = 0
2571 ! jmin = ia(1)
2572 ! jmax = ia(n+1) - 1
2573 ! j = jmax
2574 ! do 6 jdummy=jmin,jmax
2575 ! i = r(j)
2576 ! if ( .NOT. dflag .OR. ja(j) /= i .OR. i == ilast) go to 5
2577 !
2578 ! !------if dflag, then put diagonal nonzero at beginning of row
2579 ! r(j) = ia(i)
2580 ! ilast = i
2581 ! go to 6
2582 !
2583 ! !------put (off-diagonal) nonzero in last unused location in row
2584 ! 5 q(i) = q(i) - 1
2585 ! r(j) = q(i)
2586 !
2587 ! j = j-1
2588 ! 6 END DO
2589 !--phase 3 -- permute (ja,a) to upper triangular form (wrt new ordering)
2590 ! do 8 j=jmin,jmax
2591 ! 7 if (r(j) == j) go to 8
2592 ! k = r(j)
2593 ! r(j) = r(k)
2594 ! r(k) = k
2595 ! jak = ja(k)
2596 ! ja(k) = ja(j)
2597 ! ja(j) = jak
2598 ! ak = a(k)
2599 ! a(k) = a(j)
2600 ! a(j) = ak
2601 ! go to 7
2602 ! 8 END DO
2603 ! return
2604 ! end subroutine sro
2605 ! ECK CDRV
2606 ! subroutine cdrv &
2607 ! (n, r,c,ic, ia,ja,a, b, z, nsp,isp,rsp,esp, path, flag)
2608 !*** subroutine cdrv
2609 !*** driver for subroutines for solving sparse nonsymmetric systems of
2610 ! linear equations (compressed pointer storage)
2611 ! parameters
2612 ! class abbreviations are--
2613 ! n - integer variable
2614 ! f - real variable
2615 ! v - supplies a value to the driver
2616 ! r - returns a result from the driver
2617 ! i - used internally by the driver
2618 ! a - array
2619 ! class - parameter
2620 ! ------+----------
2621 ! -
2622 ! the nonzero entries of the coefficient matrix m are stored
2623 ! row-by-row in the array a. to identify the individual nonzero
2624 ! entries in each row, we need to know in which column each entry
2625 ! lies. the column indices which correspond to the nonzero entries
2626 ! of m are stored in the array ja. i.e., if a(k) = m(i,j), then
2627 ! ja(k) = j. in addition, we need to know where each row starts and
2628 ! how long it is. the index positions in ja and a where the rows of
2629 ! m begin are stored in the array ia. i.e., if m(i,j) is the first
2630 ! nonzero entry (stored) in the i-th row and a(k) = m(i,j), then
2631 ! ia(i) = k. moreover, the index in ja and a of the first location
2632 ! following the last element in the last row is stored in ia(n+1).
2633 ! thus, the number of entries in the i-th row is given by
2634 ! ia(i+1) - ia(i), the nonzero entries of the i-th row are stored
2635 ! consecutively in
2636 ! a(ia(i)), a(ia(i)+1), ..., a(ia(i+1)-1),
2637 ! and the corresponding column indices are stored consecutively in
2638 ! ja(ia(i)), ja(ia(i)+1), ..., ja(ia(i+1)-1).
2639 ! for example, the 5 by 5 matrix
2640 ! ( 1. 0. 2. 0. 0.)
2641 ! ( 0. 3. 0. 0. 0.)
2642 ! m = ( 0. 4. 5. 6. 0.)
2643 ! ( 0. 0. 0. 7. 0.)
2644 ! ( 0. 0. 0. 8. 9.)
2645 ! would be stored as
2646 ! - 1 2 3 4 5 6 7 8 9
2647 ! ---+--------------------------
2648 ! ia - 1 3 4 7 8 10
2649 ! ja - 1 3 2 2 3 4 4 4 5
2650 ! a - 1. 2. 3. 4. 5. 6. 7. 8. 9. .
2651 ! nv - n - number of variables/equations.
2652 ! fva - a - nonzero entries of the coefficient matrix m, stored
2653 ! - by rows.
2654 ! - size = number of nonzero entries in m.
2655 ! nva - ia - pointers to delimit the rows in a.
2656 ! - size = n+1.
2657 ! nva - ja - column numbers corresponding to the elements of a.
2658 ! - size = size of a.
2659 ! fva - b - right-hand side b. b and z can the same array.
2660 ! - size = n.
2661 ! fra - z - solution x. b and z can be the same array.
2662 ! - size = n.
2663 ! the rows and columns of the original matrix m can be
2664 ! reordered (e.g., to reduce fillin or ensure numerical stability)
2665 ! before calling the driver. if no reordering is done, then set
2666 ! r(i) = c(i) = ic(i) = i for i=1,...,n. the solution z is returned
2667 ! in the original order.
2668 ! if the columns have been reordered (i.e., c(i).ne.i for some
2669 ! i), then the driver will call a subroutine (nroc) which rearranges
2670 ! each row of ja and a, leaving the rows in the original order, but
2671 ! placing the elements of each row in increasing order with respect
2672 ! to the new ordering. if path.ne.1, then nroc is assumed to have
2673 ! been called already.
2674 ! nva - r - ordering of the rows of m.
2675 ! - size = n.
2676 ! nva - c - ordering of the columns of m.
2677 ! - size = n.
2678 ! nva - ic - inverse of the ordering of the columns of m. i.e.,
2679 ! - ic(c(i)) = i for i=1,...,n.
2680 ! - size = n.
2681 ! the solution of the system of linear equations is divided into
2682 ! three stages --
2683 ! nsfc -- the matrix m is processed symbolically to determine where
2684 ! fillin will occur during the numeric factorization.
2685 ! nnfc -- the matrix m is factored numerically into the product ldu
2686 ! of a unit lower triangular matrix l, a diagonal matrix
2687 ! d, and a unit upper triangular matrix u, and the system
2688 ! mx = b is solved.
2689 ! nnsc -- the linear system mx = b is solved using the ldu
2690 ! or factorization from nnfc.
2691 ! nntc -- the transposed linear system mt x = b is solved using
2692 ! the ldu factorization from nnf.
2693 ! for several systems whose coefficient matrices have the same
2694 ! nonzero structure, nsfc need be done only once (for the first
2695 ! system). then nnfc is done once for each additional system. for
2696 ! several systems with the same coefficient matrix, nsfc and nnfc
2697 ! need be done only once (for the first system). then nnsc or nntc
2698 ! is done once for each additional right-hand side.
2699 ! nv - path - path specification. values and their meanings are --
2700 ! - 1 perform nroc, nsfc, and nnfc.
2701 ! - 2 perform nnfc only (nsfc is assumed to have been
2702 ! - done in a manner compatible with the storage
2703 ! - allocation used in the driver).
2704 ! - 3 perform nnsc only (nsfc and nnfc are assumed to
2705 ! - have been done in a manner compatible with the
2706 ! - storage allocation used in the driver).
2707 ! - 4 perform nntc only (nsfc and nnfc are assumed to
2708 ! - have been done in a manner compatible with the
2709 ! - storage allocation used in the driver).
2710 ! - 5 perform nroc and nsfc.
2711 ! various errors are detected by the driver and the individual
2712 ! subroutines.
2713 ! nr - flag - error flag. values and their meanings are --
2714 ! - 0 no errors detected
2715 ! - n+k null row in a -- row = k
2716 ! - 2n+k duplicate entry in a -- row = k
2717 ! - 3n+k insufficient storage in nsfc -- row = k
2718 ! - 4n+1 insufficient storage in nnfc
2719 ! - 5n+k null pivot -- row = k
2720 ! - 6n+k insufficient storage in nsfc -- row = k
2721 ! - 7n+1 insufficient storage in nnfc
2722 ! - 8n+k zero pivot -- row = k
2723 ! - 10n+1 insufficient storage in cdrv
2724 ! - 11n+1 illegal path specification
2725 ! working storage is needed for the factored form of the matrix
2726 ! m plus various temporary vectors. the arrays isp and rsp should be
2727 ! equivalenced. integer storage is allocated from the beginning of
2728 ! isp and real storage from the end of rsp.
2729 ! nv - nsp - declared dimension of rsp. nsp generally must
2730 ! - be larger than 8n+2 + 2k (where k = (number of
2731 ! - nonzero entries in m)).
2732 ! nvira - isp - integer working storage divided up into various arrays
2733 ! - needed by the subroutines. isp and rsp should be
2734 ! - equivalenced.
2735 ! - size = lratio*nsp.
2736 ! fvira - rsp - real working storage divided up into various arrays
2737 ! - needed by the subroutines. isp and rsp should be
2738 ! - equivalenced.
2739 ! - size = nsp.
2740 ! nr - esp - if sufficient storage was available to perform the
2741 ! - symbolic factorization (nsfc), then esp is set to
2742 ! - the amount of excess storage provided (negative if
2743 ! - insufficient storage was available to perform the
2744 ! - numeric factorization (nnfc)).
2745 ! conversion to double precision
2746 ! to convert these routines for double precision arrays..
2747 ! (1) use the double precision declarations in place of the real
2748 ! declarations in each subprogram, as given in comment cards.
2749 ! (2) change the data-loaded value of the integer lratio
2750 ! in subroutine cdrv, as indicated below.
2751 ! (3) change e0 to d0 in the constants in statement number 10
2752 ! in subroutine nnfc and the line following that.
2753 ! integer :: r(*), c(*), ic(*), ia(*), ja(*), isp(*), esp, path, &
2754 ! flag, d, u, q, row, tmp, ar, umax
2755 ! real a(*), b(*), z(*), rsp(*)
2756 ! double precision :: a(*), b(*), z(*), rsp(*)
2757 ! set lratio equal to the ratio between the length of floating point
2758 ! and integer array data. e. g., lratio = 1 for (real, integer),
2759 ! lratio = 2 for (double precision, integer)
2760 ! data lratio/2/
2761 ! if (path < 1 .OR. 5 < path) go to 111
2762 !******initialize and divide up temporary storage *******************
2763 ! il = 1
2764 ! ijl = il + (n+1)
2765 ! iu = ijl + n
2766 ! iju = iu + (n+1)
2767 ! irl = iju + n
2768 ! jrl = irl + n
2769 ! jl = jrl + n
2770 ! ****** reorder a if necessary, call nsfc if flag is set ***********
2771 ! if ((path-1) * (path-5) /= 0) go to 5
2772 ! max = (lratio*nsp + 1 - jl) - (n+1) - 5*n
2773 ! jlmax = max/2
2774 ! q = jl + jlmax
2775 ! ira = q + (n+1)
2776 ! jra = ira + n
2777 ! irac = jra + n
2778 ! iru = irac + n
2779 ! jru = iru + n
2780 ! jutmp = jru + n
2781 ! jumax = lratio*nsp + 1 - jutmp
2782 ! esp = max/lratio
2783 ! if (jlmax <= 0 .OR. jumax <= 0) go to 110
2784 ! do 1 i=1,n
2785 ! if (c(i) /= i) go to 2
2786 ! 1 END DO
2787 ! go to 3
2788 ! 2 ar = nsp + 1 - n
2789 ! call nroc &
2790 ! (n, ic, ia,ja,a, isp(il), rsp(ar), isp(iu), flag)
2791 ! if (flag /= 0) go to 100
2792 ! 3 call nsfc &
2793 ! (n, r, ic, ia,ja, &
2794 ! jlmax, isp(il), isp(jl), isp(ijl), &
2795 ! jumax, isp(iu), isp(jutmp), isp(iju), &
2796 ! isp(q), isp(ira), isp(jra), isp(irac), &
2797 ! isp(irl), isp(jrl), isp(iru), isp(jru), flag)
2798 ! if(flag /= 0) go to 100
2799 ! ****** move ju next to jl *****************************************
2800 ! jlmax = isp(ijl+n-1)
2801 ! ju = jl + jlmax
2802 ! jumax = isp(iju+n-1)
2803 ! if (jumax <= 0) go to 5
2804 ! do 4 j=1,jumax
2805 ! isp(ju+j-1) = isp(jutmp+j-1)
2806 ! 4 END DO
2807 ! ****** call remaining subroutines *********************************
2808 ! 5 jlmax = isp(ijl+n-1)
2809 ! ju = jl + jlmax
2810 ! jumax = isp(iju+n-1)
2811 ! l = (ju + jumax - 2 + lratio) / lratio + 1
2812 ! lmax = isp(il+n) - 1
2813 ! d = l + lmax
2814 ! u = d + n
2815 ! row = nsp + 1 - n
2816 ! tmp = row - n
2817 ! umax = tmp - u
2818 ! esp = umax - (isp(iu+n) - 1)
2819 ! if ((path-1) * (path-2) /= 0) go to 6
2820 ! if (umax < 0) go to 110
2821 ! call nnfc &
2822 ! (n, r, c, ic, ia, ja, a, z, b, &
2823 ! lmax, isp(il), isp(jl), isp(ijl), rsp(l), rsp(d), &
2824 ! umax, isp(iu), isp(ju), isp(iju), rsp(u), &
2825 ! rsp(row), rsp(tmp), isp(irl), isp(jrl), flag)
2826 ! if(flag /= 0) go to 100
2827 ! 6 if ((path-3) /= 0) go to 7
2828 ! call nnsc &
2829 ! (n, r, c, isp(il), isp(jl), isp(ijl), rsp(l), &
2830 ! rsp(d), isp(iu), isp(ju), isp(iju), rsp(u), &
2831 ! z, b, rsp(tmp))
2832 ! 7 if ((path-4) /= 0) go to 8
2833 ! call nntc &
2834 ! (n, r, c, isp(il), isp(jl), isp(ijl), rsp(l), &
2835 ! rsp(d), isp(iu), isp(ju), isp(iju), rsp(u), &
2836 ! z, b, rsp(tmp))
2837 ! 8 return
2838 ! ** error.. error detected in nroc, nsfc, nnfc, or nnsc
2839 ! 100 return
2840 ! ** error.. insufficient storage
2841 ! 110 flag = 10*n + 1
2842 ! return
2843 ! ** error.. illegal path specification
2844 ! 111 flag = 11*n + 1
2845 ! return
2846 ! end subroutine cdrv
2847 ! subroutine nroc (n, ic, ia, ja, a, jar, ar, p, flag)
2848 ! ----------------------------------------------------------------
2849 ! yale sparse matrix package - nonsymmetric codes
2850 ! solving the system of equations mx = b
2851 ! i. calling sequences
2852 ! the coefficient matrix can be processed by an ordering routine
2853 ! (e.g., to reduce fillin or ensure numerical stability) before using
2854 ! the remaining subroutines. if no reordering is done, then set
2855 ! r(i) = c(i) = ic(i) = i for i=1,...,n. if an ordering subroutine
2856 ! is used, then nroc should be used to reorder the coefficient matrix
2857 ! the calling sequence is --
2858 ! ( (matrix ordering))
2859 ! (nroc (matrix reordering))
2860 ! nsfc (symbolic factorization to determine where fillin will
2861 ! occur during numeric factorization)
2862 ! nnfc (numeric factorization into product ldu of unit lower
2863 ! triangular matrix l, diagonal matrix d, and unit
2864 ! upper triangular matrix u, and solution of linear
2865 ! system)
2866 ! nnsc (solution of linear system for additional right-hand
2867 ! side using ldu factorization from nnfc)
2868 ! (if only one system of equations is to be solved, then the
2869 ! subroutine trk should be used.)
2870 ! ii. storage of sparse matrices
2871 ! the nonzero entries of the coefficient matrix m are stored
2872 ! row-by-row in the array a. to identify the individual nonzero
2873 ! entries in each row, we need to know in which column each entry
2874 ! lies. the column indices which correspond to the nonzero entries
2875 ! of m are stored in the array ja. i.e., if a(k) = m(i,j), then
2876 ! ja(k) = j. in addition, we need to know where each row starts and
2877 ! how long it is. the index positions in ja and a where the rows of
2878 ! m begin are stored in the array ia. i.e., if m(i,j) is the first
2879 ! (leftmost) entry in the i-th row and a(k) = m(i,j), then
2880 ! ia(i) = k. moreover, the index in ja and a of the first location
2881 ! following the last element in the last row is stored in ia(n+1).
2882 ! thus, the number of entries in the i-th row is given by
2883 ! ia(i+1) - ia(i), the nonzero entries of the i-th row are stored
2884 ! consecutively in
2885 ! a(ia(i)), a(ia(i)+1), ..., a(ia(i+1)-1),
2886 ! and the corresponding column indices are stored consecutively in
2887 ! ja(ia(i)), ja(ia(i)+1), ..., ja(ia(i+1)-1).
2888 ! for example, the 5 by 5 matrix
2889 ! ( 1. 0. 2. 0. 0.)
2890 ! ( 0. 3. 0. 0. 0.)
2891 ! m = ( 0. 4. 5. 6. 0.)
2892 ! ( 0. 0. 0. 7. 0.)
2893 ! ( 0. 0. 0. 8. 9.)
2894 ! would be stored as
2895 ! - 1 2 3 4 5 6 7 8 9
2896 ! ---+--------------------------
2897 ! ia - 1 3 4 7 8 10
2898 ! ja - 1 3 2 2 3 4 4 4 5
2899 ! a - 1. 2. 3. 4. 5. 6. 7. 8. 9. .
2900 ! the strict upper (lower) triangular portion of the matrix
2901 ! u (l) is stored in a similar fashion using the arrays iu, ju, u
2902 ! (il, jl, l) except that an additional array iju (ijl) is used to
2903 ! compress storage of ju (jl) by allowing some sequences of column
2904 ! (row) indices to used for more than one row (column) (n.b., l is
2905 ! stored by columns). iju(k) (ijl(k)) points to the starting
2906 ! location in ju (jl) of entries for the kth row (column).
2907 ! compression in ju (jl) occurs in two ways. first, if a row
2908 ! (column) i was merged into the current row (column) k, and the
2909 ! number of elements merged in from (the tail portion of) row
2910 ! (column) i is the same as the final length of row (column) k, then
2911 ! the kth row (column) and the tail of row (column) i are identical
2912 ! and iju(k) (ijl(k)) points to the start of the tail. second, if
2913 ! some tail portion of the (k-1)st row (column) is identical to the
2914 ! head of the kth row (column), then iju(k) (ijl(k)) points to the
2915 ! start of that tail portion. for example, the nonzero structure of
2916 ! the strict upper triangular part of the matrix
2917 ! d 0 x x x
2918 ! 0 d 0 x x
2919 ! 0 0 d x 0
2920 ! 0 0 0 d x
2921 ! 0 0 0 0 d
2922 ! would be represented as
2923 ! - 1 2 3 4 5 6
2924 ! ----+------------
2925 ! iu - 1 4 6 7 8 8
2926 ! ju - 3 4 5 4
2927 ! iju - 1 2 4 3 .
2928 ! the diagonal entries of l and u are assumed to be equal to one and
2929 ! are not stored. the array d contains the reciprocals of the
2930 ! diagonal entries of the matrix d.
2931 ! iii. additional storage savings
2932 ! in nsfc, r and ic can be the same array in the calling
2933 ! sequence if no reordering of the coefficient matrix has been done.
2934 ! in nnfc, r, c, and ic can all be the same array if no
2935 ! reordering has been done. if only the rows have been reordered,
2936 ! then c and ic can be the same array. if the row and column
2937 ! orderings are the same, then r and c can be the same array. z and
2938 ! row can be the same array.
2939 ! in nnsc or nntc, r and c can be the same array if no
2940 ! reordering has been done or if the row and column orderings are the
2941 ! same. z and b can be the same array. however, then b will be
2942 ! destroyed.
2943 ! iv. parameters
2944 ! following is a list of parameters to the programs. names are
2945 ! uniform among the various subroutines. class abbreviations are --
2946 ! n - integer variable
2947 ! f - real variable
2948 ! v - supplies a value to a subroutine
2949 ! r - returns a result from a subroutine
2950 ! i - used internally by a subroutine
2951 ! a - array
2952 ! class - parameter
2953 ! ------+----------
2954 ! fva - a - nonzero entries of the coefficient matrix m, stored
2955 ! - by rows.
2956 ! - size = number of nonzero entries in m.
2957 ! fva - b - right-hand side b.
2958 ! - size = n.
2959 ! nva - c - ordering of the columns of m.
2960 ! - size = n.
2961 ! fvra - d - reciprocals of the diagonal entries of the matrix d.
2962 ! - size = n.
2963 ! nr - flag - error flag. values and their meanings are --
2964 ! - 0 no errors detected
2965 ! - n+k null row in a -- row = k
2966 ! - 2n+k duplicate entry in a -- row = k
2967 ! - 3n+k insufficient storage for jl -- row = k
2968 ! - 4n+1 insufficient storage for l
2969 ! - 5n+k null pivot -- row = k
2970 ! - 6n+k insufficient storage for ju -- row = k
2971 ! - 7n+1 insufficient storage for u
2972 ! - 8n+k zero pivot -- row = k
2973 ! nva - ia - pointers to delimit the rows of a.
2974 ! - size = n+1.
2975 ! nvra - ijl - pointers to the first element in each column in jl,
2976 ! - used to compress storage in jl.
2977 ! - size = n.
2978 ! nvra - iju - pointers to the first element in each row in ju, used
2979 ! - to compress storage in ju.
2980 ! - size = n.
2981 ! nvra - il - pointers to delimit the columns of l.
2982 ! - size = n+1.
2983 ! nvra - iu - pointers to delimit the rows of u.
2984 ! - size = n+1.
2985 ! nva - ja - column numbers corresponding to the elements of a.
2986 ! - size = size of a.
2987 ! nvra - jl - row numbers corresponding to the elements of l.
2988 ! - size = jlmax.
2989 ! nv - jlmax - declared dimension of jl. jlmax must be larger than
2990 ! - the number of nonzeros in the strict lower triangle
2991 ! - of m plus fillin minus compression.
2992 ! nvra - ju - column numbers corresponding to the elements of u.
2993 ! - size = jumax.
2994 ! nv - jumax - declared dimension of ju. jumax must be larger than
2995 ! - the number of nonzeros in the strict upper triangle
2996 ! - of m plus fillin minus compression.
2997 ! fvra - l - nonzero entries in the strict lower triangular portion
2998 ! - of the matrix l, stored by columns.
2999 ! - size = lmax.
3000 ! nv - lmax - declared dimension of l. lmax must be larger than
3001 ! - the number of nonzeros in the strict lower triangle
3002 ! - of m plus fillin (il(n+1)-1 after nsfc).
3003 ! nv - n - number of variables/equations.
3004 ! nva - r - ordering of the rows of m.
3005 ! - size = n.
3006 ! fvra - u - nonzero entries in the strict upper triangular portion
3007 ! - of the matrix u, stored by rows.
3008 ! - size = umax.
3009 ! nv - umax - declared dimension of u. umax must be larger than
3010 ! - the number of nonzeros in the strict upper triangle
3011 ! - of m plus fillin (iu(n+1)-1 after nsfc).
3012 ! fra - z - solution x.
3013 ! - size = n.
3014 ! ----------------------------------------------------------------
3015 !*** subroutine nroc
3016 !*** reorders rows of a, leaving row order unchanged
3017 ! input parameters.. n, ic, ia, ja, a
3018 ! output parameters.. ja, a, flag
3019 ! parameters used internally..
3020 ! nia - p - at the kth step, p is a linked list of the reordered
3021 ! - column indices of the kth row of a. p(n+1) points
3022 ! - to the first entry in the list.
3023 ! - size = n+1.
3024 ! nia - jar - at the kth step,jar contains the elements of the
3025 ! - reordered column indices of a.
3026 ! - size = n.
3027 ! fia - ar - at the kth step, ar contains the elements of the
3028 ! - reordered row of a.
3029 ! - size = n.
3030 ! integer :: ic(*), ia(*), ja(*), jar(*), p(*), flag
3031 ! real a(*), ar(*)
3032 ! double precision :: a(*), ar(*)
3033 ! ****** for each nonempty row *******************************
3034 ! do 5 k=1,n
3035 ! jmin = ia(k)
3036 ! jmax = ia(k+1) - 1
3037 ! if(jmin > jmax) go to 5
3038 ! p(n+1) = n + 1
3039 ! ! ****** insert each element in the list *********************
3040 ! do 3 j=jmin,jmax
3041 ! newj = ic(ja(j))
3042 ! i = n + 1
3043 ! 1 if(p(i) >= newj) go to 2
3044 ! i = p(i)
3045 ! go to 1
3046 ! 2 if(p(i) == newj) go to 102
3047 ! p(newj) = p(i)
3048 ! p(i) = newj
3049 ! jar(newj) = ja(j)
3050 ! ar(newj) = a(j)
3051 ! 3 END DO
3052 ! ! ****** replace old row in ja and a *************************
3053 ! i = n + 1
3054 ! do 4 j=jmin,jmax
3055 ! i = p(i)
3056 ! ja(j) = jar(i)
3057 ! a(j) = ar(i)
3058 ! 4 END DO
3059 ! 5 END DO
3060 ! flag = 0
3061 ! return
3062 ! ** error.. duplicate entry in a
3063 ! 102 flag = n + k
3064 ! return
3065 ! end subroutine nroc
3066 ! subroutine nsfc &
3067 ! (n, r, ic, ia,ja, jlmax,il,jl,ijl, jumax,iu,ju,iju, &
3068 ! q, ira,jra, irac, irl,jrl, iru,jru, flag)
3069 !*** subroutine nsfc
3070 !*** symbolic ldu-factorization of nonsymmetric sparse matrix
3071 ! (compressed pointer storage)
3072 ! input variables.. n, r, ic, ia, ja, jlmax, jumax.
3073 ! output variables.. il, jl, ijl, iu, ju, iju, flag.
3074 ! parameters used internally..
3075 ! nia - q - suppose m* is the result of reordering m. if
3076 ! - processing of the ith row of m* (hence the ith
3077 ! - row of u) is being done, q(j) is initially
3078 ! - nonzero if m*(i,j) is nonzero (j.ge.i). since
3079 ! - values need not be stored, each entry points to the
3080 ! - next nonzero and q(n+1) points to the first. n+1
3081 ! - indicates the end of the list. for example, if n=9
3082 ! - and the 5th row of m* is
3083 ! - 0 x x 0 x 0 0 x 0
3084 ! - then q will initially be
3085 ! - a a a a 8 a a 10 5 (a - arbitrary).
3086 ! - as the algorithm proceeds, other elements of q
3087 ! - are inserted in the list because of fillin.
3088 ! - q is used in an analogous manner to compute the
3089 ! - ith column of l.
3090 ! - size = n+1.
3091 ! nia - ira, - vectors used to find the columns of m. at the kth
3092 ! nia - jra, step of the factorization, irac(k) points to the
3093 ! nia - irac head of a linked list in jra of row indices i
3094 ! - such that i .ge. k and m(i,k) is nonzero. zero
3095 ! - indicates the end of the list. ira(i) (i.ge.k)
3096 ! - points to the smallest j such that j .ge. k and
3097 ! - m(i,j) is nonzero.
3098 ! - size of each = n.
3099 ! nia - irl, - vectors used to find the rows of l. at the kth step
3100 ! nia - jrl of the factorization, jrl(k) points to the head
3101 ! - of a linked list in jrl of column indices j
3102 ! - such j .lt. k and l(k,j) is nonzero. zero
3103 ! - indicates the end of the list. irl(j) (j.lt.k)
3104 ! - points to the smallest i such that i .ge. k and
3105 ! - l(i,j) is nonzero.
3106 ! - size of each = n.
3107 ! nia - iru, - vectors used in a manner analogous to irl and jrl
3108 ! nia - jru to find the columns of u.
3109 ! - size of each = n.
3110 ! internal variables..
3111 ! jlptr - points to the last position used in jl.
3112 ! juptr - points to the last position used in ju.
3113 ! jmin,jmax - are the indices in a or u of the first and last
3114 ! elements to be examined in a given row.
3115 ! for example, jmin=ia(k), jmax=ia(k+1)-1.
3116 ! integer :: cend, qm, rend, rk, vj
3117 ! integer :: ia(*), ja(*), ira(*), jra(*), il(*), jl(*), ijl(*)
3118 ! integer :: iu(*), ju(*), iju(*), irl(*), jrl(*), iru(*), jru(*)
3119 ! integer :: r(*), ic(*), q(*), irac(*), flag
3120 ! ****** initialize pointers ****************************************
3121 ! np1 = n + 1
3122 ! jlmin = 1
3123 ! jlptr = 0
3124 ! il(1) = 1
3125 ! jumin = 1
3126 ! juptr = 0
3127 ! iu(1) = 1
3128 ! do 1 k=1,n
3129 ! irac(k) = 0
3130 ! jra(k) = 0
3131 ! jrl(k) = 0
3132 ! jru(k) = 0
3133 ! 1 END DO
3134 ! ****** initialize column pointers for a ***************************
3135 ! do 2 k=1,n
3136 ! rk = r(k)
3137 ! iak = ia(rk)
3138 ! if (iak >= ia(rk+1)) go to 101
3139 ! jaiak = ic(ja(iak))
3140 ! if (jaiak > k) go to 105
3141 ! jra(k) = irac(jaiak)
3142 ! irac(jaiak) = k
3143 ! ira(k) = iak
3144 ! 2 END DO
3145 ! ****** for each column of l and row of u **************************
3146 ! do 41 k=1,n
3147 !
3148 ! ! ****** initialize q for computing kth column of l *****************
3149 ! q(np1) = np1
3150 ! luk = -1
3151 ! ! ****** by filling in kth column of a ******************************
3152 ! vj = irac(k)
3153 ! if (vj == 0) go to 5
3154 ! 3 qm = np1
3155 ! 4 m = qm
3156 ! qm = q(m)
3157 ! if (qm < vj) go to 4
3158 ! if (qm == vj) go to 102
3159 ! luk = luk + 1
3160 ! q(m) = vj
3161 ! q(vj) = qm
3162 ! vj = jra(vj)
3163 ! if (vj /= 0) go to 3
3164 ! ! ****** link through jru *******************************************
3165 ! 5 lastid = 0
3166 ! lasti = 0
3167 ! ijl(k) = jlptr
3168 ! i = k
3169 ! 6 i = jru(i)
3170 ! if (i == 0) go to 10
3171 ! qm = np1
3172 ! jmin = irl(i)
3173 ! jmax = ijl(i) + il(i+1) - il(i) - 1
3174 ! long = jmax - jmin
3175 ! if (long < 0) go to 6
3176 ! jtmp = jl(jmin)
3177 ! if (jtmp /= k) long = long + 1
3178 ! if (jtmp == k) r(i) = -r(i)
3179 ! if (lastid >= long) go to 7
3180 ! lasti = i
3181 ! lastid = long
3182 ! ! ****** and merge the corresponding columns into the kth column ****
3183 ! 7 do 9 j=jmin,jmax
3184 ! vj = jl(j)
3185 ! 8 m = qm
3186 ! qm = q(m)
3187 ! if (qm < vj) go to 8
3188 ! if (qm == vj) go to 9
3189 ! luk = luk + 1
3190 ! q(m) = vj
3191 ! q(vj) = qm
3192 ! qm = vj
3193 ! 9 END DO
3194 ! go to 6
3195 ! ! ****** lasti is the longest column merged into the kth ************
3196 ! ! ****** see if it equals the entire kth column *********************
3197 ! 10 qm = q(np1)
3198 ! if (qm /= k) go to 105
3199 ! if (luk == 0) go to 17
3200 ! if (lastid /= luk) go to 11
3201 ! ! ****** if so, jl can be compressed ********************************
3202 ! irll = irl(lasti)
3203 ! ijl(k) = irll + 1
3204 ! if (jl(irll) /= k) ijl(k) = ijl(k) - 1
3205 ! go to 17
3206 ! ! ****** if not, see if kth column can overlap the previous one *****
3207 ! 11 if (jlmin > jlptr) go to 15
3208 ! qm = q(qm)
3209 ! do 12 j=jlmin,jlptr
3210 ! if (jl(j) - qm) 12, 13, 15
3211 ! 12 END DO
3212 ! go to 15
3213 ! 13 ijl(k) = j
3214 ! do 14 i=j,jlptr
3215 ! if (jl(i) /= qm) go to 15
3216 ! qm = q(qm)
3217 ! if (qm > n) go to 17
3218 ! 14 END DO
3219 ! jlptr = j - 1
3220 ! ! ****** move column indices from q to jl, update vectors ***********
3221 ! 15 jlmin = jlptr + 1
3222 ! ijl(k) = jlmin
3223 ! if (luk == 0) go to 17
3224 ! jlptr = jlptr + luk
3225 ! if (jlptr > jlmax) go to 103
3226 ! qm = q(np1)
3227 ! do 16 j=jlmin,jlptr
3228 ! qm = q(qm)
3229 ! jl(j) = qm
3230 ! 16 END DO
3231 ! 17 irl(k) = ijl(k)
3232 ! il(k+1) = il(k) + luk
3233 !
3234 ! ! ****** initialize q for computing kth row of u ********************
3235 ! q(np1) = np1
3236 ! luk = -1
3237 ! ! ****** by filling in kth row of reordered a ***********************
3238 ! rk = r(k)
3239 ! jmin = ira(k)
3240 ! jmax = ia(rk+1) - 1
3241 ! if (jmin > jmax) go to 20
3242 ! do 19 j=jmin,jmax
3243 ! vj = ic(ja(j))
3244 ! qm = np1
3245 ! 18 m = qm
3246 ! qm = q(m)
3247 ! if (qm < vj) go to 18
3248 ! if (qm == vj) go to 102
3249 ! luk = luk + 1
3250 ! q(m) = vj
3251 ! q(vj) = qm
3252 ! 19 END DO
3253 ! ! ****** link through jrl, ******************************************
3254 ! 20 lastid = 0
3255 ! lasti = 0
3256 ! iju(k) = juptr
3257 ! i = k
3258 ! i1 = jrl(k)
3259 ! 21 i = i1
3260 ! if (i == 0) go to 26
3261 ! i1 = jrl(i)
3262 ! qm = np1
3263 ! jmin = iru(i)
3264 ! jmax = iju(i) + iu(i+1) - iu(i) - 1
3265 ! long = jmax - jmin
3266 ! if (long < 0) go to 21
3267 ! jtmp = ju(jmin)
3268 ! if (jtmp == k) go to 22
3269 ! ! ****** update irl and jrl, *****************************************
3270 ! long = long + 1
3271 ! cend = ijl(i) + il(i+1) - il(i)
3272 ! irl(i) = irl(i) + 1
3273 ! if (irl(i) >= cend) go to 22
3274 ! j = jl(irl(i))
3275 ! jrl(i) = jrl(j)
3276 ! jrl(j) = i
3277 ! 22 if (lastid >= long) go to 23
3278 ! lasti = i
3279 ! lastid = long
3280 ! ! ****** and merge the corresponding rows into the kth row **********
3281 ! 23 do 25 j=jmin,jmax
3282 ! vj = ju(j)
3283 ! 24 m = qm
3284 ! qm = q(m)
3285 ! if (qm < vj) go to 24
3286 ! if (qm == vj) go to 25
3287 ! luk = luk + 1
3288 ! q(m) = vj
3289 ! q(vj) = qm
3290 ! qm = vj
3291 ! 25 END DO
3292 ! go to 21
3293 ! ! ****** update jrl(k) and irl(k) ***********************************
3294 ! 26 if (il(k+1) <= il(k)) go to 27
3295 ! j = jl(irl(k))
3296 ! jrl(k) = jrl(j)
3297 ! jrl(j) = k
3298 ! ! ****** lasti is the longest row merged into the kth ***************
3299 ! ! ****** see if it equals the entire kth row ************************
3300 ! 27 qm = q(np1)
3301 ! if (qm /= k) go to 105
3302 ! if (luk == 0) go to 34
3303 ! if (lastid /= luk) go to 28
3304 ! ! ****** if so, ju can be compressed ********************************
3305 ! irul = iru(lasti)
3306 ! iju(k) = irul + 1
3307 ! if (ju(irul) /= k) iju(k) = iju(k) - 1
3308 ! go to 34
3309 ! ! ****** if not, see if kth row can overlap the previous one ********
3310 ! 28 if (jumin > juptr) go to 32
3311 ! qm = q(qm)
3312 ! do 29 j=jumin,juptr
3313 ! if (ju(j) - qm) 29, 30, 32
3314 ! 29 END DO
3315 ! go to 32
3316 ! 30 iju(k) = j
3317 ! do 31 i=j,juptr
3318 ! if (ju(i) /= qm) go to 32
3319 ! qm = q(qm)
3320 ! if (qm > n) go to 34
3321 ! 31 END DO
3322 ! juptr = j - 1
3323 ! ! ****** move row indices from q to ju, update vectors **************
3324 ! 32 jumin = juptr + 1
3325 ! iju(k) = jumin
3326 ! if (luk == 0) go to 34
3327 ! juptr = juptr + luk
3328 ! if (juptr > jumax) go to 106
3329 ! qm = q(np1)
3330 ! do 33 j=jumin,juptr
3331 ! qm = q(qm)
3332 ! ju(j) = qm
3333 ! 33 END DO
3334 ! 34 iru(k) = iju(k)
3335 ! iu(k+1) = iu(k) + luk
3336 !
3337 ! ! ****** update iru, jru ********************************************
3338 ! i = k
3339 ! 35 i1 = jru(i)
3340 ! if (r(i) < 0) go to 36
3341 ! rend = iju(i) + iu(i+1) - iu(i)
3342 ! if (iru(i) >= rend) go to 37
3343 ! j = ju(iru(i))
3344 ! jru(i) = jru(j)
3345 ! jru(j) = i
3346 ! go to 37
3347 ! 36 r(i) = -r(i)
3348 ! 37 i = i1
3349 ! if (i == 0) go to 38
3350 ! iru(i) = iru(i) + 1
3351 ! go to 35
3352 !
3353 ! ! ****** update ira, jra, irac **************************************
3354 ! 38 i = irac(k)
3355 ! if (i == 0) go to 41
3356 ! 39 i1 = jra(i)
3357 ! ira(i) = ira(i) + 1
3358 ! if (ira(i) >= ia(r(i)+1)) go to 40
3359 ! irai = ira(i)
3360 ! jairai = ic(ja(irai))
3361 ! if (jairai > i) go to 40
3362 ! jra(i) = irac(jairai)
3363 ! irac(jairai) = i
3364 ! 40 i = i1
3365 ! if (i /= 0) go to 39
3366 ! 41 END DO
3367 ! ijl(n) = jlptr
3368 ! iju(n) = juptr
3369 ! flag = 0
3370 ! return
3371 ! ** error.. null row in a
3372 ! 101 flag = n + rk
3373 ! return
3374 ! ** error.. duplicate entry in a
3375 ! 102 flag = 2*n + rk
3376 ! return
3377 ! ** error.. insufficient storage for jl
3378 ! 103 flag = 3*n + k
3379 ! return
3380 ! ** error.. null pivot
3381 ! 105 flag = 5*n + k
3382 ! return
3383 ! ** error.. insufficient storage for ju
3384 ! 106 flag = 6*n + k
3385 ! return
3386 ! end subroutine nsfc
3387 ! subroutine nnfc &
3388 ! (n, r,c,ic, ia,ja,a, z, b, &
3389 ! lmax,il,jl,ijl,l, d, umax,iu,ju,iju,u, &
3390 ! row, tmp, irl,jrl, flag)
3391 !*** subroutine nnfc
3392 !*** numerical ldu-factorization of sparse nonsymmetric matrix and
3393 ! solution of system of linear equations (compressed pointer
3394 ! storage)
3395 ! input variables.. n, r, c, ic, ia, ja, a, b,
3396 ! il, jl, ijl, lmax, iu, ju, iju, umax
3397 ! output variables.. z, l, d, u, flag
3398 ! parameters used internally..
3399 ! nia - irl, - vectors used to find the rows of l. at the kth step
3400 ! nia - jrl of the factorization, jrl(k) points to the head
3401 ! - of a linked list in jrl of column indices j
3402 ! - such j .lt. k and l(k,j) is nonzero. zero
3403 ! - indicates the end of the list. irl(j) (j.lt.k)
3404 ! - points to the smallest i such that i .ge. k and
3405 ! - l(i,j) is nonzero.
3406 ! - size of each = n.
3407 ! fia - row - holds intermediate values in calculation of u and l.
3408 ! - size = n.
3409 ! fia - tmp - holds new right-hand side b* for solution of the
3410 ! - equation ux = b*.
3411 ! - size = n.
3412 ! internal variables..
3413 ! jmin, jmax - indices of the first and last positions in a row to
3414 ! be examined.
3415 ! sum - used in calculating tmp.
3416 ! integer :: rk,umax
3417 ! integer :: r(*), c(*), ic(*), ia(*), ja(*), il(*), jl(*), ijl(*)
3418 ! integer :: iu(*), ju(*), iju(*), irl(*), jrl(*), flag
3419 ! real a(*), l(*), d(*), u(*), z(*), b(*), row(*)
3420 ! real tmp(*), lki, sum, dk
3421 ! double precision :: a(*), l(*), d(*), u(*), z(*), b(*), row(*)
3422 ! double precision :: tmp(*), lki, sum, dk
3423 ! ****** initialize pointers and test storage ***********************
3424 ! if(il(n+1)-1 > lmax) go to 104
3425 ! if(iu(n+1)-1 > umax) go to 107
3426 ! do 1 k=1,n
3427 ! irl(k) = il(k)
3428 ! jrl(k) = 0
3429 ! 1 END DO
3430 ! ****** for each row ***********************************************
3431 ! do 19 k=1,n
3432 ! ! ****** reverse jrl and zero row where kth row of l will fill in ***
3433 ! row(k) = 0
3434 ! i1 = 0
3435 ! if (jrl(k) == 0) go to 3
3436 ! i = jrl(k)
3437 ! 2 i2 = jrl(i)
3438 ! jrl(i) = i1
3439 ! i1 = i
3440 ! row(i) = 0
3441 ! i = i2
3442 ! if (i /= 0) go to 2
3443 ! ! ****** set row to zero where u will fill in ***********************
3444 ! 3 jmin = iju(k)
3445 ! jmax = jmin + iu(k+1) - iu(k) - 1
3446 ! if (jmin > jmax) go to 5
3447 ! do 4 j=jmin,jmax
3448 ! row(ju(j)) = 0
3449 ! 4 END DO
3450 ! ! ****** place kth row of a in row **********************************
3451 ! 5 rk = r(k)
3452 ! jmin = ia(rk)
3453 ! jmax = ia(rk+1) - 1
3454 ! do 6 j=jmin,jmax
3455 ! row(ic(ja(j))) = a(j)
3456 ! 6 END DO
3457 ! ! ****** initialize sum, and link through jrl ***********************
3458 ! sum = b(rk)
3459 ! i = i1
3460 ! if (i == 0) go to 10
3461 ! ! ****** assign the kth row of l and adjust row, sum ****************
3462 ! 7 lki = -row(i)
3463 ! ! ****** if l is not required, then comment out the following line **
3464 ! l(irl(i)) = -lki
3465 ! sum = sum + lki * tmp(i)
3466 ! jmin = iu(i)
3467 ! jmax = iu(i+1) - 1
3468 ! if (jmin > jmax) go to 9
3469 ! mu = iju(i) - jmin
3470 ! do 8 j=jmin,jmax
3471 ! row(ju(mu+j)) = row(ju(mu+j)) + lki * u(j)
3472 ! 8 END DO
3473 ! 9 i = jrl(i)
3474 ! if (i /= 0) go to 7
3475 !
3476 ! ! ****** assign kth row of u and diagonal d, set tmp(k) *************
3477 ! 10 if (row(k) == 0.0d0) go to 108
3478 ! dk = 1.0d0 / row(k)
3479 ! d(k) = dk
3480 ! tmp(k) = sum * dk
3481 ! if (k == n) go to 19
3482 ! jmin = iu(k)
3483 ! jmax = iu(k+1) - 1
3484 ! if (jmin > jmax) go to 12
3485 ! mu = iju(k) - jmin
3486 ! do 11 j=jmin,jmax
3487 ! u(j) = row(ju(mu+j)) * dk
3488 ! 11 END DO
3489 ! 12 continue
3490 !
3491 ! ! ****** update irl and jrl, keeping jrl in decreasing order ********
3492 ! i = i1
3493 ! if (i == 0) go to 18
3494 ! 14 irl(i) = irl(i) + 1
3495 ! i1 = jrl(i)
3496 ! if (irl(i) >= il(i+1)) go to 17
3497 ! ijlb = irl(i) - il(i) + ijl(i)
3498 ! j = jl(ijlb)
3499 ! 15 if (i > jrl(j)) go to 16
3500 ! j = jrl(j)
3501 ! go to 15
3502 ! 16 jrl(i) = jrl(j)
3503 ! jrl(j) = i
3504 ! 17 i = i1
3505 ! if (i /= 0) go to 14
3506 ! 18 if (irl(k) >= il(k+1)) go to 19
3507 ! j = jl(ijl(k))
3508 ! jrl(k) = jrl(j)
3509 ! jrl(j) = k
3510 ! 19 END DO
3511 ! ****** solve ux = tmp by back substitution **********************
3512 ! k = n
3513 ! do 22 i=1,n
3514 ! sum = tmp(k)
3515 ! jmin = iu(k)
3516 ! jmax = iu(k+1) - 1
3517 ! if (jmin > jmax) go to 21
3518 ! mu = iju(k) - jmin
3519 ! do 20 j=jmin,jmax
3520 ! sum = sum - u(j) * tmp(ju(mu+j))
3521 ! 20 END DO
3522 ! 21 tmp(k) = sum
3523 ! z(c(k)) = sum
3524 ! k = k-1
3525 ! 22 END DO
3526 ! flag = 0
3527 ! return
3528 ! ** error.. insufficient storage for l
3529 ! 104 flag = 4*n + 1
3530 ! return
3531 ! ** error.. insufficient storage for u
3532 ! 107 flag = 7*n + 1
3533 ! return
3534 ! ** error.. zero pivot
3535 ! 108 flag = 8*n + k
3536 ! return
3537 ! end subroutine nnfc
3538 ! subroutine nnsc &
3539 ! (n, r, c, il, jl, ijl, l, d, iu, ju, iju, u, z, b, tmp)
3540 !*** subroutine nnsc
3541 !*** numerical solution of sparse nonsymmetric system of linear
3542 ! equations given ldu-factorization (compressed pointer storage)
3543 ! input variables.. n, r, c, il, jl, ijl, l, d, iu, ju, iju, u, b
3544 ! output variables.. z
3545 ! parameters used internally..
3546 ! fia - tmp - temporary vector which gets result of solving ly = b.
3547 ! - size = n.
3548 ! internal variables..
3549 ! jmin, jmax - indices of the first and last positions in a row of
3550 ! u or l to be used.
3551 ! integer :: r(*), c(*), il(*), jl(*), ijl(*), iu(*), ju(*), iju(*)
3552 ! real l(*), d(*), u(*), b(*), z(*), tmp(*), tmpk, sum
3553 ! double precision :: l(*), d(*), u(*), b(*), z(*), tmp(*), tmpk,sum
3554 ! ****** set tmp to reordered b *************************************
3555 ! do 1 k=1,n
3556 ! tmp(k) = b(r(k))
3557 ! 1 END DO
3558 ! ****** solve ly = b by forward substitution *********************
3559 ! do 3 k=1,n
3560 ! jmin = il(k)
3561 ! jmax = il(k+1) - 1
3562 ! tmpk = -d(k) * tmp(k)
3563 ! tmp(k) = -tmpk
3564 ! if (jmin > jmax) go to 3
3565 ! ml = ijl(k) - jmin
3566 ! do 2 j=jmin,jmax
3567 ! tmp(jl(ml+j)) = tmp(jl(ml+j)) + tmpk * l(j)
3568 ! 2 END DO
3569 ! 3 END DO
3570 ! ****** solve ux = y by back substitution ************************
3571 ! k = n
3572 ! do 6 i=1,n
3573 ! sum = -tmp(k)
3574 ! jmin = iu(k)
3575 ! jmax = iu(k+1) - 1
3576 ! if (jmin > jmax) go to 5
3577 ! mu = iju(k) - jmin
3578 ! do 4 j=jmin,jmax
3579 ! sum = sum + u(j) * tmp(ju(mu+j))
3580 ! 4 END DO
3581 ! 5 tmp(k) = -sum
3582 ! z(c(k)) = -sum
3583 ! k = k - 1
3584 ! 6 END DO
3585 ! return
3586 ! end subroutine nnsc
3587 ! subroutine nntc &
3588 ! (n, r, c, il, jl, ijl, l, d, iu, ju, iju, u, z, b, tmp)
3589 !*** subroutine nntc
3590 !*** numeric solution of the transpose of a sparse nonsymmetric system
3591 ! of linear equations given lu-factorization (compressed pointer
3592 ! storage)
3593 ! input variables.. n, r, c, il, jl, ijl, l, d, iu, ju, iju, u, b
3594 ! output variables.. z
3595 ! parameters used internally..
3596 ! fia - tmp - temporary vector which gets result of solving ut y = b
3597 ! - size = n.
3598 ! internal variables..
3599 ! jmin, jmax - indices of the first and last positions in a row of
3600 ! u or l to be used.
3601 ! integer :: r(*), c(*), il(*), jl(*), ijl(*), iu(*), ju(*), iju(*)
3602 ! real l(*), d(*), u(*), b(*), z(*), tmp(*), tmpk,sum
3603 ! double precision :: l(*), d(*), u(*), b(*), z(*), tmp(*), tmpk,sum
3604 ! ****** set tmp to reordered b *************************************
3605 ! do 1 k=1,n
3606 ! tmp(k) = b(c(k))
3607 ! 1 END DO
3608 ! ****** solve ut y = b by forward substitution *******************
3609 ! do 3 k=1,n
3610 ! jmin = iu(k)
3611 ! jmax = iu(k+1) - 1
3612 ! tmpk = -tmp(k)
3613 ! if (jmin > jmax) go to 3
3614 ! mu = iju(k) - jmin
3615 ! do 2 j=jmin,jmax
3616 ! tmp(ju(mu+j)) = tmp(ju(mu+j)) + tmpk * u(j)
3617 ! 2 END DO
3618 ! 3 END DO
3619 ! ****** solve lt x = y by back substitution **********************
3620 ! k = n
3621 ! do 6 i=1,n
3622 ! sum = -tmp(k)
3623 ! jmin = il(k)
3624 ! jmax = il(k+1) - 1
3625 ! if (jmin > jmax) go to 5
3626 ! ml = ijl(k) - jmin
3627 ! do 4 j=jmin,jmax
3628 ! sum = sum + l(j) * tmp(jl(ml+j))
3629 ! 4 END DO
3630 ! 5 tmp(k) = -sum * d(k)
3631 ! z(r(k)) = tmp(k)
3632 ! k = k - 1
3633 ! 6 END DO
3634 ! return
3635 ! end subroutine nntc
3636 ! ECK DSTODA
3637 ! SUBROUTINE DSTODA (NEQ, Y, YH, NYH, YH1, EWT, SAVF, ACOR, &
3638 ! WM, IWM, F, JAC, PJAC, SLVS)
3639 ! EXTERNAL F, JAC, PJAC, SLVS
3640 ! INTEGER :: NEQ, NYH, IWM
3641 ! DOUBLE PRECISION :: Y, YH, YH1, EWT, SAVF, ACOR, WM
3642 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), YH1(*), EWT(*), SAVF(*), &
3643 ! ACOR(*), WM(*), IWM(*)
3644 ! INTEGER :: IOWND, IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, &
3645 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
3646 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
3647 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
3648 ! INTEGER :: IOWND2, ICOUNT, IRFLAG, JTYP, MUSED, MXORDN, MXORDS
3649 ! DOUBLE PRECISION :: CONIT, CRATE, EL, ELCO, HOLD, RMAX, TESCO, &
3650 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
3651 ! DOUBLE PRECISION :: ROWND2, CM1, CM2, PDEST, PDLAST, RATIO, &
3652 ! PDNORM
3653 ! COMMON /DLS001/ CONIT, CRATE, EL(13), ELCO(13,12), &
3654 ! HOLD, RMAX, TESCO(3,12), &
3655 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
3656 ! IOWND(6), IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, &
3657 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
3658 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
3659 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
3660 ! COMMON /DLSA01/ ROWND2, CM1(12), CM2(5), PDEST, PDLAST, RATIO, &
3661 ! PDNORM, &
3662 ! IOWND2(3), ICOUNT, IRFLAG, JTYP, MUSED, MXORDN, MXORDS
3663 ! INTEGER :: I, I1, IREDO, IRET, J, JB, M, NCF, NEWQ
3664 ! INTEGER :: LM1, LM1P1, LM2, LM2P1, NQM1, NQM2
3665 ! DOUBLE PRECISION :: DCON, DDN, DEL, DELP, DSM, DUP, EXDN, EXSM, EXUP, &
3666 ! R, RH, RHDN, RHSM, RHUP, TOLD, DMNORM
3667 ! DOUBLE PRECISION :: ALPHA, DM1,DM2, EXM1,EXM2, &
3668 ! PDH, PNORM, RATE, RH1, RH1IT, RH2, RM, SM1(12)
3669 ! SAVE SM1
3670 ! DATA SM1/0.5D0, 0.575D0, 0.55D0, 0.45D0, 0.35D0, 0.25D0, &
3671 ! & 0.20D0, 0.15D0, 0.10D0, 0.075D0, 0.050D0, 0.025D0/
3672 !-----------------------------------------------------------------------
3673 ! DSTODA performs one step of the integration of an initial value
3674 ! problem for a system of ordinary differential equations.
3675 ! Note: DSTODA is independent of the value of the iteration method
3676 ! indicator MITER, when this is .ne. 0, and hence is independent
3677 ! of the type of chord method used, or the Jacobian structure.
3678 ! Communication with DSTODA is done with the following variables:
3679 ! Y = an array of length .ge. N used as the Y argument in
3680 ! all calls to F and JAC.
3681 ! NEQ = integer array containing problem size in NEQ(1), and
3682 ! passed as the NEQ argument in all calls to F and JAC.
3683 ! YH = an NYH by LMAX array containing the dependent variables
3684 ! and their approximate scaled derivatives, where
3685 ! LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
3686 ! j-th derivative of y(i), scaled by H**j/factorial(j)
3687 ! (j = 0,1,...,NQ). On entry for the first step, the first
3688 ! two columns of YH must be set from the initial values.
3689 ! NYH = a constant integer .ge. N, the first dimension of YH.
3690 ! YH1 = a one-dimensional array occupying the same space as YH.
3691 ! EWT = an array of length N containing multiplicative weights
3692 ! for local error measurements. Local errors in y(i) are
3693 ! compared to 1.0/EWT(i) in various error tests.
3694 ! SAVF = an array of working storage, of length N.
3695 ! ACOR = a work array of length N, used for the accumulated
3696 ! corrections. On a successful return, ACOR(i) contains
3697 ! the estimated one-step local error in y(i).
3698 ! WM,IWM = real and integer work arrays associated with matrix
3699 ! operations in chord iteration (MITER .ne. 0).
3700 ! PJAC = name of routine to evaluate and preprocess Jacobian matrix
3701 ! and P = I - H*EL0*Jac, if a chord method is being used.
3702 ! It also returns an estimate of norm(Jac) in PDNORM.
3703 ! SLVS = name of routine to solve linear system in chord iteration.
3704 ! CCMAX = maximum relative change in H*EL0 before PJAC is called.
3705 ! H = the step size to be attempted on the next step.
3706 ! H is altered by the error control algorithm during the
3707 ! problem. H can be either positive or negative, but its
3708 ! sign must remain constant throughout the problem.
3709 ! HMIN = the minimum absolute value of the step size H to be used.
3710 ! HMXI = inverse of the maximum absolute value of H to be used.
3711 ! HMXI = 0.0 is allowed and corresponds to an infinite HMAX.
3712 ! HMIN and HMXI may be changed at any time, but will not
3713 ! take effect until the next change of H is considered.
3714 ! TN = the independent variable. TN is updated on each step taken.
3715 ! JSTART = an integer used for input only, with the following
3716 ! values and meanings:
3717 ! 0 perform the first step.
3718 ! .gt.0 take a new step continuing from the last.
3719 ! -1 take the next step with a new value of H,
3720 ! N, METH, MITER, and/or matrix parameters.
3721 ! -2 take the next step with a new value of H,
3722 ! but with other inputs unchanged.
3723 ! On return, JSTART is set to 1 to facilitate continuation.
3724 ! KFLAG = a completion code with the following meanings:
3725 ! 0 the step was succesful.
3726 ! -1 the requested error could not be achieved.
3727 ! -2 corrector convergence could not be achieved.
3728 ! -3 fatal error in PJAC or SLVS.
3729 ! A return with KFLAG = -1 or -2 means either
3730 ! ABS(H) = HMIN or 10 consecutive failures occurred.
3731 ! On a return with KFLAG negative, the values of TN and
3732 ! the YH array are as of the beginning of the last
3733 ! step, and H is the last step size attempted.
3734 ! MAXORD = the maximum order of integration method to be allowed.
3735 ! MAXCOR = the maximum number of corrector iterations allowed.
3736 ! MSBP = maximum number of steps between PJAC calls (MITER .gt. 0).
3737 ! MXNCF = maximum number of convergence failures allowed.
3738 ! METH = current method.
3739 ! METH = 1 means Adams method (nonstiff)
3740 ! METH = 2 means BDF method (stiff)
3741 ! METH may be reset by DSTODA.
3742 ! MITER = corrector iteration method.
3743 ! MITER = 0 means functional iteration.
3744 ! MITER = JT .gt. 0 means a chord iteration corresponding
3745 ! to Jacobian type JT. (The DLSODA/DLSODAR argument JT is
3746 ! communicated here as JTYP, but is not used in DSTODA
3747 ! except to load MITER following a method switch.)
3748 ! MITER may be reset by DSTODA.
3749 ! N = the number of first-order differential equations.
3750 !-----------------------------------------------------------------------
3751 ! KFLAG = 0
3752 ! TOLD = TN
3753 ! NCF = 0
3754 ! IERPJ = 0
3755 ! IERSL = 0
3756 ! JCUR = 0
3757 ! ICF = 0
3758 ! DELP = 0.0D0
3759 ! IF (JSTART > 0) GO TO 200
3760 ! IF (JSTART == -1) GO TO 100
3761 ! IF (JSTART == -2) GO TO 160
3762 !-----------------------------------------------------------------------
3763 ! On the first call, the order is set to 1, and other variables are
3764 ! initialized. RMAX is the maximum ratio by which H can be increased
3765 ! in a single step. It is initially 1.E4 to compensate for the small
3766 ! initial H, but then is normally equal to 10. If a failure
3767 ! occurs (in corrector convergence or error test), RMAX is set at 2
3768 ! for the next increase.
3769 ! DCFODE is called to get the needed coefficients for both methods.
3770 !-----------------------------------------------------------------------
3771 ! LMAX = MAXORD + 1
3772 ! NQ = 1
3773 ! L = 2
3774 ! IALTH = 2
3775 ! RMAX = 10000.0D0
3776 ! RC = 0.0D0
3777 ! EL0 = 1.0D0
3778 ! CRATE = 0.7D0
3779 ! HOLD = H
3780 ! NSLP = 0
3781 ! IPUP = MITER
3782 ! IRET = 3
3783 ! Initialize switching parameters. METH = 1 is assumed initially. -----
3784 ! ICOUNT = 20
3785 ! IRFLAG = 0
3786 ! PDEST = 0.0D0
3787 ! PDLAST = 0.0D0
3788 ! RATIO = 5.0D0
3789 ! CALL DCFODE (2, ELCO, TESCO)
3790 ! DO 10 I = 1,5
3791 ! CM2(I) = TESCO(2,I)*ELCO(I+1,I)
3792 ! 10 END DO
3793 ! CALL DCFODE (1, ELCO, TESCO)
3794 ! DO 20 I = 1,12
3795 ! CM1(I) = TESCO(2,I)*ELCO(I+1,I)
3796 ! 20 END DO
3797 ! GO TO 150
3798 !-----------------------------------------------------------------------
3799 ! The following block handles preliminaries needed when JSTART = -1.
3800 ! IPUP is set to MITER to force a matrix update.
3801 ! If an order increase is about to be considered (IALTH = 1),
3802 ! IALTH is reset to 2 to postpone consideration one more step.
3803 ! If the caller has changed METH, DCFODE is called to reset
3804 ! the coefficients of the method.
3805 ! If H is to be changed, YH must be rescaled.
3806 ! If H or METH is being changed, IALTH is reset to L = NQ + 1
3807 ! to prevent further changes in H for that many steps.
3808 !-----------------------------------------------------------------------
3809 ! 100 IPUP = MITER
3810 ! LMAX = MAXORD + 1
3811 ! IF (IALTH == 1) IALTH = 2
3812 ! IF (METH == MUSED) GO TO 160
3813 ! CALL DCFODE (METH, ELCO, TESCO)
3814 ! IALTH = L
3815 ! IRET = 1
3816 !-----------------------------------------------------------------------
3817 ! The el vector and related constants are reset
3818 ! whenever the order NQ is changed, or at the start of the problem.
3819 !-----------------------------------------------------------------------
3820 ! 150 DO 155 I = 1,L
3821 ! EL(I) = ELCO(I,NQ)
3822 ! 155 END DO
3823 ! NQNYH = NQ*NYH
3824 ! RC = RC*EL(1)/EL0
3825 ! EL0 = EL(1)
3826 ! CONIT = 0.5D0/(NQ+2)
3827 ! GO TO (160, 170, 200), IRET
3828 !-----------------------------------------------------------------------
3829 ! If H is being changed, the H ratio RH is checked against
3830 ! RMAX, HMIN, and HMXI, and the YH array rescaled. IALTH is set to
3831 ! L = NQ + 1 to prevent a change of H for that many steps, unless
3832 ! forced by a convergence or error test failure.
3833 !-----------------------------------------------------------------------
3834 ! 160 IF (H == HOLD) GO TO 200
3835 ! RH = H/HOLD
3836 ! H = HOLD
3837 ! IREDO = 3
3838 ! GO TO 175
3839 ! 170 RH = MAX(RH,HMIN/ABS(H))
3840 ! 175 RH = MIN(RH,RMAX)
3841 ! RH = RH/MAX(1.0D0,ABS(H)*HMXI*RH)
3842 !-----------------------------------------------------------------------
3843 ! If METH = 1, also restrict the new step size by the stability region.
3844 ! If this reduces H, set IRFLAG to 1 so that if there are roundoff
3845 ! problems later, we can assume that is the cause of the trouble.
3846 !-----------------------------------------------------------------------
3847 ! IF (METH == 2) GO TO 178
3848 ! IRFLAG = 0
3849 ! PDH = MAX(ABS(H)*PDLAST,0.000001D0)
3850 ! IF (RH*PDH*1.00001D0 < SM1(NQ)) GO TO 178
3851 ! RH = SM1(NQ)/PDH
3852 ! IRFLAG = 1
3853 ! 178 CONTINUE
3854 ! R = 1.0D0
3855 ! DO 180 J = 2,L
3856 ! R = R*RH
3857 ! DO 180 I = 1,N
3858 ! YH(I,J) = YH(I,J)*R
3859 ! 180 END DO
3860 ! H = H*RH
3861 ! RC = RC*RH
3862 ! IALTH = L
3863 ! IF (IREDO == 0) GO TO 690
3864 !-----------------------------------------------------------------------
3865 ! This section computes the predicted values by effectively
3866 ! multiplying the YH array by the Pascal triangle matrix.
3867 ! RC is the ratio of new to old values of the coefficient H*EL(1).
3868 ! When RC differs from 1 by more than CCMAX, IPUP is set to MITER
3869 ! to force PJAC to be called, if a Jacobian is involved.
3870 ! In any case, PJAC is called at least every MSBP steps.
3871 !-----------------------------------------------------------------------
3872 ! 200 IF (ABS(RC-1.0D0) > CCMAX) IPUP = MITER
3873 ! IF (NST >= NSLP+MSBP) IPUP = MITER
3874 ! TN = TN + H
3875 ! I1 = NQNYH + 1
3876 ! DO 215 JB = 1,NQ
3877 ! I1 = I1 - NYH
3878 ! ! IR$ IVDEP
3879 ! DO 210 I = I1,NQNYH
3880 ! YH1(I) = YH1(I) + YH1(I+NYH)
3881 ! 210 END DO
3882 ! 215 END DO
3883 ! PNORM = DMNORM (N, YH1, EWT)
3884 !-----------------------------------------------------------------------
3885 ! Up to MAXCOR corrector iterations are taken. A convergence test is
3886 ! made on the RMS-norm of each correction, weighted by the error
3887 ! weight vector EWT. The sum of the corrections is accumulated in the
3888 ! vector ACOR(i). The YH array is not altered in the corrector loop.
3889 !-----------------------------------------------------------------------
3890 ! 220 M = 0
3891 ! RATE = 0.0D0
3892 ! DEL = 0.0D0
3893 ! DO 230 I = 1,N
3894 ! Y(I) = YH(I,1)
3895 ! 230 END DO
3896 ! CALL F (NEQ, TN, Y, SAVF)
3897 ! NFE = NFE + 1
3898 ! IF (IPUP <= 0) GO TO 250
3899 !-----------------------------------------------------------------------
3900 ! If indicated, the matrix P = I - H*EL(1)*J is reevaluated and
3901 ! preprocessed before starting the corrector iteration. IPUP is set
3902 ! to 0 as an indicator that this has been done.
3903 !-----------------------------------------------------------------------
3904 ! CALL PJAC (NEQ, Y, YH, NYH, EWT, ACOR, SAVF, WM, IWM, F, JAC)
3905 ! IPUP = 0
3906 ! RC = 1.0D0
3907 ! NSLP = NST
3908 ! CRATE = 0.7D0
3909 ! IF (IERPJ /= 0) GO TO 430
3910 ! 250 DO 260 I = 1,N
3911 ! ACOR(I) = 0.0D0
3912 ! 260 END DO
3913 ! 270 IF (MITER /= 0) GO TO 350
3914 !-----------------------------------------------------------------------
3915 ! In the case of functional iteration, update Y directly from
3916 ! the result of the last function evaluation.
3917 !-----------------------------------------------------------------------
3918 ! DO 290 I = 1,N
3919 ! SAVF(I) = H*SAVF(I) - YH(I,2)
3920 ! Y(I) = SAVF(I) - ACOR(I)
3921 ! 290 END DO
3922 ! DEL = DMNORM (N, Y, EWT)
3923 ! DO 300 I = 1,N
3924 ! Y(I) = YH(I,1) + EL(1)*SAVF(I)
3925 ! ACOR(I) = SAVF(I)
3926 ! 300 END DO
3927 ! GO TO 400
3928 !-----------------------------------------------------------------------
3929 ! In the case of the chord method, compute the corrector error,
3930 ! and solve the linear system with that as right-hand side and
3931 ! P as coefficient matrix.
3932 !-----------------------------------------------------------------------
3933 ! 350 DO 360 I = 1,N
3934 ! Y(I) = H*SAVF(I) - (YH(I,2) + ACOR(I))
3935 ! 360 END DO
3936 ! CALL SLVS (WM, IWM, Y, SAVF)
3937 ! IF (IERSL < 0) GO TO 430
3938 ! IF (IERSL > 0) GO TO 410
3939 ! DEL = DMNORM (N, Y, EWT)
3940 ! DO 380 I = 1,N
3941 ! ACOR(I) = ACOR(I) + Y(I)
3942 ! Y(I) = YH(I,1) + EL(1)*ACOR(I)
3943 ! 380 END DO
3944 !-----------------------------------------------------------------------
3945 ! Test for convergence. If M .gt. 0, an estimate of the convergence
3946 ! rate constant is stored in CRATE, and this is used in the test.
3947 ! We first check for a change of iterates that is the size of
3948 ! roundoff error. If this occurs, the iteration has converged, and a
3949 ! new rate estimate is not formed.
3950 ! In all other cases, force at least two iterations to estimate a
3951 ! local Lipschitz constant estimate for Adams methods.
3952 ! On convergence, form PDEST = local maximum Lipschitz constant
3953 ! estimate. PDLAST is the most recent nonzero estimate.
3954 !-----------------------------------------------------------------------
3955 ! 400 CONTINUE
3956 ! IF (DEL <= 100.0D0*PNORM*UROUND) GO TO 450
3957 ! IF (M == 0 .AND. METH == 1) GO TO 405
3958 ! IF (M == 0) GO TO 402
3959 ! RM = 1024.0D0
3960 ! IF (DEL <= 1024.0D0*DELP) RM = DEL/DELP
3961 ! RATE = MAX(RATE,RM)
3962 ! CRATE = MAX(0.2D0*CRATE,RM)
3963 ! 402 DCON = DEL*MIN(1.0D0,1.5D0*CRATE)/(TESCO(2,NQ)*CONIT)
3964 ! IF (DCON > 1.0D0) GO TO 405
3965 ! PDEST = MAX(PDEST,RATE/ABS(H*EL(1)))
3966 ! IF (PDEST /= 0.0D0) PDLAST = PDEST
3967 ! GO TO 450
3968 ! 405 CONTINUE
3969 ! M = M + 1
3970 ! IF (M == MAXCOR) GO TO 410
3971 ! IF (M >= 2 .AND. DEL > 2.0D0*DELP) GO TO 410
3972 ! DELP = DEL
3973 ! CALL F (NEQ, TN, Y, SAVF)
3974 ! NFE = NFE + 1
3975 ! GO TO 270
3976 !-----------------------------------------------------------------------
3977 ! The corrector iteration failed to converge.
3978 ! If MITER .ne. 0 and the Jacobian is out of date, PJAC is called for
3979 ! the next try. Otherwise the YH array is retracted to its values
3980 ! before prediction, and H is reduced, if possible. If H cannot be
3981 ! reduced or MXNCF failures have occurred, exit with KFLAG = -2.
3982 !-----------------------------------------------------------------------
3983 ! 410 IF (MITER == 0 .OR. JCUR == 1) GO TO 430
3984 ! ICF = 1
3985 ! IPUP = MITER
3986 ! GO TO 220
3987 ! 430 ICF = 2
3988 ! NCF = NCF + 1
3989 ! RMAX = 2.0D0
3990 ! TN = TOLD
3991 ! I1 = NQNYH + 1
3992 ! DO 445 JB = 1,NQ
3993 ! I1 = I1 - NYH
3994 ! ! IR$ IVDEP
3995 ! DO 440 I = I1,NQNYH
3996 ! YH1(I) = YH1(I) - YH1(I+NYH)
3997 ! 440 END DO
3998 ! 445 END DO
3999 ! IF (IERPJ < 0 .OR. IERSL < 0) GO TO 680
4000 ! IF (ABS(H) <= HMIN*1.00001D0) GO TO 670
4001 ! IF (NCF == MXNCF) GO TO 670
4002 ! RH = 0.25D0
4003 ! IPUP = MITER
4004 ! IREDO = 1
4005 ! GO TO 170
4006 !-----------------------------------------------------------------------
4007 ! The corrector has converged. JCUR is set to 0
4008 ! to signal that the Jacobian involved may need updating later.
4009 ! The local error test is made and control passes to statement 500
4010 ! if it fails.
4011 !-----------------------------------------------------------------------
4012 ! 450 JCUR = 0
4013 ! IF (M == 0) DSM = DEL/TESCO(2,NQ)
4014 ! IF (M > 0) DSM = DMNORM (N, ACOR, EWT)/TESCO(2,NQ)
4015 ! IF (DSM > 1.0D0) GO TO 500
4016 !-----------------------------------------------------------------------
4017 ! After a successful step, update the YH array.
4018 ! Decrease ICOUNT by 1, and if it is -1, consider switching methods.
4019 ! If a method switch is made, reset various parameters,
4020 ! rescale the YH array, and exit. If there is no switch,
4021 ! consider changing H if IALTH = 1. Otherwise decrease IALTH by 1.
4022 ! If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
4023 ! use in a possible order increase on the next step.
4024 ! If a change in H is considered, an increase or decrease in order
4025 ! by one is considered also. A change in H is made only if it is by a
4026 ! factor of at least 1.1. If not, IALTH is set to 3 to prevent
4027 ! testing for that many steps.
4028 !-----------------------------------------------------------------------
4029 ! KFLAG = 0
4030 ! IREDO = 0
4031 ! NST = NST + 1
4032 ! HU = H
4033 ! NQU = NQ
4034 ! MUSED = METH
4035 ! DO 460 J = 1,L
4036 ! DO 460 I = 1,N
4037 ! YH(I,J) = YH(I,J) + EL(J)*ACOR(I)
4038 ! 460 END DO
4039 ! ICOUNT = ICOUNT - 1
4040 ! IF (ICOUNT >= 0) GO TO 488
4041 ! IF (METH == 2) GO TO 480
4042 !-----------------------------------------------------------------------
4043 ! We are currently using an Adams method. Consider switching to BDF.
4044 ! If the current order is greater than 5, assume the problem is
4045 ! not stiff, and skip this section.
4046 ! If the Lipschitz constant and error estimate are not polluted
4047 ! by roundoff, go to 470 and perform the usual test.
4048 ! Otherwise, switch to the BDF methods if the last step was
4049 ! restricted to insure stability (irflag = 1), and stay with Adams
4050 ! method if not. When switching to BDF with polluted error estimates,
4051 ! in the absence of other information, double the step size.
4052 ! When the estimates are OK, we make the usual test by computing
4053 ! the step size we could have (ideally) used on this step,
4054 ! with the current (Adams) method, and also that for the BDF.
4055 ! If NQ .gt. MXORDS, we consider changing to order MXORDS on switching.
4056 ! Compare the two step sizes to decide whether to switch.
4057 ! The step size advantage must be at least RATIO = 5 to switch.
4058 !-----------------------------------------------------------------------
4059 ! IF (NQ > 5) GO TO 488
4060 ! IF (DSM > 100.0D0*PNORM*UROUND .AND. PDEST /= 0.0D0) &
4061 ! GO TO 470
4062 ! IF (IRFLAG == 0) GO TO 488
4063 ! RH2 = 2.0D0
4064 ! NQM2 = MIN(NQ,MXORDS)
4065 ! GO TO 478
4066 ! 470 CONTINUE
4067 ! EXSM = 1.0D0/L
4068 ! RH1 = 1.0D0/(1.2D0*DSM**EXSM + 0.0000012D0)
4069 ! RH1IT = 2.0D0*RH1
4070 ! PDH = PDLAST*ABS(H)
4071 ! IF (PDH*RH1 > 0.00001D0) RH1IT = SM1(NQ)/PDH
4072 ! RH1 = MIN(RH1,RH1IT)
4073 ! IF (NQ <= MXORDS) GO TO 474
4074 ! NQM2 = MXORDS
4075 ! LM2 = MXORDS + 1
4076 ! EXM2 = 1.0D0/LM2
4077 ! LM2P1 = LM2 + 1
4078 ! DM2 = DMNORM (N, YH(1,LM2P1), EWT)/CM2(MXORDS)
4079 ! RH2 = 1.0D0/(1.2D0*DM2**EXM2 + 0.0000012D0)
4080 ! GO TO 476
4081 ! 474 DM2 = DSM*(CM1(NQ)/CM2(NQ))
4082 ! RH2 = 1.0D0/(1.2D0*DM2**EXSM + 0.0000012D0)
4083 ! NQM2 = NQ
4084 ! 476 CONTINUE
4085 ! IF (RH2 < RATIO*RH1) GO TO 488
4086 ! THE SWITCH TEST PASSED. RESET RELEVANT QUANTITIES FOR BDF. ----------
4087 ! 478 RH = RH2
4088 ! ICOUNT = 20
4089 ! METH = 2
4090 ! MITER = JTYP
4091 ! PDLAST = 0.0D0
4092 ! NQ = NQM2
4093 ! L = NQ + 1
4094 ! GO TO 170
4095 !-----------------------------------------------------------------------
4096 ! We are currently using a BDF method. Consider switching to Adams.
4097 ! Compute the step size we could have (ideally) used on this step,
4098 ! with the current (BDF) method, and also that for the Adams.
4099 ! If NQ .gt. MXORDN, we consider changing to order MXORDN on switching.
4100 ! Compare the two step sizes to decide whether to switch.
4101 ! The step size advantage must be at least 5/RATIO = 1 to switch.
4102 ! If the step size for Adams would be so small as to cause
4103 ! roundoff pollution, we stay with BDF.
4104 !-----------------------------------------------------------------------
4105 ! 480 CONTINUE
4106 ! EXSM = 1.0D0/L
4107 ! IF (MXORDN >= NQ) GO TO 484
4108 ! NQM1 = MXORDN
4109 ! LM1 = MXORDN + 1
4110 ! EXM1 = 1.0D0/LM1
4111 ! LM1P1 = LM1 + 1
4112 ! DM1 = DMNORM (N, YH(1,LM1P1), EWT)/CM1(MXORDN)
4113 ! RH1 = 1.0D0/(1.2D0*DM1**EXM1 + 0.0000012D0)
4114 ! GO TO 486
4115 ! 484 DM1 = DSM*(CM2(NQ)/CM1(NQ))
4116 ! RH1 = 1.0D0/(1.2D0*DM1**EXSM + 0.0000012D0)
4117 ! NQM1 = NQ
4118 ! EXM1 = EXSM
4119 ! 486 RH1IT = 2.0D0*RH1
4120 ! PDH = PDNORM*ABS(H)
4121 ! IF (PDH*RH1 > 0.00001D0) RH1IT = SM1(NQM1)/PDH
4122 ! RH1 = MIN(RH1,RH1IT)
4123 ! RH2 = 1.0D0/(1.2D0*DSM**EXSM + 0.0000012D0)
4124 ! IF (RH1*RATIO < 5.0D0*RH2) GO TO 488
4125 ! ALPHA = MAX(0.001D0,RH1)
4126 ! DM1 = (ALPHA**EXM1)*DM1
4127 ! IF (DM1 <= 1000.0D0*UROUND*PNORM) GO TO 488
4128 ! The switch test passed. Reset relevant quantities for Adams. --------
4129 ! RH = RH1
4130 ! ICOUNT = 20
4131 ! METH = 1
4132 ! MITER = 0
4133 ! PDLAST = 0.0D0
4134 ! NQ = NQM1
4135 ! L = NQ + 1
4136 ! GO TO 170
4137 ! No method switch is being made. Do the usual step/order selection. --
4138 ! 488 CONTINUE
4139 ! IALTH = IALTH - 1
4140 ! IF (IALTH == 0) GO TO 520
4141 ! IF (IALTH > 1) GO TO 700
4142 ! IF (L == LMAX) GO TO 700
4143 ! DO 490 I = 1,N
4144 ! YH(I,LMAX) = ACOR(I)
4145 ! 490 END DO
4146 ! GO TO 700
4147 !-----------------------------------------------------------------------
4148 ! The error test failed. KFLAG keeps track of multiple failures.
4149 ! Restore TN and the YH array to their previous values, and prepare
4150 ! to try the step again. Compute the optimum step size for this or
4151 ! one lower order. After 2 or more failures, H is forced to decrease
4152 ! by a factor of 0.2 or less.
4153 !-----------------------------------------------------------------------
4154 ! 500 KFLAG = KFLAG - 1
4155 ! TN = TOLD
4156 ! I1 = NQNYH + 1
4157 ! DO 515 JB = 1,NQ
4158 ! I1 = I1 - NYH
4159 ! ! IR$ IVDEP
4160 ! DO 510 I = I1,NQNYH
4161 ! YH1(I) = YH1(I) - YH1(I+NYH)
4162 ! 510 END DO
4163 ! 515 END DO
4164 ! RMAX = 2.0D0
4165 ! IF (ABS(H) <= HMIN*1.00001D0) GO TO 660
4166 ! IF (KFLAG <= -3) GO TO 640
4167 ! IREDO = 2
4168 ! RHUP = 0.0D0
4169 ! GO TO 540
4170 !-----------------------------------------------------------------------
4171 ! Regardless of the success or failure of the step, factors
4172 ! RHDN, RHSM, and RHUP are computed, by which H could be multiplied
4173 ! at order NQ - 1, order NQ, or order NQ + 1, respectively.
4174 ! In the case of failure, RHUP = 0.0 to avoid an order increase.
4175 ! The largest of these is determined and the new order chosen
4176 ! accordingly. If the order is to be increased, we compute one
4177 ! additional scaled derivative.
4178 !-----------------------------------------------------------------------
4179 ! 520 RHUP = 0.0D0
4180 ! IF (L == LMAX) GO TO 540
4181 ! DO 530 I = 1,N
4182 ! SAVF(I) = ACOR(I) - YH(I,LMAX)
4183 ! 530 END DO
4184 ! DUP = DMNORM (N, SAVF, EWT)/TESCO(3,NQ)
4185 ! EXUP = 1.0D0/(L+1)
4186 ! RHUP = 1.0D0/(1.4D0*DUP**EXUP + 0.0000014D0)
4187 ! 540 EXSM = 1.0D0/L
4188 ! RHSM = 1.0D0/(1.2D0*DSM**EXSM + 0.0000012D0)
4189 ! RHDN = 0.0D0
4190 ! IF (NQ == 1) GO TO 550
4191 ! DDN = DMNORM (N, YH(1,L), EWT)/TESCO(1,NQ)
4192 ! EXDN = 1.0D0/NQ
4193 ! RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
4194 ! If METH = 1, limit RH according to the stability region also. --------
4195 ! 550 IF (METH == 2) GO TO 560
4196 ! PDH = MAX(ABS(H)*PDLAST,0.000001D0)
4197 ! IF (L < LMAX) RHUP = MIN(RHUP,SM1(L)/PDH)
4198 ! RHSM = MIN(RHSM,SM1(NQ)/PDH)
4199 ! IF (NQ > 1) RHDN = MIN(RHDN,SM1(NQ-1)/PDH)
4200 ! PDEST = 0.0D0
4201 ! 560 IF (RHSM >= RHUP) GO TO 570
4202 ! IF (RHUP > RHDN) GO TO 590
4203 ! GO TO 580
4204 ! 570 IF (RHSM < RHDN) GO TO 580
4205 ! NEWQ = NQ
4206 ! RH = RHSM
4207 ! GO TO 620
4208 ! 580 NEWQ = NQ - 1
4209 ! RH = RHDN
4210 ! IF (KFLAG < 0 .AND. RH > 1.0D0) RH = 1.0D0
4211 ! GO TO 620
4212 ! 590 NEWQ = L
4213 ! RH = RHUP
4214 ! IF (RH < 1.1D0) GO TO 610
4215 ! R = EL(L)/L
4216 ! DO 600 I = 1,N
4217 ! YH(I,NEWQ+1) = ACOR(I)*R
4218 ! 600 END DO
4219 ! GO TO 630
4220 ! 610 IALTH = 3
4221 ! GO TO 700
4222 ! If METH = 1 and H is restricted by stability, bypass 10 percent test.
4223 ! 620 IF (METH == 2) GO TO 622
4224 ! IF (RH*PDH*1.00001D0 >= SM1(NEWQ)) GO TO 625
4225 ! 622 IF (KFLAG == 0 .AND. RH < 1.1D0) GO TO 610
4226 ! 625 IF (KFLAG <= -2) RH = MIN(RH,0.2D0)
4227 !-----------------------------------------------------------------------
4228 ! If there is a change of order, reset NQ, L, and the coefficients.
4229 ! In any case H is reset according to RH and the YH array is rescaled.
4230 ! Then exit from 690 if the step was OK, or redo the step otherwise.
4231 !-----------------------------------------------------------------------
4232 ! IF (NEWQ == NQ) GO TO 170
4233 ! 630 NQ = NEWQ
4234 ! L = NQ + 1
4235 ! IRET = 2
4236 ! GO TO 150
4237 !-----------------------------------------------------------------------
4238 ! Control reaches this section if 3 or more failures have occured.
4239 ! If 10 failures have occurred, exit with KFLAG = -1.
4240 ! It is assumed that the derivatives that have accumulated in the
4241 ! YH array have errors of the wrong order. Hence the first
4242 ! derivative is recomputed, and the order is set to 1. Then
4243 ! H is reduced by a factor of 10, and the step is retried,
4244 ! until it succeeds or H reaches HMIN.
4245 !-----------------------------------------------------------------------
4246 ! 640 IF (KFLAG == -10) GO TO 660
4247 ! RH = 0.1D0
4248 ! RH = MAX(HMIN/ABS(H),RH)
4249 ! H = H*RH
4250 ! DO 645 I = 1,N
4251 ! Y(I) = YH(I,1)
4252 ! 645 END DO
4253 ! CALL F (NEQ, TN, Y, SAVF)
4254 ! NFE = NFE + 1
4255 ! DO 650 I = 1,N
4256 ! YH(I,2) = H*SAVF(I)
4257 ! 650 END DO
4258 ! IPUP = MITER
4259 ! IALTH = 5
4260 ! IF (NQ == 1) GO TO 200
4261 ! NQ = 1
4262 ! L = 2
4263 ! IRET = 3
4264 ! GO TO 150
4265 !-----------------------------------------------------------------------
4266 ! All returns are made through this section. H is saved in HOLD
4267 ! to allow the caller to change H on the next step.
4268 !-----------------------------------------------------------------------
4269 ! 660 KFLAG = -1
4270 ! GO TO 720
4271 ! 670 KFLAG = -2
4272 ! GO TO 720
4273 ! 680 KFLAG = -3
4274 ! GO TO 720
4275 ! 690 RMAX = 10.0D0
4276 ! 700 R = 1.0D0/TESCO(2,NQU)
4277 ! DO 710 I = 1,N
4278 ! ACOR(I) = ACOR(I)*R
4279 ! 710 END DO
4280 ! 720 HOLD = H
4281 ! JSTART = 1
4282 ! RETURN
4283 !----------------------- End of Subroutine DSTODA ----------------------
4284 ! END SUBROUTINE DSTODA
4285 ! ECK DPRJA
4286 ! SUBROUTINE DPRJA (NEQ, Y, YH, NYH, EWT, FTEM, SAVF, WM, IWM, &
4287 ! F, JAC)
4288 ! EXTERNAL F, JAC
4289 ! INTEGER :: NEQ, NYH, IWM
4290 ! DOUBLE PRECISION :: Y, YH, EWT, FTEM, SAVF, WM
4291 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), EWT(*), FTEM(*), SAVF(*), &
4292 ! WM(*), IWM(*)
4293 ! INTEGER :: IOWND, IOWNS, &
4294 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
4295 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
4296 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
4297 ! INTEGER :: IOWND2, IOWNS2, JTYP, MUSED, MXORDN, MXORDS
4298 ! DOUBLE PRECISION :: ROWNS, &
4299 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
4300 ! DOUBLE PRECISION :: ROWND2, ROWNS2, PDNORM
4301 ! COMMON /DLS001/ ROWNS(209), &
4302 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
4303 ! IOWND(6), IOWNS(6), &
4304 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
4305 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
4306 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
4307 ! COMMON /DLSA01/ ROWND2, ROWNS2(20), PDNORM, &
4308 ! IOWND2(3), IOWNS2(2), JTYP, MUSED, MXORDN, MXORDS
4309 ! INTEGER :: I, I1, I2, IER, II, J, J1, JJ, LENP, &
4310 ! MBA, MBAND, MEB1, MEBAND, ML, ML3, MU, NP1
4311 ! DOUBLE PRECISION :: CON, FAC, HL0, R, R0, SRUR, YI, YJ, YJJ, &
4312 ! DMNORM, DFNORM, DBNORM
4313 !-----------------------------------------------------------------------
4314 ! DPRJA is called by DSTODA to compute and process the matrix
4315 ! P = I - H*EL(1)*J , where J is an approximation to the Jacobian.
4316 ! Here J is computed by the user-supplied routine JAC if
4317 ! MITER = 1 or 4 or by finite differencing if MITER = 2 or 5.
4318 ! J, scaled by -H*EL(1), is stored in WM. Then the norm of J (the
4319 ! matrix norm consistent with the weighted max-norm on vectors given
4320 ! by DMNORM) is computed, and J is overwritten by P. P is then
4321 ! subjected to LU decomposition in preparation for later solution
4322 ! of linear systems with P as coefficient matrix. This is done
4323 ! by DGEFA if MITER = 1 or 2, and by DGBFA if MITER = 4 or 5.
4324 ! In addition to variables described previously, communication
4325 ! with DPRJA uses the following:
4326 ! Y = array containing predicted values on entry.
4327 ! FTEM = work array of length N (ACOR in DSTODA).
4328 ! SAVF = array containing f evaluated at predicted y.
4329 ! WM = real work space for matrices. On output it contains the
4330 ! LU decomposition of P.
4331 ! Storage of matrix elements starts at WM(3).
4332 ! WM also contains the following matrix-related data:
4333 ! WM(1) = SQRT(UROUND), used in numerical Jacobian increments.
4334 ! IWM = integer work space containing pivot information, starting at
4335 ! IWM(21). IWM also contains the band parameters
4336 ! ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
4337 ! EL0 = EL(1) (input).
4338 ! PDNORM= norm of Jacobian matrix. (Output).
4339 ! IERPJ = output error flag, = 0 if no trouble, .gt. 0 if
4340 ! P matrix found to be singular.
4341 ! JCUR = output flag = 1 to indicate that the Jacobian matrix
4342 ! (or approximation) is now current.
4343 ! This routine also uses the Common variables EL0, H, TN, UROUND,
4344 ! MITER, N, NFE, and NJE.
4345 !-----------------------------------------------------------------------
4346 ! NJE = NJE + 1
4347 ! IERPJ = 0
4348 ! JCUR = 1
4349 ! HL0 = H*EL0
4350 ! GO TO (100, 200, 300, 400, 500), MITER
4351 ! If MITER = 1, call JAC and multiply by scalar. -----------------------
4352 ! 100 LENP = N*N
4353 ! DO 110 I = 1,LENP
4354 ! WM(I+2) = 0.0D0
4355 ! 110 END DO
4356 ! CALL JAC (NEQ, TN, Y, 0, 0, WM(3), N)
4357 ! CON = -HL0
4358 ! DO 120 I = 1,LENP
4359 ! WM(I+2) = WM(I+2)*CON
4360 ! 120 END DO
4361 ! GO TO 240
4362 ! If MITER = 2, make N calls to F to approximate J. --------------------
4363 ! 200 FAC = DMNORM (N, SAVF, EWT)
4364 ! R0 = 1000.0D0*ABS(H)*UROUND*N*FAC
4365 ! IF (R0 == 0.0D0) R0 = 1.0D0
4366 ! SRUR = WM(1)
4367 ! J1 = 2
4368 ! DO 230 J = 1,N
4369 ! YJ = Y(J)
4370 ! R = MAX(SRUR*ABS(YJ),R0/EWT(J))
4371 ! Y(J) = Y(J) + R
4372 ! FAC = -HL0/R
4373 ! CALL F (NEQ, TN, Y, FTEM)
4374 ! DO 220 I = 1,N
4375 ! WM(I+J1) = (FTEM(I) - SAVF(I))*FAC
4376 ! 220 END DO
4377 ! Y(J) = YJ
4378 ! J1 = J1 + N
4379 ! 230 END DO
4380 ! NFE = NFE + N
4381 ! 240 CONTINUE
4382 ! Compute norm of Jacobian. --------------------------------------------
4383 ! PDNORM = DFNORM (N, WM(3), EWT)/ABS(HL0)
4384 ! Add identity matrix. -------------------------------------------------
4385 ! J = 3
4386 ! NP1 = N + 1
4387 ! DO 250 I = 1,N
4388 ! WM(J) = WM(J) + 1.0D0
4389 ! J = J + NP1
4390 ! 250 END DO
4391 ! Do LU decomposition on P. --------------------------------------------
4392 ! CALL DGEFA (WM(3), N, N, IWM(21), IER)
4393 ! IF (IER /= 0) IERPJ = 1
4394 ! RETURN
4395 ! Dummy block only, since MITER is never 3 in this routine. ------------
4396 ! 300 RETURN
4397 ! If MITER = 4, call JAC and multiply by scalar. -----------------------
4398 ! 400 ML = IWM(1)
4399 ! MU = IWM(2)
4400 ! ML3 = ML + 3
4401 ! MBAND = ML + MU + 1
4402 ! MEBAND = MBAND + ML
4403 ! LENP = MEBAND*N
4404 ! DO 410 I = 1,LENP
4405 ! WM(I+2) = 0.0D0
4406 ! 410 END DO
4407 ! CALL JAC (NEQ, TN, Y, ML, MU, WM(ML3), MEBAND)
4408 ! CON = -HL0
4409 ! DO 420 I = 1,LENP
4410 ! WM(I+2) = WM(I+2)*CON
4411 ! 420 END DO
4412 ! GO TO 570
4413 ! If MITER = 5, make MBAND calls to F to approximate J. ----------------
4414 ! 500 ML = IWM(1)
4415 ! MU = IWM(2)
4416 ! MBAND = ML + MU + 1
4417 ! MBA = MIN(MBAND,N)
4418 ! MEBAND = MBAND + ML
4419 ! MEB1 = MEBAND - 1
4420 ! SRUR = WM(1)
4421 ! FAC = DMNORM (N, SAVF, EWT)
4422 ! R0 = 1000.0D0*ABS(H)*UROUND*N*FAC
4423 ! IF (R0 == 0.0D0) R0 = 1.0D0
4424 ! DO 560 J = 1,MBA
4425 ! DO 530 I = J,N,MBAND
4426 ! YI = Y(I)
4427 ! R = MAX(SRUR*ABS(YI),R0/EWT(I))
4428 ! Y(I) = Y(I) + R
4429 ! 530 END DO
4430 ! CALL F (NEQ, TN, Y, FTEM)
4431 ! DO 550 JJ = J,N,MBAND
4432 ! Y(JJ) = YH(JJ,1)
4433 ! YJJ = Y(JJ)
4434 ! R = MAX(SRUR*ABS(YJJ),R0/EWT(JJ))
4435 ! FAC = -HL0/R
4436 ! I1 = MAX(JJ-MU,1)
4437 ! I2 = MIN(JJ+ML,N)
4438 ! II = JJ*MEB1 - ML + 2
4439 ! DO 540 I = I1,I2
4440 ! WM(II+I) = (FTEM(I) - SAVF(I))*FAC
4441 ! 540 END DO
4442 ! 550 END DO
4443 ! 560 END DO
4444 ! NFE = NFE + MBA
4445 ! 570 CONTINUE
4446 ! Compute norm of Jacobian. --------------------------------------------
4447 ! PDNORM = DBNORM (N, WM(ML+3), MEBAND, ML, MU, EWT)/ABS(HL0)
4448 ! Add identity matrix. -------------------------------------------------
4449 ! II = MBAND + 2
4450 ! DO 580 I = 1,N
4451 ! WM(II) = WM(II) + 1.0D0
4452 ! II = II + MEBAND
4453 ! 580 END DO
4454 ! Do LU decomposition of P. --------------------------------------------
4455 ! CALL DGBFA (WM(3), MEBAND, N, ML, MU, IWM(21), IER)
4456 ! IF (IER /= 0) IERPJ = 1
4457 ! RETURN
4458 !----------------------- End of Subroutine DPRJA -----------------------
4459 ! END SUBROUTINE DPRJA
4460 ! ECK DMNORM
4461 ! DOUBLE PRECISION :: FUNCTION DMNORM (N, V, W)
4462 !-----------------------------------------------------------------------
4463 ! This function routine computes the weighted max-norm
4464 ! of the vector of length N contained in the array V, with weights
4465 ! contained in the array w of length N:
4466 ! DMNORM = MAX(i=1,...,N) ABS(V(i))*W(i)
4467 !-----------------------------------------------------------------------
4468 ! INTEGER :: N, I
4469 ! DOUBLE PRECISION :: V, W, VM
4470 ! DIMENSION V(N), W(N)
4471 ! VM = 0.0D0
4472 ! DO 10 I = 1,N
4473 ! VM = MAX(VM,ABS(V(I))*W(I))
4474 ! 10 END DO
4475 ! DMNORM = VM
4476 ! RETURN
4477 !----------------------- End of Function DMNORM ------------------------
4478 ! END PROGRAM
4479 ! ECK DFNORM
4480 ! DOUBLE PRECISION :: FUNCTION DFNORM (N, A, W)
4481 !-----------------------------------------------------------------------
4482 ! This function computes the norm of a full N by N matrix,
4483 ! stored in the array A, that is consistent with the weighted max-norm
4484 ! on vectors, with weights stored in the array W:
4485 ! DFNORM = MAX(i=1,...,N) ( W(i) * Sum(j=1,...,N) ABS(a(i,j))/W(j) )
4486 !-----------------------------------------------------------------------
4487 ! INTEGER :: N, I, J
4488 ! DOUBLE PRECISION :: A, W, AN, SUM
4489 ! DIMENSION A(N,N), W(N)
4490 ! AN = 0.0D0
4491 ! DO 20 I = 1,N
4492 ! SUM = 0.0D0
4493 ! DO 10 J = 1,N
4494 ! SUM = SUM + ABS(A(I,J))/W(J)
4495 ! 10 END DO
4496 ! AN = MAX(AN,SUM*W(I))
4497 ! 20 END DO
4498 ! DFNORM = AN
4499 ! RETURN
4500 !----------------------- End of Function DFNORM ------------------------
4501 ! END PROGRAM
4502 ! ECK DBNORM
4503 ! DOUBLE PRECISION :: FUNCTION DBNORM (N, A, NRA, ML, MU, W)
4504 !-----------------------------------------------------------------------
4505 ! This function computes the norm of a banded N by N matrix,
4506 ! stored in the array A, that is consistent with the weighted max-norm
4507 ! on vectors, with weights stored in the array W.
4508 ! ML and MU are the lower and upper half-bandwidths of the matrix.
4509 ! NRA is the first dimension of the A array, NRA .ge. ML+MU+1.
4510 ! In terms of the matrix elements a(i,j), the norm is given by:
4511 ! DBNORM = MAX(i=1,...,N) ( W(i) * Sum(j=1,...,N) ABS(a(i,j))/W(j) )
4512 !-----------------------------------------------------------------------
4513 ! INTEGER :: N, NRA, ML, MU
4514 ! INTEGER :: I, I1, JLO, JHI, J
4515 ! DOUBLE PRECISION :: A, W
4516 ! DOUBLE PRECISION :: AN, SUM
4517 ! DIMENSION A(NRA,N), W(N)
4518 ! AN = 0.0D0
4519 ! DO 20 I = 1,N
4520 ! SUM = 0.0D0
4521 ! I1 = I + MU + 1
4522 ! JLO = MAX(I-ML,1)
4523 ! JHI = MIN(I+MU,N)
4524 ! DO 10 J = JLO,JHI
4525 ! SUM = SUM + ABS(A(I1-J,J))/W(J)
4526 ! 10 END DO
4527 ! AN = MAX(AN,SUM*W(I))
4528 ! 20 END DO
4529 ! DBNORM = AN
4530 ! RETURN
4531 !----------------------- End of Function DBNORM ------------------------
4532 ! END PROGRAM
4533 ! ECK DSRCMA
4534 ! SUBROUTINE DSRCMA (RSAV, ISAV, JOB)
4535 !-----------------------------------------------------------------------
4536 ! This routine saves or restores (depending on JOB) the contents of
4537 ! the Common blocks DLS001, DLSA01, which are used
4538 ! internally by one or more ODEPACK solvers.
4539 ! RSAV = real array of length 240 or more.
4540 ! ISAV = integer array of length 46 or more.
4541 ! JOB = flag indicating to save or restore the Common blocks:
4542 ! JOB = 1 if Common is to be saved (written to RSAV/ISAV)
4543 ! JOB = 2 if Common is to be restored (read from RSAV/ISAV)
4544 ! A call with JOB = 2 presumes a prior call with JOB = 1.
4545 !-----------------------------------------------------------------------
4546 ! INTEGER :: ISAV, JOB
4547 ! INTEGER :: ILS, ILSA
4548 ! INTEGER :: I, LENRLS, LENILS, LENRLA, LENILA
4549 ! DOUBLE PRECISION :: RSAV
4550 ! DOUBLE PRECISION :: RLS, RLSA
4551 ! DIMENSION RSAV(*), ISAV(*)
4552 ! SAVE LENRLS, LENILS, LENRLA, LENILA
4553 ! COMMON /DLS001/ RLS(218), ILS(37)
4554 ! COMMON /DLSA01/ RLSA(22), ILSA(9)
4555 ! DATA LENRLS/218/, LENILS/37/, LENRLA/22/, LENILA/9/
4556 ! IF (JOB == 2) GO TO 100
4557 ! DO 10 I = 1,LENRLS
4558 ! RSAV(I) = RLS(I)
4559 ! 10 END DO
4560 ! DO 15 I = 1,LENRLA
4561 ! RSAV(LENRLS+I) = RLSA(I)
4562 ! 15 END DO
4563 ! DO 20 I = 1,LENILS
4564 ! ISAV(I) = ILS(I)
4565 ! 20 END DO
4566 ! DO 25 I = 1,LENILA
4567 ! ISAV(LENILS+I) = ILSA(I)
4568 ! 25 END DO
4569 ! RETURN
4570 ! 100 CONTINUE
4571 ! DO 110 I = 1,LENRLS
4572 ! RLS(I) = RSAV(I)
4573 ! 110 END DO
4574 ! DO 115 I = 1,LENRLA
4575 ! RLSA(I) = RSAV(LENRLS+I)
4576 ! 115 END DO
4577 ! DO 120 I = 1,LENILS
4578 ! ILS(I) = ISAV(I)
4579 ! 120 END DO
4580 ! DO 125 I = 1,LENILA
4581 ! ILSA(I) = ISAV(LENILS+I)
4582 ! 125 END DO
4583 ! RETURN
4584 !----------------------- End of Subroutine DSRCMA ----------------------
4585 ! END SUBROUTINE DSRCMA
4586 ! ECK DRCHEK
4587 ! SUBROUTINE DRCHEK (JOB, G, NEQ, Y, YH,NYH, G0, G1, GX, JROOT, IRT)
4588 ! EXTERNAL G
4589 ! INTEGER :: JOB, NEQ, NYH, JROOT, IRT
4590 ! DOUBLE PRECISION :: Y, YH, G0, G1, GX
4591 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), G0(*), G1(*), GX(*), JROOT(*)
4592 ! INTEGER :: IOWND, IOWNS, &
4593 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
4594 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
4595 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
4596 ! INTEGER :: IOWND3, IOWNR3, IRFND, ITASKC, NGC, NGE
4597 ! DOUBLE PRECISION :: ROWNS, &
4598 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
4599 ! DOUBLE PRECISION :: ROWNR3, T0, TLAST, TOUTC
4600 ! COMMON /DLS001/ ROWNS(209), &
4601 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
4602 ! IOWND(6), IOWNS(6), &
4603 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
4604 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
4605 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
4606 ! COMMON /DLSR01/ ROWNR3(2), T0, TLAST, TOUTC, &
4607 ! IOWND3(3), IOWNR3(2), IRFND, ITASKC, NGC, NGE
4608 ! INTEGER :: I, IFLAG, JFLAG
4609 ! DOUBLE PRECISION :: HMING, T1, TEMP1, TEMP2, X
4610 ! LOGICAL :: ZROOT
4611 !-----------------------------------------------------------------------
4612 ! This routine checks for the presence of a root in the vicinity of
4613 ! the current T, in a manner depending on the input flag JOB. It calls
4614 ! Subroutine DROOTS to locate the root as precisely as possible.
4615 ! In addition to variables described previously, DRCHEK
4616 ! uses the following for communication:
4617 ! JOB = integer flag indicating type of call:
4618 ! JOB = 1 means the problem is being initialized, and DRCHEK
4619 ! is to look for a root at or very near the initial T.
4620 ! JOB = 2 means a continuation call to the solver was just
4621 ! made, and DRCHEK is to check for a root in the
4622 ! relevant part of the step last taken.
4623 ! JOB = 3 means a successful step was just taken, and DRCHEK
4624 ! is to look for a root in the interval of the step.
4625 ! G0 = array of length NG, containing the value of g at T = T0.
4626 ! G0 is input for JOB .ge. 2, and output in all cases.
4627 ! G1,GX = arrays of length NG for work space.
4628 ! IRT = completion flag:
4629 ! IRT = 0 means no root was found.
4630 ! IRT = -1 means JOB = 1 and a root was found too near to T.
4631 ! IRT = 1 means a legitimate root was found (JOB = 2 or 3).
4632 ! On return, T0 is the root location, and Y is the
4633 ! corresponding solution vector.
4634 ! T0 = value of T at one endpoint of interval of interest. Only
4635 ! roots beyond T0 in the direction of integration are sought.
4636 ! T0 is input if JOB .ge. 2, and output in all cases.
4637 ! T0 is updated by DRCHEK, whether a root is found or not.
4638 ! TLAST = last value of T returned by the solver (input only).
4639 ! TOUTC = copy of TOUT (input only).
4640 ! IRFND = input flag showing whether the last step taken had a root.
4641 ! IRFND = 1 if it did, = 0 if not.
4642 ! ITASKC = copy of ITASK (input only).
4643 ! NGC = copy of NG (input only).
4644 !-----------------------------------------------------------------------
4645 ! IRT = 0
4646 ! DO 10 I = 1,NGC
4647 ! JROOT(I) = 0
4648 ! 10 END DO
4649 ! HMING = (ABS(TN) + ABS(H))*UROUND*100.0D0
4650 ! GO TO (100, 200, 300), JOB
4651 ! Evaluate g at initial T, and check for zero values. ------------------
4652 ! 100 CONTINUE
4653 ! T0 = TN
4654 ! CALL G (NEQ, T0, Y, NGC, G0)
4655 ! NGE = 1
4656 ! ZROOT = .FALSE.
4657 ! DO 110 I = 1,NGC
4658 ! IF (ABS(G0(I)) <= 0.0D0) ZROOT = .TRUE.
4659 ! 110 END DO
4660 ! IF ( .NOT. ZROOT) GO TO 190
4661 ! g has a zero at T. Look at g at T + (small increment). --------------
4662 ! TEMP2 = MAX(HMING/ABS(H), 0.1D0)
4663 ! TEMP1 = TEMP2*H
4664 ! T0 = T0 + TEMP1
4665 ! DO 120 I = 1,N
4666 ! Y(I) = Y(I) + TEMP2*YH(I,2)
4667 ! 120 END DO
4668 ! CALL G (NEQ, T0, Y, NGC, G0)
4669 ! NGE = NGE + 1
4670 ! ZROOT = .FALSE.
4671 ! DO 130 I = 1,NGC
4672 ! IF (ABS(G0(I)) <= 0.0D0) ZROOT = .TRUE.
4673 ! 130 END DO
4674 ! IF ( .NOT. ZROOT) GO TO 190
4675 ! g has a zero at T and also close to T. Take error return. -----------
4676 ! IRT = -1
4677 ! RETURN
4678 ! 190 CONTINUE
4679 ! RETURN
4680 ! 200 CONTINUE
4681 ! IF (IRFND == 0) GO TO 260
4682 ! If a root was found on the previous step, evaluate G0 = g(T0). -------
4683 ! CALL DINTDY (T0, 0, YH, NYH, Y, IFLAG)
4684 ! CALL G (NEQ, T0, Y, NGC, G0)
4685 ! NGE = NGE + 1
4686 ! ZROOT = .FALSE.
4687 ! DO 210 I = 1,NGC
4688 ! IF (ABS(G0(I)) <= 0.0D0) ZROOT = .TRUE.
4689 ! 210 END DO
4690 ! IF ( .NOT. ZROOT) GO TO 260
4691 ! g has a zero at T0. Look at g at T + (small increment). -------------
4692 ! TEMP1 = SIGN(HMING,H)
4693 ! T0 = T0 + TEMP1
4694 ! IF ((T0 - TN)*H < 0.0D0) GO TO 230
4695 ! TEMP2 = TEMP1/H
4696 ! DO 220 I = 1,N
4697 ! Y(I) = Y(I) + TEMP2*YH(I,2)
4698 ! 220 END DO
4699 ! GO TO 240
4700 ! 230 CALL DINTDY (T0, 0, YH, NYH, Y, IFLAG)
4701 ! 240 CALL G (NEQ, T0, Y, NGC, G0)
4702 ! NGE = NGE + 1
4703 ! ZROOT = .FALSE.
4704 ! DO 250 I = 1,NGC
4705 ! IF (ABS(G0(I)) > 0.0D0) GO TO 250
4706 ! JROOT(I) = 1
4707 ! ZROOT = .TRUE.
4708 ! 250 END DO
4709 ! IF ( .NOT. ZROOT) GO TO 260
4710 ! g has a zero at T0 and also close to T0. Return root. ---------------
4711 ! IRT = 1
4712 ! RETURN
4713 ! G0 has no zero components. Proceed to check relevant interval. ------
4714 ! 260 IF (TN == TLAST) GO TO 390
4715 ! 300 CONTINUE
4716 ! Set T1 to TN or TOUTC, whichever comes first, and get g at T1. -------
4717 ! IF (ITASKC == 2 .OR. ITASKC == 3 .OR. ITASKC == 5) GO TO 310
4718 ! IF ((TOUTC - TN)*H >= 0.0D0) GO TO 310
4719 ! T1 = TOUTC
4720 ! IF ((T1 - T0)*H <= 0.0D0) GO TO 390
4721 ! CALL DINTDY (T1, 0, YH, NYH, Y, IFLAG)
4722 ! GO TO 330
4723 ! 310 T1 = TN
4724 ! DO 320 I = 1,N
4725 ! Y(I) = YH(I,1)
4726 ! 320 END DO
4727 ! 330 CALL G (NEQ, T1, Y, NGC, G1)
4728 ! NGE = NGE + 1
4729 ! Call DROOTS to search for root in interval from T0 to T1. ------------
4730 ! JFLAG = 0
4731 ! 350 CONTINUE
4732 ! CALL DROOTS (NGC, HMING, JFLAG, T0, T1, G0, G1, GX, X, JROOT)
4733 ! IF (JFLAG > 1) GO TO 360
4734 ! CALL DINTDY (X, 0, YH, NYH, Y, IFLAG)
4735 ! CALL G (NEQ, X, Y, NGC, GX)
4736 ! NGE = NGE + 1
4737 ! GO TO 350
4738 ! 360 T0 = X
4739 ! CALL DCOPY (NGC, GX, 1, G0, 1)
4740 ! IF (JFLAG == 4) GO TO 390
4741 ! Found a root. Interpolate to X and return. --------------------------
4742 ! CALL DINTDY (X, 0, YH, NYH, Y, IFLAG)
4743 ! IRT = 1
4744 ! RETURN
4745 ! 390 CONTINUE
4746 ! RETURN
4747 !----------------------- End of Subroutine DRCHEK ----------------------
4748 ! END SUBROUTINE DRCHEK
4749 ! ECK DROOTS
4750 ! SUBROUTINE DROOTS (NG, HMIN, JFLAG, X0, X1, G0, G1, GX, X, JROOT)
4751 ! INTEGER :: NG, JFLAG, JROOT
4752 ! DOUBLE PRECISION :: HMIN, X0, X1, G0, G1, GX, X
4753 ! DIMENSION G0(NG), G1(NG), GX(NG), JROOT(NG)
4754 ! INTEGER :: IOWND3, IMAX, LAST, IDUM3
4755 ! DOUBLE PRECISION :: ALPHA, X2, RDUM3
4756 ! COMMON /DLSR01/ ALPHA, X2, RDUM3(3), &
4757 ! IOWND3(3), IMAX, LAST, IDUM3(4)
4758 !-----------------------------------------------------------------------
4759 ! This subroutine finds the leftmost root of a set of arbitrary
4760 ! functions gi(x) (i = 1,...,NG) in an interval (X0,X1). Only roots
4761 ! of odd multiplicity (i.e. changes of sign of the gi) are found.
4762 ! Here the sign of X1 - X0 is arbitrary, but is constant for a given
4763 ! problem, and -leftmost- means nearest to X0.
4764 ! The values of the vector-valued function g(x) = (gi, i=1...NG)
4765 ! are communicated through the call sequence of DROOTS.
4766 ! The method used is the Illinois algorithm.
4767 ! Reference:
4768 ! Kathie L. Hiebert and Lawrence F. Shampine, Implicitly Defined
4769 ! Output Points for Solutions of ODEs, Sandia Report SAND80-0180,
4770 ! February 1980.
4771 ! Description of parameters.
4772 ! NG = number of functions gi, or the number of components of
4773 ! the vector valued function g(x). Input only.
4774 ! HMIN = resolution parameter in X. Input only. When a root is
4775 ! found, it is located only to within an error of HMIN in X.
4776 ! Typically, HMIN should be set to something on the order of
4777 ! 100 * UROUND * MAX(ABS(X0),ABS(X1)),
4778 ! where UROUND is the unit roundoff of the machine.
4779 ! JFLAG = integer flag for input and output communication.
4780 ! On input, set JFLAG = 0 on the first call for the problem,
4781 ! and leave it unchanged until the problem is completed.
4782 ! (The problem is completed when JFLAG .ge. 2 on return.)
4783 ! On output, JFLAG has the following values and meanings:
4784 ! JFLAG = 1 means DROOTS needs a value of g(x). Set GX = g(X)
4785 ! and call DROOTS again.
4786 ! JFLAG = 2 means a root has been found. The root is
4787 ! at X, and GX contains g(X). (Actually, X is the
4788 ! rightmost approximation to the root on an interval
4789 ! (X0,X1) of size HMIN or less.)
4790 ! JFLAG = 3 means X = X1 is a root, with one or more of the gi
4791 ! being zero at X1 and no sign changes in (X0,X1).
4792 ! GX contains g(X) on output.
4793 ! JFLAG = 4 means no roots (of odd multiplicity) were
4794 ! found in (X0,X1) (no sign changes).
4795 ! X0,X1 = endpoints of the interval where roots are sought.
4796 ! X1 and X0 are input when JFLAG = 0 (first call), and
4797 ! must be left unchanged between calls until the problem is
4798 ! completed. X0 and X1 must be distinct, but X1 - X0 may be
4799 ! of either sign. However, the notion of -left- and -right-
4800 ! will be used to mean nearer to X0 or X1, respectively.
4801 ! When JFLAG .ge. 2 on return, X0 and X1 are output, and
4802 ! are the endpoints of the relevant interval.
4803 ! G0,G1 = arrays of length NG containing the vectors g(X0) and g(X1),
4804 ! respectively. When JFLAG = 0, G0 and G1 are input and
4805 ! none of the G0(i) should be zero.
4806 ! When JFLAG .ge. 2 on return, G0 and G1 are output.
4807 ! GX = array of length NG containing g(X). GX is input
4808 ! when JFLAG = 1, and output when JFLAG .ge. 2.
4809 ! X = independent variable value. Output only.
4810 ! When JFLAG = 1 on output, X is the point at which g(x)
4811 ! is to be evaluated and loaded into GX.
4812 ! When JFLAG = 2 or 3, X is the root.
4813 ! When JFLAG = 4, X is the right endpoint of the interval, X1.
4814 ! JROOT = integer array of length NG. Output only.
4815 ! When JFLAG = 2 or 3, JROOT indicates which components
4816 ! of g(x) have a root at X. JROOT(i) is 1 if the i-th
4817 ! component has a root, and JROOT(i) = 0 otherwise.
4818 !-----------------------------------------------------------------------
4819 ! INTEGER :: I, IMXOLD, NXLAST
4820 ! DOUBLE PRECISION :: T2, TMAX, FRACINT, FRACSUB, ZERO,HALF,TENTH,FIVE
4821 ! LOGICAL :: ZROOT, SGNCHG, XROOT
4822 ! SAVE ZERO, HALF, TENTH, FIVE
4823 ! DATA ZERO/0.0D0/, HALF/0.5D0/, TENTH/0.1D0/, FIVE/5.0D0/
4824 ! IF (JFLAG == 1) GO TO 200
4825 ! JFLAG .ne. 1. Check for change in sign of g or zero at X1. ----------
4826 ! IMAX = 0
4827 ! TMAX = ZERO
4828 ! ZROOT = .FALSE.
4829 ! DO 120 I = 1,NG
4830 ! IF (ABS(G1(I)) > ZERO) GO TO 110
4831 ! ZROOT = .TRUE.
4832 ! GO TO 120
4833 ! ! At this point, G0(i) has been checked and cannot be zero. ------------
4834 ! 110 IF (SIGN(1.0D0,G0(I)) == SIGN(1.0D0,G1(I))) GO TO 120
4835 ! T2 = ABS(G1(I)/(G1(I)-G0(I)))
4836 ! IF (T2 <= TMAX) GO TO 120
4837 ! TMAX = T2
4838 ! IMAX = I
4839 ! 120 END DO
4840 ! IF (IMAX > 0) GO TO 130
4841 ! SGNCHG = .FALSE.
4842 ! GO TO 140
4843 ! 130 SGNCHG = .TRUE.
4844 ! 140 IF ( .NOT. SGNCHG) GO TO 400
4845 ! There is a sign change. Find the first root in the interval. --------
4846 ! XROOT = .FALSE.
4847 ! NXLAST = 0
4848 ! LAST = 1
4849 ! Repeat until the first root in the interval is found. Loop point. ---
4850 ! 150 CONTINUE
4851 ! IF (XROOT) GO TO 300
4852 ! IF (NXLAST == LAST) GO TO 160
4853 ! ALPHA = 1.0D0
4854 ! GO TO 180
4855 ! 160 IF (LAST == 0) GO TO 170
4856 ! ALPHA = 0.5D0*ALPHA
4857 ! GO TO 180
4858 ! 170 ALPHA = 2.0D0*ALPHA
4859 ! 180 X2 = X1 - (X1 - X0)*G1(IMAX) / (G1(IMAX) - ALPHA*G0(IMAX))
4860 ! If X2 is too close to X0 or X1, adjust it inward, by a fractional ----
4861 ! distance that is between 0.1 and 0.5. --------------------------------
4862 ! IF (ABS(X2 - X0) < HALF*HMIN) THEN
4863 ! FRACINT = ABS(X1 - X0)/HMIN
4864 ! FRACSUB = TENTH
4865 ! IF (FRACINT <= FIVE) FRACSUB = HALF/FRACINT
4866 ! X2 = X0 + FRACSUB*(X1 - X0)
4867 ! ENDIF
4868 ! IF (ABS(X1 - X2) < HALF*HMIN) THEN
4869 ! FRACINT = ABS(X1 - X0)/HMIN
4870 ! FRACSUB = TENTH
4871 ! IF (FRACINT <= FIVE) FRACSUB = HALF/FRACINT
4872 ! X2 = X1 - FRACSUB*(X1 - X0)
4873 ! ENDIF
4874 ! JFLAG = 1
4875 ! X = X2
4876 ! Return to the calling routine to get a value of GX = g(X). -----------
4877 ! RETURN
4878 ! Check to see in which interval g changes sign. -----------------------
4879 ! 200 IMXOLD = IMAX
4880 ! IMAX = 0
4881 ! TMAX = ZERO
4882 ! ZROOT = .FALSE.
4883 ! DO 220 I = 1,NG
4884 ! IF (ABS(GX(I)) > ZERO) GO TO 210
4885 ! ZROOT = .TRUE.
4886 ! GO TO 220
4887 ! ! Neither G0(i) nor GX(i) can be zero at this point. -------------------
4888 ! 210 IF (SIGN(1.0D0,G0(I)) == SIGN(1.0D0,GX(I))) GO TO 220
4889 ! T2 = ABS(GX(I)/(GX(I) - G0(I)))
4890 ! IF (T2 <= TMAX) GO TO 220
4891 ! TMAX = T2
4892 ! IMAX = I
4893 ! 220 END DO
4894 ! IF (IMAX > 0) GO TO 230
4895 ! SGNCHG = .FALSE.
4896 ! IMAX = IMXOLD
4897 ! GO TO 240
4898 ! 230 SGNCHG = .TRUE.
4899 ! 240 NXLAST = LAST
4900 ! IF ( .NOT. SGNCHG) GO TO 250
4901 ! Sign change between X0 and X2, so replace X1 with X2. ----------------
4902 ! X1 = X2
4903 ! CALL DCOPY (NG, GX, 1, G1, 1)
4904 ! LAST = 1
4905 ! XROOT = .FALSE.
4906 ! GO TO 270
4907 ! 250 IF ( .NOT. ZROOT) GO TO 260
4908 ! Zero value at X2 and no sign change in (X0,X2), so X2 is a root. -----
4909 ! X1 = X2
4910 ! CALL DCOPY (NG, GX, 1, G1, 1)
4911 ! XROOT = .TRUE.
4912 ! GO TO 270
4913 ! No sign change between X0 and X2. Replace X0 with X2. ---------------
4914 ! 260 CONTINUE
4915 ! CALL DCOPY (NG, GX, 1, G0, 1)
4916 ! X0 = X2
4917 ! LAST = 0
4918 ! XROOT = .FALSE.
4919 ! 270 IF (ABS(X1-X0) <= HMIN) XROOT = .TRUE.
4920 ! GO TO 150
4921 ! Return with X1 as the root. Set JROOT. Set X = X1 and GX = G1. -----
4922 ! 300 JFLAG = 2
4923 ! X = X1
4924 ! CALL DCOPY (NG, G1, 1, GX, 1)
4925 ! DO 320 I = 1,NG
4926 ! JROOT(I) = 0
4927 ! IF (ABS(G1(I)) > ZERO) GO TO 310
4928 ! JROOT(I) = 1
4929 ! GO TO 320
4930 ! 310 IF (SIGN(1.0D0,G0(I)) /= SIGN(1.0D0,G1(I))) JROOT(I) = 1
4931 ! 320 END DO
4932 ! RETURN
4933 ! No sign change in the interval. Check for zero at right endpoint. ---
4934 ! 400 IF ( .NOT. ZROOT) GO TO 420
4935 ! Zero value at X1 and no sign change in (X0,X1). Return JFLAG = 3. ---
4936 ! X = X1
4937 ! CALL DCOPY (NG, G1, 1, GX, 1)
4938 ! DO 410 I = 1,NG
4939 ! JROOT(I) = 0
4940 ! IF (ABS(G1(I)) <= ZERO) JROOT (I) = 1
4941 ! 410 END DO
4942 ! JFLAG = 3
4943 ! RETURN
4944 ! No sign changes in this interval. Set X = X1, return JFLAG = 4. -----
4945 ! 420 CALL DCOPY (NG, G1, 1, GX, 1)
4946 ! X = X1
4947 ! JFLAG = 4
4948 ! RETURN
4949 !----------------------- End of Subroutine DROOTS ----------------------
4950 ! END SUBROUTINE DROOTS
4951 ! ECK DSRCAR
4952 ! SUBROUTINE DSRCAR (RSAV, ISAV, JOB)
4953 !-----------------------------------------------------------------------
4954 ! This routine saves or restores (depending on JOB) the contents of
4955 ! the Common blocks DLS001, DLSA01, DLSR01, which are used
4956 ! internally by one or more ODEPACK solvers.
4957 ! RSAV = real array of length 245 or more.
4958 ! ISAV = integer array of length 55 or more.
4959 ! JOB = flag indicating to save or restore the Common blocks:
4960 ! JOB = 1 if Common is to be saved (written to RSAV/ISAV)
4961 ! JOB = 2 if Common is to be restored (read from RSAV/ISAV)
4962 ! A call with JOB = 2 presumes a prior call with JOB = 1.
4963 !-----------------------------------------------------------------------
4964 ! INTEGER :: ISAV, JOB
4965 ! INTEGER :: ILS, ILSA, ILSR
4966 ! INTEGER :: I, IOFF, LENRLS, LENILS, LENRLA, LENILA, LENRLR, LENILR
4967 ! DOUBLE PRECISION :: RSAV
4968 ! DOUBLE PRECISION :: RLS, RLSA, RLSR
4969 ! DIMENSION RSAV(*), ISAV(*)
4970 ! SAVE LENRLS, LENILS, LENRLA, LENILA, LENRLR, LENILR
4971 ! COMMON /DLS001/ RLS(218), ILS(37)
4972 ! COMMON /DLSA01/ RLSA(22), ILSA(9)
4973 ! COMMON /DLSR01/ RLSR(5), ILSR(9)
4974 ! DATA LENRLS/218/, LENILS/37/, LENRLA/22/, LENILA/9/
4975 ! DATA LENRLR/5/, LENILR/9/
4976 ! IF (JOB == 2) GO TO 100
4977 ! DO 10 I = 1,LENRLS
4978 ! RSAV(I) = RLS(I)
4979 ! 10 END DO
4980 ! DO 15 I = 1,LENRLA
4981 ! RSAV(LENRLS+I) = RLSA(I)
4982 ! 15 END DO
4983 ! IOFF = LENRLS + LENRLA
4984 ! DO 20 I = 1,LENRLR
4985 ! RSAV(IOFF+I) = RLSR(I)
4986 ! 20 END DO
4987 ! DO 30 I = 1,LENILS
4988 ! ISAV(I) = ILS(I)
4989 ! 30 END DO
4990 ! DO 35 I = 1,LENILA
4991 ! ISAV(LENILS+I) = ILSA(I)
4992 ! 35 END DO
4993 ! IOFF = LENILS + LENILA
4994 ! DO 40 I = 1,LENILR
4995 ! ISAV(IOFF+I) = ILSR(I)
4996 ! 40 END DO
4997 ! RETURN
4998 ! 100 CONTINUE
4999 ! DO 110 I = 1,LENRLS
5000 ! RLS(I) = RSAV(I)
5001 ! 110 END DO
5002 ! DO 115 I = 1,LENRLA
5003 ! RLSA(I) = RSAV(LENRLS+I)
5004 ! 115 END DO
5005 ! IOFF = LENRLS + LENRLA
5006 ! DO 120 I = 1,LENRLR
5007 ! RLSR(I) = RSAV(IOFF+I)
5008 ! 120 END DO
5009 ! DO 130 I = 1,LENILS
5010 ! ILS(I) = ISAV(I)
5011 ! 130 END DO
5012 ! DO 135 I = 1,LENILA
5013 ! ILSA(I) = ISAV(LENILS+I)
5014 ! 135 END DO
5015 ! IOFF = LENILS + LENILA
5016 ! DO 140 I = 1,LENILR
5017 ! ILSR(I) = ISAV(IOFF+I)
5018 ! 140 END DO
5019 ! RETURN
5020 !----------------------- End of Subroutine DSRCAR ----------------------
5021 ! END SUBROUTINE DSRCAR
5022 ! ECK DSTODPK
5023 ! SUBROUTINE DSTODPK (NEQ, Y, YH, NYH, YH1, EWT, SAVF, SAVX, ACOR, &
5024 ! WM, IWM, F, JAC, PSOL)
5025 ! EXTERNAL F, JAC, PSOL
5026 ! INTEGER :: NEQ, NYH, IWM
5027 ! DOUBLE PRECISION :: Y, YH, YH1, EWT, SAVF, SAVX, ACOR, WM
5028 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), YH1(*), EWT(*), SAVF(*), &
5029 ! SAVX(*), ACOR(*), WM(*), IWM(*)
5030 ! INTEGER :: IOWND, IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, &
5031 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
5032 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
5033 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
5034 ! INTEGER :: JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
5035 ! NNI, NLI, NPS, NCFN, NCFL
5036 ! DOUBLE PRECISION :: CONIT, CRATE, EL, ELCO, HOLD, RMAX, TESCO, &
5037 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
5038 ! DOUBLE PRECISION :: DELT, EPCON, SQRTN, RSQRTN
5039 ! COMMON /DLS001/ CONIT, CRATE, EL(13), ELCO(13,12), &
5040 ! HOLD, RMAX, TESCO(3,12), &
5041 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
5042 ! IOWND(6), IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, &
5043 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
5044 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
5045 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
5046 ! COMMON /DLPK01/ DELT, EPCON, SQRTN, RSQRTN, &
5047 ! JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
5048 ! NNI, NLI, NPS, NCFN, NCFL
5049 !-----------------------------------------------------------------------
5050 ! DSTODPK performs one step of the integration of an initial value
5051 ! problem for a system of Ordinary Differential Equations.
5052 !-----------------------------------------------------------------------
5053 ! The following changes were made to generate Subroutine DSTODPK
5054 ! from Subroutine DSTODE:
5055 ! 1. The array SAVX was added to the call sequence.
5056 ! 2. PJAC and SLVS were replaced by PSOL in the call sequence.
5057 ! 3. The Common block /DLPK01/ was added for communication.
5058 ! 4. The test constant EPCON is loaded into Common below statement
5059 ! numbers 125 and 155, and used below statement 400.
5060 ! 5. The Newton iteration counter MNEWT is set below 220 and 400.
5061 ! 6. The call to PJAC was replaced with a call to DPKSET (fixed name),
5062 ! with a longer call sequence, called depending on JACFLG.
5063 ! 7. The corrector residual is stored in SAVX (not Y) at 360,
5064 ! and the solution vector is in SAVX in the 380 loop.
5065 ! 8. SLVS was renamed DSOLPK and includes NEQ, SAVX, EWT, F, and JAC.
5066 ! SAVX was added because DSOLPK now needs Y and SAVF undisturbed.
5067 ! 9. The nonlinear convergence failure count NCFN is set at 430.
5068 !-----------------------------------------------------------------------
5069 ! Note: DSTODPK is independent of the value of the iteration method
5070 ! indicator MITER, when this is .ne. 0, and hence is independent
5071 ! of the type of chord method used, or the Jacobian structure.
5072 ! Communication with DSTODPK is done with the following variables:
5073 ! NEQ = integer array containing problem size in NEQ(1), and
5074 ! passed as the NEQ argument in all calls to F and JAC.
5075 ! Y = an array of length .ge. N used as the Y argument in
5076 ! all calls to F and JAC.
5077 ! YH = an NYH by LMAX array containing the dependent variables
5078 ! and their approximate scaled derivatives, where
5079 ! LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
5080 ! j-th derivative of y(i), scaled by H**j/factorial(j)
5081 ! (j = 0,1,...,NQ). On entry for the first step, the first
5082 ! two columns of YH must be set from the initial values.
5083 ! NYH = a constant integer .ge. N, the first dimension of YH.
5084 ! YH1 = a one-dimensional array occupying the same space as YH.
5085 ! EWT = an array of length N containing multiplicative weights
5086 ! for local error measurements. Local errors in y(i) are
5087 ! compared to 1.0/EWT(i) in various error tests.
5088 ! SAVF = an array of working storage, of length N.
5089 ! Also used for input of YH(*,MAXORD+2) when JSTART = -1
5090 ! and MAXORD .lt. the current order NQ.
5091 ! SAVX = an array of working storage, of length N.
5092 ! ACOR = a work array of length N, used for the accumulated
5093 ! corrections. On a successful return, ACOR(i) contains
5094 ! the estimated one-step local error in y(i).
5095 ! WM,IWM = real and integer work arrays associated with matrix
5096 ! operations in chord iteration (MITER .ne. 0).
5097 ! CCMAX = maximum relative change in H*EL0 before DPKSET is called.
5098 ! H = the step size to be attempted on the next step.
5099 ! H is altered by the error control algorithm during the
5100 ! problem. H can be either positive or negative, but its
5101 ! sign must remain constant throughout the problem.
5102 ! HMIN = the minimum absolute value of the step size H to be used.
5103 ! HMXI = inverse of the maximum absolute value of H to be used.
5104 ! HMXI = 0.0 is allowed and corresponds to an infinite HMAX.
5105 ! HMIN and HMXI may be changed at any time, but will not
5106 ! take effect until the next change of H is considered.
5107 ! TN = the independent variable. TN is updated on each step taken.
5108 ! JSTART = an integer used for input only, with the following
5109 ! values and meanings:
5110 ! 0 perform the first step.
5111 ! .gt.0 take a new step continuing from the last.
5112 ! -1 take the next step with a new value of H, MAXORD,
5113 ! N, METH, MITER, and/or matrix parameters.
5114 ! -2 take the next step with a new value of H,
5115 ! but with other inputs unchanged.
5116 ! On return, JSTART is set to 1 to facilitate continuation.
5117 ! KFLAG = a completion code with the following meanings:
5118 ! 0 the step was succesful.
5119 ! -1 the requested error could not be achieved.
5120 ! -2 corrector convergence could not be achieved.
5121 ! -3 fatal error in DPKSET or DSOLPK.
5122 ! A return with KFLAG = -1 or -2 means either
5123 ! ABS(H) = HMIN or 10 consecutive failures occurred.
5124 ! On a return with KFLAG negative, the values of TN and
5125 ! the YH array are as of the beginning of the last
5126 ! step, and H is the last step size attempted.
5127 ! MAXORD = the maximum order of integration method to be allowed.
5128 ! MAXCOR = the maximum number of corrector iterations allowed.
5129 ! MSBP = maximum number of steps between DPKSET calls (MITER .gt. 0).
5130 ! MXNCF = maximum number of convergence failures allowed.
5131 ! METH/MITER = the method flags. See description in driver.
5132 ! N = the number of first-order differential equations.
5133 !-----------------------------------------------------------------------
5134 ! INTEGER :: I, I1, IREDO, IRET, J, JB, M, NCF, NEWQ
5135 ! DOUBLE PRECISION :: DCON, DDN, DEL, DELP, DSM, DUP, EXDN, EXSM, EXUP, &
5136 ! R, RH, RHDN, RHSM, RHUP, TOLD, DVNORM
5137 ! KFLAG = 0
5138 ! TOLD = TN
5139 ! NCF = 0
5140 ! IERPJ = 0
5141 ! IERSL = 0
5142 ! JCUR = 0
5143 ! ICF = 0
5144 ! DELP = 0.0D0
5145 ! IF (JSTART > 0) GO TO 200
5146 ! IF (JSTART == -1) GO TO 100
5147 ! IF (JSTART == -2) GO TO 160
5148 !-----------------------------------------------------------------------
5149 ! On the first call, the order is set to 1, and other variables are
5150 ! initialized. RMAX is the maximum ratio by which H can be increased
5151 ! in a single step. It is initially 1.E4 to compensate for the small
5152 ! initial H, but then is normally equal to 10. If a failure
5153 ! occurs (in corrector convergence or error test), RMAX is set at 2
5154 ! for the next increase.
5155 !-----------------------------------------------------------------------
5156 ! LMAX = MAXORD + 1
5157 ! NQ = 1
5158 ! L = 2
5159 ! IALTH = 2
5160 ! RMAX = 10000.0D0
5161 ! RC = 0.0D0
5162 ! EL0 = 1.0D0
5163 ! CRATE = 0.7D0
5164 ! HOLD = H
5165 ! MEO = METH
5166 ! NSLP = 0
5167 ! IPUP = MITER
5168 ! IRET = 3
5169 ! GO TO 140
5170 !-----------------------------------------------------------------------
5171 ! The following block handles preliminaries needed when JSTART = -1.
5172 ! IPUP is set to MITER to force a matrix update.
5173 ! If an order increase is about to be considered (IALTH = 1),
5174 ! IALTH is reset to 2 to postpone consideration one more step.
5175 ! If the caller has changed METH, DCFODE is called to reset
5176 ! the coefficients of the method.
5177 ! If the caller has changed MAXORD to a value less than the current
5178 ! order NQ, NQ is reduced to MAXORD, and a new H chosen accordingly.
5179 ! If H is to be changed, YH must be rescaled.
5180 ! If H or METH is being changed, IALTH is reset to L = NQ + 1
5181 ! to prevent further changes in H for that many steps.
5182 !-----------------------------------------------------------------------
5183 ! 100 IPUP = MITER
5184 ! LMAX = MAXORD + 1
5185 ! IF (IALTH == 1) IALTH = 2
5186 ! IF (METH == MEO) GO TO 110
5187 ! CALL DCFODE (METH, ELCO, TESCO)
5188 ! MEO = METH
5189 ! IF (NQ > MAXORD) GO TO 120
5190 ! IALTH = L
5191 ! IRET = 1
5192 ! GO TO 150
5193 ! 110 IF (NQ <= MAXORD) GO TO 160
5194 ! 120 NQ = MAXORD
5195 ! L = LMAX
5196 ! DO 125 I = 1,L
5197 ! EL(I) = ELCO(I,NQ)
5198 ! 125 END DO
5199 ! NQNYH = NQ*NYH
5200 ! RC = RC*EL(1)/EL0
5201 ! EL0 = EL(1)
5202 ! CONIT = 0.5D0/(NQ+2)
5203 ! EPCON = CONIT*TESCO(2,NQ)
5204 ! DDN = DVNORM (N, SAVF, EWT)/TESCO(1,L)
5205 ! EXDN = 1.0D0/L
5206 ! RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
5207 ! RH = MIN(RHDN,1.0D0)
5208 ! IREDO = 3
5209 ! IF (H == HOLD) GO TO 170
5210 ! RH = MIN(RH,ABS(H/HOLD))
5211 ! H = HOLD
5212 ! GO TO 175
5213 !-----------------------------------------------------------------------
5214 ! DCFODE is called to get all the integration coefficients for the
5215 ! current METH. Then the EL vector and related constants are reset
5216 ! whenever the order NQ is changed, or at the start of the problem.
5217 !-----------------------------------------------------------------------
5218 ! 140 CALL DCFODE (METH, ELCO, TESCO)
5219 ! 150 DO 155 I = 1,L
5220 ! EL(I) = ELCO(I,NQ)
5221 ! 155 END DO
5222 ! NQNYH = NQ*NYH
5223 ! RC = RC*EL(1)/EL0
5224 ! EL0 = EL(1)
5225 ! CONIT = 0.5D0/(NQ+2)
5226 ! EPCON = CONIT*TESCO(2,NQ)
5227 ! GO TO (160, 170, 200), IRET
5228 !-----------------------------------------------------------------------
5229 ! If H is being changed, the H ratio RH is checked against
5230 ! RMAX, HMIN, and HMXI, and the YH array rescaled. IALTH is set to
5231 ! L = NQ + 1 to prevent a change of H for that many steps, unless
5232 ! forced by a convergence or error test failure.
5233 !-----------------------------------------------------------------------
5234 ! 160 IF (H == HOLD) GO TO 200
5235 ! RH = H/HOLD
5236 ! H = HOLD
5237 ! IREDO = 3
5238 ! GO TO 175
5239 ! 170 RH = MAX(RH,HMIN/ABS(H))
5240 ! 175 RH = MIN(RH,RMAX)
5241 ! RH = RH/MAX(1.0D0,ABS(H)*HMXI*RH)
5242 ! R = 1.0D0
5243 ! DO 180 J = 2,L
5244 ! R = R*RH
5245 ! DO 180 I = 1,N
5246 ! YH(I,J) = YH(I,J)*R
5247 ! 180 END DO
5248 ! H = H*RH
5249 ! RC = RC*RH
5250 ! IALTH = L
5251 ! IF (IREDO == 0) GO TO 690
5252 !-----------------------------------------------------------------------
5253 ! This section computes the predicted values by effectively
5254 ! multiplying the YH array by the Pascal triangle matrix.
5255 ! The flag IPUP is set according to whether matrix data is involved
5256 ! (JACFLG .ne. 0) or not (JACFLG = 0), to trigger a call to DPKSET.
5257 ! IPUP is set to MITER when RC differs from 1 by more than CCMAX,
5258 ! and at least every MSBP steps, when JACFLG = 1.
5259 ! RC is the ratio of new to old values of the coefficient H*EL(1).
5260 !-----------------------------------------------------------------------
5261 ! 200 IF (JACFLG /= 0) GO TO 202
5262 ! IPUP = 0
5263 ! CRATE = 0.7D0
5264 ! GO TO 205
5265 ! 202 IF (ABS(RC-1.0D0) > CCMAX) IPUP = MITER
5266 ! IF (NST >= NSLP+MSBP) IPUP = MITER
5267 ! 205 TN = TN + H
5268 ! I1 = NQNYH + 1
5269 ! DO 215 JB = 1,NQ
5270 ! I1 = I1 - NYH
5271 ! ! IR$ IVDEP
5272 ! DO 210 I = I1,NQNYH
5273 ! YH1(I) = YH1(I) + YH1(I+NYH)
5274 ! 210 END DO
5275 ! 215 END DO
5276 !-----------------------------------------------------------------------
5277 ! Up to MAXCOR corrector iterations are taken. A convergence test is
5278 ! made on the RMS-norm of each correction, weighted by the error
5279 ! weight vector EWT. The sum of the corrections is accumulated in the
5280 ! vector ACOR(i). The YH array is not altered in the corrector loop.
5281 !-----------------------------------------------------------------------
5282 ! 220 M = 0
5283 ! MNEWT = 0
5284 ! DO 230 I = 1,N
5285 ! Y(I) = YH(I,1)
5286 ! 230 END DO
5287 ! CALL F (NEQ, TN, Y, SAVF)
5288 ! NFE = NFE + 1
5289 ! IF (IPUP <= 0) GO TO 250
5290 !-----------------------------------------------------------------------
5291 ! If indicated, DPKSET is called to update any matrix data needed,
5292 ! before starting the corrector iteration.
5293 ! IPUP is set to 0 as an indicator that this has been done.
5294 !-----------------------------------------------------------------------
5295 ! CALL DPKSET (NEQ, Y, YH1, EWT, ACOR, SAVF, WM, IWM, F, JAC)
5296 ! IPUP = 0
5297 ! RC = 1.0D0
5298 ! NSLP = NST
5299 ! CRATE = 0.7D0
5300 ! IF (IERPJ /= 0) GO TO 430
5301 ! 250 DO 260 I = 1,N
5302 ! ACOR(I) = 0.0D0
5303 ! 260 END DO
5304 ! 270 IF (MITER /= 0) GO TO 350
5305 !-----------------------------------------------------------------------
5306 ! In the case of functional iteration, update Y directly from
5307 ! the result of the last function evaluation.
5308 !-----------------------------------------------------------------------
5309 ! DO 290 I = 1,N
5310 ! SAVF(I) = H*SAVF(I) - YH(I,2)
5311 ! Y(I) = SAVF(I) - ACOR(I)
5312 ! 290 END DO
5313 ! DEL = DVNORM (N, Y, EWT)
5314 ! DO 300 I = 1,N
5315 ! Y(I) = YH(I,1) + EL(1)*SAVF(I)
5316 ! ACOR(I) = SAVF(I)
5317 ! 300 END DO
5318 ! GO TO 400
5319 !-----------------------------------------------------------------------
5320 ! In the case of the chord method, compute the corrector error,
5321 ! and solve the linear system with that as right-hand side and
5322 ! P as coefficient matrix.
5323 !-----------------------------------------------------------------------
5324 ! 350 DO 360 I = 1,N
5325 ! SAVX(I) = H*SAVF(I) - (YH(I,2) + ACOR(I))
5326 ! 360 END DO
5327 ! CALL DSOLPK (NEQ, Y, SAVF, SAVX, EWT, WM, IWM, F, PSOL)
5328 ! IF (IERSL < 0) GO TO 430
5329 ! IF (IERSL > 0) GO TO 410
5330 ! DEL = DVNORM (N, SAVX, EWT)
5331 ! DO 380 I = 1,N
5332 ! ACOR(I) = ACOR(I) + SAVX(I)
5333 ! Y(I) = YH(I,1) + EL(1)*ACOR(I)
5334 ! 380 END DO
5335 !-----------------------------------------------------------------------
5336 ! Test for convergence. If M .gt. 0, an estimate of the convergence
5337 ! rate constant is stored in CRATE, and this is used in the test.
5338 !-----------------------------------------------------------------------
5339 ! 400 IF (M /= 0) CRATE = MAX(0.2D0*CRATE,DEL/DELP)
5340 ! DCON = DEL*MIN(1.0D0,1.5D0*CRATE)/EPCON
5341 ! IF (DCON <= 1.0D0) GO TO 450
5342 ! M = M + 1
5343 ! IF (M == MAXCOR) GO TO 410
5344 ! IF (M >= 2 .AND. DEL > 2.0D0*DELP) GO TO 410
5345 ! MNEWT = M
5346 ! DELP = DEL
5347 ! CALL F (NEQ, TN, Y, SAVF)
5348 ! NFE = NFE + 1
5349 ! GO TO 270
5350 !-----------------------------------------------------------------------
5351 ! The corrector iteration failed to converge.
5352 ! If MITER .ne. 0 and the Jacobian is out of date, DPKSET is called for
5353 ! the next try. Otherwise the YH array is retracted to its values
5354 ! before prediction, and H is reduced, if possible. If H cannot be
5355 ! reduced or MXNCF failures have occurred, exit with KFLAG = -2.
5356 !-----------------------------------------------------------------------
5357 ! 410 IF (MITER == 0 .OR. JCUR == 1 .OR. JACFLG == 0) GO TO 430
5358 ! ICF = 1
5359 ! IPUP = MITER
5360 ! GO TO 220
5361 ! 430 ICF = 2
5362 ! NCF = NCF + 1
5363 ! NCFN = NCFN + 1
5364 ! RMAX = 2.0D0
5365 ! TN = TOLD
5366 ! I1 = NQNYH + 1
5367 ! DO 445 JB = 1,NQ
5368 ! I1 = I1 - NYH
5369 ! ! IR$ IVDEP
5370 ! DO 440 I = I1,NQNYH
5371 ! YH1(I) = YH1(I) - YH1(I+NYH)
5372 ! 440 END DO
5373 ! 445 END DO
5374 ! IF (IERPJ < 0 .OR. IERSL < 0) GO TO 680
5375 ! IF (ABS(H) <= HMIN*1.00001D0) GO TO 670
5376 ! IF (NCF == MXNCF) GO TO 670
5377 ! RH = 0.5D0
5378 ! IPUP = MITER
5379 ! IREDO = 1
5380 ! GO TO 170
5381 !-----------------------------------------------------------------------
5382 ! The corrector has converged. JCUR is set to 0
5383 ! to signal that the Jacobian involved may need updating later.
5384 ! The local error test is made and control passes to statement 500
5385 ! if it fails.
5386 !-----------------------------------------------------------------------
5387 ! 450 JCUR = 0
5388 ! IF (M == 0) DSM = DEL/TESCO(2,NQ)
5389 ! IF (M > 0) DSM = DVNORM (N, ACOR, EWT)/TESCO(2,NQ)
5390 ! IF (DSM > 1.0D0) GO TO 500
5391 !-----------------------------------------------------------------------
5392 ! After a successful step, update the YH array.
5393 ! Consider changing H if IALTH = 1. Otherwise decrease IALTH by 1.
5394 ! If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
5395 ! use in a possible order increase on the next step.
5396 ! If a change in H is considered, an increase or decrease in order
5397 ! by one is considered also. A change in H is made only if it is by a
5398 ! factor of at least 1.1. If not, IALTH is set to 3 to prevent
5399 ! testing for that many steps.
5400 !-----------------------------------------------------------------------
5401 ! KFLAG = 0
5402 ! IREDO = 0
5403 ! NST = NST + 1
5404 ! HU = H
5405 ! NQU = NQ
5406 ! DO 470 J = 1,L
5407 ! DO 470 I = 1,N
5408 ! YH(I,J) = YH(I,J) + EL(J)*ACOR(I)
5409 ! 470 END DO
5410 ! IALTH = IALTH - 1
5411 ! IF (IALTH == 0) GO TO 520
5412 ! IF (IALTH > 1) GO TO 700
5413 ! IF (L == LMAX) GO TO 700
5414 ! DO 490 I = 1,N
5415 ! YH(I,LMAX) = ACOR(I)
5416 ! 490 END DO
5417 ! GO TO 700
5418 !-----------------------------------------------------------------------
5419 ! The error test failed. KFLAG keeps track of multiple failures.
5420 ! Restore TN and the YH array to their previous values, and prepare
5421 ! to try the step again. Compute the optimum step size for this or
5422 ! one lower order. After 2 or more failures, H is forced to decrease
5423 ! by a factor of 0.2 or less.
5424 !-----------------------------------------------------------------------
5425 ! 500 KFLAG = KFLAG - 1
5426 ! TN = TOLD
5427 ! I1 = NQNYH + 1
5428 ! DO 515 JB = 1,NQ
5429 ! I1 = I1 - NYH
5430 ! ! IR$ IVDEP
5431 ! DO 510 I = I1,NQNYH
5432 ! YH1(I) = YH1(I) - YH1(I+NYH)
5433 ! 510 END DO
5434 ! 515 END DO
5435 ! RMAX = 2.0D0
5436 ! IF (ABS(H) <= HMIN*1.00001D0) GO TO 660
5437 ! IF (KFLAG <= -3) GO TO 640
5438 ! IREDO = 2
5439 ! RHUP = 0.0D0
5440 ! GO TO 540
5441 !-----------------------------------------------------------------------
5442 ! Regardless of the success or failure of the step, factors
5443 ! RHDN, RHSM, and RHUP are computed, by which H could be multiplied
5444 ! at order NQ - 1, order NQ, or order NQ + 1, respectively.
5445 ! In the case of failure, RHUP = 0.0 to avoid an order increase.
5446 ! the largest of these is determined and the new order chosen
5447 ! accordingly. If the order is to be increased, we compute one
5448 ! additional scaled derivative.
5449 !-----------------------------------------------------------------------
5450 ! 520 RHUP = 0.0D0
5451 ! IF (L == LMAX) GO TO 540
5452 ! DO 530 I = 1,N
5453 ! SAVF(I) = ACOR(I) - YH(I,LMAX)
5454 ! 530 END DO
5455 ! DUP = DVNORM (N, SAVF, EWT)/TESCO(3,NQ)
5456 ! EXUP = 1.0D0/(L+1)
5457 ! RHUP = 1.0D0/(1.4D0*DUP**EXUP + 0.0000014D0)
5458 ! 540 EXSM = 1.0D0/L
5459 ! RHSM = 1.0D0/(1.2D0*DSM**EXSM + 0.0000012D0)
5460 ! RHDN = 0.0D0
5461 ! IF (NQ == 1) GO TO 560
5462 ! DDN = DVNORM (N, YH(1,L), EWT)/TESCO(1,NQ)
5463 ! EXDN = 1.0D0/NQ
5464 ! RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
5465 ! 560 IF (RHSM >= RHUP) GO TO 570
5466 ! IF (RHUP > RHDN) GO TO 590
5467 ! GO TO 580
5468 ! 570 IF (RHSM < RHDN) GO TO 580
5469 ! NEWQ = NQ
5470 ! RH = RHSM
5471 ! GO TO 620
5472 ! 580 NEWQ = NQ - 1
5473 ! RH = RHDN
5474 ! IF (KFLAG < 0 .AND. RH > 1.0D0) RH = 1.0D0
5475 ! GO TO 620
5476 ! 590 NEWQ = L
5477 ! RH = RHUP
5478 ! IF (RH < 1.1D0) GO TO 610
5479 ! R = EL(L)/L
5480 ! DO 600 I = 1,N
5481 ! YH(I,NEWQ+1) = ACOR(I)*R
5482 ! 600 END DO
5483 ! GO TO 630
5484 ! 610 IALTH = 3
5485 ! GO TO 700
5486 ! 620 IF ((KFLAG == 0) .AND. (RH < 1.1D0)) GO TO 610
5487 ! IF (KFLAG <= -2) RH = MIN(RH,0.2D0)
5488 !-----------------------------------------------------------------------
5489 ! If there is a change of order, reset NQ, L, and the coefficients.
5490 ! In any case H is reset according to RH and the YH array is rescaled.
5491 ! Then exit from 690 if the step was OK, or redo the step otherwise.
5492 !-----------------------------------------------------------------------
5493 ! IF (NEWQ == NQ) GO TO 170
5494 ! 630 NQ = NEWQ
5495 ! L = NQ + 1
5496 ! IRET = 2
5497 ! GO TO 150
5498 !-----------------------------------------------------------------------
5499 ! Control reaches this section if 3 or more failures have occured.
5500 ! If 10 failures have occurred, exit with KFLAG = -1.
5501 ! It is assumed that the derivatives that have accumulated in the
5502 ! YH array have errors of the wrong order. Hence the first
5503 ! derivative is recomputed, and the order is set to 1. Then
5504 ! H is reduced by a factor of 10, and the step is retried,
5505 ! until it succeeds or H reaches HMIN.
5506 !-----------------------------------------------------------------------
5507 ! 640 IF (KFLAG == -10) GO TO 660
5508 ! RH = 0.1D0
5509 ! RH = MAX(HMIN/ABS(H),RH)
5510 ! H = H*RH
5511 ! DO 645 I = 1,N
5512 ! Y(I) = YH(I,1)
5513 ! 645 END DO
5514 ! CALL F (NEQ, TN, Y, SAVF)
5515 ! NFE = NFE + 1
5516 ! DO 650 I = 1,N
5517 ! YH(I,2) = H*SAVF(I)
5518 ! 650 END DO
5519 ! IPUP = MITER
5520 ! IALTH = 5
5521 ! IF (NQ == 1) GO TO 200
5522 ! NQ = 1
5523 ! L = 2
5524 ! IRET = 3
5525 ! GO TO 150
5526 !-----------------------------------------------------------------------
5527 ! All returns are made through this section. H is saved in HOLD
5528 ! to allow the caller to change H on the next step.
5529 !-----------------------------------------------------------------------
5530 ! 660 KFLAG = -1
5531 ! GO TO 720
5532 ! 670 KFLAG = -2
5533 ! GO TO 720
5534 ! 680 KFLAG = -3
5535 ! GO TO 720
5536 ! 690 RMAX = 10.0D0
5537 ! 700 R = 1.0D0/TESCO(2,NQU)
5538 ! DO 710 I = 1,N
5539 ! ACOR(I) = ACOR(I)*R
5540 ! 710 END DO
5541 ! 720 HOLD = H
5542 ! JSTART = 1
5543 ! RETURN
5544 !----------------------- End of Subroutine DSTODPK ---------------------
5545 ! END SUBROUTINE DSTODPK
5546 ! ECK DPKSET
5547 ! SUBROUTINE DPKSET (NEQ, Y, YSV, EWT, FTEM, SAVF, WM, IWM, F, JAC)
5548 ! EXTERNAL F, JAC
5549 ! INTEGER :: NEQ, IWM
5550 ! DOUBLE PRECISION :: Y, YSV, EWT, FTEM, SAVF, WM
5551 ! DIMENSION NEQ(*), Y(*), YSV(*), EWT(*), FTEM(*), SAVF(*), &
5552 ! WM(*), IWM(*)
5553 ! INTEGER :: IOWND, IOWNS, &
5554 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
5555 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
5556 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
5557 ! INTEGER :: JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
5558 ! NNI, NLI, NPS, NCFN, NCFL
5559 ! DOUBLE PRECISION :: ROWNS, &
5560 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
5561 ! DOUBLE PRECISION :: DELT, EPCON, SQRTN, RSQRTN
5562 ! COMMON /DLS001/ ROWNS(209), &
5563 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
5564 ! IOWND(6), IOWNS(6), &
5565 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
5566 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
5567 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
5568 ! COMMON /DLPK01/ DELT, EPCON, SQRTN, RSQRTN, &
5569 ! JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
5570 ! NNI, NLI, NPS, NCFN, NCFL
5571 !-----------------------------------------------------------------------
5572 ! DPKSET is called by DSTODPK to interface with the user-supplied
5573 ! routine JAC, to compute and process relevant parts of
5574 ! the matrix P = I - H*EL(1)*J , where J is the Jacobian df/dy,
5575 ! as need for preconditioning matrix operations later.
5576 ! In addition to variables described previously, communication
5577 ! with DPKSET uses the following:
5578 ! Y = array containing predicted values on entry.
5579 ! YSV = array containing predicted y, to be saved (YH1 in DSTODPK).
5580 ! FTEM = work array of length N (ACOR in DSTODPK).
5581 ! SAVF = array containing f evaluated at predicted y.
5582 ! WM = real work space for matrices.
5583 ! Space for preconditioning data starts at WM(LOCWP).
5584 ! IWM = integer work space.
5585 ! Space for preconditioning data starts at IWM(LOCIWP).
5586 ! IERPJ = output error flag, = 0 if no trouble, .gt. 0 if
5587 ! JAC returned an error flag.
5588 ! JCUR = output flag = 1 to indicate that the Jacobian matrix
5589 ! (or approximation) is now current.
5590 ! This routine also uses Common variables EL0, H, TN, IERPJ, JCUR, NJE.
5591 !-----------------------------------------------------------------------
5592 ! INTEGER :: IER
5593 ! DOUBLE PRECISION :: HL0
5594 ! IERPJ = 0
5595 ! JCUR = 1
5596 ! HL0 = EL0*H
5597 ! CALL JAC (F, NEQ, TN, Y, YSV, EWT, SAVF, FTEM, HL0, &
5598 ! WM(LOCWP), IWM(LOCIWP), IER)
5599 ! NJE = NJE + 1
5600 ! IF (IER == 0) RETURN
5601 ! IERPJ = 1
5602 ! RETURN
5603 !----------------------- End of Subroutine DPKSET ----------------------
5604 ! END SUBROUTINE DPKSET
5605 ! ECK DSOLPK
5606 ! SUBROUTINE DSOLPK (NEQ, Y, SAVF, X, EWT, WM, IWM, F, PSOL)
5607 ! EXTERNAL F, PSOL
5608 ! INTEGER :: NEQ, IWM
5609 ! DOUBLE PRECISION :: Y, SAVF, X, EWT, WM
5610 ! DIMENSION NEQ(*), Y(*), SAVF(*), X(*), EWT(*), WM(*), IWM(*)
5611 ! INTEGER :: IOWND, IOWNS, &
5612 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
5613 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
5614 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
5615 ! INTEGER :: JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
5616 ! NNI, NLI, NPS, NCFN, NCFL
5617 ! DOUBLE PRECISION :: ROWNS, &
5618 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
5619 ! DOUBLE PRECISION :: DELT, EPCON, SQRTN, RSQRTN
5620 ! COMMON /DLS001/ ROWNS(209), &
5621 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
5622 ! IOWND(6), IOWNS(6), &
5623 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
5624 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
5625 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
5626 ! COMMON /DLPK01/ DELT, EPCON, SQRTN, RSQRTN, &
5627 ! JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
5628 ! NNI, NLI, NPS, NCFN, NCFL
5629 !-----------------------------------------------------------------------
5630 ! This routine interfaces to one of DSPIOM, DSPIGMR, DPCG, DPCGS, or
5631 ! DUSOL, for the solution of the linear system arising from a Newton
5632 ! iteration. It is called if MITER .ne. 0.
5633 ! In addition to variables described elsewhere,
5634 ! communication with DSOLPK uses the following variables:
5635 ! WM = real work space containing data for the algorithm
5636 ! (Krylov basis vectors, Hessenberg matrix, etc.)
5637 ! IWM = integer work space containing data for the algorithm
5638 ! X = the right-hand side vector on input, and the solution vector
5639 ! on output, of length N.
5640 ! IERSL = output flag (in Common):
5641 ! IERSL = 0 means no trouble occurred.
5642 ! IERSL = 1 means the iterative method failed to converge.
5643 ! If the preconditioner is out of date, the step
5644 ! is repeated with a new preconditioner.
5645 ! Otherwise, the stepsize is reduced (forcing a
5646 ! new evaluation of the preconditioner) and the
5647 ! step is repeated.
5648 ! IERSL = -1 means there was a nonrecoverable error in the
5649 ! iterative solver, and an error exit occurs.
5650 ! This routine also uses the Common variables TN, EL0, H, N, MITER,
5651 ! DELT, EPCON, SQRTN, RSQRTN, MAXL, KMP, MNEWT, NNI, NLI, NPS, NCFL,
5652 ! LOCWP, LOCIWP.
5653 !-----------------------------------------------------------------------
5654 ! INTEGER :: IFLAG, LB, LDL, LHES, LIOM, LGMR, LPCG, LP, LQ, LR, &
5655 ! LV, LW, LWK, LZ, MAXLP1, NPSL
5656 ! DOUBLE PRECISION :: DELTA, HL0
5657 ! IERSL = 0
5658 ! HL0 = H*EL0
5659 ! DELTA = DELT*EPCON
5660 ! GO TO (100, 200, 300, 400, 900, 900, 900, 900, 900), MITER
5661 !-----------------------------------------------------------------------
5662 ! Use the SPIOM algorithm to solve the linear system P*x = -f.
5663 !-----------------------------------------------------------------------
5664 ! 100 CONTINUE
5665 ! LV = 1
5666 ! LB = LV + N*MAXL
5667 ! LHES = LB + N
5668 ! LWK = LHES + MAXL*MAXL
5669 ! CALL DCOPY (N, X, 1, WM(LB), 1)
5670 ! CALL DSCAL (N, RSQRTN, EWT, 1)
5671 ! CALL DSPIOM (NEQ, TN, Y, SAVF, WM(LB), EWT, N, MAXL, KMP, DELTA, &
5672 ! HL0, JPRE, MNEWT, F, PSOL, NPSL, X, WM(LV), WM(LHES), IWM, &
5673 ! LIOM, WM(LOCWP), IWM(LOCIWP), WM(LWK), IFLAG)
5674 ! NNI = NNI + 1
5675 ! NLI = NLI + LIOM
5676 ! NPS = NPS + NPSL
5677 ! CALL DSCAL (N, SQRTN, EWT, 1)
5678 ! IF (IFLAG /= 0) NCFL = NCFL + 1
5679 ! IF (IFLAG >= 2) IERSL = 1
5680 ! IF (IFLAG < 0) IERSL = -1
5681 ! RETURN
5682 !-----------------------------------------------------------------------
5683 ! Use the SPIGMR algorithm to solve the linear system P*x = -f.
5684 !-----------------------------------------------------------------------
5685 ! 200 CONTINUE
5686 ! MAXLP1 = MAXL + 1
5687 ! LV = 1
5688 ! LB = LV + N*MAXL
5689 ! LHES = LB + N + 1
5690 ! LQ = LHES + MAXL*MAXLP1
5691 ! LWK = LQ + 2*MAXL
5692 ! LDL = LWK + MIN(1,MAXL-KMP)*N
5693 ! CALL DCOPY (N, X, 1, WM(LB), 1)
5694 ! CALL DSCAL (N, RSQRTN, EWT, 1)
5695 ! CALL DSPIGMR (NEQ, TN, Y, SAVF, WM(LB), EWT, N, MAXL, MAXLP1, KMP, &
5696 ! DELTA, HL0, JPRE, MNEWT, F, PSOL, NPSL, X, WM(LV), WM(LHES), &
5697 ! WM(LQ), LGMR, WM(LOCWP), IWM(LOCIWP), WM(LWK), WM(LDL), IFLAG)
5698 ! NNI = NNI + 1
5699 ! NLI = NLI + LGMR
5700 ! NPS = NPS + NPSL
5701 ! CALL DSCAL (N, SQRTN, EWT, 1)
5702 ! IF (IFLAG /= 0) NCFL = NCFL + 1
5703 ! IF (IFLAG >= 2) IERSL = 1
5704 ! IF (IFLAG < 0) IERSL = -1
5705 ! RETURN
5706 !-----------------------------------------------------------------------
5707 ! Use DPCG to solve the linear system P*x = -f
5708 !-----------------------------------------------------------------------
5709 ! 300 CONTINUE
5710 ! LR = 1
5711 ! LP = LR + N
5712 ! LW = LP + N
5713 ! LZ = LW + N
5714 ! LWK = LZ + N
5715 ! CALL DCOPY (N, X, 1, WM(LR), 1)
5716 ! CALL DPCG (NEQ, TN, Y, SAVF, WM(LR), EWT, N, MAXL, DELTA, HL0, &
5717 ! JPRE, MNEWT, F, PSOL, NPSL, X, WM(LP), WM(LW), WM(LZ), &
5718 ! LPCG, WM(LOCWP), IWM(LOCIWP), WM(LWK), IFLAG)
5719 ! NNI = NNI + 1
5720 ! NLI = NLI + LPCG
5721 ! NPS = NPS + NPSL
5722 ! IF (IFLAG /= 0) NCFL = NCFL + 1
5723 ! IF (IFLAG >= 2) IERSL = 1
5724 ! IF (IFLAG < 0) IERSL = -1
5725 ! RETURN
5726 !-----------------------------------------------------------------------
5727 ! Use DPCGS to solve the linear system P*x = -f
5728 !-----------------------------------------------------------------------
5729 ! 400 CONTINUE
5730 ! LR = 1
5731 ! LP = LR + N
5732 ! LW = LP + N
5733 ! LZ = LW + N
5734 ! LWK = LZ + N
5735 ! CALL DCOPY (N, X, 1, WM(LR), 1)
5736 ! CALL DPCGS (NEQ, TN, Y, SAVF, WM(LR), EWT, N, MAXL, DELTA, HL0, &
5737 ! JPRE, MNEWT, F, PSOL, NPSL, X, WM(LP), WM(LW), WM(LZ), &
5738 ! LPCG, WM(LOCWP), IWM(LOCIWP), WM(LWK), IFLAG)
5739 ! NNI = NNI + 1
5740 ! NLI = NLI + LPCG
5741 ! NPS = NPS + NPSL
5742 ! IF (IFLAG /= 0) NCFL = NCFL + 1
5743 ! IF (IFLAG >= 2) IERSL = 1
5744 ! IF (IFLAG < 0) IERSL = -1
5745 ! RETURN
5746 !-----------------------------------------------------------------------
5747 ! Use DUSOL, which interfaces to PSOL, to solve the linear system
5748 ! (no Krylov iteration).
5749 !-----------------------------------------------------------------------
5750 ! 900 CONTINUE
5751 ! LB = 1
5752 ! LWK = LB + N
5753 ! CALL DCOPY (N, X, 1, WM(LB), 1)
5754 ! CALL DUSOL (NEQ, TN, Y, SAVF, WM(LB), EWT, N, DELTA, HL0, MNEWT, &
5755 ! PSOL, NPSL, X, WM(LOCWP), IWM(LOCIWP), WM(LWK), IFLAG)
5756 ! NNI = NNI + 1
5757 ! NPS = NPS + NPSL
5758 ! IF (IFLAG /= 0) NCFL = NCFL + 1
5759 ! IF (IFLAG == 3) IERSL = 1
5760 ! IF (IFLAG < 0) IERSL = -1
5761 ! RETURN
5762 !----------------------- End of Subroutine DSOLPK ----------------------
5763 ! END SUBROUTINE DSOLPK
5764 ! ECK DSPIOM
5765 ! SUBROUTINE DSPIOM (NEQ, TN, Y, SAVF, B, WGHT, N, MAXL, KMP, DELTA, &
5766 ! HL0, JPRE, MNEWT, F, PSOL, NPSL, X, V, HES, IPVT, &
5767 ! LIOM, WP, IWP, WK, IFLAG)
5768 ! EXTERNAL F, PSOL
5769 ! INTEGER :: NEQ,N,MAXL,KMP,JPRE,MNEWT,NPSL,IPVT,LIOM,IWP,IFLAG
5770 ! DOUBLE PRECISION :: TN,Y,SAVF,B,WGHT,DELTA,HL0,X,V,HES,WP,WK
5771 ! DIMENSION NEQ(*), Y(*), SAVF(*), B(*), WGHT(*), X(*), V(N,*), &
5772 ! HES(MAXL,MAXL), IPVT(*), WP(*), IWP(*), WK(*)
5773 !-----------------------------------------------------------------------
5774 ! This routine solves the linear system A * x = b using a scaled
5775 ! preconditioned version of the Incomplete Orthogonalization Method.
5776 ! An initial guess of x = 0 is assumed.
5777 !-----------------------------------------------------------------------
5778 ! On entry
5779 ! NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
5780 ! TN = current value of t.
5781 ! Y = array containing current dependent variable vector.
5782 ! SAVF = array containing current value of f(t,y).
5783 ! B = the right hand side of the system A*x = b.
5784 ! B is also used as work space when computing the
5785 ! final approximation.
5786 ! (B is the same as V(*,MAXL+1) in the call to DSPIOM.)
5787 ! WGHT = array of length N containing scale factors.
5788 ! 1/WGHT(i) are the diagonal elements of the diagonal
5789 ! scaling matrix D.
5790 ! N = the order of the matrix A, and the lengths
5791 ! of the vectors Y, SAVF, B, WGHT, and X.
5792 ! MAXL = the maximum allowable order of the matrix HES.
5793 ! KMP = the number of previous vectors the new vector VNEW
5794 ! must be made orthogonal to. KMP .le. MAXL.
5795 ! DELTA = tolerance on residuals b - A*x in weighted RMS-norm.
5796 ! HL0 = current value of (step size h) * (coefficient l0).
5797 ! JPRE = preconditioner type flag.
5798 ! MNEWT = Newton iteration counter (.ge. 0).
5799 ! WK = real work array of length N used by DATV and PSOL.
5800 ! WP = real work array used by preconditioner PSOL.
5801 ! IWP = integer work array used by preconditioner PSOL.
5802 ! On return
5803 ! X = the final computed approximation to the solution
5804 ! of the system A*x = b.
5805 ! V = the N by (LIOM+1) array containing the LIOM
5806 ! orthogonal vectors V(*,1) to V(*,LIOM).
5807 ! HES = the LU factorization of the LIOM by LIOM upper
5808 ! Hessenberg matrix whose entries are the
5809 ! scaled inner products of A*V(*,k) and V(*,i).
5810 ! IPVT = an integer array containg pivoting information.
5811 ! It is loaded in DHEFA and used in DHESL.
5812 ! LIOM = the number of iterations performed, and current
5813 ! order of the upper Hessenberg matrix HES.
5814 ! NPSL = the number of calls to PSOL.
5815 ! IFLAG = integer error flag:
5816 ! 0 means convergence in LIOM iterations, LIOM.le.MAXL.
5817 ! 1 means the convergence test did not pass in MAXL
5818 ! iterations, but the residual norm is .lt. 1,
5819 ! or .lt. norm(b) if MNEWT = 0, and so X is computed.
5820 ! 2 means the convergence test did not pass in MAXL
5821 ! iterations, residual .gt. 1, and X is undefined.
5822 ! 3 means there was a recoverable error in PSOL
5823 ! caused by the preconditioner being out of date.
5824 ! -1 means there was a nonrecoverable error in PSOL.
5825 !-----------------------------------------------------------------------
5826 ! INTEGER :: I, IER, INFO, J, K, LL, LM1
5827 ! DOUBLE PRECISION :: BNRM, BNRM0, PROD, RHO, SNORMW, DNRM2, TEM
5828 ! IFLAG = 0
5829 ! LIOM = 0
5830 ! NPSL = 0
5831 !-----------------------------------------------------------------------
5832 ! The initial residual is the vector b. Apply scaling to b, and test
5833 ! for an immediate return with X = 0 or X = b.
5834 !-----------------------------------------------------------------------
5835 ! DO 10 I = 1,N
5836 ! V(I,1) = B(I)*WGHT(I)
5837 ! 10 END DO
5838 ! BNRM0 = DNRM2 (N, V, 1)
5839 ! BNRM = BNRM0
5840 ! IF (BNRM0 > DELTA) GO TO 30
5841 ! IF (MNEWT > 0) GO TO 20
5842 ! CALL DCOPY (N, B, 1, X, 1)
5843 ! RETURN
5844 ! 20 DO 25 I = 1,N
5845 ! X(I) = 0.0D0
5846 ! 25 END DO
5847 ! RETURN
5848 ! 30 CONTINUE
5849 ! Apply inverse of left preconditioner to vector b. --------------------
5850 ! IER = 0
5851 ! IF (JPRE == 0 .OR. JPRE == 2) GO TO 55
5852 ! CALL PSOL (NEQ, TN, Y, SAVF, WK, HL0, WP, IWP, B, 1, IER)
5853 ! NPSL = 1
5854 ! IF (IER /= 0) GO TO 300
5855 ! Calculate norm of scaled vector V(*,1) and normalize it. -------------
5856 ! DO 50 I = 1,N
5857 ! V(I,1) = B(I)*WGHT(I)
5858 ! 50 END DO
5859 ! BNRM = DNRM2(N, V, 1)
5860 ! DELTA = DELTA*(BNRM/BNRM0)
5861 ! 55 TEM = 1.0D0/BNRM
5862 ! CALL DSCAL (N, TEM, V(1,1), 1)
5863 ! Zero out the HES array. ----------------------------------------------
5864 ! DO 65 J = 1,MAXL
5865 ! DO 60 I = 1,MAXL
5866 ! HES(I,J) = 0.0D0
5867 ! 60 END DO
5868 ! 65 END DO
5869 !-----------------------------------------------------------------------
5870 ! Main loop on LL = l to compute the vectors V(*,2) to V(*,MAXL).
5871 ! The running product PROD is needed for the convergence test.
5872 !-----------------------------------------------------------------------
5873 ! PROD = 1.0D0
5874 ! DO 90 LL = 1,MAXL
5875 ! LIOM = LL
5876 ! !-----------------------------------------------------------------------
5877 ! ! Call routine DATV to compute VNEW = Abar*v(l), where Abar is
5878 ! ! the matrix A with scaling and inverse preconditioner factors applied.
5879 ! ! Call routine DORTHOG to orthogonalize the new vector vnew = V(*,l+1).
5880 ! ! Call routine DHEFA to update the factors of HES.
5881 ! !-----------------------------------------------------------------------
5882 ! CALL DATV (NEQ, Y, SAVF, V(1,LL), WGHT, X, F, PSOL, V(1,LL+1), &
5883 ! WK, WP, IWP, HL0, JPRE, IER, NPSL)
5884 ! IF (IER /= 0) GO TO 300
5885 ! CALL DORTHOG (V(1,LL+1), V, HES, N, LL, MAXL, KMP, SNORMW)
5886 ! CALL DHEFA (HES, MAXL, LL, IPVT, INFO, LL)
5887 ! LM1 = LL - 1
5888 ! IF (LL > 1 .AND. IPVT(LM1) == LM1) PROD = PROD*HES(LL,LM1)
5889 ! IF (INFO /= LL) GO TO 70
5890 ! !-----------------------------------------------------------------------
5891 ! ! The last pivot in HES was found to be zero.
5892 ! ! If vnew = 0 or l = MAXL, take an error return with IFLAG = 2.
5893 ! ! otherwise, continue the iteration without a convergence test.
5894 ! !-----------------------------------------------------------------------
5895 ! IF (SNORMW == 0.0D0) GO TO 120
5896 ! IF (LL == MAXL) GO TO 120
5897 ! GO TO 80
5898 ! !-----------------------------------------------------------------------
5899 ! ! Update RHO, the estimate of the norm of the residual b - A*x(l).
5900 ! ! test for convergence. If passed, compute approximation x(l).
5901 ! ! If failed and l .lt. MAXL, then continue iterating.
5902 ! !-----------------------------------------------------------------------
5903 ! 70 CONTINUE
5904 ! RHO = BNRM*SNORMW*ABS(PROD/HES(LL,LL))
5905 ! IF (RHO <= DELTA) GO TO 200
5906 ! IF (LL == MAXL) GO TO 100
5907 ! ! If l .lt. MAXL, store HES(l+1,l) and normalize the vector v(*,l+1).
5908 ! 80 CONTINUE
5909 ! HES(LL+1,LL) = SNORMW
5910 ! TEM = 1.0D0/SNORMW
5911 ! CALL DSCAL (N, TEM, V(1,LL+1), 1)
5912 ! 90 END DO
5913 !-----------------------------------------------------------------------
5914 ! l has reached MAXL without passing the convergence test:
5915 ! If RHO is not too large, compute a solution anyway and return with
5916 ! IFLAG = 1. Otherwise return with IFLAG = 2.
5917 !-----------------------------------------------------------------------
5918 ! 100 CONTINUE
5919 ! IF (RHO <= 1.0D0) GO TO 150
5920 ! IF (RHO <= BNRM .AND. MNEWT == 0) GO TO 150
5921 ! 120 CONTINUE
5922 ! IFLAG = 2
5923 ! RETURN
5924 ! 150 IFLAG = 1
5925 !-----------------------------------------------------------------------
5926 ! Compute the approximation x(l) to the solution.
5927 ! Since the vector X was used as work space, and the initial guess
5928 ! of the Newton correction is zero, X must be reset to zero.
5929 !-----------------------------------------------------------------------
5930 ! 200 CONTINUE
5931 ! LL = LIOM
5932 ! DO 210 K = 1,LL
5933 ! B(K) = 0.0D0
5934 ! 210 END DO
5935 ! B(1) = BNRM
5936 ! CALL DHESL (HES, MAXL, LL, IPVT, B)
5937 ! DO 220 K = 1,N
5938 ! X(K) = 0.0D0
5939 ! 220 END DO
5940 ! DO 230 I = 1,LL
5941 ! CALL DAXPY (N, B(I), V(1,I), 1, X, 1)
5942 ! 230 END DO
5943 ! DO 240 I = 1,N
5944 ! X(I) = X(I)/WGHT(I)
5945 ! 240 END DO
5946 ! IF (JPRE <= 1) RETURN
5947 ! CALL PSOL (NEQ, TN, Y, SAVF, WK, HL0, WP, IWP, X, 2, IER)
5948 ! NPSL = NPSL + 1
5949 ! IF (IER /= 0) GO TO 300
5950 ! RETURN
5951 !-----------------------------------------------------------------------
5952 ! This block handles error returns forced by routine PSOL.
5953 !-----------------------------------------------------------------------
5954 ! 300 CONTINUE
5955 ! IF (IER < 0) IFLAG = -1
5956 ! IF (IER > 0) IFLAG = 3
5957 ! RETURN
5958 !----------------------- End of Subroutine DSPIOM ----------------------
5959 ! END SUBROUTINE DSPIOM
5960 ! ECK DATV
5961 ! SUBROUTINE DATV (NEQ, Y, SAVF, V, WGHT, FTEM, F, PSOL, Z, VTEM, &
5962 ! WP, IWP, HL0, JPRE, IER, NPSL)
5963 ! EXTERNAL F, PSOL
5964 ! INTEGER :: NEQ, IWP, JPRE, IER, NPSL
5965 ! DOUBLE PRECISION :: Y, SAVF, V, WGHT, FTEM, Z, VTEM, WP, HL0
5966 ! DIMENSION NEQ(*), Y(*), SAVF(*), V(*), WGHT(*), FTEM(*), Z(*), &
5967 ! VTEM(*), WP(*), IWP(*)
5968 ! INTEGER :: IOWND, IOWNS, &
5969 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
5970 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
5971 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
5972 ! DOUBLE PRECISION :: ROWNS, &
5973 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
5974 ! COMMON /DLS001/ ROWNS(209), &
5975 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
5976 ! IOWND(6), IOWNS(6), &
5977 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
5978 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
5979 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
5980 !-----------------------------------------------------------------------
5981 ! This routine computes the product
5982 ! (D-inverse)*(P1-inverse)*(I - hl0*df/dy)*(P2-inverse)*(D*v),
5983 ! where D is a diagonal scaling matrix, and P1 and P2 are the
5984 ! left and right preconditioning matrices, respectively.
5985 ! v is assumed to have WRMS norm equal to 1.
5986 ! The product is stored in z. This is computed by a
5987 ! difference quotient, a call to F, and two calls to PSOL.
5988 !-----------------------------------------------------------------------
5989 ! On entry
5990 ! NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
5991 ! Y = array containing current dependent variable vector.
5992 ! SAVF = array containing current value of f(t,y).
5993 ! V = real array of length N (can be the same array as Z).
5994 ! WGHT = array of length N containing scale factors.
5995 ! 1/WGHT(i) are the diagonal elements of the matrix D.
5996 ! FTEM = work array of length N.
5997 ! VTEM = work array of length N used to store the
5998 ! unscaled version of V.
5999 ! WP = real work array used by preconditioner PSOL.
6000 ! IWP = integer work array used by preconditioner PSOL.
6001 ! HL0 = current value of (step size h) * (coefficient l0).
6002 ! JPRE = preconditioner type flag.
6003 ! On return
6004 ! Z = array of length N containing desired scaled
6005 ! matrix-vector product.
6006 ! IER = error flag from PSOL.
6007 ! NPSL = the number of calls to PSOL.
6008 ! In addition, this routine uses the Common variables TN, N, NFE.
6009 !-----------------------------------------------------------------------
6010 ! INTEGER :: I
6011 ! DOUBLE PRECISION :: FAC, RNORM, DNRM2, TEMPN
6012 ! Set VTEM = D * V.
6013 ! DO 10 I = 1,N
6014 ! VTEM(I) = V(I)/WGHT(I)
6015 ! 10 END DO
6016 ! IER = 0
6017 ! IF (JPRE >= 2) GO TO 30
6018 ! JPRE = 0 or 1. Save Y in Z and increment Y by VTEM.
6019 ! CALL DCOPY (N, Y, 1, Z, 1)
6020 ! DO 20 I = 1,N
6021 ! Y(I) = Z(I) + VTEM(I)
6022 ! 20 END DO
6023 ! FAC = HL0
6024 ! GO TO 60
6025 ! JPRE = 2 or 3. Apply inverse of right preconditioner to VTEM.
6026 ! 30 CONTINUE
6027 ! CALL PSOL (NEQ, TN, Y, SAVF, FTEM, HL0, WP, IWP, VTEM, 2, IER)
6028 ! NPSL = NPSL + 1
6029 ! IF (IER /= 0) RETURN
6030 ! Calculate L-2 norm of (D-inverse) * VTEM.
6031 ! DO 40 I = 1,N
6032 ! Z(I) = VTEM(I)*WGHT(I)
6033 ! 40 END DO
6034 ! TEMPN = DNRM2 (N, Z, 1)
6035 ! RNORM = 1.0D0/TEMPN
6036 ! Save Y in Z and increment Y by VTEM/norm.
6037 ! CALL DCOPY (N, Y, 1, Z, 1)
6038 ! DO 50 I = 1,N
6039 ! Y(I) = Z(I) + VTEM(I)*RNORM
6040 ! 50 END DO
6041 ! FAC = HL0*TEMPN
6042 ! For all JPRE, call F with incremented Y argument, and restore Y.
6043 ! 60 CONTINUE
6044 ! CALL F (NEQ, TN, Y, FTEM)
6045 ! NFE = NFE + 1
6046 ! CALL DCOPY (N, Z, 1, Y, 1)
6047 ! Set Z = (identity - hl0*Jacobian) * VTEM, using difference quotient.
6048 ! DO 70 I = 1,N
6049 ! Z(I) = FTEM(I) - SAVF(I)
6050 ! 70 END DO
6051 ! DO 80 I = 1,N
6052 ! Z(I) = VTEM(I) - FAC*Z(I)
6053 ! 80 END DO
6054 ! Apply inverse of left preconditioner to Z, if nontrivial.
6055 ! IF (JPRE == 0 .OR. JPRE == 2) GO TO 85
6056 ! CALL PSOL (NEQ, TN, Y, SAVF, FTEM, HL0, WP, IWP, Z, 1, IER)
6057 ! NPSL = NPSL + 1
6058 ! IF (IER /= 0) RETURN
6059 ! 85 CONTINUE
6060 ! Apply D-inverse to Z and return.
6061 ! DO 90 I = 1,N
6062 ! Z(I) = Z(I)*WGHT(I)
6063 ! 90 END DO
6064 ! RETURN
6065 !----------------------- End of Subroutine DATV ------------------------
6066 ! END SUBROUTINE DATV
6067 ! ECK DORTHOG
6068 ! SUBROUTINE DORTHOG (VNEW, V, HES, N, LL, LDHES, KMP, SNORMW)
6069 ! INTEGER :: N, LL, LDHES, KMP
6070 ! DOUBLE PRECISION :: VNEW, V, HES, SNORMW
6071 ! DIMENSION VNEW(*), V(N,*), HES(LDHES,*)
6072 !-----------------------------------------------------------------------
6073 ! This routine orthogonalizes the vector VNEW against the previous
6074 ! KMP vectors in the V array. It uses a modified Gram-Schmidt
6075 ! orthogonalization procedure with conditional reorthogonalization.
6076 ! This is the version of 28 may 1986.
6077 !-----------------------------------------------------------------------
6078 ! On entry
6079 ! VNEW = the vector of length N containing a scaled product
6080 ! of the Jacobian and the vector V(*,LL).
6081 ! V = the N x l array containing the previous LL
6082 ! orthogonal vectors v(*,1) to v(*,LL).
6083 ! HES = an LL x LL upper Hessenberg matrix containing,
6084 ! in HES(i,k), k.lt.LL, scaled inner products of
6085 ! A*V(*,k) and V(*,i).
6086 ! LDHES = the leading dimension of the HES array.
6087 ! N = the order of the matrix A, and the length of VNEW.
6088 ! LL = the current order of the matrix HES.
6089 ! KMP = the number of previous vectors the new vector VNEW
6090 ! must be made orthogonal to (KMP .le. MAXL).
6091 ! On return
6092 ! VNEW = the new vector orthogonal to V(*,i0) to V(*,LL),
6093 ! where i0 = MAX(1, LL-KMP+1).
6094 ! HES = upper Hessenberg matrix with column LL filled in with
6095 ! scaled inner products of A*V(*,LL) and V(*,i).
6096 ! SNORMW = L-2 norm of VNEW.
6097 !-----------------------------------------------------------------------
6098 ! INTEGER :: I, I0
6099 ! DOUBLE PRECISION :: ARG, DDOT, DNRM2, SUMDSQ, TEM, VNRM
6100 ! Get norm of unaltered VNEW for later use. ----------------------------
6101 ! VNRM = DNRM2 (N, VNEW, 1)
6102 !-----------------------------------------------------------------------
6103 ! Do modified Gram-Schmidt on VNEW = A*v(LL).
6104 ! Scaled inner products give new column of HES.
6105 ! Projections of earlier vectors are subtracted from VNEW.
6106 !-----------------------------------------------------------------------
6107 ! I0 = MAX(1,LL-KMP+1)
6108 ! DO 10 I = I0,LL
6109 ! HES(I,LL) = DDOT (N, V(1,I), 1, VNEW, 1)
6110 ! TEM = -HES(I,LL)
6111 ! CALL DAXPY (N, TEM, V(1,I), 1, VNEW, 1)
6112 ! 10 END DO
6113 !-----------------------------------------------------------------------
6114 ! Compute SNORMW = norm of VNEW.
6115 ! If VNEW is small compared to its input value (in norm), then
6116 ! reorthogonalize VNEW to V(*,1) through V(*,LL).
6117 ! Correct if relative correction exceeds 1000*(unit roundoff).
6118 ! finally, correct SNORMW using the dot products involved.
6119 !-----------------------------------------------------------------------
6120 ! SNORMW = DNRM2 (N, VNEW, 1)
6121 ! IF (VNRM + 0.001D0*SNORMW /= VNRM) RETURN
6122 ! SUMDSQ = 0.0D0
6123 ! DO 30 I = I0,LL
6124 ! TEM = -DDOT (N, V(1,I), 1, VNEW, 1)
6125 ! IF (HES(I,LL) + 0.001D0*TEM == HES(I,LL)) GO TO 30
6126 ! HES(I,LL) = HES(I,LL) - TEM
6127 ! CALL DAXPY (N, TEM, V(1,I), 1, VNEW, 1)
6128 ! SUMDSQ = SUMDSQ + TEM**2
6129 ! 30 END DO
6130 ! IF (SUMDSQ == 0.0D0) RETURN
6131 ! ARG = MAX(0.0D0,SNORMW**2 - SUMDSQ)
6132 ! SNORMW = SQRT(ARG)
6133 ! RETURN
6134 !----------------------- End of Subroutine DORTHOG ---------------------
6135 ! END SUBROUTINE DORTHOG
6136 ! ECK DSPIGMR
6137 ! SUBROUTINE DSPIGMR (NEQ, TN, Y, SAVF, B, WGHT, N, MAXL, MAXLP1, &
6138 ! KMP, DELTA, HL0, JPRE, MNEWT, F, PSOL, NPSL, X, V, HES, Q, &
6139 ! LGMR, WP, IWP, WK, DL, IFLAG)
6140 ! EXTERNAL F, PSOL
6141 ! INTEGER :: NEQ,N,MAXL,MAXLP1,KMP,JPRE,MNEWT,NPSL,LGMR,IWP,IFLAG
6142 ! DOUBLE PRECISION :: TN,Y,SAVF,B,WGHT,DELTA,HL0,X,V,HES,Q,WP,WK,DL
6143 ! DIMENSION NEQ(*), Y(*), SAVF(*), B(*), WGHT(*), X(*), V(N,*), &
6144 ! HES(MAXLP1,*), Q(*), WP(*), IWP(*), WK(*), DL(*)
6145 !-----------------------------------------------------------------------
6146 ! This routine solves the linear system A * x = b using a scaled
6147 ! preconditioned version of the Generalized Minimal Residual method.
6148 ! An initial guess of x = 0 is assumed.
6149 !-----------------------------------------------------------------------
6150 ! On entry
6151 ! NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6152 ! TN = current value of t.
6153 ! Y = array containing current dependent variable vector.
6154 ! SAVF = array containing current value of f(t,y).
6155 ! B = the right hand side of the system A*x = b.
6156 ! B is also used as work space when computing
6157 ! the final approximation.
6158 ! (B is the same as V(*,MAXL+1) in the call to DSPIGMR.)
6159 ! WGHT = the vector of length N containing the nonzero
6160 ! elements of the diagonal scaling matrix.
6161 ! N = the order of the matrix A, and the lengths
6162 ! of the vectors WGHT, B and X.
6163 ! MAXL = the maximum allowable order of the matrix HES.
6164 ! MAXLP1 = MAXL + 1, used for dynamic dimensioning of HES.
6165 ! KMP = the number of previous vectors the new vector VNEW
6166 ! must be made orthogonal to. KMP .le. MAXL.
6167 ! DELTA = tolerance on residuals b - A*x in weighted RMS-norm.
6168 ! HL0 = current value of (step size h) * (coefficient l0).
6169 ! JPRE = preconditioner type flag.
6170 ! MNEWT = Newton iteration counter (.ge. 0).
6171 ! WK = real work array used by routine DATV and PSOL.
6172 ! DL = real work array used for calculation of the residual
6173 ! norm RHO when the method is incomplete (KMP .lt. MAXL).
6174 ! Not needed or referenced in complete case (KMP = MAXL).
6175 ! WP = real work array used by preconditioner PSOL.
6176 ! IWP = integer work array used by preconditioner PSOL.
6177 ! On return
6178 ! X = the final computed approximation to the solution
6179 ! of the system A*x = b.
6180 ! LGMR = the number of iterations performed and
6181 ! the current order of the upper Hessenberg
6182 ! matrix HES.
6183 ! NPSL = the number of calls to PSOL.
6184 ! V = the N by (LGMR+1) array containing the LGMR
6185 ! orthogonal vectors V(*,1) to V(*,LGMR).
6186 ! HES = the upper triangular factor of the QR decomposition
6187 ! of the (LGMR+1) by lgmr upper Hessenberg matrix whose
6188 ! entries are the scaled inner-products of A*V(*,i)
6189 ! and V(*,k).
6190 ! Q = real array of length 2*MAXL containing the components
6191 ! of the Givens rotations used in the QR decomposition
6192 ! of HES. It is loaded in DHEQR and used in DHELS.
6193 ! IFLAG = integer error flag:
6194 ! 0 means convergence in LGMR iterations, LGMR .le. MAXL.
6195 ! 1 means the convergence test did not pass in MAXL
6196 ! iterations, but the residual norm is .lt. 1,
6197 ! or .lt. norm(b) if MNEWT = 0, and so x is computed.
6198 ! 2 means the convergence test did not pass in MAXL
6199 ! iterations, residual .gt. 1, and X is undefined.
6200 ! 3 means there was a recoverable error in PSOL
6201 ! caused by the preconditioner being out of date.
6202 ! -1 means there was a nonrecoverable error in PSOL.
6203 !-----------------------------------------------------------------------
6204 ! INTEGER :: I, IER, INFO, IP1, I2, J, K, LL, LLP1
6205 ! DOUBLE PRECISION :: BNRM,BNRM0,C,DLNRM,PROD,RHO,S,SNORMW,DNRM2,TEM
6206 ! IFLAG = 0
6207 ! LGMR = 0
6208 ! NPSL = 0
6209 !-----------------------------------------------------------------------
6210 ! The initial residual is the vector b. Apply scaling to b, and test
6211 ! for an immediate return with X = 0 or X = b.
6212 !-----------------------------------------------------------------------
6213 ! DO 10 I = 1,N
6214 ! V(I,1) = B(I)*WGHT(I)
6215 ! 10 END DO
6216 ! BNRM0 = DNRM2 (N, V, 1)
6217 ! BNRM = BNRM0
6218 ! IF (BNRM0 > DELTA) GO TO 30
6219 ! IF (MNEWT > 0) GO TO 20
6220 ! CALL DCOPY (N, B, 1, X, 1)
6221 ! RETURN
6222 ! 20 DO 25 I = 1,N
6223 ! X(I) = 0.0D0
6224 ! 25 END DO
6225 ! RETURN
6226 ! 30 CONTINUE
6227 ! Apply inverse of left preconditioner to vector b. --------------------
6228 ! IER = 0
6229 ! IF (JPRE == 0 .OR. JPRE == 2) GO TO 55
6230 ! CALL PSOL (NEQ, TN, Y, SAVF, WK, HL0, WP, IWP, B, 1, IER)
6231 ! NPSL = 1
6232 ! IF (IER /= 0) GO TO 300
6233 ! Calculate norm of scaled vector V(*,1) and normalize it. -------------
6234 ! DO 50 I = 1,N
6235 ! V(I,1) = B(I)*WGHT(I)
6236 ! 50 END DO
6237 ! BNRM = DNRM2 (N, V, 1)
6238 ! DELTA = DELTA*(BNRM/BNRM0)
6239 ! 55 TEM = 1.0D0/BNRM
6240 ! CALL DSCAL (N, TEM, V(1,1), 1)
6241 ! Zero out the HES array. ----------------------------------------------
6242 ! DO 65 J = 1,MAXL
6243 ! DO 60 I = 1,MAXLP1
6244 ! HES(I,J) = 0.0D0
6245 ! 60 END DO
6246 ! 65 END DO
6247 !-----------------------------------------------------------------------
6248 ! Main loop to compute the vectors V(*,2) to V(*,MAXL).
6249 ! The running product PROD is needed for the convergence test.
6250 !-----------------------------------------------------------------------
6251 ! PROD = 1.0D0
6252 ! DO 90 LL = 1,MAXL
6253 ! LGMR = LL
6254 ! !-----------------------------------------------------------------------
6255 ! ! Call routine DATV to compute VNEW = Abar*v(ll), where Abar is
6256 ! ! the matrix A with scaling and inverse preconditioner factors applied.
6257 ! ! Call routine DORTHOG to orthogonalize the new vector VNEW = V(*,LL+1).
6258 ! ! Call routine DHEQR to update the factors of HES.
6259 ! !-----------------------------------------------------------------------
6260 ! CALL DATV (NEQ, Y, SAVF, V(1,LL), WGHT, X, F, PSOL, V(1,LL+1), &
6261 ! WK, WP, IWP, HL0, JPRE, IER, NPSL)
6262 ! IF (IER /= 0) GO TO 300
6263 ! CALL DORTHOG (V(1,LL+1), V, HES, N, LL, MAXLP1, KMP, SNORMW)
6264 ! HES(LL+1,LL) = SNORMW
6265 ! CALL DHEQR (HES, MAXLP1, LL, Q, INFO, LL)
6266 ! IF (INFO == LL) GO TO 120
6267 ! !-----------------------------------------------------------------------
6268 ! ! Update RHO, the estimate of the norm of the residual b - A*xl.
6269 ! ! If KMP .lt. MAXL, then the vectors V(*,1),...,V(*,LL+1) are not
6270 ! ! necessarily orthogonal for LL .gt. KMP. The vector DL must then
6271 ! ! be computed, and its norm used in the calculation of RHO.
6272 ! !-----------------------------------------------------------------------
6273 ! PROD = PROD*Q(2*LL)
6274 ! RHO = ABS(PROD*BNRM)
6275 ! IF ((LL > KMP) .AND. (KMP < MAXL)) THEN
6276 ! IF (LL == KMP+1) THEN
6277 ! CALL DCOPY (N, V(1,1), 1, DL, 1)
6278 ! DO 75 I = 1,KMP
6279 ! IP1 = I + 1
6280 ! I2 = I*2
6281 ! S = Q(I2)
6282 ! C = Q(I2-1)
6283 ! DO 70 K = 1,N
6284 ! DL(K) = S*DL(K) + C*V(K,IP1)
6285 ! 70 END DO
6286 ! 75 END DO
6287 ! ENDIF
6288 ! S = Q(2*LL)
6289 ! C = Q(2*LL-1)/SNORMW
6290 ! LLP1 = LL + 1
6291 ! DO 80 K = 1,N
6292 ! DL(K) = S*DL(K) + C*V(K,LLP1)
6293 ! 80 END DO
6294 ! DLNRM = DNRM2 (N, DL, 1)
6295 ! RHO = RHO*DLNRM
6296 ! ENDIF
6297 ! !-----------------------------------------------------------------------
6298 ! ! Test for convergence. If passed, compute approximation xl.
6299 ! ! if failed and LL .lt. MAXL, then continue iterating.
6300 ! !-----------------------------------------------------------------------
6301 ! IF (RHO <= DELTA) GO TO 200
6302 ! IF (LL == MAXL) GO TO 100
6303 ! !-----------------------------------------------------------------------
6304 ! ! Rescale so that the norm of V(1,LL+1) is one.
6305 ! !-----------------------------------------------------------------------
6306 ! TEM = 1.0D0/SNORMW
6307 ! CALL DSCAL (N, TEM, V(1,LL+1), 1)
6308 ! 90 END DO
6309 ! 100 CONTINUE
6310 ! IF (RHO <= 1.0D0) GO TO 150
6311 ! IF (RHO <= BNRM .AND. MNEWT == 0) GO TO 150
6312 ! 120 CONTINUE
6313 ! IFLAG = 2
6314 ! RETURN
6315 ! 150 IFLAG = 1
6316 !-----------------------------------------------------------------------
6317 ! Compute the approximation xl to the solution.
6318 ! Since the vector X was used as work space, and the initial guess
6319 ! of the Newton correction is zero, X must be reset to zero.
6320 !-----------------------------------------------------------------------
6321 ! 200 CONTINUE
6322 ! LL = LGMR
6323 ! LLP1 = LL + 1
6324 ! DO 210 K = 1,LLP1
6325 ! B(K) = 0.0D0
6326 ! 210 END DO
6327 ! B(1) = BNRM
6328 ! CALL DHELS (HES, MAXLP1, LL, Q, B)
6329 ! DO 220 K = 1,N
6330 ! X(K) = 0.0D0
6331 ! 220 END DO
6332 ! DO 230 I = 1,LL
6333 ! CALL DAXPY (N, B(I), V(1,I), 1, X, 1)
6334 ! 230 END DO
6335 ! DO 240 I = 1,N
6336 ! X(I) = X(I)/WGHT(I)
6337 ! 240 END DO
6338 ! IF (JPRE <= 1) RETURN
6339 ! CALL PSOL (NEQ, TN, Y, SAVF, WK, HL0, WP, IWP, X, 2, IER)
6340 ! NPSL = NPSL + 1
6341 ! IF (IER /= 0) GO TO 300
6342 ! RETURN
6343 !-----------------------------------------------------------------------
6344 ! This block handles error returns forced by routine PSOL.
6345 !-----------------------------------------------------------------------
6346 ! 300 CONTINUE
6347 ! IF (IER < 0) IFLAG = -1
6348 ! IF (IER > 0) IFLAG = 3
6349 ! RETURN
6350 !----------------------- End of Subroutine DSPIGMR ---------------------
6351 ! END SUBROUTINE DSPIGMR
6352 ! ECK DPCG
6353 ! SUBROUTINE DPCG (NEQ, TN, Y, SAVF, R, WGHT, N, MAXL, DELTA, HL0, &
6354 ! JPRE, MNEWT, F, PSOL, NPSL, X, P, W, Z, LPCG, WP, IWP, WK, IFLAG)
6355 ! EXTERNAL F, PSOL
6356 ! INTEGER :: NEQ, N, MAXL, JPRE, MNEWT, NPSL, LPCG, IWP, IFLAG
6357 ! DOUBLE PRECISION :: TN,Y,SAVF,R,WGHT,DELTA,HL0,X,P,W,Z,WP,WK
6358 ! DIMENSION NEQ(*), Y(*), SAVF(*), R(*), WGHT(*), X(*), P(*), W(*), &
6359 ! Z(*), WP(*), IWP(*), WK(*)
6360 !-----------------------------------------------------------------------
6361 ! This routine computes the solution to the system A*x = b using a
6362 ! preconditioned version of the Conjugate Gradient algorithm.
6363 ! It is assumed here that the matrix A and the preconditioner
6364 ! matrix M are symmetric positive definite or nearly so.
6365 !-----------------------------------------------------------------------
6366 ! On entry
6367 ! NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6368 ! TN = current value of t.
6369 ! Y = array containing current dependent variable vector.
6370 ! SAVF = array containing current value of f(t,y).
6371 ! R = the right hand side of the system A*x = b.
6372 ! WGHT = array of length N containing scale factors.
6373 ! 1/WGHT(i) are the diagonal elements of the diagonal
6374 ! scaling matrix D.
6375 ! N = the order of the matrix A, and the lengths
6376 ! of the vectors Y, SAVF, R, WGHT, P, W, Z, WK, and X.
6377 ! MAXL = the maximum allowable number of iterates.
6378 ! DELTA = tolerance on residuals b - A*x in weighted RMS-norm.
6379 ! HL0 = current value of (step size h) * (coefficient l0).
6380 ! JPRE = preconditioner type flag.
6381 ! MNEWT = Newton iteration counter (.ge. 0).
6382 ! WK = real work array used by routine DATP.
6383 ! WP = real work array used by preconditioner PSOL.
6384 ! IWP = integer work array used by preconditioner PSOL.
6385 ! On return
6386 ! X = the final computed approximation to the solution
6387 ! of the system A*x = b.
6388 ! LPCG = the number of iterations performed, and current
6389 ! order of the upper Hessenberg matrix HES.
6390 ! NPSL = the number of calls to PSOL.
6391 ! IFLAG = integer error flag:
6392 ! 0 means convergence in LPCG iterations, LPCG .le. MAXL.
6393 ! 1 means the convergence test did not pass in MAXL
6394 ! iterations, but the residual norm is .lt. 1,
6395 ! or .lt. norm(b) if MNEWT = 0, and so X is computed.
6396 ! 2 means the convergence test did not pass in MAXL
6397 ! iterations, residual .gt. 1, and X is undefined.
6398 ! 3 means there was a recoverable error in PSOL
6399 ! caused by the preconditioner being out of date.
6400 ! 4 means there was a zero denominator in the algorithm.
6401 ! The system matrix or preconditioner matrix is not
6402 ! sufficiently close to being symmetric pos. definite.
6403 ! -1 means there was a nonrecoverable error in PSOL.
6404 !-----------------------------------------------------------------------
6405 ! INTEGER :: I, IER
6406 ! DOUBLE PRECISION :: ALPHA,BETA,BNRM,PTW,RNRM,DDOT,DVNORM,ZTR,ZTR0
6407 ! IFLAG = 0
6408 ! NPSL = 0
6409 ! LPCG = 0
6410 ! DO 10 I = 1,N
6411 ! X(I) = 0.0D0
6412 ! 10 END DO
6413 ! BNRM = DVNORM (N, R, WGHT)
6414 ! Test for immediate return with X = 0 or X = b. -----------------------
6415 ! IF (BNRM > DELTA) GO TO 20
6416 ! IF (MNEWT > 0) RETURN
6417 ! CALL DCOPY (N, R, 1, X, 1)
6418 ! RETURN
6419 ! 20 ZTR = 0.0D0
6420 ! Loop point for PCG iterations. ---------------------------------------
6421 ! 30 CONTINUE
6422 ! LPCG = LPCG + 1
6423 ! CALL DCOPY (N, R, 1, Z, 1)
6424 ! IER = 0
6425 ! IF (JPRE == 0) GO TO 40
6426 ! CALL PSOL (NEQ, TN, Y, SAVF, WK, HL0, WP, IWP, Z, 3, IER)
6427 ! NPSL = NPSL + 1
6428 ! IF (IER /= 0) GO TO 100
6429 ! 40 CONTINUE
6430 ! ZTR0 = ZTR
6431 ! ZTR = DDOT (N, Z, 1, R, 1)
6432 ! IF (LPCG /= 1) GO TO 50
6433 ! CALL DCOPY (N, Z, 1, P, 1)
6434 ! GO TO 70
6435 ! 50 CONTINUE
6436 ! IF (ZTR0 == 0.0D0) GO TO 200
6437 ! BETA = ZTR/ZTR0
6438 ! DO 60 I = 1,N
6439 ! P(I) = Z(I) + BETA*P(I)
6440 ! 60 END DO
6441 ! 70 CONTINUE
6442 !-----------------------------------------------------------------------
6443 ! Call DATP to compute A*p and return the answer in W.
6444 !-----------------------------------------------------------------------
6445 ! CALL DATP (NEQ, Y, SAVF, P, WGHT, HL0, WK, F, W)
6446 ! PTW = DDOT (N, P, 1, W, 1)
6447 ! IF (PTW == 0.0D0) GO TO 200
6448 ! ALPHA = ZTR/PTW
6449 ! CALL DAXPY (N, ALPHA, P, 1, X, 1)
6450 ! ALPHA = -ALPHA
6451 ! CALL DAXPY (N, ALPHA, W, 1, R, 1)
6452 ! RNRM = DVNORM (N, R, WGHT)
6453 ! IF (RNRM <= DELTA) RETURN
6454 ! IF (LPCG < MAXL) GO TO 30
6455 ! IFLAG = 2
6456 ! IF (RNRM <= 1.0D0) IFLAG = 1
6457 ! IF (RNRM <= BNRM .AND. MNEWT == 0) IFLAG = 1
6458 ! RETURN
6459 !-----------------------------------------------------------------------
6460 ! This block handles error returns from PSOL.
6461 !-----------------------------------------------------------------------
6462 ! 100 CONTINUE
6463 ! IF (IER < 0) IFLAG = -1
6464 ! IF (IER > 0) IFLAG = 3
6465 ! RETURN
6466 !-----------------------------------------------------------------------
6467 ! This block handles division by zero errors.
6468 !-----------------------------------------------------------------------
6469 ! 200 CONTINUE
6470 ! IFLAG = 4
6471 ! RETURN
6472 !----------------------- End of Subroutine DPCG ------------------------
6473 ! END SUBROUTINE DPCG
6474 ! ECK DPCGS
6475 ! SUBROUTINE DPCGS (NEQ, TN, Y, SAVF, R, WGHT, N, MAXL, DELTA, HL0, &
6476 ! JPRE, MNEWT, F, PSOL, NPSL, X, P, W, Z, LPCG, WP, IWP, WK, IFLAG)
6477 ! EXTERNAL F, PSOL
6478 ! INTEGER :: NEQ, N, MAXL, JPRE, MNEWT, NPSL, LPCG, IWP, IFLAG
6479 ! DOUBLE PRECISION :: TN,Y,SAVF,R,WGHT,DELTA,HL0,X,P,W,Z,WP,WK
6480 ! DIMENSION NEQ(*), Y(*), SAVF(*), R(*), WGHT(*), X(*), P(*), W(*), &
6481 ! Z(*), WP(*), IWP(*), WK(*)
6482 !-----------------------------------------------------------------------
6483 ! This routine computes the solution to the system A*x = b using a
6484 ! scaled preconditioned version of the Conjugate Gradient algorithm.
6485 ! It is assumed here that the scaled matrix D**-1 * A * D and the
6486 ! scaled preconditioner D**-1 * M * D are close to being
6487 ! symmetric positive definite.
6488 !-----------------------------------------------------------------------
6489 ! On entry
6490 ! NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6491 ! TN = current value of t.
6492 ! Y = array containing current dependent variable vector.
6493 ! SAVF = array containing current value of f(t,y).
6494 ! R = the right hand side of the system A*x = b.
6495 ! WGHT = array of length N containing scale factors.
6496 ! 1/WGHT(i) are the diagonal elements of the diagonal
6497 ! scaling matrix D.
6498 ! N = the order of the matrix A, and the lengths
6499 ! of the vectors Y, SAVF, R, WGHT, P, W, Z, WK, and X.
6500 ! MAXL = the maximum allowable number of iterates.
6501 ! DELTA = tolerance on residuals b - A*x in weighted RMS-norm.
6502 ! HL0 = current value of (step size h) * (coefficient l0).
6503 ! JPRE = preconditioner type flag.
6504 ! MNEWT = Newton iteration counter (.ge. 0).
6505 ! WK = real work array used by routine DATP.
6506 ! WP = real work array used by preconditioner PSOL.
6507 ! IWP = integer work array used by preconditioner PSOL.
6508 ! On return
6509 ! X = the final computed approximation to the solution
6510 ! of the system A*x = b.
6511 ! LPCG = the number of iterations performed, and current
6512 ! order of the upper Hessenberg matrix HES.
6513 ! NPSL = the number of calls to PSOL.
6514 ! IFLAG = integer error flag:
6515 ! 0 means convergence in LPCG iterations, LPCG .le. MAXL.
6516 ! 1 means the convergence test did not pass in MAXL
6517 ! iterations, but the residual norm is .lt. 1,
6518 ! or .lt. norm(b) if MNEWT = 0, and so X is computed.
6519 ! 2 means the convergence test did not pass in MAXL
6520 ! iterations, residual .gt. 1, and X is undefined.
6521 ! 3 means there was a recoverable error in PSOL
6522 ! caused by the preconditioner being out of date.
6523 ! 4 means there was a zero denominator in the algorithm.
6524 ! the scaled matrix or scaled preconditioner is not
6525 ! sufficiently close to being symmetric pos. definite.
6526 ! -1 means there was a nonrecoverable error in PSOL.
6527 !-----------------------------------------------------------------------
6528 ! INTEGER :: I, IER
6529 ! DOUBLE PRECISION :: ALPHA, BETA, BNRM, PTW, RNRM, DVNORM, ZTR, ZTR0
6530 ! IFLAG = 0
6531 ! NPSL = 0
6532 ! LPCG = 0
6533 ! DO 10 I = 1,N
6534 ! X(I) = 0.0D0
6535 ! 10 END DO
6536 ! BNRM = DVNORM (N, R, WGHT)
6537 ! Test for immediate return with X = 0 or X = b. -----------------------
6538 ! IF (BNRM > DELTA) GO TO 20
6539 ! IF (MNEWT > 0) RETURN
6540 ! CALL DCOPY (N, R, 1, X, 1)
6541 ! RETURN
6542 ! 20 ZTR = 0.0D0
6543 ! Loop point for PCG iterations. ---------------------------------------
6544 ! 30 CONTINUE
6545 ! LPCG = LPCG + 1
6546 ! CALL DCOPY (N, R, 1, Z, 1)
6547 ! IER = 0
6548 ! IF (JPRE == 0) GO TO 40
6549 ! CALL PSOL (NEQ, TN, Y, SAVF, WK, HL0, WP, IWP, Z, 3, IER)
6550 ! NPSL = NPSL + 1
6551 ! IF (IER /= 0) GO TO 100
6552 ! 40 CONTINUE
6553 ! ZTR0 = ZTR
6554 ! ZTR = 0.0D0
6555 ! DO 45 I = 1,N
6556 ! ZTR = ZTR + Z(I)*R(I)*WGHT(I)**2
6557 ! 45 END DO
6558 ! IF (LPCG /= 1) GO TO 50
6559 ! CALL DCOPY (N, Z, 1, P, 1)
6560 ! GO TO 70
6561 ! 50 CONTINUE
6562 ! IF (ZTR0 == 0.0D0) GO TO 200
6563 ! BETA = ZTR/ZTR0
6564 ! DO 60 I = 1,N
6565 ! P(I) = Z(I) + BETA*P(I)
6566 ! 60 END DO
6567 ! 70 CONTINUE
6568 !-----------------------------------------------------------------------
6569 ! Call DATP to compute A*p and return the answer in W.
6570 !-----------------------------------------------------------------------
6571 ! CALL DATP (NEQ, Y, SAVF, P, WGHT, HL0, WK, F, W)
6572 ! PTW = 0.0D0
6573 ! DO 80 I = 1,N
6574 ! PTW = PTW + P(I)*W(I)*WGHT(I)**2
6575 ! 80 END DO
6576 ! IF (PTW == 0.0D0) GO TO 200
6577 ! ALPHA = ZTR/PTW
6578 ! CALL DAXPY (N, ALPHA, P, 1, X, 1)
6579 ! ALPHA = -ALPHA
6580 ! CALL DAXPY (N, ALPHA, W, 1, R, 1)
6581 ! RNRM = DVNORM (N, R, WGHT)
6582 ! IF (RNRM <= DELTA) RETURN
6583 ! IF (LPCG < MAXL) GO TO 30
6584 ! IFLAG = 2
6585 ! IF (RNRM <= 1.0D0) IFLAG = 1
6586 ! IF (RNRM <= BNRM .AND. MNEWT == 0) IFLAG = 1
6587 ! RETURN
6588 !-----------------------------------------------------------------------
6589 ! This block handles error returns from PSOL.
6590 !-----------------------------------------------------------------------
6591 ! 100 CONTINUE
6592 ! IF (IER < 0) IFLAG = -1
6593 ! IF (IER > 0) IFLAG = 3
6594 ! RETURN
6595 !-----------------------------------------------------------------------
6596 ! This block handles division by zero errors.
6597 !-----------------------------------------------------------------------
6598 ! 200 CONTINUE
6599 ! IFLAG = 4
6600 ! RETURN
6601 !----------------------- End of Subroutine DPCGS -----------------------
6602 ! END SUBROUTINE DPCGS
6603 ! ECK DATP
6604 ! SUBROUTINE DATP (NEQ, Y, SAVF, P, WGHT, HL0, WK, F, W)
6605 ! EXTERNAL F
6606 ! INTEGER :: NEQ
6607 ! DOUBLE PRECISION :: Y, SAVF, P, WGHT, HL0, WK, W
6608 ! DIMENSION NEQ(*), Y(*), SAVF(*), P(*), WGHT(*), WK(*), W(*)
6609 ! INTEGER :: IOWND, IOWNS, &
6610 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
6611 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
6612 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
6613 ! DOUBLE PRECISION :: ROWNS, &
6614 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
6615 ! COMMON /DLS001/ ROWNS(209), &
6616 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
6617 ! IOWND(6), IOWNS(6), &
6618 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
6619 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
6620 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
6621 !-----------------------------------------------------------------------
6622 ! This routine computes the product
6623 ! w = (I - hl0*df/dy)*p
6624 ! This is computed by a call to F and a difference quotient.
6625 !-----------------------------------------------------------------------
6626 ! On entry
6627 ! NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6628 ! Y = array containing current dependent variable vector.
6629 ! SAVF = array containing current value of f(t,y).
6630 ! P = real array of length N.
6631 ! WGHT = array of length N containing scale factors.
6632 ! 1/WGHT(i) are the diagonal elements of the matrix D.
6633 ! WK = work array of length N.
6634 ! On return
6635 ! W = array of length N containing desired
6636 ! matrix-vector product.
6637 ! In addition, this routine uses the Common variables TN, N, NFE.
6638 !-----------------------------------------------------------------------
6639 ! INTEGER :: I
6640 ! DOUBLE PRECISION :: FAC, PNRM, RPNRM, DVNORM
6641 ! PNRM = DVNORM (N, P, WGHT)
6642 ! RPNRM = 1.0D0/PNRM
6643 ! CALL DCOPY (N, Y, 1, W, 1)
6644 ! DO 20 I = 1,N
6645 ! Y(I) = W(I) + P(I)*RPNRM
6646 ! 20 END DO
6647 ! CALL F (NEQ, TN, Y, WK)
6648 ! NFE = NFE + 1
6649 ! CALL DCOPY (N, W, 1, Y, 1)
6650 ! FAC = HL0*PNRM
6651 ! DO 40 I = 1,N
6652 ! W(I) = P(I) - FAC*(WK(I) - SAVF(I))
6653 ! 40 END DO
6654 ! RETURN
6655 !----------------------- End of Subroutine DATP ------------------------
6656 ! END SUBROUTINE DATP
6657 ! ECK DUSOL
6658 ! SUBROUTINE DUSOL (NEQ, TN, Y, SAVF, B, WGHT, N, DELTA, HL0, MNEWT, &
6659 ! PSOL, NPSL, X, WP, IWP, WK, IFLAG)
6660 ! EXTERNAL PSOL
6661 ! INTEGER :: NEQ, N, MNEWT, NPSL, IWP, IFLAG
6662 ! DOUBLE PRECISION :: TN, Y, SAVF, B, WGHT, DELTA, HL0, X, WP, WK
6663 ! DIMENSION NEQ(*), Y(*), SAVF(*), B(*), WGHT(*), X(*), &
6664 ! WP(*), IWP(*), WK(*)
6665 !-----------------------------------------------------------------------
6666 ! This routine solves the linear system A * x = b using only a call
6667 ! to the user-supplied routine PSOL (no Krylov iteration).
6668 ! If the norm of the right-hand side vector b is smaller than DELTA,
6669 ! the vector X returned is X = b (if MNEWT = 0) or X = 0 otherwise.
6670 ! PSOL is called with an LR argument of 0.
6671 !-----------------------------------------------------------------------
6672 ! On entry
6673 ! NEQ = problem size, passed to F and PSOL (NEQ(1) = N).
6674 ! TN = current value of t.
6675 ! Y = array containing current dependent variable vector.
6676 ! SAVF = array containing current value of f(t,y).
6677 ! B = the right hand side of the system A*x = b.
6678 ! WGHT = the vector of length N containing the nonzero
6679 ! elements of the diagonal scaling matrix.
6680 ! N = the order of the matrix A, and the lengths
6681 ! of the vectors WGHT, B and X.
6682 ! DELTA = tolerance on residuals b - A*x in weighted RMS-norm.
6683 ! HL0 = current value of (step size h) * (coefficient l0).
6684 ! MNEWT = Newton iteration counter (.ge. 0).
6685 ! WK = real work array used by PSOL.
6686 ! WP = real work array used by preconditioner PSOL.
6687 ! IWP = integer work array used by preconditioner PSOL.
6688 ! On return
6689 ! X = the final computed approximation to the solution
6690 ! of the system A*x = b.
6691 ! NPSL = the number of calls to PSOL.
6692 ! IFLAG = integer error flag:
6693 ! 0 means no trouble occurred.
6694 ! 3 means there was a recoverable error in PSOL
6695 ! caused by the preconditioner being out of date.
6696 ! -1 means there was a nonrecoverable error in PSOL.
6697 !-----------------------------------------------------------------------
6698 ! INTEGER :: I, IER
6699 ! DOUBLE PRECISION :: BNRM, DVNORM
6700 ! IFLAG = 0
6701 ! NPSL = 0
6702 !-----------------------------------------------------------------------
6703 ! Test for an immediate return with X = 0 or X = b.
6704 !-----------------------------------------------------------------------
6705 ! BNRM = DVNORM (N, B, WGHT)
6706 ! IF (BNRM > DELTA) GO TO 30
6707 ! IF (MNEWT > 0) GO TO 10
6708 ! CALL DCOPY (N, B, 1, X, 1)
6709 ! RETURN
6710 ! 10 DO 20 I = 1,N
6711 ! X(I) = 0.0D0
6712 ! 20 END DO
6713 ! RETURN
6714 ! Make call to PSOL and copy result from B to X. -----------------------
6715 ! 30 IER = 0
6716 ! CALL PSOL (NEQ, TN, Y, SAVF, WK, HL0, WP, IWP, B, 0, IER)
6717 ! NPSL = 1
6718 ! IF (IER /= 0) GO TO 100
6719 ! CALL DCOPY (N, B, 1, X, 1)
6720 ! RETURN
6721 !-----------------------------------------------------------------------
6722 ! This block handles error returns forced by routine PSOL.
6723 !-----------------------------------------------------------------------
6724 ! 100 CONTINUE
6725 ! IF (IER < 0) IFLAG = -1
6726 ! IF (IER > 0) IFLAG = 3
6727 ! RETURN
6728 !----------------------- End of Subroutine DUSOL -----------------------
6729 ! END SUBROUTINE DUSOL
6730 ! ECK DSRCPK
6731 ! SUBROUTINE DSRCPK (RSAV, ISAV, JOB)
6732 !-----------------------------------------------------------------------
6733 ! This routine saves or restores (depending on JOB) the contents of
6734 ! the Common blocks DLS001, DLPK01, which are used
6735 ! internally by the DLSODPK solver.
6736 ! RSAV = real array of length 222 or more.
6737 ! ISAV = integer array of length 50 or more.
6738 ! JOB = flag indicating to save or restore the Common blocks:
6739 ! JOB = 1 if Common is to be saved (written to RSAV/ISAV)
6740 ! JOB = 2 if Common is to be restored (read from RSAV/ISAV)
6741 ! A call with JOB = 2 presumes a prior call with JOB = 1.
6742 !-----------------------------------------------------------------------
6743 ! INTEGER :: ISAV, JOB
6744 ! INTEGER :: ILS, ILSP
6745 ! INTEGER :: I, LENILP, LENRLP, LENILS, LENRLS
6746 ! DOUBLE PRECISION :: RSAV, RLS, RLSP
6747 ! DIMENSION RSAV(*), ISAV(*)
6748 ! SAVE LENRLS, LENILS, LENRLP, LENILP
6749 ! COMMON /DLS001/ RLS(218), ILS(37)
6750 ! COMMON /DLPK01/ RLSP(4), ILSP(13)
6751 ! DATA LENRLS/218/, LENILS/37/, LENRLP/4/, LENILP/13/
6752 ! IF (JOB == 2) GO TO 100
6753 ! CALL DCOPY (LENRLS, RLS, 1, RSAV, 1)
6754 ! CALL DCOPY (LENRLP, RLSP, 1, RSAV(LENRLS+1), 1)
6755 ! DO 20 I = 1,LENILS
6756 ! ISAV(I) = ILS(I)
6757 ! 20 END DO
6758 ! DO 40 I = 1,LENILP
6759 ! ISAV(LENILS+I) = ILSP(I)
6760 ! 40 END DO
6761 ! RETURN
6762 ! 100 CONTINUE
6763 ! CALL DCOPY (LENRLS, RSAV, 1, RLS, 1)
6764 ! CALL DCOPY (LENRLP, RSAV(LENRLS+1), 1, RLSP, 1)
6765 ! DO 120 I = 1,LENILS
6766 ! ILS(I) = ISAV(I)
6767 ! 120 END DO
6768 ! DO 140 I = 1,LENILP
6769 ! ILSP(I) = ISAV(LENILS+I)
6770 ! 140 END DO
6771 ! RETURN
6772 !----------------------- End of Subroutine DSRCPK ----------------------
6773 ! END SUBROUTINE DSRCPK
6774 ! ECK DHEFA
6775 ! SUBROUTINE DHEFA (A, LDA, N, IPVT, INFO, JOB)
6776 ! INTEGER :: LDA, N, IPVT(*), INFO, JOB
6777 ! DOUBLE PRECISION :: A(LDA,*)
6778 !-----------------------------------------------------------------------
6779 ! This routine is a modification of the LINPACK routine DGEFA and
6780 ! performs an LU decomposition of an upper Hessenberg matrix A.
6781 ! There are two options available:
6782 ! (1) performing a fresh factorization
6783 ! (2) updating the LU factors by adding a row and a
6784 ! column to the matrix A.
6785 !-----------------------------------------------------------------------
6786 ! DHEFA factors an upper Hessenberg matrix by elimination.
6787 ! On entry
6788 ! A DOUBLE PRECISION(LDA, N)
6789 ! the matrix to be factored.
6790 ! LDA INTEGER
6791 ! the leading dimension of the array A .
6792 ! N INTEGER
6793 ! the order of the matrix A .
6794 ! JOB INTEGER
6795 ! JOB = 1 means that a fresh factorization of the
6796 ! matrix A is desired.
6797 ! JOB .ge. 2 means that the current factorization of A
6798 ! will be updated by the addition of a row
6799 ! and a column.
6800 ! On return
6801 ! A an upper triangular matrix and the multipliers
6802 ! which were used to obtain it.
6803 ! The factorization can be written A = L*U where
6804 ! L is a product of permutation and unit lower
6805 ! triangular matrices and U is upper triangular.
6806 ! IPVT INTEGER(N)
6807 ! an integer vector of pivot indices.
6808 ! INFO INTEGER
6809 ! = 0 normal value.
6810 ! = k if U(k,k) .eq. 0.0 . This is not an error
6811 ! condition for this subroutine, but it does
6812 ! indicate that DHESL will divide by zero if called.
6813 ! Modification of LINPACK, by Peter Brown, LLNL.
6814 ! Written 7/20/83. This version dated 6/20/01.
6815 ! BLAS called: DAXPY, IDAMAX
6816 !-----------------------------------------------------------------------
6817 ! INTEGER :: IDAMAX, J, K, KM1, KP1, L, NM1
6818 ! DOUBLE PRECISION :: T
6819 ! IF (JOB > 1) GO TO 80
6820 ! A new facorization is desired. This is essentially the LINPACK
6821 ! code with the exception that we know there is only one nonzero
6822 ! element below the main diagonal.
6823 ! Gaussian elimination with partial pivoting
6824 ! INFO = 0
6825 ! NM1 = N - 1
6826 ! IF (NM1 < 1) GO TO 70
6827 ! DO 60 K = 1, NM1
6828 ! KP1 = K + 1
6829 !
6830 ! ! Find L = pivot index
6831 !
6832 ! L = IDAMAX (2, A(K,K), 1) + K - 1
6833 ! IPVT(K) = L
6834 !
6835 ! ! Zero pivot implies this column already triangularized
6836 !
6837 ! IF (A(L,K) == 0.0D0) GO TO 40
6838 !
6839 ! ! Interchange if necessary
6840 !
6841 ! IF (L == K) GO TO 10
6842 ! T = A(L,K)
6843 ! A(L,K) = A(K,K)
6844 ! A(K,K) = T
6845 ! 10 CONTINUE
6846 !
6847 ! ! Compute multipliers
6848 !
6849 ! T = -1.0D0/A(K,K)
6850 ! A(K+1,K) = A(K+1,K)*T
6851 !
6852 ! ! Row elimination with column indexing
6853 !
6854 ! DO 30 J = KP1, N
6855 ! T = A(L,J)
6856 ! IF (L == K) GO TO 20
6857 ! A(L,J) = A(K,J)
6858 ! A(K,J) = T
6859 ! 20 CONTINUE
6860 ! CALL DAXPY (N-K, T, A(K+1,K), 1, A(K+1,J), 1)
6861 ! 30 END DO
6862 ! cycle
6863 ! 40 CONTINUE
6864 ! INFO = K
6865 ! 60 END DO
6866 ! 70 CONTINUE
6867 ! IPVT(N) = N
6868 ! IF (A(N,N) == 0.0D0) INFO = N
6869 ! RETURN
6870 ! The old factorization of A will be updated. A row and a column
6871 ! has been added to the matrix A.
6872 ! N-1 is now the old order of the matrix.
6873 ! 80 CONTINUE
6874 ! NM1 = N - 1
6875 ! Perform row interchanges on the elements of the new column, and
6876 ! perform elimination operations on the elements using the multipliers.
6877 ! IF (NM1 <= 1) GO TO 105
6878 ! DO 100 K = 2,NM1
6879 ! KM1 = K - 1
6880 ! L = IPVT(KM1)
6881 ! T = A(L,N)
6882 ! IF (L == KM1) GO TO 90
6883 ! A(L,N) = A(KM1,N)
6884 ! A(KM1,N) = T
6885 ! 90 CONTINUE
6886 ! A(K,N) = A(K,N) + A(K,KM1)*T
6887 ! 100 END DO
6888 ! 105 CONTINUE
6889 ! Complete update of factorization by decomposing last 2x2 block.
6890 ! INFO = 0
6891 ! Find L = pivot index
6892 ! L = IDAMAX (2, A(NM1,NM1), 1) + NM1 - 1
6893 ! IPVT(NM1) = L
6894 ! Zero pivot implies this column already triangularized
6895 ! IF (A(L,NM1) == 0.0D0) GO TO 140
6896 ! Interchange if necessary
6897 ! IF (L == NM1) GO TO 110
6898 ! T = A(L,NM1)
6899 ! A(L,NM1) = A(NM1,NM1)
6900 ! A(NM1,NM1) = T
6901 ! 110 CONTINUE
6902 ! Compute multipliers
6903 ! T = -1.0D0/A(NM1,NM1)
6904 ! A(N,NM1) = A(N,NM1)*T
6905 ! Row elimination with column indexing
6906 ! T = A(L,N)
6907 ! IF (L == NM1) GO TO 120
6908 ! A(L,N) = A(NM1,N)
6909 ! A(NM1,N) = T
6910 ! 120 CONTINUE
6911 ! A(N,N) = A(N,N) + T*A(N,NM1)
6912 ! GO TO 150
6913 ! 140 CONTINUE
6914 ! INFO = NM1
6915 ! 150 CONTINUE
6916 ! IPVT(N) = N
6917 ! IF (A(N,N) == 0.0D0) INFO = N
6918 ! RETURN
6919 !----------------------- End of Subroutine DHEFA -----------------------
6920 ! END SUBROUTINE DHEFA
6921 ! ECK DHESL
6922 ! SUBROUTINE DHESL (A, LDA, N, IPVT, B)
6923 ! INTEGER :: LDA, N, IPVT(*)
6924 ! DOUBLE PRECISION :: A(LDA,*), B(*)
6925 !-----------------------------------------------------------------------
6926 ! This is essentially the LINPACK routine DGESL except for changes
6927 ! due to the fact that A is an upper Hessenberg matrix.
6928 !-----------------------------------------------------------------------
6929 ! DHESL solves the real system A * x = b
6930 ! using the factors computed by DHEFA.
6931 ! On entry
6932 ! A DOUBLE PRECISION(LDA, N)
6933 ! the output from DHEFA.
6934 ! LDA INTEGER
6935 ! the leading dimension of the array A .
6936 ! N INTEGER
6937 ! the order of the matrix A .
6938 ! IPVT INTEGER(N)
6939 ! the pivot vector from DHEFA.
6940 ! B DOUBLE PRECISION(N)
6941 ! the right hand side vector.
6942 ! On return
6943 ! B the solution vector x .
6944 ! Modification of LINPACK, by Peter Brown, LLNL.
6945 ! Written 7/20/83. This version dated 6/20/01.
6946 ! BLAS called: DAXPY
6947 !-----------------------------------------------------------------------
6948 ! INTEGER :: K, KB, L, NM1
6949 ! DOUBLE PRECISION :: T
6950 ! NM1 = N - 1
6951 ! Solve A * x = b
6952 ! First solve L*y = b
6953 ! IF (NM1 < 1) GO TO 30
6954 ! DO 20 K = 1, NM1
6955 ! L = IPVT(K)
6956 ! T = B(L)
6957 ! IF (L == K) GO TO 10
6958 ! B(L) = B(K)
6959 ! B(K) = T
6960 ! 10 CONTINUE
6961 ! B(K+1) = B(K+1) + T*A(K+1,K)
6962 ! 20 END DO
6963 ! 30 CONTINUE
6964 ! Now solve U*x = y
6965 ! DO 40 KB = 1, N
6966 ! K = N + 1 - KB
6967 ! B(K) = B(K)/A(K,K)
6968 ! T = -B(K)
6969 ! CALL DAXPY (K-1, T, A(1,K), 1, B(1), 1)
6970 ! 40 END DO
6971 ! RETURN
6972 !----------------------- End of Subroutine DHESL -----------------------
6973 ! END SUBROUTINE DHESL
6974 ! ECK DHEQR
6975 ! SUBROUTINE DHEQR (A, LDA, N, Q, INFO, IJOB)
6976 ! INTEGER :: LDA, N, INFO, IJOB
6977 ! DOUBLE PRECISION :: A(LDA,*), Q(*)
6978 !-----------------------------------------------------------------------
6979 ! This routine performs a QR decomposition of an upper
6980 ! Hessenberg matrix A. There are two options available:
6981 ! (1) performing a fresh decomposition
6982 ! (2) updating the QR factors by adding a row and a
6983 ! column to the matrix A.
6984 !-----------------------------------------------------------------------
6985 ! DHEQR decomposes an upper Hessenberg matrix by using Givens
6986 ! rotations.
6987 ! On entry
6988 ! A DOUBLE PRECISION(LDA, N)
6989 ! the matrix to be decomposed.
6990 ! LDA INTEGER
6991 ! the leading dimension of the array A .
6992 ! N INTEGER
6993 ! A is an (N+1) by N Hessenberg matrix.
6994 ! IJOB INTEGER
6995 ! = 1 means that a fresh decomposition of the
6996 ! matrix A is desired.
6997 ! .ge. 2 means that the current decomposition of A
6998 ! will be updated by the addition of a row
6999 ! and a column.
7000 ! On return
7001 ! A the upper triangular matrix R.
7002 ! The factorization can be written Q*A = R, where
7003 ! Q is a product of Givens rotations and R is upper
7004 ! triangular.
7005 ! Q DOUBLE PRECISION(2*N)
7006 ! the factors c and s of each Givens rotation used
7007 ! in decomposing A.
7008 ! INFO INTEGER
7009 ! = 0 normal value.
7010 ! = k if A(k,k) .eq. 0.0 . This is not an error
7011 ! condition for this subroutine, but it does
7012 ! indicate that DHELS will divide by zero
7013 ! if called.
7014 ! Modification of LINPACK, by Peter Brown, LLNL.
7015 ! Written 1/13/86. This version dated 6/20/01.
7016 !-----------------------------------------------------------------------
7017 ! INTEGER :: I, IQ, J, K, KM1, KP1, NM1
7018 ! DOUBLE PRECISION :: C, S, T, T1, T2
7019 ! IF (IJOB > 1) GO TO 70
7020 ! A new facorization is desired.
7021 ! QR decomposition without pivoting
7022 ! INFO = 0
7023 ! DO 60 K = 1, N
7024 ! KM1 = K - 1
7025 ! KP1 = K + 1
7026 !
7027 ! ! Compute kth column of R.
7028 ! ! First, multiply the kth column of A by the previous
7029 ! ! k-1 Givens rotations.
7030 !
7031 ! IF (KM1 < 1) GO TO 20
7032 ! DO 10 J = 1, KM1
7033 ! I = 2*(J-1) + 1
7034 ! T1 = A(J,K)
7035 ! T2 = A(J+1,K)
7036 ! C = Q(I)
7037 ! S = Q(I+1)
7038 ! A(J,K) = C*T1 - S*T2
7039 ! A(J+1,K) = S*T1 + C*T2
7040 ! 10 END DO
7041 !
7042 ! ! Compute Givens components c and s
7043 !
7044 ! 20 CONTINUE
7045 ! IQ = 2*KM1 + 1
7046 ! T1 = A(K,K)
7047 ! T2 = A(KP1,K)
7048 ! IF (T2 /= 0.0D0) GO TO 30
7049 ! C = 1.0D0
7050 ! S = 0.0D0
7051 ! GO TO 50
7052 ! 30 CONTINUE
7053 ! IF (ABS(T2) < ABS(T1)) GO TO 40
7054 ! T = T1/T2
7055 ! S = -1.0D0/SQRT(1.0D0+T*T)
7056 ! C = -S*T
7057 ! GO TO 50
7058 ! 40 CONTINUE
7059 ! T = T2/T1
7060 ! C = 1.0D0/SQRT(1.0D0+T*T)
7061 ! S = -C*T
7062 ! 50 CONTINUE
7063 ! Q(IQ) = C
7064 ! Q(IQ+1) = S
7065 ! A(K,K) = C*T1 - S*T2
7066 ! IF (A(K,K) == 0.0D0) INFO = K
7067 ! 60 END DO
7068 ! RETURN
7069 ! The old factorization of A will be updated. A row and a column
7070 ! has been added to the matrix A.
7071 ! N by N-1 is now the old size of the matrix.
7072 ! 70 CONTINUE
7073 ! NM1 = N - 1
7074 ! Multiply the new column by the N previous Givens rotations.
7075 ! DO 100 K = 1,NM1
7076 ! I = 2*(K-1) + 1
7077 ! T1 = A(K,N)
7078 ! T2 = A(K+1,N)
7079 ! C = Q(I)
7080 ! S = Q(I+1)
7081 ! A(K,N) = C*T1 - S*T2
7082 ! A(K+1,N) = S*T1 + C*T2
7083 ! 100 END DO
7084 ! Complete update of decomposition by forming last Givens rotation,
7085 ! and multiplying it times the column vector (A(N,N), A(N+1,N)).
7086 ! INFO = 0
7087 ! T1 = A(N,N)
7088 ! T2 = A(N+1,N)
7089 ! IF (T2 /= 0.0D0) GO TO 110
7090 ! C = 1.0D0
7091 ! S = 0.0D0
7092 ! GO TO 130
7093 ! 110 CONTINUE
7094 ! IF (ABS(T2) < ABS(T1)) GO TO 120
7095 ! T = T1/T2
7096 ! S = -1.0D0/SQRT(1.0D0+T*T)
7097 ! C = -S*T
7098 ! GO TO 130
7099 ! 120 CONTINUE
7100 ! T = T2/T1
7101 ! C = 1.0D0/SQRT(1.0D0+T*T)
7102 ! S = -C*T
7103 ! 130 CONTINUE
7104 ! IQ = 2*N - 1
7105 ! Q(IQ) = C
7106 ! Q(IQ+1) = S
7107 ! A(N,N) = C*T1 - S*T2
7108 ! IF (A(N,N) == 0.0D0) INFO = N
7109 ! RETURN
7110 !----------------------- End of Subroutine DHEQR -----------------------
7111 ! END SUBROUTINE DHEQR
7112 ! ECK DHELS
7113 ! SUBROUTINE DHELS (A, LDA, N, Q, B)
7114 ! INTEGER :: LDA, N
7115 ! DOUBLE PRECISION :: A(LDA,*), B(*), Q(*)
7116 !-----------------------------------------------------------------------
7117 ! This is part of the LINPACK routine DGESL with changes
7118 ! due to the fact that A is an upper Hessenberg matrix.
7119 !-----------------------------------------------------------------------
7120 ! DHELS solves the least squares problem
7121 ! min (b-A*x, b-A*x)
7122 ! using the factors computed by DHEQR.
7123 ! On entry
7124 ! A DOUBLE PRECISION(LDA, N)
7125 ! the output from DHEQR which contains the upper
7126 ! triangular factor R in the QR decomposition of A.
7127 ! LDA INTEGER
7128 ! the leading dimension of the array A .
7129 ! N INTEGER
7130 ! A is originally an (N+1) by N matrix.
7131 ! Q DOUBLE PRECISION(2*N)
7132 ! The coefficients of the N givens rotations
7133 ! used in the QR factorization of A.
7134 ! B DOUBLE PRECISION(N+1)
7135 ! the right hand side vector.
7136 ! On return
7137 ! B the solution vector x .
7138 ! Modification of LINPACK, by Peter Brown, LLNL.
7139 ! Written 1/13/86. This version dated 6/20/01.
7140 ! BLAS called: DAXPY
7141 !-----------------------------------------------------------------------
7142 ! INTEGER :: IQ, K, KB, KP1
7143 ! DOUBLE PRECISION :: C, S, T, T1, T2
7144 ! Minimize (b-A*x, b-A*x)
7145 ! First form Q*b.
7146 ! DO 20 K = 1, N
7147 ! KP1 = K + 1
7148 ! IQ = 2*(K-1) + 1
7149 ! C = Q(IQ)
7150 ! S = Q(IQ+1)
7151 ! T1 = B(K)
7152 ! T2 = B(KP1)
7153 ! B(K) = C*T1 - S*T2
7154 ! B(KP1) = S*T1 + C*T2
7155 ! 20 END DO
7156 ! Now solve R*x = Q*b.
7157 ! DO 40 KB = 1, N
7158 ! K = N + 1 - KB
7159 ! B(K) = B(K)/A(K,K)
7160 ! T = -B(K)
7161 ! CALL DAXPY (K-1, T, A(1,K), 1, B(1), 1)
7162 ! 40 END DO
7163 ! RETURN
7164 !----------------------- End of Subroutine DHELS -----------------------
7165 ! END SUBROUTINE DHELS
7166 ! ECK DLHIN
7167 ! SUBROUTINE DLHIN (NEQ, N, T0, Y0, YDOT, F, TOUT, UROUND, &
7168 ! EWT, ITOL, ATOL, Y, TEMP, H0, NITER, IER)
7169 ! EXTERNAL F
7170 ! DOUBLE PRECISION :: T0, Y0, YDOT, TOUT, UROUND, EWT, ATOL, Y, &
7171 ! TEMP, H0
7172 ! INTEGER :: NEQ, N, ITOL, NITER, IER
7173 ! DIMENSION NEQ(*), Y0(*), YDOT(*), EWT(*), ATOL(*), Y(*), TEMP(*)
7174 !-----------------------------------------------------------------------
7175 ! Call sequence input -- NEQ, N, T0, Y0, YDOT, F, TOUT, UROUND,
7176 ! EWT, ITOL, ATOL, Y, TEMP
7177 ! Call sequence output -- H0, NITER, IER
7178 ! Common block variables accessed -- None
7179 ! Subroutines called by DLHIN: F, DCOPY
7180 ! Function routines called by DLHIN: DVNORM
7181 !-----------------------------------------------------------------------
7182 ! This routine computes the step size, H0, to be attempted on the
7183 ! first step, when the user has not supplied a value for this.
7184 ! First we check that TOUT - T0 differs significantly from zero. Then
7185 ! an iteration is done to approximate the initial second derivative
7186 ! and this is used to define H from WRMS-norm(H**2 * yddot / 2) = 1.
7187 ! A bias factor of 1/2 is applied to the resulting h.
7188 ! The sign of H0 is inferred from the initial values of TOUT and T0.
7189 ! Communication with DLHIN is done with the following variables:
7190 ! NEQ = NEQ array of solver, passed to F.
7191 ! N = size of ODE system, input.
7192 ! T0 = initial value of independent variable, input.
7193 ! Y0 = vector of initial conditions, input.
7194 ! YDOT = vector of initial first derivatives, input.
7195 ! F = name of subroutine for right-hand side f(t,y), input.
7196 ! TOUT = first output value of independent variable
7197 ! UROUND = machine unit roundoff
7198 ! EWT, ITOL, ATOL = error weights and tolerance parameters
7199 ! as described in the driver routine, input.
7200 ! Y, TEMP = work arrays of length N.
7201 ! H0 = step size to be attempted, output.
7202 ! NITER = number of iterations (and of f evaluations) to compute H0,
7203 ! output.
7204 ! IER = the error flag, returned with the value
7205 ! IER = 0 if no trouble occurred, or
7206 ! IER = -1 if TOUT and t0 are considered too close to proceed.
7207 !-----------------------------------------------------------------------
7208 ! Type declarations for local variables --------------------------------
7209 ! DOUBLE PRECISION :: AFI, ATOLI, DELYI, HALF, HG, HLB, HNEW, HRAT, &
7210 ! HUB, HUN, PT1, T1, TDIST, TROUND, TWO, DVNORM, YDDNRM
7211 ! INTEGER :: I, ITER
7212 !-----------------------------------------------------------------------
7213 ! The following Fortran-77 declaration is to cause the values of the
7214 ! listed (local) variables to be saved between calls to this integrator.
7215 !-----------------------------------------------------------------------
7216 ! SAVE HALF, HUN, PT1, TWO
7217 ! DATA HALF /0.5D0/, HUN /100.0D0/, PT1 /0.1D0/, TWO /2.0D0/
7218 ! NITER = 0
7219 ! TDIST = ABS(TOUT - T0)
7220 ! TROUND = UROUND*MAX(ABS(T0),ABS(TOUT))
7221 ! IF (TDIST < TWO*TROUND) GO TO 100
7222 ! Set a lower bound on H based on the roundoff level in T0 and TOUT. ---
7223 ! HLB = HUN*TROUND
7224 ! Set an upper bound on H based on TOUT-T0 and the initial Y and YDOT. -
7225 ! HUB = PT1*TDIST
7226 ! ATOLI = ATOL(1)
7227 ! DO 10 I = 1,N
7228 ! IF (ITOL == 2 .OR. ITOL == 4) ATOLI = ATOL(I)
7229 ! DELYI = PT1*ABS(Y0(I)) + ATOLI
7230 ! AFI = ABS(YDOT(I))
7231 ! IF (AFI*HUB > DELYI) HUB = DELYI/AFI
7232 ! 10 END DO
7233 ! Set initial guess for H as geometric mean of upper and lower bounds. -
7234 ! ITER = 0
7235 ! HG = SQRT(HLB*HUB)
7236 ! If the bounds have crossed, exit with the mean value. ----------------
7237 ! IF (HUB < HLB) THEN
7238 ! H0 = HG
7239 ! GO TO 90
7240 ! ENDIF
7241 ! Looping point for iteration. -----------------------------------------
7242 ! 50 CONTINUE
7243 ! Estimate the second derivative as a difference quotient in f. --------
7244 ! T1 = T0 + HG
7245 ! DO 60 I = 1,N
7246 ! Y(I) = Y0(I) + HG*YDOT(I)
7247 ! 60 END DO
7248 ! CALL F (NEQ, T1, Y, TEMP)
7249 ! DO 70 I = 1,N
7250 ! TEMP(I) = (TEMP(I) - YDOT(I))/HG
7251 ! 70 END DO
7252 ! YDDNRM = DVNORM (N, TEMP, EWT)
7253 ! Get the corresponding new value of H. --------------------------------
7254 ! IF (YDDNRM*HUB*HUB > TWO) THEN
7255 ! HNEW = SQRT(TWO/YDDNRM)
7256 ! ELSE
7257 ! HNEW = SQRT(HG*HUB)
7258 ! ENDIF
7259 ! ITER = ITER + 1
7260 !-----------------------------------------------------------------------
7261 ! Test the stopping conditions.
7262 ! Stop if the new and previous H values differ by a factor of .lt. 2.
7263 ! Stop if four iterations have been done. Also, stop with previous H
7264 ! if hnew/hg .gt. 2 after first iteration, as this probably means that
7265 ! the second derivative value is bad because of cancellation error.
7266 !-----------------------------------------------------------------------
7267 ! IF (ITER >= 4) GO TO 80
7268 ! HRAT = HNEW/HG
7269 ! IF ( (HRAT > HALF) .AND. (HRAT < TWO) ) GO TO 80
7270 ! IF ( (ITER >= 2) .AND. (HNEW > TWO*HG) ) THEN
7271 ! HNEW = HG
7272 ! GO TO 80
7273 ! ENDIF
7274 ! HG = HNEW
7275 ! GO TO 50
7276 ! Iteration done. Apply bounds, bias factor, and sign. ----------------
7277 ! 80 H0 = HNEW*HALF
7278 ! IF (H0 < HLB) H0 = HLB
7279 ! IF (H0 > HUB) H0 = HUB
7280 ! 90 H0 = SIGN(H0, TOUT - T0)
7281 ! Restore Y array from Y0, then exit. ----------------------------------
7282 ! CALL DCOPY (N, Y0, 1, Y, 1)
7283 ! NITER = ITER
7284 ! IER = 0
7285 ! RETURN
7286 ! Error return for TOUT - T0 too small. --------------------------------
7287 ! 100 IER = -1
7288 ! RETURN
7289 !----------------------- End of Subroutine DLHIN -----------------------
7290 ! END SUBROUTINE DLHIN
7291 ! ECK DSTOKA
7292 ! SUBROUTINE DSTOKA (NEQ, Y, YH, NYH, YH1, EWT, SAVF, SAVX, ACOR, &
7293 ! WM, IWM, F, JAC, PSOL)
7294 ! EXTERNAL F, JAC, PSOL
7295 ! INTEGER :: NEQ, NYH, IWM
7296 ! DOUBLE PRECISION :: Y, YH, YH1, EWT, SAVF, SAVX, ACOR, WM
7297 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), YH1(*), EWT(*), SAVF(*), &
7298 ! SAVX(*), ACOR(*), WM(*), IWM(*)
7299 ! INTEGER :: IOWND, IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, &
7300 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
7301 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
7302 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
7303 ! INTEGER :: NEWT, NSFI, NSLJ, NJEV
7304 ! INTEGER :: JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
7305 ! NNI, NLI, NPS, NCFN, NCFL
7306 ! DOUBLE PRECISION :: CONIT, CRATE, EL, ELCO, HOLD, RMAX, TESCO, &
7307 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
7308 ! DOUBLE PRECISION :: STIFR
7309 ! DOUBLE PRECISION :: DELT, EPCON, SQRTN, RSQRTN
7310 ! COMMON /DLS001/ CONIT, CRATE, EL(13), ELCO(13,12), &
7311 ! HOLD, RMAX, TESCO(3,12), &
7312 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
7313 ! IOWND(6), IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, &
7314 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
7315 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
7316 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
7317 ! COMMON /DLS002/ STIFR, NEWT, NSFI, NSLJ, NJEV
7318 ! COMMON /DLPK01/ DELT, EPCON, SQRTN, RSQRTN, &
7319 ! JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
7320 ! NNI, NLI, NPS, NCFN, NCFL
7321 !-----------------------------------------------------------------------
7322 ! DSTOKA performs one step of the integration of an initial value
7323 ! problem for a system of Ordinary Differential Equations.
7324 ! This routine was derived from Subroutine DSTODPK in the DLSODPK
7325 ! package by the addition of automatic functional/Newton iteration
7326 ! switching and logic for re-use of Jacobian data.
7327 !-----------------------------------------------------------------------
7328 ! Note: DSTOKA is independent of the value of the iteration method
7329 ! indicator MITER, when this is .ne. 0, and hence is independent
7330 ! of the type of chord method used, or the Jacobian structure.
7331 ! Communication with DSTOKA is done with the following variables:
7332 ! NEQ = integer array containing problem size in NEQ(1), and
7333 ! passed as the NEQ argument in all calls to F and JAC.
7334 ! Y = an array of length .ge. N used as the Y argument in
7335 ! all calls to F and JAC.
7336 ! YH = an NYH by LMAX array containing the dependent variables
7337 ! and their approximate scaled derivatives, where
7338 ! LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
7339 ! j-th derivative of y(i), scaled by H**j/factorial(j)
7340 ! (j = 0,1,...,NQ). On entry for the first step, the first
7341 ! two columns of YH must be set from the initial values.
7342 ! NYH = a constant integer .ge. N, the first dimension of YH.
7343 ! YH1 = a one-dimensional array occupying the same space as YH.
7344 ! EWT = an array of length N containing multiplicative weights
7345 ! for local error measurements. Local errors in y(i) are
7346 ! compared to 1.0/EWT(i) in various error tests.
7347 ! SAVF = an array of working storage, of length N.
7348 ! Also used for input of YH(*,MAXORD+2) when JSTART = -1
7349 ! and MAXORD .lt. the current order NQ.
7350 ! SAVX = an array of working storage, of length N.
7351 ! ACOR = a work array of length N, used for the accumulated
7352 ! corrections. On a successful return, ACOR(i) contains
7353 ! the estimated one-step local error in y(i).
7354 ! WM,IWM = real and integer work arrays associated with matrix
7355 ! operations in chord iteration (MITER .ne. 0).
7356 ! CCMAX = maximum relative change in H*EL0 before DSETPK is called.
7357 ! H = the step size to be attempted on the next step.
7358 ! H is altered by the error control algorithm during the
7359 ! problem. H can be either positive or negative, but its
7360 ! sign must remain constant throughout the problem.
7361 ! HMIN = the minimum absolute value of the step size H to be used.
7362 ! HMXI = inverse of the maximum absolute value of H to be used.
7363 ! HMXI = 0.0 is allowed and corresponds to an infinite HMAX.
7364 ! HMIN and HMXI may be changed at any time, but will not
7365 ! take effect until the next change of H is considered.
7366 ! TN = the independent variable. TN is updated on each step taken.
7367 ! JSTART = an integer used for input only, with the following
7368 ! values and meanings:
7369 ! 0 perform the first step.
7370 ! .gt.0 take a new step continuing from the last.
7371 ! -1 take the next step with a new value of H, MAXORD,
7372 ! N, METH, MITER, and/or matrix parameters.
7373 ! -2 take the next step with a new value of H,
7374 ! but with other inputs unchanged.
7375 ! On return, JSTART is set to 1 to facilitate continuation.
7376 ! KFLAG = a completion code with the following meanings:
7377 ! 0 the step was succesful.
7378 ! -1 the requested error could not be achieved.
7379 ! -2 corrector convergence could not be achieved.
7380 ! -3 fatal error in DSETPK or DSOLPK.
7381 ! A return with KFLAG = -1 or -2 means either
7382 ! ABS(H) = HMIN or 10 consecutive failures occurred.
7383 ! On a return with KFLAG negative, the values of TN and
7384 ! the YH array are as of the beginning of the last
7385 ! step, and H is the last step size attempted.
7386 ! MAXORD = the maximum order of integration method to be allowed.
7387 ! MAXCOR = the maximum number of corrector iterations allowed.
7388 ! MSBP = maximum number of steps between DSETPK calls (MITER .gt. 0).
7389 ! MXNCF = maximum number of convergence failures allowed.
7390 ! METH/MITER = the method flags. See description in driver.
7391 ! N = the number of first-order differential equations.
7392 !-----------------------------------------------------------------------
7393 ! INTEGER :: I, I1, IREDO, IRET, J, JB, JOK, M, NCF, NEWQ, NSLOW
7394 ! DOUBLE PRECISION :: DCON, DDN, DEL, DELP, DRC, DSM, DUP, EXDN, EXSM, &
7395 ! EXUP, DFNORM, R, RH, RHDN, RHSM, RHUP, ROC, STIFF, TOLD, DVNORM
7396 ! KFLAG = 0
7397 ! TOLD = TN
7398 ! NCF = 0
7399 ! IERPJ = 0
7400 ! IERSL = 0
7401 ! JCUR = 0
7402 ! ICF = 0
7403 ! DELP = 0.0D0
7404 ! IF (JSTART > 0) GO TO 200
7405 ! IF (JSTART == -1) GO TO 100
7406 ! IF (JSTART == -2) GO TO 160
7407 !-----------------------------------------------------------------------
7408 ! On the first call, the order is set to 1, and other variables are
7409 ! initialized. RMAX is the maximum ratio by which H can be increased
7410 ! in a single step. It is initially 1.E4 to compensate for the small
7411 ! initial H, but then is normally equal to 10. If a failure
7412 ! occurs (in corrector convergence or error test), RMAX is set at 2
7413 ! for the next increase.
7414 !-----------------------------------------------------------------------
7415 ! LMAX = MAXORD + 1
7416 ! NQ = 1
7417 ! L = 2
7418 ! IALTH = 2
7419 ! RMAX = 10000.0D0
7420 ! RC = 0.0D0
7421 ! EL0 = 1.0D0
7422 ! CRATE = 0.7D0
7423 ! HOLD = H
7424 ! MEO = METH
7425 ! NSLP = 0
7426 ! NSLJ = 0
7427 ! IPUP = 0
7428 ! IRET = 3
7429 ! NEWT = 0
7430 ! STIFR = 0.0D0
7431 ! GO TO 140
7432 !-----------------------------------------------------------------------
7433 ! The following block handles preliminaries needed when JSTART = -1.
7434 ! IPUP is set to MITER to force a matrix update.
7435 ! If an order increase is about to be considered (IALTH = 1),
7436 ! IALTH is reset to 2 to postpone consideration one more step.
7437 ! If the caller has changed METH, DCFODE is called to reset
7438 ! the coefficients of the method.
7439 ! If the caller has changed MAXORD to a value less than the current
7440 ! order NQ, NQ is reduced to MAXORD, and a new H chosen accordingly.
7441 ! If H is to be changed, YH must be rescaled.
7442 ! If H or METH is being changed, IALTH is reset to L = NQ + 1
7443 ! to prevent further changes in H for that many steps.
7444 !-----------------------------------------------------------------------
7445 ! 100 IPUP = MITER
7446 ! LMAX = MAXORD + 1
7447 ! IF (IALTH == 1) IALTH = 2
7448 ! IF (METH == MEO) GO TO 110
7449 ! CALL DCFODE (METH, ELCO, TESCO)
7450 ! MEO = METH
7451 ! IF (NQ > MAXORD) GO TO 120
7452 ! IALTH = L
7453 ! IRET = 1
7454 ! GO TO 150
7455 ! 110 IF (NQ <= MAXORD) GO TO 160
7456 ! 120 NQ = MAXORD
7457 ! L = LMAX
7458 ! DO 125 I = 1,L
7459 ! EL(I) = ELCO(I,NQ)
7460 ! 125 END DO
7461 ! NQNYH = NQ*NYH
7462 ! RC = RC*EL(1)/EL0
7463 ! EL0 = EL(1)
7464 ! CONIT = 0.5D0/(NQ+2)
7465 ! EPCON = CONIT*TESCO(2,NQ)
7466 ! DDN = DVNORM (N, SAVF, EWT)/TESCO(1,L)
7467 ! EXDN = 1.0D0/L
7468 ! RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
7469 ! RH = MIN(RHDN,1.0D0)
7470 ! IREDO = 3
7471 ! IF (H == HOLD) GO TO 170
7472 ! RH = MIN(RH,ABS(H/HOLD))
7473 ! H = HOLD
7474 ! GO TO 175
7475 !-----------------------------------------------------------------------
7476 ! DCFODE is called to get all the integration coefficients for the
7477 ! current METH. Then the EL vector and related constants are reset
7478 ! whenever the order NQ is changed, or at the start of the problem.
7479 !-----------------------------------------------------------------------
7480 ! 140 CALL DCFODE (METH, ELCO, TESCO)
7481 ! 150 DO 155 I = 1,L
7482 ! EL(I) = ELCO(I,NQ)
7483 ! 155 END DO
7484 ! NQNYH = NQ*NYH
7485 ! RC = RC*EL(1)/EL0
7486 ! EL0 = EL(1)
7487 ! CONIT = 0.5D0/(NQ+2)
7488 ! EPCON = CONIT*TESCO(2,NQ)
7489 ! GO TO (160, 170, 200), IRET
7490 !-----------------------------------------------------------------------
7491 ! If H is being changed, the H ratio RH is checked against
7492 ! RMAX, HMIN, and HMXI, and the YH array rescaled. IALTH is set to
7493 ! L = NQ + 1 to prevent a change of H for that many steps, unless
7494 ! forced by a convergence or error test failure.
7495 !-----------------------------------------------------------------------
7496 ! 160 IF (H == HOLD) GO TO 200
7497 ! RH = H/HOLD
7498 ! H = HOLD
7499 ! IREDO = 3
7500 ! GO TO 175
7501 ! 170 RH = MAX(RH,HMIN/ABS(H))
7502 ! 175 RH = MIN(RH,RMAX)
7503 ! RH = RH/MAX(1.0D0,ABS(H)*HMXI*RH)
7504 ! R = 1.0D0
7505 ! DO 180 J = 2,L
7506 ! R = R*RH
7507 ! DO 180 I = 1,N
7508 ! YH(I,J) = YH(I,J)*R
7509 ! 180 END DO
7510 ! H = H*RH
7511 ! RC = RC*RH
7512 ! IALTH = L
7513 ! IF (IREDO == 0) GO TO 690
7514 !-----------------------------------------------------------------------
7515 ! This section computes the predicted values by effectively
7516 ! multiplying the YH array by the Pascal triangle matrix.
7517 ! The flag IPUP is set according to whether matrix data is involved
7518 ! (NEWT .gt. 0 .and. JACFLG .ne. 0) or not, to trigger a call to DSETPK.
7519 ! IPUP is set to MITER when RC differs from 1 by more than CCMAX,
7520 ! and at least every MSBP steps, when JACFLG = 1.
7521 ! RC is the ratio of new to old values of the coefficient H*EL(1).
7522 !-----------------------------------------------------------------------
7523 ! 200 IF (NEWT == 0 .OR. JACFLG == 0) THEN
7524 ! DRC = 0.0D0
7525 ! IPUP = 0
7526 ! CRATE = 0.7D0
7527 ! ELSE
7528 ! DRC = ABS(RC - 1.0D0)
7529 ! IF (DRC > CCMAX) IPUP = MITER
7530 ! IF (NST >= NSLP+MSBP) IPUP = MITER
7531 ! ENDIF
7532 ! TN = TN + H
7533 ! I1 = NQNYH + 1
7534 ! DO 215 JB = 1,NQ
7535 ! I1 = I1 - NYH
7536 ! ! IR$ IVDEP
7537 ! DO 210 I = I1,NQNYH
7538 ! YH1(I) = YH1(I) + YH1(I+NYH)
7539 ! 210 END DO
7540 ! 215 END DO
7541 !-----------------------------------------------------------------------
7542 ! Up to MAXCOR corrector iterations are taken. A convergence test is
7543 ! made on the RMS-norm of each correction, weighted by the error
7544 ! weight vector EWT. The sum of the corrections is accumulated in the
7545 ! vector ACOR(i). The YH array is not altered in the corrector loop.
7546 ! Within the corrector loop, an estimated rate of convergence (ROC)
7547 ! and a stiffness ratio estimate (STIFF) are kept. Corresponding
7548 ! global estimates are kept as CRATE and stifr.
7549 !-----------------------------------------------------------------------
7550 ! 220 M = 0
7551 ! MNEWT = 0
7552 ! STIFF = 0.0D0
7553 ! ROC = 0.05D0
7554 ! NSLOW = 0
7555 ! DO 230 I = 1,N
7556 ! Y(I) = YH(I,1)
7557 ! 230 END DO
7558 ! CALL F (NEQ, TN, Y, SAVF)
7559 ! NFE = NFE + 1
7560 ! IF (NEWT == 0 .OR. IPUP <= 0) GO TO 250
7561 !-----------------------------------------------------------------------
7562 ! If indicated, DSETPK is called to update any matrix data needed,
7563 ! before starting the corrector iteration.
7564 ! JOK is set to indicate if the matrix data need not be recomputed.
7565 ! IPUP is set to 0 as an indicator that the matrix data is up to date.
7566 !-----------------------------------------------------------------------
7567 ! JOK = 1
7568 ! IF (NST == 0 .OR. NST > NSLJ+50) JOK = -1
7569 ! IF (ICF == 1 .AND. DRC < 0.2D0) JOK = -1
7570 ! IF (ICF == 2) JOK = -1
7571 ! IF (JOK == -1) THEN
7572 ! NSLJ = NST
7573 ! NJEV = NJEV + 1
7574 ! ENDIF
7575 ! CALL DSETPK (NEQ, Y, YH1, EWT, ACOR, SAVF, JOK, WM, IWM, F, JAC)
7576 ! IPUP = 0
7577 ! RC = 1.0D0
7578 ! DRC = 0.0D0
7579 ! NSLP = NST
7580 ! CRATE = 0.7D0
7581 ! IF (IERPJ /= 0) GO TO 430
7582 ! 250 DO 260 I = 1,N
7583 ! ACOR(I) = 0.0D0
7584 ! 260 END DO
7585 ! 270 IF (NEWT /= 0) GO TO 350
7586 !-----------------------------------------------------------------------
7587 ! In the case of functional iteration, update Y directly from
7588 ! the result of the last function evaluation, and STIFF is set to 1.0.
7589 !-----------------------------------------------------------------------
7590 ! DO 290 I = 1,N
7591 ! SAVF(I) = H*SAVF(I) - YH(I,2)
7592 ! Y(I) = SAVF(I) - ACOR(I)
7593 ! 290 END DO
7594 ! DEL = DVNORM (N, Y, EWT)
7595 ! DO 300 I = 1,N
7596 ! Y(I) = YH(I,1) + EL(1)*SAVF(I)
7597 ! ACOR(I) = SAVF(I)
7598 ! 300 END DO
7599 ! STIFF = 1.0D0
7600 ! GO TO 400
7601 !-----------------------------------------------------------------------
7602 ! In the case of the chord method, compute the corrector error,
7603 ! and solve the linear system with that as right-hand side and
7604 ! P as coefficient matrix. STIFF is set to the ratio of the norms
7605 ! of the residual and the correction vector.
7606 !-----------------------------------------------------------------------
7607 ! 350 DO 360 I = 1,N
7608 ! SAVX(I) = H*SAVF(I) - (YH(I,2) + ACOR(I))
7609 ! 360 END DO
7610 ! DFNORM = DVNORM (N, SAVX, EWT)
7611 ! CALL DSOLPK (NEQ, Y, SAVF, SAVX, EWT, WM, IWM, F, PSOL)
7612 ! IF (IERSL < 0) GO TO 430
7613 ! IF (IERSL > 0) GO TO 410
7614 ! DEL = DVNORM (N, SAVX, EWT)
7615 ! IF (DEL > 1.0D-8) STIFF = MAX(STIFF, DFNORM/DEL)
7616 ! DO 380 I = 1,N
7617 ! ACOR(I) = ACOR(I) + SAVX(I)
7618 ! Y(I) = YH(I,1) + EL(1)*ACOR(I)
7619 ! 380 END DO
7620 !-----------------------------------------------------------------------
7621 ! Test for convergence. If M .gt. 0, an estimate of the convergence
7622 ! rate constant is made for the iteration switch, and is also used
7623 ! in the convergence test. If the iteration seems to be diverging or
7624 ! converging at a slow rate (.gt. 0.8 more than once), it is stopped.
7625 !-----------------------------------------------------------------------
7626 ! 400 IF (M /= 0) THEN
7627 ! ROC = MAX(0.05D0, DEL/DELP)
7628 ! CRATE = MAX(0.2D0*CRATE,ROC)
7629 ! ENDIF
7630 ! DCON = DEL*MIN(1.0D0,1.5D0*CRATE)/EPCON
7631 ! IF (DCON <= 1.0D0) GO TO 450
7632 ! M = M + 1
7633 ! IF (M == MAXCOR) GO TO 410
7634 ! IF (M >= 2 .AND. DEL > 2.0D0*DELP) GO TO 410
7635 ! IF (ROC > 10.0D0) GO TO 410
7636 ! IF (ROC > 0.8D0) NSLOW = NSLOW + 1
7637 ! IF (NSLOW >= 2) GO TO 410
7638 ! MNEWT = M
7639 ! DELP = DEL
7640 ! CALL F (NEQ, TN, Y, SAVF)
7641 ! NFE = NFE + 1
7642 ! GO TO 270
7643 !-----------------------------------------------------------------------
7644 ! The corrector iteration failed to converge.
7645 ! If functional iteration is being done (NEWT = 0) and MITER .gt. 0
7646 ! (and this is not the first step), then switch to Newton
7647 ! (NEWT = MITER), and retry the step. (Setting STIFR = 1023 insures
7648 ! that a switch back will not occur for 10 step attempts.)
7649 ! If Newton iteration is being done, but using a preconditioner that
7650 ! is out of date (JACFLG .ne. 0 .and. JCUR = 0), then signal for a
7651 ! re-evalutation of the preconditioner, and retry the step.
7652 ! In all other cases, the YH array is retracted to its values
7653 ! before prediction, and H is reduced, if possible. If H cannot be
7654 ! reduced or MXNCF failures have occurred, exit with KFLAG = -2.
7655 !-----------------------------------------------------------------------
7656 ! 410 ICF = 1
7657 ! IF (NEWT == 0) THEN
7658 ! IF (NST == 0) GO TO 430
7659 ! IF (MITER == 0) GO TO 430
7660 ! NEWT = MITER
7661 ! STIFR = 1023.0D0
7662 ! IPUP = MITER
7663 ! GO TO 220
7664 ! ENDIF
7665 ! IF (JCUR == 1 .OR. JACFLG == 0) GO TO 430
7666 ! IPUP = MITER
7667 ! GO TO 220
7668 ! 430 ICF = 2
7669 ! NCF = NCF + 1
7670 ! NCFN = NCFN + 1
7671 ! RMAX = 2.0D0
7672 ! TN = TOLD
7673 ! I1 = NQNYH + 1
7674 ! DO 445 JB = 1,NQ
7675 ! I1 = I1 - NYH
7676 ! ! IR$ IVDEP
7677 ! DO 440 I = I1,NQNYH
7678 ! YH1(I) = YH1(I) - YH1(I+NYH)
7679 ! 440 END DO
7680 ! 445 END DO
7681 ! IF (IERPJ < 0 .OR. IERSL < 0) GO TO 680
7682 ! IF (ABS(H) <= HMIN*1.00001D0) GO TO 670
7683 ! IF (NCF == MXNCF) GO TO 670
7684 ! RH = 0.5D0
7685 ! IPUP = MITER
7686 ! IREDO = 1
7687 ! GO TO 170
7688 !-----------------------------------------------------------------------
7689 ! The corrector has converged. JCUR is set to 0 to signal that the
7690 ! preconditioner involved may need updating later.
7691 ! The stiffness ratio STIFR is updated using the latest STIFF value.
7692 ! The local error test is made and control passes to statement 500
7693 ! if it fails.
7694 !-----------------------------------------------------------------------
7695 ! 450 JCUR = 0
7696 ! IF (NEWT > 0) STIFR = 0.5D0*(STIFR + STIFF)
7697 ! IF (M == 0) DSM = DEL/TESCO(2,NQ)
7698 ! IF (M > 0) DSM = DVNORM (N, ACOR, EWT)/TESCO(2,NQ)
7699 ! IF (DSM > 1.0D0) GO TO 500
7700 !-----------------------------------------------------------------------
7701 ! After a successful step, update the YH array.
7702 ! If Newton iteration is being done and STIFR is less than 1.5,
7703 ! then switch to functional iteration.
7704 ! Consider changing H if IALTH = 1. Otherwise decrease IALTH by 1.
7705 ! If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
7706 ! use in a possible order increase on the next step.
7707 ! If a change in H is considered, an increase or decrease in order
7708 ! by one is considered also. A change in H is made only if it is by a
7709 ! factor of at least 1.1. If not, IALTH is set to 3 to prevent
7710 ! testing for that many steps.
7711 !-----------------------------------------------------------------------
7712 ! KFLAG = 0
7713 ! IREDO = 0
7714 ! NST = NST + 1
7715 ! IF (NEWT == 0) NSFI = NSFI + 1
7716 ! IF (NEWT > 0 .AND. STIFR < 1.5D0) NEWT = 0
7717 ! HU = H
7718 ! NQU = NQ
7719 ! DO 470 J = 1,L
7720 ! DO 470 I = 1,N
7721 ! YH(I,J) = YH(I,J) + EL(J)*ACOR(I)
7722 ! 470 END DO
7723 ! IALTH = IALTH - 1
7724 ! IF (IALTH == 0) GO TO 520
7725 ! IF (IALTH > 1) GO TO 700
7726 ! IF (L == LMAX) GO TO 700
7727 ! DO 490 I = 1,N
7728 ! YH(I,LMAX) = ACOR(I)
7729 ! 490 END DO
7730 ! GO TO 700
7731 !-----------------------------------------------------------------------
7732 ! The error test failed. KFLAG keeps track of multiple failures.
7733 ! Restore TN and the YH array to their previous values, and prepare
7734 ! to try the step again. Compute the optimum step size for this or
7735 ! one lower order. After 2 or more failures, H is forced to decrease
7736 ! by a factor of 0.2 or less.
7737 !-----------------------------------------------------------------------
7738 ! 500 KFLAG = KFLAG - 1
7739 ! TN = TOLD
7740 ! I1 = NQNYH + 1
7741 ! DO 515 JB = 1,NQ
7742 ! I1 = I1 - NYH
7743 ! ! IR$ IVDEP
7744 ! DO 510 I = I1,NQNYH
7745 ! YH1(I) = YH1(I) - YH1(I+NYH)
7746 ! 510 END DO
7747 ! 515 END DO
7748 ! RMAX = 2.0D0
7749 ! IF (ABS(H) <= HMIN*1.00001D0) GO TO 660
7750 ! IF (KFLAG <= -3) GO TO 640
7751 ! IREDO = 2
7752 ! RHUP = 0.0D0
7753 ! GO TO 540
7754 !-----------------------------------------------------------------------
7755 ! Regardless of the success or failure of the step, factors
7756 ! RHDN, RHSM, and RHUP are computed, by which H could be multiplied
7757 ! at order NQ - 1, order NQ, or order NQ + 1, respectively.
7758 ! in the case of failure, RHUP = 0.0 to avoid an order increase.
7759 ! the largest of these is determined and the new order chosen
7760 ! accordingly. If the order is to be increased, we compute one
7761 ! additional scaled derivative.
7762 !-----------------------------------------------------------------------
7763 ! 520 RHUP = 0.0D0
7764 ! IF (L == LMAX) GO TO 540
7765 ! DO 530 I = 1,N
7766 ! SAVF(I) = ACOR(I) - YH(I,LMAX)
7767 ! 530 END DO
7768 ! DUP = DVNORM (N, SAVF, EWT)/TESCO(3,NQ)
7769 ! EXUP = 1.0D0/(L+1)
7770 ! RHUP = 1.0D0/(1.4D0*DUP**EXUP + 0.0000014D0)
7771 ! 540 EXSM = 1.0D0/L
7772 ! RHSM = 1.0D0/(1.2D0*DSM**EXSM + 0.0000012D0)
7773 ! RHDN = 0.0D0
7774 ! IF (NQ == 1) GO TO 560
7775 ! DDN = DVNORM (N, YH(1,L), EWT)/TESCO(1,NQ)
7776 ! EXDN = 1.0D0/NQ
7777 ! RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
7778 ! 560 IF (RHSM >= RHUP) GO TO 570
7779 ! IF (RHUP > RHDN) GO TO 590
7780 ! GO TO 580
7781 ! 570 IF (RHSM < RHDN) GO TO 580
7782 ! NEWQ = NQ
7783 ! RH = RHSM
7784 ! GO TO 620
7785 ! 580 NEWQ = NQ - 1
7786 ! RH = RHDN
7787 ! IF (KFLAG < 0 .AND. RH > 1.0D0) RH = 1.0D0
7788 ! GO TO 620
7789 ! 590 NEWQ = L
7790 ! RH = RHUP
7791 ! IF (RH < 1.1D0) GO TO 610
7792 ! R = EL(L)/L
7793 ! DO 600 I = 1,N
7794 ! YH(I,NEWQ+1) = ACOR(I)*R
7795 ! 600 END DO
7796 ! GO TO 630
7797 ! 610 IALTH = 3
7798 ! GO TO 700
7799 ! 620 IF ((KFLAG == 0) .AND. (RH < 1.1D0)) GO TO 610
7800 ! IF (KFLAG <= -2) RH = MIN(RH,0.2D0)
7801 !-----------------------------------------------------------------------
7802 ! If there is a change of order, reset NQ, L, and the coefficients.
7803 ! In any case H is reset according to RH and the YH array is rescaled.
7804 ! Then exit from 690 if the step was OK, or redo the step otherwise.
7805 !-----------------------------------------------------------------------
7806 ! IF (NEWQ == NQ) GO TO 170
7807 ! 630 NQ = NEWQ
7808 ! L = NQ + 1
7809 ! IRET = 2
7810 ! GO TO 150
7811 !-----------------------------------------------------------------------
7812 ! Control reaches this section if 3 or more failures have occured.
7813 ! If 10 failures have occurred, exit with KFLAG = -1.
7814 ! It is assumed that the derivatives that have accumulated in the
7815 ! YH array have errors of the wrong order. Hence the first
7816 ! derivative is recomputed, and the order is set to 1. Then
7817 ! H is reduced by a factor of 10, and the step is retried,
7818 ! until it succeeds or H reaches HMIN.
7819 !-----------------------------------------------------------------------
7820 ! 640 IF (KFLAG == -10) GO TO 660
7821 ! RH = 0.1D0
7822 ! RH = MAX(HMIN/ABS(H),RH)
7823 ! H = H*RH
7824 ! DO 645 I = 1,N
7825 ! Y(I) = YH(I,1)
7826 ! 645 END DO
7827 ! CALL F (NEQ, TN, Y, SAVF)
7828 ! NFE = NFE + 1
7829 ! DO 650 I = 1,N
7830 ! YH(I,2) = H*SAVF(I)
7831 ! 650 END DO
7832 ! IPUP = MITER
7833 ! IALTH = 5
7834 ! IF (NQ == 1) GO TO 200
7835 ! NQ = 1
7836 ! L = 2
7837 ! IRET = 3
7838 ! GO TO 150
7839 !-----------------------------------------------------------------------
7840 ! All returns are made through this section. H is saved in HOLD
7841 ! to allow the caller to change H on the next step.
7842 !-----------------------------------------------------------------------
7843 ! 660 KFLAG = -1
7844 ! GO TO 720
7845 ! 670 KFLAG = -2
7846 ! GO TO 720
7847 ! 680 KFLAG = -3
7848 ! GO TO 720
7849 ! 690 RMAX = 10.0D0
7850 ! 700 R = 1.0D0/TESCO(2,NQU)
7851 ! DO 710 I = 1,N
7852 ! ACOR(I) = ACOR(I)*R
7853 ! 710 END DO
7854 ! 720 HOLD = H
7855 ! JSTART = 1
7856 ! RETURN
7857 !----------------------- End of Subroutine DSTOKA ----------------------
7858 ! END SUBROUTINE DSTOKA
7859 ! ECK DSETPK
7860 ! SUBROUTINE DSETPK (NEQ, Y, YSV, EWT, FTEM, SAVF, JOK, WM, IWM, &
7861 ! F, JAC)
7862 ! EXTERNAL F, JAC
7863 ! INTEGER :: NEQ, JOK, IWM
7864 ! DOUBLE PRECISION :: Y, YSV, EWT, FTEM, SAVF, WM
7865 ! DIMENSION NEQ(*), Y(*), YSV(*), EWT(*), FTEM(*), SAVF(*), &
7866 ! WM(*), IWM(*)
7867 ! INTEGER :: IOWND, IOWNS, &
7868 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
7869 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
7870 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
7871 ! INTEGER :: JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
7872 ! NNI, NLI, NPS, NCFN, NCFL
7873 ! DOUBLE PRECISION :: ROWNS, &
7874 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
7875 ! DOUBLE PRECISION :: DELT, EPCON, SQRTN, RSQRTN
7876 ! COMMON /DLS001/ ROWNS(209), &
7877 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
7878 ! IOWND(6), IOWNS(6), &
7879 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
7880 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
7881 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
7882 ! COMMON /DLPK01/ DELT, EPCON, SQRTN, RSQRTN, &
7883 ! JPRE, JACFLG, LOCWP, LOCIWP, LSAVX, KMP, MAXL, MNEWT, &
7884 ! NNI, NLI, NPS, NCFN, NCFL
7885 !-----------------------------------------------------------------------
7886 ! DSETPK is called by DSTOKA to interface with the user-supplied
7887 ! routine JAC, to compute and process relevant parts of
7888 ! the matrix P = I - H*EL(1)*J , where J is the Jacobian df/dy,
7889 ! as need for preconditioning matrix operations later.
7890 ! In addition to variables described previously, communication
7891 ! with DSETPK uses the following:
7892 ! Y = array containing predicted values on entry.
7893 ! YSV = array containing predicted y, to be saved (YH1 in DSTOKA).
7894 ! FTEM = work array of length N (ACOR in DSTOKA).
7895 ! SAVF = array containing f evaluated at predicted y.
7896 ! JOK = input flag showing whether it was judged that Jacobian matrix
7897 ! data need not be recomputed (JOK = 1) or needs to be
7898 ! (JOK = -1).
7899 ! WM = real work space for matrices.
7900 ! Space for preconditioning data starts at WM(LOCWP).
7901 ! IWM = integer work space.
7902 ! Space for preconditioning data starts at IWM(LOCIWP).
7903 ! IERPJ = output error flag, = 0 if no trouble, .gt. 0 if
7904 ! JAC returned an error flag.
7905 ! JCUR = output flag to indicate whether the matrix data involved
7906 ! is now current (JCUR = 1) or not (JCUR = 0).
7907 ! This routine also uses Common variables EL0, H, TN, IERPJ, JCUR, NJE.
7908 !-----------------------------------------------------------------------
7909 ! INTEGER :: IER
7910 ! DOUBLE PRECISION :: HL0
7911 ! IERPJ = 0
7912 ! JCUR = 0
7913 ! IF (JOK == -1) JCUR = 1
7914 ! HL0 = EL0*H
7915 ! CALL JAC (F, NEQ, TN, Y, YSV, EWT, SAVF, FTEM, HL0, JOK, &
7916 ! WM(LOCWP), IWM(LOCIWP), IER)
7917 ! NJE = NJE + 1
7918 ! IF (IER == 0) RETURN
7919 ! IERPJ = 1
7920 ! RETURN
7921 !----------------------- End of Subroutine DSETPK ----------------------
7922 ! END SUBROUTINE DSETPK
7923 ! ECK DSRCKR
7924 ! SUBROUTINE DSRCKR (RSAV, ISAV, JOB)
7925 !-----------------------------------------------------------------------
7926 ! This routine saves or restores (depending on JOB) the contents of
7927 ! the Common blocks DLS001, DLS002, DLSR01, DLPK01, which
7928 ! are used internally by the DLSODKR solver.
7929 ! RSAV = real array of length 228 or more.
7930 ! ISAV = integer array of length 63 or more.
7931 ! JOB = flag indicating to save or restore the Common blocks:
7932 ! JOB = 1 if Common is to be saved (written to RSAV/ISAV)
7933 ! JOB = 2 if Common is to be restored (read from RSAV/ISAV)
7934 ! A call with JOB = 2 presumes a prior call with JOB = 1.
7935 !-----------------------------------------------------------------------
7936 ! INTEGER :: ISAV, JOB
7937 ! INTEGER :: ILS, ILS2, ILSR, ILSP
7938 ! INTEGER :: I, IOFF, LENILP, LENRLP, LENILS, LENRLS, LENILR, LENRLR
7939 ! DOUBLE PRECISION :: RSAV, RLS, RLS2, RLSR, RLSP
7940 ! DIMENSION RSAV(*), ISAV(*)
7941 ! SAVE LENRLS, LENILS, LENRLP, LENILP, LENRLR, LENILR
7942 ! COMMON /DLS001/ RLS(218), ILS(37)
7943 ! COMMON /DLS002/ RLS2, ILS2(4)
7944 ! COMMON /DLSR01/ RLSR(5), ILSR(9)
7945 ! COMMON /DLPK01/ RLSP(4), ILSP(13)
7946 ! DATA LENRLS/218/, LENILS/37/, LENRLP/4/, LENILP/13/
7947 ! DATA LENRLR/5/, LENILR/9/
7948 ! IF (JOB == 2) GO TO 100
7949 ! CALL DCOPY (LENRLS, RLS, 1, RSAV, 1)
7950 ! RSAV(LENRLS+1) = RLS2
7951 ! CALL DCOPY (LENRLR, RLSR, 1, RSAV(LENRLS+2), 1)
7952 ! CALL DCOPY (LENRLP, RLSP, 1, RSAV(LENRLS+LENRLR+2), 1)
7953 ! DO 20 I = 1,LENILS
7954 ! ISAV(I) = ILS(I)
7955 ! 20 END DO
7956 ! ISAV(LENILS+1) = ILS2(1)
7957 ! ISAV(LENILS+2) = ILS2(2)
7958 ! ISAV(LENILS+3) = ILS2(3)
7959 ! ISAV(LENILS+4) = ILS2(4)
7960 ! IOFF = LENILS + 2
7961 ! DO 30 I = 1,LENILR
7962 ! ISAV(IOFF+I) = ILSR(I)
7963 ! 30 END DO
7964 ! IOFF = IOFF + LENILR
7965 ! DO 40 I = 1,LENILP
7966 ! ISAV(IOFF+I) = ILSP(I)
7967 ! 40 END DO
7968 ! RETURN
7969 ! 100 CONTINUE
7970 ! CALL DCOPY (LENRLS, RSAV, 1, RLS, 1)
7971 ! RLS2 = RSAV(LENRLS+1)
7972 ! CALL DCOPY (LENRLR, RSAV(LENRLS+2), 1, RLSR, 1)
7973 ! CALL DCOPY (LENRLP, RSAV(LENRLS+LENRLR+2), 1, RLSP, 1)
7974 ! DO 120 I = 1,LENILS
7975 ! ILS(I) = ISAV(I)
7976 ! 120 END DO
7977 ! ILS2(1) = ISAV(LENILS+1)
7978 ! ILS2(2) = ISAV(LENILS+2)
7979 ! ILS2(3) = ISAV(LENILS+3)
7980 ! ILS2(4) = ISAV(LENILS+4)
7981 ! IOFF = LENILS + 2
7982 ! DO 130 I = 1,LENILR
7983 ! ILSR(I) = ISAV(IOFF+I)
7984 ! 130 END DO
7985 ! IOFF = IOFF + LENILR
7986 ! DO 140 I = 1,LENILP
7987 ! ILSP(I) = ISAV(IOFF+I)
7988 ! 140 END DO
7989 ! RETURN
7990 !----------------------- End of Subroutine DSRCKR ----------------------
7991 ! END SUBROUTINE DSRCKR
7992 ! ECK DAINVG
7993 ! SUBROUTINE DAINVG (RES, ADDA, NEQ, T, Y, YDOT, MITER, &
7994 ! ML, MU, PW, IPVT, IER )
7995 ! EXTERNAL RES, ADDA
7996 ! INTEGER :: NEQ, MITER, ML, MU, IPVT, IER
7997 ! INTEGER :: I, LENPW, MLP1, NROWPW
7998 ! DOUBLE PRECISION :: T, Y, YDOT, PW
7999 ! DIMENSION Y(*), YDOT(*), PW(*), IPVT(*)
8000 !-----------------------------------------------------------------------
8001 ! This subroutine computes the initial value
8002 ! of the vector YDOT satisfying
8003 ! A * YDOT = g(t,y)
8004 ! when A is nonsingular. It is called by DLSODI for
8005 ! initialization only, when ISTATE = 0 .
8006 ! DAINVG returns an error flag IER:
8007 ! IER = 0 means DAINVG was successful.
8008 ! IER .ge. 2 means RES returned an error flag IRES = IER.
8009 ! IER .lt. 0 means the a-matrix was found to be singular.
8010 !-----------------------------------------------------------------------
8011 ! IF (MITER >= 4) GO TO 100
8012 ! Full matrix case -----------------------------------------------------
8013 ! LENPW = NEQ*NEQ
8014 ! DO 10 I = 1, LENPW
8015 ! PW(I) = 0.0D0
8016 ! 10 END DO
8017 ! IER = 1
8018 ! CALL RES ( NEQ, T, Y, PW, YDOT, IER )
8019 ! IF (IER > 1) RETURN
8020 ! CALL ADDA ( NEQ, T, Y, 0, 0, PW, NEQ )
8021 ! CALL DGEFA ( PW, NEQ, NEQ, IPVT, IER )
8022 ! IF (IER == 0) GO TO 20
8023 ! IER = -IER
8024 ! RETURN
8025 ! 20 CALL DGESL ( PW, NEQ, NEQ, IPVT, YDOT, 0 )
8026 ! RETURN
8027 ! Band matrix case -----------------------------------------------------
8028 ! 100 CONTINUE
8029 ! NROWPW = 2*ML + MU + 1
8030 ! LENPW = NEQ * NROWPW
8031 ! DO 110 I = 1, LENPW
8032 ! PW(I) = 0.0D0
8033 ! 110 END DO
8034 ! IER = 1
8035 ! CALL RES ( NEQ, T, Y, PW, YDOT, IER )
8036 ! IF (IER > 1) RETURN
8037 ! MLP1 = ML + 1
8038 ! CALL ADDA ( NEQ, T, Y, ML, MU, PW(MLP1), NROWPW )
8039 ! CALL DGBFA ( PW, NROWPW, NEQ, ML, MU, IPVT, IER )
8040 ! IF (IER == 0) GO TO 120
8041 ! IER = -IER
8042 ! RETURN
8043 ! 120 CALL DGBSL ( PW, NROWPW, NEQ, ML, MU, IPVT, YDOT, 0 )
8044 ! RETURN
8045 !----------------------- End of Subroutine DAINVG ----------------------
8046 ! END SUBROUTINE DAINVG
8047 ! ECK DSTODI
8048 ! SUBROUTINE DSTODI (NEQ, Y, YH, NYH, YH1, EWT, SAVF, SAVR, &
8049 ! ACOR, WM, IWM, RES, ADDA, JAC, PJAC, SLVS )
8050 ! EXTERNAL RES, ADDA, JAC, PJAC, SLVS
8051 ! INTEGER :: NEQ, NYH, IWM
8052 ! DOUBLE PRECISION :: Y, YH, YH1, EWT, SAVF, SAVR, ACOR, WM
8053 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), YH1(*), EWT(*), SAVF(*), &
8054 ! SAVR(*), ACOR(*), WM(*), IWM(*)
8055 ! INTEGER :: IOWND, IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, &
8056 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
8057 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
8058 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
8059 ! DOUBLE PRECISION :: CONIT, CRATE, EL, ELCO, HOLD, RMAX, TESCO, &
8060 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
8061 ! COMMON /DLS001/ CONIT, CRATE, EL(13), ELCO(13,12), &
8062 ! HOLD, RMAX, TESCO(3,12), &
8063 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
8064 ! IOWND(6), IALTH, IPUP, LMAX, MEO, NQNYH, NSLP, &
8065 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
8066 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
8067 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
8068 ! INTEGER :: I, I1, IREDO, IRES, IRET, J, JB, KGO, M, NCF, NEWQ
8069 ! DOUBLE PRECISION :: DCON, DDN, DEL, DELP, DSM, DUP, &
8070 ! ELJH, EL1H, EXDN, EXSM, EXUP, &
8071 ! R, RH, RHDN, RHSM, RHUP, TOLD, DVNORM
8072 !-----------------------------------------------------------------------
8073 ! DSTODI performs one step of the integration of an initial value
8074 ! problem for a system of Ordinary Differential Equations.
8075 ! Note: DSTODI is independent of the value of the iteration method
8076 ! indicator MITER, and hence is independent
8077 ! of the type of chord method used, or the Jacobian structure.
8078 ! Communication with DSTODI is done with the following variables:
8079 ! NEQ = integer array containing problem size in NEQ(1), and
8080 ! passed as the NEQ argument in all calls to RES, ADDA,
8081 ! and JAC.
8082 ! Y = an array of length .ge. N used as the Y argument in
8083 ! all calls to RES, JAC, and ADDA.
8084 ! NEQ = integer array containing problem size in NEQ(1), and
8085 ! passed as the NEQ argument in all calls tO RES, G, ADDA,
8086 ! and JAC.
8087 ! YH = an NYH by LMAX array containing the dependent variables
8088 ! and their approximate scaled derivatives, where
8089 ! LMAX = MAXORD + 1. YH(i,j+1) contains the approximate
8090 ! j-th derivative of y(i), scaled by H**j/factorial(j)
8091 ! (j = 0,1,...,NQ). On entry for the first step, the first
8092 ! two columns of YH must be set from the initial values.
8093 ! NYH = a constant integer .ge. N, the first dimension of YH.
8094 ! YH1 = a one-dimensional array occupying the same space as YH.
8095 ! EWT = an array of length N containing multiplicative weights
8096 ! for local error measurements. Local errors in y(i) are
8097 ! compared to 1.0/EWT(i) in various error tests.
8098 ! SAVF = an array of working storage, of length N. also used for
8099 ! input of YH(*,MAXORD+2) when JSTART = -1 and MAXORD is less
8100 ! than the current order NQ.
8101 ! Same as YDOTI in the driver.
8102 ! SAVR = an array of working storage, of length N.
8103 ! ACOR = a work array of length N used for the accumulated
8104 ! corrections. On a succesful return, ACOR(i) contains
8105 ! the estimated one-step local error in y(i).
8106 ! WM,IWM = real and integer work arrays associated with matrix
8107 ! operations in chord iteration.
8108 ! PJAC = name of routine to evaluate and preprocess Jacobian matrix.
8109 ! SLVS = name of routine to solve linear system in chord iteration.
8110 ! CCMAX = maximum relative change in H*EL0 before PJAC is called.
8111 ! H = the step size to be attempted on the next step.
8112 ! H is altered by the error control algorithm during the
8113 ! problem. H can be either positive or negative, but its
8114 ! sign must remain constant throughout the problem.
8115 ! HMIN = the minimum absolute value of the step size H to be used.
8116 ! HMXI = inverse of the maximum absolute value of H to be used.
8117 ! HMXI = 0.0 is allowed and corresponds to an infinite HMAX.
8118 ! HMIN and HMXI may be changed at any time, but will not
8119 ! take effect until the next change of H is considered.
8120 ! TN = the independent variable. TN is updated on each step taken.
8121 ! JSTART = an integer used for input only, with the following
8122 ! values and meanings:
8123 ! 0 perform the first step.
8124 ! .gt.0 take a new step continuing from the last.
8125 ! -1 take the next step with a new value of H, MAXORD,
8126 ! N, METH, MITER, and/or matrix parameters.
8127 ! -2 take the next step with a new value of H,
8128 ! but with other inputs unchanged.
8129 ! On return, JSTART is set to 1 to facilitate continuation.
8130 ! KFLAG = a completion code with the following meanings:
8131 ! 0 the step was succesful.
8132 ! -1 the requested error could not be achieved.
8133 ! -2 corrector convergence could not be achieved.
8134 ! -3 RES ordered immediate return.
8135 ! -4 error condition from RES could not be avoided.
8136 ! -5 fatal error in PJAC or SLVS.
8137 ! A return with KFLAG = -1, -2, or -4 means either
8138 ! ABS(H) = HMIN or 10 consecutive failures occurred.
8139 ! On a return with KFLAG negative, the values of TN and
8140 ! the YH array are as of the beginning of the last
8141 ! step, and H is the last step size attempted.
8142 ! MAXORD = the maximum order of integration method to be allowed.
8143 ! MAXCOR = the maximum number of corrector iterations allowed.
8144 ! MSBP = maximum number of steps between PJAC calls.
8145 ! MXNCF = maximum number of convergence failures allowed.
8146 ! METH/MITER = the method flags. See description in driver.
8147 ! N = the number of first-order differential equations.
8148 !-----------------------------------------------------------------------
8149 ! KFLAG = 0
8150 ! TOLD = TN
8151 ! NCF = 0
8152 ! IERPJ = 0
8153 ! IERSL = 0
8154 ! JCUR = 0
8155 ! ICF = 0
8156 ! DELP = 0.0D0
8157 ! IF (JSTART > 0) GO TO 200
8158 ! IF (JSTART == -1) GO TO 100
8159 ! IF (JSTART == -2) GO TO 160
8160 !-----------------------------------------------------------------------
8161 ! On the first call, the order is set to 1, and other variables are
8162 ! initialized. RMAX is the maximum ratio by which H can be increased
8163 ! in a single step. It is initially 1.E4 to compensate for the small
8164 ! initial H, but then is normally equal to 10. If a failure
8165 ! occurs (in corrector convergence or error test), RMAX is set at 2
8166 ! for the next increase.
8167 !-----------------------------------------------------------------------
8168 ! LMAX = MAXORD + 1
8169 ! NQ = 1
8170 ! L = 2
8171 ! IALTH = 2
8172 ! RMAX = 10000.0D0
8173 ! RC = 0.0D0
8174 ! EL0 = 1.0D0
8175 ! CRATE = 0.7D0
8176 ! HOLD = H
8177 ! MEO = METH
8178 ! NSLP = 0
8179 ! IPUP = MITER
8180 ! IRET = 3
8181 ! GO TO 140
8182 !-----------------------------------------------------------------------
8183 ! The following block handles preliminaries needed when JSTART = -1.
8184 ! IPUP is set to MITER to force a matrix update.
8185 ! If an order increase is about to be considered (IALTH = 1),
8186 ! IALTH is reset to 2 to postpone consideration one more step.
8187 ! If the caller has changed METH, DCFODE is called to reset
8188 ! the coefficients of the method.
8189 ! If the caller has changed MAXORD to a value less than the current
8190 ! order NQ, NQ is reduced to MAXORD, and a new H chosen accordingly.
8191 ! If H is to be changed, YH must be rescaled.
8192 ! If H or METH is being changed, IALTH is reset to L = NQ + 1
8193 ! to prevent further changes in H for that many steps.
8194 !-----------------------------------------------------------------------
8195 ! 100 IPUP = MITER
8196 ! LMAX = MAXORD + 1
8197 ! IF (IALTH == 1) IALTH = 2
8198 ! IF (METH == MEO) GO TO 110
8199 ! CALL DCFODE (METH, ELCO, TESCO)
8200 ! MEO = METH
8201 ! IF (NQ > MAXORD) GO TO 120
8202 ! IALTH = L
8203 ! IRET = 1
8204 ! GO TO 150
8205 ! 110 IF (NQ <= MAXORD) GO TO 160
8206 ! 120 NQ = MAXORD
8207 ! L = LMAX
8208 ! DO 125 I = 1,L
8209 ! EL(I) = ELCO(I,NQ)
8210 ! 125 END DO
8211 ! NQNYH = NQ*NYH
8212 ! RC = RC*EL(1)/EL0
8213 ! EL0 = EL(1)
8214 ! CONIT = 0.5D0/(NQ+2)
8215 ! DDN = DVNORM (N, SAVF, EWT)/TESCO(1,L)
8216 ! EXDN = 1.0D0/L
8217 ! RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
8218 ! RH = MIN(RHDN,1.0D0)
8219 ! IREDO = 3
8220 ! IF (H == HOLD) GO TO 170
8221 ! RH = MIN(RH,ABS(H/HOLD))
8222 ! H = HOLD
8223 ! GO TO 175
8224 !-----------------------------------------------------------------------
8225 ! DCFODE is called to get all the integration coefficients for the
8226 ! current METH. Then the EL vector and related constants are reset
8227 ! whenever the order NQ is changed, or at the start of the problem.
8228 !-----------------------------------------------------------------------
8229 ! 140 CALL DCFODE (METH, ELCO, TESCO)
8230 ! 150 DO 155 I = 1,L
8231 ! EL(I) = ELCO(I,NQ)
8232 ! 155 END DO
8233 ! NQNYH = NQ*NYH
8234 ! RC = RC*EL(1)/EL0
8235 ! EL0 = EL(1)
8236 ! CONIT = 0.5D0/(NQ+2)
8237 ! GO TO (160, 170, 200), IRET
8238 !-----------------------------------------------------------------------
8239 ! If H is being changed, the H ratio RH is checked against
8240 ! RMAX, HMIN, and HMXI, and the YH array rescaled. IALTH is set to
8241 ! L = NQ + 1 to prevent a change of H for that many steps, unless
8242 ! forced by a convergence or error test failure.
8243 !-----------------------------------------------------------------------
8244 ! 160 IF (H == HOLD) GO TO 200
8245 ! RH = H/HOLD
8246 ! H = HOLD
8247 ! IREDO = 3
8248 ! GO TO 175
8249 ! 170 RH = MAX(RH,HMIN/ABS(H))
8250 ! 175 RH = MIN(RH,RMAX)
8251 ! RH = RH/MAX(1.0D0,ABS(H)*HMXI*RH)
8252 ! R = 1.0D0
8253 ! DO 180 J = 2,L
8254 ! R = R*RH
8255 ! DO 180 I = 1,N
8256 ! YH(I,J) = YH(I,J)*R
8257 ! 180 END DO
8258 ! H = H*RH
8259 ! RC = RC*RH
8260 ! IALTH = L
8261 ! IF (IREDO == 0) GO TO 690
8262 !-----------------------------------------------------------------------
8263 ! This section computes the predicted values by effectively
8264 ! multiplying the YH array by the Pascal triangle matrix.
8265 ! RC is the ratio of new to old values of the coefficient H*EL(1).
8266 ! When RC differs from 1 by more than CCMAX, IPUP is set to MITER
8267 ! to force PJAC to be called.
8268 ! In any case, PJAC is called at least every MSBP steps.
8269 !-----------------------------------------------------------------------
8270 ! 200 IF (ABS(RC-1.0D0) > CCMAX) IPUP = MITER
8271 ! IF (NST >= NSLP+MSBP) IPUP = MITER
8272 ! TN = TN + H
8273 ! I1 = NQNYH + 1
8274 ! DO 215 JB = 1,NQ
8275 ! I1 = I1 - NYH
8276 ! ! IR$ IVDEP
8277 ! DO 210 I = I1,NQNYH
8278 ! YH1(I) = YH1(I) + YH1(I+NYH)
8279 ! 210 END DO
8280 ! 215 END DO
8281 !-----------------------------------------------------------------------
8282 ! Up to MAXCOR corrector iterations are taken. A convergence test is
8283 ! made on the RMS-norm of each correction, weighted by H and the
8284 ! error weight vector EWT. The sum of the corrections is accumulated
8285 ! in ACOR(i). The YH array is not altered in the corrector loop.
8286 !-----------------------------------------------------------------------
8287 ! 220 M = 0
8288 ! DO 230 I = 1,N
8289 ! SAVF(I) = YH(I,2) / H
8290 ! Y(I) = YH(I,1)
8291 ! 230 END DO
8292 ! IF (IPUP <= 0) GO TO 240
8293 !-----------------------------------------------------------------------
8294 ! If indicated, the matrix P = A - H*EL(1)*dr/dy is reevaluated and
8295 ! preprocessed before starting the corrector iteration. IPUP is set
8296 ! to 0 as an indicator that this has been done.
8297 !-----------------------------------------------------------------------
8298 ! CALL PJAC (NEQ, Y, YH, NYH, EWT, ACOR, SAVR, SAVF, WM, IWM, &
8299 ! RES, JAC, ADDA )
8300 ! IPUP = 0
8301 ! RC = 1.0D0
8302 ! NSLP = NST
8303 ! CRATE = 0.7D0
8304 ! IF (IERPJ == 0) GO TO 250
8305 ! IF (IERPJ < 0) GO TO 435
8306 ! IRES = IERPJ
8307 ! GO TO (430, 435, 430), IRES
8308 ! Get residual at predicted values, if not already done in PJAC. -------
8309 ! 240 IRES = 1
8310 ! CALL RES ( NEQ, TN, Y, SAVF, SAVR, IRES )
8311 ! NFE = NFE + 1
8312 ! KGO = ABS(IRES)
8313 ! GO TO ( 250, 435, 430 ) , KGO
8314 ! 250 DO 260 I = 1,N
8315 ! ACOR(I) = 0.0D0
8316 ! 260 END DO
8317 !-----------------------------------------------------------------------
8318 ! Solve the linear system with the current residual as
8319 ! right-hand side and P as coefficient matrix.
8320 !-----------------------------------------------------------------------
8321 ! 270 CONTINUE
8322 ! CALL SLVS (WM, IWM, SAVR, SAVF)
8323 ! IF (IERSL < 0) GO TO 430
8324 ! IF (IERSL > 0) GO TO 410
8325 ! EL1H = EL(1) * H
8326 ! DEL = DVNORM (N, SAVR, EWT) * ABS(H)
8327 ! DO 380 I = 1,N
8328 ! ACOR(I) = ACOR(I) + SAVR(I)
8329 ! SAVF(I) = ACOR(I) + YH(I,2)/H
8330 ! Y(I) = YH(I,1) + EL1H*ACOR(I)
8331 ! 380 END DO
8332 !-----------------------------------------------------------------------
8333 ! Test for convergence. If M .gt. 0, an estimate of the convergence
8334 ! rate constant is stored in CRATE, and this is used in the test.
8335 !-----------------------------------------------------------------------
8336 ! IF (M /= 0) CRATE = MAX(0.2D0*CRATE,DEL/DELP)
8337 ! DCON = DEL*MIN(1.0D0,1.5D0*CRATE)/(TESCO(2,NQ)*CONIT)
8338 ! IF (DCON <= 1.0D0) GO TO 460
8339 ! M = M + 1
8340 ! IF (M == MAXCOR) GO TO 410
8341 ! IF (M >= 2 .AND. DEL > 2.0D0*DELP) GO TO 410
8342 ! DELP = DEL
8343 ! IRES = 1
8344 ! CALL RES ( NEQ, TN, Y, SAVF, SAVR, IRES )
8345 ! NFE = NFE + 1
8346 ! KGO = ABS(IRES)
8347 ! GO TO ( 270, 435, 410 ) , KGO
8348 !-----------------------------------------------------------------------
8349 ! The correctors failed to converge, or RES has returned abnormally.
8350 ! on a convergence failure, if the Jacobian is out of date, PJAC is
8351 ! called for the next try. Otherwise the YH array is retracted to its
8352 ! values before prediction, and H is reduced, if possible.
8353 ! take an error exit if IRES = 2, or H cannot be reduced, or MXNCF
8354 ! failures have occurred, or a fatal error occurred in PJAC or SLVS.
8355 !-----------------------------------------------------------------------
8356 ! 410 ICF = 1
8357 ! IF (JCUR == 1) GO TO 430
8358 ! IPUP = MITER
8359 ! GO TO 220
8360 ! 430 ICF = 2
8361 ! NCF = NCF + 1
8362 ! RMAX = 2.0D0
8363 ! 435 TN = TOLD
8364 ! I1 = NQNYH + 1
8365 ! DO 445 JB = 1,NQ
8366 ! I1 = I1 - NYH
8367 ! ! IR$ IVDEP
8368 ! DO 440 I = I1,NQNYH
8369 ! YH1(I) = YH1(I) - YH1(I+NYH)
8370 ! 440 END DO
8371 ! 445 END DO
8372 ! IF (IRES == 2) GO TO 680
8373 ! IF (IERPJ < 0 .OR. IERSL < 0) GO TO 685
8374 ! IF (ABS(H) <= HMIN*1.00001D0) GO TO 450
8375 ! IF (NCF == MXNCF) GO TO 450
8376 ! RH = 0.25D0
8377 ! IPUP = MITER
8378 ! IREDO = 1
8379 ! GO TO 170
8380 ! 450 IF (IRES == 3) GO TO 680
8381 ! GO TO 670
8382 !-----------------------------------------------------------------------
8383 ! The corrector has converged. JCUR is set to 0
8384 ! to signal that the Jacobian involved may need updating later.
8385 ! The local error test is made and control passes to statement 500
8386 ! if it fails.
8387 !-----------------------------------------------------------------------
8388 ! 460 JCUR = 0
8389 ! IF (M == 0) DSM = DEL/TESCO(2,NQ)
8390 ! IF (M > 0) DSM = ABS(H) * DVNORM (N, ACOR, EWT)/TESCO(2,NQ)
8391 ! IF (DSM > 1.0D0) GO TO 500
8392 !-----------------------------------------------------------------------
8393 ! After a successful step, update the YH array.
8394 ! Consider changing H if IALTH = 1. Otherwise decrease IALTH by 1.
8395 ! If IALTH is then 1 and NQ .lt. MAXORD, then ACOR is saved for
8396 ! use in a possible order increase on the next step.
8397 ! If a change in H is considered, an increase or decrease in order
8398 ! by one is considered also. A change in H is made only if it is by a
8399 ! factor of at least 1.1. If not, IALTH is set to 3 to prevent
8400 ! testing for that many steps.
8401 !-----------------------------------------------------------------------
8402 ! KFLAG = 0
8403 ! IREDO = 0
8404 ! NST = NST + 1
8405 ! HU = H
8406 ! NQU = NQ
8407 ! DO 470 J = 1,L
8408 ! ELJH = EL(J)*H
8409 ! DO 470 I = 1,N
8410 ! YH(I,J) = YH(I,J) + ELJH*ACOR(I)
8411 ! 470 END DO
8412 ! IALTH = IALTH - 1
8413 ! IF (IALTH == 0) GO TO 520
8414 ! IF (IALTH > 1) GO TO 700
8415 ! IF (L == LMAX) GO TO 700
8416 ! DO 490 I = 1,N
8417 ! YH(I,LMAX) = ACOR(I)
8418 ! 490 END DO
8419 ! GO TO 700
8420 !-----------------------------------------------------------------------
8421 ! The error test failed. KFLAG keeps track of multiple failures.
8422 ! restore TN and the YH array to their previous values, and prepare
8423 ! to try the step again. Compute the optimum step size for this or
8424 ! one lower order. After 2 or more failures, H is forced to decrease
8425 ! by a factor of 0.1 or less.
8426 !-----------------------------------------------------------------------
8427 ! 500 KFLAG = KFLAG - 1
8428 ! TN = TOLD
8429 ! I1 = NQNYH + 1
8430 ! DO 515 JB = 1,NQ
8431 ! I1 = I1 - NYH
8432 ! ! IR$ IVDEP
8433 ! DO 510 I = I1,NQNYH
8434 ! YH1(I) = YH1(I) - YH1(I+NYH)
8435 ! 510 END DO
8436 ! 515 END DO
8437 ! RMAX = 2.0D0
8438 ! IF (ABS(H) <= HMIN*1.00001D0) GO TO 660
8439 ! IF (KFLAG <= -7) GO TO 660
8440 ! IREDO = 2
8441 ! RHUP = 0.0D0
8442 ! GO TO 540
8443 !-----------------------------------------------------------------------
8444 ! Regardless of the success or failure of the step, factors
8445 ! RHDN, RHSM, and RHUP are computed, by which H could be multiplied
8446 ! at order NQ - 1, order NQ, or order NQ + 1, respectively.
8447 ! In the case of failure, RHUP = 0.0 to avoid an order increase.
8448 ! The largest of these is determined and the new order chosen
8449 ! accordingly. If the order is to be increased, we compute one
8450 ! additional scaled derivative.
8451 !-----------------------------------------------------------------------
8452 ! 520 RHUP = 0.0D0
8453 ! IF (L == LMAX) GO TO 540
8454 ! DO 530 I = 1,N
8455 ! SAVF(I) = ACOR(I) - YH(I,LMAX)
8456 ! 530 END DO
8457 ! DUP = ABS(H) * DVNORM (N, SAVF, EWT)/TESCO(3,NQ)
8458 ! EXUP = 1.0D0/(L+1)
8459 ! RHUP = 1.0D0/(1.4D0*DUP**EXUP + 0.0000014D0)
8460 ! 540 EXSM = 1.0D0/L
8461 ! RHSM = 1.0D0/(1.2D0*DSM**EXSM + 0.0000012D0)
8462 ! RHDN = 0.0D0
8463 ! IF (NQ == 1) GO TO 560
8464 ! DDN = DVNORM (N, YH(1,L), EWT)/TESCO(1,NQ)
8465 ! EXDN = 1.0D0/NQ
8466 ! RHDN = 1.0D0/(1.3D0*DDN**EXDN + 0.0000013D0)
8467 ! 560 IF (RHSM >= RHUP) GO TO 570
8468 ! IF (RHUP > RHDN) GO TO 590
8469 ! GO TO 580
8470 ! 570 IF (RHSM < RHDN) GO TO 580
8471 ! NEWQ = NQ
8472 ! RH = RHSM
8473 ! GO TO 620
8474 ! 580 NEWQ = NQ - 1
8475 ! RH = RHDN
8476 ! IF (KFLAG < 0 .AND. RH > 1.0D0) RH = 1.0D0
8477 ! GO TO 620
8478 ! 590 NEWQ = L
8479 ! RH = RHUP
8480 ! IF (RH < 1.1D0) GO TO 610
8481 ! R = H*EL(L)/L
8482 ! DO 600 I = 1,N
8483 ! YH(I,NEWQ+1) = ACOR(I)*R
8484 ! 600 END DO
8485 ! GO TO 630
8486 ! 610 IALTH = 3
8487 ! GO TO 700
8488 ! 620 IF ((KFLAG == 0) .AND. (RH < 1.1D0)) GO TO 610
8489 ! IF (KFLAG <= -2) RH = MIN(RH,0.1D0)
8490 !-----------------------------------------------------------------------
8491 ! If there is a change of order, reset NQ, L, and the coefficients.
8492 ! In any case H is reset according to RH and the YH array is rescaled.
8493 ! Then exit from 690 if the step was OK, or redo the step otherwise.
8494 !-----------------------------------------------------------------------
8495 ! IF (NEWQ == NQ) GO TO 170
8496 ! 630 NQ = NEWQ
8497 ! L = NQ + 1
8498 ! IRET = 2
8499 ! GO TO 150
8500 !-----------------------------------------------------------------------
8501 ! All returns are made through this section. H is saved in HOLD
8502 ! to allow the caller to change H on the next step.
8503 !-----------------------------------------------------------------------
8504 ! 660 KFLAG = -1
8505 ! GO TO 720
8506 ! 670 KFLAG = -2
8507 ! GO TO 720
8508 ! 680 KFLAG = -1 - IRES
8509 ! GO TO 720
8510 ! 685 KFLAG = -5
8511 ! GO TO 720
8512 ! 690 RMAX = 10.0D0
8513 ! 700 R = H/TESCO(2,NQU)
8514 ! DO 710 I = 1,N
8515 ! ACOR(I) = ACOR(I)*R
8516 ! 710 END DO
8517 ! 720 HOLD = H
8518 ! JSTART = 1
8519 ! RETURN
8520 !----------------------- End of Subroutine DSTODI ----------------------
8521 ! END SUBROUTINE DSTODI
8522 ! ECK DPREPJI
8523 ! SUBROUTINE DPREPJI (NEQ, Y, YH, NYH, EWT, RTEM, SAVR, S, WM, IWM, &
8524 ! RES, JAC, ADDA)
8525 ! EXTERNAL RES, JAC, ADDA
8526 ! INTEGER :: NEQ, NYH, IWM
8527 ! DOUBLE PRECISION :: Y, YH, EWT, RTEM, SAVR, S, WM
8528 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), EWT(*), RTEM(*), &
8529 ! S(*), SAVR(*), WM(*), IWM(*)
8530 ! INTEGER :: IOWND, IOWNS, &
8531 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
8532 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
8533 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
8534 ! DOUBLE PRECISION :: ROWNS, &
8535 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
8536 ! COMMON /DLS001/ ROWNS(209), &
8537 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
8538 ! IOWND(6), IOWNS(6), &
8539 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
8540 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
8541 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
8542 ! INTEGER :: I, I1, I2, IER, II, IRES, J, J1, JJ, LENP, &
8543 ! MBA, MBAND, MEB1, MEBAND, ML, ML3, MU
8544 ! DOUBLE PRECISION :: CON, FAC, HL0, R, SRUR, YI, YJ, YJJ
8545 !-----------------------------------------------------------------------
8546 ! DPREPJI is called by DSTODI to compute and process the matrix
8547 ! P = A - H*EL(1)*J , where J is an approximation to the Jacobian dr/dy,
8548 ! where r = g(t,y) - A(t,y)*s. Here J is computed by the user-supplied
8549 ! routine JAC if MITER = 1 or 4, or by finite differencing if MITER =
8550 ! 2 or 5. J is stored in WM, rescaled, and ADDA is called to generate
8551 ! P. P is then subjected to LU decomposition in preparation
8552 ! for later solution of linear systems with P as coefficient
8553 ! matrix. This is done by DGEFA if MITER = 1 or 2, and by
8554 ! DGBFA if MITER = 4 or 5.
8555 ! In addition to variables described previously, communication
8556 ! with DPREPJI uses the following:
8557 ! Y = array containing predicted values on entry.
8558 ! RTEM = work array of length N (ACOR in DSTODI).
8559 ! SAVR = array used for output only. On output it contains the
8560 ! residual evaluated at current values of t and y.
8561 ! S = array containing predicted values of dy/dt (SAVF in DSTODI).
8562 ! WM = real work space for matrices. On output it contains the
8563 ! LU decomposition of P.
8564 ! Storage of matrix elements starts at WM(3).
8565 ! WM also contains the following matrix-related data:
8566 ! WM(1) = SQRT(UROUND), used in numerical Jacobian increments.
8567 ! IWM = integer work space containing pivot information, starting at
8568 ! IWM(21). IWM also contains the band parameters
8569 ! ML = IWM(1) and MU = IWM(2) if MITER is 4 or 5.
8570 ! EL0 = el(1) (input).
8571 ! IERPJ = output error flag.
8572 ! = 0 if no trouble occurred,
8573 ! = 1 if the P matrix was found to be singular,
8574 ! = IRES (= 2 or 3) if RES returned IRES = 2 or 3.
8575 ! JCUR = output flag = 1 to indicate that the Jacobian matrix
8576 ! (or approximation) is now current.
8577 ! This routine also uses the Common variables EL0, H, TN, UROUND,
8578 ! MITER, N, NFE, and NJE.
8579 !-----------------------------------------------------------------------
8580 ! NJE = NJE + 1
8581 ! HL0 = H*EL0
8582 ! IERPJ = 0
8583 ! JCUR = 1
8584 ! GO TO (100, 200, 300, 400, 500), MITER
8585 ! If MITER = 1, call RES, then JAC, and multiply by scalar. ------------
8586 ! 100 IRES = 1
8587 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
8588 ! NFE = NFE + 1
8589 ! IF (IRES > 1) GO TO 600
8590 ! LENP = N*N
8591 ! DO 110 I = 1,LENP
8592 ! WM(I+2) = 0.0D0
8593 ! 110 END DO
8594 ! CALL JAC ( NEQ, TN, Y, S, 0, 0, WM(3), N )
8595 ! CON = -HL0
8596 ! DO 120 I = 1,LENP
8597 ! WM(I+2) = WM(I+2)*CON
8598 ! 120 END DO
8599 ! GO TO 240
8600 ! If MITER = 2, make N + 1 calls to RES to approximate J. --------------
8601 ! 200 CONTINUE
8602 ! IRES = -1
8603 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
8604 ! NFE = NFE + 1
8605 ! IF (IRES > 1) GO TO 600
8606 ! SRUR = WM(1)
8607 ! J1 = 2
8608 ! DO 230 J = 1,N
8609 ! YJ = Y(J)
8610 ! R = MAX(SRUR*ABS(YJ),0.01D0/EWT(J))
8611 ! Y(J) = Y(J) + R
8612 ! FAC = -HL0/R
8613 ! CALL RES ( NEQ, TN, Y, S, RTEM, IRES )
8614 ! NFE = NFE + 1
8615 ! IF (IRES > 1) GO TO 600
8616 ! DO 220 I = 1,N
8617 ! WM(I+J1) = (RTEM(I) - SAVR(I))*FAC
8618 ! 220 END DO
8619 ! Y(J) = YJ
8620 ! J1 = J1 + N
8621 ! 230 END DO
8622 ! IRES = 1
8623 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
8624 ! NFE = NFE + 1
8625 ! IF (IRES > 1) GO TO 600
8626 ! Add matrix A. --------------------------------------------------------
8627 ! 240 CONTINUE
8628 ! CALL ADDA(NEQ, TN, Y, 0, 0, WM(3), N)
8629 ! Do LU decomposition on P. --------------------------------------------
8630 ! CALL DGEFA (WM(3), N, N, IWM(21), IER)
8631 ! IF (IER /= 0) IERPJ = 1
8632 ! RETURN
8633 ! Dummy section for MITER = 3
8634 ! 300 RETURN
8635 ! If MITER = 4, call RES, then JAC, and multiply by scalar. ------------
8636 ! 400 IRES = 1
8637 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
8638 ! NFE = NFE + 1
8639 ! IF (IRES > 1) GO TO 600
8640 ! ML = IWM(1)
8641 ! MU = IWM(2)
8642 ! ML3 = ML + 3
8643 ! MBAND = ML + MU + 1
8644 ! MEBAND = MBAND + ML
8645 ! LENP = MEBAND*N
8646 ! DO 410 I = 1,LENP
8647 ! WM(I+2) = 0.0D0
8648 ! 410 END DO
8649 ! CALL JAC ( NEQ, TN, Y, S, ML, MU, WM(ML3), MEBAND)
8650 ! CON = -HL0
8651 ! DO 420 I = 1,LENP
8652 ! WM(I+2) = WM(I+2)*CON
8653 ! 420 END DO
8654 ! GO TO 570
8655 ! If MITER = 5, make ML + MU + 2 calls to RES to approximate J. --------
8656 ! 500 CONTINUE
8657 ! IRES = -1
8658 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
8659 ! NFE = NFE + 1
8660 ! IF (IRES > 1) GO TO 600
8661 ! ML = IWM(1)
8662 ! MU = IWM(2)
8663 ! ML3 = ML + 3
8664 ! MBAND = ML + MU + 1
8665 ! MBA = MIN(MBAND,N)
8666 ! MEBAND = MBAND + ML
8667 ! MEB1 = MEBAND - 1
8668 ! SRUR = WM(1)
8669 ! DO 560 J = 1,MBA
8670 ! DO 530 I = J,N,MBAND
8671 ! YI = Y(I)
8672 ! R = MAX(SRUR*ABS(YI),0.01D0/EWT(I))
8673 ! Y(I) = Y(I) + R
8674 ! 530 END DO
8675 ! CALL RES ( NEQ, TN, Y, S, RTEM, IRES)
8676 ! NFE = NFE + 1
8677 ! IF (IRES > 1) GO TO 600
8678 ! DO 550 JJ = J,N,MBAND
8679 ! Y(JJ) = YH(JJ,1)
8680 ! YJJ = Y(JJ)
8681 ! R = MAX(SRUR*ABS(YJJ),0.01D0/EWT(JJ))
8682 ! FAC = -HL0/R
8683 ! I1 = MAX(JJ-MU,1)
8684 ! I2 = MIN(JJ+ML,N)
8685 ! II = JJ*MEB1 - ML + 2
8686 ! DO 540 I = I1,I2
8687 ! WM(II+I) = (RTEM(I) - SAVR(I))*FAC
8688 ! 540 END DO
8689 ! 550 END DO
8690 ! 560 END DO
8691 ! IRES = 1
8692 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
8693 ! NFE = NFE + 1
8694 ! IF (IRES > 1) GO TO 600
8695 ! Add matrix A. --------------------------------------------------------
8696 ! 570 CONTINUE
8697 ! CALL ADDA(NEQ, TN, Y, ML, MU, WM(ML3), MEBAND)
8698 ! Do LU decomposition of P. --------------------------------------------
8699 ! CALL DGBFA (WM(3), MEBAND, N, ML, MU, IWM(21), IER)
8700 ! IF (IER /= 0) IERPJ = 1
8701 ! RETURN
8702 ! Error return for IRES = 2 or IRES = 3 return from RES. ---------------
8703 ! 600 IERPJ = IRES
8704 ! RETURN
8705 !----------------------- End of Subroutine DPREPJI ---------------------
8706 ! END SUBROUTINE DPREPJI
8707 ! ECK DAIGBT
8708 ! SUBROUTINE DAIGBT (RES, ADDA, NEQ, T, Y, YDOT, &
8709 ! MB, NB, PW, IPVT, IER )
8710 ! EXTERNAL RES, ADDA
8711 ! INTEGER :: NEQ, MB, NB, IPVT, IER
8712 ! INTEGER :: I, LENPW, LBLOX, LPB, LPC
8713 ! DOUBLE PRECISION :: T, Y, YDOT, PW
8714 ! DIMENSION Y(*), YDOT(*), PW(*), IPVT(*), NEQ(*)
8715 !-----------------------------------------------------------------------
8716 ! This subroutine computes the initial value
8717 ! of the vector YDOT satisfying
8718 ! A * YDOT = g(t,y)
8719 ! when A is nonsingular. It is called by DLSOIBT for
8720 ! initialization only, when ISTATE = 0 .
8721 ! DAIGBT returns an error flag IER:
8722 ! IER = 0 means DAIGBT was successful.
8723 ! IER .ge. 2 means RES returned an error flag IRES = IER.
8724 ! IER .lt. 0 means the A matrix was found to have a singular
8725 ! diagonal block (hence YDOT could not be solved for).
8726 !-----------------------------------------------------------------------
8727 ! LBLOX = MB*MB*NB
8728 ! LPB = 1 + LBLOX
8729 ! LPC = LPB + LBLOX
8730 ! LENPW = 3*LBLOX
8731 ! DO 10 I = 1,LENPW
8732 ! PW(I) = 0.0D0
8733 ! 10 END DO
8734 ! IER = 1
8735 ! CALL RES (NEQ, T, Y, PW, YDOT, IER)
8736 ! IF (IER > 1) RETURN
8737 ! CALL ADDA (NEQ, T, Y, MB, NB, PW(1), PW(LPB), PW(LPC) )
8738 ! CALL DDECBT (MB, NB, PW, PW(LPB), PW(LPC), IPVT, IER)
8739 ! IF (IER == 0) GO TO 20
8740 ! IER = -IER
8741 ! RETURN
8742 ! 20 CALL DSOLBT (MB, NB, PW, PW(LPB), PW(LPC), YDOT, IPVT)
8743 ! RETURN
8744 !----------------------- End of Subroutine DAIGBT ----------------------
8745 ! END SUBROUTINE DAIGBT
8746 ! ECK DPJIBT
8747 ! SUBROUTINE DPJIBT (NEQ, Y, YH, NYH, EWT, RTEM, SAVR, S, WM, IWM, &
8748 ! RES, JAC, ADDA)
8749 ! EXTERNAL RES, JAC, ADDA
8750 ! INTEGER :: NEQ, NYH, IWM
8751 ! DOUBLE PRECISION :: Y, YH, EWT, RTEM, SAVR, S, WM
8752 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), EWT(*), RTEM(*), &
8753 ! S(*), SAVR(*), WM(*), IWM(*)
8754 ! INTEGER :: IOWND, IOWNS, &
8755 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
8756 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
8757 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
8758 ! DOUBLE PRECISION :: ROWNS, &
8759 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
8760 ! COMMON /DLS001/ ROWNS(209), &
8761 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
8762 ! IOWND(6), IOWNS(6), &
8763 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
8764 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
8765 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
8766 ! INTEGER :: I, IER, IIA, IIB, IIC, IPA, IPB, IPC, IRES, J, J1, J2, &
8767 ! K, K1, LENP, LBLOX, LPB, LPC, MB, MBSQ, MWID, NB
8768 ! DOUBLE PRECISION :: CON, FAC, HL0, R, SRUR
8769 !-----------------------------------------------------------------------
8770 ! DPJIBT is called by DSTODI to compute and process the matrix
8771 ! P = A - H*EL(1)*J , where J is an approximation to the Jacobian dr/dy,
8772 ! and r = g(t,y) - A(t,y)*s. Here J is computed by the user-supplied
8773 ! routine JAC if MITER = 1, or by finite differencing if MITER = 2.
8774 ! J is stored in WM, rescaled, and ADDA is called to generate P.
8775 ! P is then subjected to LU decomposition by DDECBT in preparation
8776 ! for later solution of linear systems with P as coefficient matrix.
8777 ! In addition to variables described previously, communication
8778 ! with DPJIBT uses the following:
8779 ! Y = array containing predicted values on entry.
8780 ! RTEM = work array of length N (ACOR in DSTODI).
8781 ! SAVR = array used for output only. On output it contains the
8782 ! residual evaluated at current values of t and y.
8783 ! S = array containing predicted values of dy/dt (SAVF in DSTODI).
8784 ! WM = real work space for matrices. On output it contains the
8785 ! LU decomposition of P.
8786 ! Storage of matrix elements starts at WM(3).
8787 ! WM also contains the following matrix-related data:
8788 ! WM(1) = SQRT(UROUND), used in numerical Jacobian increments.
8789 ! IWM = integer work space containing pivot information, starting at
8790 ! IWM(21). IWM also contains block structure parameters
8791 ! MB = IWM(1) and NB = IWM(2).
8792 ! EL0 = EL(1) (input).
8793 ! IERPJ = output error flag.
8794 ! = 0 if no trouble occurred,
8795 ! = 1 if the P matrix was found to be unfactorable,
8796 ! = IRES (= 2 or 3) if RES returned IRES = 2 or 3.
8797 ! JCUR = output flag = 1 to indicate that the Jacobian matrix
8798 ! (or approximation) is now current.
8799 ! This routine also uses the Common variables EL0, H, TN, UROUND,
8800 ! MITER, N, NFE, and NJE.
8801 !-----------------------------------------------------------------------
8802 ! NJE = NJE + 1
8803 ! HL0 = H*EL0
8804 ! IERPJ = 0
8805 ! JCUR = 1
8806 ! MB = IWM(1)
8807 ! NB = IWM(2)
8808 ! MBSQ = MB*MB
8809 ! LBLOX = MBSQ*NB
8810 ! LPB = 3 + LBLOX
8811 ! LPC = LPB + LBLOX
8812 ! LENP = 3*LBLOX
8813 ! GO TO (100, 200), MITER
8814 ! If MITER = 1, call RES, then JAC, and multiply by scalar. ------------
8815 ! 100 IRES = 1
8816 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
8817 ! NFE = NFE + 1
8818 ! IF (IRES > 1) GO TO 600
8819 ! DO 110 I = 1,LENP
8820 ! WM(I+2) = 0.0D0
8821 ! 110 END DO
8822 ! CALL JAC (NEQ, TN, Y, S, MB, NB, WM(3), WM(LPB), WM(LPC))
8823 ! CON = -HL0
8824 ! DO 120 I = 1,LENP
8825 ! WM(I+2) = WM(I+2)*CON
8826 ! 120 END DO
8827 ! GO TO 260
8828 ! If MITER = 2, make 3*MB + 1 calls to RES to approximate J. -----------
8829 ! 200 CONTINUE
8830 ! IRES = -1
8831 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
8832 ! NFE = NFE + 1
8833 ! IF (IRES > 1) GO TO 600
8834 ! MWID = 3*MB
8835 ! SRUR = WM(1)
8836 ! DO 205 I = 1,LENP
8837 ! WM(2+I) = 0.0D0
8838 ! 205 END DO
8839 ! DO 250 K = 1,3
8840 ! DO 240 J = 1,MB
8841 ! ! Increment Y(I) for group of column indices, and call RES. ----
8842 ! J1 = J+(K-1)*MB
8843 ! DO 210 I = J1,N,MWID
8844 ! R = MAX(SRUR*ABS(Y(I)),0.01D0/EWT(I))
8845 ! Y(I) = Y(I) + R
8846 ! 210 END DO
8847 ! CALL RES (NEQ, TN, Y, S, RTEM, IRES)
8848 ! NFE = NFE + 1
8849 ! IF (IRES > 1) GO TO 600
8850 ! DO 215 I = 1,N
8851 ! RTEM(I) = RTEM(I) - SAVR(I)
8852 ! 215 END DO
8853 ! K1 = K
8854 ! DO 230 I = J1,N,MWID
8855 ! ! Get Jacobian elements in column I (block-column K1). -------
8856 ! Y(I) = YH(I,1)
8857 ! R = MAX(SRUR*ABS(Y(I)),0.01D0/EWT(I))
8858 ! FAC = -HL0/R
8859 ! ! Compute and load elements PA(*,J,K1). ----------------------
8860 ! IIA = I - J
8861 ! IPA = 2 + (J-1)*MB + (K1-1)*MBSQ
8862 ! DO 221 J2 = 1,MB
8863 ! WM(IPA+J2) = RTEM(IIA+J2)*FAC
8864 ! 221 END DO
8865 ! IF (K1 <= 1) GO TO 223
8866 ! ! Compute and load elements PB(*,J,K1-1). --------------------
8867 ! IIB = IIA - MB
8868 ! IPB = IPA + LBLOX - MBSQ
8869 ! DO 222 J2 = 1,MB
8870 ! WM(IPB+J2) = RTEM(IIB+J2)*FAC
8871 ! 222 END DO
8872 ! 223 CONTINUE
8873 ! IF (K1 >= NB) GO TO 225
8874 ! ! Compute and load elements PC(*,J,K1+1). --------------------
8875 ! IIC = IIA + MB
8876 ! IPC = IPA + 2*LBLOX + MBSQ
8877 ! DO 224 J2 = 1,MB
8878 ! WM(IPC+J2) = RTEM(IIC+J2)*FAC
8879 ! 224 END DO
8880 ! 225 CONTINUE
8881 ! IF (K1 /= 3) GO TO 227
8882 ! ! Compute and load elements PC(*,J,1). -----------------------
8883 ! IPC = IPA - 2*MBSQ + 2*LBLOX
8884 ! DO 226 J2 = 1,MB
8885 ! WM(IPC+J2) = RTEM(J2)*FAC
8886 ! 226 END DO
8887 ! 227 CONTINUE
8888 ! IF (K1 /= NB-2) GO TO 229
8889 ! ! Compute and load elements PB(*,J,NB). ----------------------
8890 ! IIB = N - MB
8891 ! IPB = IPA + 2*MBSQ + LBLOX
8892 ! DO 228 J2 = 1,MB
8893 ! WM(IPB+J2) = RTEM(IIB+J2)*FAC
8894 ! 228 END DO
8895 ! 229 K1 = K1 + 3
8896 ! 230 END DO
8897 ! 240 END DO
8898 ! 250 END DO
8899 ! RES call for first corrector iteration. ------------------------------
8900 ! IRES = 1
8901 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
8902 ! NFE = NFE + 1
8903 ! IF (IRES > 1) GO TO 600
8904 ! Add matrix A. --------------------------------------------------------
8905 ! 260 CONTINUE
8906 ! CALL ADDA (NEQ, TN, Y, MB, NB, WM(3), WM(LPB), WM(LPC))
8907 ! Do LU decomposition on P. --------------------------------------------
8908 ! CALL DDECBT (MB, NB, WM(3), WM(LPB), WM(LPC), IWM(21), IER)
8909 ! IF (IER /= 0) IERPJ = 1
8910 ! RETURN
8911 ! Error return for IRES = 2 or IRES = 3 return from RES. ---------------
8912 ! 600 IERPJ = IRES
8913 ! RETURN
8914 !----------------------- End of Subroutine DPJIBT ----------------------
8915 ! END SUBROUTINE DPJIBT
8916 ! ECK DSLSBT
8917 ! SUBROUTINE DSLSBT (WM, IWM, X, TEM)
8918 ! INTEGER :: IWM
8919 ! INTEGER :: LBLOX, LPB, LPC, MB, NB
8920 ! DOUBLE PRECISION :: WM, X, TEM
8921 ! DIMENSION WM(*), IWM(*), X(*), TEM(*)
8922 !-----------------------------------------------------------------------
8923 ! This routine acts as an interface between the core integrator
8924 ! routine and the DSOLBT routine for the solution of the linear system
8925 ! arising from chord iteration.
8926 ! Communication with DSLSBT uses the following variables:
8927 ! WM = real work space containing the LU decomposition,
8928 ! starting at WM(3).
8929 ! IWM = integer work space containing pivot information, starting at
8930 ! IWM(21). IWM also contains block structure parameters
8931 ! MB = IWM(1) and NB = IWM(2).
8932 ! X = the right-hand side vector on input, and the solution vector
8933 ! on output, of length N.
8934 ! TEM = vector of work space of length N, not used in this version.
8935 !-----------------------------------------------------------------------
8936 ! MB = IWM(1)
8937 ! NB = IWM(2)
8938 ! LBLOX = MB*MB*NB
8939 ! LPB = 3 + LBLOX
8940 ! LPC = LPB + LBLOX
8941 ! CALL DSOLBT (MB, NB, WM(3), WM(LPB), WM(LPC), X, IWM(21))
8942 ! RETURN
8943 !----------------------- End of Subroutine DSLSBT ----------------------
8944 ! END SUBROUTINE DSLSBT
8945 ! ECK DDECBT
8946 ! SUBROUTINE DDECBT (M, N, A, B, C, IP, IER)
8947 ! INTEGER :: M, N, IP(M,N), IER
8948 ! DOUBLE PRECISION :: A(M,M,N), B(M,M,N), C(M,M,N)
8949 !-----------------------------------------------------------------------
8950 ! Block-tridiagonal matrix decomposition routine.
8951 ! Written by A. C. Hindmarsh.
8952 ! Latest revision: November 10, 1983 (ACH)
8953 ! Reference: UCID-30150
8954 ! Solution of Block-Tridiagonal Systems of Linear
8955 ! Algebraic Equations
8956 ! A.C. Hindmarsh
8957 ! February 1977
8958 ! The input matrix contains three blocks of elements in each block-row,
8959 ! including blocks in the (1,3) and (N,N-2) block positions.
8960 ! DDECBT uses block Gauss elimination and Subroutines DGEFA and DGESL
8961 ! for solution of blocks. Partial pivoting is done within
8962 ! block-rows only.
8963 ! Note: this version uses LINPACK routines DGEFA/DGESL instead of
8964 ! of dec/sol for solution of blocks, and it uses the BLAS routine DDOT
8965 ! for dot product calculations.
8966 ! Input:
8967 ! M = order of each block.
8968 ! N = number of blocks in each direction of the matrix.
8969 ! N must be 4 or more. The complete matrix has order M*N.
8970 ! A = M by M by N array containing diagonal blocks.
8971 ! A(i,j,k) contains the (i,j) element of the k-th block.
8972 ! B = M by M by N array containing the super-diagonal blocks
8973 ! (in B(*,*,k) for k = 1,...,N-1) and the block in the (N,N-2)
8974 ! block position (in B(*,*,N)).
8975 ! C = M by M by N array containing the subdiagonal blocks
8976 ! (in C(*,*,k) for k = 2,3,...,N) and the block in the
8977 ! (1,3) block position (in C(*,*,1)).
8978 ! IP = integer array of length M*N for working storage.
8979 ! Output:
8980 ! A,B,C = M by M by N arrays containing the block-LU decomposition
8981 ! of the input matrix.
8982 ! IP = M by N array of pivot information. IP(*,k) contains
8983 ! information for the k-th digonal block.
8984 ! IER = 0 if no trouble occurred, or
8985 ! = -1 if the input value of M or N was illegal, or
8986 ! = k if a singular matrix was found in the k-th diagonal block.
8987 ! Use DSOLBT to solve the associated linear system.
8988 ! External routines required: DGEFA and DGESL (from LINPACK) and
8989 ! DDOT (from the BLAS, or Basic Linear Algebra package).
8990 !-----------------------------------------------------------------------
8991 ! INTEGER :: NM1, NM2, KM1, I, J, K
8992 ! DOUBLE PRECISION :: DP, DDOT
8993 ! IF (M < 1 .OR. N < 4) GO TO 210
8994 ! NM1 = N - 1
8995 ! NM2 = N - 2
8996 ! Process the first block-row. -----------------------------------------
8997 ! CALL DGEFA (A, M, M, IP, IER)
8998 ! K = 1
8999 ! IF (IER /= 0) GO TO 200
9000 ! DO 10 J = 1,M
9001 ! CALL DGESL (A, M, M, IP, B(1,J,1), 0)
9002 ! CALL DGESL (A, M, M, IP, C(1,J,1), 0)
9003 ! 10 END DO
9004 ! Adjust B(*,*,2). -----------------------------------------------------
9005 ! DO 40 J = 1,M
9006 ! DO 30 I = 1,M
9007 ! DP = DDOT (M, C(I,1,2), M, C(1,J,1), 1)
9008 ! B(I,J,2) = B(I,J,2) - DP
9009 ! 30 END DO
9010 ! 40 END DO
9011 ! Main loop. Process block-rows 2 to N-1. -----------------------------
9012 ! DO 100 K = 2,NM1
9013 ! KM1 = K - 1
9014 ! DO 70 J = 1,M
9015 ! DO 60 I = 1,M
9016 ! DP = DDOT (M, C(I,1,K), M, B(1,J,KM1), 1)
9017 ! A(I,J,K) = A(I,J,K) - DP
9018 ! 60 END DO
9019 ! 70 END DO
9020 ! CALL DGEFA (A(1,1,K), M, M, IP(1,K), IER)
9021 ! IF (IER /= 0) GO TO 200
9022 ! DO 80 J = 1,M
9023 ! CALL DGESL (A(1,1,K), M, M, IP(1,K), B(1,J,K), 0)
9024 ! 80 END DO
9025 ! 100 END DO
9026 ! Process last block-row and return. -----------------------------------
9027 ! DO 130 J = 1,M
9028 ! DO 120 I = 1,M
9029 ! DP = DDOT (M, B(I,1,N), M, B(1,J,NM2), 1)
9030 ! C(I,J,N) = C(I,J,N) - DP
9031 ! 120 END DO
9032 ! 130 END DO
9033 ! DO 160 J = 1,M
9034 ! DO 150 I = 1,M
9035 ! DP = DDOT (M, C(I,1,N), M, B(1,J,NM1), 1)
9036 ! A(I,J,N) = A(I,J,N) - DP
9037 ! 150 END DO
9038 ! 160 END DO
9039 ! CALL DGEFA (A(1,1,N), M, M, IP(1,N), IER)
9040 ! K = N
9041 ! IF (IER /= 0) GO TO 200
9042 ! RETURN
9043 ! Error returns. -------------------------------------------------------
9044 ! 200 IER = K
9045 ! RETURN
9046 ! 210 IER = -1
9047 ! RETURN
9048 !----------------------- End of Subroutine DDECBT ----------------------
9049 ! END SUBROUTINE DDECBT
9050 ! ECK DSOLBT
9051 ! SUBROUTINE DSOLBT (M, N, A, B, C, Y, IP)
9052 ! INTEGER :: M, N, IP(M,N)
9053 ! DOUBLE PRECISION :: A(M,M,N), B(M,M,N), C(M,M,N), Y(M,N)
9054 !-----------------------------------------------------------------------
9055 ! Solution of block-tridiagonal linear system.
9056 ! Coefficient matrix must have been previously processed by DDECBT.
9057 ! M, N, A,B,C, and IP must not have been changed since call to DDECBT.
9058 ! Written by A. C. Hindmarsh.
9059 ! Input:
9060 ! M = order of each block.
9061 ! N = number of blocks in each direction of matrix.
9062 ! A,B,C = M by M by N arrays containing block LU decomposition
9063 ! of coefficient matrix from DDECBT.
9064 ! IP = M by N integer array of pivot information from DDECBT.
9065 ! Y = array of length M*N containg the right-hand side vector
9066 ! (treated as an M by N array here).
9067 ! Output:
9068 ! Y = solution vector, of length M*N.
9069 ! External routines required: DGESL (LINPACK) and DDOT (BLAS).
9070 !-----------------------------------------------------------------------
9071 ! INTEGER :: NM1, NM2, I, K, KB, KM1, KP1
9072 ! DOUBLE PRECISION :: DP, DDOT
9073 ! NM1 = N - 1
9074 ! NM2 = N - 2
9075 ! Forward solution sweep. ----------------------------------------------
9076 ! CALL DGESL (A, M, M, IP, Y, 0)
9077 ! DO 30 K = 2,NM1
9078 ! KM1 = K - 1
9079 ! DO 20 I = 1,M
9080 ! DP = DDOT (M, C(I,1,K), M, Y(1,KM1), 1)
9081 ! Y(I,K) = Y(I,K) - DP
9082 ! 20 END DO
9083 ! CALL DGESL (A(1,1,K), M, M, IP(1,K), Y(1,K), 0)
9084 ! 30 END DO
9085 ! DO 50 I = 1,M
9086 ! DP = DDOT (M, C(I,1,N), M, Y(1,NM1), 1) &
9087 ! + DDOT (M, B(I,1,N), M, Y(1,NM2), 1)
9088 ! Y(I,N) = Y(I,N) - DP
9089 ! 50 END DO
9090 ! CALL DGESL (A(1,1,N), M, M, IP(1,N), Y(1,N), 0)
9091 ! Backward solution sweep. ---------------------------------------------
9092 ! DO 80 KB = 1,NM1
9093 ! K = N - KB
9094 ! KP1 = K + 1
9095 ! DO 70 I = 1,M
9096 ! DP = DDOT (M, B(I,1,K), M, Y(1,KP1), 1)
9097 ! Y(I,K) = Y(I,K) - DP
9098 ! 70 END DO
9099 ! 80 END DO
9100 ! DO 100 I = 1,M
9101 ! DP = DDOT (M, C(I,1,1), M, Y(1,3), 1)
9102 ! Y(I,1) = Y(I,1) - DP
9103 ! 100 END DO
9104 ! RETURN
9105 !----------------------- End of Subroutine DSOLBT ----------------------
9106 ! END SUBROUTINE DSOLBT
9107 ! ECK DIPREPI
9108 ! SUBROUTINE DIPREPI (NEQ, Y, S, RWORK, IA, JA, IC, JC, IPFLAG, &
9109 ! RES, JAC, ADDA)
9110 ! EXTERNAL RES, JAC, ADDA
9111 ! INTEGER :: NEQ, IA, JA, IC, JC, IPFLAG
9112 ! DOUBLE PRECISION :: Y, S, RWORK
9113 ! DIMENSION NEQ(*), Y(*), S(*), RWORK(*), IA(*), JA(*), IC(*), JC(*)
9114 ! INTEGER :: IOWND, IOWNS, &
9115 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
9116 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
9117 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
9118 ! INTEGER :: IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
9119 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
9120 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
9121 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
9122 ! DOUBLE PRECISION :: ROWNS, &
9123 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
9124 ! DOUBLE PRECISION :: RLSS
9125 ! COMMON /DLS001/ ROWNS(209), &
9126 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
9127 ! IOWND(6), IOWNS(6), &
9128 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
9129 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
9130 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
9131 ! COMMON /DLSS01/ RLSS(6), &
9132 ! IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
9133 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
9134 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
9135 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
9136 ! INTEGER :: I, IMAX, LEWTN, LYHD, LYHN
9137 !-----------------------------------------------------------------------
9138 ! This routine serves as an interface between the driver and
9139 ! Subroutine DPREPI. Tasks performed here are:
9140 ! * call DPREPI,
9141 ! * reset the required WM segment length LENWK,
9142 ! * move YH back to its final location (following WM in RWORK),
9143 ! * reset pointers for YH, SAVR, EWT, and ACOR, and
9144 ! * move EWT to its new position if ISTATE = 0 or 1.
9145 ! IPFLAG is an output error indication flag. IPFLAG = 0 if there was
9146 ! no trouble, and IPFLAG is the value of the DPREPI error flag IPPER
9147 ! if there was trouble in Subroutine DPREPI.
9148 !-----------------------------------------------------------------------
9149 ! IPFLAG = 0
9150 ! Call DPREPI to do matrix preprocessing operations. -------------------
9151 ! CALL DPREPI (NEQ, Y, S, RWORK(LYH), RWORK(LSAVF), RWORK(LEWT), &
9152 ! RWORK(LACOR), IA, JA, IC, JC, RWORK(LWM), RWORK(LWM), IPFLAG, &
9153 ! RES, JAC, ADDA)
9154 ! LENWK = MAX(LREQ,LWMIN)
9155 ! IF (IPFLAG < 0) RETURN
9156 ! If DPREPI was successful, move YH to end of required space for WM. ---
9157 ! LYHN = LWM + LENWK
9158 ! IF (LYHN > LYH) RETURN
9159 ! LYHD = LYH - LYHN
9160 ! IF (LYHD == 0) GO TO 20
9161 ! IMAX = LYHN - 1 + LENYHM
9162 ! DO 10 I=LYHN,IMAX
9163 ! RWORK(I) = RWORK(I+LYHD)
9164 ! 10 END DO
9165 ! LYH = LYHN
9166 ! Reset pointers for SAVR, EWT, and ACOR. ------------------------------
9167 ! 20 LSAVF = LYH + LENYH
9168 ! LEWTN = LSAVF + N
9169 ! LACOR = LEWTN + N
9170 ! IF (ISTATC == 3) GO TO 40
9171 ! If ISTATE = 1, move EWT (left) to its new position. ------------------
9172 ! IF (LEWTN > LEWT) RETURN
9173 ! DO 30 I=1,N
9174 ! RWORK(I+LEWTN-1) = RWORK(I+LEWT-1)
9175 ! 30 END DO
9176 ! 40 LEWT = LEWTN
9177 ! RETURN
9178 !----------------------- End of Subroutine DIPREPI ---------------------
9179 ! END SUBROUTINE DIPREPI
9180 ! ECK DPREPI
9181 ! SUBROUTINE DPREPI (NEQ, Y, S, YH, SAVR, EWT, RTEM, IA, JA, IC, JC, &
9182 ! WK, IWK, IPPER, RES, JAC, ADDA)
9183 ! EXTERNAL RES, JAC, ADDA
9184 ! INTEGER :: NEQ, IA, JA, IC, JC, IWK, IPPER
9185 ! DOUBLE PRECISION :: Y, S, YH, SAVR, EWT, RTEM, WK
9186 ! DIMENSION NEQ(*), Y(*), S(*), YH(*), SAVR(*), EWT(*), RTEM(*), &
9187 ! IA(*), JA(*), IC(*), JC(*), WK(*), IWK(*)
9188 ! INTEGER :: IOWND, IOWNS, &
9189 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
9190 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
9191 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
9192 ! INTEGER :: IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
9193 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
9194 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
9195 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
9196 ! DOUBLE PRECISION :: ROWNS, &
9197 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
9198 ! DOUBLE PRECISION :: RLSS
9199 ! COMMON /DLS001/ ROWNS(209), &
9200 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
9201 ! IOWND(6), IOWNS(6), &
9202 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
9203 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
9204 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
9205 ! COMMON /DLSS01/ RLSS(6), &
9206 ! IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
9207 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
9208 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
9209 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
9210 ! INTEGER :: I, IBR, IER, IPIL, IPIU, IPTT1, IPTT2, J, K, KNEW, KAMAX, &
9211 ! KAMIN, KCMAX, KCMIN, LDIF, LENIGP, LENWK1, LIWK, LJFO, MAXG, &
9212 ! NP1, NZSUT
9213 ! DOUBLE PRECISION :: ERWT, FAC, YJ
9214 !-----------------------------------------------------------------------
9215 ! This routine performs preprocessing related to the sparse linear
9216 ! systems that must be solved.
9217 ! The operations that are performed here are:
9218 ! * compute sparseness structure of the iteration matrix
9219 ! P = A - con*J according to MOSS,
9220 ! * compute grouping of column indices (MITER = 2),
9221 ! * compute a new ordering of rows and columns of the matrix,
9222 ! * reorder JA corresponding to the new ordering,
9223 ! * perform a symbolic LU factorization of the matrix, and
9224 ! * set pointers for segments of the IWK/WK array.
9225 ! In addition to variables described previously, DPREPI uses the
9226 ! following for communication:
9227 ! YH = the history array. Only the first column, containing the
9228 ! current Y vector, is used. Used only if MOSS .ne. 0.
9229 ! S = array of length NEQ, identical to YDOTI in the driver, used
9230 ! only if MOSS .ne. 0.
9231 ! SAVR = a work array of length NEQ, used only if MOSS .ne. 0.
9232 ! EWT = array of length NEQ containing (inverted) error weights.
9233 ! Used only if MOSS = 2 or 4 or if ISTATE = MOSS = 1.
9234 ! RTEM = a work array of length NEQ, identical to ACOR in the driver,
9235 ! used only if MOSS = 2 or 4.
9236 ! WK = a real work array of length LENWK, identical to WM in
9237 ! the driver.
9238 ! IWK = integer work array, assumed to occupy the same space as WK.
9239 ! LENWK = the length of the work arrays WK and IWK.
9240 ! ISTATC = a copy of the driver input argument ISTATE (= 1 on the
9241 ! first call, = 3 on a continuation call).
9242 ! IYS = flag value from ODRV or CDRV.
9243 ! IPPER = output error flag , with the following values and meanings:
9244 ! = 0 no error.
9245 ! = -1 insufficient storage for internal structure pointers.
9246 ! = -2 insufficient storage for JGROUP.
9247 ! = -3 insufficient storage for ODRV.
9248 ! = -4 other error flag from ODRV (should never occur).
9249 ! = -5 insufficient storage for CDRV.
9250 ! = -6 other error flag from CDRV.
9251 ! = -7 if the RES routine returned error flag IRES = IER = 2.
9252 ! = -8 if the RES routine returned error flag IRES = IER = 3.
9253 !-----------------------------------------------------------------------
9254 ! IBIAN = LRAT*2
9255 ! IPIAN = IBIAN + 1
9256 ! NP1 = N + 1
9257 ! IPJAN = IPIAN + NP1
9258 ! IBJAN = IPJAN - 1
9259 ! LENWK1 = LENWK - N
9260 ! LIWK = LENWK*LRAT
9261 ! IF (MOSS == 0) LIWK = LIWK - N
9262 ! IF (MOSS == 1 .OR. MOSS == 2) LIWK = LENWK1*LRAT
9263 ! IF (IPJAN+N-1 > LIWK) GO TO 310
9264 ! IF (MOSS == 0) GO TO 30
9265 ! IF (ISTATC == 3) GO TO 20
9266 ! ISTATE = 1 and MOSS .ne. 0. Perturb Y for structure determination.
9267 ! Initialize S with random nonzero elements for structure determination.
9268 ! DO 10 I=1,N
9269 ! ERWT = 1.0D0/EWT(I)
9270 ! FAC = 1.0D0 + 1.0D0/(I + 1.0D0)
9271 ! Y(I) = Y(I) + FAC*SIGN(ERWT,Y(I))
9272 ! S(I) = 1.0D0 + FAC*ERWT
9273 ! 10 END DO
9274 ! GO TO (70, 100, 150, 200), MOSS
9275 ! 20 CONTINUE
9276 ! ISTATE = 3 and MOSS .ne. 0. Load Y from YH(*,1) and S from YH(*,2). --
9277 ! DO 25 I = 1,N
9278 ! Y(I) = YH(I)
9279 ! S(I) = YH(N+I)
9280 ! 25 END DO
9281 ! GO TO (70, 100, 150, 200), MOSS
9282 ! MOSS = 0. Process user's IA,JA and IC,JC. ----------------------------
9283 ! 30 KNEW = IPJAN
9284 ! KAMIN = IA(1)
9285 ! KCMIN = IC(1)
9286 ! IWK(IPIAN) = 1
9287 ! DO 60 J = 1,N
9288 ! DO 35 I = 1,N
9289 ! IWK(LIWK+I) = 0
9290 ! 35 END DO
9291 ! KAMAX = IA(J+1) - 1
9292 ! IF (KAMIN > KAMAX) GO TO 45
9293 ! DO 40 K = KAMIN,KAMAX
9294 ! I = JA(K)
9295 ! IWK(LIWK+I) = 1
9296 ! IF (KNEW > LIWK) GO TO 310
9297 ! IWK(KNEW) = I
9298 ! KNEW = KNEW + 1
9299 ! 40 END DO
9300 ! 45 KAMIN = KAMAX + 1
9301 ! KCMAX = IC(J+1) - 1
9302 ! IF (KCMIN > KCMAX) GO TO 55
9303 ! DO 50 K = KCMIN,KCMAX
9304 ! I = JC(K)
9305 ! IF (IWK(LIWK+I) /= 0) GO TO 50
9306 ! IF (KNEW > LIWK) GO TO 310
9307 ! IWK(KNEW) = I
9308 ! KNEW = KNEW + 1
9309 ! 50 END DO
9310 ! 55 IWK(IPIAN+J) = KNEW + 1 - IPJAN
9311 ! KCMIN = KCMAX + 1
9312 ! 60 END DO
9313 ! GO TO 240
9314 ! MOSS = 1. Compute structure from user-supplied Jacobian routine JAC. -
9315 ! 70 CONTINUE
9316 ! A dummy call to RES allows user to create temporaries for use in JAC.
9317 ! IER = 1
9318 ! CALL RES (NEQ, TN, Y, S, SAVR, IER)
9319 ! IF (IER > 1) GO TO 370
9320 ! DO 75 I = 1,N
9321 ! SAVR(I) = 0.0D0
9322 ! WK(LENWK1+I) = 0.0D0
9323 ! 75 END DO
9324 ! K = IPJAN
9325 ! IWK(IPIAN) = 1
9326 ! DO 95 J = 1,N
9327 ! CALL ADDA (NEQ, TN, Y, J, IWK(IPIAN), IWK(IPJAN), WK(LENWK1+1))
9328 ! CALL JAC (NEQ, TN, Y, S, J, IWK(IPIAN), IWK(IPJAN), SAVR)
9329 ! DO 90 I = 1,N
9330 ! LJFO = LENWK1 + I
9331 ! IF (WK(LJFO) == 0.0D0) GO TO 80
9332 ! WK(LJFO) = 0.0D0
9333 ! SAVR(I) = 0.0D0
9334 ! GO TO 85
9335 ! 80 IF (SAVR(I) == 0.0D0) GO TO 90
9336 ! SAVR(I) = 0.0D0
9337 ! 85 IF (K > LIWK) GO TO 310
9338 ! IWK(K) = I
9339 ! K = K+1
9340 ! 90 END DO
9341 ! IWK(IPIAN+J) = K + 1 - IPJAN
9342 ! 95 END DO
9343 ! GO TO 240
9344 ! MOSS = 2. Compute structure from results of N + 1 calls to RES. ------
9345 ! 100 DO 105 I = 1,N
9346 ! WK(LENWK1+I) = 0.0D0
9347 ! 105 END DO
9348 ! K = IPJAN
9349 ! IWK(IPIAN) = 1
9350 ! IER = -1
9351 ! IF (MITER == 1) IER = 1
9352 ! CALL RES (NEQ, TN, Y, S, SAVR, IER)
9353 ! IF (IER > 1) GO TO 370
9354 ! DO 130 J = 1,N
9355 ! CALL ADDA (NEQ, TN, Y, J, IWK(IPIAN), IWK(IPJAN), WK(LENWK1+1))
9356 ! YJ = Y(J)
9357 ! ERWT = 1.0D0/EWT(J)
9358 ! Y(J) = YJ + SIGN(ERWT,YJ)
9359 ! CALL RES (NEQ, TN, Y, S, RTEM, IER)
9360 ! IF (IER > 1) RETURN
9361 ! Y(J) = YJ
9362 ! DO 120 I = 1,N
9363 ! LJFO = LENWK1 + I
9364 ! IF (WK(LJFO) == 0.0D0) GO TO 110
9365 ! WK(LJFO) = 0.0D0
9366 ! GO TO 115
9367 ! 110 IF (RTEM(I) == SAVR(I)) GO TO 120
9368 ! 115 IF (K > LIWK) GO TO 310
9369 ! IWK(K) = I
9370 ! K = K + 1
9371 ! 120 END DO
9372 ! IWK(IPIAN+J) = K + 1 - IPJAN
9373 ! 130 END DO
9374 ! GO TO 240
9375 ! MOSS = 3. Compute structure from the user's IA/JA and JAC routine. ---
9376 ! 150 CONTINUE
9377 ! A dummy call to RES allows user to create temporaries for use in JAC.
9378 ! IER = 1
9379 ! CALL RES (NEQ, TN, Y, S, SAVR, IER)
9380 ! IF (IER > 1) GO TO 370
9381 ! DO 155 I = 1,N
9382 ! SAVR(I) = 0.0D0
9383 ! 155 END DO
9384 ! KNEW = IPJAN
9385 ! KAMIN = IA(1)
9386 ! IWK(IPIAN) = 1
9387 ! DO 190 J = 1,N
9388 ! CALL JAC (NEQ, TN, Y, S, J, IWK(IPIAN), IWK(IPJAN), SAVR)
9389 ! KAMAX = IA(J+1) - 1
9390 ! IF (KAMIN > KAMAX) GO TO 170
9391 ! DO 160 K = KAMIN,KAMAX
9392 ! I = JA(K)
9393 ! SAVR(I) = 0.0D0
9394 ! IF (KNEW > LIWK) GO TO 310
9395 ! IWK(KNEW) = I
9396 ! KNEW = KNEW + 1
9397 ! 160 END DO
9398 ! 170 KAMIN = KAMAX + 1
9399 ! DO 180 I = 1,N
9400 ! IF (SAVR(I) == 0.0D0) GO TO 180
9401 ! SAVR(I) = 0.0D0
9402 ! IF (KNEW > LIWK) GO TO 310
9403 ! IWK(KNEW) = I
9404 ! KNEW = KNEW + 1
9405 ! 180 END DO
9406 ! IWK(IPIAN+J) = KNEW + 1 - IPJAN
9407 ! 190 END DO
9408 ! GO TO 240
9409 ! MOSS = 4. Compute structure from user's IA/JA and N + 1 RES calls. ---
9410 ! 200 KNEW = IPJAN
9411 ! KAMIN = IA(1)
9412 ! IWK(IPIAN) = 1
9413 ! IER = -1
9414 ! IF (MITER == 1) IER = 1
9415 ! CALL RES (NEQ, TN, Y, S, SAVR, IER)
9416 ! IF (IER > 1) GO TO 370
9417 ! DO 235 J = 1,N
9418 ! YJ = Y(J)
9419 ! ERWT = 1.0D0/EWT(J)
9420 ! Y(J) = YJ + SIGN(ERWT,YJ)
9421 ! CALL RES (NEQ, TN, Y, S, RTEM, IER)
9422 ! IF (IER > 1) RETURN
9423 ! Y(J) = YJ
9424 ! KAMAX = IA(J+1) - 1
9425 ! IF (KAMIN > KAMAX) GO TO 225
9426 ! DO 220 K = KAMIN,KAMAX
9427 ! I = JA(K)
9428 ! RTEM(I) = SAVR(I)
9429 ! IF (KNEW > LIWK) GO TO 310
9430 ! IWK(KNEW) = I
9431 ! KNEW = KNEW + 1
9432 ! 220 END DO
9433 ! 225 KAMIN = KAMAX + 1
9434 ! DO 230 I = 1,N
9435 ! IF (RTEM(I) == SAVR(I)) GO TO 230
9436 ! IF (KNEW > LIWK) GO TO 310
9437 ! IWK(KNEW) = I
9438 ! KNEW = KNEW + 1
9439 ! 230 END DO
9440 ! IWK(IPIAN+J) = KNEW + 1 - IPJAN
9441 ! 235 END DO
9442 ! 240 CONTINUE
9443 ! IF (MOSS == 0 .OR. ISTATC == 3) GO TO 250
9444 ! If ISTATE = 0 or 1 and MOSS .ne. 0, restore Y from YH. ---------------
9445 ! DO 245 I = 1,N
9446 ! Y(I) = YH(I)
9447 ! 245 END DO
9448 ! 250 NNZ = IWK(IPIAN+N) - 1
9449 ! IPPER = 0
9450 ! NGP = 0
9451 ! LENIGP = 0
9452 ! IPIGP = IPJAN + NNZ
9453 ! IF (MITER /= 2) GO TO 260
9454 ! Compute grouping of column indices (MITER = 2). ----------------------
9455 ! MAXG = NP1
9456 ! IPJGP = IPJAN + NNZ
9457 ! IBJGP = IPJGP - 1
9458 ! IPIGP = IPJGP + N
9459 ! IPTT1 = IPIGP + NP1
9460 ! IPTT2 = IPTT1 + N
9461 ! LREQ = IPTT2 + N - 1
9462 ! IF (LREQ > LIWK) GO TO 320
9463 ! CALL JGROUP (N, IWK(IPIAN), IWK(IPJAN), MAXG, NGP, IWK(IPIGP), &
9464 ! IWK(IPJGP), IWK(IPTT1), IWK(IPTT2), IER)
9465 ! IF (IER /= 0) GO TO 320
9466 ! LENIGP = NGP + 1
9467 ! Compute new ordering of rows/columns of Jacobian. --------------------
9468 ! 260 IPR = IPIGP + LENIGP
9469 ! IPC = IPR
9470 ! IPIC = IPC + N
9471 ! IPISP = IPIC + N
9472 ! IPRSP = (IPISP-2)/LRAT + 2
9473 ! IESP = LENWK + 1 - IPRSP
9474 ! IF (IESP < 0) GO TO 330
9475 ! IBR = IPR - 1
9476 ! DO 270 I = 1,N
9477 ! IWK(IBR+I) = I
9478 ! 270 END DO
9479 ! NSP = LIWK + 1 - IPISP
9480 ! CALL ODRV(N, IWK(IPIAN), IWK(IPJAN), WK, IWK(IPR), IWK(IPIC), NSP, &
9481 ! IWK(IPISP), 1, IYS)
9482 ! IF (IYS == 11*N+1) GO TO 340
9483 ! IF (IYS /= 0) GO TO 330
9484 ! Reorder JAN and do symbolic LU factorization of matrix. --------------
9485 ! IPA = LENWK + 1 - NNZ
9486 ! NSP = IPA - IPRSP
9487 ! LREQ = MAX(12*N/LRAT, 6*N/LRAT+2*N+NNZ) + 3
9488 ! LREQ = LREQ + IPRSP - 1 + NNZ
9489 ! IF (LREQ > LENWK) GO TO 350
9490 ! IBA = IPA - 1
9491 ! DO 280 I = 1,NNZ
9492 ! WK(IBA+I) = 0.0D0
9493 ! 280 END DO
9494 ! IPISP = LRAT*(IPRSP - 1) + 1
9495 ! CALL CDRV(N,IWK(IPR),IWK(IPC),IWK(IPIC),IWK(IPIAN),IWK(IPJAN), &
9496 ! WK(IPA),WK(IPA),WK(IPA),NSP,IWK(IPISP),WK(IPRSP),IESP,5,IYS)
9497 ! LREQ = LENWK - IESP
9498 ! IF (IYS == 10*N+1) GO TO 350
9499 ! IF (IYS /= 0) GO TO 360
9500 ! IPIL = IPISP
9501 ! IPIU = IPIL + 2*N + 1
9502 ! NZU = IWK(IPIL+N) - IWK(IPIL)
9503 ! NZL = IWK(IPIU+N) - IWK(IPIU)
9504 ! IF (LRAT > 1) GO TO 290
9505 ! CALL ADJLR (N, IWK(IPISP), LDIF)
9506 ! LREQ = LREQ + LDIF
9507 ! 290 CONTINUE
9508 ! IF (LRAT == 2 .AND. NNZ == N) LREQ = LREQ + 1
9509 ! NSP = NSP + LREQ - LENWK
9510 ! IPA = LREQ + 1 - NNZ
9511 ! IBA = IPA - 1
9512 ! IPPER = 0
9513 ! RETURN
9514 ! 310 IPPER = -1
9515 ! LREQ = 2 + (2*N + 1)/LRAT
9516 ! LREQ = MAX(LENWK+1,LREQ)
9517 ! RETURN
9518 ! 320 IPPER = -2
9519 ! LREQ = (LREQ - 1)/LRAT + 1
9520 ! RETURN
9521 ! 330 IPPER = -3
9522 ! CALL CNTNZU (N, IWK(IPIAN), IWK(IPJAN), NZSUT)
9523 ! LREQ = LENWK - IESP + (3*N + 4*NZSUT - 1)/LRAT + 1
9524 ! RETURN
9525 ! 340 IPPER = -4
9526 ! RETURN
9527 ! 350 IPPER = -5
9528 ! RETURN
9529 ! 360 IPPER = -6
9530 ! LREQ = LENWK
9531 ! RETURN
9532 ! 370 IPPER = -IER - 5
9533 ! LREQ = 2 + (2*N + 1)/LRAT
9534 ! RETURN
9535 !----------------------- End of Subroutine DPREPI ----------------------
9536 ! END SUBROUTINE DPREPI
9537 ! ECK DAINVGS
9538 ! SUBROUTINE DAINVGS (NEQ, T, Y, WK, IWK, TEM, YDOT, IER, RES, ADDA)
9539 ! EXTERNAL RES, ADDA
9540 ! INTEGER :: NEQ, IWK, IER
9541 ! INTEGER :: IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
9542 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
9543 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
9544 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
9545 ! INTEGER :: I, IMUL, J, K, KMIN, KMAX
9546 ! DOUBLE PRECISION :: T, Y, WK, TEM, YDOT
9547 ! DOUBLE PRECISION :: RLSS
9548 ! DIMENSION Y(*), WK(*), IWK(*), TEM(*), YDOT(*)
9549 ! COMMON /DLSS01/ RLSS(6), &
9550 ! IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
9551 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
9552 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
9553 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
9554 !-----------------------------------------------------------------------
9555 ! This subroutine computes the initial value of the vector YDOT
9556 ! satisfying
9557 ! A * YDOT = g(t,y)
9558 ! when A is nonsingular. It is called by DLSODIS for initialization
9559 ! only, when ISTATE = 0. The matrix A is subjected to LU
9560 ! decomposition in CDRV. Then the system A*YDOT = g(t,y) is solved
9561 ! in CDRV.
9562 ! In addition to variables described previously, communication
9563 ! with DAINVGS uses the following:
9564 ! Y = array of initial values.
9565 ! WK = real work space for matrices. On output it contains A and
9566 ! its LU decomposition. The LU decomposition is not entirely
9567 ! sparse unless the structure of the matrix A is identical to
9568 ! the structure of the Jacobian matrix dr/dy.
9569 ! Storage of matrix elements starts at WK(3).
9570 ! WK(1) = SQRT(UROUND), not used here.
9571 ! IWK = integer work space for matrix-related data, assumed to
9572 ! be equivalenced to WK. In addition, WK(IPRSP) and WK(IPISP)
9573 ! are assumed to have identical locations.
9574 ! TEM = vector of work space of length N (ACOR in DSTODI).
9575 ! YDOT = output vector containing the initial dy/dt. YDOT(i) contains
9576 ! dy(i)/dt when the matrix A is non-singular.
9577 ! IER = output error flag with the following values and meanings:
9578 ! = 0 if DAINVGS was successful.
9579 ! = 1 if the A-matrix was found to be singular.
9580 ! = 2 if RES returned an error flag IRES = IER = 2.
9581 ! = 3 if RES returned an error flag IRES = IER = 3.
9582 ! = 4 if insufficient storage for CDRV (should not occur here).
9583 ! = 5 if other error found in CDRV (should not occur here).
9584 !-----------------------------------------------------------------------
9585 ! DO 10 I = 1,NNZ
9586 ! WK(IBA+I) = 0.0D0
9587 ! 10 END DO
9588 ! IER = 1
9589 ! CALL RES (NEQ, T, Y, WK(IPA), YDOT, IER)
9590 ! IF (IER > 1) RETURN
9591 ! KMIN = IWK(IPIAN)
9592 ! DO 30 J = 1,NEQ
9593 ! KMAX = IWK(IPIAN+J) - 1
9594 ! DO 15 K = KMIN,KMAX
9595 ! I = IWK(IBJAN+K)
9596 ! TEM(I) = 0.0D0
9597 ! 15 END DO
9598 ! CALL ADDA (NEQ, T, Y, J, IWK(IPIAN), IWK(IPJAN), TEM)
9599 ! DO 20 K = KMIN,KMAX
9600 ! I = IWK(IBJAN+K)
9601 ! WK(IBA+K) = TEM(I)
9602 ! 20 END DO
9603 ! KMIN = KMAX + 1
9604 ! 30 END DO
9605 ! NLU = NLU + 1
9606 ! IER = 0
9607 ! DO 40 I = 1,NEQ
9608 ! TEM(I) = 0.0D0
9609 ! 40 END DO
9610 ! Numerical factorization of matrix A. ---------------------------------
9611 ! CALL CDRV (NEQ,IWK(IPR),IWK(IPC),IWK(IPIC),IWK(IPIAN),IWK(IPJAN), &
9612 ! WK(IPA),TEM,TEM,NSP,IWK(IPISP),WK(IPRSP),IESP,2,IYS)
9613 ! IF (IYS == 0) GO TO 50
9614 ! IMUL = (IYS - 1)/NEQ
9615 ! IER = 5
9616 ! IF (IMUL == 8) IER = 1
9617 ! IF (IMUL == 10) IER = 4
9618 ! RETURN
9619 ! Solution of the linear system. ---------------------------------------
9620 ! 50 CALL CDRV (NEQ,IWK(IPR),IWK(IPC),IWK(IPIC),IWK(IPIAN),IWK(IPJAN), &
9621 ! WK(IPA),YDOT,YDOT,NSP,IWK(IPISP),WK(IPRSP),IESP,4,IYS)
9622 ! IF (IYS /= 0) IER = 5
9623 ! RETURN
9624 !----------------------- End of Subroutine DAINVGS ---------------------
9625 ! END SUBROUTINE DAINVGS
9626 ! ECK DPRJIS
9627 ! SUBROUTINE DPRJIS (NEQ, Y, YH, NYH, EWT, RTEM, SAVR, S, WK, IWK, &
9628 ! RES, JAC, ADDA)
9629 ! EXTERNAL RES, JAC, ADDA
9630 ! INTEGER :: NEQ, NYH, IWK
9631 ! DOUBLE PRECISION :: Y, YH, EWT, RTEM, SAVR, S, WK
9632 ! DIMENSION NEQ(*), Y(*), YH(NYH,*), EWT(*), RTEM(*), &
9633 ! S(*), SAVR(*), WK(*), IWK(*)
9634 ! INTEGER :: IOWND, IOWNS, &
9635 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
9636 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
9637 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
9638 ! INTEGER :: IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
9639 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
9640 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
9641 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
9642 ! DOUBLE PRECISION :: ROWNS, &
9643 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND
9644 ! DOUBLE PRECISION :: RLSS
9645 ! COMMON /DLS001/ ROWNS(209), &
9646 ! CCMAX, EL0, H, HMIN, HMXI, HU, RC, TN, UROUND, &
9647 ! IOWND(6), IOWNS(6), &
9648 ! ICF, IERPJ, IERSL, JCUR, JSTART, KFLAG, L, &
9649 ! LYH, LEWT, LACOR, LSAVF, LWM, LIWM, METH, MITER, &
9650 ! MAXORD, MAXCOR, MSBP, MXNCF, N, NQ, NST, NFE, NJE, NQU
9651 ! COMMON /DLSS01/ RLSS(6), &
9652 ! IPLOST, IESP, ISTATC, IYS, IBA, IBIAN, IBJAN, IBJGP, &
9653 ! IPIAN, IPJAN, IPJGP, IPIGP, IPR, IPC, IPIC, IPISP, IPRSP, IPA, &
9654 ! LENYH, LENYHM, LENWK, LREQ, LRAT, LREST, LWMIN, MOSS, MSBJ, &
9655 ! NSLJ, NGP, NLU, NNZ, NSP, NZL, NZU
9656 ! INTEGER :: I, IMUL, IRES, J, JJ, JMAX, JMIN, K, KMAX, KMIN, NG
9657 ! DOUBLE PRECISION :: CON, FAC, HL0, R, SRUR
9658 !-----------------------------------------------------------------------
9659 ! DPRJIS is called to compute and process the matrix
9660 ! P = A - H*EL(1)*J, where J is an approximation to the Jacobian dr/dy,
9661 ! where r = g(t,y) - A(t,y)*s. J is computed by columns, either by
9662 ! the user-supplied routine JAC if MITER = 1, or by finite differencing
9663 ! if MITER = 2. J is stored in WK, rescaled, and ADDA is called to
9664 ! generate P. The matrix P is subjected to LU decomposition in CDRV.
9665 ! P and its LU decomposition are stored separately in WK.
9666 ! In addition to variables described previously, communication
9667 ! with DPRJIS uses the following:
9668 ! Y = array containing predicted values on entry.
9669 ! RTEM = work array of length N (ACOR in DSTODI).
9670 ! SAVR = array containing r evaluated at predicted y. On output it
9671 ! contains the residual evaluated at current values of t and y.
9672 ! S = array containing predicted values of dy/dt (SAVF in DSTODI).
9673 ! WK = real work space for matrices. On output it contains P and
9674 ! its sparse LU decomposition. Storage of matrix elements
9675 ! starts at WK(3).
9676 ! WK also contains the following matrix-related data.
9677 ! WK(1) = SQRT(UROUND), used in numerical Jacobian increments.
9678 ! IWK = integer work space for matrix-related data, assumed to be
9679 ! equivalenced to WK. In addition, WK(IPRSP) and IWK(IPISP)
9680 ! are assumed to have identical locations.
9681 ! EL0 = EL(1) (input).
9682 ! IERPJ = output error flag (in COMMON).
9683 ! = 0 if no error.
9684 ! = 1 if zero pivot found in CDRV.
9685 ! = IRES (= 2 or 3) if RES returned IRES = 2 or 3.
9686 ! = -1 if insufficient storage for CDRV (should not occur).
9687 ! = -2 if other error found in CDRV (should not occur here).
9688 ! JCUR = output flag = 1 to indicate that the Jacobian matrix
9689 ! (or approximation) is now current.
9690 ! This routine also uses other variables in Common.
9691 !-----------------------------------------------------------------------
9692 ! HL0 = H*EL0
9693 ! CON = -HL0
9694 ! JCUR = 1
9695 ! NJE = NJE + 1
9696 ! GO TO (100, 200), MITER
9697 ! If MITER = 1, call RES, then call JAC and ADDA for each column. ------
9698 ! 100 IRES = 1
9699 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
9700 ! NFE = NFE + 1
9701 ! IF (IRES > 1) GO TO 600
9702 ! KMIN = IWK(IPIAN)
9703 ! DO 130 J = 1,N
9704 ! KMAX = IWK(IPIAN+J)-1
9705 ! DO 110 I = 1,N
9706 ! RTEM(I) = 0.0D0
9707 ! 110 END DO
9708 ! CALL JAC (NEQ, TN, Y, S, J, IWK(IPIAN), IWK(IPJAN), RTEM)
9709 ! DO 120 I = 1,N
9710 ! RTEM(I) = RTEM(I)*CON
9711 ! 120 END DO
9712 ! CALL ADDA (NEQ, TN, Y, J, IWK(IPIAN), IWK(IPJAN), RTEM)
9713 ! DO 125 K = KMIN,KMAX
9714 ! I = IWK(IBJAN+K)
9715 ! WK(IBA+K) = RTEM(I)
9716 ! 125 END DO
9717 ! KMIN = KMAX + 1
9718 ! 130 END DO
9719 ! GO TO 290
9720 ! If MITER = 2, make NGP + 1 calls to RES to approximate J and P. ------
9721 ! 200 CONTINUE
9722 ! IRES = -1
9723 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
9724 ! NFE = NFE + 1
9725 ! IF (IRES > 1) GO TO 600
9726 ! SRUR = WK(1)
9727 ! JMIN = IWK(IPIGP)
9728 ! DO 240 NG = 1,NGP
9729 ! JMAX = IWK(IPIGP+NG) - 1
9730 ! DO 210 J = JMIN,JMAX
9731 ! JJ = IWK(IBJGP+J)
9732 ! R = MAX(SRUR*ABS(Y(JJ)),0.01D0/EWT(JJ))
9733 ! Y(JJ) = Y(JJ) + R
9734 ! 210 END DO
9735 ! CALL RES (NEQ,TN,Y,S,RTEM,IRES)
9736 ! NFE = NFE + 1
9737 ! IF (IRES > 1) GO TO 600
9738 ! DO 230 J = JMIN,JMAX
9739 ! JJ = IWK(IBJGP+J)
9740 ! Y(JJ) = YH(JJ,1)
9741 ! R = MAX(SRUR*ABS(Y(JJ)),0.01D0/EWT(JJ))
9742 ! FAC = -HL0/R
9743 ! KMIN = IWK(IBIAN+JJ)
9744 ! KMAX = IWK(IBIAN+JJ+1) - 1
9745 ! DO 220 K = KMIN,KMAX
9746 ! I = IWK(IBJAN+K)
9747 ! RTEM(I) = (RTEM(I) - SAVR(I))*FAC
9748 ! 220 END DO
9749 ! CALL ADDA (NEQ, TN, Y, JJ, IWK(IPIAN), IWK(IPJAN), RTEM)
9750 ! DO 225 K = KMIN,KMAX
9751 ! I = IWK(IBJAN+K)
9752 ! WK(IBA+K) = RTEM(I)
9753 ! 225 END DO
9754 ! 230 END DO
9755 ! JMIN = JMAX + 1
9756 ! 240 END DO
9757 ! IRES = 1
9758 ! CALL RES (NEQ, TN, Y, S, SAVR, IRES)
9759 ! NFE = NFE + 1
9760 ! IF (IRES > 1) GO TO 600
9761 ! Do numerical factorization of P matrix. ------------------------------
9762 ! 290 NLU = NLU + 1
9763 ! IERPJ = 0
9764 ! DO 295 I = 1,N
9765 ! RTEM(I) = 0.0D0
9766 ! 295 END DO
9767 ! CALL CDRV (N,IWK(IPR),IWK(IPC),IWK(IPIC),IWK(IPIAN),IWK(IPJAN), &
9768 ! WK(IPA),RTEM,RTEM,NSP,IWK(IPISP),WK(IPRSP),IESP,2,IYS)
9769 ! IF (IYS == 0) RETURN
9770 ! IMUL = (IYS - 1)/N
9771 ! IERPJ = -2
9772 ! IF (IMUL == 8) IERPJ = 1
9773 ! IF (IMUL == 10) IERPJ = -1
9774 ! RETURN
9775 ! Error return for IRES = 2 or IRES = 3 return from RES. ---------------
9776 ! 600 IERPJ = IRES
9777 ! RETURN
9778 !----------------------- End of Subroutine DPRJIS ----------------------
9779 ! END SUBROUTINE DPRJIS