Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Case Setup (Case object) & Coupling

Once your grids are ready (see Grids and Bathymetry), the next step is creating a Case, CrocoDash’s orchestration object that ties your grid definition into CESM. Case(...) also decides, from your chosen compset, which additional forcings you’re on the hook for in Configure Forcings.

This notebook covers:

  • Section 1: the standalone-ocean case (Case(...) basics, compset reference table)

  • Section 2: how to discover what a compset requires, before calling configure_forcings

  • Section 3: coupling: sea ice (CICE6)

  • Section 4: coupling: biogeochemistry (MARBL)

  • Section 5: coupling: waves (WW3)

📖 CrocoDash case setup docs

Section 1: Create a Standalone-Ocean Case

After generating the MOM6 domain, the next step is to create a CESM case using CrocoDash. This process is straightforward and involves instantiating the CrocoDash Case object. The Case object requires the following inputs:

  • CESM Source Directory: A local path to a compatible CESM source copy.

  • Case Name: A unique name for the CESM case.

  • Input Directory: The directory where all necessary input files will be written.

  • MOM6 Domain Objects: the Grid, Topo, and VGrid created in Grids and Bathymetry.

  • Project ID: (Optional) A project ID, if required by the machine.

  • Compset: The set of models to be used in the Case. Standalone Ocean, Ocean-BGC, Ocean-Seaice, Ocean-Runoff.

Begin by specifying the case name and the necessary directory paths. Ensure the CESM root directory points to your own local copy of CESM.

from pathlib import Path

# CESM case (experiment) name
casename = "panama-not"

# CESM source root (Update this path accordingly!!!)
cesmroot = "<CESM>"

# Place where all your input files go
inputdir = Path("<inputdir>") / casename

# CESM case directory
caseroot = Path("<casedir>") / casename

Compset quick-reference

The compset argument controls which model components are active. Start with the ocean-only default and swap or add stubs as needed:

What you wantChange in compset=
Ocean only (default)compset="CR_JRA"
+ Sea ice (CICE6)change CR_JRAGR_JRA
+ Biogeochemistry (MARBL)add %MARBL-BIO to the MOM6 component, e.g. MOM6%REGIONAL%MARBL-BIO
+ Waves (WW3)swap the stub SWAVWW3 in the long name
+ Data runoff (GLOFAS)use CR_JRA_GLOFAS
+ Data runoff (JRA)use CR_JRA with DROF%JRA (see Configure Forcings, Section 5)

For a deeper dive into each option:

from CrocoDash.case import Case

case = Case(
    cesmroot = cesmroot,
    caseroot = caseroot,
    inputdir = inputdir,
    ocn_grid = grid,
    ocn_vgrid = vgrid,
    ocn_topo = topo,
    project = 'CESM0030',
    override = True,
    machine = "derecho",
    compset = "CR_JRA" # This is the alias of the compset, the longname (which is printed when you run this command) is 1850_DATM%JRA_SLND_SICE_MOM6%REGIONAL_SROF_SGLC_SWAV. Feel free to use either way!
)

Section 2: Discover What a Compset Requires

Right after Case(...) succeeds, it prints a summary of any required forcing configurations you still owe for the compset you chose. These become your keyword arguments to case.configure_forcings(...) in the next step. A MARBL compset, for example, requires BGC, BGCIC (which needs marbl_ic_filepath), and BGCIronForcing. A DROF compset additionally requires Runoff, which takes no arguments of its own.

What pulls in a configurator is the compset component, not the data product: any DROF compset requires Runoff whether or not you use %GLOFAS.

You don’t have to build a real Case to see this. The same registry the constructor calls is available standalone, keyed off any compset long name string:

from CrocoDash.forcing_configurations import ForcingConfigRegistry


def print_required(compset):
    print(compset)
    for config_class in ForcingConfigRegistry.find_required_configurators(compset):
        user_args = ForcingConfigRegistry.get_user_args(config_class)
        print(f"  Required: {config_class.name}  (needs: {user_args or 'no arguments'})")


# Section 4 below builds a Case with this compset (MARBL, no active runoff):
print_required("1850_DATM%NYF_SLND_SICE_MOM6%MARBL-BIO%REGIONAL_SROF_SGLC_SWAV")

# Switching SROF to DROF adds a Runoff configurator to the required list:
print_required("1850_DATM%NYF_SLND_SICE_MOM6%MARBL-BIO%REGIONAL_DROF%GLOFAS_SGLC_SWAV")

On a live Case, case.compset_lname gives you the resolved long name CrocoDash already validated against, so you can run the same check without retyping it:

