From 4eef80e96caabbcc0121d3f323061124f47d8635 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Tue, 23 Sep 2025 16:18:38 -0600 Subject: [PATCH 01/26] Add PUMAS atmospheric_physics branch to git submodules. --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 5d1800afb..3f94b5c7d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,8 +19,8 @@ fxDONOTUSEurl = https://github.com/MPAS-Dev/MPAS-Model.git [submodule "ncar-physics"] path = src/physics/ncar_ccpp - url = https://github.com/ESCOMP/atmospheric_physics - fxtag = 73fce2706c1f70e1ba63ff4bb3dcb80323bb9cc6 + url = https://github.com/nusbaume/atmospheric_physics + fxtag = 5354628c996375ce0312f530de66158b6772310f fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] From 1048fa95b649ff4d1337d5ec6b16785b2dc0bf7d Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Fri, 26 Sep 2025 15:14:02 -0600 Subject: [PATCH 02/26] Remove code that incorrectly (and needlessly) reset the log level. --- cime_config/create_readnl_files.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cime_config/create_readnl_files.py b/cime_config/create_readnl_files.py index 1dd5e9323..60184d650 100644 --- a/cime_config/create_readnl_files.py +++ b/cime_config/create_readnl_files.py @@ -930,16 +930,6 @@ def __init__(self, args, description, schema_paths=None, logger=None): else: self.__outdir = args.output_dir # end if - if logger: - if args.debug: - loglevel = logging.DEBUG - elif args.quiet: - loglevel = logging.ERROR - else: - loglevel = logging.INFO - # end if - logger.setLevel(loglevel) - # end if self.__scheme_read_file = None self.__nlfile_arg = "nlfile" self.__active_schemes_arg = "active_schemes" From 0943b88ba01e42edc94d6df9b2dfa5f7cca42cdd Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Fri, 26 Sep 2025 15:59:51 -0600 Subject: [PATCH 03/26] Add PUMAS DDT metadata file to CAM-SIMA registry. --- src/data/registry.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/data/registry.xml b/src/data/registry.xml index 9985d559a..a6080ee93 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -21,6 +21,9 @@ $SRCROOT/src/dynamics/utils/vert_coord.meta $SRCROOT/src/dynamics/utils/hycoef.meta + + $SRCROOT/src/physics/ncar_ccpp/schemes/pumas/pumas/micro_pumas_diags.meta + From 62bc560f2b41caed4e8ffec8423062e94791828b Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Mon, 29 Sep 2025 15:22:31 -0600 Subject: [PATCH 04/26] Update atmospheric_physics and PUMAS submodules to fix namelist variable metadata. --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 3f94b5c7d..6a54de1a7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = 5354628c996375ce0312f530de66158b6772310f + fxtag = b5e674c4a7eacc0ce2a1ac4e4767a7b00af3b3be fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] From 35a4b7be38eabe9e19192e5be75c303a49f6e321 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Tue, 30 Sep 2025 12:58:38 -0600 Subject: [PATCH 05/26] Update atmospheric_physics to add ccpp_dimensions init phase, and fix logical variable standard names. --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 6a54de1a7..c42c74ea1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = b5e674c4a7eacc0ce2a1ac4e4767a7b00af3b3be + fxtag = 61ad2ed56e321d4513bf18eee72e9488c3d38ea3 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] From 741f2732de7d4384f0b2b2d69de86703db3f847b Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Thu, 2 Oct 2025 13:43:50 -0600 Subject: [PATCH 06/26] Update atmospheric_physics module with needed metadata changes needed by new CCPP-framework tag. --- .gitmodules | 2 +- src/physics/ncar_ccpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index c42c74ea1..59c6a5e5e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = 61ad2ed56e321d4513bf18eee72e9488c3d38ea3 + fxtag = 80ae20a51ccca0036996eb5df68b6fe3f07b0580 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] diff --git a/src/physics/ncar_ccpp b/src/physics/ncar_ccpp index 73fce2706..80ae20a51 160000 --- a/src/physics/ncar_ccpp +++ b/src/physics/ncar_ccpp @@ -1 +1 @@ -Subproject commit 73fce2706c1f70e1ba63ff4bb3dcb80323bb9cc6 +Subproject commit 80ae20a51ccca0036996eb5df68b6fe3f07b0580 From 31ef05a0786350deeb46018f03646905b703ed68 Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Tue, 21 Oct 2025 17:15:14 -0600 Subject: [PATCH 07/26] Update registry with required PUMAS variables --- src/data/registry.xml | 96 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/data/registry.xml b/src/data/registry.xml index a6080ee93..b8a6490e7 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -34,6 +34,15 @@ + + + + 4 + + .true. .false. + + + + horizontal_dimension vertical_layer_dimension + RELVAR pbuf_RELVAR + + + horizontal_dimension vertical_layer_dimension + ALST pbuf_ALST + + + horizontal_dimension vertical_layer_dimension + AIST pbuf_AIST + + + horizontal_dimension vertical_layer_dimension + QSATFAC pbuf_QSATFAC + + + horizontal_dimension vertical_layer_dimension + NAAI pbuf_NAAI + + + horizontal_dimension vertical_layer_dimension + NPCCN pbuf_NPCCN + + + horizontal_dimension vertical_layer_dimension dust_size_bins_dimension + RNDST pbuf_RNDST + + + horizontal_dimension vertical_layer_dimension dust_size_bins_dimension + NACON pbuf_NACON + + + horizontal_dimension vertical_layer_dimension + REI pbuf_REI + + + horizontal_dimension vertical_layer_dimension + FRZIMM pbuf_FRZIMM + + + horizontal_dimension vertical_layer_dimension + FRZCNT pbuf_FRZCNT + + + horizontal_dimension vertical_layer_dimension + FRZDEP pbuf_FRZDEP + + From ada9d9559cf9e7b46b1c1e2ea50c018ceba7e4de Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Fri, 5 Dec 2025 14:15:20 -0700 Subject: [PATCH 08/26] Updates to support accum_enhan --- src/data/registry.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/data/registry.xml b/src/data/registry.xml index b8a6490e7..589c4cf05 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -1632,6 +1632,13 @@ horizontal_dimension vertical_layer_dimension FRZDEP pbuf_FRZDEP + + horizontal_dimension vertical_layer_dimension + accre_enhan pbuf_accre_enhan + From b6c8f6cb13c05a7dc55dd52f0fb46d79f9a20bf7 Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Wed, 10 Dec 2025 16:33:52 -0700 Subject: [PATCH 09/26] Fixed accre_enhan variable --- src/data/registry.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/registry.xml b/src/data/registry.xml index 589c4cf05..32e4fb623 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -1633,7 +1633,7 @@ FRZDEP pbuf_FRZDEP horizontal_dimension vertical_layer_dimension From aaa445938a15d37a235be1b53f5ab9be5ffb84dd Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Wed, 31 Dec 2025 10:55:54 -0700 Subject: [PATCH 10/26] Add snapshot variables for PUMAS --- src/data/registry.xml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/data/registry.xml b/src/data/registry.xml index 32e4fb623..c2ca037ee 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -1605,7 +1605,7 @@ NACON pbuf_NACON horizontal_dimension vertical_layer_dimension @@ -1639,6 +1639,20 @@ horizontal_dimension vertical_layer_dimension accre_enhan pbuf_accre_enhan + + horizontal_dimension vertical_layer_dimension + tnd_qsnow pbuf_tnd_qsnow + + + horizontal_dimension vertical_layer_dimension + tnd_nsnow pbuf_tnd_nsnow + From 848215c833bcf78a89b5655b7afcdcdf8d278a91 Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Mon, 12 Jan 2026 11:54:34 -0700 Subject: [PATCH 11/26] fix standard name --- src/data/registry.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/registry.xml b/src/data/registry.xml index 284a6c665..d015a68ef 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -37,7 +37,7 @@ - From 84ffa8f168b856013232397edd168295e3983e2c Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Mon, 12 Jan 2026 12:01:55 -0700 Subject: [PATCH 12/26] update atmos_phys external --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 166e6bbbe..07133a784 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = 8b359bf + fxtag = 2b8b259 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] From 306e07781c6915fabdd7745d3940ff20a89415e4 Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Mon, 12 Jan 2026 13:36:46 -0700 Subject: [PATCH 13/26] Update atmos_phys external --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 07133a784..20567fd09 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = 2b8b259 + fxtag = 55fb203 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] From 3a8b3bebdf2ec86eab2deda2e7744902a8f269a4 Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Thu, 15 Jan 2026 11:10:28 -0700 Subject: [PATCH 14/26] Add changes needed to include 'pumas_r8' in the CCPP cap. --- .gitmodules | 4 +-- ccpp_framework | 2 +- cime_config/cam_autogen.py | 25 ++++++++++------ cime_config/cam_build_cache.py | 45 +++++++++++++++-------------- src/data/generate_registry_data.py | 46 ++++++++++++------------------ src/physics/ncar_ccpp | 2 +- 6 files changed, 63 insertions(+), 61 deletions(-) diff --git a/.gitmodules b/.gitmodules index 20567fd09..0ded115b8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "ccpp-framework"] path = ccpp_framework - url = https://github.com/NCAR/ccpp-framework - fxtag = 2025-10-01-dev + url = https://github.com/nusbaume/ccpp-framework + fxtag = d7122eaeca8e625012bb90e6f947929d9b8ee6ee fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/NCAR/ccpp-framework [submodule "history"] diff --git a/ccpp_framework b/ccpp_framework index d20a1858f..d7122eaec 160000 --- a/ccpp_framework +++ b/ccpp_framework @@ -1 +1 @@ -Subproject commit d20a1858f9ce0d12c1cbe2757fcbdb979c421333 +Subproject commit d7122eaeca8e625012bb90e6f947929d9b8ee6ee diff --git a/cime_config/cam_autogen.py b/cime_config/cam_autogen.py index 695364b24..f312d207a 100644 --- a/cime_config/cam_autogen.py +++ b/cime_config/cam_autogen.py @@ -390,8 +390,7 @@ def generate_registry(data_search, build_cache, atm_root, bldroot, for reg_file in registry_files: retvals = gen_registry(reg_file, dycore, genreg_dir, gen_fort_indent, source_mods_dir, atm_root, - logger=_LOGGER, schema_paths=data_search, - error_on_no_validate=True) + logger=_LOGGER, schema_paths=data_search) retcode, reg_file_list, ic_names, registry_constituents, vars_init_value = retvals # Raise error if gen_registry failed: if retcode != 0: @@ -491,8 +490,18 @@ def generate_physics_suites(build_cache, preproc_defs, host_name, # End for # Figure out if we need to generate new physics code genccpp_dir = os.path.join(bldroot, "ccpp") - kind_phys = ['kind_phys = REAL64'] - kind_types = kind_phys + + # Kind definition(s) dictionary: + kind_types = {} + + # Use ISO-Fortran double-precision real + # definition for default physics kind: + kind_types['kind_phys'] = ['ISO_FORTRAN_ENV', 'REAL64'] + + # If PUMAS is listed as a physics scheme, then add + # its kind definition to the dictionary as well: + if 'micro_pumas_ccpp' in scheme_names: + kind_types['pumas_r8'] = ['pumas_kinds', 'kind_r8'] # Set location of CCPP "capfiles.txt" file: cap_output_file = os.path.join(genccpp_dir, "ccpp_datatable.xml") @@ -517,7 +526,7 @@ def generate_physics_suites(build_cache, preproc_defs, host_name, do_gen_ccpp = force or build_cache.ccpp_mismatch(sdfs, scheme_files, host_files, preproc_cache_str, - kind_phys) + kind_types) else: os.makedirs(genccpp_dir) do_gen_ccpp = True @@ -575,9 +584,9 @@ def generate_physics_suites(build_cache, preproc_defs, host_name, _LOGGER.debug(" preproc defs: %s", preproc_cache_str) _LOGGER.debug(" output directory: '%s'", genccpp_dir) _LOGGER.debug(" kind definitions:") - for kind_type in kind_types: - name, ktype = [x.strip() for x in kind_type.split('=')] - _LOGGER.debug(" %s: '%s'", name, ktype) + for kind_name, kind_info in kind_types.items(): + kind_type = kind_info[1] # Second element is the kind parameter name + _LOGGER.debug(" %s: '%s'", kind_name, kind_type) # end for # generate CCPP caps diff --git a/cime_config/cam_build_cache.py b/cime_config/cam_build_cache.py index 3e23b74a8..8bf507b0c 100644 --- a/cime_config/cam_build_cache.py +++ b/cime_config/cam_build_cache.py @@ -302,8 +302,11 @@ def __init__(self, build_cache): elif item.tag == 'kind_type': if isinstance(item.text, str): if item.text: - kname, ktype = item.text.strip().split('=') - self.__kind_types[kname.strip()] = ktype.strip() + kinfo = item.text.strip().split() + kname = kinfo[0] + kmod = kinfo[1] + ktype = kinfo[2] + self.__kind_types[kname.strip()] = [kmod.strip(), ktype.strip()] # end if # end if else: @@ -318,7 +321,8 @@ def __init__(self, build_cache): # end if (no else, we just have an almost empty object) # We always need a default definition for kind_phys if 'kind_phys' not in self.__kind_types: - self.__kind_types['kind_phys'] = 'REAL64' + #Assume ISO-Fortran double-precision real: + self.__kind_types['kind_phys'] = ['ISO_FORTRAN_ENV', 'REAL64'] # end if def update_registry(self, gen_reg_file, registry_source_files, @@ -346,11 +350,7 @@ def update_ccpp(self, suite_definition_files, scheme_files, host_files, """Replace the ccpp cache data with input data """ self.__preproc_defs = preproc_defs - self.__kind_types = {} - for kind_def in kind_types: - name, ktype = [x.strip() for x in kind_def.split('=')] - self.__kind_types[name] = ktype - # end for + self.__kind_types = kind_types self.__sdfs = {} for sfile in suite_definition_files: new_entry = FileStatus(sfile, 'SDF') @@ -445,9 +445,9 @@ def write(self): self.__create_nl_file.file_hash) preproc = ET.SubElement(ccpp, 'preproc_defs') preproc.text = self.__preproc_defs - for kind_def, kind_type in self.__kind_types.items(): + for kind_def, kind_info in self.__kind_types.items(): kind_elem = ET.SubElement(ccpp, 'kind_type') - kind_elem.text = f"{kind_def}={kind_type}" + kind_elem.text = f"{kind_def} {kind_info[0]} {kind_info[1]}" # end for #Combine elments into an Element Tree object: @@ -500,18 +500,19 @@ def ccpp_mismatch(self, sdfs, scheme_files, host_files, (self.__preproc_defs != preproc_defs)) if not mismatch: my_kind_defs = set(self.__kind_types.keys()) - test_kdefs = {z[0] : z[1] for z in - [[x.strip() for x in y.split('=')] - for y in kind_types]} - test_kind_keys = test_kdefs.keys() - test_kind_set = set(test_kind_keys) - mismatch = my_kind_defs != test_kind_set - for ref_kind in test_kind_keys: - if mismatch: - break - # end if - mismatch = test_kdefs[ref_kind] != self.__kind_types[ref_kind] - # end for + my_kind_defs = set() + + # Convert kind_types dict to set of strings for comparison + for kind_name, kind_info in self.__kind_types.items(): + my_kind_defs.add(f"{kind_name} {' '.join(kind_info)}") + + # Convert input kind_types dict to set of strings for comparison + test_kind_defs = set() + for kind_name, kind_info in kind_types.items(): + test_kind_defs.add(f"{kind_name} {' '.join(kind_info)}") + + # Determine if the sets are different (i.e. a mismatch) + mismatch = my_kind_defs != test_kind_defs # end if # For SDFs, we need to make sure we have 1-1 files # Note that this method will ignore duplicated files. diff --git a/src/data/generate_registry_data.py b/src/data/generate_registry_data.py index 0d0e93b3d..0c4b4a25a 100755 --- a/src/data/generate_registry_data.py +++ b/src/data/generate_registry_data.py @@ -1820,7 +1820,7 @@ def _create_variables_with_initial_value_list(registry): ############################################################################### def gen_registry(registry_file, dycore, outdir, indent, src_mod, src_root, loglevel=None, logger=None, - schema_paths=None, error_on_no_validate=False): + schema_paths=None): ############################################################################### """Parse a registry XML file and generate source code and metadata. is the name of the dycore for DP coupling specialization. @@ -1863,35 +1863,27 @@ def gen_registry(registry_file, dycore, outdir, indent, try: emsg = f"Invalid registry file, {registry_file}" file_ok = validate_xml_file(registry_file, 'registry', version, - logger, schema_path=schema_dir, - error_on_noxmllint=error_on_no_validate) + logger, schema_path=schema_dir) except CCPPError as ccpperr: + # Cleanup error message and print + # to log before raising the exception emsg += f"\n{ccpperr}" - file_ok = False - # end try - if not file_ok: - if error_on_no_validate: - raise CCPPError(emsg) - # end if logger.error(emsg) - retcode = 1 - files = None - ic_names = None - registry_constituents = None - vars_init_value = None - else: - library_name = registry.get('name') - emsg = f"Parsing registry, {library_name}" - logger.debug(emsg) - reg_dir = os.path.dirname(registry_file) - files = write_registry_files(registry, dycore, outdir, src_mod, - 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) - vars_init_value = _create_variables_with_initial_value_list(registry) - retcode = 0 # Throw exception on error - # end if + raise CCPPError(emsg) + # end try + + library_name = registry.get('name') + emsg = f"Parsing registry, {library_name}" + logger.debug(emsg) + reg_dir = os.path.dirname(registry_file) + files = write_registry_files(registry, dycore, outdir, src_mod, + 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) + vars_init_value = _create_variables_with_initial_value_list(registry) + retcode = 0 # Throw exception on error + return retcode, files, ic_names, registry_constituents, vars_init_value def main(): diff --git a/src/physics/ncar_ccpp b/src/physics/ncar_ccpp index 8b359bf45..55fb20373 160000 --- a/src/physics/ncar_ccpp +++ b/src/physics/ncar_ccpp @@ -1 +1 @@ -Subproject commit 8b359bf45c4ffa82ed9310447dd8259b3c1d6dd2 +Subproject commit 55fb203739f3e61cb3e0649f719ea2e0ee065de6 From 57232e37b619d1c5d18cbb93b8c191ea42ad668c Mon Sep 17 00:00:00 2001 From: Jesse Nusbaumer Date: Fri, 16 Jan 2026 10:24:04 -0700 Subject: [PATCH 15/26] Update ccpp-framework hash to include additional framework tests. --- .gitmodules | 2 +- ccpp_framework | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 0ded115b8..9da72d574 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "ccpp-framework"] path = ccpp_framework url = https://github.com/nusbaume/ccpp-framework - fxtag = d7122eaeca8e625012bb90e6f947929d9b8ee6ee + fxtag = f1c2b73ed8cc13200819b724c0e5c0795e67b743 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/NCAR/ccpp-framework [submodule "history"] diff --git a/ccpp_framework b/ccpp_framework index d7122eaec..f1c2b73ed 160000 --- a/ccpp_framework +++ b/ccpp_framework @@ -1 +1 @@ -Subproject commit d7122eaeca8e625012bb90e6f947929d9b8ee6ee +Subproject commit f1c2b73ed8cc13200819b724c0e5c0795e67b743 From 2af61daceff21f17bcc54d4d18e1a5d821f3ba8c Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Mon, 26 Jan 2026 14:30:54 -0700 Subject: [PATCH 16/26] Add pbuf_ACCRE_ENHAN to registry.xml --- src/data/registry.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/registry.xml b/src/data/registry.xml index d015a68ef..ded55bcf2 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -1700,7 +1700,7 @@ units="1" type="real" kind="kind_phys" allocatable="allocatable"> horizontal_dimension vertical_layer_dimension - accre_enhan pbuf_accre_enhan + accre_enhan pbuf_accre_enhan pbuf_ACCRE_ENHAN Date: Tue, 10 Feb 2026 13:38:33 -0700 Subject: [PATCH 17/26] Revert "Add changes needed to include 'pumas_r8' in the CCPP cap." This reverts commit 3a8b3bebdf2ec86eab2deda2e7744902a8f269a4. --- .gitmodules | 4 +-- cime_config/cam_autogen.py | 25 ++++++---------- cime_config/cam_build_cache.py | 45 ++++++++++++++--------------- src/data/generate_registry_data.py | 46 ++++++++++++++++++------------ src/physics/ncar_ccpp | 2 +- 5 files changed, 60 insertions(+), 62 deletions(-) diff --git a/.gitmodules b/.gitmodules index 9da72d574..20567fd09 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "ccpp-framework"] path = ccpp_framework - url = https://github.com/nusbaume/ccpp-framework - fxtag = f1c2b73ed8cc13200819b724c0e5c0795e67b743 + url = https://github.com/NCAR/ccpp-framework + fxtag = 2025-10-01-dev fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/NCAR/ccpp-framework [submodule "history"] diff --git a/cime_config/cam_autogen.py b/cime_config/cam_autogen.py index f312d207a..695364b24 100644 --- a/cime_config/cam_autogen.py +++ b/cime_config/cam_autogen.py @@ -390,7 +390,8 @@ def generate_registry(data_search, build_cache, atm_root, bldroot, for reg_file in registry_files: retvals = gen_registry(reg_file, dycore, genreg_dir, gen_fort_indent, source_mods_dir, atm_root, - logger=_LOGGER, schema_paths=data_search) + logger=_LOGGER, schema_paths=data_search, + error_on_no_validate=True) retcode, reg_file_list, ic_names, registry_constituents, vars_init_value = retvals # Raise error if gen_registry failed: if retcode != 0: @@ -490,18 +491,8 @@ def generate_physics_suites(build_cache, preproc_defs, host_name, # End for # Figure out if we need to generate new physics code genccpp_dir = os.path.join(bldroot, "ccpp") - - # Kind definition(s) dictionary: - kind_types = {} - - # Use ISO-Fortran double-precision real - # definition for default physics kind: - kind_types['kind_phys'] = ['ISO_FORTRAN_ENV', 'REAL64'] - - # If PUMAS is listed as a physics scheme, then add - # its kind definition to the dictionary as well: - if 'micro_pumas_ccpp' in scheme_names: - kind_types['pumas_r8'] = ['pumas_kinds', 'kind_r8'] + kind_phys = ['kind_phys = REAL64'] + kind_types = kind_phys # Set location of CCPP "capfiles.txt" file: cap_output_file = os.path.join(genccpp_dir, "ccpp_datatable.xml") @@ -526,7 +517,7 @@ def generate_physics_suites(build_cache, preproc_defs, host_name, do_gen_ccpp = force or build_cache.ccpp_mismatch(sdfs, scheme_files, host_files, preproc_cache_str, - kind_types) + kind_phys) else: os.makedirs(genccpp_dir) do_gen_ccpp = True @@ -584,9 +575,9 @@ def generate_physics_suites(build_cache, preproc_defs, host_name, _LOGGER.debug(" preproc defs: %s", preproc_cache_str) _LOGGER.debug(" output directory: '%s'", genccpp_dir) _LOGGER.debug(" kind definitions:") - for kind_name, kind_info in kind_types.items(): - kind_type = kind_info[1] # Second element is the kind parameter name - _LOGGER.debug(" %s: '%s'", kind_name, kind_type) + for kind_type in kind_types: + name, ktype = [x.strip() for x in kind_type.split('=')] + _LOGGER.debug(" %s: '%s'", name, ktype) # end for # generate CCPP caps diff --git a/cime_config/cam_build_cache.py b/cime_config/cam_build_cache.py index 8bf507b0c..3e23b74a8 100644 --- a/cime_config/cam_build_cache.py +++ b/cime_config/cam_build_cache.py @@ -302,11 +302,8 @@ def __init__(self, build_cache): elif item.tag == 'kind_type': if isinstance(item.text, str): if item.text: - kinfo = item.text.strip().split() - kname = kinfo[0] - kmod = kinfo[1] - ktype = kinfo[2] - self.__kind_types[kname.strip()] = [kmod.strip(), ktype.strip()] + kname, ktype = item.text.strip().split('=') + self.__kind_types[kname.strip()] = ktype.strip() # end if # end if else: @@ -321,8 +318,7 @@ def __init__(self, build_cache): # end if (no else, we just have an almost empty object) # We always need a default definition for kind_phys if 'kind_phys' not in self.__kind_types: - #Assume ISO-Fortran double-precision real: - self.__kind_types['kind_phys'] = ['ISO_FORTRAN_ENV', 'REAL64'] + self.__kind_types['kind_phys'] = 'REAL64' # end if def update_registry(self, gen_reg_file, registry_source_files, @@ -350,7 +346,11 @@ def update_ccpp(self, suite_definition_files, scheme_files, host_files, """Replace the ccpp cache data with input data """ self.__preproc_defs = preproc_defs - self.__kind_types = kind_types + self.__kind_types = {} + for kind_def in kind_types: + name, ktype = [x.strip() for x in kind_def.split('=')] + self.__kind_types[name] = ktype + # end for self.__sdfs = {} for sfile in suite_definition_files: new_entry = FileStatus(sfile, 'SDF') @@ -445,9 +445,9 @@ def write(self): self.__create_nl_file.file_hash) preproc = ET.SubElement(ccpp, 'preproc_defs') preproc.text = self.__preproc_defs - for kind_def, kind_info in self.__kind_types.items(): + for kind_def, kind_type in self.__kind_types.items(): kind_elem = ET.SubElement(ccpp, 'kind_type') - kind_elem.text = f"{kind_def} {kind_info[0]} {kind_info[1]}" + kind_elem.text = f"{kind_def}={kind_type}" # end for #Combine elments into an Element Tree object: @@ -500,19 +500,18 @@ def ccpp_mismatch(self, sdfs, scheme_files, host_files, (self.__preproc_defs != preproc_defs)) if not mismatch: my_kind_defs = set(self.__kind_types.keys()) - my_kind_defs = set() - - # Convert kind_types dict to set of strings for comparison - for kind_name, kind_info in self.__kind_types.items(): - my_kind_defs.add(f"{kind_name} {' '.join(kind_info)}") - - # Convert input kind_types dict to set of strings for comparison - test_kind_defs = set() - for kind_name, kind_info in kind_types.items(): - test_kind_defs.add(f"{kind_name} {' '.join(kind_info)}") - - # Determine if the sets are different (i.e. a mismatch) - mismatch = my_kind_defs != test_kind_defs + test_kdefs = {z[0] : z[1] for z in + [[x.strip() for x in y.split('=')] + for y in kind_types]} + test_kind_keys = test_kdefs.keys() + test_kind_set = set(test_kind_keys) + mismatch = my_kind_defs != test_kind_set + for ref_kind in test_kind_keys: + if mismatch: + break + # end if + mismatch = test_kdefs[ref_kind] != self.__kind_types[ref_kind] + # end for # end if # For SDFs, we need to make sure we have 1-1 files # Note that this method will ignore duplicated files. diff --git a/src/data/generate_registry_data.py b/src/data/generate_registry_data.py index 0c4b4a25a..0d0e93b3d 100755 --- a/src/data/generate_registry_data.py +++ b/src/data/generate_registry_data.py @@ -1820,7 +1820,7 @@ def _create_variables_with_initial_value_list(registry): ############################################################################### def gen_registry(registry_file, dycore, outdir, indent, src_mod, src_root, loglevel=None, logger=None, - schema_paths=None): + schema_paths=None, error_on_no_validate=False): ############################################################################### """Parse a registry XML file and generate source code and metadata. is the name of the dycore for DP coupling specialization. @@ -1863,27 +1863,35 @@ def gen_registry(registry_file, dycore, outdir, indent, try: emsg = f"Invalid registry file, {registry_file}" file_ok = validate_xml_file(registry_file, 'registry', version, - logger, schema_path=schema_dir) + logger, schema_path=schema_dir, + error_on_noxmllint=error_on_no_validate) except CCPPError as ccpperr: - # Cleanup error message and print - # to log before raising the exception emsg += f"\n{ccpperr}" - logger.error(emsg) - raise CCPPError(emsg) + file_ok = False # end try - - library_name = registry.get('name') - emsg = f"Parsing registry, {library_name}" - logger.debug(emsg) - reg_dir = os.path.dirname(registry_file) - files = write_registry_files(registry, dycore, outdir, src_mod, - 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) - vars_init_value = _create_variables_with_initial_value_list(registry) - retcode = 0 # Throw exception on error - + if not file_ok: + if error_on_no_validate: + raise CCPPError(emsg) + # end if + logger.error(emsg) + retcode = 1 + files = None + ic_names = None + registry_constituents = None + vars_init_value = None + else: + library_name = registry.get('name') + emsg = f"Parsing registry, {library_name}" + logger.debug(emsg) + reg_dir = os.path.dirname(registry_file) + files = write_registry_files(registry, dycore, outdir, src_mod, + 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) + vars_init_value = _create_variables_with_initial_value_list(registry) + retcode = 0 # Throw exception on error + # end if return retcode, files, ic_names, registry_constituents, vars_init_value def main(): diff --git a/src/physics/ncar_ccpp b/src/physics/ncar_ccpp index 55fb20373..8b359bf45 160000 --- a/src/physics/ncar_ccpp +++ b/src/physics/ncar_ccpp @@ -1 +1 @@ -Subproject commit 55fb203739f3e61cb3e0649f719ea2e0ee065de6 +Subproject commit 8b359bf45c4ffa82ed9310447dd8259b3c1d6dd2 From 01fbbafe5d2b6e3be31e55eba89eb5112eb38a86 Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Wed, 11 Feb 2026 14:03:08 -0700 Subject: [PATCH 18/26] Update registry and remove old variable from generate_registry_data.xml --- src/data/generate_registry_data.py | 3 +- src/data/registry.xml | 246 +---------------------------- 2 files changed, 2 insertions(+), 247 deletions(-) diff --git a/src/data/generate_registry_data.py b/src/data/generate_registry_data.py index 2ddcf1528..b8e022528 100755 --- a/src/data/generate_registry_data.py +++ b/src/data/generate_registry_data.py @@ -1863,8 +1863,7 @@ def gen_registry(registry_file, dycore, outdir, indent, try: emsg = f"Invalid registry file, {registry_file}" file_ok = validate_xml_file(registry_file, 'registry', version, - logger, schema_path=schema_dir, - error_on_noxmllint=error_on_no_validate) + logger, schema_path=schema_dir) except CCPPError as ccpperr: emsg += f"\n{ccpperr}" file_ok = False diff --git a/src/data/registry.xml b/src/data/registry.xml index a28415b5d..ded55bcf2 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -3,14 +3,6 @@ - - $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_fluxes_byband.meta - $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_fluxes.meta - $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_gas_concentrations.meta - $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_gas_optics_rrtmgp.meta - $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_optical_props.meta - $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_source_functions.meta - $SRCROOT/src/physics/ncar_ccpp/to_be_ccppized/coords_1d.meta $SRCROOT/src/utils/spmd_utils.meta $SRCROOT/src/control/cam_control_mod.meta @@ -20,7 +12,6 @@ $SRCROOT/src/physics/utils/orbital_data.meta $SRCROOT/src/physics/utils/musica_ccpp_dependencies.meta $SRCROOT/src/physics/utils/physics_grid.meta - $SRCROOT/src/physics/utils/radiation_namelist.meta $SRCROOT/src/physics/utils/cam_constituents.meta $SRCROOT/src/physics/utils/tropopause_climo_read.meta $SRCROOT/src/physics/utils/gravity_wave_drag_ridge_read.meta @@ -39,9 +30,7 @@ - - @@ -389,11 +378,6 @@ units="flag" type="logical"> flag indicating if it is the first timestep of an initial run - - flag indicating if it is the first timestep of restart run - horizontal_dimension vertical_layer_dimension dvdt tend_dvdt - - horizontal_dimension vertical_layer_dimension - unset_real - @@ -506,21 +483,6 @@ units="1" type="real" kind="kind_phys"> fractional calendar day at end of current timestep - - fractional calendar day at end of next timestep - - - fractional calendar day at which to next perform shortwave radiation - - - number of seconds until next shortwave radiation timestep - graupel mass mixing ratio with respect to moist air plus all airborne condensates GRAUQM cnst_GRAUQM - - Q cnst_Q - - - CO2 cnst_CO2 - - - N2O cnst_N2O - - - CH4 cnst_CH4 - - - CFC12 cnst_CFC12 - - - CFC11STAR pbuf_CFC11STAR - - - O2 pbuf_O2 - - - ozone pbuf_ozone - 0.0_kind_phys cflx cam_in_cflx - - horizontal_dimension - 0.0_kind_phys - FSNT pbuf_FSNT - - - horizontal_dimension - 0.0_kind_phys - FSNS pbuf_FSNS - - - horizontal_dimension - 0.0_kind_phys - FLNT pbuf_FLNT - - - horizontal_dimension - 0.0_kind_phys - FLNS pbuf_FLNS - @@ -1679,7 +1569,7 @@ allocatable="allocatable" access="protected" > horizontal_dimension vertical_layer_dimension number_of_ccpp_constituents - 1._kind_phys + 1 .false. - - - 0._kind_phys - - - horizontal_dimension - COSZRS pbuf_COSZRS - - - horizontal_dimension vertical_layer_dimension - unset_real - CLDFSNOW pbuf_CLDFSNOW - - - horizontal_dimension vertical_layer_dimension - unset_real - CLDFGRAU pbuf_CLDFGRAU - - - horizontal_dimension vertical_layer_dimension - unset_real - ICGRAUWP pbuf_ICGRAUWP - - - horizontal_dimension vertical_layer_dimension - unset_real - DEGRAU pbuf_DEGRAU - - - horizontal_dimension vertical_layer_dimension - 0._kind_phys - LAMBDAC pbuf_LAMBDAC - - - horizontal_dimension vertical_layer_dimension - 0._kind_phys - MU pbuf_MU - - - horizontal_dimension vertical_layer_dimension - 0._kind_phys - ICLWP pbuf_ICLWP - - - horizontal_dimension vertical_layer_dimension - 0._kind_phys - ICIWP pbuf_ICIWP - - - horizontal_dimension vertical_layer_dimension - 0._kind_phys - ICSWP pbuf_ICSWP - - - horizontal_dimension vertical_layer_dimension - 0._kind_phys - DEI pbuf_DEI - - - horizontal_dimension vertical_layer_dimension - 0._kind_phys - DES pbuf_DES - - - horizontal_dimension vertical_layer_dimension - 0._kind_phys - QRS pbuf_QRS - - - horizontal_dimension vertical_layer_dimension - 0._kind_phys - QRL pbuf_QRL - - - 2 - - - .true. - - - .false. - - Date: Fri, 13 Feb 2026 15:44:17 -0700 Subject: [PATCH 19/26] merge changes and pumas registry variables --- .gitmodules | 4 +- src/data/registry.xml | 246 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 247 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 21c8e527b..0d79dfe68 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "ccpp-framework"] path = ccpp_framework - url = https://github.com/NCAR/ccpp-framework - fxtag = 2025-10-15-dev + url = https://github.com/gold2718/ccpp-framework + fxtag = b465661 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/NCAR/ccpp-framework [submodule "history"] diff --git a/src/data/registry.xml b/src/data/registry.xml index ded55bcf2..a28415b5d 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -3,6 +3,14 @@ + + $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_fluxes_byband.meta + $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_fluxes.meta + $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_gas_concentrations.meta + $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_gas_optics_rrtmgp.meta + $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_optical_props.meta + $SRCROOT/src/physics/ncar_ccpp/schemes/rrtmgp/objects/ccpp_source_functions.meta + $SRCROOT/src/physics/ncar_ccpp/to_be_ccppized/coords_1d.meta $SRCROOT/src/utils/spmd_utils.meta $SRCROOT/src/control/cam_control_mod.meta @@ -12,6 +20,7 @@ $SRCROOT/src/physics/utils/orbital_data.meta $SRCROOT/src/physics/utils/musica_ccpp_dependencies.meta $SRCROOT/src/physics/utils/physics_grid.meta + $SRCROOT/src/physics/utils/radiation_namelist.meta $SRCROOT/src/physics/utils/cam_constituents.meta $SRCROOT/src/physics/utils/tropopause_climo_read.meta $SRCROOT/src/physics/utils/gravity_wave_drag_ridge_read.meta @@ -30,7 +39,9 @@ + + @@ -378,6 +389,11 @@ units="flag" type="logical"> flag indicating if it is the first timestep of an initial run + + flag indicating if it is the first timestep of restart run + horizontal_dimension vertical_layer_dimension dvdt tend_dvdt + + horizontal_dimension vertical_layer_dimension + unset_real + @@ -483,6 +506,21 @@ units="1" type="real" kind="kind_phys"> fractional calendar day at end of current timestep + + fractional calendar day at end of next timestep + + + fractional calendar day at which to next perform shortwave radiation + + + number of seconds until next shortwave radiation timestep + graupel mass mixing ratio with respect to moist air plus all airborne condensates GRAUQM cnst_GRAUQM + + Q cnst_Q + + + CO2 cnst_CO2 + + + N2O cnst_N2O + + + CH4 cnst_CH4 + + + CFC12 cnst_CFC12 + + + CFC11STAR pbuf_CFC11STAR + + + O2 pbuf_O2 + + + ozone pbuf_ozone + 0.0_kind_phys cflx cam_in_cflx + + horizontal_dimension + 0.0_kind_phys + FSNT pbuf_FSNT + + + horizontal_dimension + 0.0_kind_phys + FSNS pbuf_FSNS + + + horizontal_dimension + 0.0_kind_phys + FLNT pbuf_FLNT + + + horizontal_dimension + 0.0_kind_phys + FLNS pbuf_FLNS + @@ -1569,7 +1679,7 @@ allocatable="allocatable" access="protected" > horizontal_dimension vertical_layer_dimension number_of_ccpp_constituents - 1 + 1._kind_phys .false. + + + 0._kind_phys + + + horizontal_dimension + COSZRS pbuf_COSZRS + + + horizontal_dimension vertical_layer_dimension + unset_real + CLDFSNOW pbuf_CLDFSNOW + + + horizontal_dimension vertical_layer_dimension + unset_real + CLDFGRAU pbuf_CLDFGRAU + + + horizontal_dimension vertical_layer_dimension + unset_real + ICGRAUWP pbuf_ICGRAUWP + + + horizontal_dimension vertical_layer_dimension + unset_real + DEGRAU pbuf_DEGRAU + + + horizontal_dimension vertical_layer_dimension + 0._kind_phys + LAMBDAC pbuf_LAMBDAC + + + horizontal_dimension vertical_layer_dimension + 0._kind_phys + MU pbuf_MU + + + horizontal_dimension vertical_layer_dimension + 0._kind_phys + ICLWP pbuf_ICLWP + + + horizontal_dimension vertical_layer_dimension + 0._kind_phys + ICIWP pbuf_ICIWP + + + horizontal_dimension vertical_layer_dimension + 0._kind_phys + ICSWP pbuf_ICSWP + + + horizontal_dimension vertical_layer_dimension + 0._kind_phys + DEI pbuf_DEI + + + horizontal_dimension vertical_layer_dimension + 0._kind_phys + DES pbuf_DES + + + horizontal_dimension vertical_layer_dimension + 0._kind_phys + QRS pbuf_QRS + + + horizontal_dimension vertical_layer_dimension + 0._kind_phys + QRL pbuf_QRL + + + 2 + + + .true. + + + .false. + + Date: Wed, 18 Feb 2026 14:35:50 -0700 Subject: [PATCH 20/26] Update atmos_phys external and add diag_name to constituent instantiate call --- .gitmodules | 2 +- src/control/cam_comp.F90 | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 450347085..75b867f58 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = 55fb203 + fxtag = c5bbc1b fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] diff --git a/src/control/cam_comp.F90 b/src/control/cam_comp.F90 index febecdeaa..fd12892b4 100644 --- a/src/control/cam_comp.F90 +++ b/src/control/cam_comp.F90 @@ -656,6 +656,7 @@ subroutine cam_register_constituents(cam_runtime_opts) units="kg kg-1", & default_value=0._kind_phys, & vertical_dim="vertical_layer_dimension", & + diag_name="Q", & advected=.true., & errcode=errflg, errmsg=errmsg) From 888393f8f34f74f6afe1bd5c4df74732ffa1fba4 Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Fri, 13 Mar 2026 17:31:33 -0600 Subject: [PATCH 21/26] Updates to help PUMAS to run --- .gitmodules | 6 +- src/data/registry.xml | 27 +- src/data/write_init_files.py | 10 +- src/physics/utils/physics_data.F90 | 380 +++++++++++++++++++++++++---- 4 files changed, 363 insertions(+), 60 deletions(-) diff --git a/.gitmodules b/.gitmodules index 75b867f58..c03cddf75 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "ccpp-framework"] path = ccpp_framework - url = https://github.com/gold2718/ccpp-framework - fxtag = b465661 + url = https://github.com/NCAR/ccpp-framework + fxtag = 9d87be6 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/NCAR/ccpp-framework [submodule "history"] @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = c5bbc1b + fxtag = 544d46a fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] diff --git a/src/data/registry.xml b/src/data/registry.xml index e5c945403..2277e3367 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -1855,6 +1855,24 @@ + + + + + + 0.8_kind_phys + + + + + .false. + + + horizontal_dimension vertical_layer_dimension + 0 FRZIMM pbuf_FRZIMM horizontal_dimension vertical_layer_dimension + 0 FRZCNT pbuf_FRZCNT horizontal_dimension vertical_layer_dimension + 0 FRZDEP pbuf_FRZDEP horizontal_dimension vertical_layer_dimension accre_enhan pbuf_accre_enhan pbuf_ACCRE_ENHAN + + horizontal_dimension vertical_layer_dimension - tnd_qsnow pbuf_tnd_qsnow + cnst_SNOWQM tnd_qsnow pbuf_tnd_qsnow horizontal_dimension vertical_layer_dimension - tnd_nsnow pbuf_tnd_nsnow + cnst_NUMSNO tnd_nsnow pbuf_tnd_nsnow diff --git a/src/data/write_init_files.py b/src/data/write_init_files.py index ce8ffb299..3bbf1569a 100644 --- a/src/data/write_init_files.py +++ b/src/data/write_init_files.py @@ -1288,7 +1288,8 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, ["shr_kind_mod", ["SHR_KIND_CS, SHR_KIND_CL, SHR_KIND_CX"]], ["physics_data", ["check_field", "find_input_name_idx", "no_exist_idx", "init_mark_idx", - "prot_no_init_idx", "const_idx"]], + "prot_no_init_idx", "const_idx", + "flush_check_field_verbose"]], ["cam_ccpp_cap", ["ccpp_physics_suite_variables", "cam_advected_constituents_array", "cam_model_const_properties"]], @@ -1501,6 +1502,11 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, outfile.write("end if", 3) outfile.write("end do", 2) + # Flush any buffered verbose entries (printed after all diff entries): + outfile.comment("Flush verbose check_field entries (printed after diffs):", 2) + outfile.write("call flush_check_field_verbose()", 2) + outfile.blank_line() + # Close check file outfile.comment("Close check file:", 2) outfile.write("call cam_pio_closefile(file)", 2) @@ -1508,7 +1514,7 @@ def write_phys_check_subroutine(outfile, host_dict, host_vars, host_imports, outfile.write("nullify(file)", 2) # Check if no differences were found - outfile.write("if (is_first) then", 2) + outfile.write("if (.not. overall_diff_found) then", 2) outfile.write("if (masterproc) then", 3) outfile.write("write(iulog,*) ''", 4) outfile.write("write(iulog,*) 'No differences found!'", 4) diff --git a/src/physics/utils/physics_data.F90 b/src/physics/utils/physics_data.F90 index 4bd95ada4..7d43f1412 100644 --- a/src/physics/utils/physics_data.F90 +++ b/src/physics/utils/physics_data.F90 @@ -7,8 +7,9 @@ module physics_data public :: read_field public :: read_constituent_dimensioned_field public :: check_field + public :: flush_check_field_verbose - !Non-standard variable indices: + ! Non-standard variable indices: integer, public, parameter :: no_exist_idx = -1 integer, public, parameter :: init_mark_idx = -2 integer, public, parameter :: prot_no_init_idx = -3 @@ -30,6 +31,18 @@ module physics_data module procedure read_constituent_dimensioned_field_2d end interface read_constituent_dimensioned_field + ! Module-level storage for verbose check_field entries. + ! These are accumulated during check_field calls and flushed + ! at the end via flush_check_field_verbose, so that the verbose + ! "OK" list is printed after any diff entries. + integer, parameter :: max_verbose_entries = 1000 + integer, parameter :: verbose_name_len = 256 + integer, save :: num_verbose_entries = 0 + character(len=verbose_name_len), save :: verbose_stdnames(max_verbose_entries) + integer, save :: verbose_global_count(max_verbose_entries) + real(8), save :: verbose_avg_model(max_verbose_entries) + real(8), save :: verbose_avg_snapshot(max_verbose_entries) + !============================================================================== CONTAINS !============================================================================== @@ -638,6 +651,9 @@ subroutine check_field_2d(file, var_names, timestep, current_value, & use cam_field_read, only: cam_read_field use mpi, only: mpi_maxloc, mpi_sum, mpi_status_size use mpi, only: mpi_2double_precision, mpi_integer + use mpi, only: mpi_double_precision + use shr_infnan_mod, only: shr_infnan_isnan + use cam_logfile, only: debug_output, DEBUGOUT_INFO !Max possible length of variable name in file: use phys_vars_init_check, only: std_name_len @@ -669,6 +685,19 @@ subroutine check_field_2d(file, var_names, timestep, current_value, & real(kind_phys) :: max_diff_gl(2) !Stores the global max diff and its MPI rank integer :: max_diff_gl_col integer :: diff_count_gl + integer :: nan_count ! Count of NaNs found + integer :: nan_count_gl ! Global count of NaNs + logical :: has_nan ! Flag indicating NaN was found + + ! Variables for verbose mode global averages + real(kind_phys) :: local_sum_model ! Local sum of model values + real(kind_phys) :: local_sum_snapshot ! Local sum of snapshot values + integer :: local_count ! Local count of valid (non-NaN) values + real(kind_phys) :: global_sum_model ! Global sum of model values + real(kind_phys) :: global_sum_snapshot! Global sum of snapshot values + integer :: global_count ! Global count of valid values + real(kind_phys) :: global_avg_model ! Global average of model state + real(kind_phys) :: global_avg_snapshot! Global average of snapshot !Initialize output variables ierr = 0 @@ -691,31 +720,82 @@ subroutine check_field_2d(file, var_names, timestep, current_value, & call cam_read_field(found_name, file, buffer, var_found, & timelevel=timestep, log_output=.false.) if (var_found) then + nan_count = 0 + has_nan = .false. + + ! Initialize verbose mode accumulators + local_sum_model = 0._kind_phys + local_sum_snapshot = 0._kind_phys + local_count = 0 + do col = 1, size(buffer) - if (abs(current_value(col)) < min_relative_value) then - !Calculate absolute difference: - diff = abs(current_value(col) - buffer(col)) + ! First, check if there are NaNs anywhere in the state + if (shr_infnan_isnan(current_value(col))) then + nan_count = nan_count + 1 + + if (.not. has_nan) then ! First NaN found for this variable + has_nan = .true. + + ! Set max diff to NaN (if not already) to signal NaN was found + max_diff(1) = current_value(col) - buffer(col) ! = nan + max_diff_col = col + end if else - !Calculate relative difference: - diff = abs(current_value(col) - buffer(col)) / & - abs(current_value(col)) - end if - if (diff > max_diff(1)) then - max_diff(1) = diff - max_diff_col = col - end if - if (diff > min_difference) then - diff_count = diff_count + 1 + ! Accumulate for global average (verbose mode) + local_sum_model = local_sum_model + current_value(col) + local_sum_snapshot = local_sum_snapshot + buffer(col) + local_count = local_count + 1 + + ! Calculate actual diffs for non-NaN values: + if (abs(current_value(col)) < min_relative_value) then + !Calculate absolute difference: + diff = abs(current_value(col) - buffer(col)) + else + !Calculate relative difference: + diff = abs(current_value(col) - buffer(col)) / & + abs(current_value(col)) + end if + ! Only update max diff if greater and not already nan: + if (diff > max_diff(1) .and. .not. has_nan) then + max_diff(1) = diff + max_diff_col = col + end if + if (diff > min_difference) then + diff_count = diff_count + 1 + end if end if end do + + !Add NaN count to total difference count: + diff_count = diff_count + nan_count + !Gather results across all nodes to get global values + call mpi_reduce(nan_count, nan_count_gl, 1, mpi_integer, & + mpi_sum, masterprocid, mpicom, ierr) call mpi_reduce(diff_count, diff_count_gl, 1, mpi_integer, & - mpi_sum, masterprocid, mpicom, ierr) + mpi_sum, masterprocid, mpicom, ierr) call mpi_allreduce(max_diff, max_diff_gl, 1, & MPI_2DOUBLE_PRECISION, & mpi_maxloc, mpicom, ierr) + ! Gather global averages for verbose mode + if (debug_output >= DEBUGOUT_INFO) then + call mpi_reduce(local_sum_model, global_sum_model, 1, & + mpi_double_precision, mpi_sum, masterprocid, & + mpicom, ierr) + call mpi_reduce(local_sum_snapshot, global_sum_snapshot, 1, & + mpi_double_precision, mpi_sum, masterprocid, & + mpicom, ierr) + call mpi_reduce(local_count, global_count, 1, mpi_integer, & + mpi_sum, masterprocid, mpicom, ierr) + + if (masterproc .and. global_count > 0) then + global_avg_model = global_sum_model / real(global_count, kind_phys) + global_avg_snapshot = global_sum_snapshot / real(global_count, kind_phys) + end if + end if + if (iam == int(max_diff_gl(2)) .and. .not. masterproc) then !The largest diff happened on this task, so the local max is !the global max. So send the local max value's dimension @@ -737,13 +817,21 @@ subroutine check_field_2d(file, var_names, timestep, current_value, & !Print difference stats to log file if (masterproc) then if (diff_count_gl > 0) then - call write_check_field_entry(stdname, diff_count_gl, & + call write_check_field_entry(stdname, diff_count_gl, & + nan_count_gl, & max_diff_gl(1), & int(max_diff_gl(2)), & max_diff_gl_col, is_first) is_first = .false. diff_found = .true. end if + ! Store verbose entry for later printing (after all diffs) + if ((debug_output >= DEBUGOUT_INFO) .and. & + diff_count_gl == 0 .and. global_count > 0) then + call store_verbose_entry(stdname, global_count, & + global_avg_model, & + global_avg_snapshot) + end if end if end if end if @@ -763,7 +851,10 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & use cam_field_read, only: cam_read_field use mpi, only: mpi_maxloc, mpi_sum, mpi_status_size use mpi, only: mpi_2double_precision, mpi_integer + use mpi, only: mpi_double_precision use vert_coord, only: pver, pverp + use shr_infnan_mod, only: shr_infnan_isnan + use cam_logfile, only: debug_output, DEBUGOUT_INFO !Max possible length of variable name in file: use phys_vars_init_check, only: std_name_len @@ -800,6 +891,19 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & integer :: max_diff_gl_col integer :: max_diff_gl_lev integer :: diff_count_gl + integer :: nan_count ! Count of NaNs found + integer :: nan_count_gl ! Global count of NaNs + logical :: has_nan ! Flag indicating NaN was found + + ! Variables for verbose mode global averages + real(kind_phys) :: local_sum_model ! Local sum of model values + real(kind_phys) :: local_sum_snapshot ! Local sum of snapshot values + integer :: local_count ! Local count of valid (non-NaN) values + real(kind_phys) :: global_sum_model ! Global sum of model values + real(kind_phys) :: global_sum_snapshot! Global sum of snapshot values + integer :: global_count ! Global count of valid values + real(kind_phys) :: global_avg_model ! Global average of model state + real(kind_phys) :: global_avg_snapshot! Global average of snapshot !Initialize output variables ierr = 0 @@ -832,29 +936,62 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & timelevel=timestep, dim3name=trim(vcoord_name), & dim3_bnds=[1, num_levs], log_output=.false.) if (var_found) then + nan_count = 0 + has_nan = .false. + + ! Initialize verbose mode accumulators + local_sum_model = 0._kind_phys + local_sum_snapshot = 0._kind_phys + local_count = 0 + do lev = 1, num_levs do col = 1, size(buffer(:,lev)) - if (abs(current_value(col, lev)) < min_relative_value) then - !Calculate absolute difference: - diff = abs(current_value(col, lev) - buffer(col, lev)) + ! First, check if there are NaNs anywhere in the state + if (shr_infnan_isnan(current_value(col, lev))) then + nan_count = nan_count + 1 + + if (.not. has_nan) then ! First NaN found for this variable + has_nan = .true. + + ! Set max diff to NaN (if not already) to signal NaN was found + max_diff(1) = current_value(col,lev) - buffer(col,lev) ! = nan + max_diff_col = col + max_diff_lev = lev + end if else - !Calculate relative difference: - diff = abs(current_value(col, lev) - buffer(col, lev)) / & - abs(current_value(col, lev)) - end if - if (diff > max_diff(1)) then - max_diff(1) = diff - max_diff_col = col - max_diff_lev = lev - end if - !Determine if diff is large enough to be considered a "hit" - if (diff > min_difference) then - diff_count = diff_count + 1 + ! Accumulate for global average (verbose mode) + local_sum_model = local_sum_model + current_value(col, lev) + local_sum_snapshot = local_sum_snapshot + buffer(col, lev) + local_count = local_count + 1 + + ! Calculate actual diffs for non-NaN values: + if (abs(current_value(col, lev)) < min_relative_value) then + !Calculate absolute difference: + diff = abs(current_value(col, lev) - buffer(col, lev)) + else + !Calculate relative difference: + diff = abs(current_value(col, lev) - buffer(col, lev)) / & + abs(current_value(col, lev)) + end if + if (diff > max_diff(1)) then + max_diff(1) = diff + max_diff_col = col + max_diff_lev = lev + end if + !Determine if diff is large enough to be considered a "hit" + if (diff > min_difference) then + diff_count = diff_count + 1 + end if end if end do end do - !Make relevant MPI calls to get global values: + !Add NaN count to total difference count: + diff_count = diff_count + nan_count + + !Gather results across all nodes to get global values + call mpi_reduce(nan_count, nan_count_gl, 1, mpi_integer, & + mpi_sum, masterprocid, mpicom, ierr) call mpi_reduce(diff_count, diff_count_gl, 1, mpi_integer, & mpi_sum, masterprocid, mpicom, ierr) @@ -862,6 +999,23 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & MPI_2DOUBLE_PRECISION, & mpi_maxloc, mpicom, ierr) + ! Gather global averages for verbose mode + if (debug_output >= DEBUGOUT_INFO) then + call mpi_reduce(local_sum_model, global_sum_model, 1, & + mpi_double_precision, mpi_sum, masterprocid, & + mpicom, ierr) + call mpi_reduce(local_sum_snapshot, global_sum_snapshot, 1, & + mpi_double_precision, mpi_sum, masterprocid, & + mpicom, ierr) + call mpi_reduce(local_count, global_count, 1, mpi_integer, & + mpi_sum, masterprocid, mpicom, ierr) + + if (masterproc .and. global_count > 0) then + global_avg_model = global_sum_model / real(global_count, kind_phys) + global_avg_snapshot = global_sum_snapshot / real(global_count, kind_phys) + end if + end if + if (iam == int(max_diff_gl(2)) .and. .not. masterproc) then !The largest diff happened on this task, so the local max is !the global max. So send the local max value's dimension @@ -889,15 +1043,23 @@ subroutine check_field_3d(file, var_names, vcoord_name, timestep, & !Print difference stats to log file if (masterproc) then if (diff_count_gl > 0) then - call write_check_field_entry(stdname, diff_count_gl, & + call write_check_field_entry(stdname, diff_count_gl, & + nan_count_gl, & max_diff_gl(1), & int(max_diff_gl(2)), & - max_diff_gl_col, & - is_first, & + max_diff_gl_col, & + is_first, & max_diff_lev=max_diff_gl_lev) is_first = .false. diff_found = .true. end if + ! Store verbose entry for later printing (after all diffs) + if ((debug_output >= DEBUGOUT_INFO) .and. & + diff_count_gl == 0 .and. global_count > 0) then + call store_verbose_entry(stdname, global_count, & + global_avg_model, & + global_avg_snapshot) + end if end if end if end if @@ -958,6 +1120,9 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & integer :: max_diff_gl_lev integer :: max_diff_gl_extra_dim integer :: diff_count_gl + integer :: nan_count + integer :: nan_count_gl + logical :: has_nan !Initialize output variables ierr = 0 @@ -972,6 +1137,8 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & max_diff(1) = 0._kind_phys max_diff(2) = real(iam, kind_phys) !MPI rank for this task diff_found = .false. + nan_count = 0 + has_nan = .false. call cam_pio_find_var(file, var_names, found_name, vardesc, var_found) if (.not. var_found) then @@ -997,28 +1164,53 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & do extra_dim = 1, size(buffer, 3) do lev = 1, num_levs do col = 1, size(buffer(:,lev,extra_dim)) - if (abs(current_value(col, lev, extra_dim)) < min_relative_value) then - !Calculate absolute difference: - diff = abs(current_value(col, lev, extra_dim) - buffer(col, lev, extra_dim)) + ! Check for NaNs first + if (current_value(col, lev, extra_dim) /= current_value(col, lev, extra_dim) .or. & + buffer(col, lev, extra_dim) /= buffer(col, lev, extra_dim)) then + nan_count = nan_count + 1 + if (.not. has_nan) then + has_nan = .true. + + ! Force max_diff to NaN to signal NaN found + max_diff(1) = current_value(col, lev, extra_dim) - & + buffer(col, lev, extra_dim) + max_diff_col = col + max_diff_lev = lev + max_diff_extra_dim = extra_dim + end if else - !Calculate relative difference: - diff = abs(current_value(col, lev, extra_dim) - buffer(col, lev, extra_dim)) / & - abs(current_value(col, lev, extra_dim)) - end if - if (diff > max_diff(1)) then - max_diff(1) = diff - max_diff_col = col - max_diff_lev = lev - max_diff_extra_dim = extra_dim - end if - !Determine if diff is large enough to be considered a "hit" - if (diff > min_difference) then - diff_count = diff_count + 1 + if (abs(current_value(col, lev, extra_dim)) < min_relative_value) then + ! Absolute difference + diff = abs(current_value(col, lev, extra_dim) - & + buffer(col, lev, extra_dim)) + else + ! Relative difference + diff = abs(current_value(col, lev, extra_dim) - & + buffer(col, lev, extra_dim)) / & + abs(current_value(col, lev, extra_dim)) + end if + + if (diff > max_diff(1)) then + max_diff(1) = diff + max_diff_col = col + max_diff_lev = lev + max_diff_extra_dim = extra_dim + end if + + if (diff > min_difference) then + diff_count = diff_count + 1 + end if end if end do end do end do + !Add NaN count to total difference count: + diff_count = diff_count + nan_count + + call mpi_reduce(nan_count, nan_count_gl, 1, mpi_integer, & + mpi_sum, masterprocid, mpicom, ierr) + !Make relevant MPI calls to get global values: call mpi_reduce(diff_count, diff_count_gl, 1, mpi_integer, & mpi_sum, masterprocid, mpicom, ierr) @@ -1061,6 +1253,7 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & if (masterproc) then if (diff_count_gl > 0) then call write_check_field_entry(stdname, diff_count_gl, & + nan_count_gl, & max_diff_gl(1), & int(max_diff_gl(2)), & max_diff_gl_col, & @@ -1077,7 +1270,8 @@ subroutine check_field_4d(file, var_names, vcoord_name, timestep, & end subroutine check_field_4d - subroutine write_check_field_entry(stdname, diff_count, & + subroutine write_check_field_entry(stdname, & + diff_count, nan_count, & max_diff, max_diff_rank, & max_diff_col, is_first, & max_diff_lev, max_diff_extra_dim) @@ -1089,6 +1283,7 @@ subroutine write_check_field_entry(stdname, diff_count, & !Dummy variables: character(len=*), intent(in) :: stdname integer, intent(in) :: diff_count + integer, intent(in) :: nan_count real(kind_phys), intent(in) :: max_diff integer, intent(in) :: max_diff_rank !MPI rank max diff occurred on integer, intent(in) :: max_diff_col !max diff column (1st) dimension value @@ -1119,7 +1314,7 @@ subroutine write_check_field_entry(stdname, diff_count, & slen = 0 end if - !Write out difference and index valuesa: + !Write out difference and index values: if (present(max_diff_lev)) then if(present(max_diff_extra_dim)) then write(index_str, '(a,i0,a,i0,a,i0,a,i0,a)') "(",max_diff_rank,",",max_diff_col,",",max_diff_lev,",",max_diff_extra_dim,")" @@ -1132,6 +1327,85 @@ subroutine write_check_field_entry(stdname, diff_count, & write(fmt_str, '(a,i0,a)') "(1x,a,t",indent_level+1,",1x,i7,2x,e8.2,3x,a)" write(iulog, fmt_str) stdname(1:slen), diff_count, max_diff, index_str + !Print out warning if any NaN values found: + if (nan_count > 0) then + write(iulog, '(a,i0,a)') ' (!) ', nan_count, & + ' NaN values in variable!' + end if + end subroutine write_check_field_entry + subroutine store_verbose_entry(stdname, global_count, & + global_avg_model, global_avg_snapshot) + use ccpp_kinds, only: kind_phys + + !Dummy variables: + character(len=*), intent(in) :: stdname + integer, intent(in) :: global_count + real(kind_phys), intent(in) :: global_avg_model + real(kind_phys), intent(in) :: global_avg_snapshot + + if (num_verbose_entries < max_verbose_entries) then + num_verbose_entries = num_verbose_entries + 1 + verbose_stdnames(num_verbose_entries) = stdname + verbose_global_count(num_verbose_entries) = global_count + verbose_avg_model(num_verbose_entries) = global_avg_model + verbose_avg_snapshot(num_verbose_entries) = global_avg_snapshot + end if + + end subroutine store_verbose_entry + + subroutine flush_check_field_verbose() + ! + ! Writes all buffered verbose check_field entries to the log. + ! This should be called after all check_field calls are complete, + ! so that the verbose "OK" list appears after any diff entries. + ! + + use cam_logfile, only: iulog + use spmd_utils, only: masterproc + use shr_kind_mod, only: cs=>shr_kind_cs + + !Local variables: + character(len=cs) :: fmt_str + integer :: i, slen + integer, parameter :: indent_level = 50 + + if (num_verbose_entries == 0) return + if (.not. masterproc) return + + !Write verbose check_field log header: + write(iulog, *) '' + write(iulog, *) 'No differences found for all the variables below:' + write(iulog, *) 'Note: If a variable is not in the registry, ' + write(iulog, *) ' or if a constituent is not registered,' + write(iulog, *) ' it is not checked against the snapshot.' + write(iulog, *) ' Verify all model state variables are enumerated below:' + write(iulog, *) '' + write(fmt_str, '(a,i0,a)') "(1x,a,t",indent_level+1,",1x,a,3x,a,3x,a)" + write(iulog, fmt_str) 'Variable Checked', '# Values', 'Avg (model)', 'Avg (snapshot)' + write(fmt_str, '(a,i0,a)') "(1x,a,t",indent_level+1,",1x,a,3x,a,3x,a)" + write(iulog, fmt_str) '--------', '--------', '------------', '--------------' + + do i = 1, num_verbose_entries + slen = len_trim(verbose_stdnames(i)) + + !Write standard name separately if longer than the indent level: + if (slen > indent_level) then + write(iulog, '(a)') trim(verbose_stdnames(i)) + slen = 0 + end if + + !Write out verbose entry with global averages: + write(fmt_str, '(a,i0,a)') "(1x,a,t",indent_level+1,",1x,i8,3x,es12.5,3x,es12.5)" + write(iulog, fmt_str) verbose_stdnames(i)(1:slen), & + verbose_global_count(i), verbose_avg_model(i), & + verbose_avg_snapshot(i) + end do + + !Reset the buffer for the next check_data call: + num_verbose_entries = 0 + + end subroutine flush_check_field_verbose + end module physics_data From f84a8dab199434fd2dd9337fe203399f1f3e6026 Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Wed, 13 May 2026 13:40:09 -0600 Subject: [PATCH 22/26] Add numliq, etc to registry --- src/data/registry.xml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/data/registry.xml b/src/data/registry.xml index 4ae1d95f2..210e8c839 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -635,6 +635,39 @@ graupel mass mixing ratio with respect to moist air plus all airborne condensates GRAUQM cnst_GRAUQM + + mass number concentration of cloud liquid water wrt moist air plus all airborne condensates + horizontal_dimension vertical_layer_dimension + NUMLIQ cnst_NUMLIQ + + + mass number concentration of Cloud ice mass mixing ratio with respect to moist air plus all airborne condensates + horizontal_dimension vertical_layer_dimension + NUMICE cnst_NUMICE + + + mass number concentration of rain mass mixing ratio with respect to moist air plus all airborne condensates + horizontal_dimension vertical_layer_dimension + NUMRAI cnst_NUMRAI + + + mass number concentration of snow mass mixing ratio with respect to moist air plus all airborne condensates + NUMSNO cnst_NUMSNO + + + mass number concentration of graupel mass mixing ratio with respect to moist air plus all airborne condensates + NUMGRA cnst_NUMGRA + From 44fed542b4ca1f4a9bd631d0804a8d1bcfd12d66 Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Wed, 17 Jun 2026 09:14:55 -0600 Subject: [PATCH 23/26] Update atmos_phys external --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index dc8f131ae..e95f7fe2f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = 22510f2 + fxtag = 090416b fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] From a18d032d126f6043440762aa126f5fc77c26873e Mon Sep 17 00:00:00 2001 From: Cheryl Craig Date: Thu, 18 Jun 2026 15:27:29 -0600 Subject: [PATCH 24/26] changes required to get PUMAS to be BFB --- .gitmodules | 2 +- src/data/registry.xml | 119 ++++++++++++++++++++++++++++++++---------- 2 files changed, 93 insertions(+), 28 deletions(-) diff --git a/.gitmodules b/.gitmodules index e95f7fe2f..fa19648b4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "ncar-physics"] path = src/physics/ncar_ccpp url = https://github.com/nusbaume/atmospheric_physics - fxtag = 090416b + fxtag = 22a3457 fxrequired = AlwaysRequired fxDONOTUSEurl = https://github.com/ESCOMP/atmospheric_physics [submodule "rrtmgp-data"] diff --git a/src/data/registry.xml b/src/data/registry.xml index 210e8c839..62898ae8f 100644 --- a/src/data/registry.xml +++ b/src/data/registry.xml @@ -30,8 +30,7 @@ $SRCROOT/src/data/ref_pres.meta $SRCROOT/src/dynamics/utils/vert_coord.meta $SRCROOT/src/dynamics/utils/hycoef.meta - - + $SRCROOT/src/physics/ncar_ccpp/schemes/pumas/pumas/micro_pumas_diags.meta @@ -587,8 +586,21 @@ standard_name="specific_heat_of_air_used_in_dycore" units="J kg-1 K-1" type="real" kind="kind_phys" allocatable="allocatable"> - specific heat of air used in the dynamical core (enthalpy for pressure-based dynamical cores and internal energy for z-based dynamical cores) + specific heat of air used in the dynamical core (enthalpy for pressure-based dynamical cores and internal energy for z-based dynamical cores), updated mid-physics for post-mass-adjustment total energy diagnostics horizontal_dimension vertical_layer_dimension + 0._kind_phys + + + Specific heat of air used in the dynamical core (enthalpy for pressure-based dynamical cores and internal energy for z-based dynamical cores), at start of physics timestep, for energy-consistency scaling and energy checker + horizontal_dimension vertical_layer_dimension + cp_or_cv_dycore @@ -636,34 +648,34 @@ GRAUQM cnst_GRAUQM mass number concentration of cloud liquid water wrt moist air plus all airborne condensates horizontal_dimension vertical_layer_dimension NUMLIQ cnst_NUMLIQ mass number concentration of Cloud ice mass mixing ratio with respect to moist air plus all airborne condensates horizontal_dimension vertical_layer_dimension NUMICE cnst_NUMICE mass number concentration of rain mass mixing ratio with respect to moist air plus all airborne condensates horizontal_dimension vertical_layer_dimension NUMRAI cnst_NUMRAI mass number concentration of snow mass mixing ratio with respect to moist air plus all airborne condensates NUMSNO cnst_NUMSNO mass number concentration of graupel mass mixing ratio with respect to moist air plus all airborne condensates NUMGRA cnst_NUMGRA @@ -1509,6 +1521,13 @@ 273.15_kind_phys tpert pbuf_tpert + + horizontal_dimension vertical_layer_dimension + pbuf_WSEDL + + + horizontal_dimension vertical_interface_dimension + 0.0_kind_phys + pbuf_kvm + + + horizontal_dimension vertical_interface_dimension + 0.0_kind_phys + pbuf_kvh + + 0.0_kind_phys pbuf_taubljy + + + horizontal_dimension + 0.0_kind_phys + pbuf_tautmsx + + + horizontal_dimension + 0.0_kind_phys + pbuf_tautmsy + + + horizontal_dimension + 0.0_kind_phys + pbuf_ksrftms + + @@ -1752,6 +1818,20 @@ dust4 pbuf_dust4 cnst_dust4 + + + horizontal_dimension vertical_layer_dimension + VOLC_MMR pbuf_VOLC_MMR + + + horizontal_dimension vertical_layer_dimension + VOLC_RAD_GEOM pbuf_VOLC_RAD_GEOM + + .false. - - - - - + @@ -1979,13 +2055,6 @@ - - .false. - - - horizontal_dimension vertical_layer_dimension REI pbuf_REI - - @@ -2072,8 +2140,7 @@ horizontal_dimension vertical_layer_dimension 0 FRZDEP pbuf_FRZDEP - - @@ -2097,7 +2164,6 @@ cnst_NUMSNO tnd_nsnow pbuf_tnd_nsnow -