diff --git a/scripts/ccpp_datafile.py b/scripts/ccpp_datafile.py
index e02061fc..9ceee5b8 100755
--- a/scripts/ccpp_datafile.py
+++ b/scripts/ccpp_datafile.py
@@ -890,7 +890,7 @@ def _new_var_entry(parent, var, full_entry=True):
>>> var = Var({'local_name' : 'foo', 'standard_name' : 'hi_mom', 'units' : 'm s-1', 'dimensions' : '(horizontal_loop_extent)', 'type' : 'real', 'intent' : 'in'}, ParseSource('vname', 'DDT', ParseContext()), _MVAR_DUMMY_RUN_ENV)
>>> _new_var_entry(parent, var)
>>> table_entry_pretty_print(parent, 0)
- '\\n \\n \\n horizontal_loop_extent\\n \\n \\n ddt\\n \\n \\n vname\\n \\n \\n\\n'
+ '\\n \\n \\n horizontal_loop_extent\\n \\n \\n ddt\\n \\n \\n vname\\n \\n \\n\\n'
>>> parent = ET.fromstring('')
>>> _new_var_entry(parent, var, full_entry=False)
diff --git a/scripts/constituents.py b/scripts/constituents.py
index bb83c3c7..e7e182c0 100644
--- a/scripts/constituents.py
+++ b/scripts/constituents.py
@@ -300,6 +300,7 @@ def write_constituent_routines(self, outfile, indent, suite_name, err_vars):
# end if
outfile.write("index = index + 1", indent+1)
long_name = var.get_prop_value('long_name')
+ diag_name = var.get_prop_value('diagnostic_name')
units = var.get_prop_value('units')
dims = var.get_dim_stdnames()
default_value = var.get_prop_value('default_value')
@@ -311,7 +312,7 @@ def write_constituent_routines(self, outfile, indent, suite_name, err_vars):
vertical_dim = ''
# end if
advect_str = self.TF_string(var.get_prop_value('advected'))
- init_args = [f'{std_name=}', f'{long_name=}',
+ init_args = [f'{std_name=}', f'{long_name=}', f'{diag_name=}',
f'{units=}', f'{vertical_dim=}',
f'advected={advect_str}',
f'errcode={errvar_names["ccpp_error_code"]}',
diff --git a/scripts/metavar.py b/scripts/metavar.py
index 62badfd7..cafdbf9f 100755
--- a/scripts/metavar.py
+++ b/scripts/metavar.py
@@ -26,7 +26,7 @@
from parse_tools import FORTRAN_CONDITIONAL_REGEX_WORDS, FORTRAN_CONDITIONAL_REGEX
from var_props import CCPP_LOOP_DIM_SUBSTS, VariableProperty, VarCompatObj
from var_props import find_horizontal_dimension, find_vertical_dimension
-from var_props import standard_name_to_long_name, default_kind_val
+from var_props import standard_name_to_long_name, local_name_to_diag_name, default_kind_val
##############################################################################
@@ -174,6 +174,9 @@ class Var:
check_fn_in=check_cf_standard_name),
VariableProperty('long_name', str, optional_in=True,
default_fn_in=standard_name_to_long_name),
+ VariableProperty('diagnostic_name', str, optional_in=True,
+ default_fn_in=local_name_to_diag_name,
+ check_fn_in=check_diagnostic_id),
VariableProperty('units', str,
check_fn_in=check_units),
VariableProperty('dimensions', list,
@@ -189,9 +192,6 @@ class Var:
optional_in=True, default_in=False),
VariableProperty('allocatable', bool,
optional_in=True, default_in=False),
- VariableProperty('diagnostic_name', str,
- optional_in=True, default_in='',
- check_fn_in=check_diagnostic_id),
VariableProperty('diagnostic_name_fixed', str,
optional_in=True, default_in='',
check_fn_in=check_diagnostic_fixed),
diff --git a/scripts/var_props.py b/scripts/var_props.py
index a53e8b68..fc217548 100755
--- a/scripts/var_props.py
+++ b/scripts/var_props.py
@@ -128,6 +128,44 @@ def find_vertical_dimension(dims):
# end for
return (var_vdim, vindex)
+########################################################################
+def local_name_to_diag_name(prop_dict, context=None):
+########################################################################
+ """
+ Translate a local_name to its default diagnostic name.
+ Currently, this is just equal to the local name. If no local name
+ exists in the property dictionary, a truncation of the standard
+ name is used. (256 characters = max length of NetCDF variable name)
+ >>> local_name_to_diag_name({'local_name':'foo', 'standard_nam':'cloud_optical_depth'})
+ 'foo'
+ >>> local_name_to_diag_name({'standard_name':'cloud_optical_depth_layers_from_0p55mu_to_0p99mu'})
+ 'cloud_optical_depth_layers_from_0p55mu_to_0p99mu'
+ >>> local_name_to_diag_name({'units':'km'}) #doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ parse_source.CCPPError: No standard name or local name to convert to diagnostic name
+ """
+ diag_name = None
+ if 'local_name' in prop_dict:
+ locname = prop_dict['local_name']
+ if locname:
+ diag_name = prop_dict['local_name']
+ # end if
+ elif 'standard_name' in prop_dict:
+ stdname = prop_dict['standard_name']
+ if stdname:
+ maxlen = 256
+ diag_name = stdname[:maxlen]
+ # end if
+ # end if
+
+ if not diag_name:
+ emsg = 'No standard name or local name to convert to diagnostic name'
+ raise CCPPError(emsg)
+ # end if
+
+ return diag_name
+
########################################################################
def standard_name_to_long_name(prop_dict, context=None):
########################################################################
diff --git a/src/ccpp_constituent_prop_mod.F90 b/src/ccpp_constituent_prop_mod.F90
index a08291b6..29e8a365 100644
--- a/src/ccpp_constituent_prop_mod.F90
+++ b/src/ccpp_constituent_prop_mod.F90
@@ -34,6 +34,7 @@ module ccpp_constituent_prop_mod
! for a constituent species and provides interfaces to access that data.
character(len=:), private, allocatable :: var_std_name
character(len=:), private, allocatable :: var_long_name
+ character(len=:), private, allocatable :: var_diag_name
character(len=:), private, allocatable :: var_units
character(len=:), private, allocatable :: vert_dim
integer, private :: const_ind = int_unassigned
@@ -60,6 +61,7 @@ module ccpp_constituent_prop_mod
procedure :: is_instantiated => ccp_is_instantiated
procedure :: standard_name => ccp_get_standard_name
procedure :: long_name => ccp_get_long_name
+ procedure :: diagnostic_name => ccp_get_diagnostic_name
procedure :: units => ccp_get_units
procedure :: is_layer_var => ccp_is_layer_var
procedure :: is_interface_var => ccp_is_interface_var
@@ -103,6 +105,7 @@ module ccpp_constituent_prop_mod
! Informational methods
procedure :: standard_name => ccpt_get_standard_name
procedure :: long_name => ccpt_get_long_name
+ procedure :: diagnostic_name => ccpt_get_diagnostic_name
procedure :: units => ccpt_get_units
procedure :: is_layer_var => ccpt_is_layer_var
procedure :: is_interface_var => ccpt_is_interface_var
@@ -219,6 +222,7 @@ subroutine copyConstituent(outConst, inConst)
outConst%var_std_name = inConst%var_std_name
outConst%var_long_name = inConst%var_long_name
+ outConst%var_diag_name = inConst%var_diag_name
outConst%vert_dim = inConst%vert_dim
outConst%const_ind = inConst%const_ind
outConst%advected = inConst%advected
@@ -373,8 +377,8 @@ end function ccp_is_instantiated
!#######################################################################
- subroutine ccp_instantiate(this, std_name, long_name, units, vertical_dim, &
- advected, default_value, min_value, molar_mass, water_species, &
+ subroutine ccp_instantiate(this, std_name, long_name, diag_name, units, &
+ vertical_dim, advected, default_value, min_value, molar_mass, water_species, &
mixing_ratio_type, errcode, errmsg)
! Initialize all fields in
@@ -382,6 +386,7 @@ subroutine ccp_instantiate(this, std_name, long_name, units, vertical_dim, &
class(ccpp_constituent_properties_t), intent(inout) :: this
character(len=*), intent(in) :: std_name
character(len=*), intent(in) :: long_name
+ character(len=*), intent(in) :: diag_name
character(len=*), intent(in) :: units
character(len=*), intent(in) :: vertical_dim
logical, optional, intent(in) :: advected
@@ -404,6 +409,7 @@ subroutine ccp_instantiate(this, std_name, long_name, units, vertical_dim, &
end if
if (errcode == 0) then
this%var_long_name = trim(long_name)
+ this%var_diag_name = trim(diag_name)
this%var_units = trim(units)
this%vert_dim = trim(vertical_dim)
if (present(advected)) then
@@ -479,6 +485,9 @@ subroutine ccp_deallocate(this)
if (allocated(this%var_long_name)) then
deallocate(this%var_long_name)
end if
+ if (allocated(this%var_diag_name)) then
+ deallocate(this%var_diag_name)
+ end if
if (allocated(this%vert_dim)) then
deallocate(this%vert_dim)
end if
@@ -530,6 +539,25 @@ end subroutine ccp_get_long_name
!#######################################################################
+ subroutine ccp_get_diagnostic_name(this, diag_name, errcode, errmsg)
+ ! Return this constituent's diagnostic name
+
+ ! Dummy arguments
+ class(ccpp_constituent_properties_t), intent(in) :: this
+ character(len=*), intent(out) :: diag_name
+ integer, optional, intent(out) :: errcode
+ character(len=*), optional, intent(out) :: errmsg
+
+ if (this%is_instantiated(errcode, errmsg)) then
+ diag_name = this%var_diag_name
+ else
+ diag_name = ''
+ end if
+
+ end subroutine ccp_get_diagnostic_name
+
+ !#######################################################################
+
subroutine ccp_get_units(this, units, errcode, errmsg)
! Return this constituent's units
@@ -763,6 +791,7 @@ subroutine ccp_is_equivalent(this, oconst, equiv, errcode, errmsg)
oconst%is_instantiated(errcode, errmsg)) then
equiv = (trim(this%var_std_name) == trim(oconst%var_std_name)) .and. &
(trim(this%var_long_name) == trim(oconst%var_long_name)) .and. &
+ (trim(this%var_diag_name) == trim(oconst%var_diag_name)) .and. &
(trim(this%vert_dim) == trim(oconst%vert_dim)) .and. &
(trim(this%var_units) == trim(oconst%var_units)) .and. &
(this%advected .eqv. oconst%advected) .and. &
@@ -1007,7 +1036,6 @@ logical function ccp_is_match(this, comp_props) result(is_match)
! Local variable
logical :: val, comp_val
character(len=stdname_len) :: char_val, char_comp_val
- logical :: check
! By default, every constituent is a match
is_match = .true.
@@ -1989,6 +2017,29 @@ end subroutine ccpt_get_long_name
!#######################################################################
+ subroutine ccpt_get_diagnostic_name(this, diag_name, errcode, errmsg)
+ ! Return this constituent's diagnostic name
+
+ ! Dummy arguments
+ class(ccpp_constituent_prop_ptr_t), intent(in) :: this
+ character(len=*), intent(out) :: diag_name
+ integer, optional, intent(out) :: errcode
+ character(len=*), optional, intent(out) :: errmsg
+ ! Local variable
+ character(len=*), parameter :: subname = 'ccpt_get_diagnostic_name'
+
+ if (associated(this%prop)) then
+ call this%prop%diagnostic_name(diag_name, errcode, errmsg)
+ else
+ diag_name = ''
+ call append_errvars(1, ": invalid constituent pointer", &
+ subname, errcode=errcode, errmsg=errmsg)
+ end if
+
+ end subroutine ccpt_get_diagnostic_name
+
+ !#######################################################################
+
subroutine ccpt_get_units(this, units, errcode, errmsg)
! Return this constituent's units
diff --git a/test/advection_test/cld_ice.F90 b/test/advection_test/cld_ice.F90
index 759bcab1..15f5b502 100644
--- a/test/advection_test/cld_ice.F90
+++ b/test/advection_test/cld_ice.F90
@@ -34,13 +34,13 @@ subroutine cld_ice_register(dyn_const_ice, errmsg, errcode)
return
end if
call dyn_const_ice(1)%instantiate(std_name='dyn_const1', long_name='dyn const1', &
- units='kg kg-1', default_value=0._kind_phys, &
- vertical_dim='vertical_layer_dimension', advected=.true., &
- min_value=1000._kind_phys, water_species=.true., mixing_ratio_type='wet', &
+ diag_name='DYNCONST1', units='kg kg-1', default_value=0._kind_phys, &
+ vertical_dim='vertical_layer_dimension', advected=.true., &
+ min_value=1000._kind_phys, water_species=.true., mixing_ratio_type='wet', &
errcode=errcode, errmsg=errmsg)
call dyn_const_ice(2)%instantiate(std_name='dyn_const2_wrt_moist_air', long_name='dyn const2', &
- units='kg kg-1', default_value=0._kind_phys, &
- vertical_dim='vertical_layer_dimension', advected=.true., &
+ diag_name='DYNCONST2', units='kg kg-1', default_value=0._kind_phys, &
+ vertical_dim='vertical_layer_dimension', advected=.true., &
water_species=.false., errcode=errcode, errmsg=errmsg)
end subroutine cld_ice_register
diff --git a/test/advection_test/cld_liq.F90 b/test/advection_test/cld_liq.F90
index 023a608c..83a6f961 100644
--- a/test/advection_test/cld_liq.F90
+++ b/test/advection_test/cld_liq.F90
@@ -31,7 +31,7 @@ subroutine cld_liq_register(dyn_const, errmsg, errflg)
return
end if
call dyn_const(1)%instantiate(std_name="dyn_const3_wrt_moist_air_and_condensed_water", long_name='dyn const3', &
- units='kg kg-1', default_value=1._kind_phys, &
+ diag_name='DYNCONST3', units='kg kg-1', default_value=1._kind_phys, &
vertical_dim='vertical_layer_dimension', advected=.true., &
water_species=.true., mixing_ratio_type='dry', &
errcode=errflg, errmsg=errmsg)
diff --git a/test/advection_test/cld_liq.meta b/test/advection_test/cld_liq.meta
index e55dcfe7..b3ef3a0d 100644
--- a/test/advection_test/cld_liq.meta
+++ b/test/advection_test/cld_liq.meta
@@ -105,6 +105,7 @@
intent = in
[ cld_liq_array ]
standard_name = cloud_liquid_dry_mixing_ratio
+ diagnostic_name = CLDLIQ
advected = .true.
units = kg kg-1
dimensions = (horizontal_dimension, vertical_layer_dimension)
diff --git a/test/advection_test/dlc_liq.F90 b/test/advection_test/dlc_liq.F90
index 93230f81..db456073 100644
--- a/test/advection_test/dlc_liq.F90
+++ b/test/advection_test/dlc_liq.F90
@@ -31,7 +31,7 @@ subroutine dlc_liq_init(dyn_const, errmsg, errflg)
return
end if
call dyn_const(1)%instantiate(std_name="dyn_const3", long_name='dyn const3', &
- units='kg kg-1', default_value=1._kind_phys, &
+ diag_name='DYNCONST3', units='kg kg-1', default_value=1._kind_phys, &
vertical_dim='vertical_layer_dimension', advected=.true., &
errcode=errflg, errmsg=errmsg)
call dyn_const(1)%standard_name(stdname, errcode=errflg, errmsg=errmsg)
diff --git a/test/advection_test/test_host.F90 b/test/advection_test/test_host.F90
index c1482a93..30a618e8 100644
--- a/test/advection_test/test_host.F90
+++ b/test/advection_test/test_host.F90
@@ -266,12 +266,12 @@ subroutine test_host(retval, test_suites)
'constituent with this name already exists'
allocate(host_constituents(2))
call host_constituents(1)%instantiate(std_name="specific_humidity", &
- long_name="Specific humidity", units="kg kg-1", &
+ long_name="Specific humidity", diag_name='H2O', units="kg kg-1", &
vertical_dim="vertical_layer_dimension", advected=.true., &
min_value=1000._kind_phys, molar_mass=2000._kind_phys, &
errcode=errflg, errmsg=errmsg)
call host_constituents(2)%instantiate(std_name="specific_humidity", &
- long_name="Specific humidity", units="kg kg", &
+ long_name="Specific humidity", diag_name='H2O', units="kg kg", &
vertical_dim="vertical_layer_dimension", advected=.true., &
min_value=1000._kind_phys, molar_mass=2000._kind_phys, &
errcode=errflg, errmsg=errmsg)
@@ -309,12 +309,12 @@ subroutine test_host(retval, test_suites)
end do
allocate(host_constituents(2))
call host_constituents(1)%instantiate(std_name="specific_humidity", &
- long_name="Specific humidity", units="kg kg-1", &
+ long_name="Specific humidity", diag_name='H2O', units="kg kg-1", &
vertical_dim="vertical_layer_dimension", advected=.true., &
- min_value=1000._kind_phys, molar_mass=2000._kind_phys, &
+ min_value=1000._kind_phys, molar_mass=2000._kind_phys, &
errcode=errflg, errmsg=errmsg)
call host_constituents(2)%instantiate(std_name="specific_humidity", &
- long_name="Specific humidity", units="kg kg-1", &
+ long_name="Specific humidity", diag_name='H2O', units="kg kg-1", &
vertical_dim="vertical_layer_dimension", advected=.true., &
min_value=1000._kind_phys, molar_mass=2000._kind_phys, &
errcode=errflg, errmsg=errmsg)
@@ -480,6 +480,63 @@ subroutine test_host(retval, test_suites)
! Reset error flag to continue testing other properties:
errflg = 0
end if
+
+ ! Diagnostic name:
+ call const_props(index_liq)%diagnostic_name(const_str, errflg, errmsg)
+ if (errflg /= 0) then
+ write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", &
+ "to get diagnostic name for cld_liq index = ", &
+ index_liq, trim(errmsg)
+ errflg_final = -1 ! Notify test script that a failure occured
+ end if
+ if (errflg == 0) then
+ if (trim(const_str) /= 'CLDLIQ') then
+ write(6, *) "ERROR: diagnostic name, '", trim(const_str), &
+ "' should be 'CLDLIQ'"
+ errflg_final = -1 ! Notify test script that a failure occured
+ end if
+ else
+ ! Reset error flag to continue testing other properties:
+ errflg = 0
+ end if
+ ! Check default diagnostic name is set correctly
+ call const_props(index_ice)%diagnostic_name(const_str, errflg, errmsg)
+ if (errflg /= 0) then
+ write(6, '(a,i0,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", &
+ "to get diagnostic name for cld_ice index = ", &
+ index_ice, trim(errmsg)
+ errflg_final = -1 ! Notify test script that a failure occured
+ end if
+ if (errflg == 0) then
+ if (trim(const_str) /= 'cld_ice_array') then
+ write(6, *) "ERROR: diagnostic name, '", trim(const_str), &
+ "' should be 'cld_ice_array'"
+ errflg_final = -1 ! Notify test script that a failure occured
+ end if
+ else
+ ! Reset error flag to continue testing other properties:
+ errflg = 0
+ end if
+ ! Check diagnostic name of a dynamic constituent
+ call const_props(index_dyn2)%diagnostic_name(const_str, errflg, &
+ errmsg)
+ if (errflg /= 0) then
+ write(6, '(a,i0,a,a,i0,/,a)') "ERROR: Error, ", errflg, " trying ", &
+ "to get diagnostic name for dyn_const2 index = ", &
+ index_dyn2, trim(errmsg)
+ errflg_final = -1 ! Notify test script that a failure occured
+ end if
+ if (errflg == 0) then
+ if (trim(const_str) /= 'DYNCONST2') then
+ write(6, *) "ERROR: diagnostic name, '", trim(const_str), &
+ "' should be 'DYNCONST2'"
+ errflg_final = -1 ! Notify test script that a failure occured
+ end if
+ else
+ ! Reset error flag to continue testing other properties:
+ errflg = 0
+ end if
+
! Mass mixing ratio:
call const_props(index_ice)%is_mass_mixing_ratio(const_log, errflg, &
errmsg)
diff --git a/test/unit_tests/sample_scheme_files/temp_adjust.F90 b/test/unit_tests/sample_scheme_files/temp_adjust.F90
index 7b1d0cbb..70613ba1 100644
--- a/test/unit_tests/sample_scheme_files/temp_adjust.F90
+++ b/test/unit_tests/sample_scheme_files/temp_adjust.F90
@@ -29,7 +29,7 @@ subroutine temp_adjust_register(config_var, dyn_const, errflg, errmsg)
allocate(dyn_const(1))
call dyn_const(1)%instantiate(std_name="dyn_const", long_name='dyn const', &
- units='kg kg-1', default_value=1._kind_phys, &
+ diag_name='DYNCONST', units='kg kg-1', default_value=1._kind_phys, &
vertical_dim='vertical_layer_dimension', advected=.true., &
errcode=errflg, errmsg=errmsg)