1 | !---------------------------------------------------------------
|
---|
2 | ! This is the problem module for the Rayleigh-Taylor instability.
|
---|
3 | !---------------------------------------------------------------
|
---|
4 | MODULE Problem
|
---|
5 |
|
---|
6 | ! In general, DataDeclarations is always used since it defines the InfoDef type
|
---|
7 | ! PhysicsDeclarations and GlobalDeclarations are almost always used
|
---|
8 | ! To see exactly what these "sub-modules" define, look at their .f90 files in the astrobear directory
|
---|
9 | USE DataDeclarations
|
---|
10 | USE PhysicsDeclarations
|
---|
11 | USE GlobalDeclarations
|
---|
12 | USE SourceDeclarations
|
---|
13 | IMPLICIT NONE
|
---|
14 | SAVE
|
---|
15 |
|
---|
16 | ! This PUBLIC statement must be present
|
---|
17 | PUBLIC ProblemModuleInit, ProblemGridInit, &
|
---|
18 | ProblemBeforeStep, ProblemAfterStep, ProblemSetErrFlag
|
---|
19 |
|
---|
20 | ! Some variables are used in more than one SUBROUTINE so they are defined here
|
---|
21 | ! qPREC is a type of precision defined in GlobalDeclarations
|
---|
22 | REAL(KIND=qPREC), PUBLIC :: DensityAbove, DensityBelow, Amplitude, atwood_number, wave_number, lambda_analytic
|
---|
23 |
|
---|
24 | CONTAINS
|
---|
25 |
|
---|
26 | ! Initialize module variables
|
---|
27 | SUBROUTINE ProblemModuleInit()
|
---|
28 |
|
---|
29 | ! Define variables and namelists
|
---|
30 | INTEGER :: OpenStatus
|
---|
31 | NAMELIST /ProblemData/ DensityAbove, DensityBelow, Amplitude
|
---|
32 |
|
---|
33 | ! Open problem.data and read in data
|
---|
34 | ! Problem_Data_Handle is just an integer defined in GlobalDeclarations
|
---|
35 | ! OpenStatus variable could be used to check if file is opening correctly
|
---|
36 | OPEN(UNIT=Problem_Data_Handle, FILE='problem.data', STATUS="OLD",IOSTAT=OpenStatus)
|
---|
37 | READ(Problem_Data_Handle, NML=ProblemData)
|
---|
38 | CLOSE(Problem_Data_Handle)
|
---|
39 | END SUBROUTINE ProblemModuleInit
|
---|
40 |
|
---|
41 | ! Initialize data arrays
|
---|
42 | SUBROUTINE ProblemGridInit(Info)
|
---|
43 |
|
---|
44 | ! User defined variables, note which ones must be REAL and which are INTEGER
|
---|
45 | TYPE(InfoDef) :: Info
|
---|
46 | INTEGER :: rmbc, zrmbc, mx, my, mz, i, j, k
|
---|
47 | REAL(KIND=qPREC) :: x, y, z, rho, P, Lx, Ly, Lz, vy
|
---|
48 | REAL(KIND=qPREC) :: dx, dz, xlower, ylower, zlower
|
---|
49 |
|
---|
50 | ! Initializes the q-array
|
---|
51 | Info%q=0
|
---|
52 |
|
---|
53 | ! levels is defined in GlobalDeclarations
|
---|
54 | rmbc=levels(Info%level)%gmbc(levels(Info%level)%step)
|
---|
55 |
|
---|
56 | ! Assign some useful values with convenient names for ease of use and readability
|
---|
57 | ! Gxbounds is defined in GlobalDeclarations
|
---|
58 | mx=Info%mX(1); dx=levels(Info%level)%dX; xlower=Info%xbounds(1,1); Lx=Gxbounds(1,2)-Gxbounds(1,1)
|
---|
59 | my=Info%mX(2); dz=levels(Info%level)%dX; ylower=Info%xbounds(2,1); Ly=Gxbounds(2,2)-Gxbounds(2,1)
|
---|
60 | mz=Info%mX(3); zlower=Info%xbounds(3,1); Lz=Gxbounds(3,2)-Gxbounds(3,1)
|
---|
61 |
|
---|
62 | ! Allows for 2D or 3D simulations
|
---|
63 | ! Note that in 2D, Lz is explicitly set to 1 so there is no divide by zero in the perturbation
|
---|
64 | SELECT CASE(nDim)
|
---|
65 | CASE(2)
|
---|
66 | zrmbc=0;mz=1;zlower=0;dz=0;Lz=1
|
---|
67 | CASE(3)
|
---|
68 | zrmbc=rmbc
|
---|
69 | END SELECT
|
---|
70 |
|
---|
71 |
|
---|
72 |
|
---|
73 | ! Initialize the grid
|
---|
74 | DO k=1-zrmbc, mz+zrmbc
|
---|
75 | DO j=1-rmbc, my+rmbc
|
---|
76 | DO i=1-rmbc, mx+rmbc
|
---|
77 |
|
---|
78 | ! Cell-to-space conversion (half is defined in GlobalDeclarations)
|
---|
79 | x=(xlower + (REAL(i) - half) * dx)
|
---|
80 | y=(ylower + (REAL(j) - half) * dx)
|
---|
81 | z=(zlower + (REAL(k) - half) * dz)
|
---|
82 |
|
---|
83 | ! Define density profile
|
---|
84 | IF (y < 0) THEN
|
---|
85 | rho = DensityBelow
|
---|
86 | ELSE
|
---|
87 | rho = DensityAbove
|
---|
88 | END IF
|
---|
89 |
|
---|
90 | ! Define pressure gradient
|
---|
91 | P = 2.5 - rho * mCentral * y
|
---|
92 |
|
---|
93 | ! Define perturbation (Pi is defined in PhysicsDeclarations)
|
---|
94 | vy = Amplitude * (1+COS(2*Pi*x/Lx)) * (1+COS(2*Pi*y/Ly)) * (1+COS(2*Pi*z/Lz)) / 8
|
---|
95 |
|
---|
96 | ! Put information into q-array (gamma, ivy, iE are defined in PhysicsDeclarations)
|
---|
97 | Info%q(i, j, k, 1) = rho
|
---|
98 | Info%q(i, j, k, ivy) = rho * vy
|
---|
99 | Info%q(i, j, k, iE) = P / (gamma - 1.0) + half * rho * vy**2
|
---|
100 | END DO
|
---|
101 | END DO
|
---|
102 | END DO
|
---|
103 |
|
---|
104 | ! For analysis...calculates the analytic growth rate and saves it in a file
|
---|
105 | atwood_number = (DensityAbove - DensityBelow) / (DensityAbove + DensityBelow)
|
---|
106 | wave_number = 2*Pi/Lx
|
---|
107 | lambda_analytic = SQRT(atwood_number * wave_number * mCentral)
|
---|
108 | OPEN(UNIT=82,FILE='GrowthRate.data',STATUS='REPLACE')
|
---|
109 | WRITE(82,*) lambda_analytic
|
---|
110 | CLOSE(82)
|
---|
111 |
|
---|
112 | END SUBROUTINE ProblemGridInit
|
---|
113 |
|
---|
114 | ! Place any pre-processing operations here (This is what is meant by leaving a SUBROUTINE as a stub)
|
---|
115 | SUBROUTINE ProblemBeforeStep(Info)
|
---|
116 | TYPE(InfoDef) :: Info
|
---|
117 | END SUBROUTINE ProblemBeforeStep
|
---|
118 |
|
---|
119 | ! Place any post-processing operations here
|
---|
120 | SUBROUTINE ProblemAfterStep(Info)
|
---|
121 | TYPE(InfoDef) :: Info
|
---|
122 | END SUBROUTINE ProblemAfterStep
|
---|
123 |
|
---|
124 | ! Can be used to set additional refinement
|
---|
125 | SUBROUTINE ProblemSetErrFlag(Info)
|
---|
126 | TYPE(InfoDef) :: Info
|
---|
127 | REAL(KIND=qPREC) :: pos
|
---|
128 | REAL(KIND=qPREC), PARAMETER :: lambda = 0.6472
|
---|
129 | REAL(KIND=qPREC), DIMENSION(0:MaxLevel) :: mybuffer
|
---|
130 | REAL(KIND=qPREC), DIMENSION(:,:), POINTER :: offsets
|
---|
131 | REAL(KIND=qPREC), DIMENSION(3,2) :: xBounds
|
---|
132 | INTEGER, DIMENSION(3,2) :: mS
|
---|
133 | INTEGER, DIMENSION(:,:,:), POINTER :: mSs
|
---|
134 | INTEGER :: i, nOverlaps
|
---|
135 | mybuffer(0:MaxLevel)=(/5d-2,25d-3,125d-4/)
|
---|
136 | xBounds=GxBounds
|
---|
137 | pos=0.003*EXP(lambda*levels(Info%level)%tnow) + mybuffer(Info%level)
|
---|
138 | xBounds(2,:)=(/-pos,+pos/)
|
---|
139 | CALL CalcPhysicalOverlaps(Info, xBounds, mSs, nOverlaps, offsets, IEVERYWHERE, lHydroPeriodic,0)
|
---|
140 | IF (nOverlaps > 0) THEN
|
---|
141 | DO i=1,nOverlaps
|
---|
142 | mS=mSs(i,:,:)
|
---|
143 | Info%ErrFlag(mS(1,1):mS(1,2), mS(2,1):mS(2,2), mS(3,1):mS(3,2)) = 1
|
---|
144 | END DO
|
---|
145 | DEALLOCATE(mSs, offsets)
|
---|
146 | NULLIFY(mSs, offsets)
|
---|
147 | END IF
|
---|
148 | END SUBROUTINE ProblemSetErrFlag
|
---|
149 |
|
---|
150 | END MODULE Problem
|
---|