CIME buildnml and Configuration Validation
components/omega/cime_config/buildnml generates a case’s omega.yml by
layering Omega’s defaults, coupled/mesh overrides, runtime overrides derived
from the case, and user_nl_omega (see Model Configuration (Config)). This
page covers the Python package behind buildnml, how its configuration is
validated, and how to add support for a new mesh.
omega_buildnml package
components/omega/cime_config/omega_buildnml/ implements the merging and
validation logic used by buildnml:
read_write.pyreads/writes YAML config files and packaged data.config.pymerges the configuration layers and resolves mesh input files.validate.pyvalidates overrides andIOStreamsagainstDefault.yml.data/input_files.yamlmaps each supported mesh to its input file(s).data/config_overrides.yamlholds the coupled and mesh-specific overrides.
Validation runs whenever these files are read, so a bad edit fails fast at
case.setup rather than surfacing as a confusing runtime error. Stream
names are checked dynamically against Default.yml rather than a
hardcoded list: the coupled section of config_overrides.yaml and a
case’s user_nl_omega are free to define brand-new IOStreams entries,
but a stream referenced in input_files.yaml must already exist in
Default.yml, since input_files.yaml only supplies a Filename
override for an existing IOStreams entry. IOStreams is not permitted
under a mesh entry in config_overrides.yaml’s meshes section, since
per-mesh IOStreams overrides aren’t a supported use case; put IOStreams
that apply to every mesh under coupled instead. The required streams
(HorzMeshIn, InitialVertCoord, InitialState) are always enforced.
Validation and CI
components/omega/cime_config/validate_config.py runs the same validation
against every mesh and override entry (rather than just the ones needed for
one case), so it catches problems anywhere in the packaged configuration:
cd components/omega/cime_config
./validate_config.py
The omega-buildnml GitHub Actions workflow runs this script, along with
omega_buildnml’s pytest unit tests across supported Python versions, on
every pull request touching cime_config/ or Default.yml. Run both
locally before opening a PR that changes either:
cd components/omega/cime_config
./validate_config.py
python -m pytest omega_buildnml/tests -v
Adding a supported mesh
Confirm the mesh’s grid alias is already defined for E3SM in
cime_config/config_grids.xmlat the repository root;buildnmllooks up input files by the case’sOCN_GRIDvalue.Add an entry for the mesh to
data/input_files.yaml, listing the input file(s) that provide itsHorzMeshIn,InitialVertCoord, andInitialStatestreams (split across multipleinputsentries if the initial condition is a separate file from the mesh).If the mesh needs overrides beyond Omega’s defaults and the coupled overrides, add a
meshes.<mesh name>entry todata/config_overrides.yaml.Run
./validate_config.pyto confirm the new entries are complete and consistent withDefault.yml.