Source File : Wave.F



Two Dimensional Wave Equation with inflow in x and periodic in y.
10 time frames of a circle moving up from the lower left corner and exit to the right boundary.


| Input File |


Note : Portions of Code that colored

Red are essential for used with PseudoPack.

List of Routines


! |  Back to the Top  |

!------
! Demonstration Program for the use of PseudoPack.  
!
!             2-D Scalar Wave Equation  
!
!          Chebyshev/Fourier Implementation
!
!             1:  U_t+a*U_x+b*U_y=0
!             2:  U_t+y*U_x-x*U_y=0
!                
!
!   Initial  Condition : U(x,y,0) = Smoothed Gaussian
!   Boundary Condition : Periodic in y direction
!                        Inflow/Outflow in x direction
!
!------

c------
c Must include this include statement for used with Macros in pseudopack.h
c------

#include "pseudopack.h" 
!
!============================================================
!
MODULE Initial_Parameter

  Integer  :: Flux_Choice

  REALTYPE :: Speed_x, Speed_y
  REALTYPE :: C_x, C_y, Radius_Ratio, Gaussian_Order
  REALTYPE :: Left_x, Right_x, Bottom_y, Top_y

END MODULE Initial_Parameter
!
!============================================================
!
Program Wave_2D

  USE PseudoPack 
  USE Initial_Parameter

implicit NONE

integer, parameter :: N_Frame = 10

Integer  :: Index_x, Method_x, Point_Type_x, Max_Diff_x, &
            Algorithm_x, Symmetry_x,                     &
            N_x, BlockSize_x, Map_x, Manual_x, Map_F_x,  &
            Filter_Choice_D_x, Mode_CutOff_D_x,          &
              Smooth_1_D_x, Smooth_2_D_x,                &
            Filter_Choice_S_x, Mode_CutOff_S_x            
REALTYPE :: alpha_x, Angle_x,                            &
            Omega_D_x, Order_D_x, Omega_S_x, Order_S_x   

Integer  :: Index_y, Method_y, Point_Type_y, Max_Diff_y, &
            Algorithm_y, Symmetry_y,                     &
            N_y, BlockSize_y, Map_y, Manual_y, Map_F_y,  &
            Filter_Choice_D_y, Mode_CutOff_D_y,          &
              Smooth_1_D_y, Smooth_2_D_y,                &
            Filter_Choice_S_y, Mode_CutOff_S_y  
REALTYPE :: alpha_y, Angle_y,                            &
            Omega_D_y, Order_D_y, Omega_S_y, Order_S_y

Integer  :: N, M, LDY, M_D, M_S
Integer  :: Step, N_Time_Step, N_Inc, Status
logical  :: BlowUp
REALTYPE :: Time, Final_Time, dt, CFL

REALTYPE, dimension(:,:), ALLOCATABLE :: u 
! |  Back to the Top  |
REALTYPE, dimension(:)  , ALLOCATABLE :: x, y
REALTYPE, dimension(:)  , ALLOCATABLE :: D_x, D_y, S_x, S_y

TYPE (PS_Property  ) :: Property
TYPE (PS_Grid_Index) :: Grid_Index
TYPE (PS_Domain    ) :: Domain
TYPE (PS_Mapping   ) :: Mapping
TYPE (PS_Filtering ) :: Filtering_D, Filtering_S

!--------------------------------------------------------------
! First Executable Statement start here.....
!--------------------------------------------------------------

!------
! Input Data 
!------
call Input (7)

N = N_x-1
M = N_y-1

Allocate (x(0:N), y(0:M), u(0:N,0:M))

! |  Back to the Top  |
!------
! Specify the leading dimension of the data array
!------

LDY = SIZE(u, DIM=1)

!------
! Setup in x direction
!------

