Orchestration over the pure seam operators in rdb_ocean_fold:
dereferences the state slots (outer-shim per-tracer loop) and calls
the explicit-shape fold kernels.
Ordering contract: periodic-x is wrapped FIRST, fold SECOND — every
fold routine is called AFTER the matching periodic wrap so it reads
the already cyclically-wrapped corner columns.
Stagger map:
* h_layer, η, tracer hTr → centre fold (copy, no sign flip)
* u_face_x_layer, bt_ubt → u-face fold (negate — true vector)
* v_face_y_layer, bt_vbt → v-face fold (negate + on-row
antisymmetric projection of the fold line, storage row
nghost+ny_phys+1 — see the rdb_ocean_fold header)
Every routine no-ops when bc%north_fold is .false. ⇒ non-tripolar
runs stay bit-identical. bc%north_fold is RANK-LOCAL: true only on
the rank that owns the physical north edge (has_north), so on a
north-south split the other ranks leave their north ghosts to the MPI
exchange that precedes every call here (exchange → periodic wrap →
fold). See the rdb_ocean_fold header for the decomposition limits.
px dispatch
px = 1 (ocean_fold_is_distributed() false): the local kernels,
textually unchanged. px > 1: every routine becomes ONE collective
group of the owner-routed exchange (rdb_ocean_fold_exchange) over
the north rank row — all its ranks have north_fold set and reach the
same call — with the same fields, signs and fold-line projection. The
optional device_resident only matters on that path (host-side setup
calls pass .false., as for the halo primitives).
Nodes of different colours represent the following:
Solid arrows point from a submodule to the (sub)module which it is
descended from. Dashed arrows point from a module or program unit to
modules which it uses.
Where possible, edges connecting nodes are
given different colours to make them easier to distinguish in
large graphs.
Nodes of different colours represent the following:
Solid arrows point from a submodule to the (sub)module which it is
descended from. Dashed arrows point from a module or program unit to
modules which it uses.
Where possible, edges connecting nodes are
given different colours to make them easier to distinguish in
large graphs.
Fold ONLY h_layer + tracers (centre fields) — the continuity
mid-split site, which re-wraps the centre fields between the
zonal and meridional Lie-split halves. No-op when not folding.
Fold the north seam of an arbitrary flat cell-centred (T-stagger)
SCALAR field — copy, no sign flip, exactly fold_north_centre’s
contract. Exists so a caller holding a sequence-associated flat
view of a higher-rank array (the sea-ice category state’s
ice_halo_centre_flat pattern — part_size/m_ice/m_snow/
enth_ice/sal_ice/enth_snow/mca_ice/mca_snow, and the
per-cell flux diagnostics salt_flux_diag/heat_flux_diag/
sw_thru_diag) can fold it without going through
multilayer_state_t. Every one of these is a per-category mass,
enthalpy, salinity or fractional area — a scalar, not a vector
component — so negate is never offered here. Call AFTER the
field’s halo exchange (which also performs the single-rank
periodic wrap). No-op when bc%north_fold is .false..
Fold the north seam of h_layer, u/v layer faces, and every
registered tracer. Call AFTER ocean_periodic_wrap_state.
No-op when bc%north_fold is .false.
Fold the surface-stress pair: tau_x (u, −) and tau_y (v, − +
fold-row projection) — true vector components. Call after the
pair’s exchange + periodic wrap. No-op when not folding.
Fold the pred_corr step time-means u_av (u, −), v_av (v, −, +
fold-row projection) and h_av (T) — the stage-entry site that
mirrors the prognostic fold for the Coriolis / viscosity inputs.
Call after their periodic wrap. No-op when not folding or when
the means are not allocated (ssp_rk2). Device-only: unlike the
other dispatchers it takes no device_resident flag, because its
production caller (run_stage_split) always runs on the mapped state.
Fold the viscous-remnant pair: visc_rem_u (u-face) and
visc_rem_v (v-face) — PR-1’s bt_work%visc_rem_u/v seam.
UNLIKE ocean_fold_wrap_stress (its vector twin, tau_x/tau_y),
visc_rem is a POSITIVE SCALAR (the fraction of a barotropic
acceleration a layer still feels after one implicit-friction
step, MOM6 vertvisc_remnant), not a flux/velocity component,
so both face kernels are called
with negate=.false.: the 180-degree fold still swaps which side
of the seam the ghost value comes from, but the value itself does
not change sign, and the v-face fold-line duplicate DOF is forced
EQUAL (not opposite) across the seam. Call after the pair’s halo
exchange + periodic wrap (MOM6’s pass_visc_rem group pass, run
after every one of the three vertvisc_remnant calls). No-op
when not folding.