required = ForcingConfigRegistry.find_required_configurators(case.compset_lname)

See Configure Forcings for how each required configurator maps onto a configure_forcings() keyword. Two more introspection helpers worth knowing: ForcingConfigRegistry.find_valid_configurators(compset) (same pattern as find_required_configurators, but returns everything compatible with the compset, not just what’s required), and, per configurator class rather than on the registry itself, configurator_cls.validate_compset_compatibility(compset) / ForcingConfigRegistry.return_missing_inputs(configurator_cls, inputs_dict) (checked against a specific configurator class + an inputs dict, not a plain compset string).

Section 3: Coupling: Sea Ice (CICE6)

Swap the stub SICE (stub sea ice) for CICE in the compset. Everything else, grid, topo, vgrid, forcings, is identical to the standalone run.

from CrocoDash.case import Case

case = Case(
    cesmroot=cesmroot,
    caseroot=caseroot,
    inputdir=inputdir,
    ocn_grid=grid,
    ocn_vgrid=vgrid,
    ocn_topo=topo,
    project="NCGD0011",
    override=True,
    machine="derecho",
    compset="GR_JRA",  # GR_JRA = 1850_DATM%JRA_SLND_CICE_MOM6%REGIONAL_SROF_SGLC_SWAV
)

Optional: Warm start from CICE restart files

After a first run you can use CICE restart files as the ice initial condition instead of the default (open water). This gives a more realistic sea-ice state at the start of subsequent runs.

  1. Find restart files in your archive: <caseroot>/archive/rest/<year>/, look for *.cice.r.*.nc. If unsure of the archive path, run ./xmlquery DOUT_S_ROOT in the case directory.

  2. Copy the file to your run directory: cp <restart_file> <run_dir>/.

  3. Open user_nl_cice and set ice_ic = "<restart_filename>".

Section 4: Coupling: Biogeochemistry (MARBL)

MARBL (the Marine Biogeochemistry Library) is bundled with CESM. Activating it requires:

  1. A compset that includes MOM6%REGIONAL%MARBL-BIO.

  2. A MARBL global initial-condition file.

  3. Passing BGC-specific kwargs to configure_forcings (see Configure Forcings, Section 6).

Optionally, combine with river nutrients by also enabling GLOFAS runoff.

from CrocoDash.case import Case

case = Case(
    cesmroot=cesmroot,
    caseroot=caseroot,
    inputdir=inputdir,
    ocn_grid=grid,
    ocn_vgrid=vgrid,
    ocn_topo=topo,
    project="NCGD0011",
    override=True,
    machine="derecho",
    compset="CR1850MARBL_JRA",
)

Once this Case exists, rerun Section 2’s discovery check against case.compset_lname to confirm exactly which configure_forcings kwargs you owe, for this compset that’s marbl_ic_filepath (matching the first print_required(...) call above, and the printed report Case(...) already gave you).

Section 5: Coupling: Waves (WW3)

Swap the stub SWAV (stub waves) for WW3 in the compset. There is no regional alias for a wave-coupled compset yet, the shipped ones (CW_JRA, GW_JRA) use global MOM6, so pass the long name directly:

from CrocoDash.case import Case

case = Case(
    cesmroot=cesmroot,
    caseroot=caseroot,
    inputdir=inputdir,
    ocn_grid=grid,
    ocn_vgrid=vgrid,
    ocn_topo=topo,
    project="NCGD0011",
    override=True,
    machine="derecho",
    compset="1850_DATM%NYF_SLND_SICE_MOM6%REGIONAL_SROF_SGLC_WW3_SESP",
)
print("WW3 in compset:", case.ww3_in_compset)

SESP on the end is CESM’s stub external-system-processing component, unrelated to waves, it’s simply what a compset long name carries after an active WAV component. Dropping it (..._SGLC_WW3) also works.

With WW3 active, Case(...) writes WW3’s grid-preprocessor input files into <inputdir>/ocnice/ alongside the MOM6 grid files: ww3_grid.inp plus <grid_name>_x.inp, _y.inp, _bottom.inp, and _mapsta.inp, derived from the same Topo you already built. WW3’s mod_def step reads these before runtime, so the wave model runs on your ocean grid and land/sea mask, with no separate wave grid to build.

case.ww3_in_compset is the same check CrocoDash uses internally, and is worth printing if you’re unsure whether your long name actually activated the wave model.

Wave forcing itself, boundary spectra flowing in through the open boundaries, is covered in Configure Forcings, Section 8.

Next steps

Continue to Configure Forcings to fill in the BGC/runoff arguments this compset requires, or jump to Process Forcings once configured.