Skip to content

Commit

Permalink
read in all possible constituents from file, not just build-time ones (
Browse files Browse the repository at this point in the history
…#301)

Tag name (required for release branches):
Originator(s): peverwhee

Summary (include the keyword ['closes', 'fixes', 'resolves'] and issue
number):
- Updates to enable reading in data for runtime constituents

Describe any changes made to build system:
M    cime_config/cam_autogen.py
M    cime_config/cam_build_cache.py
M    cime_config/cam_config.py
- keep track of registry constituents

Describe any changes made to the namelist: None

List any changes to the defaults for the input datasets (e.g. boundary
datasets): None

List all files eliminated and why: None

List all files added and what they do: None

List all existing files that have been modified, and describe the
changes:
(Helpful git command: `git diff --name-status
development...<your_branch_name>`)
M    src/data/generate_registry_data.py
- create list of registry constituents to pass to write_init_files
M    src/data/write_init_files.py
- handle constituents separately from other host variables; read/check
ALL constituent variables, not just "required" ones
M    test/unit/test_*.py
- update calling lists

If there are new failures (compare to the
`test/existing-test-failures.txt` file),
have them OK'd by the gatekeeper, note them here, and add them to the
file.
If there are baseline differences, include the test and the reason for
the
diff. What is the nature of the change? Roundoff?

derecho/intel/aux_sima:

derecho/gnu/aux_sima:

If this changes climate describe any run(s) done to evaluate the new
climate in enough detail that it(they) could be reproduced:

CAM-SIMA date used for the baseline comparison tests if different than
latest:

---------

Co-authored-by: Courtney Peverley <courtneyp@izumi.cgd.ucar.edu>
  • Loading branch information
peverwhee and Courtney Peverley authored Dec 2, 2024
1 parent e36d265 commit fd886c1
Show file tree
Hide file tree
Showing 29 changed files with 1,513 additions and 1,096 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
[submodule "ncar-physics"]
path = src/physics/ncar_ccpp
url = https://github.com/ESCOMP/atmospheric_physics
fxtag = 045b630a8c3b41d90b6c006392c3907af762dd39
fxtag = d46bb55e233e8f16b4e7a7b5a90352e99c7a5d72
fxrequired = AlwaysRequired
fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics
[submodule "ccs_config"]
Expand Down
16 changes: 9 additions & 7 deletions cime_config/cam_autogen.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ def generate_registry(data_search, build_cache, atm_root, bldroot,
gen_fort_indent, source_mods_dir, atm_root,
logger=_LOGGER, schema_paths=data_search,
error_on_no_validate=True)
retcode, reg_file_list, ic_names = retvals
retcode, reg_file_list, ic_names, registry_constituents = retvals
# Raise error if gen_registry failed:
if retcode != 0:
emsg = "ERROR:Unable to generate CAM data structures from {}, err = {}"
Expand All @@ -406,14 +406,15 @@ def generate_registry(data_search, build_cache, atm_root, bldroot,
# Save build details in the build cache
reg_file_paths = [x.file_path for x in reg_file_list if x.file_path]
build_cache.update_registry(gen_reg_file, registry_files, dycore,
reg_file_paths, ic_names)
reg_file_paths, ic_names, registry_constituents)
else:
# If we did not run the registry generator, retrieve info from cache
reg_file_paths = build_cache.reg_file_list()
ic_names = build_cache.ic_names()
registry_constituents = build_cache.constituents()
# End if

return genreg_dir, do_gen_registry, reg_file_paths, ic_names
return genreg_dir, do_gen_registry, reg_file_paths, ic_names, registry_constituents

###############################################################################
def generate_physics_suites(build_cache, preproc_defs, host_name,
Expand Down Expand Up @@ -443,7 +444,8 @@ def generate_physics_suites(build_cache, preproc_defs, host_name,
suite_search = [source_mods_dir, atm_suites_path, atm_test_suites_path]
# Find all scheme metadata files, organized by scheme name
atm_schemes_path = os.path.join(atm_phys_top_dir, "schemes")
source_search = [source_mods_dir, atm_schemes_path]
atm_test_schemes_path = os.path.join(atm_phys_top_dir, "test", "test_schemes")
source_search = [source_mods_dir, atm_schemes_path, atm_test_schemes_path]
all_scheme_files = _find_metadata_files(source_search, find_scheme_names)

# Find the SDFs specified for this model build
Expand Down Expand Up @@ -657,7 +659,7 @@ def generate_physics_suites(build_cache, preproc_defs, host_name,
###############################################################################
def generate_init_routines(build_cache, bldroot, force_ccpp, force_init,
source_mods_dir, gen_fort_indent,
cap_database, ic_names):
cap_database, ic_names, registry_constituents):
###############################################################################
"""
Generate the host model initialization source code files
Expand Down Expand Up @@ -695,8 +697,8 @@ def generate_init_routines(build_cache, bldroot, force_ccpp, force_init,
# within write_init_files (so that write_init_files can be the place
# where the source include files are stored).
source_paths = [source_mods_dir, _REG_GEN_DIR]
retmsg = write_init_files(cap_database, ic_names, init_dir,
_find_file, source_paths,
retmsg = write_init_files(cap_database, ic_names, registry_constituents,
init_dir, _find_file, source_paths,
gen_fort_indent, _LOGGER)

#Check that script ran properly:
Expand Down
16 changes: 15 additions & 1 deletion cime_config/cam_build_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ def __init__(self, build_cache):
self.__kind_types = {}
self.__reg_gen_files = []
self.__ic_names = {}
self.__constituents = []
if os.path.exists(build_cache):
# Initialize build cache state
_, cache = read_xml_file(build_cache)
Expand All @@ -252,6 +253,10 @@ def __init__(self, build_cache):
# end if
itext = clean_xml_text(item)
self.__ic_names[stdname].append(itext)
elif item.tag == 'constituent_entry':
stdname = item.get('standard_name')
itext = clean_xml_text(item)
self.__constituents.append(itext)
else:
emsg = "ERROR: Unknown registry tag, '{}'"
raise ValueError(emsg.format(item.tag))
Expand Down Expand Up @@ -313,7 +318,7 @@ def __init__(self, build_cache):
# end if

def update_registry(self, gen_reg_file, registry_source_files,
dycore, reg_file_list, ic_names):
dycore, reg_file_list, ic_names, constituents):
"""Replace the registry cache data with input data
"""
self.__dycore = dycore
Expand All @@ -328,6 +333,7 @@ def update_registry(self, gen_reg_file, registry_source_files,
# ic_names are the initial condition variable names from the registry,
# and should already be of type dict:
self.__ic_names = ic_names
self.__constituents = constituents

def update_ccpp(self, suite_definition_files, scheme_files, host_files,
xml_files, namelist_meta_files, namelist_groups,
Expand Down Expand Up @@ -400,6 +406,10 @@ def write(self):
ic_entry.text = ic_name
# end for
# end for
for stdname in self.__constituents:
const_entry = ET.SubElement(registry, 'constituent_entry')
const_entry.text = stdname
# end for
# CCPP
ccpp = ET.SubElement(new_cache, 'CCPP')
for sfile in self.__sdfs.values():
Expand Down Expand Up @@ -603,5 +613,9 @@ def ic_names(self):
"""Return a copy of the registry initial conditions dictionary"""
return dict(self.__ic_names)

def constituents(self):
"""Return a copy of the registry constituents list"""
return list(self.__constituents)

#############
# End of file
4 changes: 2 additions & 2 deletions cime_config/cam_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,7 @@ def generate_cam_src(self, gen_fort_indent):
retvals = generate_registry(data_search, build_cache, self.__atm_root,
self.__bldroot, source_mods_dir,
dyn, gen_fort_indent)
reg_dir, force_ccpp, reg_files, ic_names = retvals
reg_dir, force_ccpp, reg_files, ic_names, registry_constituents = retvals

#Add registry path to config object:
reg_dir_desc = "Location of auto-generated registry code."
Expand Down Expand Up @@ -871,7 +871,7 @@ def generate_cam_src(self, gen_fort_indent):
init_dir = generate_init_routines(build_cache, self.__bldroot,
force_ccpp, force_init,
source_mods_dir, gen_fort_indent,
capgen_db, ic_names)
capgen_db, ic_names, registry_constituents)

#Add registry path to config object:
init_dir_desc = "Location of auto-generated physics initialization code."
Expand Down
6 changes: 3 additions & 3 deletions src/data/air_composition.F90
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ subroutine air_composition_init()
!
! CLDICE
!
case('cloud_ice_water_mixing_ratio_wrt_moist_air_and_condensed_water')
call air_species_info('cloud_ice_water_mixing_ratio_wrt_moist_air_and_condensed_water', &
case('cloud_ice_mixing_ratio_wrt_moist_air_and_condensed_water')
call air_species_info('cloud_ice_mixing_ratio_wrt_moist_air_and_condensed_water', &
ix, mw)
thermodynamic_active_species_idx(icnst) = ix
thermodynamic_active_species_cp (icnst) = cpice
Expand Down Expand Up @@ -408,7 +408,7 @@ subroutine air_composition_init()
!
! GRAUQM
!
case('graupel_water_mixing_ratio_wrt_moist_air_and_conedensed_water')
case('graupel_water_mixing_ratio_wrt_moist_air_and_condensed_water')
call air_species_info('graupel_water_mixing_ratio_wrt_moist_air_and_condensed_water', &
ix, mw)
thermodynamic_active_species_idx(icnst) = ix
Expand Down
29 changes: 28 additions & 1 deletion src/data/generate_registry_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -1734,6 +1734,31 @@ def _create_ic_name_dict(registry):
# end for
return ic_name_dict

###############################################################################
def _create_constituent_list(registry):
###############################################################################
"""
Create a list of all constituents found in the registry.
To be used by write_init_files.py - need to keep track
of all constituent variables, not just ones required by
CCPP metadata, to handle runtime constituents
"""
constituent_list = []
for section in registry:
if section.tag == 'file':
for obj in section:
if obj.tag == 'variable':
if obj.get('constituent'):
stdname = obj.get('standard_name')
constituent_list.append(stdname)
# end if (ignore non-constituents)
# end if (ignore other node types)
# end for
# end if (ignore other node types)
# end for
return constituent_list


###############################################################################
def gen_registry(registry_file, dycore, outdir, indent,
src_mod, src_root, loglevel=None, logger=None,
Expand Down Expand Up @@ -1794,6 +1819,7 @@ def gen_registry(registry_file, dycore, outdir, indent,
retcode = 1
files = None
ic_names = None
constituents = None
else:
library_name = registry.get('name')
emsg = f"Parsing registry, {library_name}"
Expand All @@ -1803,9 +1829,10 @@ def gen_registry(registry_file, dycore, outdir, indent,
src_root, reg_dir, indent, logger)
# See comment in _create_ic_name_dict
ic_names = _create_ic_name_dict(registry)
registry_constituents = _create_constituent_list(registry)
retcode = 0 # Throw exception on error
# end if
return retcode, files, ic_names
return retcode, files, ic_names, registry_constituents

def main():
"""Function to execute when module called as a script"""
Expand Down
12 changes: 12 additions & 0 deletions src/data/registry.xml
Original file line number Diff line number Diff line change
Expand Up @@ -445,5 +445,17 @@
<dimensions>horizontal_dimension vertical_layer_dimension</dimensions>
<ic_file_input_names>RAINQM cnst_RAINQM</ic_file_input_names>
</variable>
<variable local_name="snowqm"
standard_name="snow_mixing_ratio_wrt_moist_air_and_condensed_water"
units="kg kg-1" type="real" constituent="true">
<long_name>snow mass mixing ratio with respect to moist air plus all airborne condensates</long_name>
<ic_file_input_names>SNOWQM cnst_SNOWQM</ic_file_input_names>
</variable>
<variable local_name="grauqm"
standard_name="graupel_water_mixing_ratio_wrt_moist_air_and_condensed_water"
units="kg kg-1" type="real" constituent="true">
<long_name>graupel mass mixing ratio with respect to moist air plus all airborne condensates</long_name>
<ic_file_input_names>GRAUQM cnst_GRAUQM</ic_file_input_names>
</variable>
</file>
</registry>
Loading

0 comments on commit fd886c1

Please sign in to comment.