Changes between Version 50 and Version 51 of ModulesOnAstroBear


Ignore:
Timestamp:
04/24/17 16:03:38 (8 years ago)
Author:
Jonathan
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • ModulesOnAstroBear

    v50 v51  
    9999
    100100
    101 ==== Initializing a Grid / Updating boundary conditions ====
    102 
    103 Initializing a grid  involves taking a spatially-constructed problem setup and discretizing it so that it fits nicely in an array.  This process is easiest to explain by dissecting an example, such as the one below, where we are trying to initialize the grid with a uniform background (density = 1, pressure = 1) and an overdense spherical clump centered at the origin with radius 1.  We then want to add a constant wind of density 1, pressure 1, and velocity 10 coming from the left boundary.
     101== Reading in Problem parameters and converting to computational units ==
     102
     103Initializing a grid involves setting the fluid values at each cell with spatially averaged values of your initial coniditions.  This process is easiest to explain by dissecting an example, such as the one below, where we are trying to initialize the grid with a uniform background (density = '''rhoAmb''', Temperature = '''Tamb''') and an overdense spherical clump centered at the origin with radius '''R''', density '''rhoClump''' in pressure equilibrium with the ambient.  We then want to add a constant wind of density '''rhoWind''', Temperature '''TWind''', and velocity '''Vwind''' coming from the left boundary.
     104
     105
     106First, we need to declare our variables and add them to the !ProblemData Namelist.  Then in !ProblemModuleInit, we read them in from the problem.data file and convert all of the variables to computational units.  Here I will assume that input variables are in cgs units (with Temperature in Kelvin).  We are also going to declare additional derived variables to store the calculated wind pressure, clump pressure, and ambient pressure.
     107
     108{{{
     109MODULE Problem
     110  USE GlobalDeclarations
     111  USE PhysicsDeclarations
     112  USE DataDeclarations
     113  IMPLICIT NONE
     114  SAVE
     115  PUBLIC ProblemModuleInit, ProblemGridInit, ProblemBeforeStep, &
     116         ProblemAfterStep, ProblemSetErrFlag, ProblemBeforeGlobalStep
     117  PRIVATE
     118  REAL(KIND=qPREC) :: rhoAmb, Tamb, rhoClump, RClump, rhoWind, TWind, vWind
     119  REAL(KIND=qPREC) :: pWind, pClump, pAmb
     120
     121CONTAINS
     122
     123  SUBROUTINE ProblemModuleInit()
     124    NAMELIST/ProblemData/ rhoAmb, Tamb, rhoClump, RClump, rhoWind, TWind, vWind
     125    OPEN(UNIT=PROBLEM_DATA_HANDLE, FILE='problem.data', STATUS="OLD")
     126    READ(PROBLEM_DATA_HANDLE,NML=ProblemData)
     127    CLOSE(PROBLEM_DATA_HANDLE)
     128    rhoAmb = rhoAmb / rScale
     129    rhoClump = rhoClump / rScale
     130    rhoWind = rhoWind / rScale
     131    TAmb = TAmb / TempScale
     132    TWind = TWind / TempScale
     133    RClump = RClump / lScale
     134    vWind = vWind / velScale
     135
     136    pAmb = rhoAmb * TAmb
     137    pWind = rhoWind * TWind
     138    pClump = pAmb
     139
     140  END SUBROUTINE
     141}}}
     142
     143=== Using Template Functions ===
     144One way to apply our initial/boundary functions to grid patches is to use template subroutines.  This involves writing IC and BC subroutines that adhere to a certain form and then passing them to the ApplyTemplate subroutine.  The ApplyTemplate loops over the grid cells and converts the q-array to primitive form (density, velocity, pressure) before calling the template function (in this case !InitialCondition or !BoundaryCondition.
     145
     146{{{
     147
     148 SUBROUTINE ProblemGridInit(Info)
     149    TYPE(InfoDef) :: Info
     150    CALL ApplyFunction(InitialCondition, Info)
     151  END SUBROUTINE ProblemGridInit
     152
     153  SUBROUTINE ProblemBeforeStep(Info)
     154    TYPE(InfoDef) :: Info
     155    CALL ApplyFunction(BoundaryCondition, Info)
     156  END SUBROUTINE ProblemBeforeStep
     157
     158
     159  SUBROUTINE InitialCondition(pos, t, dt, q, Ghost)
     160    REAL(KIND=qPREC), DIMENSION(:) :: pos
     161    REAL(KIND=qPREC), DIMENSION(:) :: q
     162    REAL(KIND=qPREC) :: t, dt
     163    LOGICAL :: Ghost
     164    IF (sqrt(sum(pos**2)) < RClump) THEN
     165       q(1) = rhoClump
     166       q(imom(1:nDim))=0
     167       q(iE) = pClump
     168    ELSE
     169       q(1) = rhoAmb
     170       q(imom(1:nDim)) = 0
     171       q(iE) = pAmb
     172    END IF
     173  END SUBROUTINE InitialCondition
     174
     175
     176  SUBROUTINE BoundaryCondition(pos, t, dt, q, Ghost)
     177    REAL(KIND=qPREC), DIMENSION(:) :: pos
     178    REAL(KIND=qPREC), DIMENSION(:) :: q
     179    REAL(KIND=qPREC) :: t, dt
     180    LOGICAL :: Ghost
     181    IF (pos(1) < GxBounds(1,1)) THEN
     182       q(1) = rhoWind
     183       q(imom(1:nDim))=0
     184       q(ivx) = vWind
     185       q(iE) = pWind
     186    END IF
     187  END SUBROUTINE BoundaryCondition
     188
     189 
     190}}}
     191
     192A second option is to loop over the cells ourselves
     193
    104194
    105195{{{
     
    109199    REAL(KIND=xPREC) :: pos(3)
    110200
    111     ! Initialize background
    112     Info%q(1:Info%mX(1),1:Info%mX(2),1:Info%mX(3), 1)=1d0
    113     Info%q(1:Info%mX(1),1:Info%mX(2),1:Info%mX(3), ivx)=0d0
    114     IF (ivy /= 0) Info%q(1:Info%mX(1),1:Info%mX(2),1:Info%mX(3), ivy)=0d0
    115     IF (ivz /= 0) Info%q(1:Info%mX(1),1:Info%mX(2),1:Info%mX(3), ivz)=0d0
    116     IF (iE /= 0) Info%q(1:Info%mX(1),1:Info%mX(2),1:Info%mX(3), iE)=gamma7   
    117 
    118     ! Increase density for points inside of clump
     201    ! Loop over cells in patch
    119202    DO i=1, Info%mX(1)
    120203      DO j=1, Info%mX(2)
    121204        DO k=1, Info%mX(3)
    122205          pos=CellPos(Info, i, j, k)
    123           IF (sqrt(sum(pos**2)) < 1d0) THEN
    124             Info%q(i,j,k,irho) = 10d0
     206          IF (sqrt(sum(pos**2)) < RClump) THEN
     207            Info%q(i,j,k,irho) = rhoClump
     208            Info%q(i,j,k,imom(1:nDim)) = 0
     209            Info%q(i,j,k,iE) = gamma7*pClump
     210          ELSE
     211            Info%q(i,j,k,irho) = rhoAmb
     212            Info%q(i,j,k,imom(1:nDim)) = 0
     213            Info%q(i,j,k,iE) = gamma7*pAmb
    125214          END IF                 
    126215        END DO
     
    143232          pos=CellPos(Info, i, j, k)
    144233          IF (pos(1) < GxBounds(1,1)) THEN
    145             Info%q(i,j,k,irho) = 1d0
    146             Info%q(i,j,k,ivx)=10d0
    147             IF (iE /= 0) Info%q(i,j,k, iE)=gamma7+50d0
     234            Info%q(i,j,k,irho) = rhoWind
     235            Info%q(i,j,k,ivx)=vWind*rhoWind
     236            IF (iE /= 0) Info%q(i,j,k, iE)=gamma7*pWind+.5d0*rhoWind*vWind**2
    148237            IF (ivy /= 0) Info%q(i,j,k, ivy)=0d0
    149238            IF (ivz /= 0) Info%q(i,j,k, ivz)=0d0