39
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 2D Wave Equation Main Program o #include "pseudopack.h" o Storage Allocation o Specify Leading Dimension o Setup Derived Data Type in x o Setup Differentiatial Operator in x o Setup Smoothing Operator in x o Setup Derived Data Type in y

Fortran Nnn

Embed Size (px)

Citation preview

Page 1: Fortran Nnn

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

2D Wave Equation Main Program o #include "pseudopack.h" o Storage Allocation o Specify Leading Dimension o Setup Derived Data Type in x o Setup Differentiatial Operator in x o Setup Smoothing Operator in x o Setup Derived Data Type in y o Setup Differentiatial Operator in y o Setup Smoothing Operator in y

Input Initial Conditions Time Step

Page 2: Fortran Nnn

Runge Kutta Scheme o Solution Smoothing call

Flux o Differentiation call

Boundary Conditions Graphic Output

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

#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

Page 3: Fortran Nnn

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_SInteger :: Step, N_Time_Step, N_Inc, Statuslogical :: BlowUpREALTYPE :: Time, Final_Time, dt, CFL

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

TYPE (PS_Property ) :: PropertyTYPE (PS_Grid_Index) :: Grid_IndexTYPE (PS_Domain ) :: DomainTYPE (PS_Mapping ) :: MappingTYPE (PS_Filtering ) :: Filtering_D, Filtering_S

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

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

N = N_x-1M = 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)

Page 4: Fortran Nnn

!------! 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)

!------

Page 5: Fortran Nnn

! 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 = 0call 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 = 0Time = 0

100 continue Step = Step + 1Time = 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

Page 6: Fortran Nnn

!------! 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 = 0call 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

Page 7: Fortran Nnn

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

Page 8: Fortran Nnn

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, jREALTYPE :: alpha, Radius, R, L_x, L_y, xx, yy

REALTYPE, dimension(0:N) :: xREALTYPE, dimension(0:M) :: yREALTYPE, dimension(0:LDY-1,0:M) :: u

Page 9: Fortran Nnn

alpha = -LOG(EPSILON(ONE))

L_x = Right_x-Left_xL_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_yelse C_x = Left_x+Radius C_y = Bottom_y+Radiusendif

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

enddoenddo

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, jREALTYPE :: CFL, dt, ddt, dx, dy

REALTYPE, dimension(0:N) :: xREALTYPE, dimension(0:M) :: yREALTYPE, 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) enddoenddo

Page 10: Fortran Nnn

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, LDYREALTYPE :: Time, dt, Time_n, Time_Now

REALTYPE, dimension(0:N) :: xREALTYPE, dimension(0:M) :: yREALTYPE, 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!------

Page 11: Fortran Nnn

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, jREALTYPE :: xx, yy

REALTYPE, dimension(0:N) :: xREALTYPE, dimension(0:M) :: yREALTYPE, 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

Page 12: Fortran Nnn

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, LDYREALTYPE :: Time

REALTYPE, dimension(0:N) :: xREALTYPE, dimension(0:M) :: yREALTYPE, 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, jREALTYPE :: Time

REALTYPE, dimension(0:N) :: xREALTYPE, dimension(0:M) :: yREALTYPE, 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+1endif 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

Page 13: Fortran Nnn

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

implicit NONE

integer :: N, M, LDY, lid, Step, Status, i, jREALTYPE :: Time

REALTYPE, dimension(0:N) :: xREALTYPE, dimension(0:M) :: yREALTYPE, 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 |

Inhomogeneous wave equation    by Reinaldo Baretti Machín and Alfonso Baretti Huertas

 

  

 

Page 14: Fortran Nnn

  

 

e-mail:  [email protected]

 Home page:

http://www1.uprh.edu/rbaretti

http://www1.uprh.edu/rbaretti/methodsoftheoreticalphysics.htm

http://www1.uprh.edu/rbaretti/methodsoftheoreticalphysicsPART2.htm

http://www1.uprh.edu/rbaretti/methodsoftheoreticalphysicsPART3.htm

