Free Web Hosting Provider - Web Hosting - E-commerce - High Speed Internet - Free Web Page
Search the Web





Download the code
The model equation to be solved is of the form:
∂φ/∂t + u∂φ/∂x + v∂φ/∂y = 0
*        A. Salih, Dept. of Mechanical Engg., NIT - Trichy, India.      *
*************************************************************************
*     THIS PROGRAM SOLVES TWO-DIMENSIONAL LINEAR WAVE EQUATION IN A     *
*         DOUBLY PERIODIC DOMAIN USING FINITE DIFFERENCE METHOD         *
*                -Schemes: 1. Upwind Scheme                             *
*                          2. MacCormack Method                         *
*                          3. ENO-2 Scheme                              *
*************************************************************************
*
      PROGRAM LINEAR_WAVE_2D
      implicit doubleprecision (a-h,o-z)
      include 'scalars/integers.inc'
      include 'scalars/parameters.inc'
      open(unit=11,file='input.dat',status='unknown')
      open(unit=21,file='output.dat',status='unknown')
      open(unit=31,file='outputs/x.dat',status='unknown')
      open(unit=32,file='outputs/y.dat',status='unknown')
      open(unit=33,file='outputs/phi.dat',status='unknown')
      open(unit=34,file='outputs/time.dat',status='unknown')
      open(unit=35,file='outputs/time2.dat',status='unknown')
      open(unit=36,file='outputs/phi_trans.dat',status='unknown')
      open(unit=37,file='outputs/phi_cent.dat',status='unknown')
c
      pi = 4*datan(1d0)
c
      CALL READ_IN          ! read-in data
      close (unit=11)

      CALL GRID             ! setting up the grid points in the domain

      CALL INITIAL_COND     ! setting up initial condition

      CALL SOLVE            ! setting up system of equations
      
      CALL PRINTOUT         ! printing out the computational results

      CALL WRITE_OUT     ! write-out the basic data used for computation
c
      stop
      end
*
***SUBROUTINE: READING IN THE BASIC DATA *******************************
*
      subroutine READ_IN
      implicit doubleprecision (a-h,o-z)
      include 'array_dimension.inc'
      include 'scalars/integers.inc'
      include 'scalars/reals.inc'
c
      read(11,*) alx         ! actual length of domain in x-direction
      read(11,*) aly         ! actual length of domain in y-direction
      read(11,*) ic_type     ! initial U profile (1-U_INITIAL1)
      read(11,*) u           ! value of advection velocity in x-direction
      read(11,*) v           ! value of advection velocity in y-direction
      read(11,*) Co          ! Courant number for calculating time step
      read(11,*) tfinal      ! time at which the solution is desired
      read(11,*) scheme      ! 1-Upwind, 2-MacCormack, 3-ENO-2
      read(11,*) print_freq  ! 
c
c     calculation of time-step dt based on the stability condition
      dx = alx /(m-1)
      dy = aly /(n-1)
      dt = Co /(dabs(u)/dx + dabs(v)/dy)
      maxntimestp = tfinal /dt
      dt = tfinal /maxntimestp              ! revised time-step
      Co = dt*(dabs(u)/dx + dabs(v)/dy)     ! revised Courant number
      if (tfinal < dt) then
         print*, 'Warning: final time is less than time-step!'
         stop
      endif
c
      return
      end
*
***SUBROUTINE: WRITING OUT THE BASIC DATA USED FOR COMPUTATION**********
*
      subroutine WRITE_OUT
      implicit doubleprecision (a-h,o-z)
      include 'array_dimension.inc'
      include 'scalars/integers.inc'
      include 'scalars/reals.inc'
c
      write(21,*) 'Linear, 1-dimensional wave equation with periodic bou
     $ndary conditions:'
c
      if (scheme == 1) then
         write(21,*) 'Upwind Scheme'
      elseif (scheme == 2) then
         write(21,*) 'MacCormack Method'
      elseif (scheme == 3) then
         write(21,*) 'Essentially NonOscillatory Scheme'
      endif
c
      write(21,*) 'Advection velocity in x-direction, u =', u
      write(21,*) 'Advection velocity in y-direction, v =', v
      write(21,*) 'Courant number, Co =', Co
      write(21,*) 'Length of domain in x-direction', alx
      write(21,*) 'Length of domain in x-direction', aly
      write(21,*) 'Number of grids (including boundaries):', mx, '     
     $X', ny
      write(21,*) 'dx =', dx
      write(21,*) 'dy =', dy
      write(21,*) 'dt =', dt
      write(21,*) 'No. of time step = ', ntimestp
      write(21,*) 'Final time = ', time
c
      return
      end
*
****SUBROUTINE: GRID****************************************************
*
      SUBROUTINE GRID
      implicit doubleprecision (a-h,o-z)
      include 'array_dimension.inc'
      include 'scalars/integers.inc'
      include 'scalars/reals.inc'
      include 'arrays/grid.inc'
c
c     m = no. of grid points (including boundary nodes) in x-direction
c     n = no. of grid points (including boundary nodes) in y-direction
      dx   = alx /(m-1)
      x(1) = 0
      do i = 2, m
         x(i) = x(i-1) + dx
      enddo
