1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
C/MEMBR ADD NAME=PREPJ,SSI=0
subroutine prepj (neq, y, yh, nyh, ewt, ftem, savf, wm, iwm,
1 f, jac)
clll. optimize
external f, jac
integer neq, nyh, iwm
integer iownd, iowns,
1 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter,
2 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
integer i, i1, i2, ier, ii, j, j1, jj, lenp,
1 mba, mband, meb1, meband, ml, ml3, mu
double precision y, yh, ewt, ftem, savf, wm
double precision rownd, rowns,
1 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround
double precision con, di, fac, hl0, r, r0, srur, yi, yj, yjj,
1 vnorm
dimension neq(*), y(*), yh(nyh,*), ewt(*), ftem(*), savf(*),
1 wm(*), iwm(*)
integer iero
common /ierode/ iero
common /ls0001/ rownd, rowns(209),
2 ccmax, el0, h, hmin, hmxi, hu, rc, tn, uround,
3 iownd(14), iowns(6),
4 icf, ierpj, iersl, jcur, jstart, kflag, l, meth, miter,
5 maxord, maxcor, msbp, mxncf, n, nq, nst, nfe, nje, nqu
save/ls0001/
c-----------------------------------------------------------------------
c%purpose
c prepj is called by stode to compute and process the matrix
c p = i - h*el(1)*j , where j is an approximation to the jacobian.
c here j is computed by the user-supplied routine jac if
c miter = 1 or 4, or by finite differencing if miter = 2, 3, or 5.
c if miter = 3, a diagonal approximation to j is used.
c j is stored in wm and replaced by p. if miter .ne. 3, p is then
c subjected to lu decomposition in preparation for later solution
c of linear systems with p as coefficient matrix. this is done
c by dgefa if miter = 1 or 2, and by dgbfa if miter = 4 or 5.
c
c%additonal parameters
c in addition to variables described previously, communication
c with prepj uses the following..
c y = array containing predicted values on entry.
c ftem = work array of length n (acor in stode).
c savf = array containing f evaluated at predicted y.
c wm = real work space for matrices. on output it contains the
c inverse diagonal matrix if miter = 3 and the lu decomposition
c of p if miter is 1, 2 , 4, or 5.
c storage of matrix elements starts at wm(3).
c wm also contains the following matrix-related data..
c wm(1) = sqrt(uround), used in numerical jacobian increments.
c wm(2) = h*el0, saved for later use if miter = 3.
c iwm = integer work space containing pivot information, starting at
c iwm(21), if miter is 1, 2, 4, or 5. iwm also contains band
c parameters ml = iwm(1) and mu = iwm(2) if miter is 4 or 5.
c el0 = el(1) (input).
c ierpj = output error flag, = 0 if no trouble, .gt. 0 if
c p matrix found to be singular.
c jcur = output flag = 1 to indicate that the jacobian matrix
c (or approximation) is now current.
c this routine also uses the common variables el0, h, tn, uround,
c miter, n, nfe, and nje.
c!
c-----------------------------------------------------------------------
nje = nje + 1
ierpj = 0
jcur = 1
hl0 = h*el0
go to (100, 200, 300, 400, 500), miter
c if miter = 1, call jac and multiply by scalar. -----------------------
100 lenp = n*n
do 110 i = 1,lenp
110 wm(i+2) = 0.0d+0
call jac (neq, tn, y, 0, 0, wm(3), n)
if(iero.gt.0) return
con = -hl0
do 120 i = 1,lenp
120 wm(i+2) = wm(i+2)*con
go to 240
c if miter = 2, make n calls to f to approximate j. --------------------
200 fac = vnorm (n, savf, ewt)
r0 = 1000.0d+0*abs(h)*uround*dble(n)*fac
if (r0 .eq. 0.0d+0) r0 = 1.0d+0
srur = wm(1)
j1 = 2
do 230 j = 1,n
yj = y(j)
r = max(srur*abs(yj),r0/ewt(j))
y(j) = y(j) + r
fac = -hl0/r
call f (neq, tn, y, ftem)
if(iero.gt.0) return
do 220 i = 1,n
220 wm(i+j1) = (ftem(i) - savf(i))*fac
y(j) = yj
j1 = j1 + n
230 continue
nfe = nfe + n
c add identity matrix. -------------------------------------------------
240 j = 3
do 250 i = 1,n
wm(j) = wm(j) + 1.0d+0
250 j = j + (n + 1)
c do lu decomposition on p. --------------------------------------------
call dgefa (wm(3), n, n, iwm(21), ier)
if (ier .ne. 0) ierpj = 1
return
c if miter = 3, construct a diagonal approximation to j and p. ---------
300 wm(2) = hl0
r = el0*0.10d+0
do 310 i = 1,n
310 y(i) = y(i) + r*(h*savf(i) - yh(i,2))
call f (neq, tn, y, wm(3))
if(iero.gt.0) return
nfe = nfe + 1
do 320 i = 1,n
r0 = h*savf(i) - yh(i,2)
di = 0.10d+0*r0 - h*(wm(i+2) - savf(i))
wm(i+2) = 1.0d+0
if (abs(r0) .lt. uround/ewt(i)) go to 320
if (abs(di) .eq. 0.0d+0) go to 330
wm(i+2) = 0.10d+0*r0/di
320 continue
return
330 ierpj = 1
return
c if miter = 4, call jac and multiply by scalar. -----------------------
400 ml = iwm(1)
mu = iwm(2)
cc mod 06-01-89
cc ml3 = ml + 3
ml3 = 3
cc fin
mband = ml + mu + 1
meband = mband + ml
lenp = meband*n
do 410 i = 1,lenp
410 wm(i+2) = 0.0d+0
call jac (neq, tn, y, ml, mu, wm(ml3), meband)
if(iero.gt.0) return
con = -hl0
do 420 i = 1,lenp
420 wm(i+2) = wm(i+2)*con
go to 570
c if miter = 5, make mband calls to f to approximate j. ----------------
500 ml = iwm(1)
mu = iwm(2)
mband = ml + mu + 1
mba = min(mband,n)
meband = mband + ml
meb1 = meband - 1
srur = wm(1)
fac = vnorm (n, savf, ewt)
r0 = 1000.0d+0*abs(h)*uround*dble(n)*fac
if (r0 .eq. 0.0d+0) r0 = 1.0d+0
do 560 j = 1,mba
do 530 i = j,n,mband
yi = y(i)
r = max(srur*abs(yi),r0/ewt(i))
530 y(i) = y(i) + r
call f (neq, tn, y, ftem)
if(iero.gt.0) return
do 550 jj = j,n,mband
y(jj) = yh(jj,1)
yjj = y(jj)
r = max(srur*abs(yjj),r0/ewt(jj))
fac = -hl0/r
i1 = max(jj-mu,1)
i2 = min(jj+ml,n)
ii = jj*meb1 - ml + 2
do 540 i = i1,i2
540 wm(ii+i) = (ftem(i) - savf(i))*fac
550 continue
560 continue
nfe = nfe + mba
c add identity matrix. -------------------------------------------------
570 ii = mband + 2
do 580 i = 1,n
wm(ii) = wm(ii) + 1.0d+0
580 ii = ii + meband
c do lu decomposition of p. --------------------------------------------
call dgbfa (wm(3), meband, n, ml, mu, iwm(21), ier)
if (ier .ne. 0) ierpj = 1
return
c----------------------- end of subroutine prepj -----------------------
end
|