As you hopefully already know, GEM can run in parallel, using MPI and/or OpenMP. In the physics, when using MPI, the model domain gets horizontally divided into tiles, or rather cubes. Each MPI process is taking care of one of these cubes.
However, the physics do not see the whole "cube" at once but they are called for one "slab" (ni*nk) at the time. With ni being the number of points in x-direction of the particular tile and nk being the number of vertical levels, which can be atmospheric model levels, soil or ice levels or even "levels" for the different surface fractions.
Physics fields, that are used in different routines and also available for output, are organized in so called "busses". These busses are very veeeeery long 2-D arrays, filled with one field after the other. For each field there is one row per level, followed by the next field. The starting location of each field in a bus is defined in a variable.
There are 5 of these busses in the physics:
All fields that are in a bus need to get declared with the command "PHYVARnCx". Where 'n' is the "real" dimension of the field : 2 (ni*nj), 3 (ni*nj*nk), or 4. And 'x' can be '1' or otherwise 'C', for fields which only get declared under a certain condition.
The syntax is:
PHYVARnD1 (name, description) |
Where :
'name' is the "name" by which the field can get addressed in the physics. This variable is actually an integer which contains the starting position of the field in the bus.
'description' is a string containing a set of keys followed by a name, description or value. The different keys are separated by a ';'. These are the accepted keys:
VN= ; ===> formal name - mandatory, will appear in model listing; should be same as 'name' above ON= ; ===> output name (4 letters only) - mandatory IN= ; ===> input name (4 letters only) - defaults to 'ON' SN= ; ===> series name (4 letters only) - defaults to 'ON' VD= ; ===> formal description - mandatory, will appear in model listing VS= ; ===> variable shape (accepted shapes are M, T, E and A with +, - or * followed by an integer) VB= ; ===> bus identification (E, D, P or V) - mandatory MIN= ; ===> minimum value of the field (useful to keep i.e. humidity fields above zero) MAX= ; ===> maximum value of the field WLOAD= ; ===> water load flag (default=0) HZD= ; ===> Horizontal diffusion (default=0) MASSC= ; ===> mass conserv (default=0) MONOT= ; ===> monotone interpolation (default=1) |
As mentioned above, the entry bus is almost not used anymore.
If possible, do not add fields to the dynamic bus as this gets quite complicated.
For both, variables need to get declared in rpnphy/base/phyvar.hf. Variables from the entry bus need to get declared as "VB=e1", fields from the dynamic bus as "VB=d1".
All physics fields that are NOT needed to calculate the next timestep should go in the volatile bus. These are, for example, precipitation rates or instantaneous radiation. However, their accumulators need to be in the permanent bus, since they usually get accumulated over several timesteps. The same goes for averages, minimum and maximum fields. But there are also instantaneous fields that need to be in the permanent but like snow depth or temperature fields, because they are needed for the next timestep.
If variable is in the rest of the physics
base/phyvar.hf : variable declaration in physics bus
surface/sfcbus_mod.F90 : copy variable from physics bus to surface bus
SFCVAR(name_in_surface_bus, 'name_in_physics_bus')
Explain what a bus is: slab with just land points etc.
in class_main:
declare variable as pointer with the correct dimension (1-D)
all usually 2-D fields are 1-D because we only get one row
all usually 3-D fields are 2-D because we only get one slab