call PS_Setup (  Property=Property   , Index=Index_x, Method=Method_x, &
                                         Algorithm=Algorithm_x,        &
               Grid_Index=Grid_Index , N=N_x, M=N_y, LDY=LDY,          &
                  Mapping=Mapping    , Map=Map_x)

call PS_Setup_Filtering   (Filtering_D , Filter_Choice_D_x)
call PS_Setup_Filtering   (Filtering_S , Filter_Choice_S_x)

call PS_Get_Operator_Size ('D', N_x, M_D, Property)
  Allocate (D_x(M_D))

call PS_Setup_Operator    (N_x, D_x, x, Property, Grid_Index,          &
                                Mapping=Mapping, Filtering=Filtering_D)

call PS_Get_Operator_Size ('S', N_x, M_S, Filtering_S, Property)
  Allocate (S_x(M_S))
call PS_Setup_Operator    (N_x, S_x, Property, Grid_Index, Filtering_S)

!------
! Setup in y direction
!------

call PS_Setup (  Property=Property   , Index=Index_y, Method=Method_y, &
                                         Algorithm=Algorithm_y,        &
               Grid_Index=Grid_Index , N=N_y, M=N_x, LDY=LDY,          &
                   Domain=Domain     , x0=Bottom_y, x1=Top_y,          &
                                         Map_F=Map_F_y,                &
                  Mapping=Mapping    , Map=Map_y)

call PS_Setup_Filtering   (Filtering_D , Filter_Choice_D_y)
call PS_Setup_Filtering   (Filtering_S , Filter_Choice_S_y)

call PS_Get_Operator_Size ('D', N_y, M_D, Property) 
  Allocate (D_y(M_D))
call PS_Setup_Operator    (N_y, D_y, y, Property, Grid_Index,          &
                                Domain, Filtering=Filtering_D)

call PS_Get_Operator_Size ('S', N_y, M_S, Filtering_S, Property) 
  Allocate (S_y(M_S))
call PS_Setup_Operator    (N_y, S_y, Property, Grid_Index, Filtering_S)

!------
! Finished Setup
!------

call Echo_Code_Information

!------
! Compute Initial Condition
!------
call Initial_Conditions (N, M, x, y, u, LDY)

!------
! Compute Time Step dt
!------
call Time_Step (N, M, x, y, u, LDY, CFL, dt)

!------
! Output Initial Condition
!------

OPEN (UNIT=10, FILE='wave_Movie.dat', STATUS="UNKNOWN") ; REWIND (10)
OPEN (UNIT=11, FILE='wave.dat'      , STATUS="UNKNOWN") ; REWIND (11)
OPEN (UNIT=12, FILE='wave_Movie.m'  , STATUS="UNKNOWN") ; REWIND (12)
OPEN (UNIT=13, FILE='wave.m'        , STATUS="UNKNOWN") ; REWIND (13)

Status  = 0
call TecPlot   (N, M, Step, Time, x, y, u, LDY, Status, 10)
call Matlab    (N, M, Step, Time, x, y, u, LDY, Status, 12)
Status = 1

N_Time_Step = INT(Final_Time/dt)
N_Inc       = MAX(N_Time_Step/(N_Frame-2),1)

call Echo_Time_Step_Information

!------
! Start the Runge Kutta Time Stepping
!------
Step    = 0
Time    = 0

 100  continue
 
Step = Step + 1
Time = Time + dt


call RK_TVD (N, M, Time, dt, x, y, u, LDY, D_x, D_y, S_x, S_y)


if (Step/N_Inc*N_Inc == Step) then
  write (6,*) 'The Current Step, Time is ',Step, Time 

  call TecPlot   (N, M, Step, Time, x, y, u, LDY, Status, 10)
  call Matlab    (N, M, Step, Time, x, y, u, LDY, Status, 12)
endif

BlowUp = MAXVAL(ABS(u)) >  TWO   ! Do not fool around with this variable