http://www1.uprh.edu/rbaretti/methodsoftheoreticalphysicsPART4.htm

http://www1.uprh.edu/rbaretti/methodsoftheoreticalphysicsPART5.htm

http://www1.uprh.edu/rbaretti/methodsoftheoreticalphysicsPart6.htm

 

References:

 

1.  Numerical Solution of Differential Equations by Ph. D., D. Sc. William Edmund Milne

2. Numerical Methods by J. Douglas Faires and Richard L. Burden

 3. Mathematical Methods for the Natural and Engineering Sciences (Series on Advances in Mathematics for Applied Sciences, Vol. 65) by Ronald E. Mickens

 4. Mathematics in Engineering and Science by L. R. Mustoe and M. D. J. Barry (Paperback - Jun 1998)

 5. Applied mathematics for engineers and physicists by Louis Albert Pipes

Page 15: Fortran Nnn

6. Partial Differential Equations in Physics: Lectures on Theoretical Physics by Arnold Sommerfeld

7. Schaum's Outline of Advanced Mathematics for Engineers and Scientists (Schaum's Outline Series) by Murray R. Spiegel

8. http://www1.uprh.edu/rbaretti/HeatequationPart2sep72010.htm

9. Mathematical Methods in Physics and Engineering by John W. Dettman , page 386.

 

 

ABSTRACT: A FORTRAN code is written to implement the procedure of forward difference solution of the inhomogeneous wave equation in one dimension..

 

An example of an inhomogeneous wave equation in one dimension is [9] ,

 

                                    ∂ 2u(x,t) /∂ t 2     =    (σ/ρ ) ∂2 u(x,t) /∂x2   +(F0 /ρ) sin(π x)    ,         (1)

                                     ∂ 2u(x,t) /∂ t 2     =    v2 ∂2 u(x,t) /∂x2   +(F0 /ρ) sin(π x)                                          (2)

where  ρ ~ mass/length  , σ ~tension ,the wave velocity v ~(σ/ρ )1/2 ~ length /time  and (F0 /ρ) sin(π x) ~ force density   ~ newton/length .

 The boundary conditions are  specified  u(0,t) =  0  , u(L,t)= 0 . Two initial conditions are necessary. The functions f(x) and g(x) specify the initial u and the initial first derivative  ∂u/∂t ,

                                                     u(x,0)= f(x)                                                                 (3)

                                                ∂ u(x,0)/∂t = g(x)                                         .                    (4)   

Page 16: Fortran Nnn

Writing (1) as a finite difference equation and solving for u(x,t+∆t) one gets

u (x, t+∆t) =  [(∆t v /∆x )2 ] {u(x+∆x,t) + u(x-∆x,t) }  + 2 {1- (∆t v /∆x )2 } u(x,t)    + (∆t)2 (F0 /ρ) sin(π x)        (5)

 

 

                          

 

Page 17: Fortran Nnn

Fig 1. The forward difference approximation finds u(x, t+∆t) in terms of  the previous values u(x , t)  , u(x+∆x, t), u(x-∆x, t) and

 u(x, t-∆t). The procedure is stable if  

                                                        ∆t v /∆x  << 1                                                        , (5)

and just as with the heat equation  the choices of ∆x and ∆t  are not independent. 

 

 Example :

Let L = 1 meter ,  σ =1 N , ρ = 1kg/m , F0 = 1  N/m  , v = 1 m/s . The boundary conditions are  u(0,t) = 0   ,  u(L,t)=0  We take as the initial conditions

u(x,0)=f(x) =0      and    (∂u/∂t)t=0 = 0 = g(x)   .

The analytic solution is [9]

 uexact(x,t)=(F0/(pi**2*sigma))*sin(pi*x)*(1.-     $ cos(pi*sqrt(sigma/rho)*t) )

                                                    uexact(x,t) = (F0 /(π2 σ) ) sin(πx) { 1- cos(π (σ/ρ)1/2 t) }        .  (6)  

 

Page 18: Fortran Nnn

  

