.. _SuiteGroupCaps: **************************************** Suite and Group *Caps* **************************************** The connection between the :term:`host model` and the physics :term:`schemes` through the :term:`CCPP Framework` is realized with :term:`caps` on both sides as illustrated in :numref:`Figure %s `. The CCPP *prebuild* script discussed in :numref:`Chapter %s ` generates the :term:`caps ` that connect the physics schemes to the CCPP Framework. This chapter describes the :term:`suite` and :term:`group caps`, while the host model *caps* are described in :numref:`Chapter %s `. These *caps* autogenerated by ``ccpp_prebuild.py`` reside in the directory defined by the ``CAPS_DIR`` variable (see example in :ref:`Listing 8.1 `). Overview ======== When CCPP is built, the CCPP Framework and physics are statically linked to the executable. This allows the best performance and efficient memory use. This build requires metadata provided by the host model and variables requested from the physics scheme. Only the variables required for the specified suites are kept, requiring one or more :term:`SDF`\ s (see left side of :numref:`Figure %s `) as arguments to the ``ccpp_prebuild.py`` script. The CCPP *prebuild* step performs the tasks below. * Check requested vs provided variables by ``standard_name``. * Check units, rank, type. Perform unit conversions if a mismatch of units is detected and the required conversion has been implemented (see :numref:`Section %s ` for details). * Filter unused schemes and variables. * Create Fortran code for the static Application Programming Interface (API). * Create *caps* for groups and suite(s). * Populate makefiles with schemes and *caps*. The *prebuild* step will produce the following files for any host model. Note that the location of these files varies between the host models and whether an in-source or out-of-source build is used. * List of variables provided by host model and required by physics: .. code-block:: console CCPP_VARIABLES_FV3.tex * cmake/gnumake snippets and shell script that contain all *caps* to be compiled: .. code-block:: console CCPP_CAPS.{cmake,mk,sh} * cmake/gnumake snippets and shell script that contain all schemes to be compiled: .. code-block:: console CCPP_SCHEMES.{cmake,mk,sh} * List of CCPP types: .. code-block:: console CCPP_TYPEDEFS.{cmake,mk,sh} * List of variables provided by host model: .. code-block:: console CCPP_VARIABLES_FV3.html * One *cap* per physics group (fast_physics, physics, radiation, time_vary, stochastic, …) for each suite: .. code-block:: console ccpp_{suite_name}_{group_name}_cap.F90 * *Cap* for each suite: .. code-block:: console ccpp_{suite_name}_cap.F90 * Autogenerated API (aka CCPP Framework). .. code-block:: console ccpp_static_api.F90 ``ccpp_static_api.F90`` is an interface, which contains subroutines ``ccpp_physics_init``, ``ccpp_physics_timestep_init``, ``ccpp_physics_run``, ``ccpp_physics_timestep_finalize``, and ``ccpp_physics_finalize``. Each subroutine uses a ``suite_name`` and an optional argument, ``group_name``, to call the groups of a specified suite (e.g. ``fast_physics``, ``physics``, ``time_vary``, ``radiation``, ``stochastic``, etc.), or to call the entire suite. For example, ``ccpp_static_api.F90`` would contain module ``ccpp_static_api`` with subroutines ``ccpp_physics_{init, timestep_init, run, timestep_finalize, finalize}``. Interested users should run ``ccpp_prebuild.py`` as appropriate for their model and inspect these auto-generated files. .. _AutomaticUnitConversions: Automatic unit conversions ========================== The CCPP framework is capable of performing automatic unit conversions if a mismatch of units between the host model and a physics scheme is detected, provided that the required unit conversion has been implemented. If a mismatch of units is detected and an automatic unit conversion can be performed, the CCPP prebuild script will document this with a log message as in the following example: .. code-block:: console INFO: Comparing metadata for requested and provided variables ... INFO: Automatic unit conversion from m to um for effective_radius_of_stratiform_cloud_ice_particle_in_um after returning from MODULE_mp_thompson SCHEME_mp_thompson SUBROUTINE_mp_thompson_run INFO: Automatic unit conversion from m to um for effective_radius_of_stratiform_cloud_liquid_water_particle_in_um after returning from MODULE_mp_thompson SCHEME_mp_thompson SUBROUTINE_mp_thompson_run INFO: Automatic unit conversion from m to um for effective_radius_of_stratiform_cloud_snow_particle_in_um after returning from MODULE_mp_thompson SCHEME_mp_thompson SUBROUTINE_mp_thompson_run INFO: Generating schemes makefile/cmakefile snippet ... The CCPP framework is performing only the minimum unit conversions necessary, depending on the intent information of the variable in the :term:`parameterization`\'s metadata table. In the above example, the cloud effective radii are ``intent(out)`` variables, which means that no unit conversion is required before entering the subroutine ``mp_thompson_run``. Therefore, it is imperative to use the correct value for the ``intent`` attribute in the metadata. A common pitfall is to declare a variable as ``intent(out)``, and then fail to guarantee to completely overwrite the contents of the variable in the file. Below are examples for auto-generated code performing automatic unit conversions from ``m`` to ``um`` or back, depending on the intent of the variable. The conversions are performed in the individual physics scheme caps for the dynamic build, or the group caps for the build. .. code-block:: fortran ! var1 is intent(in) call mp_thompson_run(...,recloud=1.0E-6_kind_phys*re_cloud,...,errmsg=cdata%errmsg,errflg=cdata%errflg) ierr=cdata%errflg ! var1 is intent(inout) allocate(tmpvar1, source=re_cloud) tmpvar1 = 1.0E-6_kind_phys*re_cloud call mp_thompson_run(...,re_cloud=tmpvar1,...,errmsg=cdata%errmsg,errflg=cdata%errflg) ierr=cdata%errflg re_cloud = 1.0E+6_kind_phys*tmpvar1 deallocate(tmpvar1) ! var1 is intent(out) allocate(tmpvar1, source=re_cloud) call mp_thompson_run(...,re_cloud=tmpvar1,...,errmsg=cdata%errmsg,errflg=cdata%errflg) ierr=cdata%errflg re_cloud = 1.0E+6_kind_phys*tmpvar1 deallocate(tmpvar1) If a required unit conversion has not been implemented the CCPP prebuild script will generate an error message as follows: .. code-block:: console INFO: Comparing metadata for requested and provided variables ... ERROR: Error, automatic unit conversion from m to pc for effective_radius_of_stratiform_cloud_ice_particle_in_um in MODULE_mp_thompson SCHEME_mp_thompson SUBROUTINE_mp_thompson_run not implemented All automatic unit conversions are implemented in ``ccpp-framework/scripts/conversion_tools/unit_conversion.py``, new unit conversions can be added to this file by following the existing examples.