if (BlowUp) then
  Final_Time = Time
  write (6,*)
  write (6,*) '--------------------------------------------------'
  write (6,*) 'Stopped!  Unstable Numerical Solution ....'
  write (6,*) '--------------------------------------------------'
  write (6,*)
endif

if (Time <  Final_Time) goto 100

!------
! Output Data
!------
call TecPlot   (N, M, Step, Time, x, y, u, LDY, Status, 10)
call Matlab    (N, M, Step, Time, x, y, u, LDY, Status, 12)

Status = 0
call TecPlot   (N, M, Step, Time, x, y, u, LDY, Status, 11)
call Matlab    (N, M, Step, Time, x, y, u, LDY, Status, 13)

call Echo_Final_Message

CONTAINS
! |  Back to the Top  |
  Subroutine Input (LID)

  integer  :: LID, IOS

  OPEN (UNIT=LID, FILE='Wave.input', STATUS='OLD', IOSTAT=IOS)

  call PS_Input (Index_x, Method_x, Point_Type_x, Max_Diff_x,  &
                   Algorithm_x, Symmetry_x,                    &
                 N_x, BlockSize_x, Left_x, Right_x, Map_F_x,   &
                   Map_x, Manual_x, alpha_x, Angle_x,          &
                 Filter_Choice_D_x, Mode_CutOff_D_x,           &
                   Omega_D_x, Order_D_x,                       &
                   Smooth_1_D_x, Smooth_2_D_x,                 &
                 Filter_Choice_S_x, Mode_CutOff_S_x,           &
                   Omega_S_x, Order_S_x,                       &
                 LID)

  call PS_Input (Index_y, Method_y, Point_Type_y, Max_Diff_y,  &
                   Algorithm_y, Symmetry_y,                    &
                 N_y, BlockSize_y, Bottom_y, Top_y, Map_F_y,   &
                   Map_y, Manual_y, alpha_y, Angle_y,          &
                 Filter_Choice_D_y, Mode_CutOff_D_y,           &
                   Omega_D_y, Order_D_y,                       &
                   Smooth_1_D_y, Smooth_2_D_y,                 &
                 Filter_Choice_S_y, Mode_CutOff_S_y,           &
                   Omega_S_y, Order_S_y,                       &
                 LID)

  read (LID,'(//)')
  read (LID,*) Final_Time
  read (LID,*) CFL
  read (LID,'(//)')
  read (LID,*) Flux_Choice
  read (LID,*)
  read (LID,*) Speed_x, Speed_y
  read (LID,*)     C_x,     C_y 
  read (LID,*) Radius_Ratio
  read (LID,*) Gaussian_Order

  CLOSE (LID)

  if (Flux_Choice == 1) then
    Speed_x = ONE ; Speed_y = ONE
  endif

  END Subroutine Input 