c
      dy   = aly /(n-1)
      y(1) = 0
      do j = 2, n
         y(j) = y(j-1) + dy
      enddo
c
      return
      end
*
***SUBROUTINE: INITIAL CONDITIONS FOR U ********************************
*
      SUBROUTINE INITIAL_COND
      implicit doubleprecision (a-h,o-z)
      include 'scalars/integers.inc'
c
c     defining the initial conditions
      if (ic_type == 1) then
         CALL PHI_INITIAL1
      endif
c
      return
      end
*
****SUBROUTINE: INITIAL CONDITION
*
      SUBROUTINE PHI_INITIAL1
      implicit doubleprecision (a-h,o-z)
      include 'array_dimension.inc'
      include 'scalars/integers.inc'
      include 'scalars/reals.inc'
      include 'scalars/parameters.inc'
      include 'arrays/grid.inc'
      include 'arrays/phi.inc'
c
c     parameters
      half = 1d0/2d0
      onet = 1d0/3d0
c
      do j = 1, n
      do i = 1, m
         term = dsqrt( (x(i)-half)**2 + (y(j)-half)**2 )
         if (term < onet) then
              PHI(i,j) = dcos(2*pi*x(i)) + dcos(2*pi*y(j)) + 2d0
         else
              PHI(i,j) = dcos(2*pi*x(i)) + dcos(2*pi*y(j)) - 2d0
         endif
      enddo
      enddo
c
      return
      end
*
***SUBROUTINE: NUMERICAL SOLUTION USING DIFFERENT SCHEMES***************
*
      subroutine SOLVE
      implicit doubleprecision (a-h,o-z)
      include 'array_dimension.inc'
      include 'scalars/integers.inc'
      include 'scalars/reals.inc'
      include 'scalars/parameters.inc'
      include 'arrays/grid.inc'
      include 'arrays/phi.inc'
      doubleprecision PHIN(-1:m1+1,-1:n1+1), PHIPRED(-1:m1+1,-1:n1+1)
      doubleprecision minmod_xm,minmod_xp,minmod_ym,minmod_yp
c
c     storing the values of u at nth time level
      PHIN = PHI
c
      ntimestp = 0
      maxdif = 1d9
      time = 0d0
      write(34,101) time        ! continuous time
      write(35,101) time        ! intermittent time
      monitorx = m/4
      monitory = n/4
      write(36,*) PHI(monitorx,monitory)
c
10    if (ntimestp < maxntimestp) then
c        periodic boundary conditions
c        west
         do j = 1,n
         do i = 0,-1,-1
            PHIN(i,j) = PHIN(m+i-1,j)
         enddo
         enddo
c        east
         do j = 1,n
         do i = 1,2
            PHIN(m+i,j) = PHIN(i+1,j)
         enddo
         enddo
c        south
         do i = 1,m
         do j = 0,-1,-1
            PHIN(i,j) = PHIN(i,n+j-1)
         enddo
         enddo
c        north
         do i = 1,m
         do j = 1,2
            PHIN(i,n+j) = PHIN(i,j+1)
         enddo
         enddo
c
         if (scheme == 1) then                          ! Upwind
            do j = 1,n
            do i = 1,m
               dPhidx_m = (PHIN(i,j) - PHIN(i-1,j)) /dx
               dPhidx_p = (PHIN(i+1,j) - PHIN(i,j)) /dx
               dPhidy_m = (PHIN(i,j) - PHIN(i,j-1)) /dy
               dPhidy_p = (PHIN(i,j+1) - PHIN(i,j)) /dy
               VdPhids  = max(u,0d0)*dPhidx_m + min(u,0d0)*dPhidx_p +
     $                          max(v,0d0)*dPhidy_m + min(v,0d0)*dPhidy_p 
               PHI(i,j) = PHIN(i,j) - VdPhids*dt
            enddo
            enddo
c
         elseif (scheme == 2) then                      ! MacCormack
c           predictor step
            do j = 1,n
            do i = 1,m
               udPhi = u*(PHIN(i+1,j) - PHIN(i,j))
               vdPhi = v*(PHIN(i,j+1) - PHIN(i,j))
               PHIPRED(i,j) = PHIN(i,j) - (udPhi/dx + vdPhi/dy)*dt
            enddo
            enddo
c
            do j = 1,n
            do i = 0,-1,-1
               PHIPRED(i,j) = PHIPRED(m+i-1,j)
            enddo
            enddo
            do j = 1,n
            do i = 1,2
               PHIPRED(m+i,j) = PHIPRED(i+1,j)
            enddo
            enddo
            do i = 1,m
            do j = 0,-1,-1
               PHIPRED(i,j) = PHIPRED(i,n+j-1)
            enddo
            enddo
            do i = 1,m
            do j = 1,2
               PHIPRED(i,n+j) = PHIPRED(i,j+1)
            enddo
            enddo
