From e9310accba11e1775a107f29d302b259fe15e012 Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Sat, 11 Jul 2026 08:31:57 -0600 Subject: [PATCH 01/14] interim commit of phys_cycle/cplhist updates --- cime_config/config_component.xml | 22 +++++- cime_config/config_compsets.xml | 39 ++++++++++ cime_config/config_pes.xml | 71 ++++++++++--------- cime_config/phys_cycle_postrun | 118 +++++++++++++++++++++++++++++++ cime_config/phys_cycle_prerun | 92 ++++++++++++++++++++++++ 5 files changed, 308 insertions(+), 34 deletions(-) create mode 100755 cime_config/phys_cycle_postrun create mode 100755 cime_config/phys_cycle_prerun diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index c2c20041..070298fb 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -5,9 +5,10 @@ - MOM6 OCEAN + MOM6 OCEAN MARBL Biogeochemistry Tracer Library base biotic tracers MARBL Biogeochemistry Tracer Library abiotic DIC tracers + phys cycle option @@ -206,6 +207,25 @@ + + integer + 0 + run_component_mom + env_run.xml + number of years to run before cycling MOM6 physics + MOM6 physics cycling only occurs if MOM6_PHYS_CYCLE_YEARS_IN_CYCLE>0 + and pre- and post-run scripts are specified in env vars + PRERUN_SCRIPT and POSTRUN_SCRIPT + + + + integer + 0 + run_component_mom + env_run.xml + number of months run since most recent cycling of MOM6 physics + + ========================================= MOM6 naming conventions diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml index 6e5cf63b..d7512fd3 100644 --- a/cime_config/config_compsets.xml +++ b/cime_config/config_compsets.xml @@ -115,9 +115,48 @@ 1850_DATM%JRA-1p5-2023_SLND_CICE_MOM6%MARBL-BIO_DROF%JRA-1p5-2023_SGLC_WW3 + + GW1850MARBL_JRA_PHYS_CYCLE + 1850_DATM%JRA-1p5-2023_SLND_CICE_MOM6%MARBL-BIO%PHYS-CYCLE_DROF%JRA-1p5-2023_SGLC_WW3 + + + + GW1850MARBL_CPLHIST + 1850_DATM%CPLHIST_SLND_CICE_MOM6%MARBL-BIO_DROF%CPLHIST_SGLC_WW3 + + + + GW1850MARBL_CPLHIST_PHYS_CYCLE + 1850_DATM%CPLHIST_SLND_CICE_MOM6%MARBL-BIO%PHYS-CYCLE_DROF%CPLHIST_SGLC_WW3 + + GW1850ABIOMARBL_JRA 1850_DATM%JRA-1p5-2023_SLND_CICE_MOM6%MARBL-ABIO_DROF%JRA-1p5-2023_SGLC_WW3 + + + + + + + $SRCROOT/components/mom/cime_config/phys_cycle_prerun + + + + + + $SRCROOT/components/mom/cime_config/phys_cycle_postrun + + + + + + FALSE + + + + + diff --git a/cime_config/config_pes.xml b/cime_config/config_pes.xml index 6ae579d3..36561ac3 100644 --- a/cime_config/config_pes.xml +++ b/cime_config/config_pes.xml @@ -210,39 +210,6 @@ 0 - - none - - 384 - 384 - 384 - 384 - 2560 - 1 - 128 - 1 - - - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - - - 0 - 0 - 0 - 0 - 512 - 0 - 384 - 0 - - none @@ -413,6 +380,44 @@ + + + + MARBL 2/3, any DATM forcing, including CPLHIST + + 384 + 384 + 384 + 384 + 2560 + 1 + 128 + 1 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + + + 0 + 0 + 0 + 0 + 512 + 0 + 384 + 0 + + + + + diff --git a/cime_config/phys_cycle_postrun b/cime_config/phys_cycle_postrun new file mode 100755 index 00000000..5df6a66e --- /dev/null +++ b/cime_config/phys_cycle_postrun @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +"""mom6 physics cycle postrun script +""" + +import os, shutil, sys + +_CIMEROOT = os.environ.get("CIMEROOT") +if _CIMEROOT is None: + raise SystemExit("ERROR: must set CIMEROOT environment variable") +sys.path.append(os.path.join(_CIMEROOT, "scripts", "Tools")) + +from standard_script_setup import * +from CIME.case import Case +from CIME.utils import expect + +logger = logging.getLogger(__name__) + +############################################################################### +def phys_cycle_postrun(caseroot): +############################################################################### + + ch = logging.StreamHandler(stream=sys.stdout) + ch.setLevel(logging.INFO) + logger.addHandler(ch) + + with Case(caseroot) as case: + mom6_phys_cycle_years_in_cycle = case.get_value("MOM6_PHYS_CYCLE_YEARS_IN_CYCLE") + expect(mom6_phys_cycle_years_in_cycle is not None, + "MOM6_PHYS_CYCLE_YEARS_IN_CYCLE should be defined when %s is called" % sys.argv[0]) + if (mom6_phys_cycle_years_in_cycle <= 0): + return + + # ------------------------------------------------------------------------- + # Determine if model has run the length of MOM6 physics run cycle length + # ------------------------------------------------------------------------- + + run_type = case.get_value("RUN_TYPE") + stop_option = case.get_value("STOP_OPTION") + stop_n = case.get_value("STOP_N") + caseroot = case.get_value("CASEROOT") + rundir = case.get_value("RUNDIR") + + mom6_phys_cycle_months_run_since_cycle = case.get_value("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE") + mom6_phys_cycle_years_in_cycle = case.get_value("MOM6_PHYS_CYCLE_YEARS_IN_CYCLE") + + # we know from phys_cycle_prerun that stop_option is either "nmonth*" or "nyear*" + + if stop_option.find("nmonth") == 0: + mom6_phys_cycle_months_run_since_cycle_new = mom6_phys_cycle_months_run_since_cycle + stop_n + if stop_option.find("nyear") == 0: + mom6_phys_cycle_months_run_since_cycle_new = mom6_phys_cycle_months_run_since_cycle + stop_n * 12 + + case.set_value("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE", mom6_phys_cycle_months_run_since_cycle_new) + logger.info("mom6_phys_cycle_months_run_since_cycle is now %d" % mom6_phys_cycle_months_run_since_cycle_new) + + mom6_phys_cycle_months_in_cycle = mom6_phys_cycle_years_in_cycle * 12 + if mom6_phys_cycle_months_run_since_cycle_new < mom6_phys_cycle_months_in_cycle: + case.set_value("CONTINUE_RUN", "TRUE") + case.set_value("MOM6_PASSIVE_TRACER_RESTART_OVERRIDE", "none") + case.flush() + return + + expect(mom6_phys_cycle_months_run_since_cycle_new <= mom6_phys_cycle_months_in_cycle, + "MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE has overshot MOM6_PHYS_CYCLE_MONTHS_IN_CYCLE=%d" + % mom6_phys_cycle_months_in_cycle) + + # ------------------------------------------------------------------------- + # Model has run the length of MOM6 physics run cycle length + # Reset model physics, keeping restart file for tracers to continue to evolve + # ------------------------------------------------------------------------- + + logger.info("resetting model physics") + case.set_value("CONTINUE_RUN", "FALSE") + case.set_value("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE", 0) + + with open(os.path.join(rundir, "rpointer.ocn.restart"),'r') as f: + case.set_value("MOM6_PASSIVE_TRACER_RESTART_OVERRIDE", os.path.join(rundir, f.readline())) + + # ------------------------------------------------------------------------- + # Compute new RUN_STARTDATE + # ------------------------------------------------------------------------- + + run_startdate = case.get_value("RUN_STARTDATE") + yyyy = int(run_startdate[:4]) + yyyy = yyyy + mom6_phys_cycle_years_in_cycle + run_startdate = "%04d" % yyyy + run_startdate[4:] + case.set_value("RUN_STARTDATE", run_startdate) + + # ------------------------------------------------------------------------- + # Compute new _CPLHIST_YR_ALIGN variables + # ------------------------------------------------------------------------- + + for align_varname in [ "DATM_CPLHIST_YR_ALIGN", "DROF_CPLHIST_YR_ALIGN" ]: + align_val = case.get_value(align_varname) + if align_val is not None: + align_val = align_val + mom6_phys_cycle_years_in_cycle + case.set_value(align_varname, align_val) + + case.flush() + + # ------------------------------------------------------------------------- + # re-prestage MOM6 rpointer files if necessary + # ------------------------------------------------------------------------- + + if run_type != "startup": + for rpointer_filename in [ "rpointer.ocn.restart", "rpointer.ocn.ovf" ]: + sfile = os.path.join(caseroot, "Buildconf", "momconf", rpointer_filename+".orig") + dfile = os.path.join(rundir, rpointer_filename) + expect(os.path.isfile(sfile), "required mom6 file %s is missing" % sfile) + shutil.copy(sfile, dfile) + +############################################################################### + +if __name__ == "__main__": + expect(len(sys.argv) == 2, "caseroot is a required input argument") + caseroot = sys.argv[1] + phys_cycle_postrun(caseroot) diff --git a/cime_config/phys_cycle_prerun b/cime_config/phys_cycle_prerun new file mode 100755 index 00000000..24557897 --- /dev/null +++ b/cime_config/phys_cycle_prerun @@ -0,0 +1,92 @@ +#!/usr/bin/env python + +"""mom6 physics cycle prerun script +""" + +import os, shutil, sys + +_CIMEROOT = os.environ.get("CIMEROOT") +if _CIMEROOT is None: + raise SystemExit("ERROR: must set CIMEROOT environment variable") +sys.path.append(os.path.join(_CIMEROOT, "scripts", "Tools")) + +from standard_script_setup import * +from CIME.case import Case +from CIME.utils import expect + +logger = logging.getLogger(__name__) + +############################################################################### +def phys_cycle_prerun(caseroot): +############################################################################### + + ch = logging.StreamHandler(stream=sys.stdout) + ch.setLevel(logging.INFO) + logger.addHandler(ch) + + with Case(caseroot) as case: + mom6_phys_cycle_years_in_cycle = case.get_value("MOM6_PHYS_CYCLE_YEARS_IN_CYCLE") + expect(mom6_phys_cycle_years_in_cycle is not None, + "MOM6_PHYS_CYCLE_YEARS_IN_CYCLE should be defined when %s is called" % sys.argv[0]) + logger.info("mom6_phys_cycle_years_in_cycle is %d", mom6_phys_cycle_years_in_cycle) + if (mom6_phys_cycle_years_in_cycle <= 0): + return + + # run_type cannot be branch + run_type = case.get_value("RUN_TYPE") + expect(run_type != "branch", + "RUN_TYPE set to branch not implemented for MOM6 physics cycling" + " because RUN_STARTDATE cannot be incremented") + + # stop_option must be nmonth, nmonths, nyear or nyears + stop_option = case.get_value("STOP_OPTION") + expect((stop_option.find("nmonth") == 0) or (stop_option.find("nyear") == 0), + "STOP_OPTION=%s not implemented for MOM6 physics cycling" % stop_option) + + # ------------------------------------------------------------------------- + # Ensure that phys_cycle scripts are in charge of setting CONTINUE_RUN + # ------------------------------------------------------------------------- + case.set_value("RESUBMIT_SETS_CONTINUE_RUN", "FALSE") + case.flush() + + # ------------------------------------------------------------------------- + # Ensure that the current run length will not overshoot the phys_cycle run length + # ------------------------------------------------------------------------- + + mom6_phys_cycle_months_run_since_cycle = case.get_value("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE") + mom6_phys_cycle_years_in_cycle = case.get_value("MOM6_PHYS_CYCLE_YEARS_IN_CYCLE") + + stop_n = case.get_value("STOP_N") + if stop_option.find("nmonth") == 0: + mom6_phys_cycle_months_run_since_cycle_new = mom6_phys_cycle_months_run_since_cycle + stop_n + elif stop_option.find("nyear") == 0: + mom6_phys_cycle_months_run_since_cycle_new = mom6_phys_cycle_months_run_since_cycle + stop_n * 12 + + expect(mom6_phys_cycle_months_run_since_cycle_new <= mom6_phys_cycle_years_in_cycle * 12, + "run will overshoot phys_cycle run length") + + # ------------------------------------------------------------------------- + # If this is the beginning of a physics cycle, store a copy of MOM6 rpointer + # files for resetting of model physics at beginning of next cycle. This + # is not necessary for startup runs, since MOM6 does not use restart files + # at the beginning of the physics cycle in that situation. + # ------------------------------------------------------------------------- + + if (run_type != "startup") and (mom6_phys_cycle_months_run_since_cycle == 0): + logger.info("Beginning of a physics cycle") + logger.info("Storing a copy of MOM6 rpointer files for resetting model physics") + rundir = case.get_value("RUNDIR") + caseroot = case.get_value("CASEROOT") + + for rpointer_filename in [ "rpointer.ocn.restart", "rpointer.ocn.ovf" ]: + sfile = os.path.join(rundir, rpointer_filename) + dfile = os.path.join(caseroot, "Buildconf", "momconf", rpointer_filename+".orig") + expect(os.path.isfile(sfile), "required mom6 file %s is missing" % sfile) + shutil.copy(sfile, dfile) + +############################################################################### + +if __name__ == "__main__": + expect(len(sys.argv) == 2, "caseroot is a required input argument") + caseroot = sys.argv[1] + phys_cycle_prerun(caseroot) From 4c8902297561a8dcf38f98c8e6224c43a6e8fba7 Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Sat, 11 Jul 2026 21:35:03 -0600 Subject: [PATCH 02/14] continued phys_cycle implementation remove MOM6_PASSIVE_TRACER_RESTART_OVERRIDE and rpointer file manipulation --- cime_config/phys_cycle_postrun | 15 --------------- cime_config/phys_cycle_prerun | 19 ------------------- 2 files changed, 34 deletions(-) diff --git a/cime_config/phys_cycle_postrun b/cime_config/phys_cycle_postrun index 5df6a66e..b9e490cc 100755 --- a/cime_config/phys_cycle_postrun +++ b/cime_config/phys_cycle_postrun @@ -57,7 +57,6 @@ def phys_cycle_postrun(caseroot): mom6_phys_cycle_months_in_cycle = mom6_phys_cycle_years_in_cycle * 12 if mom6_phys_cycle_months_run_since_cycle_new < mom6_phys_cycle_months_in_cycle: case.set_value("CONTINUE_RUN", "TRUE") - case.set_value("MOM6_PASSIVE_TRACER_RESTART_OVERRIDE", "none") case.flush() return @@ -74,9 +73,6 @@ def phys_cycle_postrun(caseroot): case.set_value("CONTINUE_RUN", "FALSE") case.set_value("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE", 0) - with open(os.path.join(rundir, "rpointer.ocn.restart"),'r') as f: - case.set_value("MOM6_PASSIVE_TRACER_RESTART_OVERRIDE", os.path.join(rundir, f.readline())) - # ------------------------------------------------------------------------- # Compute new RUN_STARTDATE # ------------------------------------------------------------------------- @@ -99,17 +95,6 @@ def phys_cycle_postrun(caseroot): case.flush() - # ------------------------------------------------------------------------- - # re-prestage MOM6 rpointer files if necessary - # ------------------------------------------------------------------------- - - if run_type != "startup": - for rpointer_filename in [ "rpointer.ocn.restart", "rpointer.ocn.ovf" ]: - sfile = os.path.join(caseroot, "Buildconf", "momconf", rpointer_filename+".orig") - dfile = os.path.join(rundir, rpointer_filename) - expect(os.path.isfile(sfile), "required mom6 file %s is missing" % sfile) - shutil.copy(sfile, dfile) - ############################################################################### if __name__ == "__main__": diff --git a/cime_config/phys_cycle_prerun b/cime_config/phys_cycle_prerun index 24557897..34149357 100755 --- a/cime_config/phys_cycle_prerun +++ b/cime_config/phys_cycle_prerun @@ -65,25 +65,6 @@ def phys_cycle_prerun(caseroot): expect(mom6_phys_cycle_months_run_since_cycle_new <= mom6_phys_cycle_years_in_cycle * 12, "run will overshoot phys_cycle run length") - # ------------------------------------------------------------------------- - # If this is the beginning of a physics cycle, store a copy of MOM6 rpointer - # files for resetting of model physics at beginning of next cycle. This - # is not necessary for startup runs, since MOM6 does not use restart files - # at the beginning of the physics cycle in that situation. - # ------------------------------------------------------------------------- - - if (run_type != "startup") and (mom6_phys_cycle_months_run_since_cycle == 0): - logger.info("Beginning of a physics cycle") - logger.info("Storing a copy of MOM6 rpointer files for resetting model physics") - rundir = case.get_value("RUNDIR") - caseroot = case.get_value("CASEROOT") - - for rpointer_filename in [ "rpointer.ocn.restart", "rpointer.ocn.ovf" ]: - sfile = os.path.join(rundir, rpointer_filename) - dfile = os.path.join(caseroot, "Buildconf", "momconf", rpointer_filename+".orig") - expect(os.path.isfile(sfile), "required mom6 file %s is missing" % sfile) - shutil.copy(sfile, dfile) - ############################################################################### if __name__ == "__main__": From 6115888676f7d7ae3cea94f7b21fda9cf7bf9d0c Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Fri, 31 Jul 2026 15:45:23 -0600 Subject: [PATCH 03/14] updates to phys_cycle implementation --- cime_config/phys_cycle_postrun | 22 ++++++---- cime_config/phys_cycle_prerun | 8 +++- param_templates/MOM_input.yaml | 63 ++++++++++++++++++++++++----- param_templates/json/MOM_input.json | 51 ++++++++++++++++++----- 4 files changed, 112 insertions(+), 32 deletions(-) diff --git a/cime_config/phys_cycle_postrun b/cime_config/phys_cycle_postrun index b9e490cc..b5ebde77 100755 --- a/cime_config/phys_cycle_postrun +++ b/cime_config/phys_cycle_postrun @@ -8,7 +8,7 @@ import os, shutil, sys _CIMEROOT = os.environ.get("CIMEROOT") if _CIMEROOT is None: raise SystemExit("ERROR: must set CIMEROOT environment variable") -sys.path.append(os.path.join(_CIMEROOT, "scripts", "Tools")) +sys.path.append(os.path.join(_CIMEROOT, "CIME", "Tools")) from standard_script_setup import * from CIME.case import Case @@ -24,7 +24,7 @@ def phys_cycle_postrun(caseroot): ch.setLevel(logging.INFO) logger.addHandler(ch) - with Case(caseroot) as case: + with Case(caseroot, read_only=False) as case: mom6_phys_cycle_years_in_cycle = case.get_value("MOM6_PHYS_CYCLE_YEARS_IN_CYCLE") expect(mom6_phys_cycle_years_in_cycle is not None, "MOM6_PHYS_CYCLE_YEARS_IN_CYCLE should be defined when %s is called" % sys.argv[0]) @@ -84,14 +84,20 @@ def phys_cycle_postrun(caseroot): case.set_value("RUN_STARTDATE", run_startdate) # ------------------------------------------------------------------------- - # Compute new _CPLHIST_YR_ALIGN variables + # Update CPLHIST ALIGN variables # ------------------------------------------------------------------------- - for align_varname in [ "DATM_CPLHIST_YR_ALIGN", "DROF_CPLHIST_YR_ALIGN" ]: - align_val = case.get_value(align_varname) - if align_val is not None: - align_val = align_val + mom6_phys_cycle_years_in_cycle - case.set_value(align_varname, align_val) + varnames_dict = { + 'DATM_MODE': 'DATM_CPLHIST_YR_ALIGN', + 'DROF_MODE': 'DROF_CPLHIST_YR_ALIGN' + } + for mode_varname in varnames_dict: + if case.get_value(mode_varname) == "CPLHIST": + align_varname = varnames_dict[mode_varname] + align_val = case.get_value(align_varname) + if align_val is not None: + align_val = align_val + mom6_phys_cycle_years_in_cycle + case.set_value(align_varname, align_val) case.flush() diff --git a/cime_config/phys_cycle_prerun b/cime_config/phys_cycle_prerun index 34149357..3e0451c4 100755 --- a/cime_config/phys_cycle_prerun +++ b/cime_config/phys_cycle_prerun @@ -8,7 +8,7 @@ import os, shutil, sys _CIMEROOT = os.environ.get("CIMEROOT") if _CIMEROOT is None: raise SystemExit("ERROR: must set CIMEROOT environment variable") -sys.path.append(os.path.join(_CIMEROOT, "scripts", "Tools")) +sys.path.append(os.path.join(_CIMEROOT, "CIME", "Tools")) from standard_script_setup import * from CIME.case import Case @@ -24,7 +24,7 @@ def phys_cycle_prerun(caseroot): ch.setLevel(logging.INFO) logger.addHandler(ch) - with Case(caseroot) as case: + with Case(caseroot, read_only=False) as case: mom6_phys_cycle_years_in_cycle = case.get_value("MOM6_PHYS_CYCLE_YEARS_IN_CYCLE") expect(mom6_phys_cycle_years_in_cycle is not None, "MOM6_PHYS_CYCLE_YEARS_IN_CYCLE should be defined when %s is called" % sys.argv[0]) @@ -43,6 +43,10 @@ def phys_cycle_prerun(caseroot): expect((stop_option.find("nmonth") == 0) or (stop_option.find("nyear") == 0), "STOP_OPTION=%s not implemented for MOM6 physics cycling" % stop_option) + # implementation currently requires DOUT_S=FALSE + expect(case.get_value("DOUT_S") == False, + "PHYS_CYCLE implementation assumes DOUT_S=FALSE, to locate MARBL_TRACERS_IC_FILE") + # ------------------------------------------------------------------------- # Ensure that phys_cycle scripts are in charge of setting CONTINUE_RUN # ------------------------------------------------------------------------- diff --git a/param_templates/MOM_input.yaml b/param_templates/MOM_input.yaml index 83335d69..2c8a36ef 100644 --- a/param_templates/MOM_input.yaml +++ b/param_templates/MOM_input.yaml @@ -355,11 +355,14 @@ Global: for the MARBL tracer package." datatype: string value: - $RUN_TYPE == "hybrid": - = f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc' + $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: + = f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc' else: - $MARBL_CONFIG == "latest": ${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc - $MARBL_CONFIG == "latest+4p2z": ${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc + $RUN_TYPE == "hybrid": + = f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc' + else: + $MARBL_CONFIG == "latest": ${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc + $MARBL_CONFIG == "latest+4p2z": ${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc MARBL_TRACERS_IC_FILE_IS_Z: description: | "[Boolean] default = True @@ -367,7 +370,17 @@ Global: datatype: logical units: Boolean value: - $RUN_TYPE == "hybrid": False + $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: True + else: + $RUN_TYPE == "hybrid": False + MARBL_TRACERS_INIT_VERTICAL_REMAP_ONLY: + description: | + "[Boolean] default = False + If true, initial conditions are on the model horizontal grid." + datatype: logical + units: Boolean + value: + $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: True MARBL_IC_MIN_VAL: description: | "Minimum value of tracer initial conditions @@ -1408,9 +1421,12 @@ Global: For each coordinate, an entry in DIAG_COORDS must be provided." datatype: integer value: - $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: 2 - $OCN_GRID == "tx2_0v1": 1 - $OCN_GRID == "tx0.25v1": 1 + $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: + $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: 3 + else: + $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: 2 + $OCN_GRID == "tx2_0v1": 1 + $OCN_GRID == "tx0.25v1": 1 DIAG_COORDS: description: | "A list of string tuples associating diag_table modules to @@ -1418,9 +1434,12 @@ Global: is of the form MODULE_SUFFIX,PARAMETER_SUFFIX,COORDINATE_NAME." datatype: string value: - $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: '"z Z ZSTAR", "rho2 RHO2 RHO"' - $OCN_GRID == "tx2_0v1": '"z Z ZSTAR"' - $OCN_GRID == "tx0.25v1": '"z Z ZSTAR"' + $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: + $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: '"z Z ZSTAR", "rho2 RHO2 RHO", "z2023 Z2023 ZSTAR"' + else: + $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: '"z Z ZSTAR", "rho2 RHO2 RHO"' + $OCN_GRID == "tx2_0v1": '"z Z ZSTAR"' + $OCN_GRID == "tx0.25v1": '"z Z ZSTAR"' DIAG_COORD_DEF_RHO2: description: | " default = 'WOA09' @@ -1432,6 +1451,8 @@ Global: by a comma or space, e.g. FILE:lev.nc,dz or FILE:lev.nc,interfaces=zw WOA09[:N] - the WOA09 vertical grid (approximately) + WOA09INT[:N] - layers spanned by the WOA09 depths + WOA23INT[:N] - layers spanned by the WOA23 depths FNC1:string - FNC1:dz_min,H_total,power,precision HYBRID:string - read from a file. The string specifies the filename and two variable names, separated @@ -1440,6 +1461,26 @@ Global: datatype: string value: $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: '"FILE:ocean_rho2_190917.nc,interfaces=rho2"' + DIAG_COORD_DEF_Z2023: + description: | + " default = 'WOA09' + Determines how to specify the coordinate resolution. Valid options are: + PARAM - use the vector-parameter DIAG_COORD_RES_RHO2 + UNIFORM[:N] - uniformly distributed + FILE:string - read from a file. The string specifies + the filename and variable name, separated + by a comma or space, e.g. FILE:lev.nc,dz + or FILE:lev.nc,interfaces=zw + WOA09[:N] - the WOA09 vertical grid (approximately) + WOA09INT[:N] - layers spanned by the WOA09 depths + WOA23INT[:N] - layers spanned by the WOA23 depths + FNC1:string - FNC1:dz_min,H_total,power,precision + HYBRID:string - read from a file. The string specifies + the filename and two variable names, separated + by a comma or space, for sigma-2 and dz. e.g. + HYBRID:vgrid.nc,sigma2,dz" + datatype: string + value: WOA23INT DIAG_MISVAL: description: | "TODO" diff --git a/param_templates/json/MOM_input.json b/param_templates/json/MOM_input.json index dba1d1bc..c157eac9 100644 --- a/param_templates/json/MOM_input.json +++ b/param_templates/json/MOM_input.json @@ -258,10 +258,13 @@ "description": "\"Name of file containing initial conditions\nfor the MARBL tracer package.\"\n", "datatype": "string", "value": { - "$RUN_TYPE == \"hybrid\"": "= f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc'", + "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": "= f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc'", "else": { - "$MARBL_CONFIG == \"latest\"": "${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc", - "$MARBL_CONFIG == \"latest+4p2z\"": "${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc" + "$RUN_TYPE == \"hybrid\"": "= f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc'", + "else": { + "$MARBL_CONFIG == \"latest\"": "${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc", + "$MARBL_CONFIG == \"latest+4p2z\"": "${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc" + } } } }, @@ -270,7 +273,18 @@ "datatype": "logical", "units": "Boolean", "value": { - "$RUN_TYPE == \"hybrid\"": false + "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": true, + "else": { + "$RUN_TYPE == \"hybrid\"": false + } + } + }, + "MARBL_TRACERS_INIT_VERTICAL_REMAP_ONLY": { + "description": "\"[Boolean] default = False\nIf true, initial conditions are on the model horizontal grid.\"\n", + "datatype": "logical", + "units": "Boolean", + "value": { + "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": true } }, "MARBL_IC_MIN_VAL": { @@ -1111,27 +1125,42 @@ "description": "\" The number of diagnostic vertical coordinates to use.\nFor each coordinate, an entry in DIAG_COORDS must be provided.\"\n", "datatype": "integer", "value": { - "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": 2, - "$OCN_GRID == \"tx2_0v1\"": 1, - "$OCN_GRID == \"tx0.25v1\"": 1 + "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": { + "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": 3 + }, + "else": { + "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": 2, + "$OCN_GRID == \"tx2_0v1\"": 1, + "$OCN_GRID == \"tx0.25v1\"": 1 + } } }, "DIAG_COORDS": { "description": "\"A list of string tuples associating diag_table modules to\na coordinate definition used for diagnostics. Each string\nis of the form MODULE_SUFFIX,PARAMETER_SUFFIX,COORDINATE_NAME.\"\n", "datatype": "string", "value": { - "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": "\"z Z ZSTAR\", \"rho2 RHO2 RHO\"", - "$OCN_GRID == \"tx2_0v1\"": "\"z Z ZSTAR\"", - "$OCN_GRID == \"tx0.25v1\"": "\"z Z ZSTAR\"" + "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": { + "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": "\"z Z ZSTAR\", \"rho2 RHO2 RHO\", \"z2023 Z2023 ZSTAR\"" + }, + "else": { + "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": "\"z Z ZSTAR\", \"rho2 RHO2 RHO\"", + "$OCN_GRID == \"tx2_0v1\"": "\"z Z ZSTAR\"", + "$OCN_GRID == \"tx0.25v1\"": "\"z Z ZSTAR\"" + } } }, "DIAG_COORD_DEF_RHO2": { - "description": "\" default = 'WOA09'\nDetermines how to specify the coordinate resolution. Valid options are:\nPARAM - use the vector-parameter DIAG_COORD_RES_RHO2\nUNIFORM[:N] - uniformly distributed\nFILE:string - read from a file. The string specifies\nthe filename and variable name, separated\nby a comma or space, e.g. FILE:lev.nc,dz\nor FILE:lev.nc,interfaces=zw\nWOA09[:N] - the WOA09 vertical grid (approximately)\nFNC1:string - FNC1:dz_min,H_total,power,precision\nHYBRID:string - read from a file. The string specifies\nthe filename and two variable names, separated\nby a comma or space, for sigma-2 and dz. e.g.\nHYBRID:vgrid.nc,sigma2,dz\"\n", + "description": "\" default = 'WOA09'\nDetermines how to specify the coordinate resolution. Valid options are:\nPARAM - use the vector-parameter DIAG_COORD_RES_RHO2\nUNIFORM[:N] - uniformly distributed\nFILE:string - read from a file. The string specifies\nthe filename and variable name, separated\nby a comma or space, e.g. FILE:lev.nc,dz\nor FILE:lev.nc,interfaces=zw\nWOA09[:N] - the WOA09 vertical grid (approximately)\nWOA09INT[:N] - layers spanned by the WOA09 depths\nWOA23INT[:N] - layers spanned by the WOA23 depths\nFNC1:string - FNC1:dz_min,H_total,power,precision\nHYBRID:string - read from a file. The string specifies\nthe filename and two variable names, separated\nby a comma or space, for sigma-2 and dz. e.g.\nHYBRID:vgrid.nc,sigma2,dz\"\n", "datatype": "string", "value": { "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": "\"FILE:ocean_rho2_190917.nc,interfaces=rho2\"" } }, + "DIAG_COORD_DEF_Z2023": { + "description": "\" default = 'WOA09'\nDetermines how to specify the coordinate resolution. Valid options are:\nPARAM - use the vector-parameter DIAG_COORD_RES_RHO2\nUNIFORM[:N] - uniformly distributed\nFILE:string - read from a file. The string specifies\nthe filename and variable name, separated\nby a comma or space, e.g. FILE:lev.nc,dz\nor FILE:lev.nc,interfaces=zw\nWOA09[:N] - the WOA09 vertical grid (approximately)\nWOA09INT[:N] - layers spanned by the WOA09 depths\nWOA23INT[:N] - layers spanned by the WOA23 depths\nFNC1:string - FNC1:dz_min,H_total,power,precision\nHYBRID:string - read from a file. The string specifies\nthe filename and two variable names, separated\nby a comma or space, for sigma-2 and dz. e.g.\nHYBRID:vgrid.nc,sigma2,dz\"\n", + "datatype": "string", + "value": "WOA23INT" + }, "DIAG_MISVAL": { "description": "\"TODO\"\n", "datatype": "real", From 2b47811d3c34e07ba5844dc127ee160e213dbacf Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Mon, 3 Aug 2026 10:42:44 -0600 Subject: [PATCH 04/14] phys_cycle code cleanup --- cime_config/phys_cycle_postrun | 39 +++++++++++++++++++--------------- cime_config/phys_cycle_prerun | 31 ++++++++++++++++----------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/cime_config/phys_cycle_postrun b/cime_config/phys_cycle_postrun index b5ebde77..6bbfea6a 100755 --- a/cime_config/phys_cycle_postrun +++ b/cime_config/phys_cycle_postrun @@ -3,7 +3,9 @@ """mom6 physics cycle postrun script """ -import os, shutil, sys +import logging +import os +import sys _CIMEROOT = os.environ.get("CIMEROOT") if _CIMEROOT is None: @@ -27,32 +29,36 @@ def phys_cycle_postrun(caseroot): with Case(caseroot, read_only=False) as case: mom6_phys_cycle_years_in_cycle = case.get_value("MOM6_PHYS_CYCLE_YEARS_IN_CYCLE") expect(mom6_phys_cycle_years_in_cycle is not None, - "MOM6_PHYS_CYCLE_YEARS_IN_CYCLE should be defined when %s is called" % sys.argv[0]) - if (mom6_phys_cycle_years_in_cycle <= 0): + f"MOM6_PHYS_CYCLE_YEARS_IN_CYCLE should be defined when {sys.argv[0]} is called") + if mom6_phys_cycle_years_in_cycle <= 0: return # ------------------------------------------------------------------------- # Determine if model has run the length of MOM6 physics run cycle length # ------------------------------------------------------------------------- - run_type = case.get_value("RUN_TYPE") stop_option = case.get_value("STOP_OPTION") stop_n = case.get_value("STOP_N") - caseroot = case.get_value("CASEROOT") - rundir = case.get_value("RUNDIR") - mom6_phys_cycle_months_run_since_cycle = case.get_value("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE") - mom6_phys_cycle_years_in_cycle = case.get_value("MOM6_PHYS_CYCLE_YEARS_IN_CYCLE") + mom6_phys_cycle_months_run_since_cycle = case.get_value( + "MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE" + ) # we know from phys_cycle_prerun that stop_option is either "nmonth*" or "nyear*" if stop_option.find("nmonth") == 0: - mom6_phys_cycle_months_run_since_cycle_new = mom6_phys_cycle_months_run_since_cycle + stop_n + mom6_phys_cycle_months_run_since_cycle_new = ( + mom6_phys_cycle_months_run_since_cycle + stop_n + ) if stop_option.find("nyear") == 0: - mom6_phys_cycle_months_run_since_cycle_new = mom6_phys_cycle_months_run_since_cycle + stop_n * 12 + mom6_phys_cycle_months_run_since_cycle_new = ( + mom6_phys_cycle_months_run_since_cycle + stop_n * 12 + ) - case.set_value("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE", mom6_phys_cycle_months_run_since_cycle_new) - logger.info("mom6_phys_cycle_months_run_since_cycle is now %d" % mom6_phys_cycle_months_run_since_cycle_new) + case.set_value("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE", + mom6_phys_cycle_months_run_since_cycle_new) + logger.info("mom6_phys_cycle_months_run_since_cycle_new = %d", + mom6_phys_cycle_months_run_since_cycle_new) mom6_phys_cycle_months_in_cycle = mom6_phys_cycle_years_in_cycle * 12 if mom6_phys_cycle_months_run_since_cycle_new < mom6_phys_cycle_months_in_cycle: @@ -61,8 +67,8 @@ def phys_cycle_postrun(caseroot): return expect(mom6_phys_cycle_months_run_since_cycle_new <= mom6_phys_cycle_months_in_cycle, - "MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE has overshot MOM6_PHYS_CYCLE_MONTHS_IN_CYCLE=%d" - % mom6_phys_cycle_months_in_cycle) + "MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE has overshot " + f"{mom6_phys_cycle_months_in_cycle = }") # ------------------------------------------------------------------------- # Model has run the length of MOM6 physics run cycle length @@ -80,7 +86,7 @@ def phys_cycle_postrun(caseroot): run_startdate = case.get_value("RUN_STARTDATE") yyyy = int(run_startdate[:4]) yyyy = yyyy + mom6_phys_cycle_years_in_cycle - run_startdate = "%04d" % yyyy + run_startdate[4:] + run_startdate = f"{yyyy:04d}{run_startdate[4:]}" case.set_value("RUN_STARTDATE", run_startdate) # ------------------------------------------------------------------------- @@ -91,9 +97,8 @@ def phys_cycle_postrun(caseroot): 'DATM_MODE': 'DATM_CPLHIST_YR_ALIGN', 'DROF_MODE': 'DROF_CPLHIST_YR_ALIGN' } - for mode_varname in varnames_dict: + for mode_varname, align_varname in varnames_dict.items(): if case.get_value(mode_varname) == "CPLHIST": - align_varname = varnames_dict[mode_varname] align_val = case.get_value(align_varname) if align_val is not None: align_val = align_val + mom6_phys_cycle_years_in_cycle diff --git a/cime_config/phys_cycle_prerun b/cime_config/phys_cycle_prerun index 3e0451c4..6045c76e 100755 --- a/cime_config/phys_cycle_prerun +++ b/cime_config/phys_cycle_prerun @@ -3,7 +3,9 @@ """mom6 physics cycle prerun script """ -import os, shutil, sys +import logging +import os +import sys _CIMEROOT = os.environ.get("CIMEROOT") if _CIMEROOT is None: @@ -27,24 +29,23 @@ def phys_cycle_prerun(caseroot): with Case(caseroot, read_only=False) as case: mom6_phys_cycle_years_in_cycle = case.get_value("MOM6_PHYS_CYCLE_YEARS_IN_CYCLE") expect(mom6_phys_cycle_years_in_cycle is not None, - "MOM6_PHYS_CYCLE_YEARS_IN_CYCLE should be defined when %s is called" % sys.argv[0]) - logger.info("mom6_phys_cycle_years_in_cycle is %d", mom6_phys_cycle_years_in_cycle) - if (mom6_phys_cycle_years_in_cycle <= 0): + f"MOM6_PHYS_CYCLE_YEARS_IN_CYCLE should be defined when {sys.argv[0]} is called") + logger.info("mom6_phys_cycle_years_in_cycle = %d", mom6_phys_cycle_years_in_cycle) + if mom6_phys_cycle_years_in_cycle <= 0: return - # run_type cannot be branch - run_type = case.get_value("RUN_TYPE") - expect(run_type != "branch", + # RUN_TYPE cannot be branch + expect(case.get_value("RUN_TYPE") != "branch", "RUN_TYPE set to branch not implemented for MOM6 physics cycling" " because RUN_STARTDATE cannot be incremented") # stop_option must be nmonth, nmonths, nyear or nyears stop_option = case.get_value("STOP_OPTION") expect((stop_option.find("nmonth") == 0) or (stop_option.find("nyear") == 0), - "STOP_OPTION=%s not implemented for MOM6 physics cycling" % stop_option) + f"STOP_OPTION={stop_option} not implemented for MOM6 physics cycling") # implementation currently requires DOUT_S=FALSE - expect(case.get_value("DOUT_S") == False, + expect(not case.get_value("DOUT_S"), "PHYS_CYCLE implementation assumes DOUT_S=FALSE, to locate MARBL_TRACERS_IC_FILE") # ------------------------------------------------------------------------- @@ -57,14 +58,20 @@ def phys_cycle_prerun(caseroot): # Ensure that the current run length will not overshoot the phys_cycle run length # ------------------------------------------------------------------------- - mom6_phys_cycle_months_run_since_cycle = case.get_value("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE") + mom6_phys_cycle_months_run_since_cycle = case.get_value( + "MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE" + ) mom6_phys_cycle_years_in_cycle = case.get_value("MOM6_PHYS_CYCLE_YEARS_IN_CYCLE") stop_n = case.get_value("STOP_N") if stop_option.find("nmonth") == 0: - mom6_phys_cycle_months_run_since_cycle_new = mom6_phys_cycle_months_run_since_cycle + stop_n + mom6_phys_cycle_months_run_since_cycle_new = ( + mom6_phys_cycle_months_run_since_cycle + stop_n + ) elif stop_option.find("nyear") == 0: - mom6_phys_cycle_months_run_since_cycle_new = mom6_phys_cycle_months_run_since_cycle + stop_n * 12 + mom6_phys_cycle_months_run_since_cycle_new = ( + mom6_phys_cycle_months_run_since_cycle + stop_n * 12 + ) expect(mom6_phys_cycle_months_run_since_cycle_new <= mom6_phys_cycle_years_in_cycle * 12, "run will overshoot phys_cycle run length") From eb7978e72fd6f2e7d9da21f1376d7c49ec4188f2 Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Tue, 4 Aug 2026 11:31:15 -0600 Subject: [PATCH 05/14] update phys_cycle_postrun script correct DATM_MODE ALIGN variable add more logging output --- cime_config/phys_cycle_postrun | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cime_config/phys_cycle_postrun b/cime_config/phys_cycle_postrun index 6bbfea6a..9ab584f2 100755 --- a/cime_config/phys_cycle_postrun +++ b/cime_config/phys_cycle_postrun @@ -57,7 +57,7 @@ def phys_cycle_postrun(caseroot): case.set_value("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE", mom6_phys_cycle_months_run_since_cycle_new) - logger.info("mom6_phys_cycle_months_run_since_cycle_new = %d", + logger.info("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE incremented to %d", mom6_phys_cycle_months_run_since_cycle_new) mom6_phys_cycle_months_in_cycle = mom6_phys_cycle_years_in_cycle * 12 @@ -88,13 +88,14 @@ def phys_cycle_postrun(caseroot): yyyy = yyyy + mom6_phys_cycle_years_in_cycle run_startdate = f"{yyyy:04d}{run_startdate[4:]}" case.set_value("RUN_STARTDATE", run_startdate) + logger.info("RUN_STARTDATE incremented to %s", run_startdate) # ------------------------------------------------------------------------- # Update CPLHIST ALIGN variables # ------------------------------------------------------------------------- varnames_dict = { - 'DATM_MODE': 'DATM_CPLHIST_YR_ALIGN', + 'DATM_MODE': 'DATM_YR_ALIGN', 'DROF_MODE': 'DROF_CPLHIST_YR_ALIGN' } for mode_varname, align_varname in varnames_dict.items(): @@ -103,6 +104,7 @@ def phys_cycle_postrun(caseroot): if align_val is not None: align_val = align_val + mom6_phys_cycle_years_in_cycle case.set_value(align_varname, align_val) + logger.info("%s incremented to %d", align_val, align_val) case.flush() From abac57697b4354770621c58d743310c1db87b36c Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Tue, 4 Aug 2026 11:32:41 -0600 Subject: [PATCH 06/14] add DOUT_S=TRUE support to phys_cycle --- cime_config/phys_cycle_prerun | 4 ---- param_templates/MOM_input.yaml | 5 ++++- param_templates/json/MOM_input.json | 5 ++++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cime_config/phys_cycle_prerun b/cime_config/phys_cycle_prerun index 6045c76e..7ce7a6e8 100755 --- a/cime_config/phys_cycle_prerun +++ b/cime_config/phys_cycle_prerun @@ -44,10 +44,6 @@ def phys_cycle_prerun(caseroot): expect((stop_option.find("nmonth") == 0) or (stop_option.find("nyear") == 0), f"STOP_OPTION={stop_option} not implemented for MOM6 physics cycling") - # implementation currently requires DOUT_S=FALSE - expect(not case.get_value("DOUT_S"), - "PHYS_CYCLE implementation assumes DOUT_S=FALSE, to locate MARBL_TRACERS_IC_FILE") - # ------------------------------------------------------------------------- # Ensure that phys_cycle scripts are in charge of setting CONTINUE_RUN # ------------------------------------------------------------------------- diff --git a/param_templates/MOM_input.yaml b/param_templates/MOM_input.yaml index 2c8a36ef..32450e32 100644 --- a/param_templates/MOM_input.yaml +++ b/param_templates/MOM_input.yaml @@ -356,7 +356,10 @@ Global: datatype: string value: $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: - = f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc' + $DOUT_S: + = f'${DOUT_S_ROOT}/ocn/hist/{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc' + else: + = f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc' else: $RUN_TYPE == "hybrid": = f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc' diff --git a/param_templates/json/MOM_input.json b/param_templates/json/MOM_input.json index c157eac9..9382f14d 100644 --- a/param_templates/json/MOM_input.json +++ b/param_templates/json/MOM_input.json @@ -258,7 +258,10 @@ "description": "\"Name of file containing initial conditions\nfor the MARBL tracer package.\"\n", "datatype": "string", "value": { - "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": "= f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc'", + "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": { + "$DOUT_S": "= f'${DOUT_S_ROOT}/ocn/hist/{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc'", + "else": "= f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc'" + }, "else": { "$RUN_TYPE == \"hybrid\"": "= f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc'", "else": { From 68888f23c9534c9e94e02c8c2a3c4515cc2bfd7c Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Tue, 4 Aug 2026 11:49:50 -0600 Subject: [PATCH 07/14] correct phys_cycle_postrun logging argument --- cime_config/phys_cycle_postrun | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cime_config/phys_cycle_postrun b/cime_config/phys_cycle_postrun index 9ab584f2..3ba2eba2 100755 --- a/cime_config/phys_cycle_postrun +++ b/cime_config/phys_cycle_postrun @@ -104,7 +104,7 @@ def phys_cycle_postrun(caseroot): if align_val is not None: align_val = align_val + mom6_phys_cycle_years_in_cycle case.set_value(align_varname, align_val) - logger.info("%s incremented to %d", align_val, align_val) + logger.info("%s incremented to %d", align_varname, align_val) case.flush() From b67a1443cd4f7498cbe4e5d57cf32f5d5dca1cde Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Wed, 5 Aug 2026 08:26:37 -0600 Subject: [PATCH 08/14] make PHYS_CYCLE cases less error-prone for MARBL init add MOM6_PHYS_CYCLE_MARBL_IC_FILE, MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE to env_run.xml to initialize MARBL on firts PHYS_CYCLE cycle set MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE to FALSE in phys_cycle_postrun --- cime_config/config_component.xml | 17 +++++++++++++++++ cime_config/phys_cycle_postrun | 7 +++++++ param_templates/MOM_input.yaml | 10 ++++++---- param_templates/json/MOM_input.json | 9 ++++++--- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 070298fb..9bc33199 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -226,6 +226,23 @@ number of months run since most recent cycling of MOM6 physics + + char + + run_component_mom + env_run.xml + Value to set MOM6's MARBL_TRACERS_IC_FILE to, typically in first PHYS_CYCLE cycle + + + + logical + TRUE,FALSE + TRUE + run_component_mom + env_run.xml + Determine if MOM6's MARBL_TRACERS_IC_FILE is set to MOM6_PHYS_CYCLE_MARBL_IC_FILE + + ========================================= MOM6 naming conventions diff --git a/cime_config/phys_cycle_postrun b/cime_config/phys_cycle_postrun index 3ba2eba2..7c164c15 100755 --- a/cime_config/phys_cycle_postrun +++ b/cime_config/phys_cycle_postrun @@ -33,6 +33,13 @@ def phys_cycle_postrun(caseroot): if mom6_phys_cycle_years_in_cycle <= 0: return + # ------------------------------------------------------------------------- + # Ensure MOM6_PHYS_CYCLE_MARBL_IC_FILE is only used in first PHYS_CYCLE cycle + # ------------------------------------------------------------------------- + + case.set_value("MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE", "FALSE") + case.flush() + # ------------------------------------------------------------------------- # Determine if model has run the length of MOM6 physics run cycle length # ------------------------------------------------------------------------- diff --git a/param_templates/MOM_input.yaml b/param_templates/MOM_input.yaml index 32450e32..5732709b 100644 --- a/param_templates/MOM_input.yaml +++ b/param_templates/MOM_input.yaml @@ -356,10 +356,12 @@ Global: datatype: string value: $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: - $DOUT_S: - = f'${DOUT_S_ROOT}/ocn/hist/{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc' + $MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE: $MOM6_PHYS_CYCLE_MARBL_IC_FILE else: - = f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc' + $DOUT_S: + = f'${DOUT_S_ROOT}/ocn/hist/{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc' + else: + = f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc' else: $RUN_TYPE == "hybrid": = f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc' @@ -373,7 +375,7 @@ Global: datatype: logical units: Boolean value: - $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: True + $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: = not $MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE else: $RUN_TYPE == "hybrid": False MARBL_TRACERS_INIT_VERTICAL_REMAP_ONLY: diff --git a/param_templates/json/MOM_input.json b/param_templates/json/MOM_input.json index 9382f14d..235f6dd7 100644 --- a/param_templates/json/MOM_input.json +++ b/param_templates/json/MOM_input.json @@ -259,8 +259,11 @@ "datatype": "string", "value": { "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": { - "$DOUT_S": "= f'${DOUT_S_ROOT}/ocn/hist/{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc'", - "else": "= f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc'" + "$MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE": "$MOM6_PHYS_CYCLE_MARBL_IC_FILE", + "else": { + "$DOUT_S": "= f'${DOUT_S_ROOT}/ocn/hist/{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc'", + "else": "= f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc'" + } }, "else": { "$RUN_TYPE == \"hybrid\"": "= f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc'", @@ -276,7 +279,7 @@ "datatype": "logical", "units": "Boolean", "value": { - "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": true, + "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": "= not $MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE", "else": { "$RUN_TYPE == \"hybrid\"": false } From 5736b09c7db2635f55812bcb92ab26c55f0e2973 Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Fri, 21 Aug 2026 10:03:46 -0600 Subject: [PATCH 09/14] replace MOM6_PHYS_CYCLE_MARBL_IC_FILE with MOM6_TRACER_IC_FILE_OVERRIDE_POINTER this parameter enables reading tracer ICs from multiple files introduce MARBL_ENFORCE_TRACER_ZINT set these parameters in phys_cycle_postrun update MARBL IC specification in PHYS_CYCLE mode and RUN_TYPE == "hybrid" remove unneeded Z2023 diagnostic coord --- cime_config/config_component.xml | 12 ++--- cime_config/phys_cycle_postrun | 28 ++++++------ param_templates/MOM_input.yaml | 70 ++++++++++------------------- param_templates/json/MOM_input.json | 60 ++++++++++--------------- 4 files changed, 67 insertions(+), 103 deletions(-) diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 9bc33199..97b5ee67 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -226,21 +226,23 @@ number of months run since most recent cycling of MOM6 physics - + char run_component_mom env_run.xml - Value to set MOM6's MARBL_TRACERS_IC_FILE to, typically in first PHYS_CYCLE cycle + File containing tracer IC filenames - + logical TRUE,FALSE - TRUE + FALSE run_component_mom env_run.xml - Determine if MOM6's MARBL_TRACERS_IC_FILE is set to MOM6_PHYS_CYCLE_MARBL_IC_FILE + Rescale MARBL tracers so that their vertical integrals match + their vertical integrals computed from the IC file(s). + diff --git a/cime_config/phys_cycle_postrun b/cime_config/phys_cycle_postrun index 7c164c15..730ca143 100755 --- a/cime_config/phys_cycle_postrun +++ b/cime_config/phys_cycle_postrun @@ -33,15 +33,9 @@ def phys_cycle_postrun(caseroot): if mom6_phys_cycle_years_in_cycle <= 0: return - # ------------------------------------------------------------------------- - # Ensure MOM6_PHYS_CYCLE_MARBL_IC_FILE is only used in first PHYS_CYCLE cycle - # ------------------------------------------------------------------------- - - case.set_value("MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE", "FALSE") - case.flush() - # ------------------------------------------------------------------------- # Determine if model has run the length of MOM6 physics run cycle length + # this assumes that STOP_ options have not been changed during the submission # ------------------------------------------------------------------------- stop_option = case.get_value("STOP_OPTION") @@ -67,19 +61,15 @@ def phys_cycle_postrun(caseroot): logger.info("MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE incremented to %d", mom6_phys_cycle_months_run_since_cycle_new) - mom6_phys_cycle_months_in_cycle = mom6_phys_cycle_years_in_cycle * 12 - if mom6_phys_cycle_months_run_since_cycle_new < mom6_phys_cycle_months_in_cycle: + if mom6_phys_cycle_months_run_since_cycle_new < mom6_phys_cycle_years_in_cycle * 12: case.set_value("CONTINUE_RUN", "TRUE") + case.set_value("MOM6_TRACER_IC_FILE_OVERRIDE_POINTER", "") + case.set_value("MARBL_ENFORCE_TRACER_ZINT", "FALSE") case.flush() return - expect(mom6_phys_cycle_months_run_since_cycle_new <= mom6_phys_cycle_months_in_cycle, - "MOM6_PHYS_CYCLE_MONTHS_RUN_SINCE_CYCLE has overshot " - f"{mom6_phys_cycle_months_in_cycle = }") - # ------------------------------------------------------------------------- - # Model has run the length of MOM6 physics run cycle length - # Reset model physics, keeping restart file for tracers to continue to evolve + # Model has run the length of MOM6 physics run cycle length, reset model physics # ------------------------------------------------------------------------- logger.info("resetting model physics") @@ -97,6 +87,14 @@ def phys_cycle_postrun(caseroot): case.set_value("RUN_STARTDATE", run_startdate) logger.info("RUN_STARTDATE incremented to %s", run_startdate) + # ------------------------------------------------------------------------- + # Configure tracer module initialization for new PHYS_CYCLE cycle + # ------------------------------------------------------------------------- + + case.set_value("MOM6_TRACER_IC_FILE_OVERRIDE_POINTER", + f"./rpointer.ocn.{run_startdate}-00000") + case.set_value("MARBL_ENFORCE_TRACER_ZINT", "TRUE") + # ------------------------------------------------------------------------- # Update CPLHIST ALIGN variables # ------------------------------------------------------------------------- diff --git a/param_templates/MOM_input.yaml b/param_templates/MOM_input.yaml index 5732709b..69a1e7ad 100644 --- a/param_templates/MOM_input.yaml +++ b/param_templates/MOM_input.yaml @@ -355,19 +355,17 @@ Global: for the MARBL tracer package." datatype: string value: - $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: - $MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE: $MOM6_PHYS_CYCLE_MARBL_IC_FILE - else: - $DOUT_S: - = f'${DOUT_S_ROOT}/ocn/hist/{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc' - else: - = f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc' + $MARBL_CONFIG == "latest": ${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc + $MARBL_CONFIG == "latest+4p2z": ${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc + MARBL_TRACERS_IC_FILE_OVERRIDE_POINTER: + description: | + "File containing tracer IC filenames overriding MARBL_TRACERS_IC_FILE." + datatype: string + value: + $MOM6_TRACER_IC_FILE_OVERRIDE_POINTER != "": $MOM6_TRACER_IC_FILE_OVERRIDE_POINTER else: $RUN_TYPE == "hybrid": - = f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc' - else: - $MARBL_CONFIG == "latest": ${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc - $MARBL_CONFIG == "latest+4p2z": ${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc + = f'./rpointer.ocn.{$RUN_REFDATE}-{$RUN_REFTOD}' MARBL_TRACERS_IC_FILE_IS_Z: description: | "[Boolean] default = True @@ -375,9 +373,15 @@ Global: datatype: logical units: Boolean value: - $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: = not $MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE - else: - $RUN_TYPE == "hybrid": False + $RUN_TYPE == "hybrid": False + MARBL_ENFORCE_TRACER_ZINT: + description: | + "Rescale MARBL tracers so that their vertical integrals match + their vertical integrals computed from the IC file(s). + Value is determined by MARBL_ENFORCE_TRACER_ZINT in env_run.xml" + datatype: logical + units: Boolean + value: $MARBL_ENFORCE_TRACER_ZINT MARBL_TRACERS_INIT_VERTICAL_REMAP_ONLY: description: | "[Boolean] default = False @@ -1426,12 +1430,9 @@ Global: For each coordinate, an entry in DIAG_COORDS must be provided." datatype: integer value: - $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: - $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: 3 - else: - $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: 2 - $OCN_GRID == "tx2_0v1": 1 - $OCN_GRID == "tx0.25v1": 1 + $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: 2 + $OCN_GRID == "tx2_0v1": 1 + $OCN_GRID == "tx0.25v1": 1 DIAG_COORDS: description: | "A list of string tuples associating diag_table modules to @@ -1439,12 +1440,9 @@ Global: is of the form MODULE_SUFFIX,PARAMETER_SUFFIX,COORDINATE_NAME." datatype: string value: - $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: - $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: '"z Z ZSTAR", "rho2 RHO2 RHO", "z2023 Z2023 ZSTAR"' - else: - $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: '"z Z ZSTAR", "rho2 RHO2 RHO"' - $OCN_GRID == "tx2_0v1": '"z Z ZSTAR"' - $OCN_GRID == "tx0.25v1": '"z Z ZSTAR"' + $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: '"z Z ZSTAR", "rho2 RHO2 RHO"' + $OCN_GRID == "tx2_0v1": '"z Z ZSTAR"' + $OCN_GRID == "tx0.25v1": '"z Z ZSTAR"' DIAG_COORD_DEF_RHO2: description: | " default = 'WOA09' @@ -1466,26 +1464,6 @@ Global: datatype: string value: $OCN_GRID in ["tx2_3v2", "tx2_3v3"]: '"FILE:ocean_rho2_190917.nc,interfaces=rho2"' - DIAG_COORD_DEF_Z2023: - description: | - " default = 'WOA09' - Determines how to specify the coordinate resolution. Valid options are: - PARAM - use the vector-parameter DIAG_COORD_RES_RHO2 - UNIFORM[:N] - uniformly distributed - FILE:string - read from a file. The string specifies - the filename and variable name, separated - by a comma or space, e.g. FILE:lev.nc,dz - or FILE:lev.nc,interfaces=zw - WOA09[:N] - the WOA09 vertical grid (approximately) - WOA09INT[:N] - layers spanned by the WOA09 depths - WOA23INT[:N] - layers spanned by the WOA23 depths - FNC1:string - FNC1:dz_min,H_total,power,precision - HYBRID:string - read from a file. The string specifies - the filename and two variable names, separated - by a comma or space, for sigma-2 and dz. e.g. - HYBRID:vgrid.nc,sigma2,dz" - datatype: string - value: WOA23INT DIAG_MISVAL: description: | "TODO" diff --git a/param_templates/json/MOM_input.json b/param_templates/json/MOM_input.json index 235f6dd7..9a40c8e1 100644 --- a/param_templates/json/MOM_input.json +++ b/param_templates/json/MOM_input.json @@ -258,19 +258,17 @@ "description": "\"Name of file containing initial conditions\nfor the MARBL tracer package.\"\n", "datatype": "string", "value": { - "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": { - "$MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE": "$MOM6_PHYS_CYCLE_MARBL_IC_FILE", - "else": { - "$DOUT_S": "= f'${DOUT_S_ROOT}/ocn/hist/{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc'", - "else": "= f'./{$CASE}.mom6{$INST_SUFFIX}.h.bgc.tracers.z.{$RUN_STARTDATE}.nc'" - } - }, + "$MARBL_CONFIG == \"latest\"": "${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc", + "$MARBL_CONFIG == \"latest+4p2z\"": "${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc" + } + }, + "MARBL_TRACERS_IC_FILE_OVERRIDE_POINTER": { + "description": "\"File containing tracer IC filenames overriding MARBL_TRACERS_IC_FILE.\"\n", + "datatype": "string", + "value": { + "$MOM6_TRACER_IC_FILE_OVERRIDE_POINTER != \"\"": "$MOM6_TRACER_IC_FILE_OVERRIDE_POINTER", "else": { - "$RUN_TYPE == \"hybrid\"": "= f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc'", - "else": { - "$MARBL_CONFIG == \"latest\"": "${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc", - "$MARBL_CONFIG == \"latest+4p2z\"": "${DIN_LOC_ROOT}/ocn/mom/grid_indpt/ecosys_jan_IC_omip_latlon_1x1_180W_c250613.nc" - } + "$RUN_TYPE == \"hybrid\"": "= f'./rpointer.ocn.{$RUN_REFDATE}-{$RUN_REFTOD}'" } } }, @@ -279,12 +277,15 @@ "datatype": "logical", "units": "Boolean", "value": { - "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": "= not $MOM6_PHYS_CYCLE_USE_MARBL_IC_FILE", - "else": { - "$RUN_TYPE == \"hybrid\"": false - } + "$RUN_TYPE == \"hybrid\"": false } }, + "MARBL_ENFORCE_TRACER_ZINT": { + "description": "\"Rescale MARBL tracers so that their vertical integrals match\n their vertical integrals computed from the IC file(s).\n Value is determined by MARBL_ENFORCE_TRACER_ZINT in env_run.xml\"\n", + "datatype": "logical", + "units": "Boolean", + "value": "$MARBL_ENFORCE_TRACER_ZINT" + }, "MARBL_TRACERS_INIT_VERTICAL_REMAP_ONLY": { "description": "\"[Boolean] default = False\nIf true, initial conditions are on the model horizontal grid.\"\n", "datatype": "logical", @@ -1131,28 +1132,18 @@ "description": "\" The number of diagnostic vertical coordinates to use.\nFor each coordinate, an entry in DIAG_COORDS must be provided.\"\n", "datatype": "integer", "value": { - "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": { - "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": 3 - }, - "else": { - "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": 2, - "$OCN_GRID == \"tx2_0v1\"": 1, - "$OCN_GRID == \"tx0.25v1\"": 1 - } + "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": 2, + "$OCN_GRID == \"tx2_0v1\"": 1, + "$OCN_GRID == \"tx0.25v1\"": 1 } }, "DIAG_COORDS": { "description": "\"A list of string tuples associating diag_table modules to\na coordinate definition used for diagnostics. Each string\nis of the form MODULE_SUFFIX,PARAMETER_SUFFIX,COORDINATE_NAME.\"\n", "datatype": "string", "value": { - "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": { - "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": "\"z Z ZSTAR\", \"rho2 RHO2 RHO\", \"z2023 Z2023 ZSTAR\"" - }, - "else": { - "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": "\"z Z ZSTAR\", \"rho2 RHO2 RHO\"", - "$OCN_GRID == \"tx2_0v1\"": "\"z Z ZSTAR\"", - "$OCN_GRID == \"tx0.25v1\"": "\"z Z ZSTAR\"" - } + "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": "\"z Z ZSTAR\", \"rho2 RHO2 RHO\"", + "$OCN_GRID == \"tx2_0v1\"": "\"z Z ZSTAR\"", + "$OCN_GRID == \"tx0.25v1\"": "\"z Z ZSTAR\"" } }, "DIAG_COORD_DEF_RHO2": { @@ -1162,11 +1153,6 @@ "$OCN_GRID in [\"tx2_3v2\", \"tx2_3v3\"]": "\"FILE:ocean_rho2_190917.nc,interfaces=rho2\"" } }, - "DIAG_COORD_DEF_Z2023": { - "description": "\" default = 'WOA09'\nDetermines how to specify the coordinate resolution. Valid options are:\nPARAM - use the vector-parameter DIAG_COORD_RES_RHO2\nUNIFORM[:N] - uniformly distributed\nFILE:string - read from a file. The string specifies\nthe filename and variable name, separated\nby a comma or space, e.g. FILE:lev.nc,dz\nor FILE:lev.nc,interfaces=zw\nWOA09[:N] - the WOA09 vertical grid (approximately)\nWOA09INT[:N] - layers spanned by the WOA09 depths\nWOA23INT[:N] - layers spanned by the WOA23 depths\nFNC1:string - FNC1:dz_min,H_total,power,precision\nHYBRID:string - read from a file. The string specifies\nthe filename and two variable names, separated\nby a comma or space, for sigma-2 and dz. e.g.\nHYBRID:vgrid.nc,sigma2,dz\"\n", - "datatype": "string", - "value": "WOA23INT" - }, "DIAG_MISVAL": { "description": "\"TODO\"\n", "datatype": "real", From a32d8e964896804b01639fe58f082dc462c57113 Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Sat, 22 Aug 2026 14:49:14 -0600 Subject: [PATCH 10/14] generalize ideal age initialization set AGE_IC_FILE_OVERRIDE_POINTER to MOM6_TRACER_IC_FILE_OVERRIDE_POINTER, when it is set, or to rpointer file if RUN_TYPE=hybrid --- param_templates/MOM_input.yaml | 11 ++++++----- param_templates/json/MOM_input.json | 9 ++++++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/param_templates/MOM_input.yaml b/param_templates/MOM_input.yaml index 69a1e7ad..179a0df2 100644 --- a/param_templates/MOM_input.yaml +++ b/param_templates/MOM_input.yaml @@ -3420,14 +3420,15 @@ Global: value: $RUN_TYPE == "hybrid": = f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc' - AGE_IC_FILE: + AGE_IC_FILE_OVERRIDE_POINTER: description: | - "The file in which the age-tracer initial values can be found, or an empty - string for internal initialization." + "File containing tracer IC filenames overriding AGE_IC_FILE." datatype: string value: - $RUN_TYPE == "hybrid" and $CONTINUE_RUN == False: - = f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc' + $MOM6_TRACER_IC_FILE_OVERRIDE_POINTER != "": $MOM6_TRACER_IC_FILE_OVERRIDE_POINTER + else: + $RUN_TYPE == "hybrid": + = f'./rpointer.ocn.{$RUN_REFDATE}-{$RUN_REFTOD}' T_REF: description: | "[degC] diff --git a/param_templates/json/MOM_input.json b/param_templates/json/MOM_input.json index 9a40c8e1..2e22363b 100644 --- a/param_templates/json/MOM_input.json +++ b/param_templates/json/MOM_input.json @@ -2790,11 +2790,14 @@ "$RUN_TYPE == \"hybrid\"": "= f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc'" } }, - "AGE_IC_FILE": { - "description": "\"The file in which the age-tracer initial values can be found, or an empty\nstring for internal initialization.\"\n", + "AGE_IC_FILE_OVERRIDE_POINTER": { + "description": "\"File containing tracer IC filenames overriding AGE_IC_FILE.\"\n", "datatype": "string", "value": { - "$RUN_TYPE == \"hybrid\" and $CONTINUE_RUN == False": "= f'./{$RUN_REFCASE}.mom6{$INST_SUFFIX}.r.{$RUN_REFDATE}-{$RUN_REFTOD}.nc'" + "$MOM6_TRACER_IC_FILE_OVERRIDE_POINTER != \"\"": "$MOM6_TRACER_IC_FILE_OVERRIDE_POINTER", + "else": { + "$RUN_TYPE == \"hybrid\"": "= f'./rpointer.ocn.{$RUN_REFDATE}-{$RUN_REFTOD}'" + } } }, "T_REF": { From d8f9756d30cc9caefd6618b78d4e689404ab769b Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Thu, 3 Sep 2026 15:06:07 -0600 Subject: [PATCH 11/14] comment JRA PHYS_CYCLE compset, as it doesn't work correctly --- cime_config/config_compsets.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cime_config/config_compsets.xml b/cime_config/config_compsets.xml index d7512fd3..e57bcbb3 100644 --- a/cime_config/config_compsets.xml +++ b/cime_config/config_compsets.xml @@ -115,10 +115,12 @@ 1850_DATM%JRA-1p5-2023_SLND_CICE_MOM6%MARBL-BIO_DROF%JRA-1p5-2023_SGLC_WW3 + GW1850MARBL_CPLHIST From 2955556e2c3e19e8349e2d4f11f055bd0acc0319 Mon Sep 17 00:00:00 2001 From: Keith Lindsay Date: Fri, 4 Sep 2026 15:47:12 -0600 Subject: [PATCH 12/14] set REMAP_NON_Z_IC params to true in PHYS_CYCLE cases --- param_templates/MOM_input.yaml | 18 ++++++++++++++++++ param_templates/json/MOM_input.json | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/param_templates/MOM_input.yaml b/param_templates/MOM_input.yaml index 179a0df2..9f0862d1 100644 --- a/param_templates/MOM_input.yaml +++ b/param_templates/MOM_input.yaml @@ -374,6 +374,15 @@ Global: units: Boolean value: $RUN_TYPE == "hybrid": False + MARBL_REMAP_NON_Z_IC: + description: | + "[Boolean] default = False + If true, and MARBL_IC_FILE_IS_Z is false, + then remap IC vals to current model thicknesses." + datatype: logical + units: Boolean + value: + $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: True MARBL_ENFORCE_TRACER_ZINT: description: | "Rescale MARBL tracers so that their vertical integrals match @@ -3429,6 +3438,15 @@ Global: else: $RUN_TYPE == "hybrid": = f'./rpointer.ocn.{$RUN_REFDATE}-{$RUN_REFTOD}' + AGE_REMAP_NON_Z_IC: + description: | + "[Boolean] default = False + If true, and AGE_IC_FILE_IS_Z is false, + then remap IC vals to current model thicknesses." + datatype: logical + units: Boolean + value: + $MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0: True T_REF: description: | "[degC] diff --git a/param_templates/json/MOM_input.json b/param_templates/json/MOM_input.json index 2e22363b..2e721175 100644 --- a/param_templates/json/MOM_input.json +++ b/param_templates/json/MOM_input.json @@ -280,6 +280,14 @@ "$RUN_TYPE == \"hybrid\"": false } }, + "MARBL_REMAP_NON_Z_IC": { + "description": "\"[Boolean] default = False\nIf true, and MARBL_IC_FILE_IS_Z is false,\nthen remap IC vals to current model thicknesses.\"\n", + "datatype": "logical", + "units": "Boolean", + "value": { + "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": true + } + }, "MARBL_ENFORCE_TRACER_ZINT": { "description": "\"Rescale MARBL tracers so that their vertical integrals match\n their vertical integrals computed from the IC file(s).\n Value is determined by MARBL_ENFORCE_TRACER_ZINT in env_run.xml\"\n", "datatype": "logical", @@ -2800,6 +2808,14 @@ } } }, + "AGE_REMAP_NON_Z_IC": { + "description": "\"[Boolean] default = False\nIf true, and AGE_IC_FILE_IS_Z is false,\nthen remap IC vals to current model thicknesses.\"\n", + "datatype": "logical", + "units": "Boolean", + "value": { + "$MOM6_PHYS_CYCLE_YEARS_IN_CYCLE > 0": true + } + }, "T_REF": { "description": "\"[degC]\nA reference temperature used in initialization.\"\n", "datatype": "real", From ee8e0ea7d27d3a52a497ab4dc9a00bbc4b50168d Mon Sep 17 00:00:00 2001 From: Michael Levy Date: Tue, 8 Sep 2026 09:40:31 -0600 Subject: [PATCH 13/14] Update to latest MARBL --- .gitmodules | 2 +- externals/MARBL | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index df2418f1..390cdd4e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,6 +16,6 @@ path = externals/MARBL url = https://github.com/marbl-ecosys/MARBL.git fxDONOTUSEurl = https://github.com/marbl-ecosys/MARBL.git - fxtag = marbl0.50.0 + fxtag = marbl0.50.2 fxrequired = AlwaysRequired diff --git a/externals/MARBL b/externals/MARBL index 403f6c50..a694f394 160000 --- a/externals/MARBL +++ b/externals/MARBL @@ -1 +1 @@ -Subproject commit 403f6c50bba305d59910031dae33ff0629fb8602 +Subproject commit a694f39472e8192d1fa0e4c0d4e02ea11109fc21 From 713ae5f39c2243368fa797ad698d942b3363f258 Mon Sep 17 00:00:00 2001 From: Michael Levy Date: Tue, 8 Sep 2026 17:11:05 -0600 Subject: [PATCH 14/14] One more MARBL tag --- .gitmodules | 2 +- externals/MARBL | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 390cdd4e..f2b47f41 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,6 +16,6 @@ path = externals/MARBL url = https://github.com/marbl-ecosys/MARBL.git fxDONOTUSEurl = https://github.com/marbl-ecosys/MARBL.git - fxtag = marbl0.50.2 + fxtag = marbl0.50.3 fxrequired = AlwaysRequired diff --git a/externals/MARBL b/externals/MARBL index a694f394..f00d6423 160000 --- a/externals/MARBL +++ b/externals/MARBL @@ -1 +1 @@ -Subproject commit a694f39472e8192d1fa0e4c0d4e02ea11109fc21 +Subproject commit f00d64234dbb947101f183b99d60437a08bb778b