! ==================================================================

  Subroutine Echo_Code_Information

  write (6,*)
  write (6,*) '--------------------------------------------------'
  write (6,*) 
  if (OPERATOR_METHOD(D_x)     == 0) &
    write (6,*) 'Method        in x            is   Fourier'
  if (OPERATOR_METHOD(D_x)     == 1) &
    write (6,*) 'Method        in x            is   Chebyshev'
  if (OPERATOR_METHOD(D_x)     == 2) &
    write (6,*) 'Method        in x            is   Legendre '
  if (OPERATOR_POINT_TYPE(D_x) == 1) &
    write (6,*) 'Point_type    in x            is   Gauss-Lobatto'
  if (OPERATOR_POINT_TYPE(D_x) == 2) &
    write (6,*) 'Point_type    in x            is   Gauss_Radau'
  if (OPERATOR_POINT_TYPE(D_x) == 3) &
    write (6,*) 'Point_type    in x            is   Gauss'
  if (OPERATOR_ALGORITHM(D_x)  == 0) &
    write (6,*) 'Algorithm     in x            is   MXM'
  if (OPERATOR_ALGORITHM(D_x)  == 1) &
    write (6,*) 'Algorithm     in x            is   EOD'
  if (OPERATOR_ALGORITHM(D_x)  == 2) &
    write (6,*) 'Algorithm     in x            is   Transform'
  if (OPERATOR_METHOD(D_y)     == 0) &
    write (6,*) 'Method        in y            is   Fourier'
  if (OPERATOR_METHOD(D_y)     == 1) &
    write (6,*) 'Method        in y            is   Chebyshev'
  if (OPERATOR_METHOD(D_y)     == 2) &
    write (6,*) 'Method        in y            is   Legendre '
  if (OPERATOR_POINT_TYPE(D_y) == 1) &
    write (6,*) 'Point_type    in y            is   Gauss-Lobatto'
  if (OPERATOR_POINT_TYPE(D_y) == 2) &
    write (6,*) 'Point_type    in y            is   Gauss_Radau'
  if (OPERATOR_POINT_TYPE(D_y) == 3) &
    write (6,*) 'Point_type    in y            is   Gauss'
  if (OPERATOR_ALGORITHM(D_y)  == 0) &
    write (6,*) 'Algorithm     in y            is   MXM'
  if (OPERATOR_ALGORITHM(D_y)  == 1) &
    write (6,*) 'Algorithm     in y            is   EOD'
  if (OPERATOR_ALGORITHM(D_y)  == 2) &
    write (6,*) 'Algorithm     in y            is   Transform'

  write (6,*)
  write (6,*) '--------------------------------------------------'
  write (6,*) 

  END Subroutine Echo_Code_Information
! ==================================================================

  Subroutine Echo_Time_Step_Information

  write (6,*)
  write (6,*) '--------------------------------------------------'
  write (6,*) 
  write (6,*) '                Time Step is ',dt
  write (6,*) '               Final Time is ',Final_Time
  write (6,*) 'Total Number of Time Step is ',int(Final_Time/dt)
  write (6,*) 
  write (6,*) 'Frame Increment Time Step is ',N_Inc
  write (6,*) '          Number of Frame is ',N_Frame
  write (6,*)
  write (6,*) '--------------------------------------------------'
  write (6,*) 

  END Subroutine Echo_Time_Step_Information
! ==================================================================
 
  Subroutine Echo_Final_Message

  write (6,*)
  write (6,*) '--------------------------------------------------'
  write (6,*) 'Files wave_Movie.dat and wave.dat are output in',  &
            ' TecPlot .dat format.'
  write (6,*)
  write (6,*) ' wave_Movie.dat --- contains a sequence of solution'
  write (6,*) ' wave.dat       --- contains Solution at Time ',Time
  write (6,*)
  write (6,*) 'Files wave_Movie.m and wave.m are output in',      &
            ' Matlab .m format.'
  write (6,*)
  write (6,*) ' wave_Movie.m   --- contains a sequence of solution'
  write (6,*) ' wave.m         --- contains Solution at Time ',Time
  write (6,*)
  write (6,*) 'If user does not have TecPlot or Matlab, Please replace'
  write (6,*) " the plotting Subroutine TecPlot with user's own"
  write (6,*) ' prefered plotting subroutine!' 
  write (6,*)
  write (6,*) 'Thank you for trying this package! -- WSDON'
  write (6,*)

  END Subroutine Echo_Final_Message

END Program 
!
! ==================================================================
! |  Back to the Top  |
Subroutine Initial_Conditions (N, M, x, y, u, LDY)

  USE Initial_Parameter, Order=>Gaussian_Order

implicit NONE

Integer  :: N, M, LDY, i, j
REALTYPE :: alpha, Radius, R,  L_x, L_y, xx, yy

REALTYPE, dimension(0:N)         :: x
REALTYPE, dimension(0:M)         :: y
REALTYPE, dimension(0:LDY-1,0:M) :: u

alpha = -LOG(EPSILON(ONE))

