Realistic Ocean Initial Conditions
Creation date: 2026/03/22
Contributors: Xylar Asay-Davis, Codex, Claude
Summary
This design document describes a new Polaris capability for generating realistic
ocean initial conditions in Python, starting from an ocean mesh and topography
that have already been culled by the e3sm/init workflow. This capability
belongs to the ocean/spherical/realistic_global framework, which collects task families focused
on observationally-constrained ocean initialization and evaluation, in contrast
to the idealized task families elsewhere in the ocean component. The intent is to
port the required functionality from the MPAS-Ocean init mode, especially
mpas_ocn_init_global_ocean.F, and from the Compass workflows in
compass/ocean/tests/global_ocean/init and
compass/ocean/tests/utility/extrap_woa.
Each task initializes the single ocean model selected by the [ocean] model
config option (resolved to omega or mpas-ocean during component setup).
The new workflow produces scientifically consistent initial conditions for the
configured model. In the first phase, the same capability supports MPAS-Ocean
tracers based on potential temperature and practical salinity and Omega tracers
based on conservative temperature and absolute salinity. The initial phase does
not need to support ice-shelf cavities, Haney-number vertical coordinates under
ice shelves, or SSH adjustment below ice shelves, but the design should preserve
a clean path to add those features later.
A key challenge specific to the Omega p-star coordinate is that the
geometric seafloor depth cannot be prescribed directly: BottomPressure (related
to the pseudo-height of the seafloor) must be found iteratively so that the geometric
depth recovered from the coordinate matches observed bathymetry. Because CT and
SA must be initialized on the p-star grid before specific volume can be
evaluated, the vertical coordinate and the tracer state are tightly coupled. The
algorithm for this joint initialization is described in the companion design
document pstar_init.md. Its existence means the vertical
coordinate and tracer initial state cannot be produced in isolation from each
other; the decomposition into Polaris steps must reflect this coupling.
Because the p-star iteration is model-independent — the converged geometric vertical grid depends only on bathymetry and hydrography, not on which ocean model is the final target — running the task for different models on the same mesh and hydrography produces the same geometric layer thicknesses. This makes direct model comparison possible by running the task once per model: the geometric grids at initialization will be identical, and differences in simulated state can be attributed to model formulation rather than to different initial geometries. The p-star iteration runs even when the configured model is MPAS-Ocean; there is no separate z-star path.
The Polaris ocean framework separates model inputs across staged files: a
horizontal mesh file (mesh.nc), a vertical coordinate file (vert_coord.nc;
Omega only), an initial-state file (init.nc) and — added after this document
was first written — a surface-forcing file (forcing.nc), described under
Wind forcing. The realistic init workflow writes all of them,
through the framework’s write_horiz_mesh_dataset, write_vert_coord_dataset,
write_initial_state_dataset and write_forcing_dataset helpers. The
horizontal geometry is entirely the upstream e3sm/init cull workflow’s;
mesh.nc is that culled mesh with the fields the model’s mesh stream needs but
the cull step does not produce. For MPAS-Ocean, write_vert_coord_dataset is a
no-op and the vertical coordinate variables remain in init.nc.
The primary software challenges are to replace a large, monolithic Fortran workflow with an inspectable sequence of Polaris steps; to use a model-neutral p-star intermediate step that produces the same geometric grid regardless of the target model; and to keep the workflow performant on very large meshes through chunked xarray/dask operations and materialized intermediate files. This design is successful if it produces reusable, well-tested Polaris steps that scale to production global meshes, initialize the configured model from a model-neutral geometric vertical grid, and can eventually replace the corresponding legacy Compass and MPAS-Ocean init workflows for the supported open-ocean use case.
Requirements
Requirement: Open-ocean global initial conditions can be created from a culled mesh
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
Polaris shall provide a workflow that begins from an ocean mesh and
corresponding culled topography produced by the e3sm/init cull workflow and
produces a global ocean initial condition suitable for use by a standalone
ocean model.
The initial supported use case is open ocean without ice-shelf cavities. The workflow shall therefore assume that the culled mesh does not require cavity geometry, land-ice pressure initialization, or SSH adjustment beneath floating ice.
Any topography smoothing, minimum-depth logic, or related preparation of the
ocean topography needed for initialization shall be handled upstream in the
e3sm/init topography workflow rather than inside the ocean-initialization
workflow. This supports the goal of a unified MPAS mesh and a common
topographic description across E3SM components.
Requirement: A reusable global hydrography product is available from WOA
Date last modified: 2026/04/14
Contributors: Xylar Asay-Davis, Codex
Polaris shall provide a reusable hydrography product derived from the World Ocean Atlas at 0.25-degree resolution. This product shall contain canonical conservative temperature and absolute salinity fields needed to initialize the ocean state over the full globe, including values in regions where the original product is missing and extrapolation is required for later remapping. Because WOA23 supplies in-situ temperature and practical salinity rather than conservative temperature and absolute salinity, the workflow shall derive the canonical tracers during preprocessing.
The hydrography product shall be suitable for caching because it is expected to be computationally expensive and because it should be reusable across many meshes and tasks.
Requirement: The workflow produces consistent tracer initial conditions for the configured model
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Codex, Claude
Given a common hydrographic source, Polaris shall produce initial conditions that are thermodynamically consistent with the tracer conventions of the configured ocean model.
For MPAS-Ocean, the workflow shall produce temperature and salinity fields in the form expected by MPAS-Ocean (potential temperature and practical salinity). For Omega, the workflow shall produce temperature and salinity fields in the form expected by Omega (conservative temperature and absolute salinity). The design shall minimize duplicated logic between the two model targets by sharing the p-star iteration and WOA preprocessing and branching only where tracer conversion genuinely differs.
Requirement: The p-star iteration yields a model-independent geometric vertical grid
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Codex, Claude
The p-star initialization step shall produce a geometric vertical grid that depends only on bathymetry and hydrography, not on which ocean model is the final target. As a consequence, running the task for MPAS-Ocean and for Omega on the same horizontal mesh and hydrography shall produce the same initialized geometric layer thicknesses, enabling direct geometric comparison between the two models.
This shared-grid property is a natural outcome of the p-star algorithm: the
converged geometric layer thicknesses emerge from a model-neutral iteration and
are then consumed by the model-specific initial_state step. The p-star
iteration runs even when the configured model is MPAS-Ocean; there is no
separate z-star resting-thickness path.
The workflow shall compute any density, pressure, or specific-volume fields needed to translate hydrography defined with respect to geometric depth or height into the model’s native vertical representation.
Haney-number coordinates are out of scope for the initial implementation but should remain feasible to add later.
Requirement: The capability is decomposed into inspectable Polaris steps
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
The workflow shall be organized into multiple Polaris steps with clear, meaningful outputs that users and developers can inspect independently for sanity checking, visualization, and debugging.
Where appropriate, steps shall be reusable or cacheable so that expensive work does not need to be repeated across tasks that use identical inputs.
Requirement: The workflow is practical for very large global meshes
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
The workflow shall be implementable in a way that is practical for large production meshes, including meshes on the order of uniform 5-km global resolution.
The implementation shall avoid assumptions that require the full global state to fit comfortably in memory on a single node. It shall support sensible chunk-based execution and the use of intermediate files where needed to keep the workflow robust.
Requirement: The design preserves a path to future cavity support
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
Although the first implementation does not need to support ice-shelf cavities, the workflow shall not hard-code assumptions that make later support for cavities, land-ice pressure consistency, or SSH adjustment unnecessarily difficult.
Algorithm Design
Algorithm Design: Open-ocean global initial conditions can be created from a culled mesh
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
The workflow should adopt the culled ocean mesh and associated topography from
the e3sm/init cull workflow as its starting point rather than reproducing the
mesh-culling logic inside the ocean task. This keeps responsibilities separated:
e3sm/init produces physically consistent meshes and masks, while the new ocean
initial-condition workflow consumes those products to build the 3D ocean state.
For the initial phase, the relevant topographic fields should be restricted to open-ocean quantities needed for bathymetry, land masks, and any mesh-derived auxiliary fields required by the target model.
This design also assumes that any topography smoothing or minimum-depth
enforcement needed for ocean initialization has already been applied in the
e3sm/init topography workflow, so the ocean task treats the incoming
topography as authoritative.
Algorithm Design: A reusable global hydrography product is available from WOA
Date last modified: 2026/04/14
Contributors: Xylar Asay-Davis, Codex
The workflow should create a canonical hydrography product on the native WOA23 latitude-longitude grid before any remapping to an MPAS mesh. The current implementation does this with a concrete sequence:
Create combined topography on the native 0.25-degree latitude-longitude grid.
Read WOA23 January and annual temperature and salinity climatologies and combine them into a single source product, using annual values at depths where the monthly fields are not available, then derive conservative temperature and absolute salinity from WOA23 in-situ temperature and practical salinity.
Build a 3D ocean mask on the WOA grid from the combined topography product.
Extrapolate horizontally and then vertically within the ocean mask.
Extrapolate horizontally and then vertically into land and grounded-ice regions so later remapping will not sample missing values.
Optionally produce visualization products for sanity checking.
This is conceptually similar to the existing Compass extrap_woa utility but
the Polaris implementation should favor xarray-based operations and clear
intermediate products over multiprocessing code that is tightly coupled to the
legacy workflow.
Algorithm Design: The workflow produces consistent tracer initial conditions for the configured model
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Codex, Claude
A common intermediate tracer representation should be used to avoid maintaining two largely separate initialization pipelines. The leading candidate is a canonical hydrographic state based on conservative temperature and absolute salinity because those align naturally with Omega and with the desired WOA-based source product.
Model-specific tracer fields are derived late in the workflow, in the
initial_state step:
Interpolate the canonical state onto the target mesh columns.
Convert to the tracer convention required by the configured model.
Write the resulting fields using the variable names and metadata expected by the model.
The exact thermodynamic conversions should be finalized during implementation, but the conversion logic should be isolated so it can be tested independently of horizontal and vertical interpolation.
Algorithm Design: The p-star iteration yields a model-independent geometric vertical grid
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Codex, Claude
The model-neutral geometric grid is determined by the pstar_init step.
The high-level outcome is:
Horizontally remap the source hydrography to each MPAS column on a source vertical grid.
For each water column, run the coupled p-star and tracer initialization to convergence (see pstar_init.md), producing the p-star coordinate, CT and SA at layer midpoints, specific volume, and the converged geometric layer thicknesses.
Use the resulting initialized geometric layer thicknesses in the configured model: as part of the Omega initial condition, or as
restingThicknessin MPAS-Ocean.The
initial_statestep derives any remaining model-specific vertical state, including ALE layer-thickness fields for MPAS-Ocean.
Because the Omega p-star coordinate is defined in pseudo-height rather than
geometric height, the geometric seafloor depth cannot be prescribed directly.
The pseudo-height of the seafloor (BottomPressure) must be found iteratively
so that the geometric depth recovered from the coordinate matches observed
bathymetry. This requires initializing CT and SA on the p-star grid at each
iteration step so that specific volume can be evaluated, making the vertical
coordinate and the tracer state tightly coupled. Full and partial bottom cells
add further complexity by introducing discrete jumps in the pseudo-bottom depth.
The detailed fixed-point algorithm for this joint p-star and tracer
initialization — including the proportional-ratio update for BottomPressure,
the CT/SA initialization interface, the handling of full and partial bottom
cells, and the complete list of output variables produced — is specified in the
companion design document pstar_init.md.
The initialized geometric grid emerges from the coupled iteration rather than from a geometric grid constructed in isolation; the workflow steps must reflect this coupling.
Algorithm Design: The workflow is practical for very large global meshes
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
The workflow should treat chunking and materialization as part of the algorithm design rather than as a later optimization. Likely design principles are:
Chunk horizontally over cells and only keep the full vertical column when needed.
Use explicit intermediate files between major phases so dask graphs stay bounded in size.
Reuse interpolation weights or cached preprocessed products where practical.
Keep expensive EOS calculations localized to the phases that need them.
Implementation
Implementation: Open-ocean global initial conditions can be created from a culled mesh
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
The new task should live under the ocean framework and consume outputs from a
culled-mesh step in e3sm/init, through explicit step inputs rather
than implicit filesystem assumptions. The initial task variant should target
open-ocean meshes without cavities and should accept a culled mesh,
corresponding graph file, and culled topography as inputs.
The first draft of the workflow should port only the parts of the current Compass and init-mode logic that are required for this open-ocean use case. Features related only to cavities, SSH adjustment, or ecosystem forcing can be left out until a later requirement is added for them.
This implementation should not perform its own topography smoothing or
minimum-depth preparation. Those operations should be implemented in
e3sm/init so the same prepared topography can be shared consistently across
ocean, sea-ice, land, and river workflows.
Implementation: A reusable global hydrography product is available from WOA
Date last modified: 2026/08/11
Contributors: Xylar Asay-Davis, Codex, Claude
This part of the design has landed. e3sm/init creates combined topography on
a native 0.25-degree latitude-longitude grid, and the WOA23 steps under
ocean/spherical/realistic_global/hydrography/woa23 build the corresponding
reusable product on that grid:
combine_topo, the sharede3sm/initCombineStepfor the 0.25-degree lat-lon grid, cached by default so the expensive blending is not repeatedcombine, which merges January and annual WOA23 climatologies intowoa_combined.nc, using annual values at depths where the monthly fields are not available, and derives conservative temperature and absolute salinity from WOA23’s in-situ temperature and practical salinity withgswextrapolate, which builds a 3D ocean mask from the combined topography and produces the reusable productwoa23_decav_0.25_jan_extrap.ncviz, a diagnostics step for maps and Antarctic transects, created as a shared step but not run by default
The steps are assembled by get_woa23_steps(component, include_viz), which
returns them keyed by symlink name along with their shared config. A consumer
that needs only the hydrography product — the mesh-specific init steps, for
instance — gets the same step instances rather than a second copy of the
preprocessing.
The rename worked out differently from what this section anticipated. The work
directories did move under the realistic_global family, but the Python
package did not gain a spherical level: the code is
polaris.tasks.ocean.realistic_global.hydrography.woa23. Work-directory paths
and module paths are separate concerns in Polaris and only the first is what a
user navigates, so there was no reason to make the module path longer. The same
split holds throughout this workflow: mesh-specific steps run under
ocean/spherical/realistic_global/{mesh_name}/init and live in
polaris.tasks.ocean.realistic_global.init.
Implementation: The workflow produces consistent tracer initial conditions for the configured model
Date last modified: 2026/08/11
Contributors: Xylar Asay-Davis, Codex, Claude
The workflow defines a model-neutral intermediate dataset (the pstar_init
step output) and leaves the model-specific translation to the write. That
separation is what lets the p-star iteration, WOA23 remapping and chunking
logic be shared regardless of the configured target model.
The translator layer ended up in the framework rather than in initial_state:
OceanIOStep.write_initial_state_dataset takes the convention the dataset’s
tracers are in and converts them to the one the configured model expects,
defaulting to the convention implied by eos_type. The task step supplies only
what the framework cannot know — the per-cell longitude and latitude the
conversion needs, which pstar_init.nc does not carry. Putting it there means
every task that writes an initial state converts tracers the same way, and a
step cannot forget to.
Thermodynamic calculations that are independent of the task live in
polaris.ocean.eos and polaris.ocean.init_state, as this section intended.
Implementation: The p-star iteration yields a model-independent geometric vertical grid
Date last modified: 2026/08/11
Contributors: Xylar Asay-Davis, Codex, Claude
The coupled p-star and tracer initialization described in
pstar_init.md shall be implemented as a concrete subclass of
PStarInitStep (defined in polaris/ocean/vertical/pstar_init.py). That
subclass, RealisticPStarInitStep, is defined in
polaris/tasks/ocean/realistic_global/init/pstar_init.py.
It implements the init_tracers method by interpolating CT and SA from the
pre-processed WOA hydrography product remapped to the MPAS horizontal mesh,
using the p-star layer midpoints from the current iteration as the vertical
interpolation target.
The reference 1D vertical grid that establishes the initial layer structure is
configured by setting grid_type in the [vertical_grid] section of
realistic_global_init.cfg. The pstar_init step passes this reference grid
to generate_1d_grid (in polaris/ocean/vertical/grid_1d/__init__.py),
which returns the interface depths used to dimension the p-star iteration. The
default for the realistic global init task is the pre-defined 80layerE3SMv1
grid. The grid_type option must be present in the config; if it is absent,
generate_1d_grid raises ValueError: Unexpected grid type: None.
The vertical grid turned out to be one of the things that has to vary from mesh
to mesh, which this document did not anticipate. It is set per mesh through
polaris.tasks.ocean.realistic_global.mesh_configs: an optional
<mesh_name>.cfg whose options are added after the task’s own config file and
therefore override it. The three 240 km meshes replace the 80-layer default
with a 16-level tanh_dz grid over a 3000 m bottom depth, because they exist
for fast smoke-testing rather than for realistic simulation. The same mechanism
carries the ocean-culled cell count used to size MPI tasks, and is where
per-mesh forward-run options belong as well. Anything that describes what the
ocean does on a mesh belongs there rather than in the mesh component’s own
per-mesh config, which describes the mesh itself.
Three behaviors of the iteration were settled during implementation rather than
in pstar_init.md, which specifies the fixed-point algorithm
itself. The column is anchored at the prescribed sea surface, so ssh matches
its prescribed value to machine precision and any residual left by partial-cell
snapping adjusts the diagnosed bottomDepth — the representable bathymetry —
rather than ssh, mirroring z-star partial cells. Columns too shallow to hold
min_vert_levels layers, or shallower than min_bottom_depth, are clamped.
And isolated bathymetry holes — cells deeper than every ocean neighbor — are
capped at their deepest neighbor’s level and re-solved, through
polaris.ocean.vertical.bathymetry_holes.fill_max_level_holes.
The output of the coupled initialization step — converged geometric layer
thicknesses, CT and SA, specific volume, and associated coordinate fields — shall
be exposed as an inspectable intermediate product (pstar_init). That
intermediate is a single combined dataset written in neutral (MPAS-Ocean) naming
and includes at least the full set of variables listed in the output table of
pstar_init.md. The model-specific split into separate output
files happens in the downstream initial_state step rather than in
pstar_init, keeping the intermediate inspectable without model-specific
naming or variable filtering.
The initial_state step consumes the pstar_init intermediate dataset,
performs any model-specific tracer conversions, and writes the final split
output:
vert_coord.ncviawrite_vert_coord_dataset(Omega only; no-op for MPAS-Ocean). For Omega this convertsrestingThicknesstoRefPseudoThicknessand writes the fiveInitialVertCoordfields (MinLayerCell,MaxLayerCell,BottomGeomDepth,RefPseudoThickness,VertCoordMovementWeights).init.ncviawrite_initial_state_dataset, which strips horizontal mesh variables and (for Omega) vertical coordinate variables before writing.
Surface forcing is not written by initial_state. Wind stress is produced by
a separate forcing step and written to its own forcing.nc, described under
Wind forcing below. Restoring fields remain future work.
The mesh file (mesh.nc) is written by initial_state rather than linked from
upstream. The culled mesh from e3sm/init is not by itself a complete ocean
mesh stream: add_coriolis_to_dataset adds fCell, fEdge and fVertex,
and for Omega write_horiz_mesh_dataset merges in the cell-centered
vector-reconstruction weights, which have to be the culled mesh’s since that
is the mesh the initial condition is built on. The horizontal geometry itself
is still entirely the cull step’s; nothing here re-derives it.
The p-star iteration shall run even when the configured model is MPAS-Ocean, since the converged geometric grid is always defined through the p-star iteration.
The MPAS-Ocean path derives restingThickness from the converged geometric
layer thicknesses rather than falling back to the legacy z-star resting-thickness
construction.
Implementation: The capability is decomposed into inspectable Polaris steps
Date last modified: 2026/09/24
Contributors: Xylar Asay-Davis, Codex, Claude
The decomposition landed with more steps than this section first sketched,
because remapping turned out to be worth separating from the mapping files it
uses, and because wind forcing arrived as a second remapped source. The chain
is assembled by get_realistic_init_steps(component, mesh_name, include_viz),
which builds every step with Component.get_or_create_shared_step and returns
them keyed by symlink name along with the per-mesh shared config. Steps run
under ocean/spherical/realistic_global/{mesh_name}/init, except the
mesh-independent preprocessing, which is shared across meshes:
the upstream
e3sm/initcull-topography steps, fromget_cull_topo_steps, which supply the culled ocean mesh, its graph and the remapped topographythe WOA23 hydrography steps described above, from
get_woa23_stepsthe JRA55-do wind-stress steps, from
get_jra55_steps(see Wind forcing)cull_topo: reindex the remapped topography from the base mesh to the culled ocean mesh usingocean_map_culled_to_base.nc, producingtopography_culled.nc, which is validated against a baseline when one is providedwoa23_map: build the bilinear mapping file from the 0.25-degree WOA23 lat-lon grid to the culled MPAS mesh. This is the one MPI step of the hydrography chain, and its task count is sized from the approximate culled ocean cell countremap_woa23: apply those weights withncremap, producingwoa23_on_mesh.ncjra55_mapandremap_jra55: the same two steps for the wind stresspstar_init: perform the coupled p-star and hydrography initialization described in pstar_init.md, producing the converged geometric grid, CT and SA on that grid, and all associated p-star coordinate fields; this step writes a single combined intermediate NetCDF file (pstar_init.nc) in neutral naming rather than the final split model files, so all outputs remain inspectable regardless of the target modelinitial_state: consume thepstar_initintermediate dataset, apply model-specific tracer conversions, populate remaining required fields, and writemesh.nc,vert_coord.nc(Omega only) andinit.ncforcing: write the model-specificforcing.ncfromjra55_on_mesh.ncviz: plots and sanity checks of the initial condition, vertical coordinate and forcing
Each remap is two steps rather than one because the original single step both
reimplemented what polaris.remap.MappingFileStep already provides and ran an
MPI operation (mbtempest) and a serial one (ncremap) together, which does
not schedule well under task parallelism. Splitting them also lets the mapping
step size its own task count from the estimated ocean cell count while the
ncremap call stays serial.
The step this section called diagnostics landed as viz, matching the name
used elsewhere in Polaris. It is created as a shared step but returned — and so
run — only when include_viz=True, which the standalone RealisticGlobalInit
task passes and consumers that reuse the init outputs as dependencies do not.
Workflows that build on the initial condition, such as forward runs and
dynamic adjustment, are meant to call get_realistic_init_steps the same way
and get the same step instances rather than a second copy of a chain that
costs hours.
The viz step makes Omega’s geometric layerThickness itself. Omega’s initial
state carries PseudoThickness and no SpecVol, and open_model_dataset no
longer derives equation-of-state fields (#817), so it only turns a
pseudo-thickness into a geometric one for a file that has both. The step
computes the specific volume with spec_vol_from_ds() instead.
Within this decomposition, initial_state is what ports the pieces of legacy
init-mode functionality that are neither part of pstar_init nor already
handled upstream in e3sm/init. As implemented, it:
Consumes the outputs of
pstar_init, including the converged geometric layer thicknesses and the model-agnostic hydrographic state on the target mesh.Converts that hydrographic state into the tracer conventions required by the configured model — CT and SA kept for Omega, converted to potential temperature and practical salinity for MPAS-Ocean. The conversion itself belongs to the framework’s initial-state helpers; this step supplies the per-cell longitude and latitude they need, since
pstar_init.nccarries no horizontal mesh fields.Populates quiescent dynamical initial conditions, setting
normalVelocityto zero.Computes the remaining derived fields, notably in-situ density from the specific volume the p-star iteration produced.
Writes
mesh.ncthroughwrite_horiz_mesh_dataset,vert_coord.ncthroughwrite_vert_coord_dataset(Omega only; a no-op for MPAS-Ocean, which keeps vertical coordinate variables ininit.nc) andinit.ncthroughwrite_initial_state_dataset.
Restoring fields did not land. Surface and interior restoring values and their
piston velocities are not part of the supported workflow yet, so nothing
computes them; the forcing file that replaces the legacy
init_mode_forcing_data.nc carries wind stress alone and is written by the
separate forcing step rather than by initial_state.
The first implementation should explicitly exclude or defer several categories
of legacy init-mode behavior that are present in
mpas_ocn_init_global_ocean.F but are not part of the current design scope:
Ice-shelf and land-ice-specific logic, including cavity temperature modification, land-ice pressure consistency, and SSH adjustment.
Ecosystem tracers, ecosystem forcing fields, and related pH or sediment initialization.
Shortwave-absorption auxiliary fields needed for the
ohlmann00parameterization, such as chlorophyll, zenith angle, and clear-sky radiation.Debug tracers and other optional tracer packages initialized only to simple default values in legacy init mode.
Any inland-sea culling or other mesh/topography correction that is more appropriately handled upstream in
e3sm/init.
The legacy diagnostics this section left open were decided as follows.
Haney-number fields are not written at all — the viz step’s port of Compass’
plot_initial_state drops those panels rather than reproducing them — since
Haney-number coordinates are out of scope. In-situ density is written, because
the p-star iteration already produces the specific volume it comes from and
because it is what the Omega stratification check reads.
Implementation: Wind forcing
Date last modified: 2026/08/11
Contributors: Xylar Asay-Davis, Claude
Dynamic adjustment needs a realistic, constant-in-time wind stress so the ocean can spin down fast waves against a sensible circulation. The forcing does not need to be a defensible climate product, only realistic enough that the adjusted state is dynamically sensible. Surface restoring, thermal and freshwater fluxes, atmospheric and sea-ice pressure, time-varying forcing, and all forward-model settings remain out of scope.
Source. JRA55-do v1.5.0 (MRI-JRA55-do-1-5-0), variables uas and vas:
10-m winds on the TL319 Gaussian grid (640 x 320), 3-hourly, distributed as
input4MIPs on ESGF and anonymously downloadable from the CEDA node. E3SM forces
G-cases with JRA55, so the adjusted state is adjusted against something close to
what a coupled run will apply, and the input4MIPs record pins version and
checksums. This supersedes the earlier intent to reuse the Compass NCEP
climatology, whose provenance is a 2015 filename and nothing more. The time
window is January 1958, the first month of the record and of an interannually
forced G-case, configurable via year and month.
Winds to stress. JRA55-do supplies winds, so a bulk formula is needed. Two
choices matter. First, the stress is averaged rather than the winds: computing
tau(mean wind) discards the gust contribution and underestimates stress in the
storm tracks, so stress is computed at each 3-hourly step and then averaged –
which is why the 3-hourly data is needed rather than a published monthly mean.
Second, the Large and Yeager (2004, 2009) neutral 10-m drag law is used with
rho_air = 1.22 and the wind speed clamped below at 0.5 m/s, with the stability
correction, the current-relative wind, and sea-ice drag deliberately omitted as
second-order for this purpose.
Remapping. Bilinear, in Cartesian components, with no padding of the source grid, and a check that every cell is covered. Each of these was settled by measurement or review, and each has a failure mode that is easy to reintroduce:
Bilinear rather than conservative, because the ocean responds to wind stress curl; first-order conservative gives a piecewise-constant stress whose curl is grid-scale noise, and pyremap’s moab path hard-codes
--order 1.Cartesian rather than zonal/meridional components, because the local east/north basis rotates with longitude, fastest near the poles. The stress is converted to its three Cartesian components on the source grid, each is remapped as a scalar, and the result is rotated back to east/north at each cell center, as E3SM’s coupler does for vectors. Remapping zonal and meridional components directly worked under mbtempest (a uniform vector of magnitude 1.0 measured a flat 0.998 near the North Pole) but not under ESMF, whose default pole handling builds its pole point from the zonal average of the source’s outermost row: the same vector measured 0.42 by 89.82 degrees N, tending to zero at the pole. In Cartesian components that average is meaningful, so the result no longer depends on
map_tool.No padding, because bilinear is center-based for ESMF but corner-based for mbtempest, and padding a lat-lon source so either its corners or its centers reach the pole aborts mbtempest. Duplicating a longitude column breaks both tools and is unnecessary, since TL319’s longitude corners already span exactly 360 degrees.
Every cell of the culled mesh must be covered, and the mapping files for
u-oi30-lr10andu-oi6to18-lr6to10cover all of them, the cells nearest the North Pole included.ncremapwrites zero rather than a missing value to a cell the weights do not reach, so a gap would otherwise reach the forcing file as a silent zero stress. The step instead reads each cell’s coverage (frac_b) from the mapping file and fails if any cell is short of it.
Steps. Deriving the global product is mesh-independent, and although the
reduction itself takes seconds it needs several GiB of raw winds, so the
product is cached and the work lives outside the init workflow, mirroring the
WOA23 hydrography product:
subdir |
step |
output |
|---|---|---|
|
|
|
|
|
diagnostic plots |
|
|
bilinear weights |
|
|
|
|
|
|
Output. Both models take zonal and meridional components at cell centers and
project onto edges themselves, so no vector rotation is needed. The field is
authored in MPAS-Ocean names and renamed on write through the existing
mpaso_to_omega.yaml mapping. The framework gains a fourth staged file
alongside the mesh, vertical coordinate and initial state: forcing_filename in
[ocean_staged_files], a forcing_variables list, and a
write_forcing_dataset helper.
The two models differ on the time dimension. Omega’s SfcStressForcingVars
registers 1-D fields on NCells, while MPAS-Ocean’s Registry declares
dimensions="nCells Time", so write_forcing_dataset adds Time=1 for
MPAS-Ocean only.
Jra55StressStep is default_cached, with jra55_stress.nc in the cache
database, so the multi-GiB download happens only when the standalone jra55
task regenerates the product.
The read side – staging forcing.nc as a model input, and the associated
namelist and config settings – belongs to the forward-model work rather than
to this design.
Implementation: The workflow is practical for very large global meshes
Date last modified: 2026/10/08
Contributors: Xylar Asay-Davis, Codex, Claude
The implementation should use xarray lazily by default for large fields and
should choose chunking with the target access pattern in mind. A reasonable
starting assumption is that horizontal chunking over nCells will be more
robust than attempting to process the full mesh at once.
Major stages should write intermediate NetCDF outputs rather than carrying a
single dask graph across the entire workflow. This is likely to be especially
important after WOA preprocessing, after pstar_init, and before final
model-specific output writing.
Only the second half landed. Every stage writes its own NetCDF output, but the
steps hold whole fields in memory rather than chunking them with dask, which
has been enough for u-oi6to18-lr6to10 (4.0 million ocean cells) on a single
node. The one place the work is chunked over nCells is the vertical
interpolation of the WOA23 tracers in pstar_init, which runs at every
fixed-point iteration and handles a chunk of cells at a time rather than one
column at a time. Meshes approaching uniform 5-km resolution will need more
than this.
Implementation: The design preserves a path to future cavity support
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
Even though cavities are out of scope initially, the data model should not assume that the free surface always coincides with sea level or that land-ice pressure fields are absent forever. Interfaces between topography handling, vertical-coordinate construction, and final state assembly should remain clean enough that cavity-aware logic can later be inserted without rewriting the full task.
Testing
Testing and Validation: Open-ocean global initial conditions can be created from a culled mesh
Date last modified: 2026/09/24
Contributors: Xylar Asay-Davis, Codex, Claude
The first level of testing should verify that the workflow can consume outputs
from an e3sm/init culled-mesh step and produce complete initial-condition
files for at least one supported global mesh. A small or moderate mesh should
be used for routine regression tests, with larger meshes reserved for
integration testing.
That split landed differently than “small mesh in a regression suite” suggests.
The whole chain — culling, remapping and the p-star iteration — costs hours on
any mesh worth initializing, so no task in this family belongs in a PR suite;
routine regression testing is the unit tests described below, and the workflow
itself is exercised by running it on a mesh. The 240 km meshes exist for
exactly that, which is why they override the vertical grid down to 16 levels.
Initial conditions built this way have also been carried through dynamic
adjustment on u-oi30-lr10 and u-oi6to18-lr6to10 in downstream work, which
is where artifacts in the WOA23 source data were found.
Testing and Validation: A reusable global hydrography product is available from WOA
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
Testing should verify that the preprocessed WOA product contains no missing values in the regions needed for later remapping, that metadata and dimensions are consistent, and that rerunning the step with the same inputs gives reproducible results.
Testing and Validation: The workflow produces consistent tracer initial conditions for the configured model
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Codex, Claude
Unit tests should cover any tracer-conversion utilities independently of the full task. Task-level validation should verify that model-specific outputs contain the expected tracer variable names and are thermodynamically consistent (e.g., potential temperature within physical bounds for MPAS-Ocean; conservative temperature for Omega).
Where practical, outputs on a small mesh should also be compared against the legacy Compass plus init-mode workflow, recognizing that exact bit-for-bit agreement may not be the right success criterion if the new implementation uses cleaner thermodynamic conversions.
Testing and Validation: The p-star iteration yields a model-independent geometric vertical grid
Date last modified: 2026/06/14
Contributors: Xylar Asay-Davis, Codex, Claude
Testing should verify that the pstar_init.nc intermediate file contains
consistent geometric and pseudo-height fields (layer thicknesses, interface
depths, valid-level masks) that respect bathymetry and minimum-thickness
constraints.
Running the task for both MPAS-Ocean and Omega configurations on the same mesh
and comparing the resulting pstar_init.nc intermediates (or the
restingThickness / RefPseudoThickness fields in the final outputs) should
confirm that the geometric vertical grid at initialization is identical.
For Omega, tests should also verify the convergence and stability of the p-star iteration used to relate geometric height, pressure, and pseudo-height.
For MPAS-Ocean, tests should verify that the initialized layer-thickness state is derived from the converged geometric grid from the p-star iteration rather than silently falling back to the legacy z-star construction.
Testing and Validation: The capability is decomposed into inspectable Polaris steps
Date last modified: 2026/10/15
Contributors: Xylar Asay-Davis, Codex, Claude
Each major step has unit tests under tests/ocean/realistic_global/, mirroring
the package layout: hydrography/woa23/test_combine.py and
hydrography/woa23/test_extrapolate.py for the WOA23 preprocessing,
forcing/jra55/test_stress.py for the wind-stress product,
init/test_woa23_map.py and init/test_jra55_map.py for
the mapping steps and how their task counts scale, init/test_remap_woa23.py
and init/test_remap_jra55.py for what the remapped products contain and for
the coverage check, init/test_pstar_init.py for the column helpers,
init/test_initial_state.py for which upstream files the step reads, and
init/test_forcing.py for the per-model forcing file. test_tasks.py checks
that one task is registered per mesh and that its step list is what the
decomposition says, and test_mesh_configs.py that the per-mesh overrides
reach the right options without displacing the rest.
The viz step is covered by init/test_viz_config.py rather than by a smoke
test: it checks that the step reads only config sections that exist and that no
colormap is chosen by a literal in the plotting code. Rendering the plots needs
a real initial condition, so that part is exercised by running the task rather
than in CI.
Testing and Validation: The workflow is practical for very large global meshes
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
Performance testing should include at least one larger mesh case to assess memory usage, wall-clock behavior, and whether intermediate-file boundaries are sufficient to keep dask execution stable. These tests do not need to run in the routine regression suite but should be documented and rerun periodically.
Testing and Validation: The design preserves a path to future cavity support
Date last modified: 2026/03/22
Contributors: Xylar Asay-Davis, Codex
This requirement is largely architectural in the first phase. Review-based validation is appropriate initially: the workflow should be checked for hard-coded open-ocean assumptions at module boundaries and in intermediate dataset schemas. Later, this requirement should graduate to task-level tests once cavity support is added.