2 c-----------------------------------------------------------------------
3 c Demonstration program for the DLSODI package.
4 c This is the version of 14 June 2001.
6 c This version is in double precision.
8 C this program solves a semi-discretized form of the Burgers equation,
10 c u = -(u*u/2) + eta * u
13 c for a = -1 .le. x .le. 1 = b, t .ge. 0.
15 c Boundary conditions: u(-1,t) = u(1,t) = 0.
16 c Initial profile: square wave
17 c u(0,x) = 0 for 1/2 .lt. abs(x) .le. 1
18 c u(0,x) = 1/2 for abs(x) = 1/2
19 c u(0,x) = 1 for 0 .le. abs(x) .lt. 1/2
21 c An ODE system is generated by a simplified Galerkin treatment
22 c of the spatial variable x.
25 c R. C. Y. Chin, G. W. Hedstrom, and K. E. Karlsson,
26 c A Simplified Galerkin Method for Hyperbolic Equations,
27 c Math. Comp., vol. 33, no. 146 (April 1979), pp. 647-658.
29 c The problem is run with the DLSODI package with a 10-point mesh
30 c and a 100-point mesh. In each case, it is run with two tolerances
31 c and for various appropriate values of the method flag mf.
32 c Output is on unit lout, set to 6 in a data statement below.
33 c-----------------------------------------------------------------------
34 external res
, addabd
, addafl
, jacbd
, jacfl
35 integer i
, io
, istate
, itol
, iwork
, j
,
36 1 lout
, liw
, lrw
, meth
, miter
, mf
, ml
, mu
,
37 2 n
, nout
, npts
, nerr
,
38 3 nptsm1
, n14
, n34
, n14m1
, n14p1
, n34m1
, n34p1
40 double precision a
, b
, eta
, delta
,
41 1 zero
, fourth
, half
, one
, hun
,
42 2 t
, tout
, tlast
, tinit
, errfac
,
43 3 atol
, rtol
, rwork
, y
, ydoti
, elkup
44 double precision eodsq
, r4d
46 dimension y
(99), ydoti
(99), tout
(4), atol
(2), rtol
(2)
47 dimension rwork
(2002), iwork
(125)
48 c Pass problem parameters in the Common block test1.
49 common /test1
/ r4d
, eodsq
, nm1
51 c Set problem parameters and run parameters
52 data eta
/0.05d0
/, a
/-1.0d0
/, b
/1.0d0
/
53 data zero
/0.0d0
/, fourth
/0.25d0
/, half
/.5d0
/, one
/1.0d0
/,
55 data tinit
/0.0d0
/, tlast
/0.4d0
/
56 data tout
/.10d0
,.20d0
,.30d0
,.40d0
/
57 data ml
/1/, mu
/1/, lout
/6/
58 data nout
/4/, lrw
/2002/, liw
/125/
59 data itol
/1/, rtol
/1.0d
-3, 1.0d
-6/, atol
/1.0d
-3, 1.0d
-6/
65 c Loop over two values of npts.
66 do 300 npts
= 10, 100, 90
68 c Compute the mesh width delta and other parameters.
82 c Set the initial profile (for output purposes only).
90 do 30 i
= n34p1
,nptsm1
93 if (npts
.gt
. 10) write (lout
,1010)
95 write (lout
,1100) eta
,a
,b
,tinit
,tlast
,ml
,mu
,n
(1)
96 write (lout
,1200) zero
, (y
(i
), i
=1,n
(1)), zero
98 c The j loop is over error tolerances.
102 c Loop over method flag loop (for demonstration).
106 if (miter
.eq
. 3) go to 100
107 if (miter
.le
. 2 .and
. npts
.gt
. 10) go to 100
108 if (miter
.eq
. 5 .and
. npts
.lt
. 100) go to 100
111 c Set the initial profile.
116 do 50 i
= n14p1
,n34m1
119 do 60 i
= n34p1
,nptsm1
125 write (lout
,1500) rtol
(j
), atol
(j
), mf
, npts
127 c Output loop for each case
132 if (miter
.le
. 2) call dlsodi
(res
, addafl
, jacfl
, n
, y
,
133 1 ydoti
, t
, tout
(io
), itol
, rtol
(j
), atol
(j
),
134 2 1, istate
, 0, rwork
, lrw
, iwork
, liw
, mf
)
135 if (miter
.ge
. 4) call dlsodi
(res
, addabd
, jacbd
, n
, y
,
136 1 ydoti
, t
, tout
(io
), itol
, rtol
(j
), atol
(j
),
137 2 1, istate
, 0, rwork
, lrw
, iwork
, liw
, mf
)
138 write (lout
,2000) t
, rwork
(11), iwork
(14),(y
(i
), i
=1,n
(1))
140 c If istate is not 2 on return, print message and loop.
141 if (istate
.ne
. 2) then
142 write (lout
,4000) mf
, t
, istate
149 write (lout
,3000) mf
, iwork
(11), iwork
(12), iwork
(13),
150 1 iwork
(17), iwork
(18)
152 c Estimate final error and print result.
154 errfac
= elkup
( itemp
, y
, rwork
(21), itol
, rtol
(j
), atol
(j
) )
155 if (errfac
.gt
. hun
) then
156 write (lout
,5001) errfac
159 write (lout
,5000) errfac
165 write (lout
,6000) nerr
168 1000 format(20x
,' Demonstration Problem for DLSODI')
169 1010 format(///80('*')///)
170 1100 format(/10x
,' Simplified Galerkin Solution of Burgers Equation'//
171 1 13x
,'Diffusion coefficient is eta =',d10
.2
/
172 2 13x
,'Uniform mesh on interval',d12
.3
,' to ',d12
.3
/
173 3 13x
,'Zero boundary conditions'/
174 4 13x
,'Time limits: t0 = ',d12
.5
,' tlast = ',d12
.5
/
175 5 13x
,'Half-bandwidths ml = ',i2
,' mu = ',i2
/
176 6 13x
,'System size neq = ',i3
/)
178 1200 format('Initial profile:'/17(6d12
.4
/))
180 1500 format(///80('-')///'Run with rtol =',d12
.2
,' atol =',d12
.2
,
181 1 ' mf =',i3
,' npts =',i4
,':'//)
183 2000 format('Output for time t = ',d12
.5
,' current h =',
184 1 d12
.5
,' current order =',i2
,':'/17(6d12
.4
/))
186 3000 format(//'Final statistics for mf = ',i2
,':'/
187 1 i4
,' steps,',i5
,' res,',i4
,' Jacobians,',
188 2 ' rwork size =',i6
,', iwork size =',i6
)
190 4000 format(///80('*')//20x
,'Final time reached for mf = ',i2
,
191 1 ' was t = ',d12
.5
/25x
,'at which istate = ',i2
////80('*'))
192 5000 format(' Final output is correct to within ',d8
.1
,
193 1 ' times local error tolerance')
194 5001 format(' Final output is wrong by ',d8
.1
,
195 1 ' times local error tolerance')
196 6000 format(//80('*')//
197 1 'Run completed. Number of errors encountered =',i3
)
199 c end of main program for the DLSODI demonstration problem.
202 subroutine gfun
(n
, t
, y
, g
)
203 c This subroutine computes the right-hand side function g(y,t).
204 c It uses r4d = 1/(4*delta), eodsq = eta/delta**2, and nm1 = n - 1
205 c from the Common block test1.
208 double precision t
, y
, g
, r4d
, eodsq
, two
210 common /test1
/ r4d
, eodsq
, nm1
213 g
(1) = -r4d*y
(2)**2 + eodsq*
(y
(2) - two*y
(1))
216 g
(i
) = r4d*
(y
(i
-1)**2 - y
(i
+1)**2)
217 1 + eodsq*
(y
(i
+1) - two*y
(i
) + y
(i
-1))
220 g
(n
) = r4d*y
(nm1
)**2 + eodsq*
(y
(nm1
) - two*y
(n
))
223 c end of subroutine gfun for the DLSODI demonstration problem.
226 subroutine res
(n
, t
, y
, v
, r
, ires
)
227 c This subroutine computes the residual vector
228 c r = g(t,y) - A(t,y)*v .
229 c It uses nm1 = n - 1 from Common.
230 c If ires = -1, only g(t,y) is returned in r, since A(t,y) does
233 integer i
, ires
, n
, nm1
234 double precision t
, y
, v
, r
, r4d
, eodsq
, one
, four
, six
,
236 dimension y
(*), v
(*), r
(*)
239 common /test1
/ r4d
, eodsq
, nm1
240 data one
/1.0d0
/, four
/4.0d0
/, six
/6.0d0
/
243 call gfun
(itemp
, t
, y
, r
)
244 if (ires
.eq
. -1) return
248 r
(1) = r
(1) - (fact4*v
(1) + fact1*v
(2))
250 10 r
(i
) = r
(i
) - (fact1*v
(i
-1) + fact4*v
(i
) + fact1*v
(i
+1))
251 r
(n
(1)) = r
(n
(1)) - (fact1*v
(nm1
) + fact4*v
(n
(1)))
253 c end of subroutine res for the DLSODI demonstration problem.
256 subroutine addabd
(n
, t
, y
, ml
, mu
, pa
, m0
)
257 c This subroutine computes the matrix A in band form, adds it to pa,
258 c and returns the sum in pa. The matrix A is tridiagonal, of order n,
259 c with nonzero elements (reading across) of 1/6, 4/6, 1/6.
261 integer i
, n
, m0
, ml
, mu
, mup1
, mup2
262 double precision t
, y
, pa
, fact1
, fact4
, one
, four
, six
263 dimension y
(*), pa
(m0
,*)
265 data one
/1.0d0
/, four
/4.0d0
/, six
/6.0d0
/
270 c Compute the elements of A.
273 c Add the matrix A to the matrix pa (banded).
275 pa
(mu
,i
) = pa
(mu
,i
) + fact1
276 pa
(mup1
,i
) = pa
(mup1
,i
) + fact4
277 pa
(mup2
,i
) = pa
(mup2
,i
) + fact1
280 c end of subroutine addabd for the DLSODI demonstration problem.
283 subroutine addafl
(n
, t
, y
, ml
, mu
, pa
, m0
)
284 c This subroutine computes the matrix A in full form, adds it to
285 c pa, and returns the sum in pa.
286 c It uses nm1 = n - 1 from Common.
287 c The matrix A is tridiagonal, of order n, with nonzero elements
288 c (reading across) of 1/6, 4/6, 1/6.
290 integer i
, n
, m0
, ml
, mu
, nm1
291 double precision t
, y
, pa
, r4d
, eodsq
, one
, four
, six
,
293 dimension y
(*), pa
(m0
,8)
295 common /test1
/ r4d
, eodsq
, nm1
296 data one
/1.0d0
/, four
/4.0d0
/, six
/6.0d0
/
298 c Compute the elements of A.
302 c Add the matrix A to the matrix pa (full).
305 pa
(i
,i
+1) = pa
(i
,i
+1) + fact1
306 pa
(i
,i
) = pa
(i
,i
) + fact4
307 pa
(i
,i
-1) = pa
(i
,i
-1) + fact1
309 pa
(1,2) = pa
(1,2) + fact1
310 pa
(1,1) = pa
(1,1) + fact4
311 pa
(n
(1),n
(1)) = pa
(n
(1),n
(1)) + fact4
312 pa
(n
(1),nm1
) = pa
(n
(1),nm1
) + fact1
314 c end of subroutine addafl for the DLSODI demonstration problem.
317 subroutine jacbd
(n
, t
, y
, s
, ml
, mu
, pa
, m0
)
318 c This subroutine computes the Jacobian dg/dy = d(g-a*s)/dy
319 c and stores elements
321 c dg /dy in pa(i-j+mu+1,j) in band matrix format.
322 c It uses r4d = 1/(4*delta), eodsq = eta/delta**2, and nm1 = n - 1
323 c from the Common block test1.
325 integer i
, n
, m0
, ml
, mu
, mup1
, mup2
, nm1
326 double precision t
, y
, s
, pa
, diag
, r4d
, eodsq
, two
, r2d
327 dimension y
(*), s
(*), pa
(m0
,*)
329 common /test1
/ r4d
, eodsq
, nm1
337 c Compute and store dg /dy
341 c Compute and store dg /dy
342 pa
(mu
,2) = -r2d*y
(2) + eodsq
347 c Compute and store dg /dy
348 pa
(mup2
,i
-1) = r2d*y
(i
-1) + eodsq
351 c Compute and store dg /dy
355 c Compute and store dg /dy
356 pa
(mu
,i
+1) = -r2d*y
(i
+1) + eodsq
360 c Compute and store dg /dy
361 pa
(mup2
,nm1
) = r2d*y
(nm1
) + eodsq
364 c Compute and store dg /dy
368 c end of subroutine jacbd for the DLSODI demonstration problem.
371 subroutine jacfl
(n
, t
, y
, s
, ml
, mu
, pa
, m0
)
372 c This subroutine computes the Jacobian dg/dy = d(g-a*s)/dy
373 c and stores elements
375 c dg /dy in pa(i,j) in full matrix format.
376 c It uses r4d = 1/(4*delta), eodsq = eta/delta**2, and nm1 = n - 1
377 c from the Common block test1.
379 integer i
, n
, m0
, ml
, mu
, nm1
380 double precision t
, y
, s
, pa
, diag
, r4d
, eodsq
, two
, r2d
381 dimension y
(*), s
(8), pa
(m0
,*)
383 common /test1
/ r4d
, eodsq
, nm1
390 c Compute and store dg /dy
394 c Compute and store dg /dy
395 pa
(1,2) = -r2d*y
(2) + eodsq
400 c Compute and store dg /dy
401 pa
(i
,i
-1) = r2d*y
(i
-1) + eodsq
404 c Compute and store dg /dy
408 c Compute and store dg /dy
409 pa
(i
,i
+1) = -r2d*y
(i
+1) + eodsq
413 c Compute and store dg /dy
414 pa
(n
(1),nm1
) = r2d*y
(nm1
) + eodsq
417 c Compute and store dg /dy
421 c end of subroutine jacfl for the DLSODI demonstration problem.
424 double precision function elkup
(n
, y
, ewt
, itol
, rtol
, atol
)
425 c This routine looks up approximately correct values of y at t = 0.4,
426 c ytrue = y9 or y99 depending on whether n = 9 or 99. These were
427 c obtained by running DLSODI with very tight tolerances.
428 c The returned value is
429 c elkup = norm of ( y - ytrue ) / ( rtol*abs(ytrue) + atol ).
432 double precision y
, ewt
, rtol
, atol
, y9
, y99
433 c double precision y99a, y99b, y99c,
434 c 1 y99d, y99e, y99f, y99g, dvnorm
435 dimension y
(n
), ewt
(n
), y9
(9), y99
(99)
436 dimension rtol
(*), atol
(*)
437 c dimension y99a(16), y99b(16), y99c(16), y99d(16), y99e(16),
438 c 1 y99f(16), y99g(3)
439 c equivalence (y99a(1),y99(1)), (y99b(1),y99(17)),
440 c 1 (y99c(1),y99(33)), (y99d(1),y99(49)), (y99e(1),y99(65)),
441 c 1 (y99f(1),y99(81)), (y99g(1),y99(97))
443 1 1.07001457d
-01, 2.77432492d
-01, 5.02444616d
-01, 7.21037157d
-01,
444 1 9.01670441d
-01, 8.88832048d
-01, 4.96572850d
-01, 9.46924362d
-02,
447 1 2.05114384d
-03, 4.19527452d
-03, 6.52533872d
-03, 9.13412751d
-03,
448 1 1.21140191d
-02, 1.55565301d
-02, 1.95516488d
-02, 2.41869487d
-02,
449 1 2.95465081d
-02, 3.57096839d
-02, 4.27498067d
-02, 5.07328729d
-02,
450 1 5.97163151d
-02, 6.97479236d
-02, 8.08649804d
-02, 9.30936515d
-02,
451 1 1.06448659d
-01, 1.20933239d
-01, 1.36539367d
-01, 1.53248227d
-01,
452 1 1.71030869d
-01, 1.89849031d
-01, 2.09656044d
-01, 2.30397804d
-01,
453 1 2.52013749d
-01, 2.74437805d
-01, 2.97599285d
-01, 3.21423708d
-01,
454 1 3.45833531d
-01, 3.70748792d
-01, 3.96087655d
-01, 4.21766871d
-01,
455 1 4.47702161d
-01, 4.73808532d
-01, 5.00000546d
-01, 5.26192549d
-01,
456 1 5.52298887d
-01, 5.78234121d
-01, 6.03913258d
-01, 6.29252015d
-01,
457 1 6.54167141d
-01, 6.78576790d
-01, 7.02400987d
-01, 7.25562165d
-01,
458 1 7.47985803d
-01, 7.69601151d
-01, 7.90342031d
-01, 8.10147715d
-01,
459 1 8.28963844d
-01, 8.46743353d
-01, 8.63447369d
-01, 8.79046021d
-01,
460 1 8.93519106d
-01, 9.06856541d
-01, 9.19058529d
-01, 9.30135374d
-01,
461 1 9.40106872d
-01, 9.49001208d
-01, 9.56853318d
-01, 9.63702661d
-01,
462 1 9.69590361d
-01, 9.74555682d
-01, 9.78631814d
-01, 9.81840924d
-01,
463 1 9.84188430d
-01, 9.85656465d
-01, 9.86196496d
-01, 9.85721098d
-01,
464 1 9.84094964d
-01, 9.81125395d
-01, 9.76552747d
-01, 9.70041743d
-01,
465 1 9.61175143d
-01, 9.49452051d
-01, 9.34294085d
-01, 9.15063568d
-01,
466 1 8.91098383d
-01, 8.61767660d
-01, 8.26550038d
-01, 7.85131249d
-01,
467 1 7.37510044d
-01, 6.84092540d
-01, 6.25748369d
-01, 5.63802368d
-01,
468 1 4.99946558d
-01, 4.36077986d
-01, 3.74091566d
-01, 3.15672765d
-01,
469 1 2.62134958d
-01, 2.14330497d
-01, 1.72640946d
-01, 1.37031155d
-01,
470 1 1.07140815d
-01, 8.23867920d
-02, 6.20562432d
-02, 4.53794321d
-02,
471 1 3.15789227d
-02, 1.98968820d
-02, 9.60472135d
-03 /
473 if (n
.eq
. 99) go to 99
475 c Compute local error tolerance using correct y (n = 9).
477 call dewset
( n
, itol
, rtol
, atol
, y9
, ewt
)
479 c Invert ewt and replace y by the error, y - ytrue.
482 ewt
(i
) = 1.0d0
/ewt
(i
)
483 20 y
(i
) = y
(i
) - y9
(i
)
486 c Compute local error tolerance using correct y (n = 99).
488 99 call dewset
( n
, itol
, rtol
, atol
, y99
, ewt
)
490 c Invert ewt and replace y by the error, y - ytrue.
493 ewt
(i
) = 1.0d0
/ewt
(i
)
494 120 y
(i
) = y
(i
) - y99
(i
)
496 c Find weighted norm of the error and return.
498 200 elkup
= dvnorm
(n
, y
, ewt
)
500 c end of function elkup for the DLSODI demonstration program.