L_x = Right_x-Left_x
L_y = Top_y-Bottom_y

Radius = MIN(L_y,L_x)*Radius_Ratio

if (Flux_Choice == 1) then
  C_x =   Left_x+HALF*L_x
  C_y = Bottom_y+HALF*L_y
else
  C_x =   Left_x+Radius
  C_y = Bottom_y+Radius
endif

do j = 0,M
  do i = 0,N

    xx = x(i)-C_x
    yy = y(j)-C_y
     R = SQRT(xx**2+yy**2)
    if (R <= Radius) then
      u(i,j) = EXP(-alpha*(R/Radius)**Order)
    else
      u(i,j) = ZERO
    endif

  enddo
enddo

END Subroutine Initial_Conditions 
!
! ==================================================================
! |  Back to the Top  |
Subroutine Time_Step (N, M, x, y, u, LDY, CFL, dt)

  USE Initial_Parameter, ONLY: Speed_x, Speed_y

implicit NONE

Integer  :: N, M, LDY, i, j
REALTYPE :: CFL, dt, ddt, dx, dy

REALTYPE, dimension(0:N)         :: x
REALTYPE, dimension(0:M)         :: y
REALTYPE, dimension(0:LDY-1,0:M) :: u

ddt = ZERO

do j = 1,M
  do i = 1,N
     dx = Speed_x/ABS(x(i)-x(i-1))
     dy = Speed_y/ABS(y(j)-y(j-1))*PI
    ddt = MAX(dx+dy, ddt)
  enddo
enddo
 
dt = CFL/ddt

END Subroutine Time_Step 
!
! ==================================================================
! |  Back to the Top  |

Subroutine RK_TVD (N, M, Time, dt, x, y, u, LDY, D_x, D_y, S_x, S_y)

  USE PseudoPack

implicit NONE
  
integer  :: N, M, LDY
REALTYPE :: Time, dt, Time_n, Time_Now

REALTYPE, dimension(0:N)         :: x
REALTYPE, dimension(0:M)         :: y
REALTYPE, dimension(0:LDY-1,0:M) :: u, u1, du 
REALTYPE, dimension(*)           :: D_x, D_y, S_x, S_y

             Time_n = Time-dt

             Time_Now = Time_n
!
! Stage 1 :  
! 
call Flux (N, M, x, y, u , du, LDY, D_x, D_y) 

u1(0:N,:) = u(0:N,:) - dt*du(0:N,:)

               Time_Now = Time_n+dt

call Boundary_Condition (N, M, Time_Now, x, y, u1, LDY)
!
! Stage 2 :  
! 
call Flux (N, M, x, y, u1, du, LDY, D_x, D_y) 

u1(0:N,:) = (THREE*u(0:N,:) + u1(0:N,:) - dt*du(0:N,:))/FOUR

               Time_Now = Time_n+dt/2

call Boundary_Condition (N, M, Time_Now, x, y, u1, LDY)
!
! Stage 3 :  
! 
call Flux (N, M, x, y, u1, du, LDY, D_x, D_y) 

u(0:N,:) = (u(0:N,:)+TWO*u1(0:N,:)-TWO*dt*du(0:N,:))/THREE

               Time_Now = Time_n+dt

!------
! Smooth the solution u along the First  index
!------

call PS_Smooth (LDY, S_x, u, M+1)

!------
! Smooth the solution u along the Second index
!------

call PS_Smooth (LDY, S_y, u, N+1)

!------
! Done Smoothing
!------

call Boundary_Condition (N, M, Time_Now, x, y, u, LDY)

END Subroutine RK_TVD 
!
! ==================================================================
! |  Back to the Top  |

Subroutine Flux (N, M, x, y, u, du, LDY, D_x, D_y)

  USE PseudoPack  
  USE Initial_Parameter, ONLY: Flux_Choice, Speed_x, Speed_y, C_x, C_y

integer  :: N, M, LDY, i, j
REALTYPE :: xx, yy 