Fig 2. Match of numerical and analytical solutions of the inhomogeneous wave equation.        

 tscale, tfinal = 1. 1.dt,dx,nstep,ntime= 0.00500000035 0.0500000007 20 199

x,u,uexact= 0.000E+00 0.000E+00 0.000E+00x,u,uexact= 0.500E-01 0.318E-01 0.317E-01

Page 19: Fortran Nnn

x,u,uexact= 0.100E+00 0.627E-01 0.626E-01x,u,uexact= 0.150E+00 0.922E-01 0.920E-01x,u,uexact= 0.200E+00 0.119E+00 0.119E+00x,u,uexact= 0.250E+00 0.144E+00 0.143E+00x,u,uexact= 0.300E+00 0.164E+00 0.164E+00x,u,uexact= 0.350E+00 0.181E+00 0.181E+00x,u,uexact= 0.400E+00 0.193E+00 0.193E+00x,u,uexact= 0.450E+00 0.201E+00 0.200E+00x,u,uexact= 0.500E+00 0.203E+00 0.203E+00x,u,uexact= 0.550E+00 0.201E+00 0.200E+00x,u,uexact= 0.600E+00 0.193E+00 0.193E+00x,u,uexact= 0.650E+00 0.181E+00 0.181E+00x,u,uexact= 0.700E+00 0.164E+00 0.164E+00x,u,uexact= 0.750E+00 0.144E+00 0.143E+00x,u,uexact= 0.800E+00 0.119E+00 0.119E+00x,u,uexact= 0.850E+00 0.922E-01 0.920E-01x,u,uexact= 0.900E+00 0.627E-01 0.626E-01x,u,uexact= 0.950E+00 0.318E-01 0.317E-01x,u,uexact= 0.100E+01 0.000E+00 -0.177E-07

 FORTRAN code

c Inhomogeneous wave eq. 10 sep 2011 J.W. Dettman, Dover Pub. page 386c One dimensional wave equation alfa**2*d^2 u/dx^2 = d^2u/dt^2c alfa =velocity /// c solved by forward difference methodc Lscale is the length of the string , while tscale=L/alfac stability imposes the condition sqrt(sigma/rho)*dt/dx < 1      dimension u(0:10000,0:10000)      real L , K ,K2      data L ,sigma ,rho ,F0 /1.,1.,1.,1. /      data nstep/20/      uexact(x,t)=(F0/(pi**2*sigma))*sin(pi*x)*(1.-     $ cos(pi*sqrt(sigma/rho)*t) )      ucero(x)=0.c initial speed  du(x,0)/dt      dudt(x)=0.      pi=2.*asin(1.)

Page 20: Fortran Nnn

      dx=L/float(nstep)      dt=(1./10.)*sqrt(rho/sigma)*dx      tscale=L*sqrt(rho/sigma)      K=(sigma/rho)*(dt**2/dx**2)      K2=(F0/rho)*dt**2c boundary conditions- wave has zero amplitude at x=0.and at x=L      do 70 i=0,1000      u(0,i)=0.      u(nstep,i)=0.70    continue      tfinal=tscale      ntime=int(tfinal/dt)      print*,'tscale, tfinal =',tscale, tfinal      print*,'dt,dx,nstep,ntime=',dt,dx,nstep,ntime      print*,' 'c initital data for row zero and first row u1=u0+(dudt) delta(t)      do 10 i=1,nstep-1      x=dx*float(i)      u(i,0)=ucero(x)      u(i,1)=dudt(x)*dt + ucero(x)10    continuec Forward difference approximation is taken      do 30 j=1,ntime      t=dt*float(j)      do 30 i=1,nstep-1      x=dx*float(i)      u(i,j+1)=2.*u(i,j)-u(i,j-1) + K*( u(i+1,j)-2.*u(i,j)+     $u(i-1,j))+K2*sin(pi*x)30    continuec     print*,'final time=',tfinal      do 50 i=0,nstep      x=dx*float(i)      print 100 ,x , u(i,ntime),uexact(x,tfinal)50    continue100   format(2x,'x,u,uexact=',3(3x,e10.3))      stop      end

 

