Grids API
For narrative coverage of how the three mesh types fit together, see the narrative Grids page under Concepts.
AtmosTransport.Grids.AbstractFluxTopology Type
AbstractFluxTopologySupertype for flux topology traits. Each mesh advertises its natural flux representation via flux_topology(mesh).
StructuredFluxTopology— directional (x, y, z) face fluxes on a logically rectangular mesh.FaceIndexedFluxTopology— face-indexed connectivity; the natural representation for reduced Gaussian and other unstructured meshes.
AtmosTransport.Grids.AbstractHorizontalMesh Type
AbstractHorizontalMeshSupertype for all horizontal mesh topologies.
Required methods
Any subtype must implement the geometry API defined in GeometryOps.jl:
ncells(mesh)nfaces(mesh)cell_area(mesh, c)face_length(mesh, f)face_normal(mesh, f)face_cells(mesh, f) -> (left, right)cell_faces(mesh, c) -> indices
Structured meshes additionally provide:
nx(mesh),ny(mesh)— logical grid dimensions
AtmosTransport.Grids.AbstractStructuredMesh Type
AbstractStructuredMesh <: AbstractHorizontalMeshMeshes with a logically rectangular (i, j) structure per region. Both LatLonMesh and CubedSphereMesh are structured. Structured meshes expose nx(mesh), ny(mesh) and support direct (i, j) indexing of areas and face fluxes.
AtmosTransport.Grids.AbstractVerticalCoordinate Type
AbstractVerticalCoordinate{FT}Supertype for vertical coordinate systems.
Required methods
n_levels(vc)— number of vertical levelspressure_at_level(vc, k, p_surface)— center pressurepressure_at_interface(vc, k, p_surface)— interface pressurelevel_thickness(vc, k, p_surface)— layer thickness [Pa]
AtmosTransport.Grids.AngularMidpointCenter Type
AngularMidpointCenter <: AbstractCubedSphereCenterLawCell-center law that evaluates the continuous face coordinate map at the midpoint of the logical cell:
This matches the historical synthetic/equiangular CubedSphereMesh behavior. It is not how GEOS writes native C180/C720 center coordinates.
AtmosTransport.Grids.AtmosGrid Type
AtmosGrid{H, V, Arch, FT}Composite grid: horizontal mesh + vertical coordinate + architecture.
This is the single grid object passed to all transport operators. Dispatch on H selects mesh-specific geometry; dispatch on Arch selects backend.
Fields
horizontal :: H— horizontal mesh (LatLonMesh, CubedSphereMesh, ReducedGaussianMesh)vertical :: V— vertical coordinate (HybridSigmaPressure)arch :: Arch— compute architecture (CPU, GPU)planet :: PlanetParameters{FT}— physical constants [m, m/s², Pa]
AtmosTransport.Grids.CubedSphereDefinition Type
CubedSphereDefinition(coordinate_law, center_law, panel_convention;
longitude_offset_deg=0, tag=:custom)Complete horizontal cubed-sphere definition.
The definition is the geometry contract consumed by CubedSphereMesh and all derived helpers. It deliberately separates:
coordinate_law: how logical face edges are placed on the gnomonic cube,center_law: how cell centers are derived from the face geometry,panel_convention: how the six physical faces are ordered/oriented in file arrays and halo connectivity,longitude_offset_deg: a final rigid z-axis rotation applied to all panels.
For native GMAO files use GMAOCubedSphereDefinition, which combines GMAOEqualDistanceGnomonic, FourCornerNormalizedCenter, GEOSNativePanelConvention, and the GEOS -10° longitude shift.
AtmosTransport.Grids.CubedSphereMesh Type
CubedSphereMesh{FT, C, D} <: AbstractStructuredMeshStructured cubed-sphere mesh with Nc cells per panel edge and 6 panels.
Cell areas and edge lengths are computed once at construction time from the definition's corner geometry. All 6 panels share identical metrics by symmetry, so only one set is stored.
Fields
Nc :: Int— cells per panel edgeHp :: Int— halo padding width (1 for slopes, 3 for PPM)radius :: FT— planet radius [m]definition :: D— coordinate law + center law + panel convention contractconvention :: C— panel numbering conventionconnectivity :: PanelConnectivity— edge-to-edge panel connectivitycell_areas :: Matrix{FT}—(Nc, Nc)cell areas [m²] (one panel, all identical)Δx :: Matrix{FT}—(Nc, Nc)x-direction cell widths [m]Δy :: Matrix{FT}—(Nc, Nc)y-direction cell widths [m]
AtmosTransport.Grids.CubedSphereMesh Method
CubedSphereMesh(; Nc, FT=Float64, Hp=1, radius=6.371e6,
convention=nothing, definition=nothing)Construct a cubed-sphere mesh with Nc cells per panel edge.
definition is the authoritative geometry contract. If omitted, the constructor chooses a definition from convention:
GnomonicPanelConvention()->EquiangularCubedSphereDefinition()GEOSNativePanelConvention()->GMAOCubedSphereDefinition()
This preserves legacy synthetic CS behavior for default meshes while making GEOS-IT/GEOS-FP targets use the actual GMAO equal-distance geometry whenever the GEOS-native panel convention is requested.
Keyword arguments
Nc :: Int— cells per panel edge (e.g. 48, 90, 180, 720)FT :: Type— floating-point type (defaultFloat64)Hp :: Int— halo padding width (default 1 for slopes; use 3 for PPM)radius— planet radius [m] (default Earth)convention— panel numbering convention used whendefinitionis omitteddefinition— fullCubedSphereDefinition; overridesconvention
AtmosTransport.Grids.EquiangularGnomonic Type
EquiangularGnomonic <: AbstractCubedSphereCoordinateLawClassical equiangular gnomonic face coordinate law.
For edge index s = 1, ..., Nc + 1, the local angle is
and the tangent-plane coordinate used by the gnomonic projection is
This law is useful for controlled synthetic targets and legacy binaries. It is not the native GEOS-IT/GEOS-FP cubed-sphere coordinate law.
sourceAtmosTransport.Grids.FaceIndexedFluxTopology Type
FaceIndexedFluxTopology <: AbstractFluxTopologyFluxes stored as a single face-indexed array with explicit connectivity. Natural for reduced Gaussian and other unstructured meshes.
sourceAtmosTransport.Grids.GEOSNativePanelConvention Type
GEOSNativePanelConvention <: AbstractCubedSpherePanelConventionPanel numbering and orientation used by native GEOS-FP / GEOS-IT cubed-sphere files: panels 1-2 are equatorial, 3 is north-pole, 4-5 are equatorial, and 6 is south-pole.
This type describes panel storage/order only. The GEOS -10° longitude shift and GMAO equal-distance coordinate law live in GMAOCubedSphereDefinition.
AtmosTransport.Grids.GnomonicPanelConvention Type
GnomonicPanelConvention <: AbstractCubedSpherePanelConventionClassical gnomonic panel numbering: 1-4 are equatorial panels, 5 is the north-pole panel, 6 is the south-pole panel.
sourceAtmosTransport.Grids.HybridSigmaPressure Type
HybridSigmaPressure{FT} <: AbstractVerticalCoordinate{FT}Hybrid sigma-pressure coordinate: p(k) = A(k) + B(k) * p_surface.
Vectors A and B have length Nz + 1 (level interfaces / half-levels).
AtmosTransport.Grids.LatLonMesh Type
LatLonMesh{FT} <: AbstractStructuredMeshRegular latitude-longitude mesh on the sphere.
Fields
Nx,Ny— number of cells in longitude and latitudeΔλ,Δφ— uniform spacing [degrees]λᶜ,λᶠ— cell-center and cell-face longitudes [degrees]φᶜ,φᶠ— cell-center and cell-face latitudes [degrees]radius— planet radius [m]
AtmosTransport.Grids.LatLonMesh Method
LatLonMesh(; Nx, Ny, longitude=(-180, 180), latitude=(-90, 90), ...)Construct a regular latitude-longitude mesh.
Coordinate conventions
Longitude: cell faces at
λᶠ[1..Nx+1]spanning[λ_west, λ_east], cell centers at midpointsλᶜ[i] = (λᶠ[i] + λᶠ[i+1]) / 2. Default range(-180, 180)→λᶜ[1] = -178.125°forNx=96. IMPORTANT: the spectral preprocessor's FFT synthesis (spectral_to_grid!) must uselon_shift_rad = deg2rad(λᶜ[1])to align its output with this mesh. Usingdlon/2instead causes a 180° shift for(-180, 180)meshes (see 2026-04-11 bug fix in spectral_synthesis.jl).Latitude: cell faces at
φᶠ[1..Ny+1]spanning[φ_south, φ_north], cell centers atφᶜ[j]. Default(-90, 90)→φᶜ[1] = -88.125°forNy=48. Latitude is NOT periodic (closed pole boundaries).
Indexing (column-major)
3D arrays on this mesh are (Nx, Ny, Nz) where:
i(lon) is the fastest-varying index (column-major, Julia/Fortran style)j(lat) is the middle indexk(level) is the slowest-varying index;k=1is TOA,k=Nzis surface
The flat cell index is c = i + (j-1) × Nx (1-based). Face arrays for the Arakawa C-grid are am[Nx+1, Ny, Nz] (zonal, at west edges) and bm[Nx, Ny+1, Nz] (meridional, at south edges).
AtmosTransport.Grids.PanelConnectivity Type
PanelConnectivityComplete edge-to-edge connectivity for a 6-panel cubed sphere.
neighbors[p][e] gives the PanelEdge for panel p, edge e, where edges are numbered by local index side: 1=+Y, 2=-Y, 3=+X, 4=-X.
AtmosTransport.Grids.PanelEdge Type
PanelEdgeA connection from one panel edge to a neighbor panel's edge.
Fields
panel :: Int— neighbor panel index (1-6)orientation :: Int— along-edge direction code (0=aligned, 2=reversed)
AtmosTransport.Grids.ReducedGaussianMesh Type
ReducedGaussianMesh{FT} <: AbstractHorizontalMeshReduced Gaussian mesh with variable longitude count per latitude ring.
Fields
latitudes– ring-center latitudes [degrees], ordered south -> northnlon_per_ring– number of cells on each latitude ringring_offsets– 1-based start indices into the flattened cell arraylat_faces– latitude boundaries between rings [degrees]boundary_counts– number of meridional face segments on each ring boundaryboundary_offsets– 1-based start offsets within the meridional-face blockradius– planet radius [m]
Flattening convention
Cells are flattened ring-by-ring from south to north. Within a ring, cell i is ordered west to east on a periodic longitude partition [0, 360).
Geometry note
The ring boundaries are defined by midpoint latitudes with pole caps at -90 and +90 degrees. This preserves total surface area exactly while the exact Gaussian control-volume boundaries are still being wired in.
AtmosTransport.Grids.StructuredFluxTopology Type
StructuredFluxTopology <: AbstractFluxTopologyFluxes stored as separate directional arrays (am, bm, cm) on a logically rectangular grid.
sourceAtmosTransport.Grids.EquiangularCubedSphereDefinition Method
EquiangularCubedSphereDefinition(; convention=GnomonicPanelConvention(),
longitude_offset_deg=0)Legacy synthetic/equiangular cubed-sphere definition: EquiangularGnomonic corners plus AngularMidpointCenter centers.
AtmosTransport.Grids.GEOSIT_C180 Method
GEOSIT_C180(; FT=Float64, Hp=1, radius=6.371e6)
GEOSFP_C720(; FT=Float64, Hp=1, radius=6.371e6)Convenience constructors for the two native GMAO cubed-sphere targets used for GEOS-IT and GEOS-FP comparisons.
sourceAtmosTransport.Grids.GMAOCubedSphereDefinition Method
GMAOCubedSphereDefinition(; convention=GEOSNativePanelConvention(),
longitude_offset_deg=-10)Native GMAO/GEOS cubed-sphere definition used by GEOS-IT C180 and GEOS-FP C720 files:
GMAOEqualDistanceGnomonicedge/corner law,FourCornerNormalizedCenter(cell_center2) center law,GEOSNativePanelConventionby default,final
-10°longitude shift away from the Japan corner.
AtmosTransport.Grids.b_diff Method
b_diff(vc::AbstractVerticalCoordinate, k)Difference of B coefficients across level k: B[k+1] - B[k]. Used for distributing surface pressure tendency across levels.
sourceAtmosTransport.Grids.cell_area Function
cell_area(mesh::AbstractHorizontalMesh, c) -> FTArea [m²] of cell c.
c can be:
A flat integer index (column-major:
c = i + (j-1)*Nxfor structured)A tuple
(i, j)for structured meshes
Both forms must be implemented by all concrete mesh types.
sourceAtmosTransport.Grids.cell_area Method
Cell area [m²] at local panel indices (i, j). Same on all 6 panels by gnomonic symmetry.
AtmosTransport.Grids.cell_area Method
Cell area [m²] from flat cell index c (column-major: c = i + (j-1)*Nx).
AtmosTransport.Grids.cell_areas_by_latitude Method
Cell area vector (precomputed, one per latitude band).
sourceAtmosTransport.Grids.cell_faces Function
cell_faces(mesh::AbstractHorizontalMesh, c) -> indicesIndices of faces bounding cell c. For structured meshes this returns the 4 (or 6 for hex) face indices; for unstructured meshes it uses the CSR adjacency.
AtmosTransport.Grids.cell_faces Method
cell_faces(m::LatLonMesh, c) -> (west, east, south, north)Indices of the 4 faces bounding cell c. Accepts either a flat cell index (column-major: c = i + (j-1)*Nx) or a tuple (i, j).
Returns face indices consistent with the face_length/face_normal/face_cells numbering: X-faces 1:(Nx+1)_Ny, then Y-faces (Nx+1)_Ny+1 : nfaces.
sourceAtmosTransport.Grids.coordinate_law Method
Return the coordinate law carried by mesh.definition.
AtmosTransport.Grids.cs_definition Method
Return the full cubed-sphere geometry definition carried by mesh.
AtmosTransport.Grids.default_panel_connectivity Method
default_panel_connectivity() -> PanelConnectivityReturn the GEOS-FP native cubed-sphere panel connectivity.
Edge-to-edge connections (Panel p local edge → Panel q local edge): P1 +Y→P3 -X(rev) P1 -Y→P6 +Y(aln) P1 +X→P2 -X(aln) P1 -X→P5 +Y(rev) P2 +Y→P3 -Y(aln) P2 -Y→P6 +X(rev) P2 +X→P4 -Y(rev) P2 -X→P1 +X(aln) P3 +Y→P5 -X(rev) P3 -Y→P2 +Y(aln) P3 +X→P4 -X(aln) P3 -X→P1 +Y(rev) P4 +Y→P5 -Y(aln) P4 -Y→P2 +X(rev) P4 +X→P6 -Y(rev) P4 -X→P3 +X(aln) P5 +Y→P1 -X(rev) P5 -Y→P4 +Y(aln) P5 +X→P6 -X(aln) P5 -X→P3 +Y(rev) P6 +Y→P1 -Y(aln) P6 -Y→P4 +X(rev) P6 +X→P2 -Y(rev) P6 -X→P5 +X(aln)
The table is generated from the same GEOS-native corner geometry as panel_cell_corner_lonlat(mesh, p), so balance, treeify, and NetCDF output share one convention contract.
AtmosTransport.Grids.face_cells Function
face_cells(mesh::AbstractHorizontalMesh, f) -> (left, right)The two cells sharing face f. Convention: flux from left to right is positive. Boundary faces use 0 or a sentinel for the exterior cell.
AtmosTransport.Grids.face_cells Method
For structured LatLon, faces are implicitly indexed:
X-faces: index f in 1:(Nx+1)*Ny → face between (i-1,j) and (i,j), periodic in x
Y-faces: index f in 1:Nx*(Ny+1) → face between (i,j-1) and (i,j), bounded in y
Direct (i,j,k) array access is preferred over these for performance.
sourceAtmosTransport.Grids.face_cells Method
face_cells(m, f) -> (left, right)Return the two cell indices adjacent to face f. For the face-indexed transport operator, flux through face f goes from left to right (positive flux = transfer from left to right).
Face types
Faces 1..ncells are zonal (X) faces within each ring:
Face
fsits between the western cellleft_i = i-1(periodic wrap) and the eastern cellright_i = iin the same ringj.These faces are always interior (both indices > 0).
Faces ncells+1..nfaces are meridional (Y) boundary faces between adjacent latitude rings (or at the poles):
South pole cap (boundary 1):
left = 0(pole singularity),right = cell on ring 1. A face_left=0 tells the transport kernel to treat this as a boundary — no flux accumulation on the left side.North pole cap (boundary
nrings+1):left = cell on last ring,right = 0(pole singularity).Interior boundaries (boundary
b, between ringb-1and ringb): the boundary haslcm(nlon[b-1], nlon[b])segments. Segmentsegmaps to cellsouth_iin ringb-1and cellnorth_iin ringbvia integer division:cell_i = ((seg-1) × nlon_ring) ÷ nseg + 1. This distributes boundary segments evenly among cells.
AtmosTransport.Grids.face_length Function
face_length(mesh::AbstractHorizontalMesh, f) -> FTLength [m] of face f (or area of the face cross-section for 3D).
AtmosTransport.Grids.face_length Method
face_length(m::LatLonMesh, f) -> FTLength [m] of face f using the universal face-indexed API.
X-faces (f ∈ 1:(Nx+1)_Ny) return the meridional edge length. Y-faces (f ∈ (Nx+1)_Ny+1 : nfaces) return the zonal edge length.
sourceAtmosTransport.Grids.face_normal Function
face_normal(mesh::AbstractHorizontalMesh, f) -> (nx, ny)Unit normal of face f in logical coordinates (not geographic).
For structured meshes, components are in the (i, j) index directions:
X-faces →
(1, 0)(positive = increasingi= eastward on LatLon)Y-faces →
(0, 1)(positive = increasingj= northward on LatLon)
For unstructured meshes, implementations should return components in a local tangent-plane frame defined per face (e.g., east/north or panel-local). The frame convention MUST be documented by each mesh type so that flux-signing is unambiguous.
The transport operators multiply face_normal by face_length and the face flux to compute the signed contribution to cell convergence. Consistent normal orientation between face_cells (left → right = positive) and face_normal is required.
AtmosTransport.Grids.face_normal Method
face_normal(m::LatLonMesh, f) -> (nx, ny)Unit normal of face f. X-faces → (1, 0), Y-faces → (0, 1).
AtmosTransport.Grids.gnomonic_panel_connectivity Method
gnomonic_panel_connectivity() -> PanelConnectivityReturn the classical gnomonic cubed-sphere panel connectivity.
Panels 1-4 are the equatorial belt (+x, +y, -x, -y faces); panel 5 is the north polar cap (+z face); panel 6 is the south polar cap (-z face).
This matches the gnomonic ordering used by the ERA5-CS preprocessor and all CS transport binaries written by open_streaming_cs_transport_binary.
Edge-to-edge connections (P→Q with orientation 0=aligned, 2=reversed): P1 N→P5_S(0) P1 S→P6_N(0) P1 E→P2_W(0) P1 W→P4_E(0) P2 N→P5_E(0) P2 S→P6_E(2) P2 E→P3_W(0) P2 W→P1_E(0) P3 N→P5_N(2) P3 S→P6_S(2) P3 E→P4_W(0) P3 W→P2_E(0) P4 N→P5_W(2) P4 S→P6_W(0) P4 E→P1_W(0) P4 W→P3_E(0) P5 N→P3_N(2) P5 S→P1_N(0) P5 E→P2_N(0) P5 W→P4_N(2) P6 N→P1_S(0) P6 S→P3_S(2) P6 E→P2_S(2) P6 W→P4_S(0)
sourceAtmosTransport.Grids.ncells Function
ncells(mesh::AbstractHorizontalMesh) -> IntTotal number of horizontal cells in the mesh.
sourceAtmosTransport.Grids.nfaces Function
nfaces(mesh::AbstractHorizontalMesh) -> IntTotal number of horizontal faces in the mesh.
sourceAtmosTransport.Grids.nfaces Method
Total number of faces across all 6 panels: 6 × 2 × Nc × (Nc + 1) (x + y faces per panel).
AtmosTransport.Grids.nx Function
nx(mesh::AbstractStructuredMesh) -> Int
ny(mesh::AbstractStructuredMesh) -> IntLogical grid dimensions for structured meshes.
sourceAtmosTransport.Grids.panel_cell_center_lonlat Method
panel_cell_center_lonlat(Nc, panel, FT) -> (lons, lats)
panel_cell_center_lonlat(mesh::CubedSphereMesh, panel) -> (lons, lats)Return (Nc, Nc) arrays of cell-center longitudes and latitudes in degrees for the given panel.
The Nc method is the classical gnomonic convention. The mesh method honors panel_convention(mesh), including GEOS-native panel ordering and orientation.
AtmosTransport.Grids.panel_cell_corner_lonlat Method
panel_cell_corner_lonlat(Nc, panel, FT) -> (lons, lats)
panel_cell_corner_lonlat(mesh::CubedSphereMesh, panel) -> (lons, lats)Return (Nc+1, Nc+1) arrays of cell-corner longitudes and latitudes in degrees. The mesh method honors panel_convention(mesh).
AtmosTransport.Grids.panel_cell_local_tangent_basis Method
panel_cell_local_tangent_basis(mesh, panel)
-> (x_east, x_north, y_east, y_north)Return four (Nc, Nc) matrices describing the local panel-coordinate unit vectors at cell centers in geographic (east, north) components.
For each cell, (x_east[i,j], x_north[i,j]) is the unit vector for increasing local X (i) and (y_east[i,j], y_north[i,j]) is the unit vector for increasing local Y (j). The helper honors panel_convention(mesh), including GEOS-native Y-reversed panels, and is the geometry contract used by preprocessing wind rotation.
AtmosTransport.Grids.panel_connectivity_for Method
panel_connectivity_for(convention) -> PanelConnectivityReturn the PanelConnectivity that matches the given panel-numbering convention. Dispatches to gnomonic_panel_connectivity() or default_panel_connectivity() so that the mesh and all downstream code automatically use the right edge table.
AtmosTransport.Grids.panel_convention Method
Return the panel-numbering convention struct (Gnomonic or GEOSNative).
sourceAtmosTransport.Grids.panel_labels Method
panel_labels(convention) -> NTuple{6, Symbol}Return symbolic labels for each panel under the given convention.
Gnomonic:
(:x_plus, :y_plus, :x_minus, :y_minus, :north_pole, :south_pole)— panels 1-4 are equatorial (centred on ±x, ±y axes), 5 and 6 are polar.GEOS native:
(:equatorial_1, ..., :north_pole, ..., :south_pole)— panels 1-2 and 4-5 are equatorial, 3 is north pole, 6 is south pole. This matches the file-panel ordering in GEOS-FP/GEOS-IT NetCDF variables.
AtmosTransport.Grids.reciprocal_edge Method
reciprocal_edge(conn, p, e) -> IntFind which edge of the neighbor panel connects back to panel p edge e.
AtmosTransport.Grids.ring_longitudes Method
ring_longitudes(m, j) -> Vector{FT}Return the cell-center longitudes for ring j, in [0°, 360°) convention with half-cell offset: lon[i] = (i − 0.5) × (360° / nlon).
For nlon = 96: [1.875, 5.625, ..., 358.125].
This convention matches the spectral synthesis spectral_to_ring! which uses lon_shift_rad = π / nlon to place FFT output at cell centers.