4 - Interstitials
Overview
An interstitial is a scheme that does calculations or variable modifications to connect what the host model has to what the scheme requires and vice versa.
- These schemes are placed before or after the core parameterization scheme in the suite definition file (SDF) to prep for the scheme or take what the scheme produces and translate it back to what the host model (CAM-SIMA) expects
- In CAM, interstitial code will appear as either function calls or calculations/modifications in the CAM interface just before or just after the call to the parameterization
- If the interstitial code is a function call, that function/module should be CCPP-ized (if not already) and that scheme will be included in the SDF
- It the interstitial code is loose in the CAM interface, it is recommended that, when possible, that code be moved into the scheme (either the beginning or end of the scheme subroutine)
- UNLESS: it's a common (across multiple parameterizations) calculation/translation/modification. In which case, a new scheme should be created to do that calculation (scheme will live in
$CAM-SIMA/src/physics/ncar_ccpp/schemes/utilities
) - If it is absolutely necessary to create a scheme-specific interstitial, that scheme should be called
<parameterization>_pre
or_post
(depending on where in the SDF it will be placed) and will live in thencar_ccpp/schemes/<parameterization>
directory
- UNLESS: it's a common (across multiple parameterizations) calculation/translation/modification. In which case, a new scheme should be created to do that calculation (scheme will live in
This section covers a few interstitial scenarios you are likely to face.
Diagnostics interstitial
All addfld
/outfld
calls will go in a <parameterization>_diagnostic.F90
interstitial. You can find a template and instructions for scheme-specific diagnostics here:
addfld
calls will go into the<parameterization>_diagnostic_init
subroutineoutfld
calls will go into the<parameterization>_diagnostic_run
subroutine- The interstitial itself will reside after the
<parameterization>
line in the SDF- See: History Usage for the specifications of the CAM-SIMA-versions of
addfld
andoutfld
calls
- See: History Usage for the specifications of the CAM-SIMA-versions of
Utilities
As mentioned, there are some calculations/conversions/translations that are performed often throughout the physics code in CAM. These schemes are available for use in the $CAM-SIMA/src/physics/ncar_ccpp/schemes/utilities
directory and include:
- state_converters.F90: contains common conversions/calculations of state variables, including these schemes:
Scheme name | Description | Output variable | Input variables |
---|---|---|---|
temp_to_potential_temp | convert temperature to potential temperature | air_potential_temperature | air_temperature inverse_exner_function |
potential_temp_to_temp | convert potential temperature to temperature | air_temperature | air_potential_temperature inverse_exner_function |
calc_dry_air_ideal_gas_density | Calculate density from equation of state/ideal gas law | dry_air_density | composition_dependent_gas_constant_of_dry_air air_pressure_of_dry_air air_temperature |
calc_exner | calculate dimensionless exner function | dimensionless_exner_function | composition_dependent_specific_heat_of_dry_air_at_constant_pressure composition_dependent_gas_constant_of_dry_air surface_reference_pressure air_pressure |
wet_to_dry_water_vapor | convert water vapor from wet to dry mixing ratio | water_vapor_mixing_ratio_wrt_dry_air | air_pressure_thickness air_pressure_thickness_of_dry_air water_vapor_mixing_ratio_wrt_moist_air_and_condensed_water |
dry_to_wet_water_vapor | convert water vapor from dry to wet mixing ratio | water_vapor_mixing_ratio_wrt_moist_air_and_condensed_water | air_pressure_thickness air_pressure_thickness_of_dry_air water_vapor_mixing_ratio_wrt_dry_air |
wet_to_dry_cloud_liquid_water | convert cloud liquid from wet to dry mixing ratio | cloud_liquid_water_mixing_ratio_wrt_dry_air | air_pressure_thickness air_pressure_thickness_of_dry_air cloud_liquid_water_mixing_ratio_wrt_moist_air_and_condensed_water |
dry_to_wet_cloud_liquid_water | convert cloud liquid from dry to wet mixing ratio | cloud_liquid_water_mixing_ratio_wrt_moist_air_and_condensed_water | air_pressure_thickness air_pressure_thickness_of_dry_air cloud_liquid_water_mixing_ratio_wrt_dry_air |
wet_to_dry_rain | convert rain from wet to dry mixing ratio | rain_mixing_ratio_wrt_dry_air | air_pressure_thickness air_pressure_thickness_of_dry_air rain_mixing_ratio_wrt_moist_air_and_condensed_water |
dry_to_wet_rain | convert rain from dry to wet mixing ratio | rain_mixing_ratio_wrt_moist_air_and_condensed_water | air_pressure_thickness air_pressure_thickness_of_dry_air rain_mixing_ratio_wrt_dry_air |
- geopotential_temp.F90:
- geopotential_temp: compute geopotential height (
geopotential_height_wrt_surface
) and geopotential height at interfaces (geopotential_height_wrt_surface_at_interface
) from temperature (air_temperature
)
- geopotential_temp: compute geopotential height (
- static_energy.F90
- update_dry_static_energy: calculate dry static energy (
dry_static_energy
)
- update_dry_static_energy: calculate dry static energy (
-
qneg.F90:
- qneg: Set values for constituent variables that are less than the minimum value to the minimum value (and print out what it's doing - configurable!)
- You will want to include qneg in your SDF if you are modifying constituent tendencies in your scheme. It should be after the tendencies are applied and before
geopotential_temp
-
If
qneg
is in your SDF, you will need to provide the output variablescheme_name
in your physics parameterization that is modifying constituent tendenciesscheme_name variable
If you skip this step, you will get either
parse_source.CCPPError: Input argument for qneg_run, scheme_name, not found
, or an incorrect scheme_name from a previous routine will be used
-
physics_tendency_updaters.F90: apply tendencies output by physics to state variables. You'll need to include a tendency updater in your SDF for any
ptend%X
variables in the CAM-version of your code.
Scheme name | Description | Inout variable | Input variable |
---|---|---|---|
apply_tendency_of_ eastward_wind |
Apply the eastward wind tendency calculated in the previous physics scheme(s) to the eastward_wind state variable |
eastward_wind | tendency_of_eastward_wind_ due_to_model_physics timestep_for_physics |
apply_tendency_of_ northward_wind |
Apply the northward wind tendency calculated in the previous physics scheme(s) to the northward_wind state variable |
northward_wind | tendency_of_northward_wind_ due_to_model_physics timestep_for_physics |
apply_heating_rate | Apply the heating rate (tendency_of_dry_air_enthalpy_at_constant_pressure ) to the temperature tendency and temperature state variable |
air_temperature tendency_of_air_temperature_ due_to_model_physics |
tendency_of_dry_air_enthalpy_ at_constant_pressure composition_dependent_specific_heat_ of_dry_air_at_constant_pressure timestep_for_physics |
apply_tendency_of_ air_temperature |
Apply the temperature tendency calculated in the previous physics scheme(s) to the air_temperature state variable |
air_temperature | tendency_of_air_temperature_ due_to_model_physics timestep_for_physics |
Temporary constituent handling
For now, we don't have tendency updaters for the constituents. As a result, if your parameterization includes one or more constituent, you'll have to do a little finagling.
Problem overview
CAM outputs a tendency and then passes that tendency to physics_update to be added to state%q, but CAM-SIMA (currently) updates the constituent array directly
- Write the scheme to update the constituent data directly (constituent variable passed in with
intent(inout)
) - In CAM, pass in a temporary array for the constituent rather than the actual
state%q(:,:,index)
- Then, back out the tendency after calling scheme_run and reassign that to
state%q(:,:,index)
An example of how this is done can be found ~line 276 in:
$CAM/src/physics/simple/kessler_cam.F90
Proceed to 5 - Create an SDF.
Warning
You may have to revisit this step as you debug your code.