Page 21: Fortran Nnn

 

 

 

 

 

 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:∂u/∂t + u∂u/∂x = 0

* A. Salih, Dept. of Mechanical Engg., NIT - Trichy, India. *************************************************************************** THIS PROGRAM SOLVES ONE-DIMENSIONAL NONLINEAR WAVE EQUATION WITH ** PERIODIC NAD NONPERIODIC BOUNDARY CONDITIONS USING ** CONSERVATIVE FINITE VOLUME METHOD ** -Schemes: 1. FTCS Scheme ** 2. Upwind Scheme ** 3. Lax-Friedrichs Scheme *

Page 22: Fortran Nnn

* 4. Lax-Wendroff Scheme ** 5. MacCormack Method ** 6. QUICK scheme ** 7. ENO-2 Scheme ***************************************************************************c Remarks: 1. FTCS method is unconditionally unstable.c 2. Lax-Wendroff and MacCormack Schemes produces Gibbs'c oscillations in the vicinity of discontinuities.c 3. Quick scheme also produces large oscillations.c 4. Upwind scheme and Lax-Friedrichs are highly diffusive.c 5. ENO-2 is the best among these schemes.cc Note: For the initial conditions RAMP FUNCTION and STEP FUNCTIONc non-periodic boundary conditions may be used. For other types ofc initial conditions periodic boundary conditions may be used. PROGRAM NONLINEAR_WAVE 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/u.dat',status='unknown') open(unit=33,file='outputs/time.dat',status='unknown') open(unit=34,file='outputs/time2.dat',status='unknown') open(unit=35,file='outputs/u_trans.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 computationc 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 read(11,*) bc_type ! type of BC (1-Periodic, 2-Non-Periodic)

Page 23: Fortran Nnn

read(11,*) ic_type ! initial U profile (1-RAMP FUNCTION_SHOCK, ! 2-RAMP FUNCTION_EXPAN, 3-STEP FUNCTION, ! 4-SQUAREWAVE, 5-SINEWAVE) read(11,*) umax ! maximum value of u in the initail data read(11,*) Co ! Courant number for calculating time step read(11,*) tfinal ! time at which the solution is desired read(11,*) scheme ! 1-FTCS, 2-Upwind, 3-Lax-Fredriechs, ! 4-Lax-Wendroff, 5-MacCormack, 6-QUICK, ! 7-ENO-2 read(11,*) qwt ! weight factor for QUICK scheme ! (1 - for QUICK scheme 0 - for CDS) read(11,*) print_freq !cc calculation of time-step dt based on the stability condition dx = alx /m dt = Co*dx/umax maxntimestp = tfinal /dt dt = tfinal /maxntimestp ! revised time-step Co = umax*dt/dx ! revised Courant number if (tfinal < dt) then print*, 'Warning: final time is less than time-step!' stop endifc 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 (ic_type == 1) then write(21,*) 'The initial profile is ramp function (shock)' elseif (ic_type == 2) then write(21,*) 'The initial profile is ramp function (expansion)' elseif (ic_type == 3) then write(21,*) 'The initial profile is step function' elseif (ic_type == 4) then write(21,*) 'The initial profile is square wave' elseif (ic_type == 5) then write(21,*) 'The initial profile is sine wave' endifc if (scheme == 1) then write(21,*) 'FTCS scheme' elseif (scheme == 2) then write(21,*) 'Upwind scheme' elseif (scheme == 3) then write(21,*) 'Lax-Friedrichs scheme'

Page 24: Fortran Nnn

elseif (scheme == 4) then write(21,*) 'Lax-Wendroff scheme' elseif (scheme == 5) then write(21,*) 'MacCormack scheme' elseif (scheme == 6) then write(21,*) 'QUICK scheme' elseif (scheme == 7) then write(21,*) 'Essentially NonOscillatory scheme' endifc write(21,*) 'Courant number, Co =', Co write(21,*) 'Length of the domain', alx write(21,*) 'Number of grids (including boundaries):', m write(21,*) 'dx =', dx write(21,*) 'dt =', dt write(21,*) 'No. of time step = ', ntimestp write(21,*) 'Final time = ', timec 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'cc m = number of control volumes the in x-direction dx = alx /m x(0) = -dx/2 do i = 1, m1 x(i) = x(i-1) + dx enddoc return end

****SUBROUTINE: INITIAL CONDITIONS FOR TEMPERATURE*********************** SUBROUTINE INITIAL_COND implicit doubleprecision (a-h,o-z) include 'scalars/integers.inc'cc defining the initial conditions if (ic_type == 1) then CALL RAMPFN_SHOCK elseif (ic_type == 2) then CALL RAMPFN_EXPAN elseif (ic_type == 3) then CALL STEPFN elseif (ic_type == 4) then CALL SQUAREWAVE

Page 25: Fortran Nnn

elseif (ic_type == 5) then CALL SINEWAVE endifc return end*****SUBROUTINE: INITIAL CONDITION - RAMP FUNCTION (SHOCK)* SUBROUTINE RAMPFN_SHOCK 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/u.inc'c vdisp = 0.1d0*alx uleft = vdisp + 0.1d0*alx uright = vdisp xleft = 0.3d0*alx xright = 0.4d0*alx slope = (uleft-uright) /(xleft-xright) do i = 0, m1 if (x(i) <= xleft) then U(i) = uleft elseif (x(i) < xright) then U(i) = uleft + slope*(x(i) - xleft) else U(i) = uright endif enddoc return end*****SUBROUTINE: INITIAL CONDITION - RAMP FUNCTION (EXPANSION FAN)* SUBROUTINE RAMPFN_EXPAN 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/u.inc'c vdisp = 0.1d0*alx uleft = vdisp uright = vdisp + 0.1d0*alx xleft = 0.3d0*alx xright = 0.4d0*alx slope = (uleft-uright) /(xleft-xright) do i = 0, m1 if (x(i) <= xleft) then

Page 26: Fortran Nnn

U(i) = uleft elseif (x(i) < xright) then U(i) = uleft + slope*(x(i) - xleft) else U(i) = uright endif enddoc return end*****SUBROUTINE: INITIAL CONDITION - STEP FUNCTION* SUBROUTINE STEPFN 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/u.inc'c vdisp = 0.1d0*alx uleft = vdisp + 0.1d0*alx uright = vdisp xstep = 0.3d0*alx do i = 0, m1 if (x(i) <= xstep) then U(i) = uleft else U(i) = uright endif enddoc return end*****SUBROUTINE: INITIAL CONDITION - SQUARE WAVE* SUBROUTINE SQUAREWAVE implicit doubleprecision (a-h,o-z) include 'array_dimension.inc' include 'scalars/integers.inc' include 'scalars/reals.inc' include 'scalars/parameters.inc' include 'arrays/u.inc'c amp = 1d0 vdisp = 5d-1 mleft = m/2+1 - m/10 mright = m/2 + m/10 do i = 0, m1 if ( (i <= mleft).or.(i >= mright) ) then U(i) = vdisp else U(i) = vdisp + amp

Page 27: Fortran Nnn

endif enddoc return end*****SUBROUTINE: INITIAL CONDITION - SINE WAVE* SUBROUTINE SINEWAVE implicit doubleprecision (a-h,o-z) include 'array_dimension.inc' include 'scalars/integers.inc' include 'scalars/reals.inc' include 'scalars/parameters.inc' include 'arrays/u.inc'c amp = 1d0 vdisp = 5d-1 mleft = m/2+1 - m/10 mright = m/2 + m/10 denom = mright-mleft do i = 0, m1 if ( (i <= mleft).or.(i >= mright) ) then U(i) = vdisp else U(i) = vdisp + amp*dsin(pi*(i-mleft)/denom) endif enddoc 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/u.inc' doubleprecision UN(-1:m+2), UPRED(-1:m+2), f(-1:m+2) doubleprecision minmod_m, minmod_pcc storing the values of u at nth time level UN = Uc ntimestp = 0 maxdif = 1d9 time = 0d0 write(33,101) time ! continuous time write(34,101) time ! intermittent time monitor = m/4 write(35,*) U(monitor)c

Page 28: Fortran Nnn

maccycle = 1c10 if (ntimestp < maxntimestp) thenc boundary conditions if (bc_type == 1) thenc periodic boundary conditionsc west do i = 0,-1,-1 UN(i) = UN(m+i) enddoc east do i = 1,2 UN(m+i) = UN(i) enddo elseif (bc_type == 2) thenc nonperiodic boundary conditionsc west do i = 0,-1,-1 UN(i) = UN(1) enddoc east do i = 1,2 UN(m+i) = UN(m) enddo endifc calculation of flux function do i = -1, m+2 f(i) = UN(i)**2/2d0 enddoc if (scheme == 1) then ! FTCS do i = 1,m f_w = (f(i) + f(i-1))/2 f_e = (f(i) + f(i+1))/2 U(i) = UN(i) - (dt/dx)*(f_e - f_w) enddoc elseif (scheme == 2) then ! Upwind do i = 1,m u_w = (UN(i-1) + UN(i))/2 u_e = (UN(i) + UN(i+1))/2 f_w = max(u_w,0d0)*f(i-1) + min(u_w,0d0)*f(i) f_e = max(u_e,0d0)*f(i) + min(u_e,0d0)*f(i+1) f_w = f_w /(u_w + 1d-30) f_e = f_e /(u_e + 1d-30) U(i) = UN(i) - (dt/dx)*(f_e - f_w) enddoc elseif (scheme == 3) then ! Lax-Friedrichs do i = 1,m f_w = dx/(2*dt)*(UN(i-1) - UN(i)) + (f(i) + f(i-1))/2d0 f_e = dx/(2*dt)*(UN(i) - UN(i+1)) + (f(i+1) + f(i))/2d0 U(i) = UN(i) - (dt/dx)*(f_e - f_w) enddoc elseif (scheme == 4) then ! Lax-Wendroff

Page 29: Fortran Nnn

c predictor step do i = 1,m UPRED(i) = (UN(i+1) + UN(i))/2 - (dt/dx)*(f(i+1)-f(i))/2 enddo if (bc_type == 1) then do i = 0,-1,-1 UPRED(i) = UPRED(m+i) enddo do i = 1,2 UPRED(m+i) = UPRED(i) enddo elseif (bc_type == 2) then do i = 0,-1,-1 UPRED(i) = UPRED(1) enddo do i = 1,2 UPRED(m+i) = UPRED(m) enddo endifc corrector step do i = 1,m fpred_w = UPRED(i-1)**2/2d0 fpred_e = UPRED(i)**2/2d0 U(i) = UN(i) - (dt/dx)*(fpred_e - fpred_w) enddoc elseif (scheme == 5) then ! MacCormackc Note: during first cyle, prdictor is forward differenced andc corrector backward; the order is reversed in the next cycle j = maccycle + 1 maccycle = mod(j,2)c predictor step if (maccycle == 0) then do i = 1,m UPRED(i) = UN(i) - (dt/dx)*(f(i+1) - f(i)) enddo elseif (maccycle == 1) then do i = 1,m UPRED(i) = UN(i) - (dt/dx)*(f(i) - f(i-1)) enddo endif if (bc_type == 1) then do i = 0,-1,-1 UPRED(i) = UPRED(m+i) enddo do i = 1,2 UPRED(m+i) = UPRED(i) enddo elseif (bc_type == 2) then do i = 0,-1,-1 UPRED(i) = UPRED(1) enddo do i = 1,2 UPRED(m+i) = UPRED(m) enddo endif

Page 30: Fortran Nnn

c corrector step if (maccycle == 0) then do i = 1,m fpred_w = (f(i) + UPRED(i-1)**2/2d0) /2d0 fpred_e = (f(i+1) + UPRED(i)**2/2d0) /2d0 U(i) = UN(i) - (dt/dx)*(fpred_e - fpred_w) enddo elseif (maccycle == 1) then do i = 1,m fpred_w = (f(i-1) + UPRED(i)**2/2d0) /2d0 fpred_e = (f(i) + UPRED(i+1)**2/2d0) /2d0 U(i) = UN(i) - (dt/dx)*(fpred_e - fpred_w) enddo endifc elseif (scheme == 6) then ! QUICK do i = 1,m u_w = (UN(i-1) + UN(i))/2 u_e = (UN(i) + UN(i+1))/2 f_w = max(u_w,0d0)*((f(i) + f(i-1))/2d0 - $ (qwt/8)*(f(i) - 2*f(i-1) + f(i-2))) + $ min(u_w,0d0)*((f(i) + f(i-1))/2d0 - $ (qwt/8)*(f(i+1) - 2*f(i) + f(i-1))) f_e = max(u_e,0d0)*((f(i) + f(i+1))/2d0 - $ (qwt/8)*(f(i+1) - 2*f(i) + f(i-1))) + $ min(u_e,0d0)*((f(i) + f(i+1))/2d0 - $ (qwt/8)*(f(i+2) - 2*f(i+1) + f(i))) f_w = f_w /(u_w + 1d-30) f_e = f_e /(u_e + 1d-30) U(i) = UN(i) - (dt/dx)*(f_e - f_w) enddoc elseif (scheme == 7) then ! ENO-2c second-order Essentially NonOscillatory scheme do i = 1,m u_w = (UN(i-1) + UN(i))/2 u_e = (UN(i) + UN(i+1))/2 dUdxxm = (f(i) - 2*f(i-1) + f(i-2)) /dx dUdxx = (f(i+1) - 2*f(i) + f(i-1)) /dx dUdxxp = (f(i+2) - 2*f(i+1) + f(i)) /dxc if (dUdxx *dUdxxm > 0) then minmod_m = dUdxx/(dabs(dUdxx)+1d-30) * $ min(dabs(dUdxx), dabs(dUdxxm)) else minmod_m = 0 endifc if (dUdxx *dUdxxp > 0) then minmod_p = dUdxx/(dabs(dUdxx)+1d-30) * $ min(dabs(dUdxx), dabs(dUdxxp)) else minmod_p = 0 endifc f_w = max(u_w,0d0)*(f(i-1) - (dx/2)*minmod_m) +

Page 31: Fortran Nnn

$ min(u_w,0d0)*f(i) f_e = max(u_e,0d0)*f(i) + $ min(u_e,0d0)*(f(i+1) - (dx/2)*minmod_p) f_w = f_w /(u_w + 1d-30) f_e = f_e /(u_e + 1d-30) U(i) = UN(i) - (dt/dx)*(f_e - f_w) enddo

endifc time = time + dt ntimestp = ntimestp + 1cc updating u values at fictitious nodes if (bc_type == 1) then do i = 0,-1,-1 U(i) = U(m+i) enddo do i = 1,2 U(m+i) = U(i) enddo elseif (bc_type == 2) then do i = 0,-1,-1 U(i) = U(1) enddo do i = 1,2 U(m+i) = U(m) enddo endifc UN = Uc write(33,101) time ! continuous time write(6,102) ntimestpcc printing out transient u at selected point of domain j = jcounter + 1 jcounter = mod(j,print_freq) if (jcounter == 0) then write(34,101) (time + dt) ! intermittent time write(35,*) U(monitor) endif go to 10 endifc101 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'

Page 32: Fortran Nnn

include 'scalars/integers.inc' include 'scalars/reals.inc' include 'arrays/u.inc' include 'arrays/grid.inc'c x(0) = 0 x(m+1) = alx if (bc_type == 1) then if (time == 0d0) then U(0) = U(0) U(m+1) = U(m) else U(0) = (U(0) + U(1))/2 U(m+1) = (U(m) + U(m+1))/2 endif elseif (bc_type == 2) then U(0) = U(1) U(m+1) = U(m) endif write(31,101) (x(i), i=0,m+1) write(32,102) (U(i), i=0,m+1)101 format(e13.6)102 format(e13.6)c return end