C$TEST DPOST8 c main program common /cstak/ ds double precision ds(5000) common /time/ t double precision t common /kmesh/ k, nmesh integer k, nmesh common /cmesh/ mesh double precision mesh(100) external dee, handle, uofx, bc, af integer ndx, i, is(1000), nu, nv real errpar(2), rs(1000) logical ls(1000) complex cs(500) double precision u(100), v(100), dt, ws(500), tstop integer temp equivalence (ds(1), cs(1), ws(1), rs(1), is(1), ls(1)) c to test dpost on the integro-pde c u sub t = 2 * u sub xx - int(0,1) exp(x-y)*u(y) dy on (0,1) c subject to given dirichlet bcs, chosen so that the solution is c u(x,t) = exp(t+x). c the port library stack and its aliases. c initialize the port library stack length. call istkin(5000, 4) nu = 1 errpar(1) = 0 c absolute error. errpar(2) = 1e-2 tstop = 1 dt = 1d-2 k = 4 c ndx uniform mesh points on (0,1). ndx = 7 call dumb(0d0, 1d0, ndx, k, mesh, nmesh) nv = nmesh-k c uofx needs t. t = 0 c ics for u. call dl2sff(uofx, k, mesh, nmesh, u) temp = nmesh-k do 1 i = 1, temp v(i) = u(i) 1 continue c ics for v. call dpost(u, nu, k, mesh, nmesh, v, nv, 0d0, tstop, dt, af, bc, 1 dee, errpar, handle) call wrapup stop end subroutine af(t, x, nx, u, ux, ut, utx, nu, v, vt, nv, a, 1 au, aux, aut, autx, av, avt, f, fu, fux, fut, futx, fv, fvt) integer nu, nv, nx double precision t, x(nx), u(nx, nu), ux(nx, nu), ut(nx, nu), utx( 1 nx, nu) double precision v(nv), vt(nv), a(nx, nu), au(nx, nu, nu), aux(nx, 1 nu, nu), aut(nx, nu, nu) double precision autx(nx, nu, nu), av(nx, nu, nv), avt(nx, nu, nv) 1 , f(nx, nu), fu(nx, nu, nu), fux(nx, nu, nu) double precision fut(nx, nu, nu), futx(nx, nu, nu), fv(nx, nu, nv) 1 , fvt(nx, nu, nv) common /kmesh/ k, nmesh integer k, nmesh common /cmesh/ mesh double precision mesh(100) integer i do 1 i = 1, nx a(i, 1) = 2d0*ux(i, 1) aux(i, 1, 1) = 2 f(i, 1) = ut(i, 1) fut(i, 1, 1) = 1 1 continue c get the integral. call intgrl(k, mesh, nmesh, v, x, nx, f, fv) return end subroutine bc(t, l, r, u, ux, ut, utx, nu, v, vt, nv, b, bu, 1 bux, but, butx, bv, bvt) integer nu, nv double precision t, l, r, u(nu, 2), ux(nu, 2), ut(nu, 2) double precision utx(nu, 2), v(nv), vt(nv), b(nu, 2), bu(nu, nu, 2 1 ), bux(nu, nu, 2) double precision but(nu, nu, 2), butx(nu, nu, 2), bv(nu, nv, 2), 1 bvt(nu, nv, 2) double precision dexp b(1, 1) = u(1, 1)-dexp(t) b(1, 2) = u(1, 2)-dexp(t+1d0) bu(1, 1, 1) = 1 bu(1, 1, 2) = 1 return end subroutine dee(t, k, x, nx, u, ut, nu, nxmk, v, vt, nv, d, 1 du, dut, dv, dvt) integer nxmk, nu, nv, nx integer k double precision t, x(nx), u(nxmk, nu), ut(nxmk, nu), v(nv), vt( 1 nv) double precision d(nv), du(nv, nxmk, nu), dut(nv, nxmk, nu), dv( 1 nv, nv), dvt(nv, nv) integer i do 1 i = 1, nxmk d(i) = u(i, 1)-v(i) du(i, i, 1) = 1 dv(i, i) = -1 1 continue return end subroutine handle(t0, u0, v0, t, u, v, nu, nxmk, nv, k, x, 1 nx, dt, tstop) integer nxmk, nu, nv, nx integer k double precision t0, u0(nxmk, nu), v0(nv), t, u(nxmk, nu), v(nv) double precision x(nx), dt, tstop common /time/ tt double precision tt external uofx integer i1mach double precision deesff, eu integer temp c output and checking routine. if (t0 .ne. t) goto 2 temp = i1mach(2) write (temp, 1) t0, dt 1 format (16h restart for t =, 1pe10.2, 7h dt =, 1pe10.2) return 2 tt = t eu = deesff(k, x, nx, u, uofx) temp = i1mach(2) write (temp, 3) t, eu 3 format (14h error in u(x,, 1pe10.2, 4h ) =, 1pe10.2) return end subroutine uofx(x, nx, u, w) integer nx double precision x(nx), u(nx), w(nx) common /time/ t double precision t integer i double precision dexp do 1 i = 1, nx u(i) = dexp(t+x(i)) 1 continue return end subroutine intgrl(k, mesh, nmesh, v, x, nx, f, fv) integer nx, nmesh integer k double precision mesh(nmesh), v(1), x(nx), f(nx), fv(nx, 1) integer mgq, i, j, l, ix logical first double precision ewe, ker, wgq(3), xgq(3), b(3, 4, 200), keru double precision xx(3) integer temp, temp1 data first/.true./ c to compute c f = integral from mesh(1) to mesh(nmesh) c kernel(x,y,sum(i=1,...,nmesh-k) v(i)*b(i,y)) dy c and c fv = d(f)/d(v). c assume that call kernel(x,y,u,ker,keru) returns c ker = kernel(x,y,u) and c keru = partial kernel / partial u. c v(nmesh-k),fv(nx,nmesh-k) c the following declaration is specific to k = 4 splines. if (nmesh-k .gt. 200) call seterr(27hintgrl - nmesh-k .gt. nxmax 1 , 27, 1, 2) c need more local space. if (k .ne. 4) call seterr(17hintgrl - k .ne. 4, 17, 2, 2) c use k-1 point gaussian-quadrature rule on each interval. mgq = k-1 if (first) call dgqm11(mgq, xgq, wgq) c only get gq rule once, its expensive. c the gaussian quadrature rule. c do integral interval by interval. temp = nmesh-k do 6 i = k, temp c g.q. points on (mesh(i), mesh(i+1)). do 1 j = 1, mgq xx(j) = 0.5*(mesh(i+1)+mesh(i))+0.5*(mesh(i+1)-mesh(i))*xgq( 1 j) 1 continue if (first) call dbspln(k, mesh, nmesh, xx, mgq, i, b(1, 1, i)) c only get b-spline basis once, its expensive. do 5 j = 1, mgq c get sum() v()*b()(xx). ewe = 0 do 2 l = 1, k temp1 = i+l-k ewe = ewe+v(temp1)*b(j, l, i) 2 continue do 4 ix = 1, nx c get kernel and partial. call kernel(x(ix), xx(j), ewe, ker, keru) f(ix) = f(ix)+0.5*ker*(mesh(i+1)-mesh(i))*wgq(j) do 3 l = 1, k temp1 = i+l-k fv(ix, temp1) = fv(ix, temp1)+0.5*b(j, l, i)*keru*( 1 mesh(i+1)-mesh(i))*wgq(j) 3 continue 4 continue 5 continue 6 continue first = .false. return end subroutine kernel(x, y, u, ker, keru) double precision x, y, u, ker, keru double precision dexp c to evaluate the kernel exp(x-y)*u(y) and its partial wrt. u. keru = dexp(x-y) ker = keru*u return end