The host application cap maps the host application data structures (those within IPDv4 for the FV3GFS)
to the IPDe.
Both variables and their metadata are required for each field, to help identify and register the array.
This is done through sequences of calls to
ccpp_field_add() with the appropriate metadata
attached to actual data pointers (as a reminder, standard name is the only metadata used in the first
release of CCPP).
call ccpp_field_add(cdata, 'surface_temperature', surf_t, ierr, 'K')
The input field
surf_t, as is typical with Fortran, is a pointer to the first
element of the array, and with Fortran overloading the pointer in
cdata is correctly identified
as to type, kind, and rank of
Due to a restriction in the Fortran language, there are no standard pointers that are generic pointers,
such as the C language allows.
The IPD CCPP system therefore has an underlying set of pointers in the C language that are used to point
to the original data within the host application cap.
The user does not see this C data structure, but deals only with the public face of the Fortran
cdata Derived Data Type (DDT).
type :: ccpp_t type(c_ptr) :: fields_idx type(ccpp_field_t), allocatable, dimension(:) :: fields type(ccpp_suite_t) :: suite end type ccpp_t type(ccpp_t), target :: cdata
cdata construct is the data object that is passed around.
It contains all of the (pointers to) data and metadata.
It is typical to have hierarchies of data structures, with internal methods that do operations
behind the scenes, so we will (not incorrectly) consider the cdata Fortran variable as the DDT
with pointers to all of the required fields.
Critical functions of the host application cap are defining the cdata variable(s), managing its memory, and filling it. For some host applications, such an operation may be as simple as one loop through the variable registry to call ccpp_field_add for each variable exposed to physics. For the FV3GFS, the calls to ccpp_field_add are auto-manufactured code generated at build-time from a metadata table on the host model side. This table is manually constructed as part of creating the host application cap, and must contain all variables that the host application must pass to the physics.
The existence of tables within both the host application cap and the physics schemes allows
cross-checking variables at build-time.
If a physics scheme requires a variable from the CCPP data type via
and that variable is not available, an error is detected at run-time.
This layer has five basic functionalities, associated with five subroutines. The first four calls to IPDe are made from within the host application cap, while the fifth call is made from each physics cap.
Initialize the suite, read the SDF and set up cdata, using subroutine
Note that filename is the name of the SDF. For example,
call ccpp_init(filename, cdata, ierr)
Add pointers to variables and their metadata to the cdata structure, using
call ccpp_field_add(cdata, 'surface_temperature', surf_t, ierr, 'K')
Run the CCPP-compliant schemes, using
ccpp_run. For example,
call ccpp_run(cdata%suite%ipds(i),cdata,ierr),where i is the ipd step in FV3GFS terminology.
Remove the data structures, using
ccpp_finalize. For example,
call ccpp_finalize(cdata, ierr)
Retrieve the data from the cdata structure, using
ccpp_field_get. For example,
call ccpp_field_get(cdata, 'surface_temperature', tsfc, ierr))
Traditionally within the physical parameterizations themselves, very little effort has been spent to organize the internal index ordering for consistency with either other schemes or with the calling routines. Many physical parameterizations developers have added one or more interface routines that call their particular scheme. While the assumption of column physics tends to be at the heart of many schemes, for timing performance many developers have an inner horizontal loop to help with using stride-one indexing for cache reuse.
The CCPP places no restrictions on the internal data structures utilized in the physical parameterizations. The arguments in the entry points for the physics schemes may be either standard Fortran types or derived types. The derived types require the use of an explicit interface, but since the CCPP-compliant parameterizations must be wrapped within Fortran MODULEs, this interface is automatically available.
CCPP-compliant parameterizations must contain a templated text table, in the form of Fortran comments that lists the variables, and their metadata, for the entry point routine. This table is used to automatically construct the parameterization cap. Below are a few sample lines from a table template. As the table is wide, the left and right portions of the table have been broken into a top and bottom arrangement, just for inclusion in a document and for clarity.
!! \section arg_table_sasasdeep_run !! | local var name | standard name | description | !! |----------------|--------------------------------|------------------------------------| !! | im | horizontal_loop_extent | horizontal loop extent, start at 1 | !! | ix | horizontal_dimension | horizontal dimension | !! | km | vertical_dimension | vertical layer dimension | !! | delt | time_step_for_physics | physics time step | !! | delp | air_pressure_layer_difference | pres(k) - pres(k+1) | !! | prslp | air_pressure_layer | mean layer pressure | !! | psp | surface_air_pressure | surface pressure | | units | rank | type | kind | intent | optional | |---------|------|---------|-----------|--------|----------| | index | 0 | integer | | in | F | | index | 0 | integer | | in | F | | index | 0 | integer | | in | F | | s | 0 | real | kind_phys | in | F | | Pa | 2 | real | kind_phys | in | F | | Pa | 2 | real | kind_phys | in | F | | Pa | 1 | real | kind_phys | in | F |
The automatically-manufactured caps for each of the physical parameterizations pull data from
cdata DDT as a pointer to a variable that will be passed to the individual physics scheme.
The following declarations start each of the cap files:
type(c_ptr), intent(inout) :: ptr type(ccpp_t), pointer :: cdata integer :: ierr
Then follows a succession of the arguments to the physics scheme, for example:
real, pointer :: ht(:,:)
With Fortran 2003, a feature has been added to allow a standard method to assign the target of a
ptr to a Fortran pointer
call c_f_pointer(ptr, cdata)
For each variable in the argument list for the physics scheme, the Fortran pointers are assigned.
call ccpp_field_get(cdata, 'surface_air_pressure', psp, ierr)
At the end of each physics cap is the actual call to the physics scheme with the data having been
Note that it is possible at this stage in the physics cap to implement MPI and/or chunking.
call physics_scheme_A_run (im=im, ix=ix, km=km, delt=delt, ... )
In the initial release of the CCPP, a single host application (FV3GFS) and physics suite (operational GFS FY17) are supported, and a single piece of metadata is required for identifying the correct field, the standard name. In future releases, additional metadata, such as units, will be cross checked between physics and host application.