REALTYPE, dimension(0:N)         :: x
REALTYPE, dimension(0:M)         :: y
REALTYPE, dimension(0:LDY-1,0:M) :: u, du, df 
REALTYPE, dimension(*)           :: D_x, D_y

!------
! Compute the du/dx along the First  index
!------

call PS_Diff (LDY, D_x, u, df, M+1)

!------
! Compute the du/dy along the Second index
!------

call PS_Diff (LDY, D_y, u, du, N+1)

!------
! Compute the Total Flux
!------
SELECT CASE (Flux_Choice)
  CASE (0)
    du(0:N,:) = Speed_x*df(0:N,:)+Speed_y*du(0:N,:)

  CASE (1)
    do j = 0,M
      do i = 0,N
        xx = x(i)-C_x
        yy = y(j)-C_y
        du(i,j) = yy*df(i,j)-xx*du(i,j)
      enddo
    enddo

END SELECT

END Subroutine Flux 
!
! ==================================================================
! |  Back to the Top  |
Subroutine Boundary_Condition (N, M, Time, x, y, u, LDY)

implicit NONE

Integer  :: N, M, LDY
REALTYPE :: Time

REALTYPE, dimension(0:N)         :: x
REALTYPE, dimension(0:M)         :: y
REALTYPE, dimension(0:LDY-1,0:M) :: u

u(N,:) = ZERO

END Subroutine Boundary_Condition 
!
! ==================================================================
! |  Back to the Top  |
Subroutine TecPlot (N, M, Step, Time, x, y, u, LDY, Status, lid)

implicit NONE

integer  :: N, M, LDY, lid, Step, Status, i, j
REALTYPE :: Time

REALTYPE, dimension(0:N)         :: x
REALTYPE, dimension(0:M)         :: y
REALTYPE, dimension(0:LDY-1,0:M) :: u

if (Status == 0) then
  write (lid,1000) Step, Time
  write (lid,1001)
  write (lid,1002) N+1, M+1
  write (lid,1100) ((x(i)    , i=0,N),j=0,M)
  write (lid,1100) ((y(j)    , i=0,N),j=0,M)
else
  write (lid,1003) N+1, M+1
endif
  write (lid,1100) ((u(i,j)  , i=0,N),j=0,M)

 1000 format (1x,'Title="2-D Linear Wave Equation: Step=',i5,' Time=',f10.7,'"')
 1001 format (1x,'Variables=x,y, u')
 1002 format (1x,'Zone I=',i4,' J=',i4,' F=Block')
 1003 format (1x,'Zone I=',i4,' J=',i4,' F=Block, D=(1,2)')
 1100 format (  8(1x,e18.11))

END Subroutine TecPlot 
!
! ==================================================================
!
Subroutine Matlab  (N, M, Step, Time, x, y, u, LDY, Status, lid)

implicit NONE

integer  :: N, M, LDY, lid, Step, Status, i, j
REALTYPE :: Time

REALTYPE, dimension(0:N)         :: x
REALTYPE, dimension(0:M)         :: y
REALTYPE, dimension(0:LDY-1,0:M) :: u

if (Status == 0) then
  write (lid,1000) 'x=transpose(['
  write (lid,1001) (x(i)     , i=0,N)
  write (lid,1000) ']);'
  write (lid,1000) 'y=transpose(['
  write (lid,1001) (y(j)     , j=0,M)
  write (lid,1000) ']);'
endif
  write (lid,1000) 'z=reshape(['
  write (lid,1001) ((u(i,j)  , j=0,M),i=0,N)
  write (lid,1000) '],size(y,2),size(x,2));'
  write (lid,1003) 

 1000 format (1x,a40)
 1001 format (e13.4)
 1003 format (1x,'surf(x,y,z); shading interp; pause(2)')

END Subroutine Matlab  

! |  Back to the Top  |

| Input File |