Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read in all possible constituents from file, not just build-time ones #301

Merged
merged 14 commits into from
Dec 2, 2024
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
Loading