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