f2kodepack
Reference documentation for version 0.0
Main Page
Related Pages
Modules
Files
File List
source_new
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
Generated on Thu Jan 5 2017 13:37:15 for f2kodepack by
1.8.11