c
c           corrector step
            do j = 1,n
            do i = 1,m
               udPhi = u*(PHIPRED(i,j) - PHIPRED(i-1,j))
               vdPhi = v*(PHIPRED(i,j) - PHIPRED(i,j-1))
               PHI(i,j) = (PHIN(i,j) + PHIPRED(i,j))/2d0 - 
     &                    (udPhi/dx + vdPhi/dy)*dt/2d0
            enddo
            enddo
c
         elseif (scheme == 3) then                      ! ENO-2
c          second-order Essentially NonOscillatory scheme
           do j = 1,n
           do i = 1,m
             dPhidxxm =(PHIN(i,j) - 2*PHIN(i-1,j) + PHIN(i-2,j))/(dx**2)
             dPhidxx  =(PHIN(i+1,j) - 2*PHIN(i,j) + PHIN(i-1,j))/(dx**2)
             dPhidxxp =(PHIN(i+2,j) - 2*PHIN(i+1,j) + PHIN(i,j))/(dx**2)
             dPhidyym =(PHIN(i,j) - 2*PHIN(i,j-1) + PHIN(i,j-2))/(dy**2)
             dPhidyy  =(PHIN(i,j+1) - 2*PHIN(i,j) + PHIN(i,j-1))/(dy**2)
             dPhidyyp =(PHIN(i,j+2) - 2*PHIN(i,j+1) + PHIN(i,j))/(dy**2)
c
             if ( dPhidxx * dPhidxxm > 0) then
                   minmod_xm = dPhidxx/(dabs(dPhidxx)+1d-30) * 
     $                               min( dabs(dPhidxx), dabs(dPhidxxm) )
             else
                  minmod_xm = 0
             endif
             if ( dPhidxx * dPhidxxp > 0) then
                  minmod_xp = dPhidxx/(dabs(dPhidxx)+1d-30) * 
     $                              min( dabs(dPhidxx), dabs(dPhidxxp) )
             else
                  minmod_xp = 0
             endif
c
             if ( dPhidyy * dPhidyym > 0) then
                  minmod_ym = dPhidyy/(dabs(dPhidyy)+1d-30) * 
     $                              min( dabs(dPhidyy), dabs(dPhidyym) )
             else
                  minmod_ym = 0
             endif
             if ( dPhidyy * dPhidyyp > 0) then
                  minmod_yp = dPhidyy/(dabs(dPhidyy)+1d-30) * 
     $                              min( dabs(dPhidyy), dabs(dPhidyyp) )
             else
                  minmod_yp = 0
             endif
c
             dPhidx_m = (PHIN(i,j) - PHIN(i-1,j))/dx + (dx/2)*minmod_xm
             dPhidx_p = (PHIN(i+1,j) - PHIN(i,j))/dx - (dx/2)*minmod_xp
             dPhidy_m = (PHIN(i,j) - PHIN(i,j-1))/dy + (dy/2)*minmod_ym
             dPhidy_p = (PHIN(i,j+1) - PHIN(i,j))/dy - (dy/2)*minmod_yp
c
             VdPhids  = max(u,0d0)*dPhidx_m + min(u,0d0)*dPhidx_p +
     $                        max(v,0d0)*dPhidy_m + min(v,0d0)*dPhidy_p 
             PHI(i,j) = PHIN(i,j) - VdPhids*dt
           enddo
           enddo
         endif
c
         time     = time + dt
         ntimestp = ntimestp + 1
c
c        updating phi values at fictitious nodes
         do j = 1,n
         do i = 0,-1,-1
            PHIN(i,j) = PHIN(m+i-1,j)
         enddo
         enddo
         do j = 1,n
         do i = 1,2
            PHIN(m+i,j) = PHIN(i+1,j)
         enddo
         enddo
         do i = 1,m
         do j = 0,-1,-1
            PHIN(i,j) = PHIN(i,n+j-1)
         enddo
         enddo
         do i = 1,m
         do j = 1,2
            PHIN(i,n+j) = PHIN(i,j+1)
         enddo
         enddo
c
         PHIN = PHI
c
         write(34,101) time              ! continuous time
         write(6,102) ntimestp
c
c        printing out transient phi at selected point of domain
         j = jcounter + 1
         jcounter = mod(j,print_freq)
         if (jcounter == 0) then
            write(35,101) (time + dt)    ! intermittent time
            write(36,*) PHI(monitorx,monitory)
         endif
         go to 10
      endif
c
101   format(e14.7)
102   format(i7,5x,e14.7)
*
      return
      end
*
***SUBROUTINE: PRINTING-OUT THE OUTPUT DATA*****************************
*
      SUBROUTINE PRINTOUT
      implicit doubleprecision (a-h,o-z)
      include 'array_dimension.inc'
      include 'scalars/integers.inc'
      include 'scalars/reals.inc'
      include 'arrays/phi.inc'
      include 'arrays/grid.inc'
c
      ncent = n/2
      write(31,101) (x(i), i=1,m)
      write(32,101) (y(i), i=1,n)   
      write(33,102) ((PHI(i,j), i=1,m), j=1,n)
      write(37,101) ((PHI(i,ncent)+ PHI(i,ncent+1)/2), i=1,m) !PHI center
101   format(e13.6)
102   format(128(e13.6,1x))
c
      return
      end