The first step of any CrocoDash workflow is defining the spatial domain: a horizontal
grid (Grid) and a vertical grid (VGrid). Bathymetry (Topo), which sits between
the two, has its own notebook: see Bathymetry.
CrocoDash re-exports these objects from mom6_forge with no modifications, the full API (class methods, creation patterns, file formats) lives in the mom6_forge documentation. This notebook is the CrocoDash-flavored on-ramp; follow the links in each section for the deeper narrative tutorials and interactive widgets.
This notebook covers:
Section 1: Horizontal Grid, from Scratch¶
from CrocoDash.grid import Grid
grid = Grid(
resolution = 0.05, # in degrees
xstart = 278.0, # min longitude in [0, 360]
lenx = 3.0, # longitude extent in degrees
ystart = 7.0, # min latitude in [-90, 90]
leny = 3.0, # latitude extent in degrees
name = "panama1",
)Section 2: Vertical Grid¶
The vertical grid needs a maximum depth, normally this comes from your finished Topo
object’s topo.max_depth (see Bathymetry). Here we use a
representative depth directly so this section runs on its own.
from CrocoDash.vgrid import VGrid
max_depth = 5000.0 # in practice: topo.max_depth, once you've built your Topo (see Bathymetry)
vgrid = VGrid.hyperbolic(
nk = 75, # number of vertical levels
depth = max_depth,
ratio=20.0 # target ratio of top to bottom layer thicknesses
)import matplotlib.pyplot as plt
plt.close()
for depth in vgrid.zi:
plt.axhline(y=depth, linestyle='-') # Horizontal lines
plt.ylim(max(vgrid.zi) + 10, min(vgrid.zi) - 10) # Invert y-axis so deeper values go down
plt.ylabel("Depth")
plt.title("Vertical Grid")
plt.show()Section 3: Pre-Generated or Subset Grids¶
Two ways to use a pre-existing horizontal grid instead of generating one from scratch:
Section 3.1: load a supergrid directly from a file.
Section 3.2: extract a regional sub-grid from a global supergrid by lat/lon bounds.
(Loading or building the matching Topo/VGrid for either of these follows exactly the
same pattern shown in Bathymetry and Section 2 above, just swap in
the grid object from here.)
Section 3.1: Load Pre-Generated Grid Files¶
Use this when you already have a MOM6 supergrid (ocean_hgrid.nc), e.g. from a
previous run or a shared community grid like NWA12.
from CrocoDash.grid import Grid
grid = Grid.from_supergrid("<NWA_HGRID>")Section 3.2: Subset a Global Supergrid¶
Use this when you have a global or basin-scale supergrid and want to extract a regional
sub-domain by specifying lower-left and upper-right corner coordinates, via
subgrid_from_supergrid:
from CrocoDash.grid import Grid
grid = Grid.subgrid_from_supergrid(
path="<HGRID_TRIMMED>", # path to the global supergrid
llc=(16.0, 192.0), # (l)ower (l)eft (c)orner (lat, lon)
urc=(27.0, 209.0), # (u)pper (r)ight (c)orner (lat, lon)
name="hawaii_2",
)Section 4: Polar-Projected Grids (Arctic & Antarctic)¶
Standard lat/lon grids degrade at high latitudes, cell aspect ratios become extreme,
and the MOM6 timestep constraint can become prohibitively tight near the poles. For
Arctic or Antarctic domains, mom6_forge can build a grid in a projected coordinate
system (e.g. polar stereographic) and reproject it to the geographic coordinates MOM6
expects.
Two approaches are shown here:
Interactive: use the
GridCreatorwidget and select From Projection mode.Programmatic: call
Grid.from_projection()directly.
Approach 1: Interactive GridCreator Widget¶
Launch the widget, choose From Projection in the method dropdown, select Arctic
Polar Stereographic (EPSG:3995) or Antarctic Polar Stereographic (EPSG:3031) from
the CRS dropdown, set a resolution, then drag a rectangle on the polar map to define the
domain. The widget calls Grid.from_projection() under the hood and saves the result to
GridLibrary/.
from mom6_forge.grid_creator import GridCreator
gc = GridCreator()
gcApproach 2: Programmatic: Grid.from_projection()¶
Pass a pyproj CRS (as an EPSG string or integer) along with the domain extents in metres in the native projection. The method reprojects to geographic coordinates and computes grid metrics using exact great-circle geometry.
| CRS | Region |
|---|---|
"EPSG:3995" | Arctic Polar Stereographic |
"EPSG:3031" | Antarctic Polar Stereographic |
Arctic domain (EPSG:3995)¶
EPSG:3995 is centred at the North Pole. Extents are in metres from the pole. The example below creates a 2000 km × 2000 km domain at 50 km resolution.
from mom6_forge.grid import Grid
arctic_grid = Grid.from_projection(
crs="EPSG:3995",
x_min=-1_000_000, # metres from pole
x_max= 1_000_000,
y_min=-1_000_000,
y_max= 1_000_000,
resolution_m=50_000, # 50 km
name="arctic_50km",
)
print(f"Grid size: {arctic_grid.nx} x {arctic_grid.ny}")
print(f"Lat range: {arctic_grid.tlat.values.min():.1f}° to {arctic_grid.tlat.values.max():.1f}°")import cartopy.crs as ccrs
import matplotlib.pyplot as plt
fig, ax = plt.subplots(subplot_kw={"projection": ccrs.NorthPolarStereo()}, figsize=(6, 6))
ax.set_extent([-180, 180, 45, 90], crs=ccrs.PlateCarree())
ax.coastlines()
ax.gridlines()
ax.pcolormesh(
arctic_grid.tlon, arctic_grid.tlat,
arctic_grid.tlat, # colour by latitude as a sanity check
transform=ccrs.PlateCarree(), cmap="Blues", alpha=0.6,
)
ax.set_title("Arctic domain (EPSG:3995)")
plt.tight_layout()Antarctic domain (EPSG:3031)¶
EPSG:3031 is centred at the South Pole. The example below creates a 3000 km × 3000 km domain (covering most of Antarctica) at 25 km resolution.
antarctic_grid = Grid.from_projection(
crs="EPSG:3031",
x_min=-1_500_000,
x_max= 1_500_000,
y_min=-1_500_000,
y_max= 1_500_000,
resolution_m=25_000, # 25 km
name="antarctic_25km",
)
print(f"Grid size: {antarctic_grid.nx} x {antarctic_grid.ny}")
print(f"Lat range: {antarctic_grid.tlat.values.min():.1f}° to {antarctic_grid.tlat.values.max():.1f}°")fig, ax = plt.subplots(subplot_kw={"projection": ccrs.SouthPolarStereo()}, figsize=(6, 6))
ax.set_extent([-180, 180, -90, -45], crs=ccrs.PlateCarree())
ax.coastlines()
ax.gridlines()
ax.pcolormesh(
antarctic_grid.tlon, antarctic_grid.tlat,
antarctic_grid.tlat,
transform=ccrs.PlateCarree(), cmap="Blues_r", alpha=0.6,
)
ax.set_title("Antarctic domain (EPSG:3031)")
plt.tight_layout()Next steps¶
Once you have a Grid and VGrid, build a matching Topo. See Bathymetry
, then pass all three to Case: see Case Setup.