Regridding & Mapping
mom6_forge.mapping is the regridding machinery behind bathymetry ingestion
(Topo.set_from_dataset and friends — see Bathymetry Workflow) and
coupler mapping-file generation. Most users won’t call it directly for
bathymetry, but it’s the direct entry point for generating mapping files
outside that workflow — most notably river-runoff-to-ocean mapping.
ESMF Meshes
Most functions here operate on ESMF mesh files (see ESMF mesh), the
format expected by the NUOPC coupler and by xESMF/ESMPy.
grid_from_esmf_mesh converts one back into a 2D lon/lat/mask grid dataset
for use with xESMF.
Runoff Mapping
gen_rof_maps builds the mapping file(s) MOM6 needs to route river runoff
from a runoff (ROF) mesh onto the ocean grid:
from mom6_forge.mapping import gen_rof_maps
gen_rof_maps(
rof_mesh_path="rof_ESMF_mesh.nc",
ocn_mesh_path="ocean_ESMF_mesh.nc",
output_dir="maps/",
mapping_file_prefix="rx1_to_my_ocean",
rmax=300.0, # smoothing radius, km
fold=600.0, # smoothing decay length, km
)
It always produces a nearest-neighbor map (rx1_to_my_ocean_nn.nc), which
routes each runoff cell straight into its nearest ocean cell — the problem
with this alone is that it dumps an entire river’s freshwater into a single
coastal cell, which is rarely physical.
Passing rmax/fold additionally produces a smoothed nearest-neighbor
map (rx1_to_my_ocean_r300_f600_nnsm.nc) that spreads each injection across nearby
ocean cells instead of a single point:
rmax(km) is the cutoff radius — only ocean cells within this distance of the injection point receive any of it.fold(km) is the decay length of the smoothing kernel,weight = exp(-distance / fold)— a smallerfoldconcentrates the injection near the coast, a larger one spreads it further before decaying.
Leave both None to skip smoothing and get only the nearest-neighbor map.
Rather than guessing values, get_suggested_smoothing_params(ocn_mesh_path)
derives a reasonable rmax/fold pair from the ocean mesh’s own average
resolution (rmax ≈ 5x the average cell size, fold = 2x rmax), and
gen_rof_maps itself warns if a much larger rmax is passed than that,
since it can blow up compute time and memory.
Generating a Mapping File
For any other component-to-component mapping, generate_ESMF_map_via_xesmf
builds a reusable weights file:
from mom6_forge.mapping import generate_ESMF_map_via_xesmf
generate_ESMF_map_via_xesmf(
src_mesh_path="src_ESMF_mesh.nc",
dst_mesh_path="ocean_ESMF_mesh.nc",
mapping_file="src_to_ocean_bilinear.nc",
method="bilinear", # or 'conservative', 'nearest_s2d', 'nearest_d2s'
)
generate_ESMF_map_via_esmpy does the same via ESMPy directly, which can
be preferable in MPI/HPC contexts.
Regridding a Dataset
regrid_dataset_via_xesmf regrids a dataset onto a destination grid via
xESMF (bilinear by default), reusing a precomputed weights file via
weights_path/reuse_weights=True if given.
Cressman Interpolation
A plain bilinear regrid smears the coastline when the source is much
finer-resolution than the model grid, letting land elevations bleed into
nearby ocean depths. regrid_dataset_via_cressman avoids this: for each
destination ocean cell, source ocean points within radius
L = smooth_scl * sqrt(cell_area) are averaged with weight
(r = great-circle distance, c = cressman_exp), mirroring tx2_3’s
interp_smooth.f90. Only ocean points contribute, so coastal depths aren’t
land-contaminated; cells with no coverage within L fall back to
mom6_forge.utils.iterative_fill.
This is exposed on Topo via direct_cressman_interp(), one of the two
depth methods Topo.set_from_dataset can pick automatically (see
Bathymetry Workflow). For a full walkthrough, see
8_cressman_interpolation.ipynb.
Subsampling Statistics
When the source is much finer than the grid, regrid_with_subsampling and
Topo.compute_stats/set_depth_from_stats compute per-cell statistics (mean
depth, ocean fraction, etc.) over sub-sampled points instead of relying on a
single interpolated value — the “stats-based” path in
Bathymetry Workflow.