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.
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 |