Changes between Version 14 and Version 15 of ModulesOnAstroBear


Ignore:
Timestamp:
07/12/11 19:40:53 (14 years ago)
Author:
ehansen
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • ModulesOnAstroBear

    v14 v15  
    4949
    5050=== AstroBEAR Module Basics ===
     51
     52[[BR]]
     53==== Simulation Data ====
     54
     55All AstroBEAR modules have at least one thing in common: initializing the problem domain.  Within our code, the problem domain's data is held in {{{InfoDef}}} structures, which is why so many module subroutines take an {{{InfoDef}}} structure as a parameter.
     56
     57There are two major data arrays in {{{InfoDef}}}: the {{{q}}} array and the {{{aux}}} array.  {{{q}}} holds the cell-centered data and is used by all AstroBEAR simulations.  The {{{q}}} array takes the form {{{q(x,y,z,variable)}}} where {{{variable}}} is itself a 1D array that holds the physical quantities such as density, momentum, energy, etc. The order of the quantities in the {{{variable}}} array is {{{(rho, px, py, pz, E)}}}. The {{{aux}}} array holds face-centered data, and is only used in MHD problems.  If you are running a strictly hydrodynamic problem or a hydrodynamic + elliptic problem, then you will not need {{{aux}}}.
     58
     59[[BR]]
     60==== Dimensions ====
     61
     62Currently, AstroBEAR can only run 2D and 3D problems, but a 1D hydro or MHD problem can be simulated by defining a very narrow 2D problem domain and then making sure all the activity is defined in the x-direction (i.e., no {{{py}}} or {{{pz}}} components).
     63
     64The ''core'' region of the {{{Info%q}}} array (which does not include ghost zones) is a {{{1:mx}}} by {{{1:my}}} by {{{1:mz}}} box. Mx, my, and mz denote the number of cells in the x, y, and z directions, respectively.  In two dimensions, {{{mz}}} = 1, reducing the box to a rectangle.  {{{Info%q}}} is cell-centered, so the values are assumed to be taken from the midpoint of the cell.  Thus, the cell-to-space conversion is:
     65
     66{{{
     67x=(xlower + (REAL(i,xPrec)-half) * dx)
     68y=(ylower + (REAL(j,xPrec)-half) * dy)
     69z=(zlower + (REAL(k,xPrec)-half) * dz)
     70}}}
     71
     72[[BR]]
     73The {{{Info%aux}}} array is a little different.  The {{{aux}}} array holds magnetic flux values, which are face-centered.  This means that every cell-centered value in {{{Info%q}}} is bracked in each dimension by two {{{Info%aux}}} values.  To accommodate the extra values, {{{Info%aux}}} is a {{{1:mx+1}}} by {{{1:my+1}}} by {{{1:mz+1}}} box, but the {{{aux}}} dimensions are actually different for each variable:
     74
     75{{{
     76Bx = Info%aux(1:mx+1, 1:my, 1:mz, 1)
     77By = Info%aux(1:mx, 1:my+1, 1:mz, 2)
     78Bz = Info%aux(1:mx, 1:my, 1:mz+1, 3)
     79}}}
     80
     81The additional cells (the ones in the "upper-front right" corner of the {{{aux}}} array) are not used.
     82
     83[[BR]]
     84
     85==== Units and Scaling ====
     86
     87Astrophysical problems involve many different physical units and constants with a wide range of scales.  To avoid the loss of precision that comes when computers try to work with, say, a 10^-8^ variable and a 10^24^ constant in the same expression, we scale our units into ''computational units'' before storing them in the data arrays.
     88
     89Usually, the physical scales are defined in the [PhysicsDataExplained physics.data] file--you simply enter the scales for density, temperature, velocity, etc in that file, and AstroBEAR will read them in. More complicated scaling would be defined in the {{{ProblemModuleInit()}}} routine (see above).
     90
     91You have two options for making sure that you only put scaled quantities in the data arrays: you can scale your input values before you enter them into your input file (and then assume that you are reading in scaled quantities), or you can use physical quantities in your input files and then scale them within your problem module:
     92
     93{{{
     94scaled_qty = physical_qty / physical_scale
     95}}}
     96
     97Either way, a good sanity check is to print out the physical quantities your program uses after the problem is set up.  This verifies that the values you think are going in are the values that are actually getting used.
     98
     99[[BR]]
     100
     101==== Initializing a Grid ====
     102
     103Initializing 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 density distribution given by {{{rho(x,y,z)}}}:
     104
     105Note that during the !ProblemGridInit routine, ghost zones do not need to be initialized (rmbc = 0) - however - during beforestep calculations they should be
     106
     107{{{
     108    q=>Info%q
     109
     110    rmbc=levels(Info%level)%gmbc(levels(Info%level)%step)
     111
     112    mx=Info%mX(1); dx=Info%dX(1); xlower=Info%Xlower(1)
     113    my=Info%mX(2); dy=Info%dX(2); ylower=Info%Xlower(2)
     114    mz=Info%mX(3); dz=Info%dX(3); zlower=Info%Xlower(3)
     115
     116    SELECT CASE(nDim)
     117    CASE(2)
     118       zrmbc=0;mz=1;zl=0;dz=0
     119    CASE(3)
     120       zrmbc=rmbc
     121    END SELECT
     122
     123    ! Initialize environment
     124    DO k=1-zrmbc, mz+zrmbc
     125        DO j=1-rmbc, my+rmbc
     126            DO i=1-rmbc, mx+rmbc
     127
     128                x=(xlower + (REAL(i,xPrec)-half) * dx)
     129                y=(ylower + (REAL(j,xPrec)-half) * dy)
     130                z=(zlower + (REAL(k,xPrec)-half) * dz)
     131
     132                q(i,j,k) = rho(x,y,z)
     133            END DO
     134        END DO
     135    END DO
     136}}}
     137
     138Each grid (or {{{InfoDef}}} structure) comes with several arrays that describe its geometry:
     139
     140 * '''''mX(3)''''':  The grid's overall size.  Each element {{{mx(n)}}} represents the number of cells along the ''n''th dimension.
     141 * '''''Xlower(3)''''':  The spatial coordinates of the grid's lower bound in each dimension.  These values are ''always'' given in computational units.
     142 * '''''dX(3)''''':  The size of a spatial step in a given dimension.  {{{dX(n)}}} can also be thought of as the size of a cell along dimension ''n''.
     143
     144To make this example more readable (and therefore easier to debug), we assigned the various array values more Cartesian-sounding names (ie., {{{Info%dX(2) = dy}}}).
     145
     146Similarly, when calculating the spatial equivalents of an index, we went with {{{x}}}, {{{y}}} and {{{z}}}.  The half-step in the position calculations represents the fact that the spatial position is at the ''center'' of the cell, not the left side.
     147
     148The check on the number of dimensions makes sure that 2D problem does not accidentally get initialized with ghost cells (see below) or a spatial step.  This allows us to use the same initialization code for 2D or 3D problems.
     149
     150The {{{levels()}}} array is a global array structures that contain information specific to each level.  You can see in this example that we reference the appropriate level by using the {{{Info%level}}} attribute.
     151
     152You may have noticed the nested loops don't go from {{{1}}} to {{{mX(n)}}}.  This is because the data array size is not the same as the grid size.  The size of each grid along dimension ''n'' is {{{mX(n)}}}.  The ''data arrays'', however, have a number of "ghost cells" associated with them.  The number of ghost cells on the end of a grid is given by the quantity
     153
     154{{{
     155levels(Info%level)%CoarsenRatio * levels(Info%level)%gmbc
     156}}}
     157
     158These ghost cells only appear along the dimensions of the problem, though, so the data arrays for a 2D problem will not have ghost cells along the third dimension.  So the real extents of the data arrays in a 3D problem are:
     159
     160{{{
     161Info%q(1 - rmbc : mX(1) + rmbc, &
     162       1 - rmbc : mX(2) + rmbc, &
     163       1 - rmbc : mX(3) + rmbc, &
     164       NrVars)
     165}}}
     166
     167{{{
     168Info%aux(1 - rmbc : mX(1) + rmbc + 1, &
     169         1 - rmbc : mX(2) + rmbc + 1, &
     170         1 - rmbc : mX(3) + rmbc + 1, &
     171         NrVars)
     172}}}
     173
     174
     175[[BR]]
     176==== Flagging Cells for Refinement ====
     177
     178
     179
     180[[BR]]
     181Some modules may need specific regions refined, regardless of whether or not there is any obvious error there.  AstroBEAR flags cells for refinement using the array
     182
     183{{{
     184Info%ErrorFlags(1 - rmbc : mX(1) + rmbc, &
     185                1 - rmbc : mX(2) + rmbc, &
     186                1 - rmbc : mX(2) + rmbc, &
     187                NrVars)
     188}}}
     189
     190To clear the cell at {{{(i,j,k)}}}, simply set {{{Info%ErrorFlags(i,j,k)}}} to 0.  An error flag of 0 means that the cell does not ''need'' to be refined (although it might happen anyway).  To mark a cell for refinement, set {{{Info%ErrorFlags(i,j,k)}}} to 1.  The best place to do this is in the {{{ProblemSetErrFlags()}}} routine; most conventional physical criteria for refinement are already handled by AstroBEAR itself.
     191
     192[[BR]]
     193
     194==== Sample Module ====
    51195
    52196[[BR]]
     
    61205USE PhysicsDeclarations
    62206IMPLICIT NONE
    63 }}}
    64 
    65 ==== Simulation Data ====
    66 
    67 All AstroBEAR modules have at least one thing in common: initializing the problem domain.  Within our code, the problem domain's data is held in {{{InfoDef}}} structures, which is why so many module subroutines take an {{{InfoDef}}} structure as a parameter.
    68 
    69 There are two major data arrays in {{{InfoDef}}}: the {{{q}}} array and the {{{aux}}} array.  {{{q}}} holds the cell-centered data and is used by all AstroBEAR simulations.  The {{{q}}} array takes the form {{{q(x,y,z,variable)}}} where {{{variable}}} is itself a 1D array that holds the physical quantities such as density, momentum, energy, etc. The order of the quantities in the {{{variable}}} array is {{{(rho, px, py, pz, E)}}}. The {{{aux}}} array holds face-centered data, and is only used in MHD problems.  If you are running a strictly hydrodynamic problem or a hydrodynamic + elliptic problem, then you will not need {{{aux}}}.
    70 
    71 [[BR]]
    72 ==== Dimensions ====
    73 
    74 Currently, AstroBEAR can only run 2D and 3D problems, but a 1D hydro or MHD problem can be simulated by defining a very narrow 2D problem domain and then making sure all the activity is defined in the x-direction (i.e., no {{{py}}} or {{{pz}}} components).
    75 
    76 The ''core'' region of the {{{Info%q}}} array (which does not include ghost zones) is a {{{1:mx}}} by {{{1:my}}} by {{{1:mz}}} box. Mx, my, and mz denote the number of cells in the x, y, and z directions, respectively.  In two dimensions, {{{mz}}} = 1, reducing the box to a rectangle.  {{{Info%q}}} is cell-centered, so the values are assumed to be taken from the midpoint of the cell.  Thus, the cell-to-space conversion is:
    77 
    78 {{{
    79 x=(xlower + (REAL(i,xPrec)-half) * dx)
    80 y=(ylower + (REAL(j,xPrec)-half) * dy)
    81 z=(zlower + (REAL(k,xPrec)-half) * dz)
    82 }}}
    83 
    84 [[BR]]
    85 The {{{Info%aux}}} array is a little different.  The {{{aux}}} array holds magnetic flux values, which are face-centered.  This means that every cell-centered value in {{{Info%q}}} is bracked in each dimension by two {{{Info%aux}}} values.  To accommodate the extra values, {{{Info%aux}}} is a {{{1:mx+1}}} by {{{1:my+1}}} by {{{1:mz+1}}} box, but the {{{aux}}} dimensions are actually different for each variable:
    86 
    87 {{{
    88 Bx = Info%aux(1:mx+1, 1:my, 1:mz, 1)
    89 By = Info%aux(1:mx, 1:my+1, 1:mz, 2)
    90 Bz = Info%aux(1:mx, 1:my, 1:mz+1, 3)
    91 }}}
    92 
    93 The additional cells (the ones in the "upper-front right" corner of the {{{aux}}} array) are not used.
    94 
    95 [[BR]]
    96 
    97 ==== Units and Scaling ====
    98 
    99 Astrophysical problems involve many different physical units and constants with a wide range of scales.  To avoid the loss of precision that comes when computers try to work with, say, a 10^-8^ variable and a 10^24^ constant in the same expression, we scale our units into ''computational units'' before storing them in the data arrays.
    100 
    101 Usually, the physical scales are defined in the [PhysicsDataExplained physics.data] file--you simply enter the scales for density, temperature, velocity, etc in that file, and AstroBEAR will read them in. More complicated scaling would be defined in the {{{ProblemModuleInit()}}} routine (see above).
    102 
    103 You have two options for making sure that you only put scaled quantities in the data arrays: you can scale your input values before you enter them into your input file (and then assume that you are reading in scaled quantities), or you can use physical quantities in your input files and then scale them within your problem module:
    104 
    105 {{{
    106 scaled_qty = physical_qty / physical_scale
    107 }}}
    108 
    109 Either way, a good sanity check is to print out the physical quantities your program uses after the problem is set up.  This verifies that the values you think are going in are the values that are actually getting used.
    110 
    111 [[BR]]
    112 
    113 ==== Initializing a Grid ====
    114 
    115 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 density distribution given by {{{rho(x,y,z)}}}:
    116 
    117 Note that during the !ProblemGridInit routine, ghost zones do not need to be initialized (rmbc = 0) - however - during beforestep calculations they should be
    118 
    119 {{{
    120     q=>Info%q
    121 
    122     rmbc=levels(Info%level)%gmbc(levels(Info%level)%step)
    123 
    124     mx=Info%mX(1); dx=Info%dX(1); xlower=Info%Xlower(1)
    125     my=Info%mX(2); dy=Info%dX(2); ylower=Info%Xlower(2)
    126     mz=Info%mX(3); dz=Info%dX(3); zlower=Info%Xlower(3)
    127 
    128     SELECT CASE(nDim)
    129     CASE(2)
    130        zrmbc=0;mz=1;zl=0;dz=0
    131     CASE(3)
    132        zrmbc=rmbc
    133     END SELECT
    134 
    135     ! Initialize environment
    136     DO k=1-zrmbc, mz+zrmbc
    137         DO j=1-rmbc, my+rmbc
    138             DO i=1-rmbc, mx+rmbc
    139 
    140                 x=(xlower + (REAL(i,xPrec)-half) * dx)
    141                 y=(ylower + (REAL(j,xPrec)-half) * dy)
    142                 z=(zlower + (REAL(k,xPrec)-half) * dz)
    143 
    144                 q(i,j,k) = rho(x,y,z)
    145             END DO
    146         END DO
    147     END DO
    148 }}}
    149 
    150 Each grid (or {{{InfoDef}}} structure) comes with several arrays that describe its geometry:
    151 
    152  * '''''mX(3)''''':  The grid's overall size.  Each element {{{mx(n)}}} represents the number of cells along the ''n''th dimension.
    153  * '''''Xlower(3)''''':  The spatial coordinates of the grid's lower bound in each dimension.  These values are ''always'' given in computational units.
    154  * '''''dX(3)''''':  The size of a spatial step in a given dimension.  {{{dX(n)}}} can also be thought of as the size of a cell along dimension ''n''.
    155 
    156 To make this example more readable (and therefore easier to debug), we assigned the various array values more Cartesian-sounding names (ie., {{{Info%dX(2) = dy}}}).
    157 
    158 Similarly, when calculating the spatial equivalents of an index, we went with {{{x}}}, {{{y}}} and {{{z}}}.  The half-step in the position calculations represents the fact that the spatial position is at the ''center'' of the cell, not the left side.
    159 
    160 The check on the number of dimensions makes sure that 2D problem does not accidentally get initialized with ghost cells (see below) or a spatial step.  This allows us to use the same initialization code for 2D or 3D problems.
    161 
    162 The {{{levels()}}} array is a global array structures that contain information specific to each level.  You can see in this example that we reference the appropriate level by using the {{{Info%level}}} attribute.
    163 
    164 You may have noticed the nested loops don't go from {{{1}}} to {{{mX(n)}}}.  This is because the data array size is not the same as the grid size.  The size of each grid along dimension ''n'' is {{{mX(n)}}}.  The ''data arrays'', however, have a number of "ghost cells" associated with them.  The number of ghost cells on the end of a grid is given by the quantity
    165 
    166 {{{
    167 levels(Info%level)%CoarsenRatio * levels(Info%level)%gmbc
    168 }}}
    169 
    170 These ghost cells only appear along the dimensions of the problem, though, so the data arrays for a 2D problem will not have ghost cells along the third dimension.  So the real extents of the data arrays in a 3D problem are:
    171 
    172 {{{
    173 Info%q(1 - rmbc : mX(1) + rmbc, &
    174        1 - rmbc : mX(2) + rmbc, &
    175        1 - rmbc : mX(3) + rmbc, &
    176        NrVars)
    177 }}}
    178 
    179 {{{
    180 Info%aux(1 - rmbc : mX(1) + rmbc + 1, &
    181          1 - rmbc : mX(2) + rmbc + 1, &
    182          1 - rmbc : mX(3) + rmbc + 1, &
    183          NrVars)
    184 }}}
    185 
    186 
    187 [[BR]]
    188 ==== Flagging Cells for Refinement ====
    189 
    190 
    191 
    192 [[BR]]
    193 Some modules may need specific regions refined, regardless of whether or not there is any obvious error there.  AstroBEAR flags cells for refinement using the array
    194 
    195 {{{
    196 Info%ErrorFlags(1 - rmbc : mX(1) + rmbc, &
    197                 1 - rmbc : mX(2) + rmbc, &
    198                 1 - rmbc : mX(2) + rmbc, &
    199                 NrVars)
    200 }}}
    201 
    202 To clear the cell at {{{(i,j,k)}}}, simply set {{{Info%ErrorFlags(i,j,k)}}} to 0.  An error flag of 0 means that the cell does not ''need'' to be refined (although it might happen anyway).  To mark a cell for refinement, set {{{Info%ErrorFlags(i,j,k)}}} to 1.  The best place to do this is in the {{{ProblemSetErrFlags()}}} routine; most conventional physical criteria for refinement are already handled by AstroBEAR itself.
    203 
    204 [[BR]]
     207
     208  ! Initialize the module variables
     209  SUBROUTINE ProblemModuleInit(Info)
     210  END SUBROUTINE ProblemModuleInit
     211
     212  ! Initialize the grid
     213  SUBROUTINE ProblemGridInit(Info)
     214  END SUBROUTINE ProblemGridInit
     215
     216  ! Use for pre-processing
     217  SUBROUTINE ProblemBeforeStep(Info)
     218  END SUBROUTINE ProblemBeforeStep
     219
     220  ! Use for post-processing
     221  SUBROUTINE ProblemAfterStep(Info)
     222  END SUBROUTINE ProblemAfterStep
     223
     224  ! Use for additional refinement
     225  SUBROUTINE ProblemSetErrFlag(Info)
     226  END SUBROUTINE ProblemSetErrFlag
     227}}}
    205228
    206229=== Additional Physics ===