Skip to content

Commit 676fee3

Browse files
committed
add register phase info and elaborate on runtime constituent handling
1 parent 58ca7e2 commit 676fee3

File tree

3 files changed

+113
-3
lines changed

3 files changed

+113
-3
lines changed

docs/conversion/convert-portable-layer.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@ Convert the original routines (except readnl - we'll get to that [later](create-
2929

3030
For example, if you are converting the `tj2016` `precip_tend` function, then `<parameterization>` would be `tj2016_precip_tend`.
3131

32+
- **<parameterization\>_register**
33+
- Add all code that is run only during the first timestep (nstep=0) BEFORE the physics grid has been set up.
34+
!!! Warning "Grid is not set up!"
35+
Only scalar variables can be passed in at this time, as the grid is not set up (no horizontal or vertical dimensions are available)
36+
- If your scheme has runtime constituents, this is place to add those (see [Runtime Constituent Usage](../design/constituents.md/#run-time-dynamic-constituents))
3237
- **<parameterization\>_init**
33-
- Add all code that is run only during the first timestep (nstep=0). Typically, fold register and init routines in current CAM into this routine.
38+
- Add all code that is run only during the first timestep (nstep=0) AFTER the physics grid has been set up.
3439
- **<parameterization\>_timestep_init**
3540
- Add all pre-processing code needed by the scheme at the start of each timestep. This may contain code from the CAM interface (`physpkg.F90`) routine which prepares data for the run routine at each timestep
3641
- **<parameterization\>_run**

docs/design/cam-run-process.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,14 @@ The subroutines in `cam_comp.F90` are set up to mirror the phases of the [Common
5959
1. `read_namelist` (`src/control/runtime_opts.F90`): Reads all namelists for the run, including auto-generated scheme namelists (see [build process](cam-build-process.md/#cam-sima-source-and-namelist-generation-buildnml-workflow))
6060
1. `cam_ctrl_set_physics_type` (`src/control/cam_control_mod.F90`): sets module-level configuration for variables for simple physics and moist physics schemes; logs configurations to atm log
6161
1. `cam_initfiles_open` (`src/control/cam_initfiles.F90`): Opens initial or restart file, and topography file if specified
62+
1. `phys_register` (`src/physics/utils/phys_comp.F90`): Registers physics (includes call to CCPP cap to run register phases of schemes in the Suite Definition File (SDF))
6263
1. `cam_register_constituents` (`src/control/cam_comp.F90`): Sets the total number and advected number of [constituents](constituents.md); currently ALWAYS adds water vapor as constituent (expected by the SE dycore)
6364
1. `air_composition_init` (`src/data/air_composition.F90`): Initializes air-composition-dependent model constants
6465
1. `model_grid_init` (`src/dynamics/<dycore>/dyn_grid.F90`): Initializes model grids and decompositions
6566
1. `cam_ccpp_initialize_constituents` (`$CASE/bld/atm/obj/ccpp/cam_ccpp_cap.F90`): initializes the constituent data array; after this point, we cannot add new constituents
6667
1. `dyn_init` (`src/dynamics/<dycore>/dyn_comp.F90`): Initializes the dynamical core
6768
1. `atm2hub_alloc` and `hub2atm_alloc` (`src/control/camsrfexch.F90`): Allocates and sets up surface exchange data
68-
1. `phys_init` (`src/physics/utils/phys_comp.F90`): Initializes physics (includes call to CCPP cap to run init phases of schemes in the Suite Definition File (SDF)
69+
1. `phys_init` (`src/physics/utils/phys_comp.F90`): Initializes physics (includes call to CCPP cap to run init phases of schemes in the Suite Definition File (SDF))
6970
1. `stepon_init` (`src/dynamics/<dycore>/stepon.F90`): Initializes dynamics <--> physics coupling
7071

7172
### cam_timestep_init

docs/design/constituents.md

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,121 @@ The registration and initializaiton of the constituent data array and the consti
4141
- The array is initialized to (columns, levels, number of constituents)
4242

4343
### Constituent Usage
44+
45+
#### Adding to the CCPP constituents object
46+
##### Build-time (static) constituents
47+
Build-time constituents are those that you know your scheme will always need. These constituents are treated *almost* as if they were normal arguments. To tell the CCPP Framework that a given argument is a constituent, you will add the following line to the metadata for that variable:
48+
```
49+
advected = True
50+
```
51+
This instructs the framework to handle that variable (you will not need to add it to the registry or anywhere else in the model). The framework will generate the code to allocate and initialize all constituents, and will also create and handle the associated **tendency** variable (which will be accessible via metadata with the standard name `tendency_of_<const_stdname>`)
52+
53+
##### Run-time (dynamic) constituents
54+
Run-time constituents are those that are conditional on the configuration of the model. If your scheme has runtime constituents, you will instantiate them in the register phase of your scheme. Example Fortran is below:
55+
56+
```
57+
!> \section arg_table_<scheme>_register Argument Table
58+
!! \htmlinclude <scheme>_register.html
59+
subroutine <scheme>_register(constituent_props, filename, errmsg, errcode)
60+
use ccpp_constituent_prop_mod, only: ccpp_constituent_properties_t
61+
62+
type(ccpp_constituent_properties_t), allocatable, intent(out) :: constituent_props(:)
63+
character(len=256), intent(in) :: filename
64+
character(len=512), intent(out) :: errmsg
65+
integer, intent(out) :: errcode
66+
67+
integer :: const_idx
68+
character(len=512), allocatable :: const_names(:)
69+
70+
! Read the file and determine what constituents are needed at runtime
71+
! Allocate and populate const_names with those constituents
72+
73+
! Allocate the constituent properties array
74+
allocate(constituent_props(size(const_names)), stat=ierr)
75+
if (ierr /= 0) then
76+
errcode = 1
77+
errmsg = 'Failed to allocate "constituent_props"'
78+
return
79+
end if
80+
81+
! Instantiate each constituent
82+
do const_idx = 1, size(const_names)
83+
! Instantiate call may vary based on the properties of each runtime constituent
84+
call constituent_props(const_idx)%instantiate( &
85+
std_name = const_names(const_idx), &
86+
long_name = const_names(const_idx), &
87+
units = 'kg kg-1', &
88+
vertical_dim = 'vertical_layer_dimension', &
89+
min_value = 0.0_kind_phys, &
90+
advected = .true., &
91+
water_species = .true., &
92+
mixing_ratio_type = 'wet', &
93+
errcode = errcode, &
94+
errmsg = errmsg)
95+
if (errcode /= 0) then
96+
return
97+
end if
98+
end do
99+
100+
end subroutine <scheme>_register
101+
```
102+
103+
Note that only scalar variables may be passed into the register phase as the grid has not yet been set up when the CCPP register phases are called. The metadata for the above routine is below.
104+
105+
!!! Note "Standard name for runtime constituents variable"
106+
The only requirement for this standard name is that it is unique.
107+
```
108+
[ccpp-arg-table]
109+
name = <scheme>_register
110+
type = scheme
111+
[ constituent_props ]
112+
standard_name = dynamic_constituents_for_<scheme>
113+
units = none
114+
dimensions = (:)
115+
allocatable = True
116+
type = ccpp_constituent_properties_t
117+
intent = out
118+
[ filename ]
119+
standard_name = filename_for_runtime_constituents
120+
units = none
121+
dimensions = ()
122+
type = character | kind = len=256
123+
intent = in
124+
[ errmsg ]
125+
standard_name = ccpp_error_message
126+
long_name = Error message for error handling in CCPP
127+
units = none
128+
type = character | kind = len=512
129+
dimensions = ()
130+
intent = out
131+
[ errcode ]
132+
standard_name = ccpp_error_code
133+
long_name = Error flag for error handling in CCPP
134+
units = 1
135+
type = integer
136+
dimensions = ()
137+
intent = out
138+
139+
```
140+
141+
#### Accessing the CCPP constituent object
44142
Constituent values and properties can be accessed from the host side and from the physics in the following ways:
45143

46144
- Host side: constituents and properties can be accessed via the host model and dycore by way of the `cam_constituents.F90` module, which is an interface to the CCPP cap, which is in turn an interface to the constituents object
47-
- Physics: the constituent array and/or the constituent properties object are passed into a scheme via the following metadata (the local name and intent may vary):
145+
- Physics: the constituent array, constituent tendencies, and/or the constituent properties object are passed into a scheme via the following metadata (the local name and intent may vary):
48146

49147
```
50148
[ q ]
51149
standard_name = ccpp_constituents
52150
units = none
53151
type = real | kind = kind_phys
54152
dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_ccpp_constituents)
153+
intent = in
154+
[ qtend ]
155+
standard_name = ccpp_constituent_tendencies
156+
units = none
157+
type = real | kind = kind_phys
158+
dimensions = (horizontal_loop_extent,vertical_layer_dimension,number_of_ccpp_constituents)
55159
intent = inout
56160
[ const_props ]
57161
standard_name = ccpp_constituent_properties

0 commit comments

Comments
 (0)