Common Community Physics Package (CCPP)

Data Design

The host application cap

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 surf_t.

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

The 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 ccpp_field_get() and that variable is not available, an error is detected at run-time.

The interoperable physics driver expansion (IPDe)

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 ccpp_init. 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 ccpp_field_add. For example,

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))

CCPP layer

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        |

Physics caps

The automatically-manufactured caps for each of the physical parameterizations pull data from the 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 C pointer ptr to a Fortran pointer cdata.

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 retrieved from cdata. 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, ... )

Minimum metadata that host application cap must pass to physics

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.

UCAR | Privacy Policy | Terms of Use