Comparaison des versions

Légende

  • Ces lignes ont été ajoutées. Ce mot a été ajouté.
  • Ces lignes ont été supprimées. Ce mot a été supprimé.
  • La mise en forme a été modifiée.

Sommaire

Global physics fields

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.

Busses

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.

...

  • entry bus (contains initial conditions - almost not used anymore in GEM5)
  • dynamic bus (contains fields which get passed from and to the dynamics)
  • volatile bus (contains physics fields of which the content is not needed to calculate the next timestep)
  • permanent bus (contains physics fields of which the content is needed to calculate the next timestep)
  • surface bus (contains only physics fields used by the surface schemes)

Declaring a field in a bus

All fields that are in a bus need to get declared with the command "PHYVARnCx".

...

Fields that get only(!) used by the surface schemes need to get declared in rpnphy/surface/sfc_businit.F90.
All other fields need to get declared in
rpnphy/base/phyvar.hf.

Entry, dynamic, volatile and permanent bus

As mentioned above, the entry bus is almost not used anymore. It was used for fields which got read by the entry (which does not exist anymore) and then passed to the model.
Fields from the entry bus need to get declared as "VB=e1" - see above.

...

All fields of which the content is needed in the next timestep need to be in the permanent bus. For example, 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 like snow depth or temperature fields, because they are needed for the next timestep.
Fields from the permanent bus need to get declared as "VB=p0" resp. as "VB=p1" (mandatory to get read at timestep 0) - see above.

Surface bus

This is a special bus which is only valid for the surface schemes which do not have access to any of the busses described above! However, fields from this bus still need to get declared in sfc_businit.F90 or phyvar.hf the in the volatile or permanent bus. To get them copied to the surface bus one needs to add them' in sfcbus_mod.F90 with:

...

The main specialty with this bus is that it gets "adjusted" for each surface fraction. It always contains all surface fields but only for the points for which a certain surface scheme is valid. For example, when a land surface scheme (ISBA, SVS, CLASS) is called, this bus will only contain points with a land fraction greater than a certain threshold. By doing this one avoids nasty if-constructions inside the surface routines, checking that a point has a valid surface fraction, and the bus is more compact, without any "holes", and therefore faster to read.

Accessing fields declared in a bus

There are different ways of accessing fields declared in a bus. But they all have in common that the bus(ses) need(s) to get passed to all routines which want to access fields from the bus. The bus(ses) itself/themselves need to get passes as well as its/their length.

From the basic physics

The main physics subroutine, 'physlb1', passes the three main busses on to 'phyexe'. From there on the busses are generally received and passed on as:

...


Where
      'zpmoins'/'ztmoins' are the 1- resp. 2-D "arrays" in the routine,
      'pmoins'/'tmoins' the specific position in the bus as declared in phyvar.hf and
      'f'/'p' the name of the bus as received by the routine.

Now 'zpmoins'/'ztmoins' , the pointer (zpmoins, ztmoins) can get used in the routine like "normal" arrays.


From the surface schemes

In the main surface routine, surface/sfc_main.F90, all fields needed by the surface schemes get copied from the three main busses (dynamic, permanent and volatile) to the surface bus in calls to the routine 'copybus'. The routine 'copybus' gets called for all surface schemes separately. It copies only points from the three busses to the surface bus for which there is a surface fraction of the respective surface scheme, which greater than a critical value. For example, before the soil routine (ISBA/SVS/CLASS) gets called, 'copybus' will copy all points of the needed fields that contain a soil fraction greater equal 'critmask' to the surface bus. This is done in the calls:

...

Volet

1-D fields:
    PS            (1:n)            => bus( x(pplus,  1, 1)       : ) ! Input surface pressure at t+dt
    TA            (1:n)            => bus( x(tplus,   1, nk)     : ) ! Input temperature at t+dt on lowest model level (nk)

2-D fields:
    TS            (1:N,1:IG)  => bus( x( TSOIL, 1, 1 )    : )    !  inout Temperature of soil layers [K]

Fields defined for the different surface fractions:
    ZSNOW (
1:N)           => bus( x(SNODP , 1, indx_sfc ) : )  ! output snow depth; where indx_sfc is set to the specific surface fraction


Now, the pointer (PS, TA, TS, ZSNOW) can get used in the routine like "normal" arrays.