c----------------------------------------------------------------------- c FORTRAN 77 routines for 2D wave equation solution c----------------------------------------------------------------------- c Routine to read in grid properties and initial data parameters c subroutine readinput(nx, ny, xmin, xmax, ymin, ymax,cfl, . amplitude, width, vx, vy, niters, ml, thresh) implicit none integer nx, ny integer niters, ml real*8 xmin, xmax, ymin, ymax, . cfl, amplitude, width, vx, vy, thresh c Open file and read in parameters open(unit=1,file='wave2d.in') read(1,*)nx, ny read(1,*)xmin, xmax read(1,*)ymin, ymax read(1,*)width read(1,*)amplitude read(1,*)vx, vy read(1,*)cfl read(1,*)niters read(1,*)ml read(1,*)thresh close(unit=1) return end c----------------------------------------------------------------------- c Routine to initialize data subroutine initial(lb, ub, shape, phi0, A0, B0, C0, . h, dt, ampl, width, vx, vy, xmin, ymin) implicit none integer lb(2), ub(2), shape(2) real*8 phi0(shape(1), shape(2)), . A0(shape(1), shape(2)), . B0(shape(1), shape(2)), . C0(shape(1), shape(2)) real*8 h, dt, ampl, width, vx, vy, xmin, ymin c Local variables integer i, j real*8 x, y, t c Initialize a0, b0, c0 based on what phi0 and dtphi0 are c Carry out simple minded initial data for dtphi0 for now and c Gaussian wave-packet for phi0 t = 0.0 do i = 1, shape(1) do j = 1, shape(2) x = h * (lb(1)/2 +i-1) + xmin y = h * (lb(2)/2 +j-1) + ymin phi0(i,j) = ampl * exp(-((x - vx*t)**2 + . (y - vy*t)**2)/width**2) end do end do c Initialize a0, b0, c0 do i = 1, shape(1) do j = 1, shape(2) x = h * (lb(1)/2 + i-1) + xmin y = h * (lb(2)/2 + j-1) + ymin a0(i,j) = 2.0 * ((x - vx*t)*vx + (y-vy*t)*vy)* . phi0(i,j)/width**2 b0(i,j) = -2.0 * (x-vx*t) * phi0(i,j) / width**2 c0(i,j) = -2.0 * (y-vy*t) * phi0(i,j) / width**2 end do end do return end c----------------------------------------------------------------------- c Interior Update using the Leap frog scheme c c anp => A at n+1 c anm => A at n-1 c an => A at n c c bnp => B at n+1 c bnm => B at n-1 c bn => B at n c c cnp => C at n+1 c cnm => C at n-1 c cn => C at n subroutine leapfrog2d(lb, ub, shape, anp, anm, an, . bnp, bnm, bn, cnp, cnm, cn, phip, phim, phi, . dt, h) implicit none integer lb(2), ub(2), shape(2) real*8 anp( shape(1), shape(2)), . anm( shape(1), shape(2)), . an( shape(1), shape(2)), . bnp( shape(1), shape(2)), . bnm( shape(1), shape(2)), . bn( shape(1), shape(2)), . cnp( shape(1), shape(2)), . cnm( shape(1), shape(2)), . cn( shape(1), shape(2)), . phip(shape(1), shape(2)), . phim(shape(1), shape(2)), . phi( shape(1), shape(2)) real*8 dt, h, epsilon c Local variables integer i, j, s_sten c Loop over interior grid points s_sten = 1 epsilon = 0.25 c update A do i = s_sten+1, shape(1)-s_sten do j = s_sten+1, shape(2)-s_sten anp(i,j) = anm(i,j) + . (dt /h) * (bn(i+1,j) - bn(i-1,j)) + . (dt /h) * (cn(i,j+1) - cn(i,j-1)) end do end do c update B do i = s_sten+1, shape(1)-s_sten do j = s_sten+1, shape(2)-s_sten bnp(i,j) = bnm(i,j) + . (dt / h) * (an(i+1,j) - an(i-1,j)) end do end do c update C do i = s_sten+1, shape(1)-s_sten do j = s_sten+1, shape(2)-s_sten cnp(i,j) = cnm(i,j) + . (dt / h) * (an(i,j+1) - an(i,j-1)) end do end do do i = s_sten+1, shape(1) - s_sten do j = s_sten+1, shape(2) - s_sten phip(i,j) = phim(i,j) + 2.0 * dt * an(i,j) end do end do return end c----------------------------------------------------------------------- c Routine to update phi directly using 2nd order PDE form subroutine update2nd(lb, ub, shape, phip,phim,phi, dt, h) implicit none integer lb(2), ub(2), shape(2) real*8 phip( shape(1), shape(2)), . phim( shape(1), shape(2)), . phi( shape(1), shape(2)) real*8 dt, h c Local variables integer i, j do i = 2, shape(1) - 1 do j = 2, shape(2) - 1 phip(i,j) = phim(i,j) . + (dt/h)**2 * (phi(i+1,j) + phi(i-1,j) - 2.0*phi(i,j)) . + (dt/h)**2 * (phi(i,j+1) + phi(i,j+1) - 2.0*phi(i,j)) end do end do return end c----------------------------------------------------------------------- subroutine updatephi(lb, ub, shape, phip,phim,an, dt, h) implicit none integer lb(2), ub(2), shape(2) real*8 phip( shape(1), shape(2)), . phim( shape(1), shape(2)), . an( shape(1), shape(2)) real*8 dt, h c Local variables integer i, j do i = 2, shape(1) - 1 do j = 2, shape(2) - 1 phip(i,j) = phim(i,j) + 2.0 * dt * an(i,j) end do end do return end c----------------------------------------------------------------------- c Boundary update routine c For now set simple boundary condition subroutine bdyupdt2d(lb, ub, shape, a, b, c, phi, . dt, h, glb, gub) implicit none integer lb(2), ub(2), glb(2), gub(2), shape(2) real*8 a( shape(1), shape(2)), . b( shape(1), shape(2)), . c( shape(1), shape(2)), . phi( shape(1), shape(2)) real*8 dt, h c Local variables integer i, j, k c Possible combinations c lb(1) = glb(1) then we are at the x=xmin boundary if( lb(1) .eq. glb(1) )then do j = 1, shape(2) a(lb(1), j) = 0.0 b(lb(1), j) = 0.0 c(lb(1), j) = 0.0 phi(lb(1), j) = 0.0 end do end if c ub(1) = gub(1) then we are at the x=xmax boundary if( ub(1) .eq. gub(1) )then do j = 1, shape(2) a(ub(1), j) = 0.0 b(ub(1), j) = 0.0 c(ub(1), j) = 0.0 phi(ub(1), j) = 0.0 end do end if c lb(2) = glb(2) then we are at the y=ymin boundary if( lb(2) .eq. glb(2) )then do i = 1, shape(1) a(i,lb(2)) = 0.0 b(i,lb(2)) = 0.0 c(i,lb(2)) = 0.0 phi(i, lb(2)) = 0.0 end do end if c ub(2) = gub(2) then we are at the y=ymax boundary if( ub(2) .eq. gub(2) )then do i = 1, shape(1) a(i, ub(2)) = 0.0 b(i, ub(2)) = 0.0 c(i, ub(2)) = 0.0 phi(i, ub(2)) = 0.0 end do end if return end c----------------------------------------------------------------------- subroutine pythnorm(lb, ub, shape, truncA,truncB,truncC,truncerr, . wgta, wgtb, wgtc) implicit none integer lb(2), ub(2), shape(2) real*8 trunca(shape(1), shape(2)), . truncb(shape(1), shape(2)), . truncc(shape(1), shape(2)), . truncerr(shape(1), shape(2)) real*8 wgta, wgtb, wgtc c Local variables integer i, j, k c write(0,*)'weights ',wgtA, wgtB, wgtC do i = 1, shape(1) do j = 1, shape(2) truncerr(i,j) = sqrt( wgtA * trunca(i,j)**2 + . wgtB * truncB(i,j)**2 + wgtC * truncC(i,j)**2 ) end do end do c do i = 1, shape(1) c do j = 1, shape(2) c write(12,*)i,j,truncerr(i,j) c end do c write(12,*) c end do return end c----------------------------------------------------------------------- c Routine to do smoothing in 2d c Take four neighboring points (i,j) c c (i,j) weight of w. The rest are a weight of (1-w)/4 c o c c o o o c c o c subroutine smooth2(lb, ub, shape, uf,w) implicit none integer lb(2), ub(2), shape(2) real*8 uf(shape(1), shape(2)), w c Local variables integer i, j c Smoothing using four points in the interior only do i = 2, shape(1)-1 do j = 2, shape(2)-1 uf(i,j) = w*uf(i,j) + (1.0d0 - w) * 0.25d0 * . (uf(i+1, j) + uf(i-1, j) + uf(i, j+1) + uf(i, j-1) ) end do end do return end c-----------------------------------------------------------------------