Procedures

ProcedureLocationProcedure TypeDescription
accel_visc_rem_reweight rdb_ocean_dyn Subroutine

accel_visc_rem post-apply reweight: vel = snap + rem·(vel − snap) — the whole explicit-tendency sum accumulated since the snapshot is attenuated by the per-layer viscous remnant (linearity ⇒ identical to weighting each tendency individually, MOM6 u = u_init + dt·visc_rem· (CAu + PFu + diffu)). Faces with rem == 1 (the unconditioned source=1.0 init, and every face before the first vdiff fills the producer) are SKIPPED, not rewritten — snap + 1·(vel−snap) is not an FP identity, and the skip keeps rem≡1 bitwise inert. Friction-dominated near-massless layers (rem → 0) keep their entry velocity. Public only for the unit-test suite. Under mem:separate this do concurrent runs on the device-resident arrays in production (all mapped on the ocean state); unit tests must map their own arrays explicitly. The masked write stays inside the do concurrent body (legal — no cross-iteration dep).

accel_visc_rem_snapshot rdb_ocean_dyn Subroutine

accel_visc_rem stage-entry snapshot: snap = vel, device-side. Public only for the unit-test suite. Under mem:separate this do concurrent runs on the device-resident arrays in production (both are mapped on the ocean state); unit tests must map their own arrays explicitly (!$acc enter data copyin / update self).

accumulate_flux_x rdb_continuity Subroutine

Accumulate one RK2 stage’s zonal mass flux into the windowed accumulator with the ½ RK2 weight baked in: uhtr += 0.5·mass_flux_x·dt. mass_flux_x is already area-weighted (m³/s = u·h_face·dy_cu); the product is m³.

accumulate_flux_y rdb_continuity Subroutine

Meridional analogue of accumulate_flux_x.

adcroft_recip rdb_ocean_metrics Function

Adcroft reciprocal: 1/x, but 0 -> 0 (zero-width faces give zero inverse, no NaN/Inf). Single source for every metric inverse (D4).

add_dataovr_entry rdb_config Subroutine

Register the four flat knobs of one &ocean_dataovr_nml tag. e is target, intent(in) for the same reason cfg is in every register_ocean_* above: the schema stores a pointer to the target and assigns through it at parse time, and the actual argument is always a component of the target cfg, so the association outlives this call.

add_err rdb_nml_schema Subroutine

Append a message to a growable error list.

add_top_drag_into_F_slow rdb_barotropic_coupling Subroutine

Add the ice-shelf top-drag tendency into the already-summed slow forcing. Separate from sum_slow_tendencies_into_F_slow (rather than a sixth term in it) for one reason: the top-drag slot is OPTIONAL all the way down the driver chain, and the sum above must stay a single unconditional kernel with no present branch inside its do concurrent.

Read more…
aniso_mode_is_implemented rdb_ocean_horizontal_viscosity Function

.true. iff the anisotropy-direction mode has an implemented direction tensor. Only mode 0 (grid-relative (n1,n2) = aniso_dir, a constant tensor) is built; the MOM6 flow-aligned modes are not ported. Drives the configure-time fail-loud guard in validate_config so a requested-but-unimplemented mode aborts the run instead of silently falling back to the grid-i default.

any_nan rdb_console_stats Function

ieee_is_nan OR-reduced across the five stats scalars.

append_val rdb_nml_schema Subroutine

Append one value token to the values buffer.

apply_bt_correction rdb_barotropic_coupling Subroutine

Replace the bt mode in the per-layer face velocities with the barotropic-substep end-step value, adding Δu·wt_k to every layer, Δu = u_bt_end − u_bt_at_n − dt·F_bt_u (same for v). Split-explicit convention (Hallberg 2009): momentum uses the END-of-step barotropic velocity; layer continuity earlier used the time-mean transports. Both legs of the corrector use the same end-step anchor (mismatched anchors overshoot the gravity-wave phase speed). Also rescales h_layer uniformly so the column total matches H_ref + η_end. hTr is deliberately NOT rescaled (would break exact tracer mass conservation; T = hTr/h drifts by O((η_end−η*_slow)/H) per step).

Read more…
apply_cartesian_degrees rdb_config Subroutine

Post-parse Cartesian domain sizing (MOM6 GRID_CONFIG=”cartesian” + AXIS_UNITS / LENLON / LENLAT). When &ocean_grid_nml len_lon/len_lat are set (> 0) on an ocean Cartesian grid, DERIVE the uniform &grid_nml dx/dy (metres) from the domain extent, the physical cell count (nx/ny = MOM6 NIGLOBAL/NJGLOBAL) and axis_units, exactly as MOM6’s set_grid_metrics_cartesian: degrees : dx = rad_earth · len_lon · π/180 / nx (arc length, no cos(lat)) km : dx = 1000 · len_lon / nx meters : dx = len_lon / nx and likewise dy from len_lat / ny. This runs BEFORE grid init, so the metrics, barotropic CFL and Coriolis all see the derived metres. Default (len_lon <= 0) leaves dx/dy untouched ⇒ bit-identical.

apply_clamped_meridional_north rdb_ocean_obc_baroclinic Subroutine
apply_clamped_meridional_south rdb_ocean_obc_baroclinic Subroutine
apply_clamped_zonal_east rdb_ocean_obc_baroclinic Subroutine
apply_clamped_zonal_west rdb_ocean_obc_baroclinic Subroutine
apply_diag_selection rdb_ocean_diag_derived Subroutine

Configure the ocean diagnostic set from the unified &ocean_diag_nml diags selection string. Single production entry point: parses spec once, registers the canonical defaults (consulting the spec for per-diagnostic :off skips and :cadence / :op / :coord overrides), then registers any spec entries that name a derived-catalog diagnostic (with their overrides).

Read more…
apply_factored_tracer rdb_ocean_vdiff Subroutine

Apply the pre-factored tridiagonal (from build_factorize_tracer_matrix) to one tracer: form T = hTr/h, run the Thomas RHS sweep + back-substitution against the stored pivots, and reconstitute hTr = T_new * h_layer. Operates on concentration so it conserves cell-centred T; h_layer and the factored a/b/c are read-only (shared across every tracer).

Read more…
apply_geothermal_src_impl rdb_ocean_geothermal Subroutine

Stamp src * wet_mask(i,j) onto the lowest massive layer of a tracer’s hTr array (first k with h_layer > h_min, scanning k = k_bot(i,j)..nz from the first live layer up), mirror into the matching budget contributor. Flat-impl over plain allocatables — the outer subroutine reaches ms%tracers(idx)%hTr on the host before calling this.

apply_layer_rho_init rdb_ocean_state Subroutine

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Helper: write per-layer density from layer_rho_init(:) when the caller has set at least one non-sentinel value. Sentinel is < 0; we expect exactly nz_ml non-sentinel entries listed in k=1..nz_ml order (bed → surface).

apply_maxvel_clamp rdb_ocean_dyn Subroutine

Truncate face velocities to |u| ≤ maxvel. MOM6’s MAXVEL analogue. Called once at the end of each outer step (after the RK2 average so the clipped state is what gets carried into the next stage). No-op when maxvel <= 0.

Read more…
apply_meridional_baroclinic rdb_ocean_obc_baroclinic Subroutine

Set south and north wall-face per-layer v. Mirror of apply_zonal_baroclinic for the y-direction.

apply_nudge_meridional_north rdb_ocean_obc_baroclinic Subroutine

Post-anomaly nudging for the north edge. “Incoming” at north = v_wall < 0 ⟹ tau_in.

apply_nudge_meridional_south rdb_ocean_obc_baroclinic Subroutine

Post-anomaly nudging for the south edge. “Incoming” at south = v_wall > 0 ⟹ tau_in.

apply_nudge_zonal_east rdb_ocean_obc_baroclinic Subroutine

Post-anomaly nudging for the east edge. “Incoming” at east = u_wall < 0 (westward, into domain) ⟹ tau_in.

apply_nudge_zonal_west rdb_ocean_obc_baroclinic Subroutine

Post-anomaly nudging for the west edge. “Incoming” at west = u_wall > 0 (eastward, into domain) ⟹ tau_in.

apply_one_pair rdb_nml_schema Subroutine

Consume one key = value [value...] starting at token ti; advance ti past the consumed tokens. Validates structure, unknown keys, duplicate keys, and applies via parse_tokens.

apply_orlanski_east rdb_ocean_obc_baroclinic Subroutine

Orlanski radiation for the east open edge (Orlanski 1976). Interior face index I = i_e-1 (1st), I-1 = i_e-2 (2nd). Outward normal = +x. dhdx = u(i_e-1) - u(i_e-2) (eastward gradient).

apply_orlanski_north rdb_ocean_obc_baroclinic Subroutine

Orlanski radiation for the north open edge (Orlanski 1976). Interior face J = j_n-1 (1st), J-1 = j_n-2 (2nd). Outward normal = +y. dhdx = v(j_n-1) - v(j_n-2) (northward gradient).

apply_orlanski_south rdb_ocean_obc_baroclinic Subroutine

Orlanski radiation for the south open edge (Orlanski 1976). Interior face J = j_s+1 (1st), J-1 = j_s+2 (2nd). Outward normal = -y. dhdx = v(j_s+1) - v(j_s+2) (southward gradient).

apply_orlanski_west rdb_ocean_obc_baroclinic Subroutine

Orlanski radiation for the west open edge (Orlanski 1976). Interior face index I = i_w+1 (1st), I-1 = i_w+2 (2nd). Outward normal = -x. dhdx = u(i_w+1) - u(i_w+2) (westward gradient). rx updated in-place; u_prev NOT updated here (done by the caller after all edges are set).

apply_surface_restore_2d_cover_impl rdb_ocean_surface_flux Subroutine

Ice-shelf-cover twin of apply_surface_restore_2d_impl: the open-water factor 1 - cover_frac composes multiplicatively with wet_mask, so a covered column receives EXACTLY zero restoring — and, because the same factor multiplies the budget mirror, exactly zero restoring shows up in the heat/salt surface budget there too. Separate _impl, not an in-loop present() test (house idiom).

apply_surface_restore_2d_impl rdb_ocean_surface_flux Subroutine

Stamp the per-step restoring increment dt·p·(target - surf)· wet_mask onto the top layer (k = nz) of a tracer’s hTr array and mirror it into the matching budget contributor. Explicit-shape dummies so NVHPC stdpar compiles device kernels against static bounds.

Read more…
apply_surface_src_2d_dyn_impl rdb_ocean_surface_flux Subroutine

Wet/dry variant of apply_surface_src_2d_impl: the DYNAMIC cell wet mask composes multiplicatively with the static one, so a dynamically dry column (total depth below &ocean_wetdry_nml dry_depth) receives NO surface flux — heating a mm-scale residual sliver would blow its temperature up (docs/ocean_wetdry_plan.md §4.4). Separate _impl (not an in-loop optional test): the knob-off path keeps the original kernel untouched, byte-identical.

apply_surface_src_2d_dyn_nobudget_impl rdb_ocean_surface_flux Subroutine

Wet/dry NOBUDGET twin — see apply_surface_src_2d_nobudget_impl and apply_surface_src_2d_dyn_impl.

apply_surface_src_2d_impl rdb_ocean_surface_flux Subroutine

Stamp inv_scale · Q_field(i,j) · wet_mask(i,j) onto the first LIVE layer (k_top(i,j)) of a tracer’s hTr array, mirror into the matching budget contributor. Explicit-shape dummies so NVHPC stdpar can compile device kernels against static bounds.

Read more…
apply_surface_src_2d_nobudget_impl rdb_ocean_surface_flux Subroutine

Byte-for-byte copy of apply_surface_src_2d_impl with the budget dummy and its accumulation line removed — the pseudo-salt mirror of salinity’s surface flux, which by contract (budget_id = TRACER_BUDGET_NONE) must not touch salt_budget_surface. Separate _impl, not an in-loop present(budget) test (house idiom, see apply_surface_src_2d_dyn_impl’s docstring) — this keeps the production S/T impl untouched and the increment hTr receives bit-identical to salinity’s.

apply_sw_and_restore rdb_ocean_dyn Subroutine

The two cell-centred surface kernels that do NOT route through the assembler’s Q_heat / Q_salt, with their ice-shelf-cover dispatch. Shortwave penetration reads a pristine q_sw component (or moves a lump the masked deposit never added) and restoring forms its flux in-kernel from the live SST/SSS, so each needs the cover factor of its own; everything else the atmosphere contributes is already masked inside ocean_surface_flux_assemble.

Read more…
apply_sw_penetration_cover_impl rdb_ocean_surface_flux Subroutine

Ice-shelf-cover twin of apply_sw_penetration_impl: the open-water factor 1 - cover_frac composes multiplicatively with wet_mask into the column irradiance I0, so a fully covered column neither removes the surface lump nor deposits a profile — it is left EXACTLY untouched. Separate _impl, not an in-loop present() test (house idiom, see apply_surface_src_2d_dyn_impl) — the cover-off path keeps the original kernel byte-identical.

Read more…
apply_sw_penetration_impl rdb_ocean_surface_flux Subroutine

Per-column two-band shortwave redistribution. Explicit-shape dummies so NVHPC stdpar compiles device kernels against static bounds. Difference form (I(d_top) - I(d_bot)) — no division by h, so a vanishing layer (h → 0 ⇒ d_top == d_bot) absorbs zero automatically with no guard. The transmission T(d) is the shared sw_transmission (same-module ⇒ inlined by NVHPC), so the deposition and the boundary-layer coupling cannot diverge.

Read more…
apply_time_unit_cascade rdb_config Subroutine

Post-parse time-unit fixup shared by the file + string config paths. t_end, status_interval, ocean_diag%dt_out are given in time_unit from &time_nml; multiply through to SI seconds. dt_fixed/dt_max stay in seconds; default time_unit="s" gives a 1× factor (bit-identical to before).

apply_velocity_truncation rdb_ocean_dyn Subroutine

Post-RK2 velocity housekeeping: the advective-CFL truncation (E7) followed by the absolute maxvel cap. Called once at the end of each outer step (after the RK2 average, before the ALE remap) so the carried-forward / remapped velocity field is bounded. Replaces the bare apply_maxvel_clamp call at both ocean_dyn_step / ocean_dyn_step_split sites.

Read more…
apply_w_to_h_layer rdb_ocean_vertical_advection Subroutine

h_layer(k) += dt * (w(k) - w(k+1)) per cell. Bed and surface interfaces feed through whatever w the caller set (zero for the bed by default after compute_w_from_continuity with enforce_bed_bc = true). No h-floor — plain accumulation; the caller is responsible for guarding against negative thickness if the prescribed w + dt is large.

apply_zonal_baroclinic rdb_ocean_obc_baroclinic Subroutine

Set west and east wall-face per-layer u to Flather mean + zero-gradient baroclinic anomaly (radiating edges) or uniform clamped_u (CLAMPED edge). Explicit-shape dummies; one do concurrent per edge (j outer, k inner).

arr_bytes rdb_mem_report Interface

Byte footprint of an allocatable array (0 when unallocated), so a gated-off slot naturally contributes nothing to a counted total. The COUNTED companion to the runtime’s MEASURED free-memory delta: each *_state_t sums its own arrays through this, the driver reports the total before enter_data (works on CPU builds too, where there is no device query), and mem_log_device_actuals reconciles the count against the measured mapping — a state array added without a matching bytes() term makes the measured map exceed the count and self-announces the drift (the anti-rot guard for the otherwise rot-prone per-slot count).

arr_bytes_i1 rdb_mem_report Function
arr_bytes_i2 rdb_mem_report Function
arr_bytes_i3 rdb_mem_report Function
arr_bytes_l1 rdb_mem_report Function
arr_bytes_l2 rdb_mem_report Function
arr_bytes_l3 rdb_mem_report Function
arr_bytes_r1 rdb_mem_report Function
arr_bytes_r2 rdb_mem_report Function
arr_bytes_r3 rdb_mem_report Function
arr_bytes_r4 rdb_mem_report Function
assign_h_layer rdb_ocean_min_thickness Subroutine

Copy the target field into h_layer on grounded columns only — non-grounded columns’ h_new was never written, and their old h_layer is already the exact target.

barotropic_state_bytes rdb_barotropic_state Function

Counted allocatable footprint of the ocean C-grid barotropic slot.

barotropic_state_destroy rdb_barotropic_state Subroutine

Tear down host allocations. Call exit_data first — destroying a still-device-mapped state leaks device memory silently.

barotropic_state_enter_data rdb_barotropic_state Subroutine

Attach the C-grid barotropic allocatables to the device. The parent struct is mapped by the orchestrating routine. Read+write fields use copyin; pure-workspace fields use create.

barotropic_state_enter_data_impl rdb_barotropic_state Subroutine
barotropic_state_exit_data rdb_barotropic_state Subroutine

Reverse of enter_data — copy out prognostic fields, drop scratch. Caller detaches the parent struct after this returns.

barotropic_state_exit_data_impl rdb_barotropic_state Subroutine
barotropic_state_init rdb_barotropic_state Subroutine

Allocate every C-grid barotropic array zero-filled. East-face arrays are (nx+1, ny), north-face (nx, ny+1). Scalars (manning_n, coriolis_f) are populated by state_init_from_config afterwards.

barotropic_substep_linear rdb_barotropic_substep Subroutine

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Linearized barotropic-substep kernel. Forward-Euler steps the barotropic state (eta, ubt, vbt) at dt_inner for n_steps against the constant slow forcing force_u, force_v (each at the same C-grid location as ubt, vbt). Accumulates the per-step running sums into ubt_sum, vbt_sum, eta_sum; at the end divides by n_steps and stores the time-mean back into bt_eta, bt_ubt, bt_vbt for the caller.

Read more…
barotropic_substep_nonlinear rdb_barotropic_substep Subroutine

Nonlinear barotropic substep. Same time-mean accumulator pattern as barotropic_substep_linear but the per-substep dynamics include the three barotropic nonlinearities that matter for MOM6-grade physics:

Read more…
barotropic_substep_nonlinear_interior rdb_barotropic_substep Subroutine

Interior (normal-width) entry point for the nonlinear barotropic fast loop. Unpacks the bt_work fast-loop arrays and forwards them to barotropic_substep_nonlinear (bt_halo=0), so the ~20-array plumbing lives here once instead of at every call site. The optional bc/t/eta_forcing propagate by absence (F2018 15.5.2.13), so this single entry reproduces the former present()-branch call variants bit-for-bit. See bt_wide_substep for the wide-halo march-in twin.

barotropic_workstate_bytes rdb_barotropic_workstate Function

Counted allocatable footprint of the barotropic fast-loop work state (BTCL_u/v derived-type coeffs excluded) slot (0 when unallocated).

barotropic_workstate_destroy rdb_barotropic_workstate Subroutine
barotropic_workstate_enter_data rdb_barotropic_workstate Subroutine

Attaches component arrays only — no bare copyin(this) (the polymorphic stack descriptor caused AMD libomptarget cross-slot overlap). The workstate descriptor reaches the device via the root copyin(state%ocean) (bt_work is inline all the way up); the per-slot copyin was a competing second mapping that cost ~36% of the fast loop.

barotropic_workstate_enter_data_impl rdb_barotropic_workstate Subroutine
barotropic_workstate_exit_data rdb_barotropic_workstate Subroutine
barotropic_workstate_exit_data_impl rdb_barotropic_workstate Subroutine
barotropic_workstate_init rdb_barotropic_workstate Subroutine

Allocate the 2D barotropic-substep arrays. Pass nz_ml to also allocate the split-driver slow-tendency accumulators; omit when only the 2D barotropic substep is needed (unit tests).

bathy_io_ok rdb_bathymetry Function

Translate a raw nc_check-style status (0 = ok) from one of the nc_* reader calls in load_bathymetry_into_array into the caller’s ierr contract: .true. on success; on failure, .false. with ierr = OCEAN_STATUS_ERR_IO when ierr is present (closing ncid first, when given, so a mid-read failure does not leak the file handle), or error stops with the SAME generic text nc_check itself would have used had ierr never been threaded through — keeps the legacy (no ierr) behaviour byte-identical while unblocking the ierr-present return path (F1/F2 of the P0.1 review).

bathymetry_fill_ghosts_array rdb_ocean_bathymetry_inject Subroutine

Fill ghost-cell bathymetry by constant extrapolation from the nearest interior cell. Deliberate duplicate of rdb_bathymetry::fill_bathymetry_ghosts_array — see the module docstring for why this module cannot use that one.

bathymetry_median rdb_ocean_bathymetry_inject Function

Approximate median via a full sort — b is a setup-time array (called once per create(), never per-step), so O(n log n) is fine; this exists purely to make the sign-error message name a representative depth rather than minval/maxval (which a single outlier cell would distort).

bathymetry_normalise_sign rdb_ocean_bathymetry_inject Subroutine

In-place sign-normalise b (any shape — interior or full array, the caller decides what it passes) to Roundabout’s positive-down depth convention, then validate on the NORMALISED array: zero wet cells (b > LAND_DEPTH_THRESHOLD) is rejected as OCEAN_STATUS_ERR_BATHYMETRY_SIGN, naming the median depth and the convention that was requested, so the caller can see at a glance that the OTHER convention was probably meant. NOT a “no negatives” check (see module docstring) — a majority-negative but non-empty wet fraction is accepted (legal under wet/dry).

bbl_column_conc_impl rdb_ocean_vdiff Subroutine

Cell concentrations of one tracer through THE vanished-layer column rule (rdb_vl_column_conc): hTr/h on a live layer, the donor’s concentration on a filler, never a quotient by a near-zero or negative thickness.

bbl_faces_impl rdb_ocean_vdiff Subroutine

Per-face body of vdiff_set_viscous_bbl (see there). x_face selects the u-faces (nx+1, ny) (cells i-1, i) or the v-faces (nx, ny+1) (cells j-1, j).

bbl_glue_is_effective rdb_config Function

Will &ocean_vdiff_nml bbl_glue actually be ON after setup?

Read more…
bdrag_variant_is_implemented rdb_ocean_bottom_drag Function

.true. only for a bottom-drag variant with a real kernel (BDRAG_LINEAR / BDRAG_QUADRATIC). BDRAG_INVALID returns .false.. The single gate validate_config consumes (PR-6).

beta5_0 rdb_coriolis_adv Function
beta5_1 rdb_coriolis_adv Function
beta5_2 rdb_coriolis_adv Function
beta7_0 rdb_coriolis_adv Function
beta7_1 rdb_coriolis_adv Function
beta7_2 rdb_coriolis_adv Function
beta7_3 rdb_coriolis_adv Function
bipolar_corner_latlon rdb_ocean_bipolar Subroutine

Map a logical cap location to geographic (lat, lon) in degrees. lam_deg : pseudo-longitude (geographic lon at the join ring), any real (wrapped internally); the i-direction. s : cap-row fraction, 0 = join ring (lat = phi_join), 1 = fold line; the j-direction. phi_join: join latitude (deg); cap covers lat > phi_join. lon_pole: longitude (deg) of the first cap pole; partner at lon_pole + 180.

bipolar_pole_lat rdb_ocean_bipolar Function

Latitude (deg) of the two cap poles — they sit ON the join latitude, so this is simply phi_join.

bkgnd_henyey_conflicts_profile rdb_ocean_vmix Function

.true. when both background schemes are selected at once.

Read more…
boole_dpa_face rdb_ocean_pgf_reconstruct Subroutine

HORIZONTAL (cross-face) Boole quadrature of the layer pressure increment dpa = g * int rho' dz — the face integral the FV pressure-gradient contour needs (Adcroft, Hallberg & Harrison 2008 §3; Yung, Hallberg, Adcroft & Morrison 2026 §2.4).

Read more…
boole_dpa_face_pcm rdb_ocean_pgf_reconstruct Subroutine

The cross-face Boole quadrature of boole_dpa_face for a CONSTANT-BY-LAYER (PCM) T/S column, with MOM6’s near-bottom mass-weighting of the interpolated T/S (MOM6 int_density_dz_generic_pcm, intx_dpa).

Read more…
boole_dpa_face_wright rdb_ocean_pressure_force Subroutine

boole_dpa_face with the Wright (1997) vertical rule boole_dpa_intz_layer_wright at each of the five sub-columns – identical sub-columns, weights and summation order, no eos_t handle. 15 inline Wright density evaluations per face per layer (the end points are the columns’ own dpa).

boole_dpa_intz_layer rdb_ocean_pgf_reconstruct Subroutine

5-point Boole-quadrature density-anomaly integral over one layer (Adcroft, Hallberg & Harrison 2008; White, Adcroft & Hallberg 2009). Returns the layer-integrated pressure-anomaly increment dpa = g * int rho' dz and its first moment (from the layer TOP edge inward) intz_dpa = 0.5 * g * dz^2 * bracket.

Read more…
boole_dpa_intz_layer_wright rdb_ocean_pressure_force Subroutine

boole_dpa_intz_layer specialised to Wright (1997): the same five sub-points and weights, with the density written inline (wright_rho, the expression eos_density_point evaluates) – no eos_t handle, no per-point variant dispatch. The caller selects this twin ONCE, outside its loops.

boole_layer_combine rdb_ocean_pressure_force Subroutine

Boole weights of the five sub-point density anomalies r5 (top to bottom): dpa = g*dz*<rho'> and the first moment from the top.

boole_layer_points rdb_ocean_pressure_force Subroutine

The five sub-point (T, S, p) triples of the in-layer Boole rule, top (n = 1) to bottom (n = 5), for the per-EOS twins – the same points boole_dpa_intz_layer writes out in place.

boundary_edges_linear rdb_ocean_pressure_force Subroutine

Linear-exact one-sided edge pair for a BOUNDARY layer (k=1 or k=nz), where a centred slope has no second neighbour.

Read more…
boundary_half_jump rdb_remap_column Subroutine

Linear-exact half-jump across a BOUNDARY cell (k=1 or k=nz), where a centred stencil has no second neighbour.

Read more…
bt_auto_n_inner rdb_ocean_setup Function

Smallest barotropic substep count n_inner such that the substep dt_outer/n_inner satisfies the 2-D external-gravity-wave CFL: dt_bt <= cfl_safety * l_cfl / c_ext, with l_cfl the 2-D CFL length (metrics_bt_cfl_length) and c_ext the external wave speed sqrt(g*H_max). MOM6 set_dtbt analogue, now with the cross-direction term included (the legacy estimate used a 1-D length and under-counted n_inner by ~sqrt(2) on square cells, leaving the effective 2-D CFL at ~0.92 for cfl_bt_safety=0.65 — on the edge of the forward-backward scheme’s stability).

bt_auto_n_inner_from_dt rdb_ocean_setup Function

Smallest n_inner >= 1 with dt_outer/n_inner <= dt_bt_safe, for an ALREADY-LIMITED safe barotropic substep dt_bt_safe (s) — the per-wet-cell minimum bt_cfl_dt_wet returns, reduced across ranks. bt_auto_n_inner is this with dt_bt_safe formed from a single (c_ext, l_cfl) pair.

bt_cfl_dt_wet rdb_ocean_setup Subroutine

Per-WET-CELL external-gravity-wave CFL limit (MOM6 set_dtbt):

Read more…
bt_halo_auto_exclusion rdb_config Subroutine

Single source of truth for the BT march-in exclusion set (mirrors the explicit-bt_halo > 0 fail-loud checks in validate_config). Reports whether ANY exclusion is active and names the first one (for the AUTO resolution log). When none is active, reason is “”.

bt_rem_open_impl rdb_barotropic_coupling Subroutine

compute_bt_rem under &vcoord_nml zfixed_closed_faces: the same H/(H + r·hbbl·dt_inner) with H = Σ_k h_face·open (the OPEN-column centred face depth, the weight face_depth_mean_* uses). A face whose every layer is closed has H = 0 and keeps bt_rem = 1, exactly like a dry face on the original path (it carries no barotropic transport: dy_cu_bt = 0 there).

bt_rem_wave_drag_open_impl rdb_barotropic_coupling Subroutine

compute_bt_rem_wave_drag under &vcoord_nml zfixed_closed_faces: MULTIPLIES H/(H + r_H·dt_inner) into bt_rem with the OPEN-column face depth H = Σ_k h_face·open (the bt_rem_open_impl depth). H <= 0 (every layer closed) ⇒ unmodified, MOM6’s guard.

bt_wide_bytes rdb_ocean_bt_wide Function

Counted allocatable footprint of the wide-halo BT shadow state (0 when unallocated, i.e. whenever &ocean_bt_nml bt_halo = 0).

Read more…
bt_wide_copy_in rdb_ocean_bt_wide Subroutine

Offset-copy normal-width input arrays into the wide shadow arrays. Dispatches to the non-polymorphic _impl body to avoid the class-box GPU descriptor issue (same pattern as enter/exit_data).

bt_wide_copy_in_impl rdb_ocean_bt_wide Subroutine

Non-polymorphic copy_in body. Offset = bt_halo: w_X(iw, jw) = X(clamp(iw-off), clamp(jw-off)) over the FULL wide extent — the inner band is a direct offset copy; the outer bt_halo ring is a clamped-index (constant-extrapolation) fill. The ring fill matters: without it the ring carries stale end-of-fast-loop values from the previous stage (H_ref = 0, eta from t-1), which at a PHYSICAL (non-seam) edge is never refreshed by any exchange and free-runs an inconsistent zero-depth integration that blows up in O(25) outer steps. At an MPI seam the ring is immediately overwritten with true neighbour data by entry_exchange, so the clamped fill only governs physical edges — the same sane ghost-band construction the v1 normal-width path gets from its own ghosts. Scratch / accumulator arrays (w_eta_new, w_ke, w_eta_sum, …) do not need copy-in — the substep initialises them.

bt_wide_copy_out rdb_ocean_bt_wide Subroutine

Offset-copy wide output arrays back to the normal-width arrays. Dispatches to the non-polymorphic _impl body.

bt_wide_copy_out_impl rdb_ocean_bt_wide Subroutine

Non-polymorphic copy_out body. X(i,j) = w_X(i+off, j+off) over the full normal index range. Outputs: time-mean eta/ubt/vbt, uhbt/vhbt, *_end snapshots.

bt_wide_destroy rdb_ocean_bt_wide Subroutine

Deallocate all wide state.

bt_wide_enter_data rdb_ocean_bt_wide Subroutine

Attach all wide arrays (and wide metrics leaf arrays) to the GPU present table. The containing ocean_dyn_t is already mapped by the caller; this routine attaches the components.

bt_wide_enter_data_impl rdb_ocean_bt_wide Subroutine

Non-polymorphic enter_data body (avoids class-box GPU descriptor issue).

bt_wide_entry_exchange rdb_ocean_bt_wide Subroutine

One wide grouped exchange (eta+ubt+vbt) + wide singles for the other 7 input arrays (H_ref, ubt_prev, rem_u, force_u, vbt_prev, rem_v, force_v). Fills the entire wide ghost band before the fast loop. Counter effect: +1 bt_group, +1 centre_2d, +3 face_x_2d, +3 face_y_2d. Dispatches to the non-polymorphic _impl body.

bt_wide_entry_exchange_impl rdb_ocean_bt_wide Subroutine

Non-polymorphic entry_exchange body.

bt_wide_exit_data rdb_ocean_bt_wide Subroutine

Detach all wide arrays from the GPU present table.

bt_wide_exit_data_impl rdb_ocean_bt_wide Subroutine

Non-polymorphic exit_data body.

bt_wide_init rdb_ocean_bt_wide Subroutine

Allocate the wide shadow state. Builds grid_w (same nx_phys/ny_phys as grid, nghost = grid%nghost + bt_halo), fills wide metrics via the same formula generator, fills wide f_corner. grid_config must be GRID_CONFIG_CARTESIAN or GRID_CONFIG_SPHERICAL; supergrid/tripolar are excluded at configure time.

bt_wide_substep rdb_ocean_bt_wide Subroutine

Wide-halo (march-in) entry point for the nonlinear barotropic fast loop. Unpacks the wide shadow arrays (w_*, wide grid/metrics, wide f_corner) and forwards them to barotropic_substep_nonlinear with bt_halo = bt_wide%bt_halo, so the ~20-array plumbing lives here once rather than at the call site. bc propagates by absence. Tides (eta_forcing) are a configure-time exclusion on the wide path, so none is forwarded. Interior twin: barotropic_substep_nonlinear_interior.

budget_area_field rdb_ocean_budgets Subroutine

Per-cell T-area (m²) for physical integrals: cached metrics areaT once set_area has run, else uniform grid%dx·grid%dy.

budget_total_ke rdb_ocean_budgets Function

Total KE: Σ over masked interior of 0.5·h·(u²+v²)·areaT·weight, u/v averaged from C-grid faces to centres. Public only for tests.

budget_total_mass rdb_ocean_budgets Function

Total mass: Σ over masked interior of h_layer·areaT·weight over k. Units: m³. Public only for the unit-test suite.

budget_total_tracer rdb_ocean_budgets Function

Total tracer content: Σ over masked interior of hTr·areaT·weight over k. hTr is thickness-weighted, so this is ∫(tracer·volume), the conserved quantity. Public only for the unit-test suite.

build_factorize_tracer_matrix rdb_ocean_vdiff Subroutine

Build the backward-Euler tridiagonal per cell column and run the Thomas forward factorization — the tracer-INDEPENDENT half of the vertical-diffusion solve (depends only on kv/h/dt). Run once per stage; every registered tracer then reuses the factored coefficients via apply_factored_tracer.

Read more…
build_grounded_mask rdb_ocean_min_thickness Subroutine

ONE coalesced pass: mask(i,j,1) = 1.0 iff any layer of column (i,j) is strictly below the floor; n_grounded counts them (explicit OpenACC reduction — a sum() on a present-mapped array would run host-side under NVHPC non-managed mode and read the stale shadow).

build_pending_handle rdb_ocean_api Subroutine

Shared prefix of rdb_ocean_create_from_string AND rdb_ocean_create_pending (P2.5): allocate a handle, parse + validate the config, check dt_fixed. Does NOT touch g_handle_live — callers set it themselves once they know which of the two flows they are in (immediate complete_ocean_create vs staying pending for geometry injection).

Read more…
build_rdb_schema rdb_config Subroutine

Register the validated groups + the still-external groups onto schema, capturing defaults from cfg.

build_target_field rdb_ocean_min_thickness Subroutine

target. Non-grounded columns are SKIPPED — their h_new is never read downstream (every consumer falls back to h_old via the mask).

build_ts_concentration rdb_ocean_remap Subroutine

Build layer-mean T/S concentrations (c = hTr/h) from extensive tracer content + pre-remap thicknesses, for the VCOORD_RHO density inversion. Per-layer rdb_vl_conc (a filler reads hTr/h, its donor’s concentration by I1′; a zero-thickness layer reads 0). Flat-impl, explicit-shape; one cadence-bounded launch per remap.

build_z_ctr rdb_ocean_z_init Subroutine

Layer-centre GEOPOTENTIAL depths (positive-down from the z = 0 datum) from a column of layer thicknesses. Bottom-up: k=1 bed, k=nz_ml surface. z_ctr(k) = z_top + sum_{k'=k+1..nz_ml} h(k') + 0.5*h(k).

Read more…
c_to_f_string rdb_ocean_api Subroutine

Convert a bind(c) character(kind=c_char) buffer + explicit length into a Fortran allocatable string. No null-termination assumption — c_len is authoritative (matches the recovered precedent’s convention).

canonical_diag_catalog_name rdb_ocean_diag_fills Function

Name of canonical-catalog entry i (1-based). Public for the P7 discoverability C ABI and the unit-test suite.

canonical_diag_catalog_size rdb_ocean_diag_fills Function

Number of names in the canonical-diagnostic catalog (the static set register_default_diags MAY register — some entries are gated, see canonical_diag_gate_hint). Bounds for canonical_diag_catalog_name’s index argument. Public for the P7 discoverability C ABI (rdb_ocean_canonical_catalog_size) and the unit-test suite.

canonical_diag_gate_hint rdb_ocean_diag_fills Function

The namelist gate whose closure suppresses canonical diagnostic name, for the “you asked for this and did not get it” warning. "" for the four unconditional diagnostics (SSH/u/v/KE) — a hint of "" means “this one should have registered; that is a bug, not a config”. MUST be kept in lock-step with register_default_diags’s gates; the count of non-empty hints must equal the number of conditionally-registered canonical diagnostics (test_ocean_diag/diag_gate_hint_covers_every_gate is the lock — any PR that adds a new gated canonical diagnostic must add its hint here or that test fails). This duplicates the gate NAMES only, never the gate LOGIC — the single if in register_default_diags remains the one place the gate is evaluated.

catalog_name_list rdb_ocean_diag_derived Function

Comma-separated list of catalog diagnostic names (for error text).

cavity_apply_land_exclusion rdb_ocean_cavity Subroutine

NO ICE OVER LAND (design rule R2): force z_draft = 0 on every column the bathymetry already calls land (b < LAND_DEPTH_THRESHOLD), and report how many were touched so the caller can log it.

Read more…
cavity_bound_to_grid rdb_ocean_state Function

Convert ONE shelf-box bound from metres to grid coordinate units, leaving the CAVITY_BOUND_INF “no limit” sentinel alone. Without the guard the sentinel would be scaled by the degrees-per-metre factor on a spherical grid and come out as a finite (if absurd) bound — harmless numerically, but it would stop meaning what it says, and the next reader would have to re-derive that.

cavity_buoyancy_flux rdb_ocean_cavity_melt Function

Interfacial buoyancy flux B_b (m^2/s^3), NEGATIVE = stabilising — Yung et al. (2025) eq. (6) p. 5831,

Read more…
cavity_comp_apply_impl rdb_ocean_cavity_flux Subroutine

The volume_compensation = "uniform_open_ocean" sink: remove dw metres of the top layer from every wet cell the ice does NOT cover, the removed parcel carrying that cell’s own T and S so no concentration there changes.

Read more…
cavity_comp_scale_tracer_impl rdb_ocean_cavity_flux Subroutine

Apply the compensation sink’s top-layer ratio to one PASSIVE tracer’s load. Unconditional (scale = 1 off the sink), so there is no mask branch inside the kernel.

cavity_comp_withdrawal rdb_ocean_cavity_flux Function

The uniform per-unit-area thickness the uniform_open_ocean sink removes: vol_melt/area_open, and exactly zero when there is no open ocean to remove it from (a fully ice-covered domain — the sink then does nothing rather than dividing by zero, and the volume stays in, which the mass budget reports honestly as a growing total).

Read more…
cavity_count_grounded rdb_ocean_cavity Subroutine

Count the INTERIOR columns the cavity grounds: wet bed (b >= LAND_DEPTH_THRESHOLD) but water thickness b - z_draft < h_min. Interior-only, because the ghost band carries extrapolated bathymetry and would bias the fraction the grounded_max_frac sanity bound is taken against.

cavity_count_unloaded_p_top rdb_ocean_setup Function

Count cells whose top-of-column pressure does NOT carry the isostatic ice load — the melt path’s guard that configure_ocean_cavity (the sole ms%p_top producer) ran, and ran before this check.

Read more…
cavity_count_zero_f rdb_ocean_setup Function

Count ice-covered WET columns sitting at exactly f = 0 — the configure-time domain check for exchange_law = "hj99".

Read more…
cavity_datum_impl rdb_ocean_cavity Subroutine

The BAROTROPIC DATUM: bt_H_ref = b - z_draft on a column that has water under the ice, and exactly 0 on one that is GROUNDED (b - z_draft < h_min, i.e. land by the very rule seed_wet_mask_impl applies).

Read more…
cavity_datum_residual rdb_ocean_cavity Function

Max violation of the counted-once invariant (I) in METRES of reference depth, over the WET columns: max |bt_H_ref - (b - z_draft)| where b - z_draft >= h_min.

Read more…
cavity_diff_impl rdb_ocean_diag_derived Subroutine

a - b with the cavity missing-value convention.

cavity_draft_apply_sign rdb_ocean_cavity Subroutine

Normalise a freshly loaded draft field onto Roundabout’s convention (DEPTH, positive down, >= 0).

Read more…
cavity_draft_is_finite_nonneg rdb_ocean_cavity Function

Configure-time guard: every draft entry is finite and >= 0.

Read more…
cavity_draft_is_uniform rdb_config Function

Is the configured ice-shelf draft UNIFORM over the whole array?

Read more…
cavity_exchange_velocities rdb_ocean_cavity_melt Subroutine

Exchange-velocity dispatch with the Coriolis parameter taken from the bundle (par%f_cor). Thin wrapper over cavity_exchange_velocities_f, which holds the dispatch.

cavity_exchange_velocities_f rdb_ocean_cavity_melt Subroutine

Exchange-velocity dispatch — ONE argument list for every law, so a later do concurrent kernel dispatches with a single select case and no reshaping. l_plus is the viscous Obukhov scale of the CURRENT iterate: the single scalar that carries the stratification feedback for every implicit law. Pass CAVITY_L_PLUS_NEUTRAL for the neutral / unsuppressed evaluation.

Read more…
cavity_far_field_impl rdb_ocean_cavity_flux Subroutine

Thickness-weighted mean of (T, S, u, v) over far_depth METRES below the ice base, with a PARTIAL last layer.

Read more…
cavity_fill_cover_frac rdb_ocean_cavity Subroutine

v1 ice-cover fraction: BINARY, 1 wherever there is any draft. An area-blended calving front (a partially covered cell) is a melt-physics decision, not a geometry one, so it is deliberately left for the slice that needs it — the field exists now only so that slice does not have to re-open the metrics lifecycle.

cavity_fill_p_ice_ref rdb_ocean_cavity Subroutine

p_ice_ref = (rho_ref*GRAVITY) * z_draft (Pa).

Read more…
cavity_flux_fill_impl rdb_ocean_cavity_flux Subroutine

Fill the two OWNED surface-flux components from the solved interface. FULL OVERWRITE of the whole plane, never += — the same rule the sea-ice coupler’s fillers follow, and for the same reason (a += ratchets across outer steps with no bound).

Read more…
cavity_gamma_hj99 rdb_ocean_cavity_melt Subroutine

Holland & Jenkins (1999) eqs. (14)-(18) p. 1792:

Read more…
cavity_gamma_yung25 rdb_ocean_cavity_melt Subroutine

Yung et al. (2025) “StratFeedback”, eqs. (7)-(8) p. 5832:

Read more…
cavity_heat_fluxes rdb_ocean_cavity_melt Subroutine

The three heat fluxes of (E2), W/m^2:

Read more…
cavity_ice_terms rdb_ocean_cavity_melt Subroutine

(c_i_eff, kh) for the requested ice-conduction mode — the two numbers through which every mode enters the quadratic.

Read more…
cavity_l_plus_from_state rdb_ocean_cavity_melt Function

Viscous Obukhov scale L+ = L/delta_nu with delta_nu = nu/u*, i.e. L+ = -u*^4/(nu*kappa*B_b) — Yung et al. (2025) eq. (5) p. 5831; the same definition in Vreugdenhil & Taylor (2019) eq. (27) and Rosevear et al. (2022) eqs. (6)+(8) p. 2592. POSITIVE for melting. Returns CAVITY_L_PLUS_NEUTRAL for a vanishing buoyancy flux.

cavity_l_plus_is_neutral rdb_ocean_cavity_melt Function

Is this trial L+ the neutral / unsuppressed limit?

Read more…
cavity_law_is_implicit rdb_ocean_cavity_melt Function

Does this law’s (gamma_t, gamma_s) depend on the interfacial buoyancy flux — and therefore on the melt rate it produces? Yung et al. (2025) p. 5833 states the consequence: “Since the transfer coefficients depend on L+, which in turn depends on melt rate via surface buoyancy forcing, iteration is required for convergence of the three-equation parameterisation solution.”

cavity_m_ice_from_mass rdb_ocean_cavity_melt Function

Solid-ice thickness rate (m/s) from the canonical mass flux, m_ice = m_mass/rho_i. REPORTING ONLY — this is Jenkins, Nicholls & Corr (2010)’s a_b convention.

cavity_m_weq_from_mass rdb_ocean_cavity_melt Function

Freshwater-equivalent thickness rate (m/s) from the canonical mass flux, m_weq = m_mass/rho_fw. REPORTING ONLY — this is ISOMIP+’s m_w (Asay-Davis et al. (2016) eq. (24) p. 2485), the number their figures are in.

cavity_mask_impl rdb_ocean_diag_derived Subroutine

Copy a 2-D cavity field into the diag buffer, writing IEEE NaN wherever the column was not solved. Every cavity fill that is a plain read of a slot array routes through here, so the missing-value convention cannot drift between them.

cavity_mass_apply_impl rdb_ocean_cavity_flux Subroutine

The real-mass top-layer source: add the meltwater VOLUME to h_layer at the first LIVE layer k_top(i,j), replace the virtual salt flux the assembler stamped with the real advective salt w*s_ice, and add the enthalpy dh*T_b — mirroring both tracer increments into the existing surface budget contributors.

Read more…
cavity_mass_salt_mirror_impl rdb_ocean_cavity_flux Subroutine

The pseudo-salt mirror of cavity_mass_apply_impl’s SALT increment, with no budget accumulation — budget_id = NONE, so it must not touch salt_budget_surface.

Read more…
cavity_mass_thin_is_fatal rdb_ocean_cavity_flux Function

Is this step’s clamped-withdrawal tally a FAIL-LOUD condition?

Read more…
cavity_mass_totals_impl rdb_ocean_cavity_flux Subroutine

The two INTERIOR integrals the mass budget and the compensation sink need, reduced on device in one pass:

Read more…
cavity_melt_columns rdb_ocean_cavity_melt Subroutine

Data-parallel driver: solve n independent columns.

Read more…
cavity_melt_columns_2d rdb_ocean_cavity_melt Subroutine

Masked 2-D driver: form the friction velocity and solve the interface on every ICE-COVERED column of an (nx, ny) plane, leaving the rest untouched at exactly zero.

Read more…
cavity_melt_point rdb_ocean_cavity_melt Subroutine

Scalar entry point returning only what a coupling seam consumes: the interface state, the canonical melt mass flux and the ocean -> interface heat flux. A thin wrapper over cavity_solve_melt that keeps the solution BUNDLE inside the callee, so a do concurrent over columns needs no derived-type local(...) clause at all — each iteration writes its own array elements.

cavity_melt_point_gamma rdb_ocean_cavity_melt Subroutine

cavity_melt_point plus the two EXCHANGE VELOCITIES the solve converged on.

Read more…
cavity_melt_point_gamma_f rdb_ocean_cavity_melt Subroutine

cavity_melt_point_gamma with the Coriolis parameter passed as a per-column SCALAR — what cavity_melt_columns_2d calls, so no device code has to build a modified ocean_cavity_exchange_t (see cavity_exchange_velocities_f).

cavity_melt_status_is_fatal rdb_ocean_cavity_flux Function

Is this step’s status tally a FAIL-LOUD condition?

Read more…
cavity_obukhov_length rdb_ocean_cavity_melt Function

Dimensional Obukhov length L = -u*^3/(kappa*B_b) (m), POSITIVE for a stabilising (melting) buoyancy flux. McPhee, Maykut & Morison (1987) p. 7029; the same scale appears as Yung et al. (2025) eq. (5) p. 5831. (Holland & Jenkins (1999) uses L_O in their eq. (18) but never defines it.)

Read more…
cavity_outer_residual rdb_ocean_cavity_melt Function

Outer-iteration residual G(x) = ln(L+_new(x)) - x, with the destabilising branch folded in: a non-positive, non-finite or sentinel L+_new means the buoyancy flux at this iterate is destabilising (or zero), which every law treats as L+ = +infinity, so G = +infinity. Mapping it that way keeps the bisection bracket valid instead of taking log() of a negative number.

cavity_resolve_gamma_s rdb_ocean_setup Function

Resolve the &ocean_cavity_melt_nml gamma_s “unset” sentinel to the ISOMIP+ default gamma_t/CAVITY_GAMMA_RATIO_ISOMIP (Asay-Davis et al. (2016) Table 4 p. 2483; the 35 is Jenkins, Nicholls & Corr (2010) p. 2309).

Read more…
cavity_safe_state rdb_ocean_cavity_melt Subroutine

The documented SAFE STATE returned on every non-OK status: zero melt, interface salinity equal to the far field, interface temperature on the liquidus there. m_mass is EXACTLY zero, so a failed column contributes nothing to a heat/salt budget rather than contributing a plausible wrong number.

Read more…
cavity_salt_fluxes rdb_ocean_cavity_melt Subroutine

The two sides of (E3), in (g/kg)*kg/m^2/s:

Read more…
cavity_scale_impl rdb_ocean_diag_derived Subroutine

cavity_mask_impl with a constant multiplier folded in.

cavity_solution_reset rdb_ocean_cavity_melt Subroutine

Define every component of the solution bundle. Called FIRST by cavity_solve_melt, before any early return, because the type carries no default initialisers (see its docstring: they would bar it from a do concurrent local(...) clause on gfortran).

cavity_solve_melt rdb_ocean_cavity_melt Subroutine

cavity_solve_melt_f with the Coriolis parameter taken from the bundle (par%f_cor) — the scalar entry point every host caller and the kernel suite use.

cavity_solve_melt_f rdb_ocean_cavity_melt Subroutine

Solve the three-equation system with any implemented exchange law, and return the full interface state plus the fluxes a coupling seam will consume.

Read more…
cavity_state_at_x rdb_ocean_cavity_melt Subroutine

Evaluate the whole interface at a trial x = ln(L+): exchange velocities at that stratification, the closed-form three-equation solve, the buoyancy flux the answer implies and the L+ it re-diagnoses. The fixed point of x -> ln(L+_new) is the solution of the implicit system.

cavity_status_counts_impl rdb_ocean_cavity_flux Subroutine

Reduce the per-column status plane into four counts, ON DEVICE.

Read more…
cavity_status_impl rdb_ocean_diag_derived Subroutine
cavity_t_ice rdb_ocean_cavity_melt Function

Ice temperature actually used: exactly zero when the mode ignores it, so an unset or stale T_ice cannot leak into an insulating run through L_eff.

cavity_three_equation rdb_ocean_cavity_melt Subroutine

Closed-form solve of (E1)-(E3) on the linear liquidus carried by eos. Returns the interface state and the canonical melt mass flux (kg/m^2/s, > 0 melting). See the derivation block above for the root selection, the cancellation-safe quadratic and the pre-solve melt/freeze branch.

Read more…
cavity_trim_eta_linear_impl rdb_ocean_cavity Subroutine

The TRIMMED initial surface (MOM6 TRIM_IC_FOR_P_SURF, trim_for_ice): the free-surface anomaly eta_trim that puts a loaded column top exactly where the displaced water’s own weight equals the load, so the initial state is at rest under the MOM6 barotropic split (&ocean_bt_nml bc_pgf_forcing).

Read more…
cavity_two_equation rdb_ocean_cavity_melt Subroutine

Two-equation variant: the interface salinity is the FAR-FIELD salinity, S_b = S_w exactly, i.e. the gamma_s -> infinity limit of the three-equation form (NOT the gamma_s -> 0 limit, which sends T_b -> T_w and the melt rate to zero). Holland & Jenkins (1999) section 2b(2) p. 1791; Jenkins, Nicholls & Corr (2010) eq. (6) p. 2302, where the single transfer coefficient is Gamma_TS ~ 0.006 and the freezing point is evaluated at the far-field salinity.

Read more…
cavity_ustar rdb_ocean_cavity_melt Subroutine

Interface friction velocity (m/s),

Read more…
cavity_water_column_impl rdb_ocean_cavity Subroutine

water = b - z_draft — the reference water-column thickness the datum, the layer split and the wet-mask seed all work on. Kept as one named routine so the three call sites cannot drift.

Read more…
cell_area_weighted_sum rdb_ocean_api Function

sum_k sum_ij f(i,j,k)*area(i,j) over the physical interior.

cfl_cell_value rdb_ocean_console_stats Function

Per-cell advective CFL from the C-grid face-velocity pairs and metric inverses: cfl = (|u_c|·idx + |v_c|·idy)·dt, with u_c/v_c the face averages. !$acc routine seq so it inlines into the reduction loops below — same module ⇒ NVHPC keeps it inlined (and it’s a status-cadence cold path regardless). Sole home of the CFL formula, shared by the gated + un-gated compute_max_cfl loops.

check_dataovr_file rdb_config Subroutine

Existence check for one tag’s file. NOT pure — inquire is an I/O statement, which is exactly why this is a subroutine setting has_error rather than another predicate: the pure ones above stay pure and independently testable, and this keeps the filesystem dependency in one visible place. Silent for a tag that names no file.

check_fresh rdb_ocean_data_input Subroutine

Ordering guard: update_2d/_3d must be called with the same t update_all most recently refreshed this field’s bracket with (skipped for STATIC — its bracket never changes, so “freshness” is meaningless). Catches a consumer calling update_2d/_3d before update_all has run this step, which would otherwise silently blend a stale bracket.

check_h_positive_or_die rdb_ocean_dyn Subroutine

&ocean_isopycnal_nml check_h_positive guard. Abort on the FIRST negative layer thickness, naming the pipeline stage that produced it, the offending (i,j,k), and that column’s full thickness profile.

Read more…
check_registered rdb_ocean_data_input Subroutine

Fail-loud guard shared by every per-step/fill accessor: id must name an active field of the right rank, and the caller’s dest shape must match what was declared at registration.

check_remap_preconditions_or_die rdb_ocean_dyn Subroutine

&vcoord_nml remap_check_preconditions guard (audit findings V5, V6).

Read more…
check_time_mode rdb_ocean_data_forcing Subroutine

Fail loud on a cyclic group with no period. The reader makes the same check per field; catching it once here names the namelist group the user actually edited.

check_unsupported rdb_nml_schema Subroutine

Flag unsupported namelist syntax embedded in a bare token.

check_vanished_invariant_or_die rdb_ocean_dyn Subroutine

Fail-loud TRIPWIRE for invariant I1′ — h_layer <= H_VANISHED ⇒ hTr = h_layer·c_live (the donor live layer’s concentration; hTr = 0 in a column with no live layer) for every registered tracer. Gated on &vcoord_nml check_vanished_content (default .false.), which is the knob the stability suite turns on for the cases that actually have vanishing layers.

Read more…
chksum_active rdb_ocean_chksum Function

Gate: enabled AND inside the step window.

chksum_argmax rdb_ocean_chksum Subroutine

Interior argmax of |arr|: first-encountered strict maximum over i ∈ [i0, i1], j ∈ [j0, j1], all k (the ghost ring is excluded by the caller’s bounds). Host-side (debug-window cadence only).

chksum_bt rdb_ocean_chksum Subroutine

Sample the BT substep’s 2D in/out fields at the fold seam: the fold delta is bt_ubt_end - ubt_at_n - dt*F_bt_u, so these four (+ eta) name which INPUT went non-finite when the fold’s loud count fires — the “what fed it” the nan-catch cannot see.

chksum_hotface rdb_ocean_chksum Subroutine

Hot-face anatomy at a phase seam: interior argmax |u| and |v| with the local thickness pair (donor/receiver cells), the per-face viscous remnant, and the column context (thickness of the layer below/above at the max face). The forensic question this answers: WHICH face takes the explicit dt·F kick, is it an outcrop edge (massive|vanished thickness pair), and is visc_rem actually small there (i.e. would MOM6’s attenuation have caught it)? Row format (grep “HOTFACE”): HOTFACE s

chksum_loc_extents rdb_ocean_chksum Subroutine

Map a grid-location tag (LOC_{H,U,V,Q}) to the field’s 2D extents on the Arakawa-C grid — u/v faces carry the extra wall-normal row/column, the corner both. This is the single place the C-grid extent convention lives; call sites pass loc.

chksum_loc_interior rdb_ocean_chksum Subroutine

Physical-cell index range for a grid-location tag: the ghost ring excluded. Face locations carry one MORE physical entry than cell centres in their staggered direction (an x-face array spans nx_phys + 1 faces), which is why LOC_U/LOC_Q extend i1 by one and LOC_V/LOC_Q extend j1.

Read more…
chksum_row rdb_ocean_chksum Subroutine

Emit one CHKSUM row (write(*,…) like the KE_ATTR probe — probe output bypasses the logger by design: greppable, no prefix, survives logger-level filtering).

chksum_state rdb_ocean_chksum Subroutine

Sample the prognostics (h, u, v, every tracer) at a phase seam. Call AFTER the phase named by label; drains device queues first so the async apply chain has landed. Bounds come from the location-aware API (LOC_H / LOC_U / LOC_V), not hand-written.

chksum_stats_2d rdb_ocean_chksum Subroutine

2D twin of chksum_stats_3d (BT work fields).

chksum_stats_3d rdb_ocean_chksum Subroutine

Device-side sum/min/max/nonfinite over an explicit-shape 3D field. No present clause: present_or_copyin reads the device copy in production and copies-in host data in unmapped unit tests (same convention as the BT fold’s loud count).

clamp_fraction rdb_ocean_porous Function

Clamp an open-area fraction into [0,1], NaN-safely.

Read more…
close_stream rdb_ocean_diag_netcdf Subroutine

Flush + close the NetCDF file. Idempotent.

closed_faces_update_bt_widths rdb_ocean_porous Subroutine

Refresh the BAROTROPIC face widths from the LIVE layer thicknesses when &vcoord_nml zfixed_closed_faces is on.

Read more…
collect_tokens rdb_nml_schema Subroutine

Tokenize a group body up to and including the terminating ‘/’. Token kinds are encoded by their text: “=” , “,” , a quoted or bare value, an identifier, or special markers for unsupported syntax which are flagged here. The ‘/’ ends collection.

comm_env_abort rdb_comm_env Subroutine

Abort all MPI processes with given error code

comm_env_bcast_real rdb_comm_env Subroutine

Broadcast a single real(wp) scalar from compute rank 0 Uses compute communicator so I/O server ranks don’t participate.

comm_env_compute_comm rdb_comm_env Function

Return the compute-only communicator Falls back to comm_world() if comm_env_init has not been called (e.g. tests that use raw MPI_Init).

Read more…
comm_env_compute_rank rdb_comm_env Function

Return this process’s rank in the compute communicator

comm_env_compute_size rdb_comm_env Function

Return number of compute ranks (excludes I/O ranks)

comm_env_finalize rdb_comm_env Subroutine

Finalise MPI. No-op if the comm-env was never initialised, so it is safe to call unconditionally at program exit – the shared per-test main does this for the few tests that init MPI, and it costs nothing for the rest (and on serial builds via the stub).

comm_env_global_comm rdb_comm_env Function

Return the cached global (world) communicator.

Read more…
comm_env_init rdb_comm_env Subroutine

Phase 1: Initialise MPI, cache world rank/size Call this before reading config. Idempotent: a second call is a no-op, so multiple entry points / testdrive cases can call it.

comm_env_io_server_rank rdb_comm_env Function

Return world rank of this node’s I/O server (-1 if none)

comm_env_is_io_server rdb_comm_env Function

Return .true. if this rank is a dedicated I/O server

comm_env_node_compute_ranks rdb_comm_env Function

Return world ranks of compute processes on this node

comm_env_node_n_compute rdb_comm_env Function

Return number of compute ranks on this node

comm_env_pop_compute_comm rdb_comm_env Subroutine

TEST/TOOLING-ONLY. Pops the override pushed by comm_env_push_compute_comm, restoring comm_env_compute_comm() to the real compute communicator. Fails loud on pop-without-push (a bug in the caller, not a state this seam should absorb silently). Does NOT finalize the popped communicator – the pusher owns that (e.g. freeing a self-comm built for the push).

comm_env_push_compute_comm rdb_comm_env Subroutine

TEST/TOOLING-ONLY. Temporarily overrides what comm_env_compute_comm() returns to comm, until the matching comm_env_pop_compute_comm().

Read more…
comm_env_rank rdb_comm_env Function

Return this process’s world MPI rank

comm_env_setup_roles rdb_comm_env Subroutine

Phase 2: Assign roles (I/O server vs compute), bind GPU Call this after reading config, before decomp/solver init.

comm_env_size rdb_comm_env Function

Return total number of MPI processes (including I/O ranks)

complete_ocean_create rdb_ocean_api Subroutine

Shared tail of rdb_ocean_create_from_string AND rdb_ocean_create_finalize (P2.5): engine_setup -> resolved-n_inner check -> engine_enter_data -> finalize handle bookkeeping. Consumes whatever geometry h%engine%staged_* fields carry (empty/unset for the single-call path — byte-identical to before P2.5). On any failure, destroys the WHOLE handle (F9) and clears the single-live-handle guard; c_handle is c_null_ptr and h is null on return in that case, matching rdb_ocean_destroy’s out-null convention.

compute_bt_rem rdb_barotropic_coupling Subroutine

Per-face multiplicative damping factor for the BT-substep velocity update (linear-drag branch): bt_rem_face = Htot_face / (Htot_face + r·hbbl·dt_inner) applied as ubt_new = bt_rem_u·(ubt_old + dt_inner·forces) each inner step. When the bt_substep_drag knob is off this must NOT be called and the workspace stays at 1 (no-op, bit-identical).

compute_bt_rem_from_visc_rem rdb_barotropic_coupling Subroutine

PR-2 (bt-rem-from-av-rem): build bt_rem_u/v from the SAME viscous remnant the layered momentum solve uses, MOM6’s barotropic solver. Dispatched the same way as compute_bt_rem — a RESETTER, mutually exclusive at configure with bt_substep_drag (D2, double-counted bed drag) and with bt_halo > 0 (validate_config) — so this and compute_bt_rem/ reset_bt_rem never both run for the same stage; src/core/ ocean/README.md’s “exactly one resets, everything else MULTIPLIES” contract gets this as its third resetter.

Read more…
compute_bt_rem_wave_drag rdb_barotropic_coupling Subroutine

MULTIPLIES the Egbert & Ray (2001) / Jayne & St Laurent (2001) linear (Rayleigh) barotropic wave drag into bt_rem_u/v: bt_rem_u *= Htot_face / (Htot_face + lwd_drag_u·dt_inner) lwd_drag_u/v is a static, face-resident piston velocity [m/s] built once at configure by configure_ocean_wave_drag. Uses the IDENTICAL Htot_face expression as compute_bt_rem (reuse, not a second H_tot). Composes with substep_drag exactly as MOM6 composes lin_drag_u with the viscous remnant. Htot_face <= 0 ⇒ leave bt_rem unmodified (MOM6’s guard).

compute_channel_drag_rates rdb_ocean_bottom_drag Subroutine

Device kernel for the per-layer side-drag Rayleigh rate. See ocean_channel_drag_compute_tendencies for the derivation. wet_q is (nx+1, ny+1); dyCu is (nx+1, ny) (u-face length normal to the zonal flow); dxCv is (nx, ny+1).

compute_distributed_drag rdb_ocean_bottom_drag Subroutine

HBBL-distributed bottom drag. Mirrors MOM6’s LINEAR_DRAG and quadratic-with-HBBL formulations: the drag stress is spread across the bottom hbbl metres rather than dumped into the bed-most layer.

Read more…
compute_e_anom rdb_barotropic_coupling Subroutine

SSH anomaly = 0.5·(bt_eta_end + bt_eta) − eta_PF: the part of η the BT substep produced beyond what the slow PGF saw. Zero at steady state.

compute_fv_mom6_impl rdb_ocean_pressure_force Subroutine

Faithful port of MOM6’s PressureForce_FV_Bouss per-layer PGF for the Boussinesq + per-layer Rlay path.

Read more…
compute_fv_mom6_insitu_pcm_impl rdb_ocean_pressure_force Subroutine

FV_MOM6 pressure gradient, constant-by-layer (PCM) T/S, density at the IN-SITU pressure — MOM6 PressureForce_FV_Bouss with RECONSTRUCT_FOR_PRESSURE = False (int_density_dz_generic_pcm).

Read more…
compute_fv_mom6_reconstruct_impl rdb_ocean_pressure_force Subroutine

FV_MOM6 pressure-gradient with in-layer T/S reconstruction.

Read more…
compute_gprime_impl rdb_ocean_pressure_force Subroutine

Reduced-gravity / gprime PGF for NK = 2.

Read more…
compute_gtot_faces rdb_barotropic_coupling Subroutine

Face-centred depth-weighted column averages of pbce (gtot_E/W/N/S). Wall cells fall back to pbce(:,:,nz). By construction Σ_k h_face(k)·(pbce(k) − gtot_face) = 0 per column, making the bc-PGF Δu correction depth-mean zero – UNDER THE SAME h_face/weight derive_bt_from_layers and apply_bt_correction’s folds use.

Read more…
compute_h_face_upstream rdb_barotropic_coupling Subroutine

Per-face upstream column-sum thickness h_face_up_x/y(I,j) = Σ_k h_layer(I_upstream,j,k) used by the BT chain when use_upstream_h_face = .true.. First-order upwind pick by face-velocity sign (sampled at the top of the outer step). Wall faces use the single available cell. No-op when the knob is off.

Read more…
compute_ice_totals rdb_ocean_console_stats Subroutine

Σ wet_T·areaT, Σ ci·areaT and Σ (mice/ICE_RHO_ICE)·areaT over PHYSICAL cells (ghosts excluded) — ci/mice from the two-mode per-cell gather (ice_cell_concentration_impl convention, inlined; test_ocean_ice_diags pins the fills’ copy of the same math). One pass, three reduction(+:) accumulators.

compute_ice_totals_efp rdb_ocean_console_stats Subroutine

EFP twin of compute_ice_totals. 2D-only (no k-slab blocking needed – one “slab” per accumulator), so a single efp_summands_guard call suffices. THREE SEPARATE single-pass reductions (one per accumulator, 7 reduction scalars each) rather than one kernel combining all 21 – ice diagnostics are a status-cadence cold path (SS11.11: “the EFP path costs ~nz times more kernel launches… unmeasurable at status cadence”), so the extra category-sum pass for ci/hi is free.

Read more…
compute_max_cfl rdb_ocean_console_stats Function

max (|u_c|·dt·idxT + |v_c|·dt·idyT) over PHYSICAL cells (ghosts excluded). idxT/idyT are metric inverses (= 1/dx,1/dy on uniform).

Read more…
compute_pbce rdb_barotropic_coupling Subroutine

Per-layer pressure-anomaly gravity coefficient (m/s²): the response of layer k’s pressure to a unit change in η. Montgomery form, bottom-up convention (k=1 bed, k=nz surface): pbce(:,:,nz) = g·ρ_ref/ρ_0 do k = nz-1, 1, -1 g_prime_K = g·(rho_layer(k+1) − rho_layer(k))/ρ_0 pbce(:,:,k) = pbce(:,:,k+1) + g_prime_K·(e_top_of_k − e_bed)/H Uniform-density column ⇒ pbce−gtot ≡ 0 ⇒ bc-PGF correction a no-op. Reads pgf%e_face; requires pgf%variant == OPGF_VARIANT_FV_MOM6 (other variants don’t fill e_face). validate_config and configure_ocean_pgf refuse correction_bc_pgf with any other form, so the error stop below is a backstop for direct callers.

compute_total_h rdb_ocean_console_stats Function

Σ h_layer(i,j,k)·areaT(i,j) over PHYSICAL cells (ghosts excluded). Explicit OpenACC reduction — the sum() intrinsic on a present-mapped array silently runs host-side under NVHPC non-managed mode and returns the stale host shadow.

compute_total_h_efp rdb_ocean_console_stats Function

EFP twin of compute_total_h: order-invariant fixed-point Sigma h_layer*areaT over PHYSICAL cells. K-SLAB BLOCKED: a host loop over k, one device reduction(+:e1..e6) per slab, then a host-side efp_carry combining the slab into the running total – keeps each device reduction block within EFP_MAX_SUMMANDS (SS3.3/SS6.3 of the plan; MOM6’s i/j block-partition arithmetic is NOT ported – the k-slab is simpler and sufficient at EFP_PREC_WIDTH = 36). Ghost exclusion + extent clamping copied VERBATIM from compute_total_h – a divergence here would silently change what is summed between the FP and EFP paths.

compute_total_ke rdb_ocean_console_stats Function

Σ 0.5·h·(u_c²+v_c²)·areaT over PHYSICAL cells (ghosts excluded), using cell-centred face averages. Direct OpenACC reduction.

compute_total_ke_efp rdb_ocean_console_stats Function

EFP twin of compute_total_ke. See compute_total_h_efp for the k-slab blocking design; face-averaging + extent clamping copied verbatim from compute_total_ke.

compute_total_tracer rdb_ocean_console_stats Function

Σ hTr(i,j,k)·areaT(i,j) over PHYSICAL cells (ghosts excluded). Same explicit-reduction pattern as compute_total_h.

compute_total_tracer_efp rdb_ocean_console_stats Function

EFP twin of compute_total_tracer. See compute_total_h_efp for the k-slab blocking design; ghost exclusion + extent clamping copied verbatim from compute_total_tracer.

compute_w_from_continuity rdb_ocean_vertical_advection Subroutine

Fill ms%w_interface by integrating the horizontal- continuity residual upward from the bed. Eulerian z:

Read more…
configure_log_level rdb_driver Subroutine

Set logger verbosity from string

configure_obc_edge_nodal rdb_ocean_setup Subroutine

Bake the C3 nodal/astronomical correction into one OBC edge, then fail loud (rank-0 error + error stop) if any of the edge’s constituent frequencies matches no tide-catalog entry, else log the resolved constituent → (name, f_c, V_c+u_c) map on rank 0. Host-side setup wrapper around the pure obc_tide_nodal_fill — the pure helper signals the failure via fill_ierr; the loud policy lives here.

configure_ocean_bc rdb_ocean_setup Subroutine

Populate ocean_state%bc edge tags + per-edge data values from cfg%ocean%bc (read from &ocean_bc_nml). Run this after configure_ocean_bt_split and before ocean_state_enter_data so the BC state is set before the first dyn step.

Read more…
configure_ocean_bt rdb_ocean_setup Subroutine

Barotropic-substep correction knobs (MOM6 frhatu h-weighting, bc-PGF retro-correction, bt_rem_u drag damping, visc_rem joint weight), the BT_cont_type / upstream-PPM h_face workspace allocations, and the rank-0 PGF/BT configuration log lines.

configure_ocean_bt_split rdb_ocean_setup Subroutine

Auto-derive the barotropic substep count n_inner from the external gravity-wave CFL (MOM6 set_dtbt) when requested, then latch the mode-split reference column depth bt_H_ref from the seeded bathymetry. cfg is intent(inout) because auto_n_inner writes cfg%ocean%bt%n_inner.

configure_ocean_cavity rdb_ocean_setup Subroutine

Build the static ice-shelf cavity LOAD field metrics%p_ice_ref = (rho_ref*GRAVITY)*z_draft (Pa), ASSEMBLE it into the top-of-column pressure multilayer_state_t%p_top, and assert the counted-once datum invariant.

Read more…
configure_ocean_cavity_melt rdb_ocean_setup Subroutine

Configure the ice-shelf basal-melt slot (&ocean_cavity_melt_nml, P2b): copy the knobs onto the slot’s three flat parameter bundles, resolve the gamma_s sentinel, build the per-column Coriolis array the hj99 law needs, and CHECK that the interface pressure the liquidus will read has actually been loaded.

Read more…
configure_ocean_closed_faces rdb_ocean_setup Subroutine

Build the static partial-step z-level FACE-CLOSURE mask (&vcoord_nml zfixed_closed_faces; Adcroft, Hill & Marshall 1997; Losch 2008 §2.1 for the ice-shelf cavity).

Read more…
configure_ocean_conv rdb_ocean_setup Subroutine

Copy the &ocean_conv_nml knobs onto ocean_state%vmix – every field, no dead-config gaps. Convective adjustment adds no new slot / allocatable (it lives on the already-unconditionally- allocated vmix), so unlike configure_ocean_tidal_mixing there is no separate enable latch to set on a distinct sub-object; vmix%conv_enable IS the latch. No mutual exclusion with KPP / EPBL: convection masks against whichever BL depth is live this stage (rdb_ocean_dyn.F90 vmix_apply_in_stage).

configure_ocean_ddiff rdb_ocean_setup Subroutine

Copy the &ocean_ddiff_nml knobs onto ocean_state%vmix – every field, no dead-config gaps. Like convection, double diffusion adds no new slot (it rides the unconditionally-allocated vmix and the already-mirrored vmix%eos); vmix%ddiff_enable IS the latch. Folded into vmix_split_kd_heat_salt, so it needs the interior closure pipeline (use_closure) and thermodynamics (it reads T/S and the EOS alpha/beta). enable=.false. => bit-identical.

configure_ocean_drag rdb_ocean_setup Subroutine

Bottom-drag variant + coefficients, the continuity PPM positivity guard, and the BT-budget diagnostic probe — plus their rank-0 log lines. All knobs default off/zero (bit-identical to pre-knob nmls).

configure_ocean_epbl rdb_ocean_setup Subroutine

Copy the &ocean_epbl_nml knobs onto the EPBL slot — every field, end to end (don’t repeat the KPP ri_crit/c_vt2 dead-config gap). Also fills f_centre from the same beta-plane parameters the Coriolis slot uses, copies the EOS hookup, validates the configuration, and resolves the EPBL-vs-KPP mutual exclusion.

configure_ocean_forcing rdb_ocean_setup Subroutine

Wire surface wind stress, horizontal-viscosity coefficients, and the Coriolis beta-plane + PV-scheme variant from cfg into the ocean slots.

Read more…
configure_ocean_foxkemper rdb_ocean_setup Subroutine

Copy the &ocean_foxkemper_nml knobs onto the MLE slot (B5). Validates: B5 reads epbl%mld, so EPBL must be enabled; and the resolution_taper hook is a hard error until B2 lands.

configure_ocean_hdiff rdb_ocean_setup Subroutine

Along-coordinate tracer Laplacian coefficient (&ocean_hdiff_nml kappa_h). Scalar copy onto ocean_state%hdiff_tracer, mapped with its parent slot at ocean_state_enter_data — no explicit !$acc update needed as long as this runs before that (it does; see rdb_driver.F90). Default kappa_h = 0.0 leaves the kernel’s short-circuit intact ⇒ bit-identical.

configure_ocean_k_bot rdb_ocean_setup Subroutine

Fill ms%k_bot / k_bot_u / k_bot_v — the shared index of the first LIVE layer counting UP from the bed, and the field every bed-side consumer reads instead of spelling 1. The bed-side mirror of configure_ocean_k_top.

Read more…
configure_ocean_k_top rdb_ocean_setup Subroutine

Fill ms%k_top / k_top_u / k_top_v — the shared index of the first LIVE layer counting down from the top, and the field every top-side consumer reads instead of spelling nz.

Read more…
configure_ocean_kappa_shear rdb_ocean_setup Subroutine

Copy the &ocean_kappa_shear_nml knobs onto the kappa-shear slot — every field, end to end (don’t repeat the KPP dead-config gap). Fills f_centre from the same beta-plane parameters the Coriolis slot uses, copies the EOS hookup, and validates. No mutual exclusion: kappa-shear is an interior closure that coexists with KPP / EPBL and PP81/background.

configure_ocean_land_mask rdb_ocean_setup Subroutine

Derive the static C-grid land masks from the seeded T-cell wet_mask and zero the 6 face metrics at land faces (metrics_apply_land_mask). Run AFTER configure_ocean_metrics (the metrics + inverses must exist) AND configure_ocean_bc (the periodic / fold flags drive the halo-aware mask derivation), but BEFORE ocean_state_enter_data (the host edit is what the GPU copyin captures).

Read more…
configure_ocean_lateral rdb_ocean_setup Subroutine

Flow-aware lateral-viscosity closure (Leith / Smagorinsky + biharmonic Smagorinsky_AH), the vertical coordinate (VCOORD_* code + z_fixed reference depth), and the PP81/KPP vertical-mixing switches — with their rank-0 log lines.

configure_ocean_meke rdb_ocean_setup Subroutine

Fill the MEKE slot’s cell-centre |Coriolis| from the same metrics_fill_coriolis path VarMix / EPBL use (handles beta-plane AND spherical), so beta = |grad f| for the Rhines length is live when alpha_rhines > 0. The MEKE scalar knobs are copied earlier by ocean_state_copy_config; this only fills f_centre. Host loop before enter_data. No-op when MEKE is disabled.

configure_ocean_metrics rdb_ocean_setup Subroutine

Fill the ocean_metrics_t slot per cfg%ocean%grid%grid_config, then single-source the inverses + hvisc ratio bundle (metrics_finalize). Must run BEFORE ocean_state_enter_data (the host fill is what the GPU copyin captures). For “spherical”, the &grid_nml dx/dy are reinterpreted as dlon/dlat in degrees.

configure_ocean_p_surf rdb_ocean_setup Subroutine

Configure the atmospheric surface-pressure loading slot (PR-17): copy enable, take ρ₀ from ocean_state%eos%rho0 (the single ρ₀ of record — NOT a namelist knob), and allocate the seam fields. Host-side setup — runs BEFORE ocean_state_enter_data. enable=.false. => no-op, bit-identical. The uniform-p_surf inert warning is emitted in validate_config; here we only log the enable on rank 0.

configure_ocean_pgf rdb_ocean_setup Subroutine

Pressure-force variant, the reference densities (rho0 / rho_ref, both from the single configured ρ₀ — &ocean_ic_nml rho_0 via eos%rho0), the reduced-gravity (gprime / gfs_scale) knobs, the bathymetry copy into the PGF slot, and the matching barotropic fast-loop gravity g_bt for the gprime / FV_MOM6-reduced-GFS paths.

configure_ocean_porous rdb_ocean_setup Subroutine

Configure porous barriers (&ocean_porous_nml, Adcroft 2013). Grows the ocean_metrics_t porous arrays to full face size and fills the STATIC along-face d_min/d_max/d_avg statistics; the layer-averaged open fractions themselves are recomputed on the device every RK2 stage (they depend on the interface heights).

Read more…
configure_ocean_reference_density rdb_ocean_setup Subroutine

Fan the ONE configured Boussinesq reference density out to every remaining slot that carries its own rho0 copy.

Read more…
configure_ocean_sponge rdb_ocean_setup Subroutine

Populate ocean_state%sponge’s per-cell idamp_h/idamp_u/ idamp_v maps from cfg%ocean%sponge (&ocean_sponge_nml) + the already-configured ocean_state%bc edge tags. Run AFTER configure_ocean_bc (reads the edge tags + has_* flags) and BEFORE ocean_state_enter_data.

Read more…
configure_ocean_tidal_mixing rdb_ocean_setup Subroutine

Copy the &ocean_tidal_mixing_nml knobs onto the tidal-mixing slot — every field, end to end (no dead-config gaps). Seeds the prescribed bottom energy field e_in (v1 uniform path), copies the shared EOS hookup for the N^2 buoyancy derivatives, and validates. No mutual exclusion: tidal mixing is an interior closure that coexists with KPP / EPBL / PP81 / kappa-shear.

configure_ocean_tides rdb_ocean_setup Subroutine

Configure the equilibrium body-force tide slot (C1): parse the constituent list + reference dates, fill the astronomy catalog (phase0, nodal f/u), and build the (nx,ny,3) spatial-structure arrays from metrics%geolatT/geolonT. Host-side setup — runs AFTER configure_ocean_metrics (lat/lon must be filled) and BEFORE ocean_state_enter_data. enable=.false. => no-op, bit-identical.

configure_ocean_top_drag rdb_ocean_setup Subroutine

Ice-shelf TOP drag (&ocean_tdrag_nml, Phase 4a): copy the variant + coefficients onto the slot, project the static cell-centred metrics%cover_frac onto the velocity FACES, and enforce the ONE-C_d rule against the melt slot.

Read more…
configure_ocean_tracers rdb_ocean_setup Subroutine

&ocean_tracers_nml scalar knobs (PR-7): the ideal-age Dirichlet surface value and its vintage-mode exponential growth rate. enable_ideal_age itself is latched earlier by ocean_state_copy_config (before init(grid), since it gates tracer-slot allocation) — these two scalars gate nothing, so they land here in the post-init configure pass. Both default to 0 ⇒ bit-identical.

configure_ocean_varmix rdb_ocean_setup Subroutine

Build the STATIC VarMix grid terms (f2_dx2_*, beta_dx2_*, l2_*) on the varmix slot once at configure time, from the filled curvilinear metrics + the cell-centre Coriolis magnitude. The slot scalars are copied earlier by ocean_state_copy_config; this only fills the static arrays (the per-step Res_fn/SN/assembly fire in the dyn step). No-op when VarMix is disabled.

configure_ocean_vmix rdb_ocean_setup Subroutine

Thermodynamics on/off, velocity-truncation clamp (MAXVEL), DIRECT_STRESS surface-stress distribution, KV_ML_INVZ2 surface-band viscosity, HARMONIC_VISC face-thickness mean, and the DT_THERM thermo/tracer cadence — with their rank-0 log lines.

configure_ocean_wave_drag rdb_ocean_setup Subroutine

Configure the barotropic linear (Rayleigh) wave-drag piston-velocity maps (Egbert & Ray 2001; Jayne & St Laurent 2001) — the bulk energy sink for the barotropic tide, MOM6 BT_LINEAR_WAVE_DRAG. Builds a host-only h-point r_h(nx,ny) map (uniform scalar or a resolved-bathymetry roughness proxy), scales it, averages h->face into bt_work%lwd_drag_u/v, and leaves the arrays unallocated when the knob is off (bit-identical). MUST run AFTER bathymetry is set (ocean_state%barotropic%b) and land masking (configure_ocean_land_mask) and BEFORE ocean_state_enter_data — the !$acc enter data copyin in barotropic_workstate_enter_data carries these host-filled values to the device (CLAUDE.md gotcha (2): arrays mapped create do not carry pre-map host values, so this ordering is load-bearing).

configure_ocean_wavespeed rdb_ocean_setup Subroutine

Copy the &ocean_wavespeed_nml knobs onto the wave-speed slot (B1). Diagnostic, no mutual exclusion: cg1/Rd read rho_layer directly. Fills f_centre + the static beta_centre = |grad f| field via fill_coriolis_centre + build_static — the SAME metrics_fill_coriolis path VarMix/MEKE use (planetary on spherical/tripolar, beta-plane bit-identical elsewhere) — rather than the legacy hard-coded beta-plane set_f_centre. Copies rho0 from the EOS slot for the Boussinesq gprime. Must run AFTER configure_ocean_metrics (metrics filled + finalized).

configure_ocean_wetdry rdb_ocean_setup Subroutine

Dynamic wetting/drying (docs/ocean_wetdry_plan.md): copy the &ocean_wetdry_nml knobs onto the BT workstate, allocate the wd_* workspaces (lazy — absent when the knob is off, so the default path carries no new arrays and stays byte-identical), and seed the hysteresis wet mask from the seeded bathymetry (barotropic%b — the same array configure_ocean_bt_split later latches into bt_H_ref; bt_eta is still 0 here). Must run BEFORE the restart read (so wd_wet_dyn is allocated + registered when the registry walk runs and a warm restart overwrites the seed with the saved front state) and BEFORE ocean_state_enter_data (host seeding; the enter_data walk attaches whatever is allocated).

configure_ocean_z_fixed_profile rdb_ocean_setup Subroutine

Resolve the VCOORD_Z_FIXED nominal layering onto the vcoord slot — and the VCOORD_ZSTAR one, which is the same nominal profile (MOM6 z* dilates it per column; ocean_vcoord_zstar_target): z_fixed_h_ref = &ocean_topo_nml max_depth (the uniform max_depth/nz spacing — the default, byte-identical), or, under &vcoord_nml z_fixed_profile = "list" | "tanh", the stretched per-layer tables z_fixed_zi / z_fixed_dz built by rdb_vcoord :: z_fixed_nominal_dz (z_fixed_h_ref then becomes the profile’s total depth).

Read more…
configure_rho_target rdb_ocean_setup Subroutine

Populate the isopycnal rho_target(0:nz_ml) interface densities for VCOORD_RHO / VCOORD_HYCOM. rho_target(0) is the surface (lightest) interface, rho_target(nz_ml) the bed (densest).

Read more…
console_stats_report rdb_console_stats Subroutine

Emit one MOM6-style console block from pre-computed totals. The caller has already area-weighted + reduced each scalar over its own state; this routine only latches the t=0 reference (first call), formats the lines, and runs the panic guards. When a budget with active=.true. is passed, the Error column becomes the boundary-flux + surface-source-corrected residual (see conservation_budget_t) and the outflux / source are shown.

constant_destroy rdb_ocean_boundary_data Subroutine
constant_update rdb_ocean_boundary_data Subroutine
continuity_apply_fluxes rdb_continuity Subroutine

Test-only (no production caller): unsplit apply, paired with continuity_compute_fluxes as the split path’s reference oracle. Per-layer forward-Euler thickness update.

Read more…
continuity_apply_fluxes_barotropic rdb_continuity Subroutine

Forward-Euler step: h <- h - dt * flux_h. The full split-explicit RK2 scheme (Phase 4) wraps two of these calls around an RK2 averaging pass; for Phase 2 this single-stage step is enough to exercise the kernel under the lake-at-rest, Gaussian-hump, and mass-conservation tests.

continuity_apply_meridional rdb_continuity Subroutine

Apply the meridional (y-flux) thickness update on top of the zonally-updated state: h(i,j,k) ← h(i,j,k) - dt · (Φy(i,j+1,k) - Φy(i,j,k)) · iareaT Adds the y-divergence to flux_h_layer so the field ends the split step holding the total horizontal divergence that the vertical-advection kernel consumes (w_interface(k+1) = w(k) - flux_h_layer(k)). Φy carries dx_cv; iareaT = inv_dy on uniform metrics.

Read more…
continuity_apply_zonal rdb_continuity Subroutine

Apply the zonal (x-flux) thickness update: h(i,j,k) ← h(i,j,k) - dt · (Φx(i+1,j,k) - Φx(i,j,k)) · iareaT Overwrites flux_h_layer with the x-divergence so the companion meridional apply can accumulate the total. Φx is the width-weighted transport (m³/s); iareaT closes the divergence to a per-area rate (= inv_dx on uniform metrics).

Read more…
continuity_bytes rdb_continuity Function

Counted allocatable footprint of the continuity-PPM slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

continuity_compute_fluxes rdb_continuity Subroutine

Test-only (no production caller): the unsplit reference path, kept as the oracle the split production path is checked against. Multilayer counterpart to continuity_compute_fluxes_barotropic: identical PPM reconstruction + upwind face pick + flux divergence, lifted per-layer. Each k-slice is independent (the PPM stencil reads only the same k), so the do-concurrent kernels parallelize over (k, j, i) simultaneously for GPU occupancy.

Read more…
continuity_compute_fluxes_barotropic rdb_continuity Subroutine

PPM face reconstruction + per-face mass flux + cell-centred flux divergence for the barotropic C-grid state.

Read more…
continuity_destroy rdb_continuity Subroutine
continuity_enter_data rdb_continuity Subroutine

Bare copyin(this) removed (stack-descriptor map → AMD cross-slot overlap; see ocean_surfstress_enter_data). The face buffers attach below; ct-descriptor presence (so DCs touching ct%h_face_left_x%data don’t per-launch memcpy) comes from the root copyin(state) in ocean_state_enter_data. A V100 A/B with copyin(this) gone is bit-identical and faster overall, so the root copy fully covers it.

continuity_enter_data_impl rdb_continuity Subroutine
continuity_exit_data rdb_continuity Subroutine
continuity_exit_data_impl rdb_continuity Subroutine
continuity_gm_apply rdb_continuity Subroutine

Gent-McWilliams thickness diffusion as its OWN sequential operator: move h_layer AND every tracer by the bolus transport gm%uhD/ gm%vhD, which gm_compute_transports has JUST filled from this same, untouched h_layer with this same dt.

Read more…
continuity_init rdb_continuity Subroutine

Allocate the 4 face-reconstruction scratch buffers sized at (nx_face, ny_face, nz). Default nz=1 covers the barotropic kernel; passing nz_ml sizes them for the multilayer kernel without forcing a separate init routine. Ocean init passes state%multilayer%nz_ml when the multilayer state is in play.

continuity_meridional_flux rdb_continuity Subroutine

Meridional (y-only) PPM reconstruction + per-face mass flux. Mirror of continuity_zonal_flux, with the same optional vhbt transport-constraint renormalisation. Writes ms%mass_flux_y_layer. Walls at j=1 and j=ny+1 zeroed. In the Lie split this runs after the zonal apply, so it reconstructs against the already-updated ms%h_layer.

continuity_step_split rdb_continuity Subroutine

Test-only (no production caller): continuity-only split wrapper; production runs the tracer-interleaved continuity_tracer_step_split. Directionally-split (Lie) PPM continuity step over dt:

Read more…
continuity_tracer_drain rdb_continuity Subroutine

Phase-2 (6b) windowed horizontal tracer-advection drain.

Read more…
continuity_tracer_step_split rdb_continuity Subroutine

Production entry point for the directionally-split continuity + tracer step. Interleaves the two so the CWC discrete theorem holds in the split form:

Read more…
continuity_zonal_flux rdb_continuity Subroutine

Zonal (x-only) PPM reconstruction + per-face mass flux on the multilayer C-grid. Companion to continuity_meridional_flux for the directionally-split (Lie) continuity step. Writes ms%mass_flux_x_layer and leaves mass_flux_y_layer / flux_h_layer untouched. Wall faces at i=1 and i=nx+1 are zeroed (closed-wall BC).

Read more…
coord_remap_proc rdb_ocean_diag_fills Subroutine

Return the default remap procedure pointer for an output vgrid. Used by the registration path to attach the right conservative remap when a diagnostic selects a non-layer output coordinate. Null for LAYER / unknown (no remap needed).

copy3_impl rdb_ocean_diag_derived Subroutine

Shared device copy buf = src with shape clipping — every direct-copy derived field routes through here.

copy_field_3d rdb_ocean_dyn Subroutine

src -> dst flat copy on the device. Bare-array shim avoids the deep struct deref inside do-concurrent (tracer hTr lives in an array-of-derived-types registry).

coradv_split_impl rdb_ocean_ke_probe Subroutine

Device pass: per-face PV/∇KE work split, three regions. Faces attributed to their west/south cell’s region mask.

coriolis_adv_apply_tendencies rdb_coriolis_adv Subroutine

Per-layer forward-Euler velocity update. no_wait (optional, default .false.): when .true. the apply DC loops are issued on OpenACC queue 1 and the routine returns WITHOUT syncing, so a batched caller (run_stage_split velocity-apply chain) can pipeline the whole additive apply sequence and !$acc wait(1) ONCE. Default ⇒ self-contained blocking apply (historical, safe for non-batched callers — e.g. the unsplit run_stage). Not pure because of the async/wait directives; still functionally pure.

coriolis_adv_apply_tendencies_barotropic rdb_coriolis_adv Subroutine

Forward-Euler velocity update from the tendencies the compute step wrote into pv_flux_x / pv_flux_y. u_face_x(i, j) <- u_face_x(i, j) + dt * pv_flux_x(i, j) v_face_y(i, j) <- v_face_y(i, j) + dt * pv_flux_y(i, j) Split-explicit RK2 (Phase 4) wraps a pair of these around an RK2 averaging pass.

coriolis_adv_bytes rdb_coriolis_adv Function

Counted allocatable footprint of the Coriolis-advection slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

coriolis_adv_compute_tendencies rdb_coriolis_adv Subroutine

Per-layer Coriolis + advection dispatcher. Reads this%pv_variant and routes to the matching kernel body:

Read more…
coriolis_adv_compute_tendencies_barotropic rdb_coriolis_adv Subroutine

Sadourny (1975) energy-conserving Coriolis + horizontal- momentum-advection form on the barotropic C-grid state:

Read more…
coriolis_adv_compute_tendencies_hk rdb_coriolis_adv Subroutine

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Per-layer PV-conserving Coriolis + horizontal-advection tendency in the Arakawa-Hsu (1990) form (“HK correction”). The wider 3-corner PV stencil at each face suppresses the spurious Hollingsworth-Källén instability that biases the simpler Sadourny 2-corner form at eddy-resolving resolutions.

Read more…
coriolis_adv_compute_tendencies_sadourny rdb_coriolis_adv Subroutine

Per-layer Sadourny Coriolis + advection tendency. Same algorithm as the barotropic counterpart, lifted with a k-axis on every loop. Each k-slice is independent (ζ stencil only reads same-k velocities; KE at centre only reads same-k face values), so the do-concurrent kernels parallelise over (k, j, i) for full GPU occupancy.

Read more…
coriolis_adv_compute_tendencies_sadourny_energy rdb_coriolis_adv Subroutine

Faithful MOM6 SADOURNY75_ENERGY (Sadourny 1975 energy-conserving) per-layer Coriolis + horizontal-advection tendency. This is the TRANSPORT form: the absolute-vorticity flux is the potential vorticity q = (f + ζ)/h_at_corner times the layer MASS TRANSPORT (vh/uh), so the discrete Coriolis term produces zero net domain kinetic energy (energy-conserving). The default enstrophy form (_sadourny, (f+ζ)·v) only matches this under uniform thickness.

Read more…
coriolis_adv_destroy rdb_coriolis_adv Subroutine
coriolis_adv_enter_data rdb_coriolis_adv Subroutine
coriolis_adv_enter_data_impl rdb_coriolis_adv Subroutine
coriolis_adv_exit_data rdb_coriolis_adv Subroutine
coriolis_adv_exit_data_impl rdb_coriolis_adv Subroutine
coriolis_adv_init rdb_coriolis_adv Subroutine

Allocate the 4 scratch buffers sized at (nx_face / ny_face / corner, nz). Default nz=1 covers the barotropic kernel; passing nz_ml sizes them for the multilayer kernel. Same backward-compatible pattern as continuity_init.

coriolis_adv_set_beta_plane rdb_coriolis_adv Subroutine

Populate f_corner with a beta-plane profile f(y) = f_0 + beta * (y - y_ref)

Read more…
corner_abs_vort rdb_coriolis_adv Function

BOUND_CORIOLIS abs_vort recovery: return (f+ζ) at corner (ic,jc) by multiplying the PV q_val back by the corner thickness Pass 2 divided abs_vort by — recovering (f+ζ) to round-off. Recomputes the SAME wet-area-weighted 4-cell hm_num/hm_den, then reconstructs the effective corner thickness with the SAME formula (and floors) the active corner_h variant used in Pass 2: cell_mean (default): h_corner = max(hm_num/max(hm_den,H_DIV_EPS), CORIOLIS_H_MIN_PV); av = q·h_corner. mom6_area (use_mom6_ch): Pass 2 formed q = abs_vort·hm_den/ (hm_num + PV_VOL_NEGLECT), so the consistent inverse is av = q·(hm_num + PV_VOL_NEGLECT)/hm_den (hm_den guarded by H_DIV_EPS for the fully-land corner, where q≡0 ⇒ av≡0 anyway). Without matching the variant the recovered abs_vort would be slightly inconsistent with how q was made whenever BOTH bound_coriolis and corner_h=”mom6_area” are on — visible only in the truly-vanishing- thickness limit. Chosen over a persistent abs_vort buffer so the default-off knob costs ZERO memory.

corner_is_wet rdb_ocean_porous Function

.true. iff all four cells contributing to a corner sample are wet. The masks are real 0/1 (ocean_metrics_t%wet_T), so the test is a mid-point comparison rather than an equality.

cos_reduced rdb_safe_math Function

Horner cos Taylor on |r| ≤ π/4. 9 even-power terms.

data_input_blend_2d_impl rdb_ocean_data_input Subroutine
data_input_blend_3d_impl rdb_ocean_data_input Subroutine
data_input_dims_ok rdb_ocean_data_input Function

Self-contained, non-erroring dimension validator — the single-rank (i_offset_global = j_offset_global = 0) testable twin of register_common’s inline checks; mirrors zinit_dims_ok. Opens filename, inspects var’s rank and lengths, and returns .false. on any mismatch, missing variable, or I/O error — NEVER aborts, so test code can probe the false branch without a subprocess/death-test harness (the house convention — see zinit_dims_ok).

data_input_locate rdb_ocean_data_input Subroutine

Bracket search + blend weight for a query time t (already in file-time units/offset — the caller applies t_offset/t_scale before calling). nt == 1 is degenerate: always returns n0 = n1 = 1, w = 0, never out of range.

data_input_read_slab_impl rdb_ocean_data_input Subroutine

Host-ONLY NetCDF slab read for file record rec -> fld%f0 (default) or fld%f1 (into_f1 = .true.), applying scale/add_offset once at read. Uses the module-level host workspace (registration/bracket-advance-time only — never a per-step allocation). Deliberately carries NO !$acc directive: called both before enter_data (STATIC field, at registration) and after it (LINEAR/CYCLIC bracket advance) — the caller pushes to the device itself, only when that is actually correct (data_input_refresh_brackets).

data_input_refresh_brackets rdb_ocean_data_input Subroutine

Host-side registry walk (outer shim) for field id.

data_input_time_mode_from_string rdb_ocean_data_input Function

Translate a namelist/registration-time string into a DATA_TIME_* code. Fail-loud on anything not covered by data_input_time_mode_is_implemented — an unrecognised tag must never silently fall back to a default mode.

data_input_time_mode_is_implemented rdb_ocean_data_input Function

.true. iff tag (case-insensitive) names a shipped time mode. Drives the fail-loud dispatch in data_input_time_mode_from_string — house idiom, see lateral_closure_is_implemented.

data_input_time_scale_from_units rdb_ocean_data_input Subroutine

CF units attribute (“seconds since …”, “hours since …”, …) -> a multiplier converting the raw file time axis to seconds. Only the leading unit word matters (no calendar, no reference date — see module docstring). ok = .false. for an unrecognised leading word; caller decides the fallback.

data_input_workspace_cleanup rdb_ocean_data_input Subroutine
data_input_workspace_ensure rdb_ocean_data_input Subroutine
dataovr_any_tag_set rdb_config Function

.true. when at least one tag names a file, i.e. enabling the group would actually do something.

dataovr_entry_is_valid rdb_config Function

.true. unless a tag names a file without naming the variable inside it. A blank file (tag not file-driven) is valid, and a var with no file is harmless — the tag simply never registers — so only the one combination is rejected.

dataovr_freshwater_needs_components rdb_config Function

.true. when evap/lprec are file-driven but the surface-flux component set they write into is switched off. Note the polarity: this reports the PROBLEM, not validity — named for how it reads at the call site.

dataovr_time_is_valid rdb_config Function

.true. unless time_mode='cyclic' was requested without a positive cycle_period. Checked only for the cyclic mode; cycle_period is ignored by linear/static.

days_since_1900 rdb_ocean_tide_astro Function

Days since the astronomical origin 1900-01-01 00:00 UT.

decomp_auto_factor rdb_decomp Subroutine

Choose px, py to minimise halo communication cost

Read more…
decomp_global_to_local rdb_decomp Subroutine

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Convert global physical indices to local physical indices

decomp_init rdb_decomp Subroutine

Initialise decomposition for a given rank

Read more…
decomp_init_from_config rdb_decomp Subroutine

Initialise decomposition from config, with optional auto-factoring

Read more…
decomp_local_to_global rdb_decomp Subroutine

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Convert local physical indices to global physical indices

decomp_log_summary rdb_decomp Subroutine

Log the process grid + this rank’s subdomain shape. Call from rank 0 after decomp_init_from_config so a run’s decomposition is visible at startup (the halo perimeter is what auto_factor minimises, printed here as the per-rank interior:ghost ratio cue).

decomp_rank_from_coords rdb_decomp Function

Compute rank from process grid coordinates (row-major)

derive_bt_from_layers rdb_barotropic_coupling Subroutine

Populate bt_eta, bt_ubt, bt_vbt from the current multilayer state. bt_H_ref must already be set. bt_eta = Σ_k h_layer − H_ref; bt_ubt = Σ_k(u·h_face)/Σ_k h_face. Face thickness averages the two abutting columns (wall faces use the single cell). With use_upstream_h_face, the interior face-h is the first-order upwind pick — consistent with compute_h_face_upstream.

derived_catalog_name rdb_ocean_diag_derived Function

Public only for the unit-test suite.

derived_catalog_requires rdb_ocean_diag_derived Function

The DERIVED_REQ_* code a catalog entry is gated on, -1 for an unknown name. The DECISION register_derived fails loud on, exposed as a lookup so the suite can assert it without provoking error stop — the repo’s standing pattern for testing a fail-loud rule.

derived_catalog_size rdb_ocean_diag_derived Function

Public only for the unit-test suite.

derived_requires_fail rdb_ocean_diag_derived Subroutine

Fail loud on a derived diagnostic whose prerequisite knob is off. Same three-step shape register_derived uses for an unknown name — error ring, logger, error stop — so the C ABI and the console both see it.

det_sign rdb_ocean_wave_speed Function

Sign of det(M(lam)) on rows 2..kc (Sturm/Hallberg recursion).

device_num rdb_mem_report Function

Active OpenACC device number, or -1 on CPU builds. Kept private — only the budget logger needs it.

diag_density_levels_ok rdb_config Function

.true. iff a density-coordinate diagnostic selection (global vgrid='density', or a per-diagnostic :density/:rho attribute anywhere in diags) has a usable rho_levels axis: at least one entry, strictly increasing (invert_density_targets assumes a monotone light->dense target list), and within the declared MAX_OCEAN_DIAG_Z_LEVELS array bound. Unlike sigma/z*, density bins have no auto-fill, so an unset axis must abort rather than silently size to zero. When density is not requested at all this is unconditionally .true. (no constraint).

diag_field_stats rdb_ocean_diag Subroutine

The [diag] console line’s min / max / mean for one diagnostic buffer, over the finite cells only.

Read more…
diag_io_ok rdb_ocean_diag_netcdf Function

Translate a raw nc_check-style status (0 = ok) from one of the nc_* calls in open_stream into the caller’s ierr contract: .true. on success; on failure, .false. with ierr = OCEAN_STATUS_ERR_IO when ierr is present (closing ncid first, when given, so a mid-create failure does not leak the file handle), or error stops with the same generic text nc_check itself would use had ierr never been threaded through — byte-identical legacy behaviour when ierr is omitted. Mirrors rdb_bathymetry’s bathy_io_ok (P0.1 F1).

diag_mask_bbox rdb_ocean_diag_mask Function

Index-based bounding box (test-only). Weight = 1 inside the closed interval [i0,i1] × [j0,j1], 0 outside. Indices 1-based and inclusive; ghost cells count if inside the box.

diag_mask_bytes rdb_ocean_diag_mask Function

Counted allocatable footprint of one region mask (0 when unallocated). weight is device-mapped by ocean_diag_enter_data_impl, so it must carry a term — see diag_var_bytes, which folds this in per masked diagnostic.

diag_mask_destroy rdb_ocean_diag_mask Subroutine
diag_mask_global rdb_ocean_diag_mask Function

Whole-grid mask — all weights = 1. Equivalent to “no mask”; exists for explicit registration and global-integral tests.

diag_mask_h_section rdb_ocean_diag_mask Function

Horizontal section (test-only): one cell row at j = j_row, spanning i ∈ [i0,i1]. Integrates transport across a constant-y line (v_face_y_layer at j_row = meridional throughflow).

diag_mask_v_section rdb_ocean_diag_mask Function

Vertical section (test-only): one cell column at i = i_col, spanning j ∈ [j0,j1]. Mirror of h_section for zonal throughflow.

diag_mask_vanished_is_on rdb_ocean_diag_fills Function

Query the vanished-masking mode (used by the registration path to tag non-layer diagnostics with has_missing for the NetCDF writer).

diag_reduce_stats rdb_ocean_diag Subroutine

Whole-array min / max / sum of a diagnostic buffer in ONE pass, over the FINITE cells only.

Read more…
diag_var_bytes rdb_ocean_diag Function

Counted allocatable footprint of ONE registered diagnostic (0 for every buffer that is unallocated).

Read more…
diag_vgrid_from_name rdb_ocean_engine Function

Map the &ocean_diag_nml vgrid string to a DIAG_VGRID_* tag. Unrecognised (schema-validated upstream) falls back to LAYER. Moved from rdb_driver (P2.4) so engine_configure_diag can use it without a driver dependency; re-exported by rdb_driver for any existing caller of that name.

diag_xtype_from_name rdb_ocean_diag_netcdf Function

Map the &ocean_diag_nml output_precision string onto a NetCDF element type for the diagnostic DATA variables.

Read more…
diffuse_velocity_columns_impl rdb_ocean_vdiff Subroutine

Build + solve the tridiagonal system per face column. u_face is either u_face_x_layer (x_face = .true., shape (nx+1, ny)) or v_face_y_layer (x_face = .false., shape (nx, ny+1)). h_layer is cell-centred (nx, ny, nz) and we average across the face direction to get the face thickness. kv_centre is the same cell-centred diffusivity field used by the tracer kernel — we average it across the face to get a face-located value at each interface.

Read more…
dims_geometry_ok rdb_ocean_data_input Function

Low-level geometry check used inline by register_common: .true. iff the variable has the expected rank and its two validated-length dims are each at least as long as required (decomposition-safe: a subdomain slab only needs offset+extent to fit, not to equal the file’s global length). Never aborts.

dispatch_group rdb_nml_schema Subroutine

Resolve a group name to known / external / unknown and parse (or skip) its body up to the terminating ‘/’.

draft_shape_ok rdb_ocean_z_init Function

True iff z_draft is the FULL ghosted (nx_total, ny_total) array the seeders index with (ng+i, ng+j) — i.e. it matches h_layer’s horizontal extent. Guards the (1, 1) placeholder ocean_metrics_t allocates when the cavity is off from ever being read as a field.

drain_avail_limit rdb_continuity Subroutine

Conservative upfront availability limiter on the accumulated window transports uhtr/vhtr, applied BEFORE drain_reconstruct_hprev.

Read more…
drain_avail_scale_x rdb_continuity Subroutine

Scale each interior x-face transport by its INFLOW-receiving cell’s factor (drain_avail_limit step 2). Face i between cell (i-1) and cell (i): uhtr(i)>0 ⇒ receiver i, uhtr(i)<0 ⇒ receiver i-1.

drain_avail_scale_y rdb_continuity Subroutine

Meridional analogue of drain_avail_scale_x. Face j between cell (j-1) and cell (j): vhtr(j)>0 ⇒ receiver j, vhtr(j)<0 ⇒ receiver j-1.

drain_copy_3d rdb_continuity Subroutine

dst = src (explicit-shape device copy).

drain_fill_conc rdb_continuity Subroutine

Concentration field Tr = hTr / max(hprev, DRAIN_MIN_H) for the WENO drain (the CW path builds the same field as the first loop of drain_parabola_*; factored out so the WENO path can reuse it without the parabola coefficients).

drain_limit_x rdb_continuity Subroutine

MOM6 hup/hlos/min_h two-test limiter on the zonal face transport (volume units). Face i between cell (i-1) and cell (i). Positive flow (uhr_x(i) > 0), donor = cell (i-1): hup = areaT(i-1)·hprev(i-1) − areaT(i-1)·min_h hlos = max(0, −uhr_x(i-1)) (already-committed outflow via the donor’s OTHER (west) face) cap when (hup−hlos)−uhr < 0 AND 0.5·hup−uhr < 0. Negative flow mirror, donor = cell (i).

drain_limit_y rdb_continuity Subroutine

Meridional analogue of drain_limit_x. Face j between cell (i,j-1) and cell (i,j); positive donor = cell (i,j-1).

drain_parabola_x rdb_continuity Subroutine

Rebuild the per-cell zonal CW PPM parabola from the CURRENT Tr = hTr/hprev (V2 — per pass). Interior cells (3..nx-2) use the limited PPM edges; the 2-cell boundary band falls back to PCM (aL=aR=Tr ⇒ swept reduces to the donor value, 1st order), matching tracer_advect_zonal_one_impl’s near-wall band. TODO(MOM6-fidelity): MOM6 advect_tracer keeps full PPM up to the wall (dropping to PCM only at genuine local extrema / zero mask2dCu faces), so we are 1st-order in the 2 cells nearest a true WALL where MOM6 is PPM-with-mask (periodic seams are fine — the wrap restores full PPM). Tracked divergence; revisit if near-wall tracer diffusion matters. a6 = 6·Tr − 3·(aL+aR). Mirror-T at land neighbours (C2); bit-identical for all-wet (wet_T≡1).

drain_parabola_y rdb_continuity Subroutine

Meridional analogue of drain_parabola_x. aL = south-edge, aR = north-edge value of each cell. Mirror-T at land neighbours (C2); bit-identical for all-wet.

drain_reconstruct_hprev rdb_continuity Subroutine

hprev = max(0, areaT·h_end + div(uhtr,vhtr)) · iareaT, then the vanishing-layer hatch hprev += max(0, 1e-13·hprev − h_end) (Adcroft & Hallberg 2006; reuse of VANISHING_LAYER_TOL thinking).

drain_rescale_hTr rdb_continuity Subroutine

Re-weight a tracer’s thickness-weighted content onto a new layer thickness, holding the CONCENTRATION fixed:

Read more…
drain_rescale_hTr_budget rdb_continuity Subroutine

drain_rescale_hTr + the closed-budget fill. The concentration hold / un-hold pair is NOT content-conserving cell by cell – hTr := Tr·h moves Σ areaT·hTr by Σ areaT·Tr·δh, which is only zero when Tr is uniform – so both halves have to be recorded or the closed budget is only valid on window boundaries and wobbles at every mid-window report. Recording both makes them cancel exactly, since the un-hold is the arithmetic inverse of the accumulated hold.

Read more…
drain_subtract_3d rdb_continuity Subroutine

fld = fld - sub (uhr -= uhh).

drain_swept_flux_x rdb_continuity Subroutine

MOM6 swept-average CW parabola flux for the zonal faces. Face i, donor = cell (i-1) if uhh>0 else cell (i). Per-pass Courant CFL = |uhh| / (areaT·hprev) on the donor, clamped [0,1]. uhh >= 0: F = uhh·( aR − 0.5·CFL·((aR−aL) − a6·(1 − ⅔·CFL)) ) uhh < 0: F = uhh·( aL + 0.5·CFL·((aR−aL) + a6·(1 − ⅔·CFL)) )

drain_swept_flux_x_weno rdb_continuity Subroutine

WENO analogue of drain_swept_flux_x: swept-average zonal face flux from the concentration field tr using the WENO rung ladder. recon is TRACER_RECON_WENO5/7/9 (1/2/3); the internal rung_max is recon + 1 (WENO5→2, WENO7→3, WENO9→4).

Read more…
drain_swept_flux_y rdb_continuity Subroutine

Meridional analogue of drain_swept_flux_x.

drain_swept_flux_y_weno rdb_continuity Subroutine

Meridional analogue of drain_swept_flux_x_weno.

drain_update_h_x rdb_continuity Subroutine

hprev(i) -= (uhh(i+1) - uhh(i))·iareaT (volume div → thickness).

drain_update_h_y rdb_continuity Subroutine

Meridional analogue of drain_update_h_x.

drain_update_tracer_x rdb_continuity Subroutine

hTr(i) -= (F(i+1) - F(i))·iareaT (zonal flux divergence; dt is already baked into uhh⊂uhtr, so no dt here).

drain_update_tracer_x_budget rdb_continuity Subroutine

drain_update_tracer_x + the closed-budget fill: the SAME increment written to hTr is accumulated (times w) into budget_adv, so the console out term sees the horizontal tracer transport the windowed drain performs. Without this the drain moves tracer that ms%*_budget_horiz_adv never records, and the Heat/Salt Error column has to fall back to raw drift (which then reports a live surface flux as a “leak”). w is DRAIN_BUDGET_POST_AVERAGE_WEIGHT for every drain call site.

Read more…
drain_update_tracer_y rdb_continuity Subroutine

Meridional analogue of drain_update_tracer_x.

drain_update_tracer_y_budget rdb_continuity Subroutine

Meridional analogue of drain_update_tracer_x_budget.

drain_wrap_centre rdb_continuity Subroutine

Periodic wrap (+ north fold) of a cell-centred drain field. no_wait (optional): when .true. AND not folding, the periodic wrap is issued async on queue 1 without syncing, so a caller can batch several independent wraps (e.g. the pal/par/pa6 parabola triple) and !$acc wait(1) once. Ignored when fold_n (the fold reads the wrapped field, so the periodic wrap must complete first).

drain_wrap_face_x rdb_continuity Subroutine

Periodic wrap (+ north fold) of an x-face drain field (nx+1,ny,nz).

drain_wrap_face_y rdb_continuity Subroutine

Periodic wrap (+ north fold) of a y-face drain field (nx,ny+1,nz).

drain_zero_3d rdb_continuity Subroutine

fld = 0.

driver_run rdb_driver Subroutine

Compute-rank entry point. Runs the Arakawa C-grid + continuity-PPM split-RK2 ocean dynamical core in src/core/ocean/.

driver_run_ocean rdb_driver Subroutine

Run the full compute-rank lifecycle for the ocean regime.

Read more…
driver_validate rdb_driver Subroutine

rdb --validate-only: everything driver_run does before the first step that can REFUSE a configuration — the full engine_setup sequence, so every fail-loud configure-time check in the configure_ocean_* stages (rdb_ocean_setup.F90), the stability audit and the IC seed — and nothing after it: no device mapping, no stepping, no output files (the diag stream is not opened; see engine_setup’s validate_only).

Read more…
efp_bin1_within_transport_bound rdb_efp Function

Bin 1 is NOT bounded by efp_carry (only bins 2..6 are – see the module docstring), so the double-precision transport needs its own guard: after summing nranks local values, the partial sum in bin 1 must stay <= 2**53 / nranks for the MPI_SUM-on-doubles combine to remain exact (the analogue of MOM6’s prec_error = huge(1_int64) / num_PEs, but for the int64-as- double transport rather than int64 transport). .false. ⇒ the caller must error stop, never silently proceed.

efp_carry rdb_efp Subroutine

Renormalise bins 6..2 into (-2**P, 2**P), propagating the excess into the next-more-significant bin, without changing the represented value. Bin 1 is left untouched (unbounded by construction; see the module docstring on EFP_MAX_RANKS). Mirrors MOM6 carry_overflow, which loops EFP_DIGITS..2 for the same reason.

efp_decompose rdb_efp Subroutine

Greedy sign-magnitude fixed-point decomposition of r into six int64 bins of weight pr(n), n = 1..6. Unrolled (no loop, no array indexing over pr/I_pr) so this is a template a !$acc routine seq in-module duplicate can mirror exactly (see rdb_ocean_console_stats::efp_decompose_impl, which pins against this procedure in test_efp_impl_matches_canonical).

Read more…
efp_decompose_impl rdb_ocean_console_stats Subroutine

In-module !$acc routine seq duplicate of rdb_efp::efp_decompose – six SCALAR bin outputs (not an int64(6) array) so the call sites below can accumulate directly into reduction(+:e1..e6,epoison) clauses (OpenACC has no portable array reduction). Duplicated rather than called from rdb_efp because NVHPC’s device codegen does not inline a pure !$acc routine seq helper across a module boundary (CLAUDE.md Gotchas); test_efp_impl_matches_canonical (RDB_ENABLE_TESTING- gated) pins this copy bin-for-bit against the canonical procedure over the same magnitude table – compute_ice_totals’s docstring documents the identical pattern for ice_cell_concentration_impl.

Read more…
efp_from_real rdb_efp Function

real64 -> efp_t. Wraps efp_decompose; unlike the pre-fix version, the NaN / overflow flags are NOT discarded – they seed a%poison (nonzero iff is_nan .or. is_ovf), so a poisoned summand still taints every later efp_plus/efp_to_real even though the flags themselves aren’t returned here (callers needing the raw flags call efp_decompose directly).

efp_from_transport rdb_efp Subroutine

Inverse of efp_to_transport: unpack a flat real64(EFP_TRANSPORT_WIDTH*n) buffer (post-collective, still exact integers as doubles) back into efp_t values, converting each bin AND the summed poison counter back to int64 and carrying the bins. ok = .false. iff any unpacked double is not an exact integer (would indicate the transport-exactness bound was violated) – the caller (halo_allreduce_efp_list) turns that into a fail-loud error stop, never a silent truncation.

efp_minus rdb_efp Function

Exact bin-wise integer subtraction, regularised. See efp_plus for why regularisation (not mere carry) is required for bit-for-bit order invariance, and for the poison propagation (additive here too – subtraction of a poisoned operand is still poisoned, never “cancels” back to clean).

efp_plus rdb_efp Function

Exact bin-wise integer addition, REGULARISED (not merely carried). Order-invariant BIT-FOR-BIT: efp_plus(a,b)%v == efp_plus(b,a)%v, and a running fold acc = efp_plus(acc, x_i) over any permutation of the x_i converges to the SAME raw bins (not merely the same reconstructed real) – test_efp_order_invariant asserts this on %v(:) directly, per the plan’s §9.2.

Read more…
efp_real_diff rdb_efp Function

real64 = efp_to_real(efp_minus(a, b)) – the difference of two ~1e21-scale EFP totals resolved to the EFP quantum (2**-3P), NOT to ulp(1e21) as a double subtraction would give. This is the fix documented in the plan’s SS2.2: an implementer who converts both operands to real64 FIRST and subtracts loses the whole benefit of this module.

efp_regularize rdb_efp Subroutine

efp_carry plus: force every bin to share the overall sign, so a single well-conditioned FP accumulation (efp_to_real) can form Sum pr(n)*e(n) without alternating-sign cancellation error. Mirrors MOM6 regularize_ints.

Read more…
efp_summands_guard rdb_ocean_console_stats Subroutine

Fail-loud (never silent) guard: a k-slab’s physical cell count must not exceed EFP_MAX_SUMMANDS, else a bin could overflow int64 before the next efp_carry. 1.34e8 is an 11500^2 single-rank layer – unreachable today, but the check costs one comparison at status cadence (CLAUDE.md: an unchecked bound “is a silent-corruption path exactly like the NZ_STACK_MAX one”).

efp_to_real rdb_efp Function

efp_t -> real64. Regularises a LOCAL COPY of a (never mutates the argument) – pure with intent(in), per FORTRAN_STYLE.md’s “default new procedures to pure” (MOM6’s EFP_to_real instead mutates its intent(inout) argument).

Read more…
efp_to_transport rdb_efp Subroutine

Pack a list of efp_t values into a flat real64(EFP_TRANSPORT_WIDTH*n) buffer for a single collective (halo_allreduce_efp_list). Each bin, PLUS the poison counter, is transported as an EXACTLY-representable double (see EFP_MAX_RANKS): buf((i-1)*EFP_TRANSPORT_WIDTH + n) = real(list(i)%v(n)) for n = 1..EFP_DIGITS, and buf((i-1)*EFP_TRANSPORT_WIDTH + EFP_DIGITS+1) = real(list(i)%poison). Summing poison through the SAME MPI_SUM collective as the bins is what makes a poisoned rank’s contribution reach every other rank identically – see efp_t’s docstring.

emit_drift_line rdb_console_stats Subroutine

One <Label> : <total> Error <residual> conservation line. With budget_on the residual closes the budget — (total − ref) + out − src — and the cumulative outflux / surface source are appended; without it the residual is raw drift total − ref and the line is byte-identical to the pre-budget format. label is a 4-char tag (Mass / Salt / Heat) so the colons align.

Read more…
emit_row rdb_ocean_bt_budget_probe Subroutine
enforce_vanished_one_impl rdb_multilayer_state Subroutine

Flat-impl of the I1′ sweep for ONE tracer. Explicit-shape dummies so NVHPC does not walk a descriptor per launch.

engine_configure_diag rdb_ocean_engine Subroutine

Register the default diag-manager variable set and open the per-rank NetCDF stream. No-op when diagnostics are disabled. open_stream_file = .false. (the --validate-only path) runs the level/selection checks but creates neither the output directory nor the stream. Moved verbatim from driver_run_ocean’s private configure_ocean_diag helper (P2.4) so the API/bench setup paths can reach it too; F5 residual — now takes optional ierr instead of error stopping (see rdb_ocean_diag’s set_output_*_levels for the leaf-level conversions this threads through).

engine_enter_data rdb_ocean_engine Subroutine

Map the ocean state onto the device, then (when bt_halo > 0) allocate + attach the wide-halo BT march-in workspace, then warm up the device-path halo exchanges (UCX cuda_ipc handle open, outside any timed region — see driver_run_ocean’s “Content-safety argument” comment, carried over unchanged).

engine_exit_data rdb_ocean_engine Subroutine

Unwind device residency. Idempotent-adjacent: caller checks device_mapped (mirrors rdb_handle’s ocean_handle_t).

engine_setup rdb_ocean_engine Subroutine

Host-side setup: decomposition -> grid -> god state -> IC seed -> restart (optional) -> the 21 configure_ocean_*-family stages -> ghost wraps -> halo init -> land mask -> wave drag/porous -> sea-ice IC. Does NOT map the state onto the device — call engine_enter_data next. Preserves driver_run_ocean’s exact stage order; see the per-stage comments below (carried over from the driver almost verbatim).

engine_step rdb_ocean_engine Subroutine

Advance one outer step at fixed dt, starting from simulation time t (consumed by tide/astro forcing inside ocean_dyn_step_split; the caller advances its own t_current by dt afterwards — see the module docstring for what stays caller-side). Wraps ocean_dyn_step_split (rdb_ocean_dyn.F90:1986) plus the per-step halves of the setup stages that must run BEFORE the dyn-core advance: file-forcing update/apply, boundary-data refresh, porous-area refresh.

Read more…
engine_step_finalize rdb_ocean_engine Subroutine

Second half of one outer step: derive Q_heat/Q_salt from the surface-flux component set (no-op unless &ocean_forcing_nml enable_components) and, when diagnostics are configured, run one ocean_diag_t%step. Call immediately after engine_step and, when sea ice is enabled, engine_step_ice too — see engine_step’s docstring for why this is a separate call.

engine_step_ice rdb_ocean_engine Subroutine

P2.4b: sea-ice per-step physics — ocean-side frazil accumulation, EVP dynamics (every outer step, independent of the thermo cadence: the ice’s own fast/slow split) plus the resulting ice->ocean stress coupling, and, at thermo cadence (engine%state%dyn%is_thermo_step()), category transport followed by the atmospheric-forcing / basal-flux / frazil-uptake / column-thermo / snowfall / brine / heat / shortwave / ITD chain. Transcribed VERBATIM from driver_run_ocean’s former inline sea-ice block — the internal call order is load-bearing (see the “MANDATED ORDER” comment below, itself carried over unchanged) and is NOT reordered here. Returns immediately, a no-op, when &ocean_ice_nml enable = .false. — bit-identical to before this phase.

Read more…
engine_teardown rdb_ocean_engine Subroutine

Close the diag NetCDF stream (if one was opened), release the process-global ocean-halo and fold-exchange module state, then release host-side allocations. Call after engine_exit_data.

ensure_catalog_initialised rdb_ocean_diag_derived Subroutine

Populate the catalog at runtime (procedure pointers can’t be a parameter constructor). Idempotent.

ensure_directory_exists rdb_io_netcdf Subroutine

Create path via libc mkdir(2) if it does not already exist (single path component — not a recursive mkdir -p; a missing grandparent still fails, loudly, at the inquire re-check below). Exists to close the headline P7 crash: &ocean_diag_nml/ &output_nml default output_dir = "./output" (rdb_config.F90:2316), so a first-time create() against a fresh checkout with no ./output/ directory would otherwise reach nc_create_file -> nf90_create -> ENOENT -> error stop, killing the whole host process.

Read more…
enum_parse rdb_nml_schema Subroutine
eos_apply_tfreeze_set rdb_eos Subroutine

Write the named liquidus coefficient SET onto the EOS handle. Called once, at configure time, from the earliest configure_ocean_* stage — before the flat-POD handle is copied onto the vmix / EPBL / kappa-shear / tidal-mixing slots and before ocean_state_enter_data, so every copy and every device kernel taking eos_t by value sees the configured set (same contract as rho0 / p_ref; no !$acc update device is owed).

Read more…
eos_buoyancy_coeffs rdb_eos Subroutine

Thermal-expansion and haline-contraction coefficients of the ACTIVE equation of state at a point, in the SAME DIMENSIONAL convention the eos_t members alpha_T / beta_S carry:

Read more…
eos_compute_arrays rdb_eos Subroutine

Variant dispatch on bare 3D arrays — the state-agnostic body of ocean_eos_compute (the shim hosted in rdb_ocean_eos_compute), which forwards the multilayer state’s registry arrays here. Kept free of state-type dependencies so the dispatch stays callable from a bare array context. All impls evaluate at the SINGLE, HORIZONTALLY UNIFORM reference pressure eos%p_ref (&ocean_eos_nml p_ref, default 0 ⇒ surface/potential density) with the H_VANISHED vanishing-layer fallback to eos%rho0.

Read more…
eos_density_derivs rdb_eos Subroutine

Density sensitivities ∂ρ/∂T and ∂ρ/∂S of the ACTIVE equation of state at a point — the signed twin of eos_buoyancy_coeffs, which is where the per-variant closed forms live:

Read more…
eos_density_point rdb_eos Function

Scalar density evaluation at a point — the same formulas the 3D eos_*_impl kernels apply, exposed for finite-difference verification of eos_specvol_derivs and for host-side diagnostics. Takes the shared eos_t handle by value. The else is unreachable-by-contract (see eos_validate).

eos_density_specvol_derivs rdb_eos Subroutine

eos_density_point AND eos_specvol_derivs at the same point from ONE evaluation of the active EOS. The isopycnal-slope and Redi builders need both (drho/dX = -rho^2 * dSV/dX, locally referenced); calling the two routines separately evaluated the EOS twice – under Roquet, two full roquet_spv_point calls, the first of which threw its derivatives away. Each branch uses the same expressions as the two routines it fuses, so rho, dsv_dt and dsv_ds are the numbers they return.

eos_destroy rdb_eos Subroutine
eos_freezing_point rdb_eos Function

Seawater freezing point T_f (degC) at salinity S and pressure p — the ocean-side prerequisite for the sea-ice port (PLAN_SEA_ICE.md, PR 1). Same point-function style as eos_density_point (flat-POD eos_t by value, device- callable), plus elemental so callers can evaluate whole salinity arrays in one reference.

Read more…
eos_init rdb_eos Subroutine
eos_linear_impl rdb_eos Subroutine

Linear two-tracer EOS, flat-impl form:

Read more…
eos_roquet_spv_impl rdb_eos Subroutine

Roquet et al. (2015) SpV EOS evaluated at a single reference pressure p_ref (a SCALAR by design — see the horizontal-uniformity contract in eos_compute_arrays). Same outer-shim signature as eos_linear_impl/eos_wright_impl — bare 3D arrays, model (PT, SP) tracers, vanishing-layer fallback to rho_0.

Read more…
eos_specvol_derivs rdb_eos Subroutine

Analytic specific-volume sensitivities dSV/dT and dSV/dS (SV = 1/rho) at a point. Needed by the EPBL energy bookkeeping (pressure-weighted PE-per-unit-tracer-change weights) and kappa-shear buoyancy — dSV/dX = -(1/rho^2) d(rho)/dX.

Read more…
eos_validate rdb_eos Subroutine

Host-side fail-loud gate over the device-supported variant set. Device point routines (!$acc routine seq) cannot error stop, so membership in the device-callable set is guaranteed HERE at configure time; the device else branch is then unreachable-by-contract.

eos_wright_impl rdb_eos Subroutine

Wright (1997) rational EOS evaluated at a single reference pressure p_ref, which is a SCALAR by design — see the horizontal-uniformity contract in eos_compute_arrays. Same outer-shim signature as eos_linear_impl — bare 3D arrays, vanishing-layer fallback to rho_0.

Read more…
eos_wright_pgf_column_sweep_impl rdb_eos Subroutine

FV-Wright PGF column sweep. Top-down per-column traversal that simultaneously produces the hydrostatic pressure stack p_edge_out and the in-situ density rho_insitu_out at each layer centre.

Read more…
epbl_column_kernel rdb_ocean_epbl Subroutine

Per-column EPBL solve. One do concurrent (j, i) with the serial work in k inside (j -> i -> k ordering); ALL sweep state is carried in scalars (design doc D6) — the only column arrays are the six iteration-invariant workspaces filled by the prep sweep.

Read more…
epbl_compute rdb_ocean_epbl Subroutine

Run EPBL over the domain: fill this%kd_int (interface diffusivity) and this%mld. Call at thermo cadence with the thermo dt. Outer shim: dereferences the tracer-registry hTr arrays + the 2D Q_heat/Q_salt forcing fields on the host (array-of-DT and allocatable indirection blocks NVHPC device codegen), then forwards to the column kernel which reads q_T_kin(i,j) / q_S_kin(i,j) per column inside the DC.

Read more…
epbl_find_mstar rdb_ocean_epbl Subroutine

mstar = (mechanical TKE available for entrainment) / u^3. Schemes: constant; OM4 Ekman/Obukhov balance; RH18 fits. All followed by the optional convective reduction (mstar_conv_adj in [0,1]; the u=0 corner multiplies by (1 - adj), matching the reference behaviour).

epbl_lf17_la rdb_ocean_epbl Function

Turbulent Langmuir number La = sqrt(u*/u_s_SL): the Stokes drift averaged over the surface layer of thickness zsl under the Phillips spectrum, in the singularity-safe form (Breivik et al. 2016 with Webb & Fox-Kemper 2015 directional spreading). No MIN_LANGMUIR / LA_DEPTH_MIN floors — those belong to MOM6’s profile-averaging wave paths, not LF17.

epbl_lf17_wave_state rdb_ocean_epbl Subroutine

LF17 statistical wave state from the water-side friction velocity alone: COARE 3.5 fixed-point inversion u* -> U10 (Edson et al. 2013), then the Pierson-Moskowitz-based surface Stokes drift and Phillips peak wavenumber (Li & Fox-Kemper 2017; Breivik et al. 2016). BLD-independent — call once per column, outside the MLD iteration.

epbl_lt_enhance rdb_ocean_epbl Subroutine

Apply the Langmuir enhancement to mstar (Reichl & Li 2019; Li et al. 2016 stability modification). The modified Langmuir number folds the boundary-layer stability regime in via Ekman / Obukhov / MLD length-scale ratios, split by the sign of the surface buoyancy flux; all-zero lac coefficients give La_mod = La exactly.

epbl_merge_into_kv_kt rdb_ocean_epbl Subroutine

Fold the EPBL diffusivity into the vmix interface fields. Called EVERY stage (the interior closure rewrites kv/kt each stage; kd_int itself refreshes at thermo cadence). Interior interfaces only — k=1 (bed) and k=nz+1 (surface) stay at the closed-boundary zero in both source and target.

epbl_mixlen_shape rdb_ocean_epbl Function

Mixing-length shape factor in [translay_scale, 1]: 1 at the surface, decaying to the transition-layer floor at the MLD. shaped = .false. (no MLD iteration) returns 1.

equilibrium_arguments rdb_ocean_tide_astro Subroutine

Equilibrium argument V_c (radians) for every catalog constituent at day number dnum. s,h,p,N are taken in radians (deg-mod-360 -> rad); the result is left un-modded (cos/sin are periodic). The ±pi/2 diurnal signs are load-bearing.

error_ring_clear rdb_error_ring Subroutine

Reset the ring to empty.

error_ring_count rdb_error_ring Function

Number of live messages in the ring (0..ERROR_RING_SLOTS).

error_ring_get rdb_error_ring Function

Message at ring-relative index i (0 = most recent, 1 = next-most-recent, …). Empty string if i is out of [0, error_ring_count()).

error_ring_push rdb_error_ring Subroutine

Push one message; error_ring_get(0) is always the most recent. Overwrites the oldest slot once full.

evp_average_stress_impl rdb_ice_evp Subroutine

fxoc *= mask_u/evp_sub_steps, fyoc *= mask_v/evp_sub_steps (:1415-1441).

evp_build_masks_impl rdb_ice_evp Subroutine

mask_t: wet_T inside the physical domain AND in every ghost band that is not pinned; a ghost band on a physical, non-periodic edge (land_*) is 0 (SIS2 mask2dT semantics — pins a wall edge’s ghosts to land, matching SIS2’s own domain-edge convention even when a driver run’s wet_T ghost happens to read 1). An MPI seam ghost follows wet_T, which the ocean setup exchanged; the local periodic wrap (wrap_x/_y, only on an axis the halo does not own) then overwrites a single-rank periodic band, so on one rank the result is the same wrap-or-0 mask as before. mask_u(i,j) = mask_t(i-1,j)*mask_t(i,j), mask_v ditto in y, mask_q = product of the 4 surrounding mask_t (SIS2 mask2dBu).

evp_copy_u_impl rdb_ice_evp Subroutine

u_tmp = ui (full array — the v-momentum MUST read pre-update u, D4). Explicit do concurrent element copy rather than a bare whole-array assignment (repo convention for device-resident arrays — see rdb_ml_dynamics’s h_layer0 save pattern).

evp_fill_cell_fields_impl rdb_ice_evp Subroutine

Interior copy of the gathered mis/mice/ci, masked to mask_t (defence-in-depth beyond the caller’s own wet_T gate); ghost rows/cols zeroed (the periodic wrap that follows fills them).

evp_mi_face_impl rdb_ice_evp Subroutine

mi_u(i,j) = 0.5*(mis(i-1,j)+mis(i,j)); mi_v(i,j) = 0.5*(mis(i,j-1)+mis(i,j)) (SIS2 :967-974, rdb index translation §1). Array-edge faces (i=1/i=nx+1, j=1/ j=ny+1) have no neighbour on one side; mis at those ghost rows/cols was already periodic-wrapped or zeroed, so a naive mis(i-1,j)/mis(i,j) read is always in-bounds here EXCEPT at the two hard array edges themselves — those faces are handled explicitly.

evp_pres_mice_impl rdb_ice_evp Subroutine

pres_mice = p0_rho*exp(-c0*max(1-ci,0)) (:878); dxharm = 2*dxT*dyT/(dxT+dyT); del_sh_min_pr = 2*del_sh_min_scale*dt^2 / (Tdamp*dxharm^2) guarded on dxharm > 0 (:880-890).

evp_project_ci_impl rdb_ice_evp Subroutine

PR 36: PROJECT_ICE_CONCENTRATION (SIS2 SIS_dyn_cgrid.F90:1064- 1077). ci_proj = ci*exp(-dt_cum*sh_dd) then pres_mice = p0_rho*exp(-c0*max(1-ci_proj, 0)). ci_proj is a local() scalar, NOT an array: SIS2 materialises it only for the sigI/sigII/find_ice_strength diagnostics Roundabout does not have (documented divergence). del_sh_min_pr is NOT recomputed here (it has no ci dependence, evp_pres_mice_impl above). ci_proj is deliberately unclamped above 1 – max(1-ci_proj, 0) already saturates the effect at p0_rho, and for dt_cum*|sh_dd| > 709 (an unreachable regime in any sane run) exp overflows to +Inf, max(1-Inf, 0) = 0, exp(0) = 1 – IEEE launders the overflow to exactly the correct saturated value, so no guard is needed (SIS2 has none either).

evp_q_and_mi_ratio_impl rdb_ice_evp Subroutine

q(ic,jc) = f_corner*tot_area / (Σ areaT*mis over the 4 cells + tot_area*m_neglect) (:977-982); mi_ratio_A_q via ice_evp_mi_ratio_point (requirement 5). 4 T-cells around corner (ic,jc): (ic-1,jc-1) (ic,jc-1) (ic-1,jc) (ic,jc) (SW/SE/NW/NE, §1). Array-edge corners (no T-cell on one side) get q=0/mi_ratio=0 (land-corner convention — consistent with mask_t=0 beyond the array edge).

evp_sh_dd_dt_impl rdb_ice_evp Subroutine

sh_Dt / sh_Dd at cells (:1053-1061).

evp_sh_ds_impl rdb_ice_evp Subroutine

sh_Ds at corners (:1045-1050) — requirement (4): the SINGLE scalar no-slip factor (2-mask_q) on the WHOLE combined strain. Computed over the interior+1 ring (ic,jc in [1,nx+1]x[1,ny+1] — the full corner array; out-of-band neighbours contribute 0 via zero ghost velocities at the hard array edges, never per-term mirroring).

evp_str_s_relax_impl rdb_ice_evp Subroutine

str_s relax (:1137-1143). Corners in [1,nx+1]x[1,ny+1]; the 4 surrounding T-cells at an array-edge corner are handled by zeta’s own ghost values (zero-mass ghost cells => zeta=0 there, contributing nothing) — no special-case branch needed.

evp_stress_relax_impl rdb_ice_evp Subroutine

str_d/str_t semi-implicit relax (:1124-1134), non-weak_low_shear branch only.

evp_truncate_final_impl rdb_ice_evp Subroutine

PR 36: the FINAL CFL clip (SIS2 :1443-1500) – TRUNC_BACKOFF (0.95) back-off instead of the exact bound, PLUS a count of the ice-bearing faces it touched (mi > m_neglect, SIS2 :1466,1469 – massless faces clip silently, matching SIS2: counting them would flood the driver’s warning with meaningless ice-free clips at every margin). Not a do concurrent: reductions use !$acc parallel loop reduction(...) (ice_compress_impl is the local precedent for a reduction that also mutates the arrays it walks). Same bound algebra as evp_truncate_velocity_impl, duplicated rather than shared: the in-loop variant runs evp_sub_steps (432 by default) times per outer step and must NOT carry a reduction (each would be a device->host sync); this variant runs once and must. CLAUDE.md’s “duplicate explicitly” rule – merging the two costs 432 syncs per outer step.

evp_truncate_velocity_impl rdb_ice_evp Subroutine

PR 36: the shared CFL-clip algebra – the transport-CFL bound on the ice velocity (SIS2 SIS_dyn_cgrid.F90:839-870, the in-loop half at :1338-1361, the final half at :1443-1500; this routine is the counting-free, caller-chosen-backoff form both reuse; evp_truncate_final_impl below wraps it with the 0.95 back-off and the mi > m_neglect count).

Read more…
evp_u_momentum_impl rdb_ice_evp Subroutine

u-momentum (:1172-1231, requirement 1: fxic_now carries the FULL str_t force term). Loop over u-faces ng+1..ng+nxp+1 x ng+1..ng+nyp — each iteration writes only its own face.

Read more…
evp_v_momentum_impl rdb_ice_evp Subroutine

v-momentum (:1257-1334, mirror of u). D4: reads u_tmp (the PRE-update u), never the just-updated ui. Minus on the str_t divergence term (:1263-1267).

Read more…
evp_workspace_bytes rdb_ice_state Function

Counted allocatable footprint of the EVP scratch (0 when unallocated, i.e. whenever &ocean_ice_nml dynamics is off).

Read more…
evp_workspace_destroy rdb_ice_state Subroutine

Reverse of init (host deallocation). Idempotent — safe on an already-clean workspace. Device unmapping is exit_data’s job (call it first).

evp_workspace_enter_data rdb_ice_state Subroutine
evp_workspace_enter_data_impl rdb_ice_state Subroutine

Attach the scratch to the device with create — every array is pure scratch, fully (re)written before it is read on every ice_evp_dynamics call (masks rebuilt, cell fields filled, the subcycle kernels overwrite the rest), so create (not copyin) is correct. One-level components of the type(...) dummy — same shape as ocean_sea_ice_enter_data_impl, no associate-leaf needed.

evp_workspace_exit_data rdb_ice_state Subroutine
evp_workspace_exit_data_impl rdb_ice_state Subroutine

Reverse of enter_data_impl — pure scratch, delete throughout.

evp_workspace_init rdb_ice_state Subroutine

Allocate the EVP scratch for an (nx,ny) T-cell domain, zero-init. Called ONCE per workspace lifetime — from ocean_sea_ice_init (gated on dynamics) and from the EVP test harness. nx/ny declared before the arrays that use them is unnecessary here (all allocatables), but the extents are cached for destroy.

evp_wrap_corner_impl rdb_ice_evp Subroutine

Periodic ghost-wrap for a corner-staggered field (e.g. str_s), shape (nx_total+1, ny_total+1). No corner-wrap helper exists in rdb_ocean_periodic (only centre/face_x/face_y) — this is the EVP-local twin, same two-pass (x-then-y) structure.

evp_zero_massless_velocity_impl rdb_ice_evp Subroutine

SIS2 :899-907 — zero ice velocities where BOTH neighbouring cells are massless (or the face is masked/land).

evp_zero_stress_impl rdb_ice_evp Subroutine

Zero the subcycle-averaged ice->ocean stress accumulators via an explicit do concurrent device kernel (F1): fxoc/fyoc are copyin-mapped device-resident arrays, so a host = 0.0_wp would zero only the HOST copy and leave the device copy carrying the prior call’s average (the accumulate below would then converge to S/(N-1) instead of S/N). Runs on the device-present arrays; inert no-op on host builds.

evp_zeta_impl rdb_ice_evp Subroutine

del_sh / zeta (:1082-1095). shear_at_T averages the 4 surrounding corner sh_Ds values.

ew_rank_east rdb_ocean_halo Function

East neighbour rank with periodic wrap-around.

ew_rank_west rdb_ocean_halo Function

West neighbour rank with periodic wrap-around.

fac_weno rdb_coriolis_adv Function

MOM6 fac_fn: the WENO-Z nonlinear factor (1+tau/b)^2, EXACT-clamped (not an additive epsilon) to a dominant value when the smoothness indicator b is degenerate (|b| <= eps*tau), so a locally constant stencil takes over without a 0/0. Shared by weno3/5/7.

face_depth_mean_rem_u rdb_barotropic_coupling Subroutine

face_depth_mean_u with MOM6 wt_u weighting (&ocean_bt_nml forcing_visc_rem): the weight is h_face·visc_rem(k) instead of h_face, so layers the implicit vertical-friction solve will immediately damp (grounded sliver stacks under the BBL glue, visc_rem → 0) contribute nothing to the barotropic forcing. Without this the spurious grounded-layer PGF’s depth-mean drives the fast loop ballistically even after the layer velocities themselves are glued (PGF_BUG.md §9). Denominator falls back to zero-output on an all-remnant-zero column (the substep should not force an immobilized column).

Read more…
face_depth_mean_rem_v rdb_barotropic_coupling Subroutine

Symmetric v-face counterpart of face_depth_mean_rem_u — same MOM6 wt_u floor, ieee_is_finite-guarded the same way.

face_depth_mean_u rdb_barotropic_coupling Subroutine

Depth-average a u-face 3D field, weighted by the per-layer face thickness frhat_h_face_step returns (&ocean_bt_nml frhat_scheme; FRHAT_ARITHMETIC = the plain mean of the two abutting cell columns’ h_layer values, today’s default; the argument is otherwise unchanged). Writes to a 2D field at the same u-face shape. Wall faces (i=1, nx+1) fall back to the single available cell (frhat_h_face_step degenerates there for either scheme — see its docstring).

face_depth_mean_v rdb_barotropic_coupling Subroutine

Symmetric v-face counterpart of face_depth_mean_u.

face_thick rdb_ocean_vdiff Function

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Face-thickness for the vdiff implicit operator.

Read more…
fail rdb_error_ring Subroutine

Push msg to the error ring, log it (unchanged behaviour), then either set ierr = code and return (caller must return immediately after this call) or error stop msg when ierr is absent. See the module docstring for the full contract.

fill_2d_impl rdb_ocean_diag_fills Subroutine
fill_age rdb_ocean_diag_fills Subroutine

Layer ideal age = tracers(idx_age)%hTr / h_layer (s). Read-out only; registered when &ocean_tracers_nml enable_ideal_age (idx_age > 0).

fill_and_remap rdb_ocean_diag Subroutine

Invoke the var’s fill (and remap if non-LAYER) so output_buffer holds the current sample. The accumulation / log emission step consumes output_buffer after this.

Read more…
fill_bathymetry_ghosts_array rdb_bathymetry Subroutine

Fill ghost cell bathymetry by constant extrapolation from the nearest interior cell. This ensures boundary flux computations see a consistent bottom elevation across the ghost-interior interface. Works on a target 2D array directly so both the coastal and ocean barotropic slots can reuse it.

fill_bbl_constants rdb_ocean_vdiff Subroutine

The historical constant-piston glue (bbl_per_face = .false.).

fill_buffer_impl rdb_ocean_diag Subroutine

Device-side scalar fill. Used by reset_accumulator and (when idx_temperature / idx_salinity is unset) the manager could also seed output_buffer via this; today only the accumulator reset goes through here.

fill_cavity_melt_status rdb_ocean_diag_derived Subroutine

Per-column CAVITY_MELT_* status code, as a real. 0 is OK; anything else is a column that took the kernel’s documented zero-melt safe state, and the console’s warning line says how many there were. Masked like the rest, so the plane cannot be read as “everything is fine” over open ocean.

fill_coriolis_centre rdb_ocean_setup Subroutine

Fill a cell-centre |Coriolis| array via metrics_fill_coriolis (D7). beta_plane (default) is BIT-IDENTICAL to the legacy EPBL / kappa-shear set_f_centre. The corner output is discarded here (filled into local scratch).

fill_coriolis_corner rdb_ocean_setup Subroutine

Fill a C-grid corner Coriolis array via the single generator-driven routine metrics_fill_coriolis, honouring &ocean_grid_nml coriolis_scheme (D7). beta_plane (default) is BIT-IDENTICAL to the legacy coriolis_adv_set_beta_plane; planetary uses the metrics geography. The centre output is discarded here (filled into local scratch).

fill_exch_vel_s rdb_ocean_diag_derived Subroutine

Haline exchange velocity gamma_S (m/s) — see fill_exch_vel_t.

fill_exch_vel_t rdb_ocean_diag_derived Subroutine

Thermal exchange velocity gamma_T (m/s) the solve CONVERGED on — not Gamma_T·u* re-derived here. Under hj99/yung25 the two differ by the stratification suppression.

fill_f_corner_seam_ghosts rdb_ocean_setup Subroutine

Periodic-x wrap + north-fold (scalar copy) of the static corner Coriolis array for a tripolar grid. f is reflection-invariant (same latitude at the conjugate corner), so negate=.false.

Read more…
fill_getter_2d rdb_ocean_api Subroutine

2D counterpart of fill_getter_3d.

fill_getter_3d rdb_ocean_api Subroutine

Shared tail of every 3D P2 getter: base-address c_loc, actual array extents (never assumed from grid metadata — read straight off the pointer), and the generation stamp. arr must already be pointer-associated with a live, non-empty state array.

fill_ghost_east_res rdb_ocean_obc_baroclinic Subroutine

Reservoir-based ghost fill, east edge.

fill_ghost_east_sign rdb_ocean_obc_baroclinic Subroutine

Sign-switch ghost fill for the east edge.

fill_ghost_north_res rdb_ocean_obc_baroclinic Subroutine

Reservoir-based ghost fill, north edge.

fill_ghost_north_sign rdb_ocean_obc_baroclinic Subroutine

Sign-switch ghost fill for the north edge.

fill_ghost_south_res rdb_ocean_obc_baroclinic Subroutine

Reservoir-based ghost fill, south edge.

fill_ghost_south_sign rdb_ocean_obc_baroclinic Subroutine

Sign-switch ghost fill for the south edge.

fill_ghost_west_res rdb_ocean_obc_baroclinic Subroutine

Reservoir-based ghost fill, west edge. hTr_ghost = tres_w(j, k, it) * h_ghost — unconditional.

fill_ghost_west_sign rdb_ocean_obc_baroclinic Subroutine

Sign-switch ghost fill for the west edge.

fill_gpu rdb_array_utils Interface
fill_gpu_1d rdb_array_utils Subroutine
fill_gpu_2d rdb_array_utils Subroutine
fill_gpu_3d rdb_array_utils Subroutine
fill_h_layer rdb_ocean_diag_derived Subroutine
fill_h_layer_ghosts rdb_ocean_obc_baroclinic Subroutine

Zero-gradient fill of h_layer ghosts at open-ish edges.

fill_haline_driving rdb_ocean_diag_derived Subroutine

S* = S_far − S_b (g/kg) — the salinity contrast the haline exchange acts on. Positive under melting (meltwater freshens the interface).

fill_ice_conc rdb_ocean_diag_fills Subroutine

Total sea-ice concentration (0..1) at T-centres — the two-mode per-cell gather of ice_cell_concentration_impl (rdb_ice_state), inlined (see fill_ice_conc_thick_impl). Registered by register_default_diags only when &ocean_ice_nml enable. Public only for the unit-test suite.

fill_ice_conc_thick_impl rdb_ocean_diag_fills Subroutine

Shared conc/thick device kernel. Inlines the two-mode gather of ice_cell_concentration_impl (rdb_ice_state — convention of record; test_ocean_ice_diags pins the copies equal): ncat==1 legacy lumped (per-CELL m_ice, ci = 0/1), ncat>1 SIS2 ITD (ci = min(1, Σ part_size), mice = Σ part_size·m_ice). emit_thick=.false. ⇒ buf = ci; .true. ⇒ buf = mice/ICE_RHO_ICE (grid-mean thickness, m). Scalar flag branch is constant-folded on the device — one kernel, no scratch companion.

Read more…
fill_ice_speed rdb_ocean_diag_derived Subroutine

Sea-ice drift speed |u_ice| at T-centres (m/s) — C-face pairs averaged to centre, 2-D twin of the ocean fill_ke stencil. Ice off / not init ⇒ zeros (never registered by default; opt-in via &ocean_diag_nml diags).

fill_ice_speed_impl rdb_ocean_diag_derived Subroutine
fill_ice_thick rdb_ocean_diag_fills Subroutine

Grid-mean sea-ice thickness (m) at T-centres: mice/ICE_RHO_ICE (MOM6 effective-thickness convention) — the two-mode per-cell gather of ice_cell_concentration_impl, inlined (see fill_ice_conc_thick_impl). Registered by register_default_diags only when &ocean_ice_nml enable. Public only for the unit-test suite.

fill_ice_u rdb_ocean_diag_derived Subroutine

Eastward sea-ice velocity at T-centres (m/s) — u-face pair averaged to centre, 2-D twin of fill_u_centre. Ice off / not init ⇒ zeros.

fill_ice_u_impl rdb_ocean_diag_derived Subroutine
fill_ice_v rdb_ocean_diag_derived Subroutine

Northward sea-ice velocity at T-centres (m/s) — v-face pair averaged to centre, 2-D twin of fill_v_centre. Ice off / not init ⇒ zeros.

fill_ice_v_impl rdb_ocean_diag_derived Subroutine
fill_kd_epbl rdb_ocean_diag_fills Subroutine

EPBL interface diffusivity (m^2/s). Buffer is layer-shaped (nx, ny, nz); we emit the value at the BOTTOM interface of each layer (kd_int(:, :, k) convention), losing only the identically-zero surface interface.

fill_kd_epbl_impl rdb_ocean_diag_fills Subroutine
fill_kd_kshear rdb_ocean_diag_fills Subroutine

Kappa-shear interface diffusivity (m^2/s). Buffer is layer-shaped (nx, ny, nz); we emit the value at the BOTTOM interface of each layer (kd_int(:, :, k) convention), losing only the identically-zero surface interface.

fill_ke rdb_ocean_diag_fills Subroutine

KE per cell on the C-grid: KE = 0.25·(u_W² + u_E² + v_S² + v_N²), the discrete C-grid KE-density (consistent with the Coriolis KE_ARAKAWA stencil). Public only for the unit-test suite.

fill_ke_impl rdb_ocean_diag_fills Subroutine
fill_ke_total rdb_ocean_diag_derived Subroutine

Depth-integrated kinetic energy at each cell: KE_total(i, j) = Σ_k 0.5 · h_layer(k) · (u_c² + v_c²)

fill_ke_total_impl rdb_ocean_diag_derived Subroutine
fill_kv_scalar_buf rdb_ocean_vdiff Subroutine

Broadcast the scalar viscosity kappa into the interface-located workspace. Boundary interfaces (bed at k=1, surface at k=nz+1) are forced to zero to match the closed BCs the column solve assumes; the original scalar kernel hard-coded those BCs via α_1 = 0 and β_nz = 0.

fill_melt rdb_ocean_diag_derived Subroutine

Basal melt mass flux (kg m-2 s-1), positive = melting.

fill_melt_m_per_yr rdb_ocean_diag_derived Subroutine

Basal melt rate in the ISOMIP+ reporting unit (m yr-1 of ice-equivalent freshwater) — see melt_m_per_yr_factor.

fill_mld_density rdb_ocean_diag_derived Subroutine

Mixed-layer depth via the de Boyer Montégut threshold.

fill_mld_density_impl rdb_ocean_diag_derived Subroutine

Per-column scan from the first LIVE layer (k_top, which is nz_ml unless a rigid top has vanished the layers above it) toward the bed; first layer whose ρ exceeds (surface ρ + MLD_DENSITY_THRESHOLD) marks the MLD as the cumulative h-sum above it. No crossing → MLD = full column depth. Threshold met at the surface itself → MLD = 0.

Read more…
fill_mld_epbl rdb_ocean_diag_fills Subroutine

EPBL active-mixing-layer depth (m) into the k=1 plane.

fill_pseudo_salt rdb_ocean_diag_fills Subroutine

Layer pseudo-salt = tracers(idx_pseudo_salt)%hTr / h_layer (psu). Read-out only; registered when &ocean_tracers_nml enable_pseudo_salt (idx_pseudo_salt > 0). Mirrors fill_age.

fill_pseudo_salt_diff rdb_ocean_diag_fills Subroutine

Pseudo-salt deviation D = pseudo_salt - S (psu): a direct, measured proxy for how far the passive-tracer transport path has drifted from the active-tracer (salinity) path. Gated on BOTH indices being registered.

fill_rho_layer rdb_ocean_diag_derived Subroutine

In-situ density per layer — direct read of the EOS slot (driver must have run ocean_eos_compute this step; not re-invoked here), with the NaN missing-data sentinel on every vanished layer.

fill_rho_layer_impl rdb_ocean_diag_derived Subroutine

buf = rho_layer on live layers, IEEE NaN on vanished ones.

Read more…
fill_salinity rdb_ocean_diag_fills Subroutine

Layer salinity, same pattern as temperature.

fill_sbdry rdb_ocean_diag_derived Subroutine

Interface salinity S_b (g/kg).

fill_ssh rdb_ocean_diag_fills Subroutine

SSH = total column thickness minus bathymetry depth, into the k=1 plane of buf. Multilayer or barotropic path per use_multilayer. Public only for the unit-test suite.

fill_ssh_bt_impl rdb_ocean_diag_fills Subroutine
fill_ssh_ml_impl rdb_ocean_diag_fills Subroutine
fill_tbdry rdb_ocean_diag_derived Subroutine

Interface temperature T_b (degC) — on the liquidus at S_b.

fill_temperature rdb_ocean_diag_fills Subroutine

Layer temperature = tracers(idx_temperature)%hTr / h_layer. Tracer-registry indirection dereferenced HOST-side before the flat-impl kernel (array-of-DT deep deref blocks NVHPC device codegen). Public only for the unit-test suite.

fill_tfreeze_ib rdb_ocean_diag_derived Subroutine

T_f(S_far, p_top) (degC) — the in-situ freezing point of the FAR FIELD at the ice base. Distinct from tbdry, which is the freezing point of the INTERFACE salinity S_b; their difference is the whole three-equation correction, so shipping both makes it visible.

fill_thermal_driving rdb_ocean_diag_derived Subroutine

T* = T_far − T_f(S_far, p_top) (degC) — the far-field temperature above the IN-SITU freezing point at the interface pressure. Positive drives melting. This is the single number the melt rate is roughly linear in, so it is the first thing to look at when a melt rate looks wrong.

fill_tracer_ghosts_meridional rdb_ocean_obc_baroclinic Subroutine

Upwind-aware tracer ghost fill for south and north open edges.

fill_tracer_ghosts_zerograd rdb_ocean_obc_baroclinic Subroutine

Zero-gradient CONCENTRATION fill of a tracer’s hTr ghosts at open-ish edges over the FULL cross-extent (ghost×ghost corners included): hTr_ghost = (hTr_int / h_int) * h_ghost. Runs BEFORE the upwind-aware per-edge fill, so corners keep this zero-gradient value (no corner T/S blow-up under inflow). Same gating/corner coverage as fill_h_layer_ghosts.

fill_tracer_ghosts_zonal rdb_ocean_obc_baroclinic Subroutine

Upwind-aware tracer ghost fill for west and east open edges. West inflow : u(i_w,j,k) > 0 → ghost = clamped_tr * h_ghost West outflow : u(i_w,j,k) <= 0 → ghost = interior (zero-gradient) East inflow : u(i_e,j,k) < 0 East outflow : u(i_e,j,k) >= 0

fill_tracer_impl rdb_ocean_diag_fills Subroutine

Shared flat-impl for any tracer concentration field.

Read more…
fill_transport_x rdb_ocean_diag_derived Subroutine

Depth-integrated zonal transport (m²/s): T_x(i, j) = Σ_k h_c · u_c (cell-centre form)

fill_transport_x_impl rdb_ocean_diag_derived Subroutine
fill_transport_y rdb_ocean_diag_derived Subroutine

Depth-integrated meridional transport (m²/s) — mirror of x.

fill_transport_y_impl rdb_ocean_diag_derived Subroutine
fill_u_centre rdb_ocean_diag_fills Subroutine

C-grid u-face → cell centre by simple 2-point average.

fill_u_centre_impl rdb_ocean_diag_fills Subroutine
fill_ustar_shelf rdb_ocean_diag_derived Subroutine

Melt friction velocity u* (m/s), max(sqrt(C_d(u²+v²+u_tide²)), u*_min). This is the MELT law’s u* and nothing else: it drives no momentum drag, and KPP/EPBL do not read it.

fill_uv_layer_ghosts rdb_ocean_obc_baroclinic Subroutine

Zero-gradient fill of per-layer face velocities into the OPEN-edge ghost region, corners included. u_layer (nx_total+1, ny_total, nz); v_layer (nx_total, ny_total+1, nz). x-pass over the full cross extent; y-pass clipped to the physical span unless the adjacent x-edge is open. Gated on open-ish tags ⇒ WALL/PERIODIC ⇒ no DC ⇒ bit-identical.

fill_v_centre rdb_ocean_diag_fills Subroutine
fill_v_centre_impl rdb_ocean_diag_fills Subroutine
fill_vorticity_z rdb_ocean_diag_derived Subroutine

The model’s OWN relative vorticity ζ = ∂v/∂x − ∂u/∂y, at the same C-grid corners coriolis_adv computes it at (circulation/area form, C1 slip factor), averaged corner -> cell centre. See fill_vorticity_z_impl for the formula and why it replaced a centred T-point stencil that differenced ocean velocity straight against the zero stored at land faces (a spurious no-slip-like vorticity sheet at every coast, even under the free-slip default).

fill_vorticity_z_impl rdb_ocean_diag_derived Subroutine

Cell-centred relative vorticity that MIRRORS the dynamics’ own corner ζ bit-for-bit — the shared rdb_rvc_zeta_corner body (src/shared_module_utilities/rdb_rel_vort_corner.inc), the same circulation-form formula coriolis_adv_compute_tendencies Pass 1 evaluates inline for its q_corner scratch (src/core/ocean/kernels/coriolis_adv/rdb_coriolis_adv.F90), incl. the C1 slip factor: no_slip=.false. (default, free-slip) masks a land corner (wet_q=0) to zero rel-vort; .true. (no-slip) gives it the 2-wet_q image-vorticity value instead.

Read more…
fill_water_column rdb_ocean_diag_derived Subroutine

Water-column thickness under the shelf, D = bt_H_ref + bt_eta (m) — the ONE expression every consumer of the column depth uses, which is exactly what the cavity datum (bt_H_ref = b − z_draft) buys. Masked by cover_frac: the quantity is perfectly well defined in open water, but as a CAVITY diagnostic a domain mean should be the mean cavity thickness, not that diluted by the open basin.

fill_z_draft rdb_ocean_diag_derived Subroutine

Ice-shelf draft (m, POSITIVE DOWN from the geoid) — geometry, so it needs only &ocean_cavity_dyn_nml and is masked by cover_frac rather than by the melt slot’s active. Beyond the calving front there is no draft, which is missing data, not a draft of zero.

fill_zero_impl rdb_ocean_diag_fills Subroutine

Device-side zero of buf — used when a fill’s input is missing (e.g. tracer not registered) so the fold reads a defined value.

finalise_accumulator rdb_ocean_diag Subroutine

Copy the accumulator into output_buffer. Called at cadence-fire BEFORE log / NetCDF emission consumes output_buffer.

Read more…
finalise_copy_impl rdb_ocean_diag Subroutine
finalise_scale_impl rdb_ocean_diag Subroutine

Device-side out = accum * scale_factor. Used for MEAN finalise where scale_factor = 1/dt_accum.

Read more…
find_duhbt_du rdb_bt_cont_type Function

Marginal zonal face area d(uhbt)/du. At u = 0 returns the average of the two cubic-branch slopes (discontinuity harmless — only consumed via max(…, h_neglect)).

find_dvhbt_dv rdb_bt_cont_type Function

Meridional mirror of find_duhbt_du.

find_or_create_region rdb_profiler Function
find_uhbt rdb_bt_cont_type Function

Zonal mass transport through a u-face given face velocity u. C¹ continuous in u (cubic near zero, linear saturation beyond).

find_var rdb_ocean_z_init Subroutine

Resolve a variable id: try the namelist override name first (when non-blank), then the documented fallbacks in order. Error-stops with a descriptive message when none is found.

find_vhbt rdb_bt_cont_type Function

Meridional mirror of find_uhbt.

fmt_int rdb_nml_schema Function

Format an integer.

fmt_json_bool rdb_nml_schema Function

Format a logical as a JSON true/false literal (as opposed to fmt_logical’s Fortran .true./.false.).

fmt_logical rdb_nml_schema Function

Format a logical as namelist .true./.false..

fmt_real rdb_nml_schema Function

Format a real in a stable, namelist-valid exponential form.

fold_centre_2d rdb_ocean_fold_exchange Subroutine

Cell-centred 2D north fold (copy).

fold_centre_3d rdb_ocean_fold_exchange Subroutine

Cell-centred 3D north fold (copy).

fold_corner_2d rdb_ocean_fold_exchange Subroutine

SW-corner 2D north fold (+ fold-line projection); negate for a true-vector component, copy for a scalar / vorticity.

fold_north_centre rdb_ocean_fold Interface
fold_north_centre_2d rdb_ocean_fold Subroutine

Fill the north halo of a 2D cell-centred field by the T-fold.

fold_north_centre_3d rdb_ocean_fold Subroutine

3D T-fold halo-fill — identical per level.

fold_north_corner rdb_ocean_fold Interface
fold_north_corner_2d rdb_ocean_fold Subroutine

2D Bu-corner fold: north-halo fill + on-line projection.

fold_north_u_face rdb_ocean_fold Interface
fold_north_u_face_2d rdb_ocean_fold Subroutine

Fill the north halo of a 2D x-face (Cu) field. Sign-flipped by default (negate absent / .true., the true-vector contract — wind stress, velocity). negate=.false. copies instead: for a SCALAR carried on a u-face (e.g. the viscous remnant visc_rem_u — a fraction, not a flux component), the 180-degree fold rotation still swaps which side of the seam the value sits on, but the value itself does not change sign (see fold_north_corner_2d’s negate for the matching corner-stagger contract).

fold_north_u_face_3d rdb_ocean_fold Subroutine

3D x-face (Cu) north-halo fill, per-level identical. See the 2D twin for the negate (vector vs. scalar) contract.

fold_north_v_face rdb_ocean_fold Interface
fold_north_v_face_2d rdb_ocean_fold Subroutine

2D y-face (Cv) fold: north-halo fill + on-line antisymmetric projection at the fold row. Used for the barotropic bt_vbt field in the BT fast loop. negate (default .true., see the u-face twin) selects true-vector (sign flip + self-conjugate zero) vs. scalar (copy + self-conjugate left unchanged, matching fold_north_corner_2d’s scalar contract) — a scalar on a v-face (e.g. visc_rem_v) is the SAME physical attribute of the SAME face seen from both sides of the seam, so the duplicated DOF at the fold line must agree, not cancel.

fold_north_v_face_3d rdb_ocean_fold Subroutine

3D y-face (Cv) fold: north-halo fill + on-line antisymmetric projection at the fold row. See the 2D twin for the negate (vector vs. scalar) contract.

fold_plan_build rdb_ocean_fold_plan Subroutine

Build tile rx’s send/receive lists for every peer and both column families. Pure: every north-row rank computes every tile’s receive lists itself (decomp_init arithmetic), so no handshake.

fold_plan_destroy rdb_ocean_fold_plan Subroutine

Free the plan’s lists and reset it to the empty default. Safe on a plan that was never built.

fold_receiver_entries rdb_ocean_fold_plan Subroutine

Every destination column i = 1..ncol of tile rx’s window for a column family: the owning tile own(i) of its mirror, the owner’s local storage column src(i) to read, and the fold-row class cls(i). ncol = w+2ng (T) or w+2ng+1 (U); the arrays must hold at least that many entries.

fold_row_map rdb_ocean_fold_plan Subroutine

Storage rows of message row r (1..fold_stagger_nrows) on a north-row tile of nyl physical rows: the sender reads src_row, the receiver writes dst_row. * T, u: r = d = 1..ng: src ng+nyl+1-d, dst ng+nyl+d. * v, corner: r = d+1, d = 0..ng: src ng+nyl+1-d, dst ng+nyl+1+d (d = 0 is the fold-line row, src = dst = ng+nyl+1).

fold_sample rdb_ocean_diag Subroutine

Combine the current output_buffer sample into accumulator per time_op.

Read more…
fold_sample_masked_impl rdb_ocean_diag Subroutine

Masked fold — multiplies sample by weight(i, j) before folding. MAX/MIN treat weight == 0 as “don’t update” so masked-out cells keep their seed value. Loop bounds clip to whichever extent is smaller (accumulator vs mask) so an undersized mask doesn’t OOB.

fold_sample_unmasked_impl rdb_ocean_diag Subroutine

Whole-buffer fold without a region mask. One do concurrent per op so the compiler can specialise — case-inside-loop blocks NVHPC device codegen.

fold_stagger_family rdb_ocean_fold_plan Function

Column family of a stagger (FOLD_FAM_T for T/v, FOLD_FAM_U for u/corner).

fold_stagger_nrows rdb_ocean_fold_plan Function

Rows a stagger moves per column: ng (T, u) or ng+1 (v, corner: the fold-line row is always sent, the receiver uses it only where recv_cls == FOLD_ROW_WEST).

fold_tile_extent rdb_ocean_fold_plan Subroutine

First global cell a and width w of tile rx — the decomp_init split (remainder to the WEST tiles), restated here so the plan stays pure and dependency-free (cross-checked against decomp_init by the unit test).

fold_tile_owner rdb_ocean_fold_plan Function

Tile holding global cell c (1..ni), closed form of the decomp_init split.

fold_u_2d rdb_ocean_fold_exchange Subroutine

x-face (u) 2D north fold (negate).

fold_u_3d rdb_ocean_fold_exchange Subroutine

x-face (u) 3D north fold (negate).

fold_v_2d rdb_ocean_fold_exchange Subroutine

y-face (v) 2D north fold (negate + fold-line projection).

fold_v_3d rdb_ocean_fold_exchange Subroutine

y-face (v) 3D north fold (negate + fold-line projection).

forcing_components_need_thermo rdb_config Function

&ocean_forcing_nml enable_components=.true. with &ocean_thermo_nml enable_thermodynamics=.false. is a configuration that validates but does nothing (the component set only feeds the assembler->apply_tracers thermo path) — named predicate per the lateral_closure_is_implemented idiom so validate_config reads as one line.

fv_mom6_mass_weights rdb_ocean_pressure_force Subroutine

MOM6 near-bottom hWght mass-weighting fractions of one face (MASS_WEIGHT_IN_PRESSURE_GRADIENT): the distance by which the layer top of one column sits below the other column’s bed, scaled by the squared relative thickness contrast. Zero ⇒ plain linear interpolation (hwt_ll = hwt_rr = 1, hwt_lr = hwt_rl = 0).

gate_clause rdb_ocean_diag_derived Function

Render canonical_diag_gate_hint(name) into a human-readable sentence for the “requested but not registered” warning. Phrased as a QUESTION, never a diagnosis: the hint is a hand-maintained mirror of register_default_diags’s gates (§11.2 of the PR-64 plan) and can drift from the true cause. An empty hint means the diagnostic is one of the four unconditional ones (SSH/u/v/KE) and SHOULD have registered — that is a bug, not a closed gate.

get_clamped_tracer rdb_ocean_obc_baroclinic Function

Safe accessor: return clamped_tracer(it) or 0 if unallocated/out of range.

get_wall_time rdb_profiler Function
gm_block_below_bed rdb_ocean_gm Function

MOM6 bottom-blocking (“Avoid moving dense water upslope from below the level of the bottom on the receiving side”). sfn is the unlimited streamfunction at an interface: the transport of everything BELOW it, > 0 from L to R. Its donor layer is the one just below the interface on the donor side ([e_bot, e_top]).

Read more…
gm_clamp_khth rdb_ocean_gm Subroutine

Fill the 2D face KhTh fields from the per-face base, CFL-clamped per face (native u-face idxCu/idyCu, v-face idxCv/idyCv) and zeroed on wall faces. Base = VarMix khth_ext_* when use_ext, else the scalar khth; the same diffusive-CFL min is applied either way.

gm_clamp_slope rdb_ocean_gm Function

Clamp a slope to +/- smax (bounded slope for the PE release). A non-finite slope reads as 0 (no release) rather than being laundered into ±smax by the NaN-blind clamp (CLAUDE.md).

gm_column_x rdb_ocean_gm Subroutine

u-face GM streamfunction + bolus-transport column recurrence. Interior u-face (i=2..nx) pairs columns iw=i-1 (west) and i (east). Bottom-up sweep: interior interfaces Kr=2 (bed-most) -> nz (surface-most), uhtot=0 at the bed; the surface BC (Sfn=0 at Kr=nz+1) is closed after the loop by uhD(nz)=-uhtot, giving Sum_k uhD=0 exactly. Interface Kr straddles ka=Kr (above) and kb=Kr-1 (below) and fills LAYER kb; the rsum bound keys on ka, the donor h_frac and per-layer cap on kb.

Read more…
gm_column_y rdb_ocean_gm Subroutine

v-face GM column recurrence — mirror of gm_column_x with the v-stagger. Interior v-face (j=2..ny) pairs columns js=j-1 (south) and j (north). See gm_column_x for the open-column (use_open) rule and the MOM6 nk_linear divergence note.

gm_compute_impl rdb_ocean_gm Subroutine

Flat-impl GM kernel. Passes: CFL-clamp the 2D face KhTh, the u-face and v-face column recurrences into uhD/vhD, the gm_src PE release. Each face’s column sweep is serial in k (the uhtot recurrence) but faces parallelise over (i,j).

gm_compute_transports rdb_ocean_gm Subroutine

Fill uhD/vhD (m^3/s) with the GM bolus thickness transport and gm_src with the PE release, from the CURRENT ms%h_layer and the stored slopes. Run every outer step AFTER the dynamics, and immediately followed by continuity_gm_apply with the SAME dt and the same, untouched h_layer: the availability cap A·(h − H_VANISHED)/(4·dt) bounds that h and no other (see the module docstring). No-op when disabled, uninitialised, or the slopes slot is absent/disabled.

Read more…
gm_h_frac rdb_ocean_gm Function

Donor mass fraction h_avail(k)/rsum_above(k) (0 when no mass is available above). rsum_above(k) is the cumulative availability from the surface down to and including layer k, so hf in [0,1].

gm_pe_release rdb_ocean_gm Subroutine

GM potential-energy release at cell centres for the MEKE seam: gm_src = 1/4 * Sum_k rho0 * (KHSlope^2N^2) * h over the four straddling faces, summed over interior interfaces; slope clamped to slope_max, N^2 floored at 0. gm_src >= 0 for a stable tilted column. An interface value is attributed to the layer below it (kb=K-1); bed + surface carry zero slope/N^2.

gm_pos_n2 rdb_ocean_gm Function

max(N^2, 0) for the PE release, with a non-finite N^2 read as 0 (a bare max is NaN-blind under relaxed FP, CLAUDE.md).

gm_refreshes_varmix rdb_ocean_dyn Function

.true. when the GM block below this step already calls varmix_compute (GM present + enabled + slopes present, at a thermo step) — so the standalone Gap-1 resolution-function refresh must NOT run it again (avoids a double compute and preserves the GM+VarMix slope ordering bit-for-bit).

gm_tracer_advect_x rdb_continuity Subroutine

Zonal PPM tracer advection of every horizontally-advected tracer by the GM bolus flux uflux (the resolved path’s own kernel, tracer_advect_zonal_one_impl; heat/salt budgets weighted by budget_w). No OBC ghost override: continuity_gm_apply has closed every non-periodic edge face.

gm_tracer_advect_y rdb_continuity Subroutine

Meridional twin of gm_tracer_advect_x.

gprime_nz_is_supported rdb_ocean_pressure_force Function

.true. unless variant == OPGF_VARIANT_GPRIME with nz /= 2 (PR-6 fail-loud). The reduced-gravity gprime PGF hard-writes ONLY k=1 (bottom) and k=2 (top) — with nz > 2 layers k=3..nz carry zero pressure gradient AND the “top” branch lands on layer 2 of nz (the abyss under the bottom-up convention); with nz < 2 the kernel early-returns leaving the whole PGF zero. The guard is gprime-specific — every other variant supports general nz, so this returns .true. for them regardless of nz. Wired into validate_config against cfg%nz_layers (config-time).

great_circle rdb_ocean_metrics Function

Great-circle distance (m) between two geographic points (deg), via the haversine formula (numerically stable for short arcs).

gregorian_day_number rdb_ocean_tide_astro Function

Proleptic-Gregorian Julian Day Number (integer, at 00:00 UT). Fliegel & Van Flandern algorithm.

grid_init rdb_grid Subroutine
group_add rdb_nml_schema Subroutine

Add a key to the group (sourced-allocate into a box). Error stop on duplicate key name (programming error).

group_find_key rdb_nml_schema Function

Index of name in the group’s key list, 0 if absent.

group_key_list rdb_nml_schema Function

All key names of a group as a char array.

group_name_list rdb_nml_schema Function

All registered + external group names as a char array.

grow_buffers rdb_ocean_fold_exchange Subroutine

(Re)allocate both buffers for nslab slabs per peer (exit-delete / dealloc / alloc / enter-create, as ocean_halo_buffers_ensure_nz). Never while a group is open.

h_face_upstream_open_impl rdb_barotropic_coupling Subroutine

OPEN-column upstream face thickness, for upstream_h_face under &vcoord_nml zfixed_closed_faces.

Read more…
halo_allreduce_efp_list rdb_halo Subroutine

Order-invariant EXACT cross-rank combine of nval EFP values in ONE collective (PR-32). Replaces N separate scalar halo_allreduce_sum calls with one packed allreduce.

Read more…
halo_allreduce_max rdb_halo Subroutine

MPI_Allreduce with MPI_MAX — max-type reductions are exact in FP, so a global max stays layout-reproducible (ocean-MPI plan D5). Used for auto_n_inner’s global gravity-wave CFL (shared n_inner).

halo_allreduce_min rdb_halo Subroutine

MPI_Allreduce with MPI_MIN for global timestep

halo_allreduce_sum rdb_halo Subroutine

MPI_Allreduce with MPI_SUM for CG dot products

halo_allreduce_sum_i8 rdb_halo Subroutine

Cross-rank int64 sum for the decomposition-invariant chksum bitcount (rdb_ocean_chksum). pic_mpi_lib exposes no integer(int64) allreduce overload (MPI_INTEGER8 reaches only send/recv), so the value rides the EXACT real64 allreduce: a per-field POPCNT sum is bounded by (#elements x 64), which stays FAR below the double-mantissa bound 253 for any realistic grid (253/64 ~ 1.4e14 cells), so both the local->double cast and every partial MPI_SUM are exact — the invariant survives.

halo_async_destroy rdb_halo Subroutine

Free pre-allocated halo buffers

halo_async_init rdb_halo Subroutine

Pre-allocate halo buffers for all 4 fields

halo_exchange_2d rdb_halo Subroutine

Exchange ghost-cell halos for a single 2D field

Read more…
halo_exchange_2d_device rdb_halo Subroutine

GPU-direct halo exchange via CUDA-aware MPI

Read more…
halo_exchange_3d rdb_halo Subroutine

Exchange ghost-cell halos for a 3D field (all nz layers packed per direction)

halo_exchange_3d_device rdb_halo Subroutine

GPU-direct halo exchange for a 3D field, batched across layers.

Read more…
halo_exchange_begin rdb_halo Subroutine

Pack and post non-blocking MPI sends/recvs for all 4 fields

Read more…
halo_exchange_end rdb_halo Subroutine

Wait for MPI to complete and unpack received ghost cells

Read more…
halo_sync_buffers_cleanup rdb_halo Subroutine

Release the persistent halo buffers. Idempotent.

halo_sync_buffers_cleanup_3d rdb_halo Subroutine

Release the persistent 3D halo buffers. Idempotent.

halo_sync_buffers_ensure rdb_halo Subroutine

Lazy-allocate the persistent send/recv buffers used by halo_exchange_2d_device (and halo_exchange_2d via the same pool). Sized to the per-rank subdomain; resizes on grid change.

Read more…
halo_sync_buffers_ensure_3d rdb_halo Subroutine

Lazy-allocate the persistent 3D send/recv buffers used by halo_exchange_3d_device. Sized to the per-rank subdomain and the largest nz seen so far – subsequent calls with a smaller nz reuse the existing buffer (just write fewer elements), grow-only on nz so an ML run that later does an NH w halo (nz_ml+1) doesn’t free/reallocate. Resizes in full if (nx_total, ny_total, nghost) change.

handle_check rdb_handle Function

Resolve an opaque c_ptr to a Fortran pointer and verify it.

Read more…
handle_create rdb_handle Function

Allocate a new ocean handle and return its opaque C pointer. Caller (rdb_ocean_create_from_string) is responsible for eventually passing it to handle_destroy — including on every early-return failure path, so a handle that never reached is_initialised does not leak.

handle_destroy rdb_handle Subroutine

Free an ocean handle. Idempotent on null/already-destroyed/garbage handles — silently no-ops rather than aborting, so a Python __del__ can call this blind. Caller is responsible for having already unwound device residency and called engine_teardown (engine%state%destroy() releases the god-state’s Fortran allocations) — h%state is only a pointer VIEW onto h%engine%state (see ocean_handle_t’s docstring), never separately allocated, so there is nothing to deallocate through it here; this only releases the handle’s own heap block (which takes engine — a value component — down with it). garbage or already destroyed

handle_has_area rdb_ocean_api Function

True when the handle’s metrics carry a full ghosted areaT (every grid the engine builds does); anything else falls back to grid%dx*grid%dy.

has_biharmonic_backstop rdb_ocean_lateral_mix Function

.true. iff the configured biharmonic dispatch will produce a STRICTLY POSITIVE dissipation coefficient somewhere. Drives the configure-time fail-loud guard requiring a biharmonic backstop when MEKE backscatter is on — the negative harmonic backscatter feeds a grid-scale mode that only a positive biharmonic can dissipate.

Read more…
henyey_lat_factor_impl rdb_ocean_vmix Function

Henyey, Wright & Flatte (1986) JGR 91:8487 latitude dependence of the internal-wave-driven mixing rate, in the SIMPLIFIED constant-N0 form of Harrison & Hallberg (2008) JPO 38:1894 — the in-situ column stratification is replaced by a fixed reference N0, so the factor collapses to a pure function of latitude:

Read more…
hk_corner_h rdb_coriolis_adv Function

Corner thickness of the HK PV, recomputed with EXACTLY the Pass 2 formula of coriolis_adv_compute_tendencies_hk (wet-area-weighted 4-cell mean, array-edge clamps, CORIOLIS_H_MIN_PV floor), so the closed-face branch knows the h_corner each stored q was divided by without a persistent buffer.

hk_pair_coef rdb_coriolis_adv Function

One Arakawa-Hsu pair coefficient (q1 + q2 + q3)/12 with each PV re-evaluated at a corner thickness of at least h_ref/2: q → q·h_X/(h_ref/2) where h_X < h_ref/2, q unchanged otherwise (so an inactive floor returns the unfloored sum bit for bit). h_ref is the larger thickness of the pair’s u- and v-face.

Read more…
hotface_row rdb_ocean_chksum Subroutine

One HOTFACE row (see chksum_hotface docstring for columns).

hvisc_add_aniso_coef rdb_ocean_horizontal_viscosity Subroutine

Add the Smith & McWilliams (2003) anisotropic direction-tensor coefficients onto the co-located isotropic viscosities. The tension (T-cell) coefficient gains kh_aniso·(1−n1n2²) and the shear (Bu-corner) coefficient gains kh_aniso·n1n2². For the default grid-i direction n1n2 = 0 ⇒ T gains kh_aniso, the corner gains nothing — stronger damping of along-i tension. The corner outer ring stays untouched (the divergence stencil never reads it; hvisc_avg_A_face already zeroed it).

hvisc_apply_impl rdb_ocean_horizontal_viscosity Subroutine
hvisc_avg_A_face rdb_ocean_horizontal_viscosity Subroutine

Average the per-face harmonic viscosity (ah_face_x at u-faces, ah_face_y at v-faces) onto the T-cell centres (ah_t) and the Bu corners (ah_q). The stress form needs A co-located with the tension (T-cell) and shear (corner) strains; the lateral-mix closure produces A at faces, so this is a 4-point face→cell / face→corner reduction. On a uniform A field every average returns A, preserving the Laplacian reduction.

hvisc_biharm_lap_closed rdb_ocean_horizontal_viscosity Subroutine

Pass 1 of BOTH velocity biharmonics (scalar nu_4 and the flow-aware nu4_face_*) under &vcoord_nml zfixed_closed_faces: the intermediate Laplacian lap_u/lap_v with a closed face-layer treated as a FREE-SLIP wall.

Read more…
hvisc_clamp_A rdb_ocean_horizontal_viscosity Subroutine

Per-cell CFL viscosity limiter (MOM6 BOUND_KH). Clamps the T-cell viscosity to Kh_Max_xx and the corner viscosity to Kh_Max_xy, each derived from the actual discrete stress stencil metrics + dt so the explicit forward-Euler viscous update can never overshoot. Replaces the global ah_max cap. On a uniform square grid Kh_Max = bound_coef·0.25/(dt·(1/dx²+ 1/dy²)).

hvisc_compute_biharmonic_face_impl rdb_ocean_horizontal_viscosity Subroutine

Flow-aware biharmonic friction (MOM6 SMAGORINSKY_AH analogue). Identical to hvisc_compute_biharmonic_impl except Pass 2 multiplies the second Laplacian by the per-face viscosity nu4_face_x/y instead of the scalar nu_4. The face fields are filled upstream by ocean_lateral_mix_compute_smag_ah, which sets them to C_b · L⁴ · |D| clamped to [nu4_bg, nu4_max]. Pass 2 additionally clamps each face coefficient to the per-face explicit-biharmonic CFL ceiling (hvisc_nu4_cfl_bound, scaled by bound_coef) on top of the static nu4_max floor/ceiling applied upstream — so a strain spike on a fine cell can never violate the local CFL bound.

hvisc_compute_biharmonic_impl rdb_ocean_horizontal_viscosity Subroutine

Constant-coefficient biharmonic friction: applies -ν₄ · ∇²(∇²u) to the face velocities via two chained 5-point Laplacians. Adds into the existing du_visc / dv_visc buffers (which Laplacian friction has already filled), so the caller can run with both nu_h and nu_4 non-zero.

Read more…
hvisc_compute_face_impl rdb_ocean_horizontal_viscosity Subroutine

Per-face metric Laplacian × spatially-varying viscosity. Explicit-shape dummies so NVHPC stdpar emits a device kernel without per-launch descriptor walks. See metric_lap_u/metric_lap_v for the curvilinear FV form. bound_kh engages the per-face harmonic CFL ceiling (hvisc_kh_cfl_bound); .false. ⇒ bit-identical.

hvisc_compute_scalar_impl rdb_ocean_horizontal_viscosity Subroutine

Per-face metric Laplacian × scalar viscosity. Used when no lateral-mix closure is active — falls back to constant nu_h. When nu_h = 0 the kernel still zeros all interior + boundary cells so the apply step sees a defined state. bound_kh engages the per-face harmonic CFL ceiling (hvisc_kh_cfl_bound); .false. ⇒ bit-identical.

hvisc_compute_stress rdb_ocean_horizontal_viscosity Subroutine

MOM6 thickness-weighted stress-divergence operator. Three phases: (1) tension str_xx at T-cells, (2) shear str_xy at Bu corners, (3) the divergence (1/(h_u+h_neglect))·∂str. wet_u/wet_v/wet_q mask the stress so no momentum is diffused across a coastline; h_neglect = H_VANISHED floors the velocity-point thickness. See module header for the form + the all-wet uniform-h Laplacian reduction.

Read more…
hvisc_fill_A_scalar rdb_ocean_horizontal_viscosity Subroutine

Fill the T-cell and corner harmonic-viscosity fields with the scalar nu_h (no flow-aware closure active). Constant ⇒ the T/corner averaging is exact, so the all-wet uniform-h reduction to the velocity Laplacian holds bit-for-bit.

hvisc_ke_diss_impl rdb_ocean_horizontal_viscosity Subroutine

C-grid KE budget: each face’s u·du_visc rate is split half to each adjacent T-cell and depth-integrated with ρ_k h_k. Race-free — every (i,j) writes only its own ke_diss(i,j).

hvisc_kh_cfl_bound rdb_ocean_horizontal_viscosity Function

Per-face harmonic-viscosity ceiling for the velocity-Laplacian paths (MOM6 Kh_Max_xx analogue, uniform-grid reduction): ν_max = bound_coef · 0.125 / (dt · (idx² + idy²)) — one quarter of the forward-Euler stability limit ν·dt·4·(idx²+idy²) ≤ 2, the same margin MOM6’s harmonic bound uses (“avoid overshoots when bound_coef < 1”). Keeps the FROZEN depth-mean viscous forcing on the barotropic mode (F_bt) out of the phase-reversed anti-damping regime for grid-scale gravity modes (see the bound_kh docstring). Returns huge (no clamp) for a fully-masked face. !$acc routine seq — called from the Laplacian do concurrent.

hvisc_nu4_cfl_bound rdb_ocean_horizontal_viscosity Function

Per-face explicit-biharmonic CFL ceiling on the biharmonic viscosity ν₄ (m⁴/s). Forward-Euler stability for −ν₄·∇⁴u on a local cell of spacing (dx, dy) requires (established project constant) ν₄ · dt · ((π/dx)² + (π/dy)²)² ≤ 2, so the per-face bound is ν₄_max = bound_coef · 2 / (dt · ((π·idx)² + (π·idy)²)²) where idx = 1/dx, idy = 1/dy are the metric inverses at the face (idxCu/idyCu at u-faces, idxCv/idyCv at v-faces). bound_coef (MOM6 HORVISC_BOUND_COEF, default 0.8) is the CFL safety margin shared with the harmonic hvisc_clamp_A. Returns a huge value (no clamp) when the metric inverses are both zero (a fully-masked land face) so the caller’s min leaves the coefficient untouched there. !$acc routine seq — called from the biharmonic do concurrent.

hycom_top_dz rdb_ocean_setup Function

Surface-layer thickness of the hycom z* nominal floor (m), for the configure banner: the stretched profile’s top entry, else the uniform z_fixed_h_ref/nz, else 0 (the unconfigured sigma fallback of ocean_vcoord_rho_target_column).

ice_adjust_categories rdb_ice_itd Subroutine

Outer shim (outer-shim + flat-impl pattern). No-op when the ice slot is not live (is_init gate) or when ice%ncat == 1 (the legacy-mode bit-identity contract — see module docstring). No dt/eos needed: this is a pure area/mass reshuffle, no thermodynamics.

ice_adjust_categories_impl rdb_ice_itd Subroutine

Device kernel: ONE do concurrent(j, i) over PHYSICAL cells (ghosts excluded), wet_mask > 0.5 inner gate (never a masked DC header), serial cat loops inside — each cell touches only its own (i, j, :) slice, race-free. No per-cell gather into local category-sized arrays (avoids register pressure and any compile-time ncat cap, unlike the ICE_NK_MAX-capped PER-LAYER arrays elsewhere in the ice model) — scalar temporaries only, all declared in local(...).

Read more…
ice_atm_forcing_restoring rdb_ice_atm_forcing Subroutine

Outer shim: forward the four seam arrays + four scalars to the device kernel. No registry indirection here, but keep the shim+_impl split for the explicit-shape device-kernel discipline.

ice_atm_forcing_restoring_impl rdb_ice_atm_forcing Subroutine

Full-array fill (incl. ghosts). Explicit-shape + decl-order (dims first). Runs on device-resident seam arrays (mapped by ice%enter_data).

ice_bottom_freeze rdb_ice_mass Subroutine

Bottom-freezing branch of ice_resize_SIS2 (SIS2_ice_thm.F90:1164-1188; prototype sis2_resize.py:20-45). When bmelt < 0 (net upward heat deficit at the base), freeze ocean water onto the bottom ice layer: enth_freeze = min(enthalpy(nk), enth_ocean - min_denth_freeze), m_freeze = -bmelt/(enth_ocean - enth_freeze), mass-weighted mix of the bottom layer’s enthalpy + salinity, bmelt reset to 0.

ice_bottom_melt_peel rdb_ice_mass Subroutine

Bottom melt peel (SIS2_ice_thm.F90:1246-1271; prototype sis2_resize.py:83-111). Same peel as ice_top_melt_peel but from k=nk down to k=0. The prototype’s separate ablation return is dropped (it is h2o_ice_to_ocn restricted to this call; PR 3b can re-derive it if needed).

ice_cas_to_ist_impl rdb_ice_transport Subroutine

SIS2 cell_ave_state_to_ice_state (:540). Per cell, per category: pre-floor category 1, optional thin-ice rolling (roll_factor > 0), general floor, then re-derive part_size(c) = mca_ice(c)/m_ice(c) and m_snow(c) = m_ice(c)*(mca_snow(c)/mca_ice(c)) (per-ICE-area). part_size(0) = 1 - Sum_c part_size(c) — MAY be negative here; ice_compress_impl (Phase 4) is what restores >= 0.

Read more…
ice_cat_flux_x_impl rdb_ice_transport Subroutine

SIS2 zonal_mass_flux (SIS_continuity.F90:1064): PPM reconstruction of the category-SUMMED mass htot, ONE total face transport uhtot from the swept-volume parabola integral (volcfl_face, bit-for-bit the SIS2 face expression), then the PROPORTIONATE split uh(c) = uhtot*mca(donor,c)*I_htot(donor) (SIS_continuity.F90:1199-1205, Adcroft reciprocal — I_htot=0 when htot(donor)<=0). Stencil + edge STORAGE CONVENTION + swept-face orientation copied verbatim from continuity_zonal_flux (rdb_continuity.F90:871-948): hl_x_work(i) == h_face_left_x(i) is the value AT east face i from the LEFT cell i-1 (that cell’s OWN downwind edge); hr_x_work(i) == h_face_right_x(i) is from the RIGHT cell i (its OWN left edge). H3-style limited edges + CW84 + ppm_limit_pos (SIS2 runs PPM_limit_pos UNCONDITIONALLY on the PD scheme, so it is not optional here). CFL metric: SIS2’s shipped default vol_CFL=.false. uses CFL = |u|*dt*IdxT(donor) (SIS_continuity.F90:1165) — the T-cell inverse spacing, NOT the dy_cu*iareaT swept-area ratio (== SIS2’s vol_CFL=.true. variant). Identical on uniform Cartesian; correct on spherical / anisotropic.

ice_cat_flux_y_impl rdb_ice_transport Subroutine

Meridional twin of ice_cat_flux_x_impl. Same face-indexed edge STORAGE + swept orientation as continuity_meridional_flux (rdb_continuity.F90:1159-1202): hl_y_work(i,j) == north-face h_face_left_y (from the SOUTH cell j-1), hr_y_work(i,j) == h_face_right_y (from the NORTH cell j). CFL uses IdyT(donor) (SIS2 vol_CFL=.false. default).

ice_cell_concentration_impl rdb_ice_state Subroutine

Two-mode per-cell concentration/mass gather (module docstring convention), shared by rdb_ice_evp (ice_evp_step) and rdb_ice_ocean_coupler (ice_ocean_stress_flux) so neither module depends on the other.

Read more…
ice_column_step rdb_ice_column Subroutine

Per-(cell,category) orchestrator: gather (bottom-up -> top-down flip, TRAP #2), optics, conduction (ice_temp_sis2), resize (snow add, bottom-freeze, top/bottom melt peel, rebalance), scatter (flip back).

Read more…
ice_compress_cell_inline rdb_ice_transport Subroutine

KEEP IN SYNC with ice_transport_compress_cell (the HOST tested seam twin, directly below). Same excess/ratio/compaction algorithm; this twin exists only for a different argument shape — full device-present arrays + scalar (i,j) indices for the fused device path (fixed-size device locals), vs the twin’s small standalone per-cell arrays for the unit test. Any change to the compaction logic here MUST be mirrored there (the test only drives the twin).

Read more…
ice_compress_impl rdb_ice_transport Subroutine

Outer per-cell dispatch: ONE do concurrent(j,i) over physical cells (ghosts excluded), wet_mask > 0.5 inner gate, serial in category within the cell (same shape as ice_adjust_categories_impl). The per-cell algebra is the SAME algorithm ice_transport_compress_cell implements (public, directly unit-testable on small standalone arrays — SPEC §7 test 3’s single-cell hand-check) — but this production kernel does NOT call it with a derived slice: part_size(i,j,:) etc. are NON-CONTIGUOUS sections (the category axis is not the fastest dimension), which a device !$acc routine seq call cannot take safely (would force a compiler temporary — the array-of- derived-type/strided-slice indirection trap, CLAUDE.md memory). Instead the algorithm is INLINED here operating on (i,j,c) triples directly, mirroring ice_adjust_categories_impl’s established pattern. ok is a per-cell-then-reduced flag (D7: SIS2 FATALs on the top-category overflow inconsistency; ported as a !$acc parallel loop reduction instead, since do concurrent cannot itself carry a boolean/min reduction in the house style — CLAUDE.md “Reductions use !$acc parallel loop reduction(...)”).

ice_compute_basal_flux rdb_ice_basal_flux Subroutine

Outer shim (outer-shim + flat-impl pattern): dereference the tracer registry (ms%tracers(idx)%hTr) on the HOST and forward bare arrays to the device kernel — same rule as ice_frazil_accumulate / ice_frazil_uptake. No-op when either S or T is unregistered.

ice_compute_basal_flux_impl rdb_ice_basal_flux Subroutine

Device kernel over PHYSICAL cells (ghosts excluded — same physical-cells-only contract as ice_frazil_accumulate_impl). fb/sst_seam/ssurf_seam/tfw_seam are zeroed unconditionally first. The SAMPLE seam (sst_seam/ssurf_seam/tfw_seam) is filled on every wet, non-vanished cell (harmless — the column reads it only where it has ice). But fb is filled ONLY where BOTH the cell is wet+non-vanished AND it carries ice (sum_cat m_ice > ICE_RHO_ICE*H_VANISHED, exactly ice_thermo_columns’ own per-cat ice threshold, summed): no ice base ⇒ no basal flux. This keeps the coupler and the column in lockstep on which cells exchange, so an ice-free warm ocean cell (SST > T_f, the normal open-ocean state) reports fb = 0 and the melt-side reduce kernel’s -fb term is a harmless subtraction of zero (rather than a spurious ocean-cooling Q_heat = -fb).

Read more…
ice_enth_from_ts rdb_ice_enthalpy Function

Ice specific enthalpy (J/kg) from temperature + bulk salinity — SIS2 enth_from_TS (SIS2_ice_thm.F90:1647). NOTE: here (and only here) the freezing point uses max(0, s), per SIS2. The SIS2 else branch at :1667-1671 (Cp_brine /= Cp_ice, the T_fr*log(T_fr/T) form) is deliberately NOT ported — with ICE_CP_BRINE == ICE_CP_ICE it is unreachable, and dropping it keeps the map closed-form-invertible (see module docstring).

ice_enthalpy_liquid rdb_ice_enthalpy Function

Enthalpy (J/kg) of liquid water at temperature t — SIS2 enthalpy_liquid (SIS2_ice_thm.F90:1691). s is unused in this linear form; the argument is kept for SIS2 call-site parity (enthalpy_liquid(T, S, ITV)).

ice_enthalpy_liquid_freeze rdb_ice_enthalpy Function

Enthalpy (J/kg) of liquid water at the freezing point for salinity s — SIS2 enthalpy_liquid_freeze (SIS2_ice_thm.F90:1679).

ice_evp_dynamics rdb_ice_evp Subroutine

One outer (slow) EVP call: evp_sub_steps subcycles advancing ui/vi/str_d/str_t/str_s, plus the subcycle-averaged ice->ocean stress fxoc/fyoc.

Read more…
ice_evp_dynamics_impl rdb_ice_evp Subroutine

Flat-impl core of ice_evp_dynamics: the EVP subcycle body with the persistent scratch passed as EXPLICIT-SHAPE dummies (memory: never assumed-shape into a do concurrent feeder — NVHPC would emit descriptor-walk memcpys per launch). The *_w scratch names mirror the retired module workspace 1:1, so the body below is unchanged from the pre-slot version.

Read more…
ice_evp_mi_ratio_point rdb_ice_evp Function

mi_ratio_A_q at a single corner (SIS2 :926-964), FULL form — all four branches (interior / corner-coast / straight-coast / land). weak_coast_stress=.false. hardwired (SIS2 default): sum_area is the MASKED area sum of the 4 surrounding T-cells. Factored out of the fill kernel so a unit test can pin it directly (SPEC §7 gate 8).

ice_evp_params_from_config rdb_ice_evp Function

Small constructor — build once from &ocean_ice_nml config. 11 args (> the style guide’s 6): pre-existing deviation, sanctioned by the derived-type-grouping escape hatch (FORTRAN_STYLE.md §Public procedure arguments) — the whole point of ice_evp_params_t is to be this constructor’s one-shot host. Positional (not optional): a knob threaded to the config/schema but not to this constructor reads from the namelist, validates, and does nothing — the dead-knob class the audit indicts. The compiler catches the omission; optional would not.

ice_evp_step rdb_ice_evp Subroutine

Gathers mis/mice/ci from the category state (mode-branched, mirrors PR 4b’s IST->CAS dispatch), pulls the one-step-lagged ocean surface velocity, and calls ice_evp_dynamics on ice%u_ice/v_ice/str_d/str_t/str_s/fxoc/fyoc. No-op when the ice slot is not live or dynamics is off (defence-in-depth; the driver already gates this call on ice%dynamics).

Read more…
ice_fb_part_sum_fill_impl rdb_ice_thermo_driver Subroutine

Fill fb_part_sum(i,j) = Σ_c part_size(i,j,c) restricted to categories passing the column’s OWN entry gate (m_ice(i,j,c) > ICE_RHO_ICE*H_VANISHED) — MUST run BEFORE ice_thermo_columns mutates m_ice (module docstring). Device kernel over PHYSICAL cells, inner if/serial do cat — never a masked do concurrent header.

Read more…
ice_frazil_accumulate rdb_ice_frazil Subroutine

Outer shim (outer-shim + flat-impl pattern): dereference the tracer registry (ms%tracers(idx)%hTr) on the HOST and forward bare arrays to the device kernel — NVHPC stdpar cannot follow the array-of-derived-types indirection inside a do-concurrent body. No-op when either S or T is unregistered.

ice_frazil_accumulate_impl rdb_ice_frazil Subroutine

Device kernel over PHYSICAL surface cells (ghosts excluded — wall ghosts are inert and seam ghosts are rebuilt by the wrap / exchange, so clamping them would double-count the bank in any area integral). Per wet cell at k = nz:

Read more…
ice_frazil_uptake rdb_ice_frazil_uptake Subroutine

Outer shim (outer-shim + flat-impl pattern): dereference the tracer registry (ms%tracers(idx)%hTr) on the HOST and forward bare arrays to the device kernel — NVHPC stdpar cannot follow the array-of-derived-types indirection inside a do-concurrent body (same rule as ice_frazil_accumulate). No-op when either S or T is unregistered.

Read more…
ice_frazil_uptake_column rdb_ice_frazil_uptake Subroutine

Per-(cell,category-1) column worker: gather + flip (bottom-up -> top-down, TRAP #2 discipline), spend the whole frazil bank evenly over the nk layers (SIS2:1402), rebalance, scatter + flip back. Port of add_frazil_SIS2 (SIS2_ice_thm.F90:1342-1444), bulk-salinity mode (salin_freeze = ICE_BULK_SALINITY, SIS_slow_thermo.F90: 1207-1209) — the ice_rel_salin mode is NOT ported.

Read more…
ice_frazil_uptake_impl rdb_ice_frazil_uptake Subroutine

Device kernel over PHYSICAL cells (ghosts excluded — same physical-cells-only contract as ice_frazil_accumulate_impl and ice_thermo_columns). Per wet, non-vanished, banked cell: sample SST/SSS at k = nz, compute the seawater freezing point, spend the WHOLE bank on category-1’s column via ice_frazil_uptake_column, and reset frazil_heat to 0 (fully spent). The per-cell diags (m_frozen_diag, salt_flux_diag) are zeroed UNCONDITIONALLY first, then overwritten under the gate — an unbanked/dry/land/vanished cell reports zero, not a stale value from a prior window.

Read more…
ice_frazil_uptake_multicat_impl rdb_ice_frazil_uptake Subroutine

ncat>1 SIS2 ITD-mode frazil spend. Port of SIS2 SIS_slow_thermo.F90:1121-1146 + 1181-1186 (non-filling mode — SIS2’s default SIS2_FILLING_FRAZIL=.true. thin-category fill is DEFERRED, see module docstring). Per banked cell (same wet/non-vanished/bank>0 gate as ice_frazil_uptake_impl): 1. k_merge scan (SIS2:1124-1129): first category c with part(0) + part(c) > 0.01; falls back to k_merge = 1 if no category qualifies (SIS2’s k_merge default). 2. Open-water annexation (SIS2:1131-1145): if part(0) > 0, dilute category k_merge’s thickness at CONSTANT MASS — m_ice(k_merge)/m_snow(k_merge) scale by part(k_merge)/(part(k_merge)+part(0)), part(k_merge) absorbs all of part(0), part(0) -> 0. enth/sal are per-MASS intensive — untouched by an area-only dilution. 3. Per-ice-area spend (SIS2:1181-1186): frazil_col = frazil_heat/part(k_merge) (J per m² of category area; the denominator is > 0 by construction — either an occupied category was found, or step 2 just grew part(k_merge) from the Σpart=1 invariant), then the SAME UNCHANGED ice_frazil_uptake_column spends it on category k_merge’s column. 4. Diags (per cell, part-weighted back to CELL-area units to match the ncat==1 diag convention that the couplers and rdb_ice_thermo_driver consume): m_frozen_diag = part(k_merge)*m_frozen_pt; salt_flux_diag = part(k_merge)*(m_frozen_pt*s_surf - salt_to_ice_pt)/dt_therm; frazil_heat reset to 0 (fully spent). Both diags are zeroed UNCONDITIONALLY at loop top, same contract as ice_frazil_uptake_impl.

Read more…
ice_gather_flux_x_impl rdb_ice_transport Subroutine

Gather pass (race-free): tr_flux_x_work(I,c) = val(donor of I,c), donor by the sign of the FLUX. uh is exactly 0.0 at the array-edge faces I=1 and I=nx+1 (the flux kernel zeros them unconditionally), so the I=1 donor-by-sign branch (uh>=0) would read the out-of-bounds val(0,j,c) — guarded explicitly below (I==1/I==nx+1 fall back to the IN-BOUNDS neighbour; the value is never actually consumed by the update kernel there since uh==0 at both those faces makes them inert, but the gather must still avoid the invalid index). Reads val ONLY at a donor cell — never writes val — so this kernel has no race with any other iteration.

ice_gather_flux_x_layer_impl rdb_ice_transport Subroutine

Layer-indexed twin of ice_gather_flux_x_impl for enth_ice/sal_ice/enth_snow (shape (nx,ny,ncat,nk)).

ice_gather_flux_y_impl rdb_ice_transport Subroutine

Meridional twin of ice_gather_flux_x_impl.

ice_gather_flux_y_layer_impl rdb_ice_transport Subroutine

Meridional twin of ice_gather_flux_x_layer_impl.

ice_halo_centre_flat rdb_ocean_halo_state Subroutine

Explicit-shape seam: a contiguous ice array of any rank (0:ncat third bound, rank-4 category x layer) is handed in by sequence association and exchanged as one (nxt, nyt, nz) centre field. The generic ocean_halo_centre resolves on the DUMMY’s rank, so the rank-4 actuals cannot call it directly.

ice_hlim_count rdb_config Function

Length of the LEADING run of non-sentinel (>= 0) entries in &ocean_ice_nml hlim (PR-58). Contiguity matters here (unlike apply_layer_rho_init’s bare count(>= 0)): a value AFTER the first sentinel is silently dropped by this count, so ice_hlim_spec_is_valid checks contiguity explicitly rather than trusting the count alone.

ice_hlim_spec_is_valid rdb_config Subroutine

Shape/monotonicity predicate for a supplied &ocean_ice_nml hlim list (PR-58). A SUBROUTINE, not a function — a pure FUNCTION may not carry an intent(out) dummy (reason); pure SUBROUTINES can. n = ice_hlim_count(hlim); ok iff ALL of: (a) n >= 2 – one edge gives no width to extrapolate (SIS2 divergence D1: Roundabout fails loud here instead of SIS2’s silent fallback to the default table). (b) n <= ncat + 1 – more edges than the ITD has bins. (c) all(hlim(n+1:) < 0) – contiguity: no value after the first sentinel. (d) hlim(1) > 0 – mh_lim(1) > 0 is a live gate (rdb_ice_itd ice_adjust_categories). (e) hlim(k+1) > hlim(k), k = 1..n-1 – strictly increasing. Checking (d)+(e) on the SUPPLIED list is sufficient for the FULL h_lim(1..ncat+1): the constant-width extrapolation preserves both properties by induction (h_lim(k)-h_lim(k-1) = h_lim(k-1)-h_lim(k-2)), so no redundant post-extrapolation check is needed.

ice_ic_params_from_config rdb_ice_init Function

Small constructor — build once from &ocean_ice_ic_nml. Copies ice_evp_params_from_config’s shape; the one difference is conc_config, a STRING here (parsed internally), because the namelist knob is a nml_enum string, not an already-parsed integer.

ice_ic_parse_conc_config rdb_ice_init Function

"zero"/"uniform"/"latitudes" -> ICE_IC_CONC_*; any other string -> ICE_IC_CONC_INVALID (fail-loud idiom: a pure function cannot abort, so validate_config V8 turns the sentinel into a logger%error; nml_enum allowed= is the first line of defence).

ice_ic_target_category rdb_ice_init Function

The IC’s target category for a pack of mass m [kg/m^2] (per-ICE-area, ncat>1 convention): the top bin ncat is UNBOUNDED above (mh_lim(ncat+1) is stored but never used as a cap — ice_adjust_categories’s upward pass stops at c = ncat-1), otherwise the unique c with mh_lim(c) <= m < mh_lim(c+1). Declared ncat before the explicit-shape mh_lim that uses it (decl-order).

ice_init_apply rdb_ice_init Subroutine

Outer shim (outer-shim + flat-impl pattern, mirrors ice_adjust_categories). No-op when the ice slot is not live (is_init gate) or when par%conc_config == ICE_IC_CONC_ZERO (the default-off bit-identity contract — nothing is written, not even sal_ice/enth_ice). ice is intent(inout) (not out): h_lim/mh_lim were filled at init and must survive.

ice_init_apply_impl rdb_ice_init Subroutine

Per-cell seeder. Decl-order: integer dims before the explicit-shape arrays that use them.

ice_ist_to_cas_impl rdb_ice_transport Subroutine

SIS2 ice_state_to_cell_ave_state (:465): mca(c) = part_size(c)*m(c) per category, physical cells only. Ghost cells are zeroed (never read as donors in the flux kernels below — wet mirroring + wall zeroing exclude them).

ice_itd_category_bounds rdb_ice_state Subroutine

SIS2 initialize_ice_categories (SIS_state_initialization.F90:45-78): absent hlim_vals fills the first min(ncat+1, 8) entries from the default lower-thickness-limit table HLIM_DFLT_TABLE; a supplied hlim_vals fills the first min(ncat+1, size(hlim_vals)) entries from IT instead (PR-58 — the SIS2 hLim_vals optional dummy Roundabout’s port originally declined to carry). Either way, the remainder extrapolates by constant width, h_lim(k) = 2*h_lim(k-1) - h_lim(k-2), resuming at ONE PAST however many entries were actually supplied — not at a fixed index 9. mh_lim = ICE_RHO_ICE*h_lim (SIS2 mH_cat_bound, SIS_state_initialization.F90:75-77). h_lim(c)/mh_lim(c) is the LOWER bound of category c (1-based); index ncat+1 is the lower bound that WOULD start category ncat+1 — stored (SIS2 keeps it) but never used as an upper cap on category ncat (ice_adjust_categories’s upward pass stops at c = ncat-1). No fixed-size local arrays — ncat is unbounded here (unlike the per-column ICE_NK_MAX-capped layer arrays).

Read more…
ice_limit_stresses rdb_ice_evp Subroutine

SIS2 limit_stresses (:1619-1684), lim=1 (no optional arg). Called ONCE per ice_evp_dynamics call, BEFORE the substep loop — requirement (2). Corner clamp uses the MASKED-area-weighted mean pressure of the <=4 wet neighbours — requirement (3).

ice_mask_snow_by_ice_impl rdb_ice_transport Subroutine

SIS2 masking_uh=uh_ice (SIS_continuity.F90:1210-1215): uh_snow(I,c) = 0 wherever uh_ice(I,c) == 0. Face-shaped array, works identically for the x-face (nx+1,ny,ncat) and y-face (nx,ny+1,ncat) layouts (caller passes the right extents). frac_neglect (SIS2’s second masking clause) is dead at SIS2’s own default frac_neglect=0 — not ported (D-noted in the module docstring).

ice_mass_update_x_impl rdb_ice_transport Subroutine

SIS2 :183-191: mca(c) -= dt_adv*iareaT*(uh(I)-uh(I-1)), physical cells only. No race (reads faces, writes cells).

ice_mass_update_y_impl rdb_ice_transport Subroutine

Meridional twin of ice_mass_update_x_impl.

ice_max_speed_impl rdb_ice_transport Subroutine

Max |u_ice|/|v_ice| over PHYSICAL faces only (the array-edge ghost faces carry no meaning here). !$acc parallel loop reduction (inert comment on non-OpenACC compilers) — GPU-safe max reduction for the zero-velocity exact no-op gate.

ice_ocean_brine_flux rdb_ice_ocean_coupler Subroutine

Refresh the ocean surface salt-flux field from the ice slot. Components off (default): Q_salt(i,j) = Q_salt_const + salt_flux_diag(i,j) POSITIVE SALINIFIES (TRAP #2 above — matches apply_surface_src_2d_impl’s hTr_S += dt/rho0*Q_salt). This is a FULL OVERWRITE from the configure-time constant plus the last uptake’s rate: no accumulation drift, and a thermo window with no freezing resets the field back to the background (salt_flux_diag == 0 when the bank was empty or the cell was dry/land/vanished — see ice_frazil_uptake_impl’s unconditional diag zeroing). Components on (sf%use_components, PR-12): write the ice’s own COMPONENT instead — sf%salt_flux(i,j) = salt_flux_diag(i,j) (no Q_salt_const term: ocean_surface_flux_assemble adds it). Sets has_salt either way (§13 item 6 of the PR-12 plan: any filler that can produce non-zero net salt must set the latch).

ice_ocean_brine_flux_components_impl rdb_ice_ocean_coupler Subroutine

Components-on branch: full-array overwrite of the salt_flux COMPONENT (not Q_salt) — same sign convention, no _const term (the assembler adds it). Explicit-shape + decl-order.

ice_ocean_brine_flux_impl rdb_ice_ocean_coupler Subroutine

Full-array overwrite (including ghosts — they get Q_salt_const + 0, the same value the configure-time seed already gave them, so this is a no-op there). Explicit-shape dummies + decl-order (integer dims before the arrays that use them) so NVHPC stdpar compiles a device kernel against static bounds. Runs on the device-resident Q_salt (mapped by sf%enter_data) and salt_flux_diag (mapped by ice%enter_data).

ice_ocean_heat_flux rdb_ice_ocean_coupler Subroutine

Refresh the ocean surface heat-flux field from the ice slot. Components off (default): Q_heat(i,j) = Q_heat_const + heat_flux_diag(i,j) POSITIVE DOWN into the ocean (the apply-tracers convention: d(hT) = Q_heatdt/(rho0cp)). Full overwrite from the const + last window’s rate — a window with no ice exchange resets to background. Components on (sf%use_components, PR-12): write sf%heat_added(i,j) = heat_flux_diag(i,j) instead — MOM6’s slot for a net, already-summed heat term (no _const term: the assembler adds it). Sets has_heat either way.

ice_ocean_heat_flux_components_impl rdb_ice_ocean_coupler Subroutine

Components-on branch: full-array overwrite of the heat_added COMPONENT (not Q_heat) — no _const term (the assembler adds it). Explicit-shape + decl-order.

ice_ocean_heat_flux_impl rdb_ice_ocean_coupler Subroutine

Full-array overwrite (including ghosts — same no-op-there reasoning as ice_ocean_brine_flux_impl). Explicit-shape dummies + decl-order. Runs on the device-resident Q_heat (mapped by sf%enter_data) and heat_flux_diag (mapped by ice%enter_data).

ice_ocean_stress_cleanup rdb_ice_ocean_coupler Subroutine

Release the persistent tau-blend scratch. Idempotent (safe on an already-clean workspace — the driver calls it unconditionally at ocean teardown, next to ice_evp_cleanup).

ice_ocean_stress_flux rdb_ice_ocean_coupler Subroutine

Ice->ocean momentum-mediation blend (PR 5), the momentum mirror of ice_ocean_brine_flux: FULL overwrite each outer step from the pristine wind snapshot + the lagged EVP drag, weighted by ice concentration at each face. a_u(i,j) = 0.5(ci(i-1,j) + ci(i,j)) tau_x(i,j) = (1-a_u)tau_a_x(i,j) + a_u*fxoc(i,j) ditto y (a_v(i,j) = 0.5*(ci(i,j-1)+ci(i,j))). ci is re-gathered via ice_cell_concentration_impl (shared with rdb_ice_evp, so this module never depends on the EVP kernel).

Read more…
ice_ocean_stress_flux_impl rdb_ice_ocean_coupler Subroutine

Face-blend kernel. a_u/a_v interpolate ci onto the u/v faces (Adcroft-style simple average — no mask needed since ci is already 0 on land). Explicit-shape + decl-order.

Read more…
ice_ocean_stress_resume_apply rdb_ice_ocean_coupler Subroutine

Configure-time resume apply (PR 63). tau_x/tau_y were just re-seeded from the wind-stress config by configure_ocean_forcing; if the checkpoint carried a blend (tau_ocn_valid > 0.5), overwrite them with it — the EXACT stress the uninterrupted run would have handed the ocean at this step boundary. Otherwise leave the pristine wind (D8: a fresh run’s first outer step drives the ocean with pure wind — and, for the first time, this is now literally true: no (1-a)*tau_a residual from an uninitialised fxoc).

Read more…
ice_ocean_sw_flux rdb_ice_ocean_coupler Subroutine

Refresh the ocean-surface shortwave from the ice slot’s sw_thru_diag (PR 31) — the shortwave that penetrated the ice to the water below (W/m^2, >= 0, POSITIVE DOWN into the ocean).

Read more…
ice_ocean_sw_flux_add_impl rdb_ice_ocean_coupler Subroutine

Components-off branch: ADD the ice-transmitted shortwave into the net Q_heat (including ghosts — they get +0, since the ice column gates sw_thru = 0 off-ice and sw_thru_diag is correspondingly 0 there). This is an ADD, not an overwrite, and is well-defined precisely because ice_ocean_heat_flux ran first this window and full-overwrote Q_heat — so Q_heat holds Q_heat_const + heat_flux_diag (SW-free) when this kernel lands on it, and the net is recomputed fresh every window. Explicit- shape + decl-order. Both arrays device-resident.

ice_ocean_sw_flux_components_impl rdb_ice_ocean_coupler Subroutine

Components-on branch: full-array overwrite of the q_sw COMPONENT (including ghosts — they get 0). No _const term. Explicit-shape + decl-order. Runs on the device-resident q_sw (mapped by sf%enter_data) and sw_thru_diag (mapped by ice%enter_data).

ice_optics_csim4 rdb_ice_optics Subroutine

CSIM4 albedo + Beer’s-law vertical SW partition (SIS_optics.F90:371-409). Exact port; inline literals 0.1235/0.075 (melt-albedo reductions) and 5.0/0.5 (thin-ice atan ramp) and 0.06 (thin-ice albedo floor) stay inline per SIS2 (SIS_optics.F90:378-384).

Read more…
ice_pass_x rdb_ice_transport Subroutine

One zonal pass: total-mass PPM + proportionate ice-flux split, the snow twin + co-located mask, PCM tracer riding (gather then cell update), the mass update (AFTER every ride reads the pre-update mass), and the post-pass validity reduction.

ice_pass_y rdb_ice_transport Subroutine

Meridional twin of ice_pass_x. Reads the POST-x-pass masses (SIS2 SIS_continuity.F90:170-216).

ice_rebalance_layers rdb_ice_mass Subroutine

Equal-mass repartition of ice layers 1..nk, mass-weighting enthalpy and salinity (SIS2_ice_thm.F90:1448-1512; prototype sis2_resize.py:114-161). The snow slot (m_lay(0), enthalpy(0)) is untouched. mtot_ice = sum(m_lay(1:nk)) is returned; mtot_ice == 0 is an early exit leaving the ice layers untouched (there is no ice to rebalance). The k1/k2 two-pointer drain loop follows the SIS2/prototype branch order exactly, including the (m_ice_avg - mlay_new(k2) > src_m(k1)) .or. (k2 == nk) test.

ice_ride_update_x_impl rdb_ice_transport Subroutine

Cell-update pass (race-free): reads tr_flux_x_work (the GATHERED donor VALUE at each face, from ice_gather_flux_x_impl) + its OWN cell’s mca/val (never a neighbour’s val), applies SIS2’s advect_scalar_x flux-form update + the H_NEGLECT conditioning guard (SIS_tracer_advect.F90:735-760), writes val(i,j,c). hnew is the SAME expression the mass-update kernel (d) uses, so the implied masses agree bitwise. Bitwise no-op when both faces carry zero flux (F_W==F_E==0).

Read more…
ice_ride_update_x_layer_impl rdb_ice_transport Subroutine

Layer-indexed twin of ice_ride_update_x_impl for enth_ice/sal_ice/enth_snow (shape (nx,ny,ncat,nk)). Same algebra, applied to val4(:,:,:,layer).

ice_ride_update_y_impl rdb_ice_transport Subroutine

Meridional twin of ice_ride_update_x_impl.

ice_ride_update_y_layer_impl rdb_ice_transport Subroutine

Layer-indexed twin of ice_ride_update_y_impl for enth_ice/sal_ice/enth_snow (shape (nx,ny,ncat,nk)).

ice_sample_velocity_impl rdb_ice_transport Subroutine

u_ice(i,j) = u_surf(i,j)*wet_u(i,j), ditto v. v1 interim filler (SPEC §5 Phase 0) — PR 5 EVP replaces this call with a dynamics solve writing the SAME u_ice/v_ice faces.

ice_snow_accumulate rdb_ice_mass Subroutine

Snow source-term branch of ice_resize_SIS2 (SIS2_ice_thm.F90:1122): m_lay(0) = m_lay(0) + snow. The snow layer’s specific enthalpy enthalpy(0) is UNCHANGED by snowfall – SIS2 is explicit that this “should do nothing” (SIS_slow_thermo.F90:1032-1033) and books the implied energy against the atmosphere (enth_snowfall = snow*enthalpy(0) -> Enth_Mass_in_atm). Roundabout’s atmosphere is a prescribed slab with no energy budget to charge, so that bookkeeping is not ported – a documented v1 divergence (PLAN_PR26_snowfall.md, S3).

Read more…
ice_snow_ice_flood rdb_ice_mass Subroutine

Archimedes freeboard snow-ice flooding — the FINAL substantive block of ice_resize_SIS2 (SIS2_ice_thm.F90:1303-1320; PR 27). Standard closure: Leppäranta (1983), A growth model for black ice, snow ice and snow thickness in subarctic basins, Nordic Hydrology 14, 59-70; Fichefet & Morales Maqueda (1997), JGR 102, 12609-12646 §2.3.

Read more…
ice_snow_part_ocn_fill_impl rdb_ice_thermo_driver Subroutine

PR 26: fill snow_part_ocn(i,j) — the ice-FREE share of the cell that a uniform snowfall lands on with no ice underneath — under the SAME PRE-column-snapshot contract as ice_fb_part_sum_fill_ impl (module docstring, this module docstring’s PR-26 paragraph): MUST run BEFORE ice_thermo_columns mutates m_ice, using the column’s OWN entry gate (m_ice(i,j,c) > ICE_RHO_ICE*H_VANISHED).

Read more…
ice_snowfall_ocean_share rdb_ice_snow Subroutine

Outer shim (outer-shim + flat-impl pattern): forward the ice slot’s arrays to the device kernel. Called only when ice%has_snowfall (driver gate, rdb_driver.F90) – default snowfall=0 never reaches this module.

ice_snowfall_ocean_share_impl rdb_ice_snow Subroutine

Device kernel over PHYSICAL cells (ghosts excluded). Gated on snow_part_ocn(i,j) > 0 rather than a separate wet_mask arg: ice_snow_part_ocn_fill_impl (rdb_ice_thermo_driver) already zeroes snow_part_ocn on land/dry/fully-ice-covered cells, so that field IS the wet-and-ice-free gate this kernel needs – functionally identical to (and cheaper than) re-deriving a wet_mask > 0.5 test here, and keeps this module’s signature to the (grid, ice, dt_therm) seam (no ms dependency).

Read more…
ice_t_freeze rdb_ice_enthalpy Function

Freezing temperature (degC) of the ice brine at bulk salinity s — SIS2 T_Freeze (SIS2_ice_thm.F90:1622), linear liquidus. RAW s (no max(0,s) clamp) — faithful to SIS2, which clamps only in enth_from_TS. Do not unify with ice_enth_from_ts’s internal t_fr.

ice_tau_mirror_impl rdb_ice_ocean_coupler Subroutine

PR 63. Device copy of the blend’s OUTPUT into the restart-carried mirror fields — deliberately NOT fused into ice_ocean_stress_flux_impl (that kernel stays untouched so the tau_coupling bitwise gate is unaffected by this PR). Explicit-shape + decl-order (integer dims before the arrays that use them).

ice_temp_from_en_s rdb_ice_enthalpy Function

Ice temperature (degC) from specific enthalpy + bulk salinity — SIS2 Temp_from_En_S (SIS2_ice_thm.F90:1830), Cp_ice == Cp_brine path only: the quadratic ICE_CP_ICET2 - 2BBT + ICE_LAT_FUSt_fr = 0 solved for its smaller root. The SIS2 Newton/false-position refinement (:1876-1933) is only needed when Cp_brine /= Cp_ice and is deliberately NOT ported. Uses RAW s for t_fr (no max), faithful to SIS2.

ice_temp_sis2 rdb_ice_column Subroutine

SEB + vertical-conduction column solve — SIS2 ice_temp_SIS2 (SIS2_ice_thm.F90:169-540). Port of prototype sis2_column.py:151-412. TOP-DOWN column (index 0 = snow, 1..nk = ice top->bottom) — see module docstring TRAP #2.

Read more…
ice_thermo_columns rdb_ice_column Subroutine

do concurrent cell driver: PHYSICAL cells only, inner if gate (never a masked DC header), serial do cat loop inside. Per (i,j,cat): outputs zeroed unconditionally, then gated on wet_mask > 0.5 .and. m_ice > ICE_RHO_ICE*H_VANISHED (dynamic- vanish taxonomy: skip intact, never clamp/divide a vanished column). part_size is deliberately NOT an argument — thermo is per unit ice area.

ice_thermo_driver_reduce_impl rdb_ice_thermo_driver Subroutine

Device kernel over PHYSICAL cells (ghosts excluded). Reduces the per-category column outputs into the per-cell coupling diags. heat_flux_diag/sw_thru_diag/m_melt_diag are zeroed unconditionally at loop top (this module owns them outright); salt_flux_diag is NOT zeroed — ice_frazil_uptake (which runs first this window, see the module docstring) already zeroed + wrote it, and this kernel ADDS its net-melt contribution on top, gated on wet to avoid land noise (an unwetted cell adds exactly 0).

Read more…
ice_thermo_driver_reduce_multicat_impl rdb_ice_thermo_driver Subroutine

ncat>1 SIS2 ITD-mode reduce (module docstring). Same zero/gate/ ordering contract as ice_thermo_driver_reduce_impl — the only change is PART-WEIGHTING the per-category sums (the column’s h2o_*/heat_to_ocn/sw_thru outputs are per unit ICE-COVERED area in this mode, so a per-cell total needs the part_size weight) and subtracting fb_part_sum*fb instead of the bare fb the ncat==1 path subtracts (fb is a per-cell flux; fb_part_sum is the fraction of the cell it was actually charged against — see the module docstring and rdb_ice_state%fb_part_sum).

Read more…
ice_thermo_driver_step rdb_ice_thermo_driver Subroutine

Outer shim (outer-shim + flat-impl pattern): ms/eos are accepted for call-site parity with the other thermo-cadence kernels (ice_compute_basal_flux, ice_frazil_uptake) even though this step reads its ocean-surface sample from the ice%sst_seam/ssurf_seam/tfw_seam scratch (filled by ice_compute_basal_flux earlier in the same window) rather than re-deriving it from ms/eos directly — eos is unused here but kept in the signature so a future revision that DOES need a fresh EOS evaluation does not have to change every call site.

ice_top_melt_peel rdb_ice_mass Subroutine

Top melt peel (SIS2_ice_thm.F90:1217-1242; prototype sis2_resize.py:48-80). Peels mass from k=0 (snow) upward through k=nk until tmelt is spent; a massless layer is skipped; the partial layer takes m_melt = melt_left/(enth_fr - enthalpy); any leftover melt energy (all layers exhausted) drains to heat_to_ocn. Snow/pond-free path — tmelt is assumed already >= 0 on entry (the caller folds any negative top-melt into bmelt upstream, SIS2:1159-1163).

ice_transport_compress_cell rdb_ice_transport Subroutine

KEEP IN SYNC with ice_compress_cell_inline (the DEVICE production twin, directly above). Same excess/ratio/compaction algorithm; this HOST twin exists only as the directly unit-testable seam (small standalone per-cell arrays, no !$acc routine seq), while the device twin takes full device-present arrays + a scalar (i,j) index. Any change to the compaction logic here MUST be mirrored there (the fused device path is what production runs).

Read more…
ice_transport_step rdb_ice_transport Subroutine

Entry point (host orchestration; kernels inside). Outer-shim + flat-impl: every phase below dispatches to a pure _impl kernel; this routine only sequences them and owns the host-visible ok fail-loud signal.

ice_validity_reduce_impl rdb_ice_transport Subroutine

ok = .false. when min(mca_ice) < 0, min(mca_snow) < 0, or an “orphan snow” cell exists (mca_snow > 0 where mca_ice <= 0 by more than H_NEGLECT_ICE_TRANSPORT) — SIS2 FATALs on any of these; ported as a post-pass reduction (GPU-safe fail-loud, D7) rather than an in-loop abort. Physical cells only.

in_shelf_box rdb_ocean_cavity Function

.true. inside the shelf box. Each of the four bounds is applied only when it is FINITE in the CAVITY_BOUND_INF sense, so the namelist defaults (+/-1e30) describe an unbounded shelf and a user who only wants a calving front in x need not describe y at all.

int_default_string rdb_nml_schema Function
int_is_default rdb_nml_schema Function
int_parse rdb_nml_schema Subroutine
int_value_string rdb_nml_schema Function
interp_column_linear_z rdb_ocean_z_init Subroutine

Linear-in-depth interpolation of source profile v_src on ascending depths z_src onto target depths z_ctr, with CONSTANT extrapolation beyond the source range. Comparisons in depth space so index orientations never need reconciling.

invert_density_targets rdb_ocean_vcoord Subroutine

Density-space interface inversion — the single source of truth for the RHO vcoord regrid (ocean_vcoord_compute_target_h_rho_impl) AND the DENSITY diagnostic remap (rdb_ocean_diag_fills).

Read more…
is_canonical_diag_name rdb_ocean_diag_fills Function

.true. if name is one of the canonical default diagnostics registered by register_default_diags (including the conditionally-registered EPBL / kappa-shear / tracer / sea-ice diags). Used by the selection orchestrator to route a spec entry to either the canonical-override path or the derived-catalog registration path.

is_ident_char rdb_nml_schema Function

True for identifier characters (alnum + underscore).

is_open_ish rdb_ocean_obc_baroclinic Function

Returns .true. for edge types that need baroclinic velocity treatment.

is_radiating rdb_ocean_obc_baroclinic Function

Returns .true. for Flather-class edges (not CLAMPED).

is_repeat_count rdb_nml_schema Function

True if word looks like N*value (integer, then ‘*’).

isomip_logistic rdb_ocean_state Function

1/(1 + exp(t)), saturated instead of overflowing.

Read more…
isomip_plus_bx rdb_ocean_state Function

Along-flow bedrock elevation, Asay-Davis et al. (2016) Eq. (2):

Read more…
isomip_plus_by rdb_ocean_state Function

Across-flow bedrock elevation, Asay-Davis et al. (2016) Eq. (4):

Read more…
isopycnal_vanish_tol rdb_ocean_dyn Function

Shared vanish-tolerance for Phase-2/3 kernels: the layer is considered vanished when its thickness is at or below this value. Defined as max(angstrom_h, H_VANISHED) so both the physical floor (Phase 1) and the skip/merge marker are covered by a single threshold. Providing this as a pure helper ensures Phase 2 (reset_vanished_layer_velocities) and Phase 3 (apply_velocity_truncation gate + compute_max_cfl gate) cannot drift in their vanish definition.

Read more…
json_escape rdb_nml_schema Function

Minimal JSON string escaping: backslash, double-quote, and the common control characters. Doc/name/units strings in this codebase are plain single-line ASCII, so this is deliberately not a general-purpose escaper.

json_fmt_real rdb_nml_schema Function

Real -> JSON number, robust to extreme magnitude (e.g. huge(wp) floor/ceiling sentinels like kv_max’s default): fmt_real’s E18.10 is too narrow for a 3-digit exponent and gfortran drops the E literal to fit (“0.1797693135+309”), which is not valid JSON. ES.E3 explicitly requests a 3-digit exponent field, which forces the E to stay, at a width sized for the worst case. 16 fraction digits (17 significant figures) is real64’s round-trip guarantee – one digit short (as an earlier version of this function used) rounds huge(wp)’s text UP past the true maximum finite double, so re-parsing it (e.g. Python’s json.load) overflows to infinity, which is not valid JSON and breaks the generator (tools/gen_python_config.py) that reads this file.

json_real_array rdb_nml_schema Function

Render arr(:) as a comma-separated list of JSON numbers (no enclosing brackets).

json_string_array rdb_nml_schema Function

Render arr(:) as a comma-separated list of JSON-quoted strings (no enclosing brackets – the caller supplies those).

kappa_shear_column_kernel rdb_ocean_kappa_shear Subroutine

Per-column JHL08 solve. One do concurrent (j, i) over owned cells; every column is solved serially in surface-down order. Per-thread work is fixed-size local() arrays (L1 layout — all live in GPU registers, no shared memory); the column solve bodies are the same-module pure !$acc routine seq helpers below.

Read more…
kappa_shear_compute rdb_ocean_kappa_shear Subroutine

Run kappa-shear over the domain: fill this%kd_int (interface diffusivity). Call at thermo cadence with the thermo dt. Outer shim: dereferences the tracer-registry hTr arrays on the host (the array-of-DT indirection blocks NVHPC device codegen), then forwards to the column kernel. Velocities reach the kernel as the C-grid face arrays, face-averaged to tracer points inside (same source as the PP81 interior shear).

Read more…
kappa_shear_merge_into_kv_kt rdb_ocean_kappa_shear Subroutine

Fold the kappa-shear diffusivity into the vmix interface fields, ADDITIVELY (MOM6 interior-diffusivity semantics). Called EVERY stage (the interior closure rewrites kv/kt each stage; kd_int itself refreshes at thermo cadence). Interior interfaces only — K=1 (bed) and K=nz+1 (surface) stay zero in both source and target.

Read more…
kappa_shear_vertex_kernel rdb_ocean_kappa_shear Subroutine

Per-CORNER JHL08 solve (MOM6 vertex form, Pass B). One do concurrent (jc, ic) over the interior corners [2,nx]x[2,ny] — the set whose full 2x2 cell patch exists in-array, which covers every corner any owned tracer cell needs (nghost >= 1). Ring corners stay 0.

Read more…
kappa_shear_vertex_scatter rdb_ocean_kappa_shear Subroutine

Corner -> tracer-point averaging (MOM6 vertex form, Pass C). Cell (i,j) reads its four corners SW=(i,j), SE=(i+1,j), NW=(i,j+1), NE=(i+1,j+1) — a read-only corner stencil into an own-cell write, safe as its own do concurrent but NEVER fusable with the corner solve (kd_corner is the required snapshot). Two modes: arithmetic (default): 0.25 * ((SW+NE) + (NW+SE)) geometric: 4th root of the product of the four corner values, each floored at kdmin first — a geometric mean is 0 if ANY factor is 0, which would otherwise blank Kd along every shear-zone edge. The floor applies to the CORNER values only, never the output: a land cell still gets exactly 0 via the wet_t multiply. Endpoints (bed K=1, surface K=nzp1) are forced to exactly 0. tke_int is zeroed — the vertex form does not carry a cell-centred TKE (corner TKE deliberately not materialised). Bracketing is reproducible-sum ordering; keep literal.

ke_probe_active rdb_ocean_ke_probe Function

Gate: enabled AND inside the step window.

ke_probe_coradv_split rdb_ocean_ke_probe Subroutine

Sub-attribute the coriolis_adv segment: split the just-applied tendency into its PV-flux part and its −∇KE part and print each part’s work integral per region (KE_ATTR_PV rows). Call immediately AFTER coriolis_adv_apply_tendencies (and after the “coriolis_adv” KE_ATTR sample).

Read more…
ke_probe_sample rdb_ocean_ke_probe Subroutine

Sample the three-region layer KE and print the attribution row. Call AFTER the segment being attributed; the printed dKE is “this sample minus the previous one” — i.e. the segment’s energy contribution. Drains all device queues first so the async velocity-apply chain (queue 1) has landed.

ke_regions_impl rdb_ocean_ke_probe Subroutine

h-weighted layer KE over the three regions, one device pass. Per cell: KE = Σ_k [ ¼(h_W·u_W² + h_E·u_E²) + ¼(h_S·v_S² + h_N·v_N²) ] with h_face the centred face thickness (m³/s² per unit area; uniform-Δx Cartesian, so the area factor is a constant and is dropped — attribution only needs a consistent measure). Explicit OpenACC reduction — a sum() intrinsic on a present-mapped array silently runs host-side under NVHPC non-managed mode and returns the stale host shadow.

kpp_surface_buoyancy_flux rdb_ocean_vmix Function

Surface buoyancy flux for the KPP overlay’s convective scale:

Read more…
kpp_sw_method_is_implemented rdb_ocean_vmix Function

Fail-loud predicate for kpp_sw_method — validate_config aborts on any string this rejects.

ks_adaptive_dt rdb_ocean_kappa_shear Function

Largest dt_test <= dt_rem such that, after mixing for 0.5*dt_test with kappa_out_s, the regenerated source stays within the tolerance bands of the accepted-state source (design doc section 5.3): a halving pass followed by a 5-step refinement pass.

ks_find_kappa_tke rdb_ocean_kappa_shear Subroutine

The inner Picard solve (design doc section 5.4): alternate a TKE tridiagonal sweep (Dirichlet surface, e1 tail below the deepest active interface) with a kappa tridiagonal sweep (smooth truncation ramp + active-range tracking) until the Picard increment converges. Scratch arrays are supplied by the caller to avoid double-allocating per-thread stack.

ks_gather_corner rdb_ocean_kappa_shear Subroutine

Assemble the surface-down column at corner (ic,jc) from the 2x2 cell patch + 4 adjacent faces (JHL08 vertex form; the interpolation recipes of the reference implementation): u,v : 2-point THICKNESS-weighted average across the corner, with the face thickness itself a mask-weighted 2-cell average (recomputed inline — deterministic, so the repeated evaluation is bitwise identical to MOM6’s precomputed h_at_u/h_at_v Pass A, non-OBC-bug form). T,S : 4-cell mask-AND-thickness-weighted average. The registry stores hTr = hT, which is exactly the weighted quantity, so we sum wethTr directly. h : 4-cell mask-weighted average (no thickness weight — it IS the thickness). Returns RAW h (no floor) — the caller decides floor vs massless-merge exactly as the column path does. The deliberate (SW+NE)+(SE+NW) bracketing is reproducible-sum ordering — do not reassociate.

ks_precompute rdb_ocean_kappa_shear Subroutine

Build the thickness-derived interface grids that the iteration reuses: 1/h, the interface 1/dz, the harmonic-mean interface FV cell thicknesses h_Int (Sum h_Int = Sum h), and the inverse boundary length scale squared (design doc section 5.1).

ks_projected_state rdb_ocean_kappa_shear Subroutine

Mix (u0,v0,T0,S0) implicitly with kappa_ps over dt_now, restricted to the layer band [ks,ke], and recompute N^2/S^2 at interfaces (band edges blend mixed inside / original outside). Backward-Euler tridiagonal; no-slip for u,v iff the band reaches the bed (ke==nz), insulating T,S. N^2 floored at 0 (design doc section 5.5).

ks_solve_column rdb_ocean_kappa_shear Subroutine

Full JHL08 column solve in surface-down indices (design doc section 5.1-5.2): background kappa_0 pre-step (no-slip bed for u,v; insulating T,S), frozen interface buoyancy derivatives, e1 tail recursion, then the adaptive predictor-corrector outer loop driving the Picard inner solve. Returns the time-mean diffusivity kappa_avg_sd and TKE tke_avg_sd over dt.

ks_src_func rdb_ocean_kappa_shear Function

Shear-source function K_src at one interface (JHL08 eq. for the source term): nonzero only where N^2 < Ri_c * S^2.

lateral_closure_conflicts_smag_ah rdb_ocean_lateral_mix Function

.true. iff the closure is LMIX_LEITH_BIHARM and smag_ah is on — both would fill nu4_face_* and smag_ah runs last, so it would silently overwrite the Leith-biharmonic fill (we do not max-combine biharmonic closures). Drives a fail-loud guard.

lateral_closure_is_implemented rdb_ocean_lateral_mix Function

.true. iff the closure code has a working dispatcher path. Drives the configure-time fail-loud guard. Keep in lock-step with the select case in ocean_lateral_mix_compute.

lateral_mix_uses_resoln rdb_ocean_dyn Function

.true. when the lateral-mix compute call should be handed the VarMix resolution-function face fields (Gap 1): the lateral-mix slot is present + initialised with resoln_scaled_visc, AND VarMix is present + enabled (so res_fn_u/v carry a valid, up-to-date resolution function). Either absent / off ⇒ unscaled coefficients (bit-identical).

laytemp_sis2 rdb_ice_column Function

Per-layer implicit heat-budget solve for the new layer temperature — SIS2 laytemp_SIS2 (SIS2_ice_thm.F90:544-700), ICE_CP_BRINE == ICE_CP_ICE closed-form branches only (the Newton/false-position refinement at :625-692 is dead code under the simplification and is deliberately NOT ported). Port of prototype sis2_column.py:21-55.

leith_biharm_is_inert rdb_ocean_lateral_mix Function

.true. iff the Leith-biharmonic closure is selected but its coefficient is <= 0 (PR-6 fail-loud). ν₄ is linear in c_leith_bi, so c_leith_bi <= 0 makes the whole closure a provable no-op — the user asked for biharmonic dissipation and got none. Returns .false. for any other closure (they do not read c_leith_bi, so the guard must not fire on them). Promotes the previous configure-time warning to an abort.

levenshtein rdb_nml_schema Function

Levenshtein edit distance between two (capped) strings.

linear_in_z rdb_ocean_z_init Function

Affine profile v(z) = v_ref + dv_dz*z evaluated at geopotential height z = -z_depth, i.e. v = v_ref - dv_dz*z_depth.

Read more…
load_bathymetry_into_array rdb_bathymetry Subroutine

Load bathymetry from a NetCDF file into a target 2D array shaped (grid%nx_total, grid%ny_total).

Read more…
logical_default_string rdb_nml_schema Function
logical_is_default rdb_nml_schema Function
logical_parse rdb_nml_schema Subroutine
logical_value_string rdb_nml_schema Function
lower rdb_nml_schema Function

Lowercase an ASCII string.

lower_ascii rdb_ocean_diag Function

ASCII lowercase a string (attribute matching is case-insensitive).

make_prefix rdb_nml_schema Function

Build a path:line: error prefix.

mask_bt_rem rdb_barotropic_coupling Subroutine

Fold the static land face masks into the BT-substep damping factor (bt_rem_u(land)=0 ⇒ no velocity across a land face). Runs every outer step AFTER compute_bt_rem (which resets bt_rem each step, so the mask must be re-applied). All-wet ⇒ wet_u/v≡1 ⇒ no-op (bit-identical).

mask_layer_velocities rdb_ocean_dyn Subroutine

Zero the per-layer face velocities at land faces (spec §14 C4 / R4(b.2) / MOM6 up = mask2dCu·(u+dt·accel)). Runs once per RK2 stage AFTER apply_bt_correction and inside the RK2 average so the additive layer tendencies + the BT correction cannot leave a re-ingested land-face velocity (a slow conservation leak). The transports themselves already ride zeroed metrics; this resets the prognostic velocity so derive_bt_from_layers next step sees zero there. All-wet ⇒ wet_u/v≡1 ⇒ literal no-op.

Read more…
mask_time_mean_velocities rdb_ocean_dyn Subroutine

Apply the land contract of mask_layer_velocities — static wet_u/wet_v, times the z-level open_u/open_v when zfixed_closed_faces is on — to the pred_corr time-mean velocities u_av/v_av. Called once, on the step-0 seed: the renormaliser’s u_cor, their only other writer, never writes a masked face, so what the seed leaves there is what every later step reads. (Wet/dry is refused under pred_corr, so its dynamic mask has no branch here.) All-wet, knob off ⇒ products with exactly 1, i.e. byte-identical.

massless_build_maps rdb_massless Subroutine

Build the merged massive-layer grid and the maps kc, kf. kc(k) (k=1..nz) = merged-layer index original layer k folds into; kc(nz+1) = nzc+1 is the bed sentinel. kf(K) = fractional position of original interface K inside merged layer kc(K) (0 = coincides with a merged interface -> pure lookup; (0,1) = interior -> linear blend in massless_interp_back). Identity case (no layer < h_min): nzc==nz, kc(k)==k, kf(k)==0, hc==h bit-for-bit.

massless_interp_back rdb_massless Subroutine

Inverse map: interpolate an interface quantity qc(1:nzc+1) on the merged grid back to the original nz+1 interfaces. kf==0 takes a pure lookup; interior interfaces take the linear blend between merged interfaces kc(K) and kc(K)+1 (in range since kf>0 only when kc(K) < nzc+1). Identity case: kf==0 everywhere -> q==qc.

massless_merge_fields rdb_massless Subroutine

Thickness-weighted merged means for u, v, T, S — the solver receives MEANS, not integrals, and must not re-divide. Accumulation runs in the same surface-down k order as massless_build_maps so the column-integral conservation holds to round-off.

mean_longitudes rdb_ocean_tide_astro Subroutine

Mean longitudes at day number dnum (Schureman polynomials). Returned in DEGREES, folded to [0,360). T = dnum/36525 (Julian centuries, Schureman’s 36525-day century). Multiply by TIDE_DEG2RAD to get radians for the equilibrium arguments.

meke_advect rdb_ocean_meke Subroutine

Upwind flux-form advection of E by the barotropic mass transport. advFac = adv_fac/sdt uflux(I) = baroHu(I)advFacE_upwind (E_{I-1} if baroHu>0 else E_I) E += sdtIareaTI_mass((uflux_{i-1}-uflux_i)+(vflux_{j-1}-vflux_j)) Conservative on a closed domain (interior faces only; the divergence telescopes ⇒ Sum Earea*mass conserved). adv_fac=0 never reaches here (gated by the caller) ⇒ default bit-identity.

meke_backscatter_apply rdb_ocean_meke Subroutine

Inject the MEKE harmonic backscatter into the per-face resolved harmonic viscosity (capability Gap 2, v1). Subtracts a face-average of the cell-centred ku field from ah_face_x/ah_face_y so the NET coefficient A_net = A_resolved − Ku can go NEGATIVE — that negative viscosity is the energy return into the momentum tendency (the hvisc Laplacian kernel reads these same face fields).

Read more…
meke_backscatter_apply_impl rdb_ocean_meke Subroutine

harmonic viscosity and floor the net at the CFL-stable minimum. Explicit-shape dummies for NVHPC stdpar (no descriptor walk). The backscatter coefficient is z-independent in v1 (BS_struct=1), so the cell-centred ku(i,j) is broadcast to every layer.

meke_baro_transport rdb_ocean_meke Subroutine

Depth-integrated, mass-weighted barotropic transport through each C-grid face: baroHu(I,j) = Sum_k rho_face * mass_flux_x_layer, where mass_flux_*_layer is the per-layer VOLUME transport (m^3/s, = uh_facedy) and rho_face the two-cell average density. The result is a MASS transport (kg/s) so the advective divergence pairs exactly with IareaT*I_mass (1/(areamass)) ⇒ Sum Earea*mass is conserved. Array-edge faces carry zero transport (closed domain).

meke_bbl_speed2 rdb_ocean_meke Subroutine

Resolved bed-layer speed² at cell centres: u_bbl2 = u_c² + v_c² with u_c = ½(u_face(i)+u_face(i+1)), v_c = ½(v_face(j)+v_face(j+1)), each face read on ITS OWN bed layer k_bot_u/v (the first layer live on both sides counting up; 1 off z_fixed ⇒ the historical k=1 read). Under z_fixed the layers below are inert fillers whose velocity the closed-face mask has zeroed, so a k = 1 read reported a motionless bed. The bottom eddy velocity the MEKE drag law needs (MOM6 drag_rate_visc).

meke_drag rdb_ocean_meke Subroutine

Implicit (backward-Euler) bottom-drag half-step. drag_rate = rho0i_masssqrt(cdrag^2(max(0,2bf2E)+u_bbl2+uscale^2)) [1/s] damp_rate = damping + drag_ratebf2 ; =0 where E<0 E <- E/(1 + sdt_dampdamp_rate) rho0*i_mass = rho0/(Sum_k rho_kh_k) ~= 1/depth_tot [1/m], so drag_rate ~= cdrag|U_d|/H – the MOM6 GV%H_to_RZ * I_mass factor. Without it drag_rate is m^3/(kgs), not a rate. i_mass=0 on dry columns still gives drag_rate=0. u_bbl2 is the resolved bed-layer speed² (MOM6 drag_rate_visc); it is 0 unless use_bbl_drag is set, so the default is bit-identical.

meke_feed_khth rdb_ocean_meke Subroutine

Add the geometric mean of neighbour kh_diff into VarMix’s per-face KhTh (and KhTr) base BEFORE GM’s CFL clamp: khth_u(i,j) += khth_facsqrt(kh(i-1,j)kh(i,j)) khth_fac=0 ⇒ nothing added ⇒ bit-identical seam.

meke_inv_lmix rdb_ocean_meke Function

Harmonic inverse mixing length 1/Lmix = Sum aX/LX over the five length scales (deformation, frictional, Rhines, Eady, grid). Each scale is gated aX*LX > 0 so a zero weight or a degenerate scale contributes nothing. Returns 1/Lmix (0 ⇒ Lmix degenerate).

meke_kh_closure rdb_ocean_meke Subroutine

Derived diffusivity kh = khcoeff*sqrt(2*max(0,gamma_t2*E))*Lmix. khcoeff<=0 ⇒ kh left at 0.

meke_ku_closure rdb_ocean_meke Subroutine

Derived harmonic backscatter viscosity ku = visc_coeff_ku*sqrt(2*max(0,E))*Lmix (m²/s), matching MOM6 MEKE%Ku = MEKE_VISCOSITY_COEFF_KU*sqrt(2*MEKE)*Lmix. Unlike the kh closure (which carries the barotropic-mode factor gamma_t2 inside the eddy velocity), MOM6’s Ku uses the PLAIN sqrt(2*MEKE) — no vertical-structure factor — so gamma_t2 is deliberately absent here (vertical structure BS_struct = 1; EBT/SQG deferred). Off ⇒ ku left at 0 (bit-identical seam). Always ≥ 0; the SIGN of the momentum effect is set by the subtraction downstream.

meke_lateral rdb_ocean_meke Subroutine

Harmonic-mass Laplacian diffusion of MEKE (+ optional biharmonic). Flux-form, conservative on a closed domain (interior faces only; array-edge faces carry zero flux). Kh_u = max(0,kh_bg) + khmeke_fac0.5(kh_i+kh_{i+1}), CFL-capped 0.25 uflux = Kh_u(dy_cuidxCu)[2 m_i m_{i+1}/(m_i+m_{i+1}+eps)](E_i-E_{i+1}) E += sdtiareaTi_mass((uflux_{i-1}-uflux_i)+(vflux_{j-1}-vflux_j)) Biharmonic: del2 = iareaT(d uflux’ + d vflux’) with the bare-gradient flux uflux’ = (dy_cuidxCu)(E_{i+1}-E_i); then a harmonic-mass flux of del2 with CFL cap 0.3 and E += that divergence (additive).

meke_length_scales rdb_ocean_meke Subroutine

Fill the structure factors gamma_b^2 (bottom_fac2) and gamma_t^2 (barotr_fac2) plus the mixing length le (Lmix) at each cell centre. Ldeform/Lfrict drives both gammas; Lmix is the harmonic sum of the alpha-weighted scales. beta = |grad f| from centred f_centre differences scaled by idxT/idyT (zero when f_centre is unfilled ⇒ Rhines inert). SN = 0.25*(sn_u(i)+sn_u(i-1)+ sn_v(j)+sn_v(j-1)) only when aEady>0.

meke_mass rdb_ocean_meke Subroutine

Column mass mass = Sum_k rho*max(h,H_VANISHED) (kg/m^2), its inverse i_mass (0 where mass<=0), depth_tot = Sum_k h (m), and mass_ws = mass (the harmonic-mass input for the lateral flux).

meke_source rdb_ocean_meke Subroutine

Aggregate source src = bgsrc + gmcoeff*I_mass*gm_src - frcoeff*I_mass*ke_diss and the explicit bump E += sdt*src. gmcoeff<0 ⇒ GM source off; frcoeff<0 ⇒ frictional source off. ke_diss is the lateral-viscosity KE dissipation rate (≤0), so -frcoeff*I_mass*ke_diss ≥ 0 is a mean→eddy source (0 ⇒ inert).

meke_stage_rd rdb_ocean_meke Subroutine

Copy rd_over_dx onto the device workspace. Thermo-cadence; explicit-shape; on-device (source slot is device-resident).

meke_stage_sn rdb_ocean_meke Subroutine

Copy the SN faces onto the device workspaces. Thermo-cadence; explicit-shape; on-device (VarMix slot is device-resident).

meke_step rdb_ocean_meke Subroutine

Advance the MEKE field one thermo step (Strang split), update the derived diffusivity kh_diff, and feed the geometric-mean kh into VarMix’s per-face KhTh/KhTr (the GM↔MEKE feedback). Run once per outer step at thermo cadence, after varmix_compute and before gm_compute_transports (MEKE reads gm%gm_src from the previous thermo step — a one-step lag). No-op when enable=.false., uninitialised, or the GM slot is absent.

meke_zero_2d rdb_ocean_meke Subroutine

Zero a device-resident 2D workspace (absent-source fallback).

melt_m_per_yr_factor rdb_ocean_diag_derived Function

The ISOMIP+ melt-rate conversion, kg m-2 s-1 → m yr-1 of ice-equivalent freshwater: f = SECONDS_PER_YEAR / rho_fw.

Read more…
mem_device_free_bytes rdb_mem_report Function

Free memory on the bound device, in bytes. Returns -1 when no OpenACC runtime is present.

mem_device_total_bytes rdb_mem_report Function

Total memory of the device that the OpenACC runtime is bound to, in bytes. Returns -1 when no OpenACC runtime is present (CPU / gfortran / ifx builds).

mem_device_used_bytes rdb_mem_report Function

Device memory currently in use, in bytes (total - free). DEVICE-WIDE: includes this process’s CUDA context (~300-500 MB) and every other process on a shared device — see the module header’s structural offsets. Returns -1 when no OpenACC runtime is present.

mem_format_bytes rdb_mem_report Function

Human-readable byte count: two decimals, GB at/above 1 GiB, MB below. Used for every figure in the budget log so the units stay consistent.

mem_host_rss_bytes rdb_mem_report Function

Resident set size of the current process, in bytes, parsed from VmRSS in /proc/self/status (reported in kB → scaled to bytes). Returns -1 if the file is unreadable or the field is absent (non-Linux platforms). Never aborts.

mem_log_computed_budget rdb_mem_report Subroutine

Log the COUNTED state-array footprint. Unlike the RSS figure (host-only I/O buffers + library pages) and the device query (needs an OpenACC runtime), this is an exact sum of the state’s allocatable arrays — available on every toolchain, so a CPU build gets a real footprint line too. Latching for the reconciliation is mem_set_counted_budget (separate, so the print can move to the banner while the latch stays before enter_data).

mem_log_computed_line rdb_mem_report Subroutine

Log one indented breakdown line for a component of the counted footprint (barotropic / layers / closures / …). Skipped when the component is empty so gated-off slots don’t clutter the report.

mem_log_device_actuals rdb_mem_report Subroutine

Log actual device memory after enter_data: the device-wide usage (used = total - free — includes the CUDA context and any other process on a shared device) plus the MEASURED state mapping delta (free-before-mapping minus free-now; accurate to NVHPC pool granularity, ~a few MB). Latches the post-mapping usage as the baseline for mem_log_device_growth. Silent no-op when device queries are unavailable (CPU build).

mem_log_device_growth rdb_mem_report Subroutine

Report device-memory growth since the post-enter_data baseline. Two allocations land AFTER the setup-time report and would otherwise stay invisible: the lazy first-call kernel workspaces (*_workspace_ensure, ~33% of the coastal device footprint) and the one-off CUDA runtime/kernel reservation at first launch (GBs — module-header offset 3). Call this in the end-of-run summary (prints usage + the “grew ~X after setup” attribution, so even a 10-step run shows the true footprint) and at the periodic status with quiet=.true. (no info lines). The one-shot leak WARNING measures PROGRESSIVE growth — past GROWTH_WARN_FRAC of the steady baseline latched at the first post-setup sample — so the expected one-offs never trip it. Silent no-op on CPU builds or when the baseline was never latched.

mem_log_state_budget rdb_mem_report Subroutine

Log the pre-mapping memory budget. Always logs the host-side allocation growth (ADVISORY — includes host-only I/O buffers + library pages, NOT a device estimate); when the device queries succeed it also logs the device number + free/total and latches the free-memory snapshot that mem_log_device_actuals turns into the measured mapping delta. Warns when the host growth (a conservative upper bound on what enter_data can map) exceeds 95% of free device memory — the regime where enter_data is likely to abort.

mem_set_counted_budget rdb_mem_report Subroutine

Latch the COUNTED state-array footprint for the enter_data reconciliation, WITHOUT logging. Must run before mem_log_device_actuals (the reconciliation reads this), even when the human-readable budget is printed later (e.g. folded into the driver’s post-setup banner). total_bytes is the sum of every state bytes() term (0 for gated-off slots).

metrics_apply_land_mask rdb_ocean_metrics Subroutine

Derive the static C-grid face / corner masks from the T-cell wet_mask and zero the face metrics at land faces, so every transport / gradient / circulation operator that rides those metrics couples across NO land face (MOM6 pre-masks the face LENGTHS; Adcroft & Hallberg 2006).

Read more…
metrics_assemble_from_supergrid_arrays rdb_ocean_metrics Subroutine

Fill all model metric arrays from an in-memory MOM6-style supergrid (2x-refined corner geography + edge segments + sub-cell areas), using the even/odd index sums. This is the battle-tested assembly path the NetCDF reader used inline; the tripolar generator builds the supergrid analytically and feeds it here so tripolar metrics flow through identical index logic.

Read more…
metrics_bt_cfl_length rdb_ocean_setup Function

2-D external-gravity-wave CFL length over the PHYSICAL region: l_cfl = min_cell 1 / sqrt(1/dxT^2 + 1/dyT^2). Length scale for the barotropic CFL c_ext*dt*sqrt(1/dx^2+1/dy^2) <= 1 (includes the cross-direction term; on uniform Cartesian = dx/sqrt(2)). Handles anisotropic cells exactly. Host-side, configure time.

metrics_closed_faces_alloc rdb_ocean_metrics Subroutine

Grow the z-level closed-face masks from their (1,1,1) placeholder to full face size. Call ONLY when &vcoord_nml zfixed_closed_faces is on, at configure time — after init and BEFORE ocean_state_enter_data, so the device map captures the final shapes (a realloc after enter_data would leave the device pointing at freed host memory).

Read more…
metrics_dx_min rdb_ocean_setup Function

Representative minimum grid length over the PHYSICAL region, taken over both dxT and dyT (host-side, configure time). Bit-identical to min(grid%dx, grid%dy) on uniform Cartesian.

metrics_fill_cartesian rdb_ocean_metrics Subroutine

Uniform Cartesian: every length is constant, areaX = dx*dy. Geography is left at zero (a Cartesian beta-plane has no lat/lon — the Coriolis fill uses the Cartesian y coordinate, D7). Fills all ghost rows/columns (constants, trivially). Call metrics_finalize afterwards.

metrics_fill_coriolis rdb_ocean_metrics Subroutine

Fill a corner array AND a centre array with the Coriolis parameter, from one of two schemes (D7). Does NOT touch any existing fill sites in coriolis_adv / EPBL / kappa-shear (that re-routing is M2d); this routine just exists + is tested.

Read more…
metrics_fill_from_supergrid rdb_ocean_metrics Subroutine

Load an MOM6 supergrid (mosaic) NetCDF file and fill all metric arrays. After this call the caller must invoke metrics_finalize to compute the inverses + hvisc ratio bundle.

Read more…
metrics_fill_spherical rdb_ocean_metrics Subroutine

Spherical lon-lat sector. For each stagger, geolat/geolon are evaluated at THAT point’s own location; the metric lengths use the cos of that stagger’s own latitude (the consistency trick that keeps the C-grid metrics compatible, D6): dx = rad_earth * cos(lat) * dlon_rad dy = rad_earth * dlat_rad area = dx * dy (analytic-derivative form, NOT great-circle).

Read more…
metrics_fill_tripolar rdb_ocean_metrics Subroutine

Fill every metric array for an analytic TRIPOLAR grid (Murray 1996): ordinary lon-lat for cell-corner latitude <= phi_join, and a conformal bipolar Arctic cap above (two grid poles at (phi_join, lon_pole) and (phi_join, lon_pole+180); see rdb_ocean_bipolar). The construction generates an in-memory MOM6-style supergrid (2x-refined corner geography, great-circle edge lengths, sub-cell areas) from the analytic map, then feeds the SAME metrics_assemble_from_supergrid_arrays index-sum path the NetCDF reader uses — so tripolar metrics flow through the battle-tested supergrid assembly. Call metrics_finalize after.

Read more…
metrics_fill_tripolar_whole rdb_ocean_metrics Subroutine

The undecomposed tripolar build behind metrics_fill_tripolar: grid must hold the WHOLE grid (its local extents are the global ones), so the fold and the periodic seam are both local.

metrics_finalize rdb_ocean_metrics Subroutine

Compute every stored inverse + the hvisc ratio bundle ONCE from the length/area arrays a generator already wrote, via the Adcroft reciprocal (D4). No kernel ever recomputes these.

metrics_fold_north_cu_scalar rdb_ocean_metrics Subroutine
metrics_fold_north_cv_scalar rdb_ocean_metrics Subroutine
metrics_fold_north_faces rdb_ocean_metrics Subroutine

North fold of the face and corner metric arrays (the Cu / Cv / Bu part of metrics_fold_periodic_ghosts; the T arrays are folded there).

metrics_fold_periodic_ghosts rdb_ocean_metrics Subroutine

Tripolar ghost-metric fill (M4c): periodic-x wrap of the east/west ghost columns + north-fold of the north ghost rows, for EVERY metric + geography array. Replaces the constant extrapolation the supergrid assembler left on those edges. The ONE routine both the analytic tripolar generator and the MOM6 mosaic reader (metrics_fill_from_supergrid) use.

Read more…
metrics_periodic_x_2d rdb_ocean_metrics Subroutine

West/east ghost columns of a T-array (nx_total,ny_total) by periodic wrap (column i <= ng ← i+ni; i > ng+ni ← i-ni).

metrics_periodic_x_all rdb_ocean_metrics Subroutine

Periodic-x wrap of the east/west ghost columns of every metric, geography and rotation array (the first half of metrics_fold_periodic_ghosts).

metrics_periodic_x_bu rdb_ocean_metrics Subroutine

Bu-array (nx_total+1,ny_total+1): face-type in x, same as Cu.

metrics_periodic_x_cu rdb_ocean_metrics Subroutine

Cu-array (nx_total+1,ny_total): faces 1..ni+1 physical at i=ng+1..ng+ni+1.

metrics_periodic_x_cv rdb_ocean_metrics Subroutine

Cv-array (nx_total,ny_total+1): centre-type in x, same as T.

metrics_periodic_y_2d rdb_ocean_metrics Subroutine

South/north ghost rows of a T-array by periodic wrap (the y analogue of metrics_periodic_x_2d). Only used by the land-mask ghost fill; the metric tripolar path wraps x only.

metrics_porous_alloc rdb_ocean_metrics Subroutine

Grow the porous-barrier arrays from their (1,1)/(1,1,1) placeholder size to full face size. Call ONLY when &ocean_porous_nml enable is on, at configure time — i.e. after init and BEFORE ocean_state_enter_data, so the device map captures the final shapes (a realloc after enter_data would leave the device pointing at freed host memory).

Read more…
metrics_window_2d rdb_ocean_metrics Subroutine

Copy a tile’s storage window (ghosts included) out of the undecomposed array: tile(i, j) = whole(i + io, j + jo). The stagger is carried by the shapes — a face/corner array is one wider on both sides, so the same offsets address it.

metrics_window_all rdb_ocean_metrics Subroutine

Cut a tile’s storage window (ghosts included) out of a larger assembled metric set, for every array the supergrid assembler and the fold/periodic ghost fill write: tile%X(i, j) = whole%X(i + io, j + jo). Shared by the decomposed tripolar generator (whole grid) and the decomposed supergrid reader (a full-width row band).

min_thickness_target_column rdb_ocean_min_thickness Subroutine

Build the floor-only conservative target thickness column.

Read more…
mle_bodner_timescale rdb_ocean_mle Function

Bodner et al. (2023) frontogenesis-arrest MLE timescale [s]: ts = Cr · ds · |f| · h / w’u’ where the frontal-arrest length enters inline as |f|·h/w'u' and w’u’ = max( (mstar·u³ + nstar·w³)^(2/3), min_wstar2 ), w³ = max(0, -b0)·h (destabilizing buoyancy flux only) ds = sqrt(0.5(dx²+dy²)) is the grid-scale front width. Because the product is dimensionally a TIME, this drops straight into the FK transport form uDml = ts·dyCu·idxCu·db·H² (the swap that turns classic Fox-Kemper into Bodner). w'u' is floored so a quiescent, unforced column (u→0, b0→0) never divides by zero.

mle_compute_transports rdb_ocean_mle Subroutine

Fill uhml/vhml (m^3/s) with the FK MLE overturning transport. Run once per outer step at thermo cadence, before the continuity divergence. Steps: (1) b_ml + htot_ml at cell centres (surface→bed band to mld, partial-weight the straddling layer); (2) uDml/vDml at faces from grad b_bar, timescale, H_vel²; (2b) optional per-layer availability cap (a scalar shrink keeping sum_k a(k)=0); (3) fold the mu profile a(k) → uhml/vhml. No-op when enable=.false. or the slot / state arrays are absent.

mle_face_ustar_x rdb_ocean_mle Function

Friction velocity u* = sqrt(|tau|/rho0) at the u-face from the surface wind stress, averaged onto the face. Only used by the FK11 mixrate form. Returns 0 if stress fields are absent.

mle_face_ustar_y rdb_ocean_mle Function

u* at the v-face; mirror of mle_face_ustar_x.

mle_fold_x rdb_ocean_mle Subroutine

Add the FK x-face transport into the per-layer zonal mass flux, AFTER continuity_zonal_flux fills it and BEFORE the zonal tracer advect / divergence — so the augmented flux transports both h and tracers (conservative; no velocity touched). No-op when disabled.

mle_fold_y rdb_ocean_mle Subroutine

Add the FK y-face transport into the per-layer meridional mass flux. Mirror of mle_fold_x. No-op when disabled.

mle_layer_weights rdb_ocean_mle Subroutine

Per-layer transport weights a(k) = mu(sigma_top) - mu(sigma_bot), walking surface (k=nz) -> bed (k=1). sum_k a(k) = mu(0)-mu(-1) = 0 (closed cell => conservation). Layers below the ML base get sigma <= -1 => mu=0 on both interfaces => a(k)=0 (ML-confinement).

Read more…
mle_mu_shape rdb_ocean_mle Function

FK08 second-order vertical structure function mu(sigma). sigma in [-1,0]: 0 = surface interface, -1 = ML base. mu = 0 at sigma=0 (surface) and sigma <= -1 (ML base); peaks near sigma=-0.5.

Read more…
mle_timescale rdb_ocean_mle Function

FK restratification timescale [s].

Read more…
move_group rdb_nml_schema Subroutine

Transfer a group’s contents without copying any polymorphic key box (descriptor moves only — see schema_add_group).

multilayer_enforce_vanished_content rdb_multilayer_state Subroutine

THE enforcement point for invariant I1′.

Read more…
multilayer_enforce_vanished_content_host rdb_multilayer_state Subroutine

HOST twin of enforce_vanished_content, for SETUP only. The seed (ocean_state_seed_land_cells) runs before enter_data, where a do concurrent on the offload build would work on device memory that is not mapped yet (mem:separate: no implicit copies). Plain host loops over the SAME included rdb_vl_merge_content, so the seeded state satisfies I1′ by the one definition. Never call it on a device-resident state.

multilayer_register_passive_tracer rdb_multilayer_state Subroutine

Append a passive tracer (eos_coeff = 0, budget_id = NONE) to the registry, growing tracers(:) past the default S/T[/age] set. Returns its slot in idx, or idx = 0 on refusal (registry not init’d, or locked by enter_data). MUST be called after init and BEFORE enter_data — and, on the ocean path, before ocean_bc_state_init sizes bc%n_tracers. Caller populates hTr once layer thicknesses exist, and may set tracers(idx)%standard_name / the pipeline opt-outs directly (public components). S/T/age keep their indices.

multilayer_scan_vanished_content rdb_multilayer_state Subroutine

Pure I1′ TRIPWIRE scan — counts the vanished cells that do NOT hold their donor’s concentration (rdb_vl_holds_live_conc: |hTr − h·c_live| > 1e-12·|h·c_live|, i.e. hTr ≠ 0 in a column with no live layer) and reports the largest offending |hTr − h·c_live|, without touching anything. Two device reductions per tracer, two scalars out; no H←D copy on the healthy path.

Read more…
multilayer_state_bytes rdb_multilayer_state Function

Counted allocatable footprint of the ocean C-grid layer slot: the layer prognostics + face transports + RK2 saves + density/vertical diagnostics, the per-tracer registry (each tracer sums its own arrays; ideal-age rides the registry when on), and the device-resident conservation-budget accumulators.

multilayer_state_destroy rdb_multilayer_state Subroutine
multilayer_state_enter_data rdb_multilayer_state Subroutine

Attach the C-grid multilayer allocatables to the device. The tracer registry uses the two-step pattern: array descriptor first, then each element’s hTr / hTr0 — NVHPC stdpar can’t dereference tracers(it)%hTr from a do-concurrent body otherwise.

multilayer_state_enter_data_impl rdb_multilayer_state Subroutine
multilayer_state_exit_data rdb_multilayer_state Subroutine

Reverse of enter_data. Copy out the prognostic fields and the tracer hTr arrays (so post-run host inspection works), drop scratch + RK saves. Tracer registry tears down per- element first, then the array descriptor — mirror of enter_data order.

multilayer_state_exit_data_impl rdb_multilayer_state Subroutine
multilayer_state_init rdb_multilayer_state Subroutine

Allocate per-layer C-grid arrays at the grid size and the configured layer count (caller must set this%nz_ml first). Registers salinity + temperature with default identity strings. When with_ideal_age is present and true, also registers an ideal-age tracer at index 3 (see rdb_ocean_ideal_age).

n_tracers rdb_ocean_fold_apply Function

Registered tracers carrying an allocated hTr.

nc_check rdb_io_netcdf Subroutine

Check NetCDF return status and log error if it failed

nc_close rdb_io_netcdf Subroutine

Close a NetCDF file

nc_create_file rdb_io_netcdf Subroutine

Create a new NetCDF-4 file (overwrites if exists)

nc_def_dim rdb_io_netcdf Subroutine

Define a dimension (use nf90_unlimited for unlimited)

nc_def_var_2d rdb_io_netcdf Subroutine

Define a 2D variable with working precision type

nc_def_var_3d rdb_io_netcdf Subroutine

Define a 3D variable (x, y, time) with working precision type

nc_def_var_4d rdb_io_netcdf Subroutine

Define a 4D variable (x, y, z, time) with working precision type

nc_emit_post_fire rdb_ocean_diag_netcdf Subroutine

Post-fire emit hook. Appends one slice + time value for the var that just fired. Bound to diag%emit_post_fire by open_stream.

nc_enddef rdb_io_netcdf Subroutine

End define mode, switch to data mode

nc_get_att_int rdb_io_netcdf Subroutine

Read a global integer attribute

nc_get_att_text rdb_io_netcdf Subroutine

Read a character (text) attribute from a variable — used for the CF units attribute on a time axis. Non-fail-loud: ok is .false. (and value blank) when the attribute is absent or the wrong type, so callers can fall back to a default rather than aborting on a missing/optional attribute.

nc_get_dim_len rdb_io_netcdf Subroutine

Get the length of a named dimension

nc_get_var_1d rdb_io_netcdf Subroutine

Read a full 1D array (the read sibling of rdb_put_var_1d).

nc_get_var_2d rdb_io_netcdf Subroutine

Read a full 2D array

nc_get_var_3d rdb_io_netcdf Subroutine

Read a full 3D array. Mirrors nc_get_var_2d; the target’s shape must match the file variable’s Fortran storage order (the caller handles any C/Fortran dimension reversal, as rdb_bathymetry does for 2D).

nc_get_var_slab_2d rdb_io_netcdf Subroutine

Windowed read of a 2D variable: start/count (length 2, FORTRAN dimension order) select the block that lands in data, whose shape must equal count. The per-rank readers (bathymetry, supergrid) use it to load only the rows their tile needs.

nc_get_var_slab_3d rdb_io_netcdf Subroutine

Strided slab read: start/count are the NetCDF start/count vectors in FORTRAN dimension order, with length matching the target variable’s rank (3 for a 2D-field-plus-time variable, 4 for a 3D-field-plus-time variable). data is always a plain 3D Fortran array; for the 2D-plus-time case pass a target with a trailing singleton extent (data(:,:,1)) — the netcdf-fortran generic interface dispatches on the array RANK of data, not the length of start/count, so one routine covers both shapes. This is the first strided (non-full-variable) read in the tree — mirrors nc_put_var_4d_slice for the start/count shape, on the read side.

nc_get_varid rdb_ocean_restart_io Subroutine
nc_get_varid rdb_io_netcdf Subroutine

Get the variable ID for a named variable

nc_open_read rdb_io_netcdf Subroutine

Open an existing NetCDF file for reading

nc_open_write rdb_io_netcdf Subroutine

Open an existing NetCDF file for writing

nc_put_att rdb_io_netcdf Subroutine

Write a character attribute to a variable

nc_put_att_global rdb_io_netcdf Subroutine

Write a global character attribute

nc_put_att_global_int rdb_io_netcdf Subroutine

Write a global integer attribute

nc_put_att_int rdb_io_netcdf Subroutine

Write an integer attribute to a variable

nc_put_att_real rdb_io_netcdf Subroutine

Write a real-valued attribute to a variable

nc_put_att_real_r4 rdb_io_netcdf Subroutine

Write a 32-bit real attribute to a variable. NetCDF rejects a _FillValue whose type differs from the variable’s, so a variable defined with NC_R4 must have its _FillValue / missing_value written through here, not through nc_put_att_real (real64).

nc_put_var_2d rdb_io_netcdf Subroutine

Write a full 2D array

nc_put_var_3d_slice rdb_io_netcdf Subroutine

Write a 2D slice into a 3D variable at a given time index

nc_put_var_3d_slice_r4 rdb_io_netcdf Subroutine

Write a 32-bit 2D slice into a 3D variable at a given time index. The real32 twin of nc_put_var_3d_slice: handing real64 data to an NF90_FLOAT variable is legal (netcdf converts) but writes the same bytes at twice the host->library traffic, so the diag writer stages the conversion itself and calls this.

nc_put_var_4d_slice rdb_io_netcdf Subroutine

Write a 3D slice into a 4D variable at a given time index

nc_put_var_4d_slice_r4 rdb_io_netcdf Subroutine

Write a 32-bit 3D slice into a 4D variable at a given time index. The real32 twin of nc_put_var_4d_slice.

needs_flags rdb_ocean_halo Subroutine

Compute which directions need actual MPI or local-wrap work.

next_amp rdb_nml_schema Subroutine

Advance (li,col) to the character AFTER the next ‘&’. On EOF sets li = n_lines + 1. Bare non-blank tokens before ‘&’ are tolerated as inter-group whitespace.

nml_dirname rdb_config_schema Function

Directory part of path with a trailing ‘/’, or ‘’ if none.

nml_enum rdb_nml_schema Function

Construct an enum key restricted to allowed, capturing the current target as default.

Read more…
nml_int rdb_nml_schema Function

Construct an integer key, capturing the current target as default.

nml_logical rdb_nml_schema Function

Construct a logical key, capturing the current target as default.

nml_real rdb_nml_schema Function

Construct a real key, capturing the current target as default.

nml_real_array rdb_nml_schema Function

Construct a real-array key, capturing the current target as default (whole-array compare for is_default).

nml_string rdb_nml_schema Function

Construct a string key, capturing the current target as default.

nodal_fu rdb_ocean_tide_astro Subroutine

Nodal amplitude factor f_c(N) (nondim) and phase u_c(N) (radians), fixed at the nodal reference date’s N. add_nodal = .false. returns f=1, u=0 for every constituent.

nonoverlap_vanish_tol_for rdb_ocean_pressure_force Function

The grounded-layer gate’s “vanished on one side” threshold, 2·max(angstrom_h, H_VANISHED): a layer within a factor two of the floor it can rest on. The factor is the margin that keeps every floor the Lagrangian path parks a grounded layer on inside the band — the uniform_z seed’s max(angstrom_h, 2·H_VANISHED) collapse, the conservative-floor borrow’s angstrom_h (to round-off), and the positive-definite continuity’s [angstrom_h, angstrom_h + H_VANISHED] at-floor band — while staying orders of magnitude below any layer that carries real mass.

ns_rank_north rdb_ocean_halo Function

North neighbour rank with periodic wrap-around.

ns_rank_south rdb_ocean_halo Function

South neighbour rank with periodic wrap-around.

nvtx_range_pop rdb_profiler Subroutine
nvtx_range_push rdb_profiler Subroutine
nw2_cosbell rdb_ocean_state Function

Cosine-bell kernel for the Neverworld2 basin: 0.5·(1 + cos(π·min(|x/L|,1))). Peaks at 1 for x=0, decays smoothly to 0 at |x|=L. Re-derived from Marques et al. (2022, GMD) “Neverworld2”; MOM6-inspired.

nw2_spike rdb_ocean_state Function

Sin-spike kernel for the Neverworld2 basin: 1 − sin(π·min(|x/L|,0.5)). Equals 1 at x=0 and drops to 0 at |x|=L/2 (the 0.5 cap stops the sine re-ascending past its first zero). Re-derived from Marques et al. (2022, GMD); MOM6-inspired.

nz_stack_is_sufficient rdb_constants Function

.true. when the COMPILED NZ_STACK_MAX covers nz layers. Callers that get .false. must refuse the run — the overflow is a silent thread-local-storage overrun, not a crash.

nz_stack_required rdb_constants Function

Smallest NZ_STACK_MAX that safely covers a run of nz layers.

Read more…
obc_match_constituent rdb_ocean_boundary_types Function

Resolve an OBC edge constituent’s angular frequency omega (rad/s) to the tide catalog index (rdb_ocean_tide_astro::TIDE_OMEGA) whose frequency matches within the relative tolerance OBC_TIDE_MATCH_TOL. Returns 0 when no catalog entry is within tolerance (unknown constituent) or when omega <= 0 — the caller (OBC setup) converts a 0 to a fail-loud error stop, keeping this function pure.

obc_tide_nodal_fill rdb_ocean_boundary_types Subroutine

Bake the nodal/astronomical correction into one edge’s per-constituent tidal_fnodal / tidal_arg. For each of face%n_tidal_constituents, resolve the constituent by frequency (obc_match_constituent) and set tidal_fnodal(nc) = f_all(ic), tidal_arg(nc) = v_all(ic) + u_all(ic). f_all / u_all come from nodal_fu, v_all from equilibrium_arguments, all sized TIDES_CATALOG_SIZE. On an unmatched constituent it leaves that entry untouched and returns ierr = nc (the 1-based edge slot that failed) so the caller can fail loud; ierr = 0 on success. pure — no logging / no error stop.

ocean_accumulate_mass_out rdb_ocean_dyn Subroutine

Accumulate the net mass (kg) that left the domain this RK stage into ms%mass_out. flux_h_layer is the total horizontal divergence (h_layer -= dt·flux_h_layer), so -Σ_interior(−flux_h_layer)·areaT is the boundary outflux (interior faces telescope — divergence theorem), and it is the SAME field the thickness update consumes, so with the RK2 stage weight this closes the mass budget to round-off.

ocean_apply_ale_remap_centres rdb_ocean_remap Subroutine

Orchestrate the centre-cell pass of the ALE remap step (h_layer + tracers). Public only for the unit-test suite. Sequence: skip if EULERIAN_Z/LAGRANGIAN; snapshot column total + h_old; build vcoord%target_h; remap each tracer h_old→target_h via the PPM column kernel; set h_layer = target_h; recompute bt_eta = sum_k(h_layer) - bt_H_ref. Face velocities remapped separately. Takes bt_eta/bt_H_ref directly (not ocean_dyn_t) so this module sits below the split driver in the dependency tree.

ocean_apply_ale_remap_faces rdb_ocean_remap Subroutine

Face-velocity pass of the ALE remap. Remaps u_face_x_layer and v_face_y_layer h_old→h_new using arithmetic-mean face thicknesses and the per-column kernel. Public only for the unit-test suite. Velocity treated as the face “concentration” (analogous to T=hTr/h at centres); per-face conservation sum_k(h_face·u_face) preserved (momentum-conserving). Outer-wall faces take the adjacent cell’s thickness verbatim (no across-cell to average).

ocean_apply_ale_remap_step rdb_ocean_remap Subroutine

Top-level entry the driver calls between outer steps: snapshot h_old once, remap centres (h_layer + tracers) AND faces using the same snapshot, then re-derive bt_eta. Returns early for EULERIAN_Z/LAGRANGIAN. eos (optional): required ONLY for VCOORD_RHO (isopycnal density inversion). dt (optional, s): only for the grid time-filter (regrid_time_scale > 0); absent or τ=0 (default) ⇒ filter skipped, bit-identical.

ocean_apply_conservative_min_thickness rdb_ocean_min_thickness Subroutine

Apply the conservative minimum-thickness adjustment in place on ms.

Read more…
ocean_bc_outer_face_tag rdb_ocean_boundary_types Function

The tag an edge’s OUTER FACE behaves as for the no-normal-flow closures (mass-flux zeroing in the continuity, the uhbt/vhbt wall reconciliation, the lateral tracer-diffusion walls).

Read more…
ocean_bc_state_bytes rdb_ocean_boundary_types Function

Counted allocatable footprint of the boundary state slot (0 when unallocated).

ocean_bc_state_destroy rdb_ocean_boundary_types Subroutine
ocean_bc_state_enter_data rdb_ocean_boundary_types Subroutine

GPU mapping for ocean_bc_state_t.

Read more…
ocean_bc_state_exit_data rdb_ocean_boundary_types Subroutine

GPU unmapping — components first, parent last (reverse of enter_data).

ocean_bc_state_init rdb_ocean_boundary_types Subroutine

Cache grid extents and derive periodic flags. Data buffers stay unallocated until a data source asks for them. Call ocean_bc_validate_periodic after setting per-edge tags if any edge is OBC_PERIODIC; init itself only derives the convenience flags.

ocean_bc_state_set_edges rdb_ocean_boundary_types Subroutine

Set the physical-domain-edge flags from a decomposition descriptor. Called once by the driver after configure_ocean_bc so kernels can gate wall / BC / periodic closures on physical edges (a subdomain seam is never a wall), and re-derives the rank-local north_fold (the fold is applied only by the rank that owns the north edge). Default .true. keeps single-rank bit-identity.

ocean_bc_state_set_topology rdb_ocean_boundary_types Subroutine

Pre-create GRID TOPOLOGY injection (Python runtime API plan, P2.5): force per-dimension periodicity the Oceananigans way (docs/ocean_python_api_plan.md S5b) — “the grid owns periodicity”, not the per-edge &ocean_bc_nml tags. Sets periodic_x/periodic_y directly and back-fills the edge tags on every axis the caller marks periodic (both edges together, so a west/east — or south/north — mismatch is structurally unrepresentable through this entry point, unlike the namelist path which needs ocean_bc_validate_periodic to catch one). An axis the caller does NOT mark periodic is left untouched: its edge tags keep whatever physical BC configure_ocean_bc already derived from &ocean_bc_nml — periodicity is a GRID property, but the wall/open/clamped/… physics for a Bounded dimension stays the namelist’s job.

Read more…
ocean_bc_type_from_string rdb_ocean_boundary_types Function

Convert a config-namelist edge string → integer OBC tag. Case-INSENSITIVE (to_lower), so “OPEN”/”Open”/”open” all parse to OBC_OPEN. An unrecognised name returns OBC_INVALID (PR-6 fail-loud): a typo must NOT silently close the boundary to a wall. validate_config rejects OBC_INVALID (naming the edge) before configure_ocean_bc consumes any parse result, so no production caller ever sees the sentinel at a live edge.

ocean_bc_validate_fold rdb_ocean_boundary_types Subroutine

Validate the tripolar north-fold tag. Call after all per-edge tags are set and after ocean_bc_state_init. Refreshes north_fold and stops with a diagnostic if any rule fails.

Read more…
ocean_bc_validate_periodic rdb_ocean_boundary_types Subroutine

Validate periodic pairing + ghost-width + sponge incompatibility. Call after all per-edge tags are set and after ocean_bc_state_init. Derives periodic_x / periodic_y from the final tags and stops with a diagnostic message if any rule is violated.

Read more…
ocean_bdrag_destroy rdb_ocean_bottom_drag Subroutine
ocean_bdrag_enter_data rdb_ocean_bottom_drag Subroutine
ocean_bdrag_enter_data_impl rdb_ocean_bottom_drag Subroutine
ocean_bdrag_exit_data rdb_ocean_bottom_drag Subroutine
ocean_bdrag_exit_data_impl rdb_ocean_bottom_drag Subroutine
ocean_bdrag_init rdb_ocean_bottom_drag Subroutine
ocean_bottom_drag_apply_tendencies rdb_ocean_bottom_drag Subroutine

no_wait (optional, default .false.): when .true. the apply DC loops run on OpenACC queue 1 and the routine returns WITHOUT syncing, so the batched velocity-apply chain in run_stage_split !$acc wait(1)s ONCE. Default ⇒ blocking (safe for the unsplit run_stage). Not pure because of the async/wait directives.

ocean_bottom_drag_bytes rdb_ocean_bottom_drag Function

Counted allocatable footprint of the bottom drag slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_bottom_drag_compute_tendencies rdb_ocean_bottom_drag Subroutine

Fill du_drag / dv_drag with the bottom-layer drag acceleration on each face’s first LIVE layer k_bot_u/v (≡ 1 off z_fixed); every other layer gets zero in the bed-only mode (default). When hbbl > 0 the stress is distributed across the bottom-most hbbl metres — every layer with cumulative_depth_from_bed_top ≤ hbbl gets a proportional share of the drag tendency.

Read more…
ocean_bt_forcing_visc_rem_on rdb_config Function

PR-3 (D1): is the MOM6 wt_u BT-forcing weight on, either directly (forcing_visc_rem) or via visc_rem_chain?

ocean_bt_rem_from_visc_rem_on rdb_config Function

PR-3 (D1): is bt_rem built from av_rem (MOM6’s barotropic viscous-remnant depth mean) on, either directly (bt_rem_from_visc_rem) or via visc_rem_chain?

ocean_bt_renorm_visc_rem_on rdb_config Function

PR-3 (D1): is the MOM6 continuity u_cor = u + du*visc_rem transport-matching renormaliser on, either directly (renorm_visc_rem) or via visc_rem_chain?

ocean_bt_visc_rem_producer_on rdb_config Function

D1 follow-up: is the visc_rem PRODUCER needed, independent of the (retired) weighted BT-correction fold? .true. whenever ANY real consumer is on — forcing_visc_rem/renorm_visc_rem/ bt_rem_from_visc_rem (each already .or.-ed with visc_rem_chain by their own helper) — or the legacy correction_visc_rem field itself, so a test that constructs cfg directly and sets that field alone (bypassing the nml retirement check) still gets a live producer. This is what configure_ocean_bt wires into bt_work%bt_visc_rem_producer, which vmix_apply_in_stage’s do_remnant reads — NOT bt_work%bt_correction_visc_rem, which now drives ONLY the weighted-fold dispatch in apply_bt_correction (and is never set by visc_rem_chain).

ocean_budget_is_active rdb_ocean_console_stats Function

Whether a tracer’s closed budget (out/src residual) should be reported. .true. iff the tracer is registered (tracer_idx > 0) AND the horizontal-advection accumulator is complete AND no un-instrumented interior source is active.

Read more…
ocean_budget_out rdb_ocean_console_stats Function

Console out term for a conserved tracer: the boundary transport out of the domain, from the horizontal-advection + horizontal- diffusion budgets.

Read more…
ocean_budget_src rdb_ocean_console_stats Function

Console src term for a conserved tracer: the surface (+ any other source, e.g. geothermal) contribution to the outer-step budget.

Read more…
ocean_budget_stage_weight rdb_ocean_console_stats Function

The per-outer-step weight that turns the salt/heat budget ACCUMULATORS into the state change they must account for.

Read more…
ocean_budgets_bytes rdb_ocean_budgets Function

Counted allocatable footprint of the conservation budgets (own accumulator; registry contributors are counted by their owning slot) slot (0 when unallocated).

ocean_budgets_destroy rdb_ocean_budgets Subroutine
ocean_budgets_drain_contributors rdb_ocean_budgets Subroutine

For each contributor: integrate per_cell·mask·areaT (over k) into total_integrated, then zero per_cell for the next window.

ocean_budgets_evaluate rdb_ocean_budgets Subroutine

Recompute this%values(:) from the current multilayer state. Honours this%mask — sums are weighted by mask%weight · areaT.

ocean_budgets_init rdb_ocean_budgets Subroutine
ocean_budgets_init_snapshot rdb_ocean_budgets Subroutine

Snapshot values_init from the current state. Call once after the IC is set + the EOS has run, before stepping.

ocean_budgets_register_contributor rdb_ocean_budgets Subroutine

Register a per-kernel contributor: store a non-owning pointer to the kernel-owned per_cell + metadata. Set device_resident when per_cell is GPU-mapped (drain syncs it). Idempotent on name (re-registering updates the pointer, resets the integral).

ocean_budgets_set_area rdb_ocean_budgets Subroutine

Cache the per-cell T-area (m²) from the metrics slot. After this, physical integrals weight by mask%weight·areaT; before it they fall back to grid%dx·grid%dy (= areaT on uniform Cartesian).

ocean_budgets_set_mask rdb_ocean_budgets Subroutine

Override the default global mask. Useful for regional conservation diagnostics — “mass north of 30°S stays at FP.”

ocean_cavity_flux_bytes rdb_ocean_cavity_flux Function

Counted allocatable footprint (0 when unallocated). One arr_bytes term per array — add one here when an array joins the type.

ocean_cavity_flux_destroy rdb_ocean_cavity_flux Subroutine

Release the slot. is_init is cleared FIRST.

ocean_cavity_flux_enter_data rdb_ocean_cavity_flux Subroutine

Type-bound wrapper — delegates to the non-polymorphic impl so the device-attach map base is the heap object, not a polymorphic stack box.

ocean_cavity_flux_enter_data_impl rdb_ocean_cavity_flux Subroutine

copyin (not create) throughout: f_cor carries a configure-time host fill that MUST reach the device, and the rest carry the zero init promised on both toolchains.

ocean_cavity_flux_exit_data rdb_ocean_cavity_flux Subroutine
ocean_cavity_flux_exit_data_impl rdb_ocean_cavity_flux Subroutine
ocean_cavity_flux_init rdb_ocean_cavity_flux Subroutine

Allocate the slot. Gated on enable (latched by ocean_state_init_from_config before this runs), so a run without a cavity pays fourteen (1,1) placeholders.

ocean_cavity_flux_step rdb_ocean_cavity_flux Subroutine

One cavity basal-melt update: sample the far field, solve the three-equation interface on every covered column, deliver the two owned surface-flux components, and account for the solver status.

Read more…
ocean_cavity_mass_step rdb_ocean_cavity_flux Subroutine

The real-freshwater MASS update — one call, at the THERMO cadence, from inside the RK2 stage immediately after ocean_surface_flux_apply_tracers.

Read more…
ocean_channel_drag_apply_tendencies rdb_ocean_bottom_drag Subroutine

Apply the per-layer side drag IMPLICITLY: u <- u / (1 + dt·lambda_side_u), v <- v / (1 + dt·lambda_side_v). The implicit (backward-Euler) form is unconditionally stable on thin layers where an explicit u - dt·lambda·u would overshoot. lambda ≡ 0 (default-off / all-wet / flat-bottom) ⇒ division by 1 ⇒ exact no-op. no_wait semantics mirror ocean_bottom_drag_apply_tendencies. Not pure (async/wait).

ocean_channel_drag_compute_tendencies rdb_ocean_bottom_drag Subroutine

Per-layer lateral side-wall (channel) Rayleigh RATE (lambda_side_u/v, 1/s) for every velocity face whose cross-stream perimeter is partially blocked by land or a vanished (sloping-bathymetry) neighbour layer — fires at EVERY layer k that intersects the obstruction, not just the bed. f_blocked = perimeter fraction blocked, summed over the two flanking wet_q corners (each weighted 0.5), with a corner also counted blocked when its two cross-stream cells’ min h_layer < SIDE_H_VANISH. lambda = cdrag_side·|U_face|·f_blocked/max(W, eps), W the cross-stream face length (dyCu u-face, dxCv v-face). All-wet / flat-bottom ⇒ f_blocked ≡ 0 ⇒ lambda ≡ 0 (no-op); channel_drag=.false. or cdrag_side=0 short-circuits to zero.

ocean_console_stats_report rdb_ocean_console_stats Subroutine

Compute current totals + means + max-CFL and emit a MOM6-style console block via the shared console_stats_report formatter.

Read more…
ocean_data_forcing_apply rdb_ocean_data_forcing Subroutine

Blend every active tag’s current bracket into its slot. t must be the same model time ocean_data_input_update_all was just called with — the reader enforces this and aborts otherwise.

Read more…
ocean_data_forcing_configure rdb_ocean_data_forcing Subroutine

Register every configured tag against the shared reader and resolve the heat/salt destinations. A no-op when enable = .false. — nothing registers, so ocean_data_input_update_all stays a no-op and the run is bit-identical.

ocean_data_input_bytes rdb_ocean_data_input Function

Counted allocatable footprint (0 when unallocated). Summed over every registered field’s f0/f1 — the t_axis is small (nt reals) and intentionally excluded, matching the house convention of counting device-resident footprint only.

ocean_data_input_destroy rdb_ocean_data_input Subroutine
ocean_data_input_enter_data rdb_ocean_data_input Subroutine

Type-bound wrapper — delegates to the non-polymorphic impl (the AMD libomptarget cross-slot-overlap fix; see rdb_ocean_surface_stress.F90).

ocean_data_input_enter_data_impl rdb_ocean_data_input Subroutine
ocean_data_input_exit_data rdb_ocean_data_input Subroutine
ocean_data_input_exit_data_impl rdb_ocean_data_input Subroutine
ocean_data_input_fill_static_host rdb_ocean_data_input Subroutine

One-shot HOST-side fill of a DATA_TIME_STATIC field. Copies the already-read record-1 slab into dest at the registration-time offsets. Touches NO device memory — callable at setup, before dest is mapped. Plain host do loops (NOT do concurrent — on -stdpar=gpu a bare do concurrent is unconditionally offloaded regardless of whether dest is mapped, which is exactly the silent-stale-write bug this routine exists to avoid). Fails loud for any non-static field.

ocean_data_input_fill_static_host_3d rdb_ocean_data_input Subroutine

3-D twin of fill_static_host.

ocean_data_input_init rdb_ocean_data_input Subroutine

Allocate the field registry. cfg optional so ocean_state_init (which many tests call directly with no config_t in hand) can construct a default-sized (16 slots, quiet) reader identically to the scaffold it replaces; ocean_state_init_from_config re-calls this with the real cfg%ocean%data once cfg is available — safe because nothing is registered between the two calls.

ocean_data_input_load_static_2d rdb_ocean_data_input Subroutine

One-shot STATIC 2-D read: register, fill, close. The setup-time convenience wrapper over register_2d(time_mode="static") + fill_static_host for a field that is read ONCE and never updated — a prescribed, time-constant geometry rather than a forcing. &ocean_cavity_dyn_nml draft_config="file" is the first consumer.

Read more…
ocean_data_input_register_2d rdb_ocean_data_input Subroutine

Register a 2-D time-varying field f(x, y, t). Opens the file now and keeps the handle for the run. See the module docstring for the destination-offset contract.

Read more…
ocean_data_input_register_3d rdb_ocean_data_input Subroutine

Register a 3-D time-varying field f(x, y, z, t). nz_src is the source z-level count (the consumer’s own concern — the reader validates it against the file’s z dim and does NOT flip or remap k; see the module docstring).

ocean_data_input_register_segment_2d rdb_ocean_data_input Subroutine

Register a 2-D OBC-segment field. The degenerate horizontal axis (x for west/east, y for south/north) reads as start=1, count=1; the along-edge axis slices from the global index range exactly as register_2d does. dest_i0/dest_j0 are implied by edge (degenerate axis -> index 1; along-edge axis -> grid%nghost + 1) — not arguments (see module docstring).

ocean_data_input_register_segment_3d rdb_ocean_data_input Subroutine

3-D twin of register_segment_2d (PR-22 OBC segment files).

ocean_data_input_update_2d rdb_ocean_data_input Subroutine

Blend field id’s current bracket into the caller’s WHOLE, device-mapped dest(n1, n2) array at the registration-time offset. t must equal the value update_all most recently refreshed this field with (fail-loud ordering check — a consumer calling this before update_all has run for the current step is a real bug, not a silent stale read). Exempt for DATA_TIME_STATIC fields, whose bracket never changes.

ocean_data_input_update_3d rdb_ocean_data_input Subroutine

3-D twin of update_2d.

ocean_data_input_update_all rdb_ocean_data_input Subroutine

Driver hook: refresh every registered field’s bracket for model time t (reading + pushing a new slab to the device only when the bracket actually advances). No-op when nfields == 0 — every shipped namelist today. Does NOT write into any consumer array (see module docstring) — call update_2d/_3d afterwards for that.

ocean_diag_bytes rdb_ocean_diag Function

Counted allocatable footprint of the diagnostics slot: the flat remap-level arrays, the host NetCDF staging buffer, AND the per-variable registry buffers (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type; new diag_var_t buffers go in diag_var_bytes.

ocean_diag_destroy rdb_ocean_diag Subroutine
ocean_diag_disable rdb_ocean_diag Subroutine

Turn OFF the registered diagnostic name so the dispatcher skips it entirely (no fill, no fold, no emit). Fail-loud if name matches no registered var — a typo must not silently leave a diagnostic running. Lists the registered names on abort.

ocean_diag_enter_data rdb_ocean_diag Subroutine

Attach each registered var’s per-buffer allocatables to the device. Called by ocean_state_enter_data after register_default_diags has populated vars(:) — buffers are sized at register time, so the descriptors here are valid.

Read more…
ocean_diag_enter_data_impl rdb_ocean_diag Subroutine
ocean_diag_exit_data rdb_ocean_diag Subroutine

Detach in reverse order of enter_data. Idempotency-safe via is_init gate — repeated calls without intervening enter_data become no-ops once the manager is destroyed.

ocean_diag_exit_data_impl rdb_ocean_diag Subroutine
ocean_diag_init rdb_ocean_diag Subroutine

Allocate an empty registry sized at INITIAL_CAPACITY slots. Subsequent register calls grow the array via doubling.

ocean_diag_is_registered rdb_ocean_diag Function

.true. iff a diagnostic named name is registered (enabled or not). Registration state only — says nothing about whether it will actually fire (see enabled); a disabled diagnostic is still registered and this returns .true. for it.

ocean_diag_register rdb_ocean_diag Subroutine

Register a new diagnostic variable. Grows the registry via capacity doubling on overflow. Buffer allocation depends on output_vgrid: * LAYER (default): one output_buffer(n1, n2, n3) — fill writes directly into it. * Z_FIXED (or any non-LAYER target): two buffers — layer_buffer(n1, n2, n3) for the fill, plus output_buffer(n1, n2, this%nz_out) for the remapped result. Caller must have configured nz_out via set_output_z_levels first, and bind a remap proc. Caller binds fill to a routine that knows how to populate the layer-native buffer from the state handle.

Read more…
ocean_diag_set_output_density_levels rdb_ocean_diag Subroutine

Configure the isopycnal (DENSITY) output grid — monotone-increasing target potential densities (kg/m³). Stored copy; must be called BEFORE any register with output_vgrid == DIAG_VGRID_DENSITY so the manager knows the output buffer shape (one cell per target).

ocean_diag_set_output_sigma_levels rdb_ocean_diag Subroutine

Configure the terrain-following (SIGMA) output grid — cumulative sigma fractions (0..1, monotone shallow->deep). Stored copy; must be called BEFORE any register with output_vgrid == DIAG_VGRID_SIGMA so the manager knows the output buffer shape.

ocean_diag_set_output_z_levels rdb_ocean_diag Subroutine

Configure the fixed-z output grid. Stored copy; the original z array is not retained. Must be called BEFORE any register with output_vgrid == DIAG_VGRID_Z_FIXED so the manager knows the output buffer shape.

ocean_diag_set_output_zstar_levels rdb_ocean_diag Subroutine

Configure the SSH-tracking (ZSTAR) output grid — reference interface depths (m, positive-down, monotone shallow->deep; deepest = H_ref). Stored copy; must be called BEFORE any register with output_vgrid == DIAG_VGRID_ZSTAR so the manager knows the buffer shape.

ocean_diag_step rdb_ocean_diag Subroutine

Advance every registered variable. Behaviour by time_op:

Read more…
ocean_diffusive_number rdb_ocean_stability_audit Function

Two-axis explicit forward-Euler diffusive number kappa_h*dt_therm*(1/dx_min^2+1/dy_min^2), conservatively evaluated at the SAME worst-case dx_min on both axes (matches the “use the minimum cell” instruction; exact on an isotropic worst cell, strictly more conservative than using the true per-axis pair). dx_min<=0 returns 0.

ocean_diffusive_number_limit rdb_ocean_stability_audit Function

Accessor for DIFFUSIVE_NUMBER_LIMIT.

ocean_dt_tracer_advect_ratios_ok rdb_ocean_dyn Function

Configure-time validity of the (dt_therm_ratio, dt_tracer_advect_ratio) pair. Both must be >= 1 and dt_therm_ratio must be an integer multiple of dt_tracer_advect_ratio so the ALE remap (which fires at the DT_THERM cadence) never lands inside an open tracer-flux accumulation window. The setup layer (configure_ocean_vmix) calls this and error stops with a descriptive message on .false.; exposed as a pure predicate so the validation logic is unit-testable without constructing a full ocean state.

ocean_dyn_bytes rdb_ocean_dyn Function

Counted allocatable footprint of the split-RK2 driver (BT work state + wide-halo shadow state) slot (0 when unallocated).

ocean_dyn_destroy rdb_ocean_dyn Subroutine
ocean_dyn_enable_bt_wide rdb_ocean_dyn Subroutine

Allocate, initialise, and GPU-attach the wide-halo shadow state from dyn%bt_halo (already set by the caller).

Read more…
ocean_dyn_enter_data rdb_ocean_dyn Subroutine
ocean_dyn_enter_data_impl rdb_ocean_dyn Subroutine
ocean_dyn_exit_data rdb_ocean_dyn Subroutine
ocean_dyn_exit_data_impl rdb_ocean_dyn Subroutine
ocean_dyn_flush_tracer_window rdb_ocean_dyn Subroutine

Mandatory end-of-segment flush of the windowed tracer-advect accumulators (spec §(c) — MOM6’s n == n_max). Drains any OPEN accumulation window (t_dyn_rel_adv > 0) so no Lagrangian-advanced h_layer is ever paired with FROZEN hTr at an output write, a restart checkpoint, or the end of a run segment whose length is not an exact multiple of dt_tracer_advect_ratio.

Read more…
ocean_dyn_init rdb_ocean_dyn Subroutine

Initialise the barotropic working-state slot. Pass nz_ml to also allocate the split-driver slow-tendency accumulators (F_slow_u/v, F_bt_u/v, ubt_at_n/vbt_at_n). Barotropic-substep unit tests can skip the optional argument since they don’t exercise the split-driver coupling.

ocean_dyn_is_thermo_step rdb_ocean_dyn Function

Returns .true. if the thermodynamic / tracer kernels should fire on this outer step. dt_therm_ratio <= 1 (default) → always true (every step is a thermo step, bit-identical to prior behaviour). ratio >= 2 → fires every Nth step, aligned to outer_step_count = 0 for the IC snapshot.

ocean_dyn_is_tracer_advect_step rdb_ocean_dyn Function

Returns .true. when the windowed horizontal tracer-advect drain should fire on the current outer step, evaluated with the PRE-increment outer_step_count so it aligns bit-for-bit with is_thermo_step() (which gates the ALE remap on the same count).

Read more…
ocean_dyn_step rdb_ocean_dyn Subroutine

Multilayer extension of ocean_dyn_step_barotropic. One SSP-RK2 outer step that orchestrates the full per-layer dynamical core:

Read more…
ocean_dyn_step_barotropic rdb_ocean_dyn Subroutine

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Unsplit SSP-RK2 (Heun’s method) outer step on the barotropic C-grid state. Couples continuity-PPM (h-update) and the Sadourny Coriolis-advection tendency (u, v update) into one second-order-accurate step.

Read more…
ocean_dyn_step_split rdb_ocean_dyn Subroutine

Split-explicit SSP-RK2 outer step on the multilayer state. Parallel to ocean_dyn_step (the unsplit driver still ships for tests + reference). Phase 4b-MVP scope: gravity-wave-stability fix on momentum only. ALE-aware h_layer redistribution and full nonlinear-bt corrections are deferred to a follow-up branch.

Read more…
ocean_dyn_therm_dt rdb_ocean_dyn Function

Effective dt for the thermo / tracer kernels. When dt_therm_ratio = 1 returns dt exactly; otherwise returns ratio · dt, since the kernels only fire every Nth step and must advance by that aggregate interval.

ocean_eos_compute rdb_ocean_eos_compute Subroutine

Compute ms%rho_layer from the registered (T, S) tracers. Outer-shim pattern: pulls the tracer hTr arrays off the registry on the host and forwards them as bare 3D arrays to a flat-impl chosen by eos%variant.

Read more…
ocean_epbl_bytes rdb_ocean_epbl Function

Counted allocatable footprint of the EPBL slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_epbl_destroy rdb_ocean_epbl Subroutine
ocean_epbl_enter_data rdb_ocean_epbl Subroutine
ocean_epbl_enter_data_impl rdb_ocean_epbl Subroutine
ocean_epbl_exit_data rdb_ocean_epbl Subroutine
ocean_epbl_exit_data_impl rdb_ocean_epbl Subroutine
ocean_epbl_init rdb_ocean_epbl Subroutine

Allocate the persistent fields + column workspaces. Always allocates (configure runs after init, so enable isn’t known yet); the memory cost when off is the same 7-field footprint the vmix slot already pays.

ocean_epbl_set_f_centre rdb_ocean_epbl Subroutine

Fill f_centre with the beta-plane Coriolis magnitude at cell centres: |f_0 + beta*(y - y_ref)|. Mirror of coriolis_adv_set_beta_plane (which fills corners). Call after init, before enter_data.

ocean_fold_begin rdb_ocean_fold_exchange Subroutine

Open a group of nslab (rows x layers) slabs in total (an upper bound is fine). Grows the buffers, with a warning, if the run did not reserve enough. No-op when inactive.

ocean_fold_end rdb_ocean_fold_exchange Subroutine

Close the group: every packed slab must have been unpacked.

ocean_fold_exchange rdb_ocean_fold_exchange Subroutine

Move every packed message: one isend + irecv per non-self peer with a non-empty message, the self pair as a local copy, then waitall. Collective over the north rank row.

ocean_fold_exchange_destroy rdb_ocean_fold_exchange Subroutine

Release the plan, buffers and topology. Idempotent.

ocean_fold_exchange_init rdb_ocean_fold_exchange Subroutine

Record the topology and, on a north-row rank of an east-west split folded grid, build the routing plan and map it to the device. Every rank may call it (it is not collective); a rank that does not fold, or a px = 1 run, keeps the exchange inactive.

ocean_fold_exchange_reserve rdb_ocean_fold_exchange Subroutine

Pre-size the buffers for the largest group of the run, in (row x layer) slabs summed over its fields — e.g. the ml_state group is (3 + ntracer)*nz fields of at most ng+1 rows — so no device reallocation fires mid-run. No-op when inactive or already large enough.

ocean_fold_is_distributed rdb_ocean_fold_exchange Function

True iff this rank folds through the exchange (px > 1 and a folded north edge on this rank). False on every px = 1 run and on ranks off the north row.

ocean_fold_north_centre rdb_ocean_fold_exchange Interface
ocean_fold_north_corner rdb_ocean_fold_exchange Interface
ocean_fold_north_u_face rdb_ocean_fold_exchange Interface
ocean_fold_north_v_face rdb_ocean_fold_exchange Interface
ocean_fold_pack rdb_ocean_fold_exchange Interface
ocean_fold_pack_2d rdb_ocean_fold_exchange Subroutine

Pack a 2D field of storage shape (nxa, nya) into the open group.

ocean_fold_pack_3d rdb_ocean_fold_exchange Subroutine

Pack every layer of a 3D field into the open group: the sender’s owned mirror-source points, rows below (and, for v / corner, on) the fold line.

ocean_fold_unpack rdb_ocean_fold_exchange Interface
ocean_fold_unpack_2d rdb_ocean_fold_exchange Subroutine

Unpack the next field of the exchanged group into a 2D field.

ocean_fold_unpack_3d rdb_ocean_fold_exchange Subroutine

Unpack the next field of the exchanged group: write every north ghost row (all storage columns) and, for v / corner, the fold-line row’s west half (self-conjugate column → 0 for a vector).

ocean_fold_wrap_centre_3d_state rdb_ocean_fold_apply Subroutine

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.

ocean_fold_wrap_centre_flat rdb_ocean_fold_apply Subroutine

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..

ocean_fold_wrap_eta_2d rdb_ocean_fold_apply Subroutine

Fold a 2D cell-centred η field (driver-level SSH wrap site). No-op when not folding.

ocean_fold_wrap_state rdb_ocean_fold_apply Subroutine

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.

ocean_fold_wrap_stress rdb_ocean_fold_apply Subroutine

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.

ocean_fold_wrap_time_means rdb_ocean_fold_apply Subroutine

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.

ocean_fold_wrap_visc_rem rdb_ocean_fold_apply Subroutine

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.

ocean_frazil_heat_src rdb_ocean_console_stats Function

Console src term for the sea-ice frazil clamp (PR 1): the heat the clamp ADDS to the ocean warming the supercooled surface layer up to T_f (the matching deficit is banked on ice%frazil_heat).

Read more…
ocean_geothermal_apply_tracers rdb_ocean_geothermal Subroutine

Add the geothermal bottom heat flux to the lowest massive tracer layer. Operates in hTr space (concentration thickness): d(hT_{k=1})/dt = Q_geo / (rho0 * cp) (units (W/m^2)/(kg/m^3 * J/kg/K) = Km/s, matching hTr).

Read more…
ocean_geothermal_destroy rdb_ocean_geothermal Subroutine

No-op shell mirroring the surface-flux destroy.

ocean_geothermal_init rdb_ocean_geothermal Subroutine

No-op shell mirroring the surface-flux init; sets is_init.

ocean_gm_bytes rdb_ocean_gm Function

Counted allocatable footprint of the GM slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_gm_destroy rdb_ocean_gm Subroutine
ocean_gm_enter_data rdb_ocean_gm Subroutine
ocean_gm_enter_data_impl rdb_ocean_gm Subroutine
ocean_gm_exit_data rdb_ocean_gm Subroutine
ocean_gm_exit_data_impl rdb_ocean_gm Subroutine
ocean_gm_init rdb_ocean_gm Subroutine

Allocate the 2D face KhTh fields, per-layer face transports, and the gm_src PE-release diagnostic. Always allocates (configure runs after init); host allocation (no do concurrent before enter_data).

ocean_halo_bt_group_2d rdb_ocean_halo Subroutine

Single-call two-pass exchange of three barotropic fields. Calls the three individual 2D exchanges in order, which each run their own full two-pass X-then-Y exchange.

ocean_halo_bt_group_2d_wide rdb_ocean_halo Subroutine

Width-parameterized grouped barotropic exchange (eta+ubt+vbt). Bumps oh_count_bt_group; suppresses the three inner primitive counters exactly as ocean_halo_bt_group_2d does.

ocean_halo_buffers_ensure_nz rdb_ocean_halo Subroutine

Grow the persistent send/recv buffers to hold at least nz layers. Called at the top of each 3D exchange routine before pack/unpack. The 2D routines use the same buffers and always need <= any 3D capacity, so they are unaffected.

Read more…
ocean_halo_buffers_ensure_wide rdb_ocean_halo Subroutine

Grow the persistent send/recv buffers to hold at least a wide 2D exchange at ghost width ng_wide. Uses the same exit-delete / dealloc / alloc / enter-create pattern as ocean_halo_buffers_ensure_nz. Safe to call with ng_wide == oh_nghost (no-op if already large enough).

ocean_halo_centre rdb_ocean_halo Interface
ocean_halo_centre_2d rdb_ocean_halo Subroutine

Two-pass X-then-Y halo exchange for a cell-centred 2D field.

ocean_halo_centre_2d_impl rdb_ocean_halo Subroutine

Two-pass X-then-Y halo exchange for a cell-centred 2D field. Core body shared by ocean_halo_centre_2d (ng=oh_nghost) and ocean_halo_centre_2d_wide (ng=ng_wide).

ocean_halo_centre_2d_wide rdb_ocean_halo Subroutine

Width-parameterized centre-2D halo exchange. Identical algorithm to ocean_halo_centre_2d but operates on a wider ghost band ng_wide (>= oh_nghost). Fail-loud guards prevent ng_wide from exceeding the neighbour interior.

ocean_halo_centre_3d rdb_ocean_halo Subroutine

Two-pass X-then-Y halo exchange for a cell-centred 3D field. Batched: packs ALL nz layers into one buffer per direction and posts ONE isend+irecv pair per needed direction (not per layer). Buffer index formula: ((L-1)rows + (row-1))width + k_within_strip where L=layer, rows=nyt, width=ng (centre X-pass).

ocean_halo_destroy rdb_ocean_halo Subroutine

Release buffers and topology state. Idempotent.

ocean_halo_exchange_ice_fluxes rdb_ocean_halo_state Subroutine

Seam ghosts of the three per-cell ice->ocean flux diagnostics the couplers hand to the ocean — salt_flux_diag, heat_flux_diag, sw_thru_diag — one two-pass centre exchange each.

Read more…
ocean_halo_exchange_ice_state rdb_ocean_halo_state Subroutine

Make the sea-ice CATEGORY state valid in every ghost cell (X1 of the sea-ice MPI plan): part_size, m_ice, m_snow, enth_ice, sal_ice, enth_snow, one two-pass centre exchange each, all categories (and ice layers) in one message per direction, THEN the tripolar north fold of each (added with the fold-seam fix below).

Read more…
ocean_halo_exchange_ice_transport rdb_ocean_halo_state Subroutine

X4 of the sea-ice MPI plan: the seam ghosts every advective substep of ice_transport_step reads — the cell-averaged category masses mca_ice/mca_snow (the PPM donors, 5-point stencil) and the riding intensive tracers m_ice, enth_ice, sal_ice, enth_snow (the PCM donors). mca_* ghosts are zeroed by the IST->CAS conversion and the ride/mass updates leave the ghost band one substep old, so this runs at the top of EVERY substep. On one rank with a periodic axis the primitives wrap. Also carries the tripolar north fold of the same six fields (plain-copy scalar contract) — without it the fold-seam row’s advective stencil read a stale/unrelated mirror cell every substep, which is how ice piled up without bound on that row.

ocean_halo_exchange_ml_state rdb_ocean_halo_state Subroutine

Exchange ghost cells for the four multilayer prognostic field kinds via the O1 halo primitives:

Read more…
ocean_halo_face_x rdb_ocean_halo Interface
ocean_halo_face_x_2d rdb_ocean_halo Subroutine

Two-pass X-then-Y halo exchange for a 2D x-face field.

Read more…
ocean_halo_face_x_2d_impl rdb_ocean_halo Subroutine

Two-pass X-then-Y halo exchange for a 2D x-face field. Core body shared by ocean_halo_face_x_2d (ng=oh_nghost) and ocean_halo_face_x_2d_wide (ng=ng_wide).

ocean_halo_face_x_2d_wide rdb_ocean_halo Subroutine

Width-parameterized face-x-2D halo exchange.

ocean_halo_face_x_3d rdb_ocean_halo Subroutine

Two-pass X-then-Y halo exchange for a 3D x-face field. Batched: packs ALL nz layers into one buffer per direction. Face-x ownership: west rank sends (ng+1)nytnz eastward, east rank sends ngnytnz westward (D1 asymmetry preserved). Y-pass strip is nxt1ngnz (full face-x i extent × ng rows × nz).

ocean_halo_face_y rdb_ocean_halo Interface
ocean_halo_face_y_2d rdb_ocean_halo Subroutine

Two-pass X-then-Y halo exchange for a 2D y-face field. Symmetric to face_x_2d with i↔j, x↔y.

Read more…
ocean_halo_face_y_2d_impl rdb_ocean_halo Subroutine

Two-pass X-then-Y halo exchange for a 2D y-face field. Core body shared by ocean_halo_face_y_2d (ng=oh_nghost) and ocean_halo_face_y_2d_wide (ng=ng_wide).

ocean_halo_face_y_2d_wide rdb_ocean_halo Subroutine

Width-parameterized face-y-2D halo exchange.

ocean_halo_face_y_3d rdb_ocean_halo Subroutine

Two-pass X-then-Y halo exchange for a 3D y-face field. Batched: packs ALL nz layers into one buffer per direction. Face-y ownership (D1): south rank sends (ng+1)nxtnz northward, north rank sends ngnxtnz southward. X-pass uses standard centre-style (ng per column per layer over nyt1 rows).

ocean_halo_init rdb_ocean_halo Subroutine

Initialise topology and allocate persistent device-resident buffers. Idempotent: destroys prior state before re-init on grid change.

ocean_halo_is_decomposed rdb_ocean_halo Function

True iff a genuine multi-rank seam exists (initialised, px>1 or py>1).

ocean_halo_is_decomposed_x rdb_ocean_halo Function

True iff the X axis is split across ranks (px>1); skip the local x wrap.

ocean_halo_is_decomposed_y rdb_ocean_halo Function

Y analogue of ocean_halo_is_decomposed_x (py>1).

ocean_halo_is_init rdb_ocean_halo Function

True if ocean_halo_init has been called and not yet destroyed.

ocean_halo_reserve rdb_ocean_halo Subroutine

Pre-size the pack/recv buffers to the worst-case capacity for this run at init time, so that NO device reallocation fires mid-run.

Read more…
ocean_handle_refresh_host rdb_ocean_api Subroutine

Lazy D->H refresh of every P2-exposed leaf array, gated on h%host_is_current. !$acc update self on LEAF component names only, via associate — never the aggregate ocean_state_t/ sub-state derived type (rdb_ocean_dyn.F90:2949). Inert on a host-only build.

ocean_hdiff_tracer_bytes rdb_ocean_hdiff_tracer Function

Counted allocatable footprint of the horizontal tracer diffusion slot (0 when unallocated).

ocean_hdiff_tracer_destroy rdb_ocean_hdiff_tracer Subroutine
ocean_hdiff_tracer_enter_data rdb_ocean_hdiff_tracer Subroutine
ocean_hdiff_tracer_enter_data_impl rdb_ocean_hdiff_tracer Subroutine
ocean_hdiff_tracer_exit_data rdb_ocean_hdiff_tracer Subroutine
ocean_hdiff_tracer_exit_data_impl rdb_ocean_hdiff_tracer Subroutine
ocean_hdiff_tracer_init rdb_ocean_hdiff_tracer Subroutine
ocean_heat_src_sum rdb_ocean_console_stats Function

Assemble the total HEAT source integral (pre-weight, pre-ρ) that feeds ocean_budget_src: surface flux + geothermal bottom flux + (PR-23) the map-driven sponge’s tracer-relaxation source.

Read more…
ocean_horizontal_viscosity_apply_tendencies rdb_ocean_horizontal_viscosity Subroutine

Forward-Euler accumulation of the viscous tendency onto the face velocities. Shim — hoists this%du_visc%data etc. to the host before dispatching to the flat-impl. Explicit shape dimensions are derived from ms here and passed as scalar args. no_wait (optional, default .false.): forwarded to the impl — when .true. the apply DC loops run on OpenACC queue 1 and the routine returns WITHOUT syncing, so the batched velocity-apply chain in run_stage_split !$acc wait(1)s ONCE. Default ⇒ blocking. Not pure because of the async/wait directives.

ocean_horizontal_viscosity_bytes rdb_ocean_horizontal_viscosity Function

Counted allocatable footprint of the horizontal viscosity slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_horizontal_viscosity_compute_ke_diss rdb_ocean_horizontal_viscosity Subroutine

Fill this%ke_diss with the lateral-viscosity KE dissipation rate Σ_k ρ_k h_k (u·du_visc + v·dv_visc) at T-cell centres (kg/s³; ≤0 where the viscosity removes KE). MUST run AFTER compute_tendencies (du_visc fresh) and BEFORE the viscous apply, while u_face/v_face still hold the velocity the viscosity acted on. No-op (and bit-identical) unless compute_ke_diss is set and the density field is live. Feeds the MEKE frictional source.

ocean_horizontal_viscosity_compute_tendencies rdb_ocean_horizontal_viscosity Subroutine

Source-selecting shim over ocean_horizontal_viscosity_compute_tendencies_on: absent u_src/v_src/h_src (all callers today) forwards the prognostic components — bit-identical; the pred_corr driver passes the u_av time-mean family (SPEC §4 S3).

ocean_horizontal_viscosity_compute_tendencies_on rdb_ocean_horizontal_viscosity Subroutine

Fill du_visc and dv_visc with nu_h * Laplacian of the face velocities, per layer. Closed-wall faces (i=1, i=nx+1 for u; j=1, j=ny+1 for v) get zero tendency. Interior y- boundary rows on u (j=1, j=ny) and interior x-boundary columns on v (i=1, i=nx) also get zero — equivalent to a free-slip wall condition on the tangential velocity.

Read more…
ocean_hvisc_destroy rdb_ocean_horizontal_viscosity Subroutine
ocean_hvisc_enter_data rdb_ocean_horizontal_viscosity Subroutine
ocean_hvisc_enter_data_impl rdb_ocean_horizontal_viscosity Subroutine
ocean_hvisc_exit_data rdb_ocean_horizontal_viscosity Subroutine
ocean_hvisc_exit_data_impl rdb_ocean_horizontal_viscosity Subroutine
ocean_hvisc_init rdb_ocean_horizontal_viscosity Subroutine

Allocate the two tendency scratch buffers. Same optional-nz_ml pattern as the other ocean kernels — default 1 keeps the barotropic-only constructor valid; pass nz_ml to size for the multilayer driver.

ocean_hvisc_set_aniso_direction rdb_ocean_horizontal_viscosity Subroutine

Precompute the constant Smith & McWilliams (2003) direction- tensor factors from the anisotropy direction vector (n1,n2) (grid-relative i,j components). Normalises by n1²+n2² so the caller need not pass a unit vector:

Read more…
ocean_ideal_age_age_step rdb_ocean_ideal_age Subroutine

Interior aging, k = 1 .. nz-1 (subsurface layers only — k = nz is the surface and is owned exclusively by ocean_ideal_age_reset_step): hTr_age(i,j,k) += dt * h_layer(i,j,k) dt here is the caller’s therm_dt, so this is a per-RK2- stage source; two stages + rk2_average_field_3d net exactly one +dt per outer step.

ocean_ideal_age_apply rdb_ocean_ideal_age Subroutine

Driver-facing entry point for the interior-aging SOURCE term. Self-gates on ms%idx_age <= 0 (no-op when the ideal-age tracer isn’t registered), else delegates to the flat-impl ocean_ideal_age_age_step kernel. Call once per RK2 stage with dt = therm_dt and active = dyn%is_thermo_step() — see the module header for the full contract.

ocean_ideal_age_reset_step rdb_ocean_ideal_age Subroutine

Surface Dirichlet BC, k = nz only: hTr_age(i,j,nz) = young_eff * h_layer(i,j,nz) young_eff is A_young(t) (s), a host scalar from ocean_ideal_age_young_val — this writes a CONCENTRATION times thickness, not a raw concentration (today’s hard-coded young_eff = 0 reset never exercised the h_layer factor). Writes the full 1:nx, 1:ny extent including ghosts/land, same as the historical kernel; land h_layer -> H_VANISHED makes the product negligible and no kernel reads land age.

ocean_ideal_age_reset_surface rdb_ocean_ideal_age Subroutine

Driver-facing entry point for the surface Dirichlet BC. Self-gates on ms%idx_age <= 0, else delegates to the flat-impl ocean_ideal_age_reset_step kernel. Call exactly ONCE per outer step, after rk2_average + the ALE remap — see the module header for the full ordering contract.

ocean_ideal_age_young_val rdb_ocean_ideal_age Function

Host-scalar evaluation of the surface-band age value A_young(t) (s), MOM6 ideal_age_example.F90’s young_val computation (:380-385), taken exactly in spirit including the growth_rate == 0 short-circuit (no exp call, no t dependence) — this is what keeps the default bit-identical: young = young_val if sfc_growth_rate == 0 young = young_val * exp(sfc_growth_rate*t) otherwise t is model time (s) since run start. young_val (s) and sfc_growth_rate (1/s) are host scalars from ocean_dyn_t; call this ONCE per outer step on the host, never inside a do concurrent body.

ocean_kappa_shear_bytes rdb_ocean_kappa_shear Function

Counted allocatable footprint of the kappa-shear slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_kappa_shear_destroy rdb_ocean_kappa_shear Subroutine
ocean_kappa_shear_enter_data rdb_ocean_kappa_shear Subroutine
ocean_kappa_shear_enter_data_impl rdb_ocean_kappa_shear Subroutine
ocean_kappa_shear_exit_data rdb_ocean_kappa_shear Subroutine
ocean_kappa_shear_exit_data_impl rdb_ocean_kappa_shear Subroutine
ocean_kappa_shear_init rdb_ocean_kappa_shear Subroutine

Allocate the persistent fields. Always allocates (configure runs after init, so enable is not known yet); the off-cost is the f_centre + two interface fields.

ocean_kappa_shear_init_vertex rdb_ocean_kappa_shear Subroutine

Allocate the vertex-mode corner fields and set at_vertex. Called at CONFIGURE time (after init, before enter_data) — deliberately NOT from init, so the (nx+1,ny+1,nz+1) corner carrier is only ever allocated when the vertex form is actually selected (~327 MB at 1000x800x50).

ocean_kappa_shear_set_f_centre rdb_ocean_kappa_shear Subroutine

Fill f_centre with the beta-plane Coriolis magnitude at cell centres: |f_0 + beta*(y - y_ref)|. Mirrors EPBL’s set_f_centre. Call after init, before enter_data.

ocean_kappa_shear_set_f_corner rdb_ocean_kappa_shear Subroutine

Fill f_corner with the SIGNED beta-plane Coriolis at C-grid corners: f_0 + beta(y - y_ref), corner row j at y = (j-1-nghost)dy (half a cell below centre row j — corner (i,j) is the SW corner of cell (i,j)). Bit-identical to metrics_fill_coriolis’s beta-plane corner fill. Call after init_vertex, before enter_data.

ocean_lateral_mix_bytes rdb_ocean_lateral_mix Function

Counted allocatable footprint of the lateral viscosity slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_lateral_mix_compute rdb_ocean_lateral_mix Subroutine

Dispatcher — runs the compute kernel for the active closure tag. LMIX_LEITH/LMIX_SMAGORINSKY → harmonic ah_face_*; LMIX_LEITH_BIHARM → biharmonic nu4_face_*; LMIX_BIHARMONIC → scalar nu_4 in the apply step (no per-face fill); LMIX_NONE → no-op. The independent smag_ah_active switch separately fills nu4_face_* from the strain rate. this is optional so the driver can call unconditionally. res_fn_u/v (optional VarMix resolution-function fields): when supplied AND resoln_scaled_visc, scale the dynamic coefficients before the clamps; absent ⇒ unscaled ⇒ bit-identical.

ocean_lateral_mix_compute_leith rdb_ocean_lateral_mix Subroutine

Public only for the unit-test suite; ignore in production code. Populate ah_face_x/ah_face_y (m^2/s) with the Leith viscosity A_h(face) = max(ah_bg, min(ah_max, (C_L · dx)^3 · |∇ζ|)) where ζ is relative vorticity at C-grid corners (pass 1) and |∇ζ| the 2D gradient magnitude at each face (pass 2). Wall faces get the background viscosity.

ocean_lateral_mix_compute_leith_biharm rdb_ocean_lateral_mix Subroutine

Public only for the unit-test suite; ignore in production code. Populate nu4_face_x/nu4_face_y (m⁴/s) with the 2-D Leith biharmonic viscosity A_4(face) = clamp(C_lb · grid_sp⁶ · inv_PI6 · |∇²ζ|, nu4_bg, nu4_max) where ζ is C-grid corner relative vorticity, ∇²ζ its 5-point corner Laplacian, grid_sp⁶ = grid_sp_h2³, and inv_PI6 = (1/π)⁶. Per-face |∇²ζ| is the mean of the two adjacent corner Laplacians. Wall faces get nu4_bg. Leith (1968); Griffies & Hallberg (2000).

ocean_lateral_mix_compute_smag rdb_ocean_lateral_mix Subroutine

Populate ah_face_x/ah_face_y (m^2/s) with the Smagorinsky Laplacian viscosity A_h(face) = max(ah_bg, min(ah_max, (C_S · dx)^2 · |D|)) where |D| = sqrt(D_T^2 + D_S^2) is the deformation-tensor magnitude — tension D_T = ∂u/∂x − ∂v/∂y (cell centred) and shear D_S = ∂v/∂x + ∂u/∂y (corner) — averaged onto the face. Wall faces get the background viscosity (wall-adjacent rows re-use the next interior row). Smagorinsky (1963); C_S ≈ 0.15–0.2.

ocean_lateral_mix_compute_smag_ah rdb_ocean_lateral_mix Subroutine

Public only for the unit-test suite; ignore in production code. Populate nu4_face_x/nu4_face_y (m⁴/s) with the biharmonic Smagorinsky viscosity A_4(face) = clamp(C_b · L⁴ · |D|, nu4_bg, nu4_max) where L² = 2·dx²·dy²/(dx²+dy²) (harmonic mean of dx²,dy²) and |D| is the strain-rate magnitude from compute_smag. Wall faces get nu4_bg. SMAG_BI_CONST ≈ 0.015–0.06.

ocean_lateral_mix_compute_vel_scale rdb_ocean_lateral_mix Subroutine

Public only for the unit-test suite; ignore in production code. Live velocity-scale viscosity (MOM6 KH_VEL_SCALE, Kh = U·Δ): per face A_vel = kh_vel_scale_live · L_grid · |u_face| (L_grid = sqrt(dxT·dyT)), max-combined into ah_face_* so it floors — never reduces — the active closure. seed_bg = .true. first fills every face with ah_bg (used when no closure ran); .false. only raises faces where A_vel exceeds the closure. No-op when kh_vel_scale_live <= 0.

ocean_lateral_mix_destroy rdb_ocean_lateral_mix Subroutine
ocean_lateral_mix_enter_data rdb_ocean_lateral_mix Subroutine
ocean_lateral_mix_enter_data_impl rdb_ocean_lateral_mix Subroutine
ocean_lateral_mix_exit_data rdb_ocean_lateral_mix Subroutine
ocean_lateral_mix_exit_data_impl rdb_ocean_lateral_mix Subroutine
ocean_lateral_mix_init rdb_ocean_lateral_mix Subroutine

Allocate the face viscosity coefficients + corner-vorticity scratch. Default nz_ml = 1 preserves the barotropic-only constructor; pass nz_ml = ms%nz_ml for the multilayer driver.

ocean_linear_layer_density rdb_ocean_state Function

Linearly-spaced layer densities for the MOM6 COORD_CONFIG="linear" IC analogue (set_coord_linear), re-derived for Roundabout’s bottom-up layer convention. Returns nz_ml densities, bed k=1 heaviest → surface k=nz_ml lightest, layer-centred:

Read more…
ocean_meke_bytes rdb_ocean_meke Function

Counted allocatable footprint of the MEKE slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_meke_destroy rdb_ocean_meke Subroutine
ocean_meke_enter_data rdb_ocean_meke Subroutine
ocean_meke_enter_data_impl rdb_ocean_meke Subroutine
ocean_meke_exit_data rdb_ocean_meke Subroutine
ocean_meke_exit_data_impl rdb_ocean_meke Subroutine
ocean_meke_init rdb_ocean_meke Subroutine

Allocate the prognostic field, the derived diffusivity, and the Strang-stage workspaces. Always allocates (configure runs after init); setup uses plain host allocation (no do concurrent before enter_data).

ocean_meke_set_f_centre rdb_ocean_meke Subroutine

Copy a pre-filled cell-centre Coriolis magnitude |f| (1/s) onto the MEKE slot, so beta = |grad f| for the Rhines length is live. The caller (setup) builds f_centre with the same metrics_fill_coriolis path the Coriolis / VarMix / EPBL slots use (handles beta-plane AND spherical). Host loop — call after init, before enter_data.

ocean_metrics_bytes rdb_ocean_metrics Function

Counted allocatable footprint of the grid metrics slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_metrics_destroy rdb_ocean_metrics Subroutine
ocean_metrics_enter_data rdb_ocean_metrics Subroutine
ocean_metrics_enter_data_impl rdb_ocean_metrics Subroutine

Arrays-only attach. The parent ocean_state_t is mapped by the orchestrator BEFORE this runs.

ocean_metrics_exit_data rdb_ocean_metrics Subroutine
ocean_metrics_exit_data_impl rdb_ocean_metrics Subroutine
ocean_metrics_init rdb_ocean_metrics Subroutine

Allocate + zero every metric array. Always allocates (configure runs after init, before enter_data); off-cost is ~24 (nx,ny)-class arrays (~2 MB at Tasman size).

ocean_mle_bytes rdb_ocean_mle Function

Counted allocatable footprint of the MLE / Fox-Kemper slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_mle_destroy rdb_ocean_mle Subroutine
ocean_mle_enter_data rdb_ocean_mle Subroutine
ocean_mle_enter_data_impl rdb_ocean_mle Subroutine
ocean_mle_exit_data rdb_ocean_mle Subroutine
ocean_mle_exit_data_impl rdb_ocean_mle Subroutine
ocean_mle_init rdb_ocean_mle Subroutine

Allocate the 2D ML diagnostics + per-layer face transports. Always allocates (configure runs after init); the off-state footprint is two 2D + two face-shaped 3D arrays.

ocean_munk_delta_m rdb_ocean_stability_audit Function

Munk boundary-layer width delta_M = (nu_h/beta)^(1/3). beta<=0 (f-plane — no meridional PV gradient, no Munk boundary layer) or nu_h<=0 returns huge(1.0_wp) (no constraint — never trips the >= 2-cell criterion).

ocean_munk_min_cells rdb_ocean_stability_audit Function

Accessor for MUNK_MIN_CELLS.

ocean_munk_required_nu_h rdb_ocean_stability_audit Function

nu_h (m^2/s) needed for delta_M to span exactly n_cells of width dx — the audit’s suggested fix for a Munk-layer warning.

ocean_munk_worst_case rdb_ocean_stability_audit Subroutine

Worst-case (smallest) delta_M/dx ratio over the physical domain, honouring a latitude-varying beta under coriolis_scheme='planetary' on a non-Cartesian grid (beta = 2*omega*cos(lat)/R, maximal — hence delta_M MINIMAL, the worst case — at the most equatorward row) and a constant beta (&ocean_topo_nml coriolis_beta) everywhere else. ratio_min is huge(1.0_wp) (no constraint) when beta<=0 everywhere (an f-plane run has no Munk boundary layer to resolve).

ocean_obc_any_open_edge rdb_ocean_obc_baroclinic Function

True when ANY edge TAG of the domain needs the baroclinic open-edge treatment. Reads the global tags only (never has_*), so every rank gets the same answer: callers use it to gate a COLLECTIVE seam exchange after ocean_obc_apply_baroclinic.

ocean_obc_apply_baroclinic rdb_ocean_obc_baroclinic Subroutine

Set per-layer normal velocity at open-ish faces after apply_bt_correction. Scheme via bc%radiation_scheme: RAD_ANOMALY (0, default): Flather mean + zero-gradient anomaly. RAD_ORLANSKI (1): per-layer implicit-upwind radiation (Orlanski 1976), running-mean phase speed rx; u_prev snapshot refreshed at END so cold-start (u_prev=0) sees rx=0 for a quiescent IC. Optional nudging (Marchesiello et al. 2001) composes AFTER either scheme when the selected tau > 0, toward the edge clamped_u/v: tau_in when incoming (dhdt·dhdx ≤ 0 Orlanski; outward vel ≤ 0 anomaly), else tau_out. CLAMPED: u_layer(wall) = clamped_u, all layers. No-op when no edge is open-ish.

ocean_obc_bytes rdb_ocean_obc Function

Counted allocatable footprint of the open boundary condition slot (0 when unallocated).

ocean_obc_destroy rdb_ocean_obc Subroutine
ocean_obc_fill_ghosts rdb_ocean_obc_baroclinic Subroutine

Fill h_layer and tracer hTr ghosts at open-ish edges. h_layer: zero-gradient (copy adjacent interior column). Tracer hTr per (j,k): outflow ⇒ ghost := interior (zero-gradient); inflow ⇒ ghost hTr := clamped_tracer(it) * h_ghost. Inflow criterion uses the per-layer wall-face velocity sign (outward-normal convention): west inflow u_wall>0, east u_wall<0, south v_wall>0, north v_wall<0. No-op when no edge is open-ish. Per-tracer loop outside the DCs.

ocean_obc_init rdb_ocean_obc Subroutine
ocean_obc_refill_ghost_ssh rdb_ocean_obc_baroclinic Subroutine

Re-establish a zero-gradient free surface in the open-edge GHOST columns, called at the END of the outer step (after the ALE remap) so the diagnostic manager sees a consistent halo.

Read more…
ocean_obc_update_reservoirs rdb_ocean_obc_baroclinic Subroutine

Evolve per-edge reservoir concentrations tres one timestep. Called after continuity_tracer_step_split while ms%mass_flux_{x,y}_layer still hold the stage’s wall-face fluxes. Per open-ish edge (with allocated tres_*), per (j|i, k, tracer): u_n = sign_edge * mass_flux(wall) / max(h_int, h_min) (outward normal) Implicit backward-Euler (Marchesiello et al. 2001): c_out = max(0,u_n)dt/L_out, c_in = max(0,-u_n)dt/L_in (0 if L==0) tres = (tres + c_outT_int + c_inT_data)/(1 + c_out + c_in) Degenerate L_out==0 & u_n>0 ⇒ tres = T_int (L_in==0 & u_n<0 ⇒ T_data). T_int = hTr(int)/max(h(int),h_min); T_data = clamped_tracer(it). No-op when both length scales are zero (default path).

ocean_p_surf_bytes rdb_ocean_p_surf Function

Counted allocatable footprint of the p_surf slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_p_surf_destroy rdb_ocean_p_surf Subroutine
ocean_p_surf_enter_data rdb_ocean_p_surf Subroutine

Attach the device-resident seam arrays. Only when enabled. select-type -> non-poly _impl (AMD libomptarget class-box rule).

ocean_p_surf_enter_data_impl rdb_ocean_p_surf Subroutine
ocean_p_surf_exit_data rdb_ocean_p_surf Subroutine
ocean_p_surf_exit_data_impl rdb_ocean_p_surf Subroutine
ocean_p_surf_init rdb_ocean_p_surf Subroutine

Minimal init — the real allocation happens in p_surf_configure once the namelist is available (host, before enter_data).

ocean_periodic_wrap_centre_2d rdb_ocean_periodic Subroutine

Fill ghost cells of a cell-centred 2D field (e.g. η, bt_H_ref) with the periodically-matching interior values. Explicit-shape dummies avoid per-launch descriptor-walk memcpys.

ocean_periodic_wrap_centre_3d rdb_ocean_periodic Subroutine

Fill ghost cells of a cell-centred 3D field (e.g. h_layer, hTr, T, S). no_wait (optional, default .false.): when .true., loops issue on OpenACC queue 1 and the routine returns WITHOUT syncing, so a batched caller can pipeline many tiny ghost-slab wraps and !$acc wait(1) once. Default ⇒ self-contained blocking wrap. Not pure (directives).

ocean_periodic_wrap_face_x_2d rdb_ocean_periodic Subroutine

Fill ghost faces of a 2D x-face field (e.g. bt_ubt, shape nx_total+1). Also copies the west physical-wall face value onto the east physical-wall face (belt-and-braces seam invariant, §1.1 property b). nx_face = nx_total + 1.

ocean_periodic_wrap_face_x_3d rdb_ocean_periodic Subroutine

Fill ghost faces of a 3D x-face field (e.g. u_face_x_layer). nx_face = nx_total + 1. no_wait (optional): see ocean_periodic_wrap_centre_3d — batched async(1), sync once at the caller. Not pure (async/wait directives).

ocean_periodic_wrap_face_y_2d rdb_ocean_periodic Subroutine

Fill ghost faces of a 2D y-face field (e.g. bt_vbt, shape ny_total+1). Also copies south physical-wall face onto north physical-wall face. ny_face = ny_total + 1.

ocean_periodic_wrap_face_y_3d rdb_ocean_periodic Subroutine

Fill ghost faces of a 3D y-face field (e.g. v_face_y_layer). ny_face = ny_total + 1. no_wait (optional): see ocean_periodic_wrap_centre_3d. Not pure (async/wait directives).

ocean_periodic_wrap_state rdb_ocean_periodic Subroutine

Convenience wrapper: wrap h_layer, u/v layer faces, and every registered tracer. Called at stage entry (before derive_bt_from_layers) and after continuity (before hdiff).

Read more…
ocean_poison_ghost_bands rdb_ocean_ghost_poison Subroutine

Sentinel-NaN the exchange-covered ghost bands of all multilayer prognostic fields and the BT workstate fields. Called at the TOP of each outer step (before any exchange or kernel) so that any kernel consuming an unexchanged ghost produces a loud NaN at the offending step.

Read more…
ocean_porous_refresh rdb_ocean_dyn Subroutine

Recompute the porous-barrier layer-averaged open-area fractions from the current layer thicknesses. No-op (and untouched placeholder arrays) when &ocean_porous_nml enable is off.

Read more…
ocean_pressure_force_apply rdb_ocean_pressure_force Subroutine

Forward-Euler accumulation of the PGF acceleration onto the face velocities. Additive (not overwriting), so apply ordering vs the Coriolis apply doesn’t matter before the next tendency-compute. no_wait (optional, default .false. ⇒ blocking): when .true. the apply loops run on OpenACC queue 1 and return WITHOUT syncing, so the batched velocity-apply chain can !$acc wait(1) ONCE. Not pure (async/wait directives); still functionally pure.

ocean_pressure_force_bytes rdb_ocean_pressure_force Function

Counted allocatable footprint of the pressure force slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_pressure_force_compute rdb_ocean_pressure_force Subroutine

Compute the hydrostatic pressure-gradient acceleration at every C-grid face. Variants (see the OPGF_VARIANT_* / GPRIME / FV_MOM6 constants for the per-variant formulas): MONT (layer-mean ρgh), FV_LITE (+ z-correction), FV_WRIGHT (+ in-situ Wright density), GPRIME, FV_MOM6.

Read more…
ocean_pressure_force_destroy rdb_ocean_pressure_force Subroutine
ocean_pressure_force_enter_data rdb_ocean_pressure_force Subroutine
ocean_pressure_force_enter_data_impl rdb_ocean_pressure_force Subroutine
ocean_pressure_force_exit_data rdb_ocean_pressure_force Subroutine
ocean_pressure_force_exit_data_impl rdb_ocean_pressure_force Subroutine
ocean_pressure_force_init rdb_ocean_pressure_force Subroutine

Allocate the scratch buffers. Default nz_ml=1 keeps the barotropic-only path constructible; passing nz_ml sizes them for the multilayer kernel.

Read more…
ocean_pressure_force_set_bathymetry rdb_ocean_pressure_force Subroutine

Copy b(:, :) into this%b on the host. Must be called BEFORE enter_data (the device copy is taken from the host values). Issues no update device; to refresh post enter_data the caller must issue !$acc update device(this%b) itself.

ocean_pseudo_salt_deviation rdb_ocean_pseudo_salt Subroutine

Diagnostic helper: D(i,j,k) = hTr_ps/h - hTr_s/h, i.e. the pseudo-salt concentration minus the salinity concentration.

Read more…
ocean_pseudo_salt_register rdb_ocean_pseudo_salt Subroutine

Setup-time entry point: registers the “pseudo_salt” passive tracer (name/units/long_name copied verbatim from Shao 2016) and records its slot on ms%idx_pseudo_salt. MUST be called after ms%init and before enter_data — and, on the ocean path, before ocean_bc_state_init sizes bc%n_tracers (the register_passive_tracer contract). error stops on refusal (mirrors rdb_state.F90’s treatment of a fatal setup misconfiguration — a caller that reaches here has already decided to register, so a silent no-op would be worse than a loud abort).

ocean_pseudo_salt_seed rdb_ocean_pseudo_salt Subroutine

Seed hTr(idx_pseudo_salt) = hTr(idx_salinity) over the FULL array shape (nx_total, ny_total, nz_ml) — ghosts included, matching MOM6’s isd:ied, jsd:jed seed (§4 of the plan). A halved ghost band would make the deviation diagnostic non-zero at the very first halo exchange, before any real transport has run. Self-gates on either index being unregistered. Must run AFTER every write to salinity’s initial condition (analytical IC, then any z-file overlay) and BEFORE ocean_state_enter_data.

ocean_redi_bytes rdb_ocean_redi Function

Counted allocatable footprint of the Redi slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_redi_destroy rdb_ocean_redi Subroutine
ocean_redi_enter_data rdb_ocean_redi Subroutine
ocean_redi_enter_data_impl rdb_ocean_redi Subroutine
ocean_redi_exit_data rdb_ocean_redi Subroutine
ocean_redi_exit_data_impl rdb_ocean_redi Subroutine
ocean_redi_init rdb_ocean_redi Subroutine

Allocate the Phase-A coefficient arrays. Always allocates (configure runs after init); off-state footprint is the six face-shaped (nsurf) coefficient arrays. Plain host allocation (no do concurrent before enter_data).

ocean_remap_merge_vanished_content rdb_ocean_remap Subroutine

Public test shim over the included rdb_vl_merge_content — the ONE definition of the vanished-layer content rule (src/shared_module_utilities/rdb_vanished_layer.inc). Production code calls the included copy directly; this exists so tests/test_ocean_remap_vanished.F90 can assert the rule’s own properties without a second transcription of it.

ocean_remap_scan_preconditions rdb_ocean_remap Subroutine

Scan every column for the two remap preconditions and report how badly they are missed — the domain-wide counterpart of rdb_remap_column :: remap_column_preconditions_ok.

Read more…
ocean_remap_tracer_column rdb_ocean_remap Subroutine

Single-column unit-test entry: wraps remap_column with the c = hTr/h ↔ hTr_new = c_new·h_new pattern, including the SAME two-sided vanishing-layer merge the production kernel runs (rdb_vl_merge_content + rdb_vl_column_conc), so this entry cannot drift from ocean_remap_tracer_field. Production callers go through that one.

ocean_remap_tracer_field rdb_ocean_remap Subroutine

Flat-impl tracer remap. Per (i,j) column: c = hTr/h (vanishing-layer- guarded) → per-column remap kernel → hTr_new = c_new·h_new. Conservative. budget (optional): when present, the per-cell hTr_new−hTr_old increment is accumulated into the slot (heat/salt remap deltas) before overwriting. Flat-arg so GPU codegen doesn’t chase the array-of-derived-types pointer.

Read more…
ocean_restart_check_decomp rdb_ocean_restart_io Subroutine

Validate schema + decomposition (+ optional grid/vcoord/tracer) metadata in filename against the live decomp/meta. ierr = 0 on match; 1 = schema, 2 = decomposition, 3 = grid/vcoord/tracer mismatch.

ocean_restart_destroy rdb_ocean_restart Subroutine
ocean_restart_init rdb_ocean_restart Subroutine
ocean_restart_read_local rdb_ocean_restart_io Subroutine

Read a per-rank ocean restart into the registry’s host arrays (FULL local extent) + return the scalar metadata. Validates decomp + grid/vcoord/tracer metadata first and error-stops on mismatch unless ierr is present. A REQUIRED field absent from the file is FATAL; only optional entries warn-and-seed. Must run BEFORE ocean_state_enter_data so the H->D copy carries the restored values up.

ocean_restart_write_local rdb_ocean_restart_io Subroutine

Write a per-rank ocean restart file from the registry durably (to <filename>.tmp then POSIX-rename). Device sync (!$acc update self) on the device-mapped arrays must already have been done by the caller — this is pure host NetCDF I/O.

Read more…
ocean_salt_src_sum rdb_ocean_console_stats Function

Assemble the total SALT source integral (pre-weight, pre-ρ) that feeds ocean_budget_src: surface flux + (PR-23) the map-driven sponge’s tracer-relaxation source. Mirror of ocean_heat_src_sum without the geothermal term (salt has no geothermal analogue). sponge_sum is ms%salt_budget_sponge’s area-weighted reduction — zero unless &ocean_sponge_nml enable=.true., relax_tracers=.true..

ocean_sea_ice_bytes rdb_ice_state Function

Counted allocatable footprint of the sea-ice slot (one arr_bytes term per array, mirroring ocean_meke_bytes).

ocean_sea_ice_destroy rdb_ice_state Subroutine

Reverse of init. Clears is_init first (use-after-destroy guard), then releases allocations.

ocean_sea_ice_enter_data rdb_ice_state Subroutine
ocean_sea_ice_enter_data_impl rdb_ice_state Subroutine

Attach the slot’s allocatables to the device. copyin (not create) throughout: every array is host-initialised (0, or part_size/sal_ice’s non-zero defaults) at init, and a restart read seeds the persistent ones host-side before the mapping. PR 3c’s seam + scratch fields are also copyin: they are host-zeroed at init and (re)filled device-side every thermo step, so a plain copyin is correct (and cheap — one-time). PR 4b: u_ice/v_ice are copyin (host-zeroed at init, and the v1 sampler / PR-5 EVP both WRITE them device-side every call — copyin establishes presence, same contract as the atm_* seam). PR 5: str_d/str_t/str_s are copyin (host-zeroed at init or restart-seeded; ice_evp_dynamics reads them before the first write on every call — limit_stresses runs first). tau_a_x/ tau_a_y are copyin (host-snapshotted at configure, then read device-side every substep — never written on-device). fxoc/ fyoc are copyin (host-zeroed at init or restart-seeded; the EVP core zeros them itself at call entry before accumulating). PR 63: tau_ocn_x/tau_ocn_y are copyin (host-zeroed at init or restart-seeded; ice_tau_mirror_impl WRITES them device-side every call to ice_ocean_stress_flux — same reasoning as fxoc/fyoc). tau_ocn_valid is NEVER mapped — it is host-only scalar state, set on the host by ice_ocean_stress_flux and read on the host by ice_ocean_stress_resume_apply; register_scalar forces device_mapped=.false. on the restart side for the same reason. The transport workspace is create (pure scratch, recomputed from scratch every pass — never read before written), mapped only if (this%transport) (memory Rule 2, same gate as the host-side allocation).

ocean_sea_ice_exit_data rdb_ice_state Subroutine
ocean_sea_ice_exit_data_impl rdb_ice_state Subroutine

Reverse of enter_data_impl — all six PR-3a fields are prognostic state (post-run host inspection + restart write), same as the persistent frazil bank; the drain-and-zero budget scratch is dropped. PR 3b’s m_frozen_diag/salt_flux_diag are both PERSISTENT (restart-carried) — copyout, not delete. PR 3c: heat_flux_diag/m_melt_diag are likewise PERSISTENT (copyout); PR 31’s sw_thru_diag is PERSISTENT too (copyout, restart-carried — NOT its per-category parent sw_thru, which stays delete); the atm_* seam, fb/sst_seam/ssurf_seam/ tfw_seam, and the per-category column scratch (tsurf_out/h2o_ocn_to_ice/h2o_ice_to_ocn/heat_to_ocn/ sw_thru) are all recomputed every thermo step — delete. PR 4a: h_lim/mh_lim are delete (recomputed from ncat at init, never mutated after); fb_part_sum is delete (recomputed every thermo step, same lifecycle as the other scratch seams). PR 4b: u_ice/v_ice are copyout (post-run host inspection, same contract as the melt/frazil diags); the transport workspace is delete (pure scratch), gated the same if (this%transport) as the enter_data map. PR 5: str_d/str_t/str_s/fxoc/fyoc are copyout (PERSISTENT, restart-carried); tau_a_x/tau_a_y are delete (configure-time snapshot, not restart-carried — rebuilt fresh on every run). PR 26: atm_fprec is delete (same lifecycle as the rest of the atm_* seam); fprec_ocn_diag/ snow_part_ocn are delete (SCRATCH, recomputed every thermo step, same lifecycle as fb_part_sum). PR 63: tau_ocn_x/tau_ocn_y are copyout — PERSISTENT, restart-carried, and the restart write reads the host copy (opposite lifecycle to tau_a_x/tau_a_y, do not copy that pattern). tau_ocn_valid is never mapped, so there is nothing to unmap.

ocean_sea_ice_init rdb_ice_state Subroutine

Cache the grid extents, allocate the frazil (PR 1) + Winton column (PR 3a) prognostics, and mark the slot live. Allocation is gated on enable at the parent call site (memory Rule 2), so an ice-off run never carries these arrays.

ocean_seam_refresh_surface_stress rdb_ocean_halo_state Subroutine

Make the surface-stress pair valid in every ghost cell, then re-derive stress_mag from it.

Read more…
ocean_sigma_stiffness rdb_ocean_stability_audit Function

One face’s terrain-following stiffness |h_a-h_b|/(h_a+h_b).

Read more…
ocean_sigma_stiffness_limit rdb_ocean_stability_audit Function

Accessor for SIGMA_STIFFNESS_LIMIT.

ocean_sigma_stiffness_worst rdb_ocean_stability_audit Subroutine

Worst (largest) ocean_sigma_stiffness over every face joining two WET columns inside [i0,i1] x [j0,j1], with its location, its two column thicknesses, and how many faces are over SIGMA_STIFFNESS_LIMIT.

Read more…
ocean_slopes_build_e rdb_ocean_isopycnal_slopes Subroutine

Build GEOPOTENTIAL interface heights bottom-up: e_int(:,:,1) = −bathy (the bed, below the z = 0 datum), e_int(:,:,K+1) = e_int(:,:,K) + h_layer(:,:,K). A per-column serial cumulative sum (parallel over i,j). The across-face difference e_W − e_E feeds the interface-tilt term, so the bed datum is NOT irrelevant: it must be the true bed depth, or a bathymetry step reads as an isopycnal slope.

ocean_slopes_bytes rdb_ocean_isopycnal_slopes Function

Counted allocatable footprint of the isopycnal slopes slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_slopes_compute rdb_ocean_isopycnal_slopes Subroutine

Public entry point — fill slope_x/slope_y + n2_u/n2_v at all interfaces. No-op if absent / uninitialised / disabled, so the driver can call it unconditionally. Pipeline: vert-fill T/S → build interface heights e_int → u-face pass → v-face pass.

ocean_slopes_compute_impl rdb_ocean_isopycnal_slopes Subroutine

NVHPC doesn’t descriptor-walk per launch.

ocean_slopes_destroy rdb_ocean_isopycnal_slopes Subroutine
ocean_slopes_enter_data rdb_ocean_isopycnal_slopes Subroutine

Poly TBP delegating to a type(...)-arg _impl (AMD-crash rule: bare polymorphic copyin(this) maps the stack descriptor → AMD libomptarget cross-slot overlap crash).

ocean_slopes_enter_data_impl rdb_ocean_isopycnal_slopes Subroutine
ocean_slopes_exit_data rdb_ocean_isopycnal_slopes Subroutine
ocean_slopes_exit_data_impl rdb_ocean_isopycnal_slopes Subroutine
ocean_slopes_init rdb_ocean_isopycnal_slopes Subroutine

Allocate the slope / N² outputs + the vert-fill T/S scratch + the interface-height buffer. Default nz_ml = 1 preserves the barotropic-only constructor; pass nz_ml = ms%nz_ml for the multilayer driver. Setup code uses plain host allocation (no do concurrent before enter_data).

ocean_slopes_mask_open_column rdb_ocean_isopycnal_slopes Subroutine

Zero slope / N² at every interior interface K that is NOT strictly inside its face’s open column, i.e. unless both layers it separates (K above, K-1 below) are open at that face (&vcoord_nml zfixed_closed_faces). Assigned under a test, never multiplied by the 0/1 mask, so a non-finite value formed against a filler cannot survive as NaN·0.

ocean_slopes_pass_x rdb_ocean_isopycnal_slopes Subroutine

u-face slope + N² pass. Interface K (interior 2..nz) straddles layer k=K (above, surface side) and k=K-1 (below, bed side). Bed (K=1) + surface (K=nz+1) are forced to zero. The u-face at (i,j) sits between cells (i-1,j) and (i,j); pairs columns iw=i-1 (west) and i (east), so loop i=2:nx.

ocean_slopes_pass_y rdb_ocean_isopycnal_slopes Subroutine

v-face slope + N² pass — mirror of pass_x with v-staggering. The v-face at (i,j) sits between cells (i,j-1) and (i,j); pairs columns js=j-1 (south) and j (north), loop j=2:ny.

ocean_slopes_set_bathymetry rdb_ocean_isopycnal_slopes Subroutine

Copy the bed depth b (m, positive down, (nx_total, ny_total) incl. ghosts) into this%bathy on the host. Call it with the WRAPPED + halo-exchanged barotropic%b (the seam faces read the ghosts) and BEFORE enter_data (the device copy is taken from the host values); to refresh after enter_data the caller issues !$acc update device(this%bathy) itself. No-op on an uninitialised slot.

ocean_slopes_vert_fill_ts rdb_ocean_isopycnal_slopes Subroutine

Fill massless layers in T/S with sensible values via one pass of constant-kappa·dt vertical diffusion — a SINGLE forward-elim + back-sub Thomas sweep per column (no iteration). Operates on the tracer-from-hTr conversion (T = hTr/h) and writes the scratch t_fill/s_fill; the prognostic tracers are untouched.

Read more…
ocean_sponge_apply rdb_ocean_sponge Subroutine

Apply momentum relaxation in any sponge-tagged edge band. No-op when no edge is OBC_SPONGE.

ocean_sponge_apply_maps rdb_ocean_sponge Subroutine

Map-driven sponge dispatch (&ocean_sponge_nml enable=.true.). Relaxes momentum toward u_ref/v_ref (when relax_uv) and every registered tracer toward ref_tracer (when relax_tracers), mirroring the S/T tracer relaxation into ms%salt_budget_sponge / ms%heat_budget_sponge so the console salt/heat budget can close with the sponge on (rdb_ocean_console_stats::ocean_heat_src_sum / ocean_salt_src_sum). No-op when .not. sp%is_init .or. .not. sp%enable. Run from the same slot as the legacy path — see rdb_ocean_dyn::run_stage_split’s dispatch (exactly one of the legacy band / map-driven path runs).

ocean_sponge_apply_tracers rdb_ocean_sponge Subroutine

Relax tracer concentrations (hTr/h) toward per-edge targets in any sponge band with sponge_relax_tracers = .true.. Same cosine ramp and sponge_strength as the momentum kernel. No-op otherwise. Per-tracer loop outside the inner loops (outer-shim for the array-of-derived-types registry).

ocean_sponge_bytes rdb_ocean_sponge Function

Counted allocatable footprint (0 when enable=.false. — every array is unallocated then). tools/check_bytes_accounting.py reconciles this against the measured device mapping.

ocean_sponge_destroy rdb_ocean_sponge Subroutine
ocean_sponge_enter_data rdb_ocean_sponge Subroutine

Type-bound wrapper — delegates to the non-polymorphic impl so the device-attach map base is the heap object, not a polymorphic stack box (AMD libomptarget cross-slot-overlap fix; copied verbatim from rdb_ocean_surface_flux.F90).

ocean_sponge_enter_data_impl rdb_ocean_sponge Subroutine
ocean_sponge_exit_data rdb_ocean_sponge Subroutine
ocean_sponge_exit_data_impl rdb_ocean_sponge Subroutine
ocean_sponge_init rdb_ocean_sponge Subroutine

Allocate the maps + reference-state arrays. Call ONLY when this%enable (the gated-closure convention, mirroring epbl/kshear/…) — the caller sets enable before calling, and ocean_state_init only reaches this when this%enable is .true. (see rdb_ocean_state.F90). ref_tracer is sized at max(n_tracers, 1) so an as-yet-empty tracer registry never trips a zero-extent allocate.

ocean_sponge_refresh_target rdb_ocean_sponge Subroutine

Re-evaluate the ANALYTIC target_source="linear_z" reference on the LIVE layer geometry: for every sponge cell (idamp_h > 0) and every layer,

Read more…
ocean_sponge_snapshot_reference rdb_ocean_sponge Subroutine

Snapshot the seeded initial condition into sp%ref_tracer / sp%u_ref / sp%v_ref (target_source = "ic", the only implemented source in v1). HOST-side, plain do loops (mirrors seed_ts_from_zfile — CLAUDE.md gotcha: this runs before ocean_state_enter_data).

Read more…
ocean_stability_audit rdb_ocean_stability_audit Subroutine

Run all configure-time stability checks. Must run AFTER configure_ocean_metrics + configure_ocean_land_mask (needs the real filled ocean_metrics_t), before ocean_state_enter_data. ierr present -> OCEAN_STATUS_ERR_SETUP on any hard-bound violation (never error stop); warnings always just log, whatever ierr does. Rank-0-only logging (mirrors every other configure_ocean_* info/warning line); the ERROR path itself always fires (every rank must agree the config is broken).

ocean_stability_min_cell rdb_ocean_stability_audit Subroutine

Smallest actual cell edge over the WET PHYSICAL domain (excludes ghosts and land), taken over BOTH dxT and dyT, with its (i,j) location and which axis (is_x) it came from — for actionable messages (“near j=110”). Host-side, configure time; the grid sizes here are at most a few 10^5 cells (a global tripolar config), trivial to scan once.

Read more…
ocean_state_build_restart_registry rdb_ocean_state Subroutine

Walk the ocean god state and register every field that must checkpoint for a bit-exact step-(N+1) resume (ROADMAP A1).

Read more…
ocean_state_bytes rdb_ocean_state Function

Counted allocatable footprint of the whole ocean god state, summed from each slot’s own bytes() (each term is 0 when that slot’s arrays are unallocated, so the DEFAULT-OFF closures gated in ocean_state_init contribute nothing — the total tracks the conditional allocation directly). Reported before enter_data and reconciled against the measured device mapping — a new array added without a matching bytes() term makes the measured map exceed this count and self-announces the drift (see rdb_mem_report). Slots with no allocatables (eos, restart) carry no term. The diag%vars registry USED to be excluded — it is now counted, per registered variable, by diag_var_bytes (it was the single largest uncounted device block: ~3.2 GB for the default catalog at 1000x800x50). data_input (PR-14) DOES have allocatables (f0/f1 per registered field) and IS device-mapped, so it carries a real term below — zero registered fields on every shipped namelist keeps that term at 0.

ocean_state_destroy rdb_ocean_state Subroutine
ocean_state_enter_data rdb_ocean_state Subroutine

Attach the ocean god state’s allocatables to the device. Map the parent struct first so the device knows the shape of state, then call each slot’s bound enter_data. Only slots that own host allocations need to be visited; the Phase 0 shells (dyn, continuity, coriolis_adv, …) have no allocatables yet, so they’re skipped until they ship their own bound methods.

ocean_state_exit_data rdb_ocean_state Subroutine

Reverse of ocean_state_enter_data. Walk components first, parent struct last.

ocean_state_fill_restart_metadata rdb_ocean_state Subroutine

Build the grid/vcoord/tracer fingerprint validated on resume (review #7).

ocean_state_init rdb_ocean_state Subroutine

Construct the ocean god state. Each slot’s init allocates its own arrays; the DEFAULT-OFF closures (EPBL, kappa-shear, tidal mixing, GM, Redi, MLE/Fox-Kemper, VarMix, MEKE, isopycnal slopes) are gated on their enable flag so a plain run does not pay their multi-GB footprint. This requires the enable flags to be set BEFORE init — ocean_state_init_from_config hoists them above its call this%init(grid) for exactly this reason. The gated closures’ runtime kernels already early-return on .not. enable (and enter_data/exit_data are gated in the parent walk), so a gated-off slot is never touched with unallocated arrays.

ocean_state_init_from_config rdb_ocean_state Subroutine

Seed the cfg-derived scalars the slot inits read up front (layer count, ideal-age toggle), allocate via init(grid), then override the linear-EOS params (after eos%init has set its defaults). Carries the ocean branch that state_init_from_config held before the coastal / ocean state split — the order (nz_ml + ideal_age before init, eos after) is load-bearing and matches the pre-split behaviour.

ocean_state_restart_read rdb_ocean_state Subroutine

Read a per-rank ocean restart into the (host) prognostic arrays. MUST run BEFORE ocean_state_enter_data — the subsequent H->D copy carries the restored values to the device. Restores dyn%outer_step_count (dt_therm alignment).

Read more…
ocean_state_restart_write rdb_ocean_state Subroutine

Build the registry, pull every DEVICE-MAPPED registered array down with !$acc update self, then write the per-rank file durably (tmp + rename). Safe to call mid-run (state is device-resident) — the D->H pulls leave the device copy authoritative. intent(inout): the update self mutates the host copy of state (review #12), and pointer association into state requires the target attribute.

Read more…
ocean_state_restart_write_drop_field rdb_ocean_state Subroutine

Test-only sibling of ocean_state_restart_write: identical, except the ONE registered entry whose tag matches drop_tag is written under a mangled tag instead of its real one, so a subsequent ocean_state_restart_read/ocean_restart_read_local – which looks up variables by their REAL tag – finds nothing and takes exactly the “optional field absent” path it takes for a genuinely older checkpoint. error stops if drop_tag does not match any registered entry (a typo here must not silently test nothing).

ocean_state_seed_from_cfg rdb_ocean_state Subroutine

Populate the ocean prognostic state with an analytical IC derived from cfg scalars. Bathymetry is set per cfg%ocean%topo%topo_config ("flat" → uniform ocean_max_depth; "spoon" → MOM6 spoon shape) — UNLESS injected_b is present, in which case it overrides topo_config entirely (P2.5 pre-create geometry injection). Water column thickness h = b so the free surface starts at SSH = 0. Layers split the local depth evenly (h_layer(i,j,k) = b(i,j) / nz_ml). Tracers carry per-layer h * Tr at the configured initial T/S. Velocities zeroed.

Read more…
ocean_state_seed_land_cells rdb_ocean_state Subroutine

Hold land T-cells (wet_mask==0) at FINITE reference values so the masked dyn-core never evaluates 0*NaN (a zeroed face metric times a NaN land contribution is still NaN). Spec §13.3 / land_mask_final_resolution.md R-land-state: * h_layer floored to H_VANISHED (never 0 — avoids 1/0); * tracer content zeroed (hTr = 0, so T = S = 0 — finite); * layer + barotropic face velocities zeroed at land faces.

Read more…
ocean_surface_flux_apply_cover_const rdb_ocean_surface_flux Subroutine

Mask the STATIC scalar Q_heat / Q_salt fill with the ice-shelf cover, for the use_components = .false. path only.

Read more…
ocean_surface_flux_apply_sw_penetration rdb_ocean_surface_flux Subroutine

Additive correction that redistributes the penetrating shortwave fraction of Q_heat through the upper water column as a two-band exponential (Paulson & Simpson 1977; Jerlov types), instead of leaving all of it deposited at the surface layer by ocean_surface_flux_apply_tracers.

Read more…
ocean_surface_flux_apply_tracers rdb_ocean_surface_flux Subroutine

Add the surface heat + salt fluxes directly to the top tracer layer. Operates in hTr space (concentration· thickness): for temperature d(hT_top)/dt = Q_heat(i,j) / (rho_0 · cp) For salinity d(hS_top)/dt = Q_salt(i,j) / rho_0 (Both expressed in units that match the hTr convention: hTr = T·h so the forcing has units of T·h/s = K·m/s. Q_heat / (rho_0·cp) has units (W/m^2)/(kg/m^3·J/kg/K) = K·m/s ✓.)

Read more…
ocean_surface_flux_assemble rdb_ocean_surface_flux Subroutine

The single gate that derives Q_heat/Q_salt from the component set (§3.1/§3.3 of the PR-12 plan) — the exact analogue of vmix_assemble: fillers contribute components, this routine alone derives the net fields every downstream kernel reads. A no-op unless sf%use_components — with components off, Q_heat / Q_salt are exactly what set_surface_flux_const (or a field-override path) left them, byte-for-byte.

Read more…
ocean_surface_flux_bytes rdb_ocean_surface_flux Function

Counted allocatable footprint of the surface flux slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_surface_restore_apply_tracers rdb_ocean_surface_flux Subroutine

Surface buoyancy restoring (MOM6 RESTOREBUOY): relax the top-layer (k = nz) temperature / salinity toward scalar targets with a piston velocity p [m/s]. Unlike ocean_surface_flux_apply_tracers (which reads a pre-filled static Q_* field), the restoring flux is DYNAMIC — it depends on the live SST / SSS each thermo step — so it is computed in-kernel from (target - surface_concentration) rather than a stored field. This keeps the const-flux path byte-for-byte unchanged and adds no second device sync of Q_*.

Read more…
ocean_surface_stress_apply_cover rdb_ocean_surface_stress Subroutine

Zero the wind-stress pair on every C-grid face that touches an ice-covered cell, then refresh stress_mag from the masked pair. The two halves are ONE call on purpose: a masked tau with a stale stress_mag would leave KPP/EPBL mixing on a wind that no longer reaches the water.

Read more…
ocean_surface_stress_apply_tendencies rdb_ocean_surface_stress Subroutine

Outer-shim — flattens the derived-type derefs before the do concurrent body sees them. Explicit-shape dimensions derived from ms and passed to the impl as scalar args. no_wait (optional, default .false.): forwarded to the impl — when .true. the apply DC loops run on OpenACC queue 1 without a trailing sync, so the batched velocity-apply chain in run_stage_split !$acc wait(1)s ONCE. Default ⇒ blocking. Not pure because of the async/wait directives.

ocean_surface_stress_bytes rdb_ocean_surface_stress Function

Counted allocatable footprint of the surface stress slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_surface_stress_compute_tendencies rdb_ocean_surface_stress Subroutine

Fill du_stress / dv_stress with the surface stress acceleration tau / (rho_0 * h_top) at k = nz. Outer-shim: hoist the derived-type derefs (this%tau_x, this%du_stress%data, ms%h_layer, ms%wet_mask) to the host, dispatch to flat-impl.

ocean_surface_stress_refresh_mag rdb_ocean_surface_stress Subroutine

Recompute stress_mag from the CURRENT tau_x/tau_y, shape taken from the already-allocated arrays (no grid needed — this is the grid-free twin of ocean_surface_stress_set_derived, for callers that hold the slot but not the grid).

Read more…
ocean_surface_stress_set_derived rdb_ocean_surface_stress Subroutine

Fill stress_mag from the current tau_x/tau_y — the MOM6 set_derived_forcing_fields analogue (PR-12), and the public entry point configure_ocean_forcing calls after the wind_config dispatch. Host-side (the wind field is configure-static in v1, so one fill at configure suffices — a future time-varying wind reader re-calls this after each read). Not pure: writes into ss. Call BEFORE enter_data, or follow with !$acc update device(ss%stress_mag) if already mapped. In practice this is a defensive re-fill only: every set_wind_stress_* setter already refreshes stress_mag in step (ocean_surfstress_refresh_stress_mag) so stress_mag is never stale relative to tau_x/tau_y regardless of call site (production driver OR a unit test that never reaches configure_ocean_forcing).

ocean_surface_stress_set_shelf_from_ustar rdb_ocean_surface_stress Subroutine

Publish the ice-base stress from a FRICTION VELOCITY: stress_shelf = rho_0 * u_*^2.

Read more…
ocean_surfflux_alloc_components rdb_ocean_surface_flux Subroutine

Allocate the 22-field component set + the two p_surf* fields, all source=0.0_wp, shape (nx_total, ny_total). Private — called only from set_components.

ocean_surfflux_assemble_cover_impl rdb_ocean_surface_flux Subroutine

Ice-shelf-cover twin of ocean_surfflux_assemble_impl: the open-water factor open_f = 1 - cover_frac multiplies the ATMOSPHERIC group and NOT the cavity group. Grouping, spelt out because it is the whole point of this kernel:

Read more…
ocean_surfflux_assemble_impl rdb_ocean_surface_flux Subroutine

Flat do concurrent kernel — explicit-shape dummies, integer dims declared first (decl-order, ifx #8586). See ocean_surface_flux_assemble for the physics; this is the arithmetic verbatim.

ocean_surfflux_cover_const_impl rdb_ocean_surface_flux Subroutine

Flat do concurrent kernel behind ocean_surface_flux_apply_cover_const — explicit-shape dummies, integer dims first (decl-order, ifx #8586).

ocean_surfflux_dealloc_components rdb_ocean_surface_flux Subroutine

Deallocate the component set (no-op on an already-unallocated slot — every deallocate is if (allocated(...))-guarded). Shared by destroy and by set_components re-entry.

ocean_surfflux_destroy rdb_ocean_surface_flux Subroutine
ocean_surfflux_enter_data rdb_ocean_surface_flux Subroutine

Type-bound wrapper — delegates to the non-polymorphic impl so the device-attach map base is the heap object, not a polymorphic stack box (AMD libomptarget cross-slot-overlap fix).

ocean_surfflux_enter_data_impl rdb_ocean_surface_flux Subroutine
ocean_surfflux_exit_data rdb_ocean_surface_flux Subroutine
ocean_surfflux_exit_data_impl rdb_ocean_surface_flux Subroutine
ocean_surfflux_init rdb_ocean_surface_flux Subroutine
ocean_surfflux_set_components rdb_ocean_surface_flux Subroutine

Configure-time gate for the PR-12 component set (&ocean_forcing_nml enable_components). init runs before the namelist gate is known, so allocation happens HERE rather than in init: enable = .false. (default) leaves use_components false and allocates nothing — bit-identical, zero extra device memory. enable = .true. allocates the full component set (source=0.0_wp) and flips the gate so ocean_surface_flux_assemble stops early-returning. Must be called BEFORE enter_data (rdb_ocean_state.F90’s orchestrator) so the freshly-allocated arrays get mapped. Re-entrant: calling again with a different enable deallocates first.

ocean_surfflux_set_const rdb_ocean_surface_flux Subroutine

Fill Q_heat / Q_salt uniformly from scalar values and set the has_heat / has_salt flags so the apply-tracers kernel fires. Mirrors set_wind_stress_const on the stress side. Host only — call enter_data afterwards (or !$acc update device if already mapped) to sync to the GPU.

ocean_surfflux_set_p_surf_const rdb_ocean_surface_flux Subroutine

Seed the atmospheric surface-pressure INPUT component p_surf_atm (Pa) uniformly from a scalar namelist value (PR-17 &ocean_psurf_nml p_surf_const). Full overwrite of the pristine atmospheric base; the assembled total p_surf is built from it once per outer step in p_surf_update_seam. No-op when the component set is not allocated (use_components=.false.) — the &ocean_psurf_nml enable guard in validate_config already requires enable_components=.true., so a live consumer never hits the no-op. Host only — call enter_data afterwards (or !$acc update device if already mapped) to sync to the GPU.

Read more…
ocean_surfflux_set_restore rdb_ocean_surface_flux Subroutine

Seed the surface buoyancy restoring (MOM6 RESTOREBUOY) parameters and set the has_restore_T / has_restore_S gates. Sibling to set_surface_flux_const / set_sw_penetration — kept separate so existing callers are unchanged. The piston velocities arrive in m/day (the MOM6 FLUXCONST_* unit) and are converted to MKS m/s here. Effective-enable guard: has_restore_* = enable_* .and. piston /= 0, so an enabled switch with a zero piston is a silent no-op (rather than restoring everything toward the 0-degC / 0-PSU default target). Host only; all knobs are read host-side as by-value arguments to the device _impl, so no extra device sync beyond copyin(this).

ocean_surfflux_set_sw rdb_ocean_surface_flux Subroutine

Seed the shortwave-penetration band parameters and set the has_sw gate (sw_pen_frac /= 0). Sibling to set_surface_flux_const — kept separate so existing callers of the heat/salt setter are unchanged. Host only; the scalars are read host-side by the apply kernel (they parameterise the by-value arguments passed into the device _impl), so no extra device sync is needed beyond the existing copyin(this).

Read more…
ocean_surfstress_cover_impl rdb_ocean_surface_stress Subroutine

Flat do concurrent kernel behind ocean_surface_stress_apply_cover — explicit-shape dummies, integer dims first (decl-order, ifx

Read more…
ocean_surfstress_derived_impl rdb_ocean_surface_stress Subroutine

stress_mag(i,j) = |tau| at cell centres — literal copy of the three lines this dedups from rdb_ocean_vmix.F90 (KPP, :575-577/:641-643, pre-PR-12) and rdb_ocean_epbl.F90 (:974-976, pre-PR-12): SAME face-average op order, so the substitution at each call site is bit-identical (PR-12 §7.5). Explicit-shape dummies, integer dims first (decl-order).

ocean_surfstress_destroy rdb_ocean_surface_stress Subroutine
ocean_surfstress_enter_data rdb_ocean_surface_stress Subroutine

Type-bound wrapper — delegates to the non-polymorphic impl so the device-attach map base is the heap object, not a polymorphic stack box (AMD libomptarget cross-slot-overlap fix). Slot-header presence comes from the orchestrator’s root copyin(state); only the leaf arrays + scratch are attached here.

ocean_surfstress_enter_data_impl rdb_ocean_surface_stress Subroutine
ocean_surfstress_exit_data rdb_ocean_surface_stress Subroutine
ocean_surfstress_exit_data_impl rdb_ocean_surface_stress Subroutine
ocean_surfstress_init rdb_ocean_surface_stress Subroutine
ocean_surfstress_refresh_stress_mag rdb_ocean_surface_stress Subroutine

Type-bound-facing shim behind every set_wind_stress_* setter: strips the polymorphic box (same reason as enter_data) and delegates to ocean_surface_stress_refresh_mag. Keeping this call inside each setter — rather than requiring a separate explicit call — is what keeps stress_mag correct for every existing caller, including unit tests that build ocean_surface_stress_t directly and never reach configure_ocean_forcing.

ocean_surfstress_set_2gyre rdb_ocean_surface_stress Subroutine

Fill tau_x with the MOM6 2gyre profile, tau_x(i,j) = taux_mag · (1 − cos(2π · (y − y_south) / y_len)), and zero tau_y. In Cartesian terms (y − y_south) / y_len is the normalised position from the south wall of the physical domain (0 at south, 1 at north), so the formula reduces to taux_mag · (1 − cos(2π · ((j_phys − 0.5) / ny_phys))) with j_phys = j − nghost. Physical-interior rows only; ghost rows stay at zero so wall faces see no spurious stress. Host only — call enter_data afterwards (or !$acc update device if already mapped).

Read more…
ocean_surfstress_set_const rdb_ocean_surface_stress Subroutine

Fill tau_x / tau_y uniformly with the given scalar values. Convenience helper for the spatially-constant wind case (the Tier-1 default and most unit tests). Host only — call enter_data afterwards (or !$acc update device if already mapped) to sync to GPU. Refreshes stress_mag in step (PR-12) so every existing caller — production and unit test alike — gets a consistent stress_mag with no separate call required.

ocean_surfstress_set_neverworld2 rdb_ocean_surface_stress Subroutine

Fill tau_x with the Neverworld2 zonal wind-stress profile (Marques et al. 2022, GMD; MOM6-inspired) and zero tau_y. τ_x is a 3-band piecewise function of the normalized meridional position y = (j_phys − 0.5)/ny_phys ∈ [0,1] (which equals MOM6’s (lat − south)/len_lat on a uniform grid), scaled by the peak stress taux_mag (Pa), with off = 0.02:

Read more…
ocean_tidal_mixing_bytes rdb_ocean_tidal_mixing Function

Counted allocatable footprint of the tidal mixing slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_tidal_mixing_destroy rdb_ocean_tidal_mixing Subroutine
ocean_tidal_mixing_enter_data rdb_ocean_tidal_mixing Subroutine
ocean_tidal_mixing_enter_data_impl rdb_ocean_tidal_mixing Subroutine
ocean_tidal_mixing_exit_data rdb_ocean_tidal_mixing Subroutine
ocean_tidal_mixing_exit_data_impl rdb_ocean_tidal_mixing Subroutine
ocean_tidal_mixing_init rdb_ocean_tidal_mixing Subroutine

Allocate the persistent fields. Always allocates (configure runs after init, so enable is not known yet); the off-cost is one 2D field + one interface field.

ocean_tidal_mixing_set_e_uniform rdb_ocean_tidal_mixing Subroutine

Fill the bottom energy field e_in with a uniform value. Host loop (setup phase); call after init, before enter_data.

ocean_tides_bytes rdb_ocean_tides Function

Counted allocatable footprint of the tides slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_tides_destroy rdb_ocean_tides Subroutine
ocean_tides_enter_data rdb_ocean_tides Subroutine

Attach the device-resident tide arrays. Only when enabled. select-type -> non-poly _impl (AMD libomptarget class-box rule).

ocean_tides_enter_data_impl rdb_ocean_tides Subroutine
ocean_tides_exit_data rdb_ocean_tides Subroutine
ocean_tides_exit_data_impl rdb_ocean_tides Subroutine
ocean_tides_init rdb_ocean_tides Subroutine

Minimal init — the real allocation + astronomy fill happens in tides_configure_astronomy / tides_build_struct once the namelist + metrics are available (host, before enter_data).

ocean_top_drag_apply_tendencies rdb_ocean_top_drag Subroutine

u += dt*du_drag, v += dt*dv_drag over the whole face array — layers outside the top boundary layer carry an exact zero.

Read more…
ocean_top_drag_bytes rdb_ocean_top_drag Function

Counted allocatable footprint of the top-drag slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_top_drag_compute_tendencies rdb_ocean_top_drag Subroutine

Fill du_drag / dv_drag with the top-boundary drag acceleration, stress_top with the cell-centred stress magnitude, and (when implicit_fold) lambda_top_u/v with the k = k_top Rayleigh rate the vdiff diagonal consumes (the rate-capture row and the sink row MUST be the same row).

Read more…
ocean_top_drag_destroy rdb_ocean_top_drag Subroutine

Release the slot. is_init is cleared FIRST.

ocean_top_drag_enter_data rdb_ocean_top_drag Subroutine

Type-bound wrapper — delegates to the non-polymorphic impl so the device-attach map base is the heap object, not a polymorphic box.

ocean_top_drag_enter_data_impl rdb_ocean_top_drag Subroutine

copyin (not create) for the four host-filled 2-D fields — cover_u/cover_v are STATIC configure-time geometry and would otherwise reach the device as allocator leftovers (mem:separate).

ocean_top_drag_exit_data rdb_ocean_top_drag Subroutine
ocean_top_drag_exit_data_impl rdb_ocean_top_drag Subroutine
ocean_top_drag_init rdb_ocean_top_drag Subroutine

Allocate the slot. Gated on enable (latched before this runs), so a run without an ice shelf pays five (1,1) placeholders and two (1,1,1) scratch buffers.

ocean_varmix_build_static rdb_ocean_varmix Subroutine

Fill the static f2_dx2_*, beta_dx2_*, and l2_* face fields from the (curvilinear) metrics + the cell-centre Coriolis magnitude f_centre. Called ONCE after init + configure + metrics fill (so oneOrTwo, visbeck_l_scale, and the device-resident metrics are known), BEFORE the device map. HOST loops only — these are static (functions of geometry + planetary f) and never change with time.

Read more…
ocean_varmix_bytes rdb_ocean_varmix Function

Counted allocatable footprint of the VarMix slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_varmix_destroy rdb_ocean_varmix Subroutine
ocean_varmix_enter_data rdb_ocean_varmix Subroutine
ocean_varmix_enter_data_impl rdb_ocean_varmix Subroutine
ocean_varmix_exit_data rdb_ocean_varmix Subroutine
ocean_varmix_exit_data_impl rdb_ocean_varmix Subroutine
ocean_varmix_init rdb_ocean_varmix Subroutine

Allocate the static grid terms, the per-step diagnostics, and the KhTh/KhTr base face fields. Always allocates (configure runs after init); the static f2_dx2_* / beta_dx2_* / l2_* are filled by build_static once the metrics + f_centre are known. Setup uses plain host allocation (no do concurrent before enter_data).

ocean_vcoord_build_zref_full rdb_ocean_vcoord Subroutine

Populate z_ref(i, j, 0:nz_ml) per column from the local bathymetry h_bed(i, j). Mirrors zstar_full_build_column from src/ALE/rdb_vcoord.F90 but as a 2D loop owned by this slot — keeps the coastal helper untouched while letting the ocean path own its z_ref lifecycle.

Read more…
ocean_vcoord_bytes rdb_ocean_vcoord Function

Counted allocatable footprint of the vertical coordinate slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_vcoord_closed_face_masks rdb_ocean_vcoord Subroutine

Partial-step z-level FACE CLOSURE mask for VCOORD_Z_FIXED (&vcoord_nml zfixed_closed_faces; Adcroft, Hill & Marshall 1997; Losch 2008 §2.1 for the ice-shelf cavity).

Read more…
ocean_vcoord_compute_target_h rdb_ocean_vcoord Subroutine

Thin polymorphic wrapper. A type-bound procedure’s passed object must be class(...), but mapping a polymorphic list item into a target / offload region is unspecified behaviour (gfortran -Wopenmp; see FORTRAN_STYLE.md) — so the do concurrent kernels live in the type(ocean_vcoord_t) _impl and this wrapper only resolves the concrete type. ocean_vcoord_t is never extended, so the dynamic type is always the declared type. Mirrors the enter_data/exit_data split.

ocean_vcoord_compute_target_h_impl rdb_ocean_vcoord Subroutine

Populate target_h(i,j,k) from the column-total depth (H, constant per column for the ocean path; coastal would pass the bathymetry) and the free-surface anomaly η.

Read more…
ocean_vcoord_compute_target_h_rho rdb_ocean_vcoord Subroutine

Thin polymorphic wrapper for the isopycnal (VCOORD_RHO) and hybrid z*/isopycnal (VCOORD_HYCOM) target-grid build. Mirrors ocean_vcoord_compute_target_h (resolves the concrete type so the do concurrent kernel runs on type(ocean_vcoord_t), never a polymorphic list item). Separate from compute_target_h because the RHO/HYCOM branch needs the per-layer T/S concentrations and the device-resident EOS coefficients, which the shared pure (total_h, eta) TBP cannot carry.

Read more…
ocean_vcoord_compute_target_h_rho_impl rdb_ocean_vcoord Subroutine

Isopycnal regrid: place layer interfaces on the prescribed rho_target(0:nz) potential-density surfaces. ONE do concurrent(j,i) over columns, each running the full density-space inversion on NZ_STACK_MAX fixed-size locals — no host loop, no per-call allocate.

Read more…
ocean_vcoord_count_bed_steps rdb_ocean_vcoord Function

Count the wet velocity faces at which the two columns’ BED falls in different nominal z_fixed layers — a bed staircase step that crosses a nominal interface, so that an OPEN face pairs a live layer on one side with a bed FILLER on the other. That is the face &vcoord_nml zfixed_closed_faces closes; left open, the FV pressure gradient across the step drives the flow from rest (configure_ocean_closed_faces refuses the configuration).

Read more…
ocean_vcoord_count_ledges rdb_ocean_vcoord Function

Count LEDGE cells: a cell that is LIVE at layer k but all four of whose own-layer faces are closed, i.e. water the mask has isolated. A ledge needs a one-cell-wide spike in the bed or the draft; it is inert by construction (no flux in or out, and its velocity is zeroed every stage), but a non-zero count is worth saying out loud once at configure, because it means the mask is walling off real water.

Read more…
ocean_vcoord_destroy rdb_ocean_vcoord Subroutine
ocean_vcoord_enter_data rdb_ocean_vcoord Subroutine

Map every host allocatable onto the device. Idempotent guard via is_init.

ocean_vcoord_enter_data_impl rdb_ocean_vcoord Subroutine
ocean_vcoord_eta0_target rdb_ocean_vcoord Subroutine

The target layer thickness at eta = 0 of a GEOMETRIC family that vanishes layers — the ONE definition of “live” that the partial-step face mask (configure_ocean_closed_faces) and the on-target initial seed share with the running ALE regrid.

Read more…
ocean_vcoord_exit_data rdb_ocean_vcoord Subroutine
ocean_vcoord_exit_data_impl rdb_ocean_vcoord Subroutine
ocean_vcoord_geometric_target rdb_ocean_vcoord Subroutine

Geometric target-grid kernels (EULERIAN_Z, SIGMA, ZSIGMA, ZSTAR_SIGMA, ZSTAR_FULL; formulae documented on ocean_vcoord_compute_target_h_impl). Flat on purpose — every array an explicit-shape dummy, every knob a scalar dummy — so no derived-type component and no associate-name reaches a do concurrent (see ocean_vcoord_rho_target for the GPU fault that shape caused there).

ocean_vcoord_init rdb_ocean_vcoord Subroutine

Allocate every per-column array the slot owns: dsig, z_ref_global, target_h, z_ref. All sized once at init — grids don’t resize. Host allocations only; enter_data ships them to the device.

ocean_vcoord_is_terrain_following rdb_ocean_stability_audit Function

Does this VCOORD_* code put the layer interfaces on surfaces that follow the bottom (and, under an ice shelf, the ice base)?

Read more…
ocean_vcoord_k_bot_from_target rdb_ocean_vcoord Subroutine

The shared FIRST-LIVE-LAYER index counting UP from the bed — multilayer_state_t%k_bot and its two face twins. The bed-side mirror of ocean_vcoord_k_top_from_target, built from the same layer-thickness field by the same strict > h_vanished test.

Read more…
ocean_vcoord_k_top_from_target rdb_ocean_vcoord Subroutine

The shared FIRST-LIVE-LAYER index, counting down from the top — multilayer_state_t%k_top and its two face twins — built from a layer-thickness field.

Read more…
ocean_vcoord_rho_target rdb_ocean_vcoord Subroutine

Column kernel of the RHO / HYCOM regrid (algorithm: see ocean_vcoord_compute_target_h_rho_impl). Flat on purpose: every array is an explicit-shape dummy and every knob a scalar dummy — no derived-type component and no associate reaches the do concurrent.

Read more…
ocean_vcoord_rho_target_column rdb_ocean_vcoord Subroutine

One column of the RHO / HYCOM regrid (steps 0-5 of ocean_vcoord_compute_target_h_rho_impl) — the per-thread body of ocean_vcoord_rho_target. Same module as its caller (the project rule for !$acc routine seq callees of a do concurrent).

ocean_vcoord_set_z_fixed_profile rdb_ocean_vcoord Subroutine

Install a stretched VCOORD_Z_FIXED nominal profile: flip the surface-first thicknesses into the bottom-up z_fixed_dz, build the interface table z_fixed_zi by accumulating from the surface (z_fixed_zi(nz) = 0 exactly), set z_fixed_h_ref to the total and raise z_fixed_use_profile. Setup-time host code; must run BEFORE enter_data (the copyin captures the tables).

ocean_vcoord_z_fixed_target rdb_ocean_vcoord Subroutine

VCOORD_Z_FIXED target grid — quasi-geopotential interfaces under a rigid top, with inert fillers and a partial cell at BOTH ends (Yung, Hallberg, Adcroft & Morrison 2026, JAMES, Fig. 1b: quasi-z layers are geopotential and VANISH where they outcrop into the ice base; Asay-Davis et al. 2016 §3.1.5: z-level models use both partial top and bottom cells).

Read more…
ocean_vcoord_z_fixed_target_uniform rdb_ocean_vcoord Subroutine

ocean_vcoord_z_fixed_target on the UNIFORM nominal spacing h_nominal — the historical signature, for callers (tests, setup code without a vcoord slot) that have no profile tables. Same kernel, use_profile = .false., so the arithmetic is the uniform branch’s exactly; the two tables are never read.

ocean_vcoord_zstar_target rdb_ocean_vcoord Subroutine

VCOORD_ZSTAR target grid — MOM6 z* (REGRIDDING_COORDINATE_MODE = "Z*", build_zstar_column, MOM6 src/ALE/coord_zlike.F90 lines 65-146): the FIXED nominal z profile of z_fixed (&vcoord_nml z_fixed_profile uniform / list / tanh — the same z_fixed_zi table, not a parallel one) DILATED per column by the free-surface stretching, over a partial bed cell and inert bed fillers.

Read more…
ocean_vdiff_bytes rdb_ocean_vdiff Function

Counted allocatable footprint of the implicit vertical diffusion slot (0 when unallocated).

ocean_vdiff_destroy rdb_ocean_vdiff Subroutine
ocean_vdiff_enter_data rdb_ocean_vdiff Subroutine
ocean_vdiff_enter_data_impl rdb_ocean_vdiff Subroutine
ocean_vdiff_exit_data rdb_ocean_vdiff Subroutine
ocean_vdiff_exit_data_impl rdb_ocean_vdiff Subroutine
ocean_vdiff_init rdb_ocean_vdiff Subroutine
ocean_vert_adv_destroy rdb_ocean_vertical_advection Subroutine
ocean_vert_adv_enter_data rdb_ocean_vertical_advection Subroutine

Type-bound wrapper — delegates to the non-polymorphic impl so the device-attach map base is the heap object, not a polymorphic stack box (AMD libomptarget cross-slot-overlap fix).

ocean_vert_adv_enter_data_impl rdb_ocean_vertical_advection Subroutine
ocean_vert_adv_exit_data rdb_ocean_vertical_advection Subroutine
ocean_vert_adv_exit_data_impl rdb_ocean_vertical_advection Subroutine
ocean_vert_adv_init rdb_ocean_vertical_advection Subroutine
ocean_vertical_advection_bytes rdb_ocean_vertical_advection Function

Counted allocatable footprint of the vertical advection slot (0 when unallocated).

ocean_viscous_cfl_limit rdb_ocean_stability_audit Function

Accessor for VISCOUS_CFL_LIMIT — tests reference this instead of duplicating the literal.

ocean_viscous_cfl_max_dt rdb_ocean_stability_audit Function

Largest dt (s) that keeps ocean_viscous_cfl_number at or below limit, at fixed nu_h/dx_min — the “reduce dt below …” half of the audit’s suggested fix.

ocean_viscous_cfl_max_nu_h rdb_ocean_stability_audit Function

Largest nu_h (m^2/s) that keeps ocean_viscous_cfl_number at or below limit, at fixed dt/dx_min — the “reduce nu_h below …” half of the audit’s suggested fix.

ocean_viscous_cfl_number rdb_ocean_stability_audit Function

nu_h*dt/dx_min^2 — the single-axis viscous-diffusion stability number checked against VISCOUS_CFL_LIMIT. dx_min MUST be the smallest actual cell edge in the domain (e.g. metrics_dx_min/ocean_stability_min_cell), never a nominal &grid_nml dx/dy (degrees on non-Cartesian grids). dx_min<=0 (degenerate/unset grid) returns 0 (no constraint expressible).

ocean_vmix_bytes rdb_ocean_vmix Function

Counted allocatable footprint of the vertical mixing slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_vmix_destroy rdb_ocean_vmix Subroutine
ocean_vmix_enter_data rdb_ocean_vmix Subroutine
ocean_vmix_enter_data_impl rdb_ocean_vmix Subroutine
ocean_vmix_exit_data rdb_ocean_vmix Subroutine
ocean_vmix_exit_data_impl rdb_ocean_vmix Subroutine
ocean_vmix_init rdb_ocean_vmix Subroutine

Allocate the kv / kt / ks diffusivity fields at layer interfaces. Default values: kv = kv_bg (= pp81_nu_bg), kt = ks = kt_bg (= pp81_kappa_bg) at interior interfaces; boundary interfaces k=1 and k=nz+1 are zeroed (closed BC). BL fields (bl_depth, gamma_*) seed at zero. ks is allocated so the assembly stage (vmix_assemble) can floor/clip it; vmix_split_kd_heat_salt derives its live value from kt every stage, and vdiff_apply_tracers consumes it for salinity + every passive tracer.

Read more…
ocean_wave_speed_build_static rdb_ocean_wave_speed Subroutine

Copy a pre-filled cell-centre Coriolis magnitude |f| (1/s) onto the slot (mirror of ocean_meke_set_f_centre — the caller builds f_centre via fill_coriolis_centre / metrics_fill_coriolis, which handles beta-plane AND planetary/spherical), and fill the static beta_centre = |grad f| field with the SAME centred-difference stencil meke_length_scales uses (edge rows/columns left at 0 -> the extratropical Rd = cg1/|f| branch there).

Read more…
ocean_wave_speed_bytes rdb_ocean_wave_speed Function

Counted allocatable footprint of the wave speed slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.

ocean_wave_speed_destroy rdb_ocean_wave_speed Subroutine
ocean_wave_speed_enter_data rdb_ocean_wave_speed Subroutine
ocean_wave_speed_enter_data_impl rdb_ocean_wave_speed Subroutine
ocean_wave_speed_exit_data rdb_ocean_wave_speed Subroutine
ocean_wave_speed_exit_data_impl rdb_ocean_wave_speed Subroutine
ocean_wave_speed_init rdb_ocean_wave_speed Subroutine

Allocate the persistent (nx, ny) fields. Always allocates (configure runs after init, so enable is not known yet); the off-state footprint is four 2D arrays.

oh_count_bt_group rdb_ocean_halo_counters Subroutine

Increment the bt_group counter. Called once in ocean_halo_bt_group_2d bodies.

oh_count_bt_u_mid rdb_ocean_halo_counters Subroutine

Increment the bt_u_mid counter. Called at the mid-substep bt_ubt face_x exchange site.

oh_count_centre_2d rdb_ocean_halo_counters Subroutine

Increment the centre_2d standalone counter. Called at the top of each ocean_halo_centre_2d body.

oh_count_centre_3d rdb_ocean_halo_counters Subroutine

Increment the centre_3d standalone counter. Called once in ocean_halo_centre_3d (after suppressing inner 2d bumps).

oh_count_face_x_2d rdb_ocean_halo_counters Subroutine

Increment the face_x_2d standalone counter. Called at the top of each ocean_halo_face_x_2d body.

oh_count_face_x_3d rdb_ocean_halo_counters Subroutine

Increment the face_x_3d standalone counter. Called once in ocean_halo_face_x_3d (after suppressing inner 2d bumps).

oh_count_face_y_2d rdb_ocean_halo_counters Subroutine

Increment the face_y_2d standalone counter. Called at the top of each ocean_halo_face_y_2d body.

oh_count_face_y_3d rdb_ocean_halo_counters Subroutine

Increment the face_y_3d standalone counter. Called once in ocean_halo_face_y_3d (batched, no per-layer 2d loop).

oh_count_ml_state rdb_ocean_halo_counters Subroutine

Increment the ml_state counter. Called once in ocean_halo_exchange_ml_state.

oh_count_msgs rdb_ocean_halo_counters Subroutine

Increment the MPI isend post counter by n. NOT subject to the suppress depth: messages are physical MPI operations regardless of semantic grouping. Called in the MPI rdb_ocean_halo once per exchange after each set of HALO_ISEND_N calls; n is the number of ISENDs just posted.

oh_count_suppress_off rdb_ocean_halo_counters Subroutine

Decrement suppress depth (floored at 0) after a wrapper completes.

oh_count_suppress_on rdb_ocean_halo_counters Subroutine

Increment suppress depth so inner primitive increments are no-ops. Nesting-safe: each on/off pair increments/decrements a counter so nested suppress pairs (ml_state wrapping 3d wrappers) work correctly.

oh_count_suppressed rdb_ocean_halo_counters Function

Return .true. if suppress depth > 0 (any suppress scope is active).

oh_counters_format rdb_ocean_halo_counters Function

Return a one-line counter summary string.

Read more…
oh_counters_get rdb_ocean_halo_counters Subroutine

Return all 9 semantic counters in one call.

oh_counters_msgs rdb_ocean_halo_counters Function

Return the total MPI ISEND post count. NOT included in oh_counters_total (separate physical counter).

oh_counters_reset rdb_ocean_halo_counters Subroutine

Reset all 9 semantic counters and the message counter to zero. Does NOT reset the suppress flag.

oh_counters_total rdb_ocean_halo_counters Function

Return the sum of all 9 semantic counters.

ok_all_ranks rdb_ice_transport Subroutine

Make a validity flag rank-uniform (global AND, as an exact min of 0/1) BEFORE anyone acts on it: a rank-local early return would strand the other ranks in the next substep’s exchange. No collective unless the run is decomposed (a serial run inside a multi-rank job — the bit-identity reference — stays local).

one_m_exp_x rdb_ocean_epbl Function

(1 - exp(-x)) / x, Taylor-safe at small x.

open_ghost_fill_edge rdb_ocean_obc_baroclinic Function

Edge types that receive the open zero-gradient ghost fill (velocity here, η in the barotropic substep — kept identical on purpose). OPEN / TIDAL / CHAPMAN / CLAMPED; NOT NESTED (barotropic-wall path).

open_stream rdb_ocean_diag_netcdf Subroutine

Create the NetCDF file, define dims + vars for every currently-registered diag var, and bind the post-fire emit hook. Must be called AFTER all register calls land — vars registered later get no NetCDF binding and are not written.

Read more…
output_rank_filename rdb_io_netcdf Function

Generate a per-rank filename: /_rank_NNNNNN.nc

p_surf_configure rdb_ocean_p_surf Subroutine

Allocate eta_ib/eta_seam (host, before enter_data). No-op when .not. enable (bit-identical; zero extra device memory). Mirrors tides_configure_astronomy.

p_surf_update_seam rdb_ocean_p_surf Subroutine

Refresh the combined seam field eta_seam for the current outer step from the assembled total surface pressure p_surf (read-only; see the module header for where the assembly happens): fold eta_ib = -p_surf/(rho0 g_bt) into eta_seam = eta_ib [+ eta_tide]. g_bt is the barotropic-substep gravity (bt_work%g_bt), passed in at call time so the seam scales with the ocean’s own dynamics. eta_tide (optional) is the equilibrium-tide + scalar-SAL seam, added when the tide is on. Host does one reciprocal; the fill is a single explicit-shape do concurrent. p_surf is the device-resident ocean_surface_flux_t%p_surf component array.

p_surf_update_seam_impl rdb_ocean_p_surf Subroutine

Flat-impl device fill (explicit-shape dummies — no descriptor walk). eta_ib(i,j) = -p_surf(i,j)*i_rho0_g and eta_seam(i,j) = eta_ib(i,j) [+ eta_tide(i,j)]. Loop-invariant use_tide branch kept INSIDE the single do concurrent (one launch, uniform branch is ~free). Contiguous index (i) innermost.

p_top_has_producer rdb_config Function

Is there anything in this configuration that WRITES multilayer_state_t%p_top?

Read more…
parse_bdrag_variant rdb_ocean_bottom_drag Function

Translate a namelist string into a BDRAG_* code. An unrecognised string returns BDRAG_INVALID (PR-6 fail-loud — a typo must not silently select the quadratic default over the linear form or vice versa; the two obey different physics).

parse_buoyancy_coeffs rdb_ocean_vmix Function

Map the &ocean_vmix_nml buoyancy_coeffs string to a BUOY_COEFFS_* tag; BUOY_COEFFS_INVALID for an unrecognised string, which configure_ocean_vmix turns into a fail-loud abort (never a silent fallback to the constants). The accepted set must match the nml_enum allowed= list in register_ocean_vmix.

parse_cadence_attr rdb_ocean_diag Subroutine

Parse a cadence attribute <int><unit> (unit s/m/h/d) to seconds. ok=.false. if s is not a well-formed positive cadence.

parse_cavity_draft_config rdb_ocean_cavity Function

&ocean_cavity_dyn_nml draft_config -> CAVITY_DRAFT_*. Returns CAVITY_DRAFT_INVALID on an unrecognised spelling — the caller fails loud; there is no silent default.

parse_cavity_draft_sign rdb_ocean_cavity Function

&ocean_cavity_dyn_nml draft_sign -> CAVITY_SIGN_*. Returns CAVITY_SIGN_INVALID on an unrecognised spelling — the caller fails loud.

parse_cavity_draft_source rdb_ocean_cavity Function

&ocean_cavity_dyn_nml draft_source -> CAVITY_SOURCE_*.

parse_cavity_exchange_law rdb_ocean_cavity_melt Function

Translate an exchange-law string into a CAVITY_LAW_* code. RESERVED laws parse successfully — the refusal belongs to cavity_exchange_velocities, which returns CAVITY_MELT_NOT_IMPLEMENTED — so that a typo (CAVITY_LAW_INVALID) and an honest request for unwritten physics stay distinguishable.

parse_cavity_freshwater rdb_ocean_cavity_melt Function

Translate a &ocean_cavity_melt_nml freshwater string into a CAVITY_FW_* code. The accepted set MIRRORS the nml_enum registration in register_ocean_cavity_melt — the two lists move together.

parse_cavity_ice_mode rdb_ocean_cavity_melt Function

Translate an ice-conduction string into a CAVITY_ICE_* code.

parse_cavity_volume_comp rdb_ocean_cavity_melt Function

Translate a &ocean_cavity_melt_nml volume_compensation string into a CAVITY_VC_* code. Mirrors the nml_enum list.

parse_constituent_list rdb_ocean_setup Subroutine

Tokenize a whitespace/comma-separated constituent list into catalog indices (case-insensitive). Unknown tokens fail loud; nconst is the count of recognised entries.

parse_coriolis_scheme rdb_ocean_metrics Function

Map a &ocean_grid_nml coriolis_scheme string onto its enum.

parse_date_string rdb_ocean_tide_astro Subroutine

Parse a “YYYY-MM-DD” calendar date. ok = .false. on any malformed field (caller decides fail-loud policy).

parse_diag_remap_scheme rdb_ocean_diag_fills Function

Map a &ocean_diag_nml diag_remap_scheme string to the REMAP_* enum; returns -1 for an unrecognised name (caller fails loud).

parse_diag_spec rdb_ocean_diag Function

Parse the &ocean_diag_nml diags selection string into structured entries. Entries are whitespace/comma-separated; within an entry, colon-separated attributes are self-identifying (order-free):

Read more…
parse_eos_variant rdb_eos Function

Translate a &ocean_eos_nml eos=... string into an EOS_VARIANT_* code. Unrecognised values fall back to EOS_VARIANT_LINEAR (the default = bit-identical to runs that omit the knob). Membership in the device-callable set is enforced separately by eos_validate at configure time.

parse_epbl_combine rdb_ocean_epbl Function
parse_epbl_lt_scheme rdb_ocean_epbl Function
parse_epbl_mstar_scheme rdb_ocean_epbl Function
parse_epbl_vstar_scheme rdb_ocean_epbl Function
parse_file rdb_nml_schema Subroutine

Read the namelist file at path, then drive the parse. The file is the only on-disk touch; the walk runs on the in-memory lines (shared with the from-buffer path, parse_from_lines).

parse_frhat_scheme rdb_constants Function

Convert an &ocean_bt_nml frhat_scheme namelist string to a FRHAT_* constant. Unrecognised ⇒ default_code if given, else FRHAT_ARITHMETIC.

parse_from_lines rdb_nml_schema Subroutine

Walk an in-memory namelist (already split into lines): strip comments, scan for &group headers, dispatch keys. label names the source in error messages — a file path for parse_file, a sentinel (e.g. ““) for buffer parses.

parse_grid_config rdb_ocean_metrics Function

Map a &ocean_grid_nml grid_config string onto its enum. Unknown -> cartesian (the schema enum already validates the set; this is the canonical-name dispatch).

parse_group_body rdb_nml_schema Subroutine

Tokenize and apply key = value... pairs until ‘/’.

parse_kpp_sw_method rdb_ocean_vmix Function

Map the &ocean_thermo_nml kpp_sw_method string to a KPP_SW_* tag; -1 for an unrecognised string (fail-loud at validate_config).

parse_lateral_closure rdb_ocean_lateral_mix Function

Translate a namelist string into an LMIX_* code. Returns LMIX_INVALID on an unrecognised value (fail loud at configure); only “none”/”off”/”” map to LMIX_NONE.

parse_ocean_vcoord_type rdb_ocean_vcoord Function

Ocean-path wrapper around the canonical parse_vcoord_type in rdb_vcoord. Pins the unrecognised-string fallback to VCOORD_EULERIAN_Z — the ocean path’s “do nothing” default, distinct from the coastal path’s VCOORD_SIGMA fallback. Kept as a thin name-preserving wrapper so the ocean-only semantic (fallback choice) is visible at the call site.

parse_one_spec_token rdb_ocean_diag Subroutine

Parse a single name[:attr]... token into a diag_spec_t. Fails loud on an unrecognised attribute.

parse_opgf_variant rdb_ocean_pressure_force Function

Translate a namelist string into an OPGF_VARIANT_* code. Unrecognised values fall back to OPGF_VARIANT_FV_LITE (the production default).

parse_porous_eta_interp rdb_ocean_porous Function

Map &ocean_porous_nml eta_interp onto POROUS_ETA_*. An unrecognised string returns -1 so the caller can fail loud.

parse_porous_source rdb_ocean_porous Function

Map &ocean_porous_nml source onto POROUS_SOURCE_*. An unrecognised string returns -1 so the caller can fail loud.

parse_pv_adv_scheme rdb_coriolis_adv Function

Translate a namelist string into a PV_ADV_* code. An unrecognised string returns PV_ADV_INVALID (fail-loud — a typo must not silently degrade the PV interpolation). weno5/weno7 are implemented; they additionally require nghost >= 4/5 (pv_adv_required_nghost), checked at configure.

parse_pv_variant rdb_coriolis_adv Function

Translate a namelist string into a PV_VARIANT_* code. An unrecognised string returns PV_VARIANT_INVALID (PR-6: fail-loud — a typo must NOT silently degrade to SADOURNY, which is a materially different conservation law). "al81" still maps to PV_VARIANT_AL81 (the reservation), but that code is rejected by pv_variant_is_implemented at configure.

parse_remap_method rdb_vcoord Function

Convert a namelist string to a REMAP_* constant.

parse_stretching_mode rdb_vcoord Function

Convert a namelist string to a STRETCH_* constant.

parse_tdrag_variant rdb_ocean_top_drag Function

Translate a namelist string into a TDRAG_* code. An unrecognised string returns TDRAG_INVALID — a typo must abort rather than silently select one of two laws with different coefficient dimensions. Accepts the same spellings as parse_bdrag_variant, deliberately: the two groups mirror.

parse_tfreeze_set rdb_eos Function

Translate a &ocean_eos_nml tfreeze_set=... string into a TFREEZE_SET_* code. Unlike parse_eos_variant this one does NOT fall back to a default on a typo: it returns TFREEZE_SET_INVALID and validate_config aborts. Silently defaulting would turn a mistyped liquidus into a 0.03 °C shift in the freezing point — a melt-rate sign change at the margin, with no run-time symptom at all.

parse_tracer_recon rdb_recon_weno Function

Map a namelist string onto a TRACER_RECON_* code.

Read more…
parse_vcoord_type rdb_vcoord Function

Convert a namelist string to a VCOORD_* constant (shared by coastal and ocean backends). Unrecognised ⇒ default_code if given, else VCOORD_SIGMA. Ocean callers pass default_code = VCOORD_EULERIAN_Z.

parse_z_fixed_profile rdb_vcoord Function

&vcoord_nml z_fixed_profile string -> ZFIXED_PROFILE_* code (ZFIXED_PROFILE_INVALID for anything else — the caller fails loud).

path_to_c_string rdb_io_netcdf Function

Pack a Fortran string into a null-terminated c_char array for the mkdir binding above. Private duplicate of rdb_ocean_restart_io’s string_to_c (that one is private to its own module) — small enough that sharing it is not worth a cross-module dependency for a two-line helper.

pd_limit_meridional_impl rdb_continuity Subroutine

Positive-definite per-donor outflux limiter — meridional (y) pass (P2). Mirror of pd_limit_zonal_impl; reads the post-zonal-apply h_layer (= h*), which is exactly the availability the second Lie pass must respect, and scales mass_flux_y so h_layer >= h_lim holds after continuity_apply_meridional. Cell (i,j,k) outflow = (north face j+1 when positive) + (south face j when negative); interior face j ∈ 2..ny scaled by its upwind donor’s θ (south cell j−1 when the face flux ≥ 0, else north cell j). See the zonal twin for the θ construction, ghost range, MPI-seam determinism, and the v1.1 v_cor re-matching rationale (MOM6 v_cor scaled by the same per-face θ so it stays consistent with the limited flux).

pd_limit_zonal_impl rdb_continuity Subroutine

Positive-definite per-donor outflux limiter — zonal (x) pass (P2, plan §P2 / decision D2). Scales the per-layer east-face mass fluxes DOWN so no donor cell loses more thickness than it holds above the floor h_lim: guarantees h_layer >= h_lim after continuity_apply_zonal, with ZERO mass created — outfluxes shrink, thickness is never inflated (the deliberate contrast with MOM6’s max(h, Angstrom) injection; the conservative borrow stays the backstop). Two device passes:

Read more…
pgf_free_surface_gravity rdb_barotropic_coupling Function

The gravity of the free-surface term the slow layer PGF CARRIES, i.e. −∂⟨PGF⟩/∂(∇η) for a uniform-density column (m/s²):

Read more…
pgf_nonoverlap_gate_on rdb_ocean_state Function

Single source of truth for “is the grounded-layer PGF gate armed?” (&ocean_isopycnal_nml pgf_skip_nonoverlap → ocean_pressure_force_t%skip_nonoverlap).

Read more…
plm_edges_layer rdb_ocean_pressure_force Subroutine

PLM top/bottom edge values of ONE layer k of a layer-mean field q, via a two-stage h-weighted van-Leer slope (White, Adcroft & Hallberg 2009 §2). Returns the SHALLOWER edge in q_t (toward k+1) and the DEEPER edge in q_b (toward k-1), bottom-up. Boundary layers (k=1, k=nz) -> boundary_edges_linear, the linear-exact one-sided pair.

Read more…
plm_face_swept rdb_recon_weno Function

PLM (piecewise-linear) swept-average face value.

Read more…
plm_slope_nonuniform rdb_remap_column Subroutine

Thickness-weighted PLM slope — Colella & Woodward (1984) eq (1.7) with the (1.8) bound, the form MOM6 ships as PLM_slope_cw.

Read more…
poison_centre_2d rdb_ocean_ghost_poison Subroutine

Poison centre-type 2D ghost bands.

poison_centre_3d rdb_ocean_ghost_poison Subroutine

Poison centre-type 3D ghost bands.

poison_face_x_2d rdb_ocean_ghost_poison Subroutine

Poison x-face 2D ghost bands. fld has shape (nx_total+1, ny_total) = (nxl+2ng+1, nyl+2ng). NEVER poison i = ng+1 (west seam face) or i = ng+nxl+1 (east seam face): these carry ownership/wrap-direction asymmetries that make it unsafe to overwrite them. West ghost faces: i = 1..ng. East ghost faces: i = ng+nxl+2..nx_face. Y-bands centre-type.

poison_face_x_3d rdb_ocean_ghost_poison Subroutine

Poison x-face 3D ghost bands. Seam-face exclusion: see poison_face_x_2d.

poison_face_y_2d rdb_ocean_ghost_poison Subroutine

Poison y-face 2D ghost bands. fld has shape (nx_total, ny_total+1) = (nxl+2ng, nyl+2ng+1). NEVER poison j = ng+1 (south seam face) or j = ng+nyl+1 (north seam face). South ghost faces: j = 1..ng. North ghost faces: j = ng+nyl+2..ny_face. X-bands are centre-type: i = 1..ng and i = ng+nxl+1..nx_total.

poison_face_y_3d rdb_ocean_ghost_poison Subroutine

Poison y-face 3D ghost bands. Seam-face exclusion: see poison_face_y_2d.

porous_cum_area rdb_ocean_porous Function

Cumulative open area of a face from the deepest along-face point up to interface height eta, per unit face length (m — it is the vertical integral of porous_open_width). Layer-averaged open fractions are differences of this function divided by the layer thickness, which is exact (no quadrature error) because d(area)/d(eta) = porous_open_width(eta) identically.

porous_eta_face rdb_ocean_porous Function

Interface height at a velocity point from the two adjacent cell-centre interface heights. MOM6’s PORBAR_ETA_INTERP options. POROUS_ETA_MAX (the higher, i.e. shallower, interface) is the default and the LEAST blocking: the open width w is monotone increasing in the interface height, so the rule that returns the larger height leaves the most of the face open. POROUS_ETA_MIN is the most blocking.

porous_fill_stats_resolved rdb_ocean_porous Subroutine

Fill the per-face d_min / d_max / d_avg from the RESOLVED bottom elevation, sampled at three points ALONG each face: the two end corners and the midpoint. A corner sample is the mean of the four cells around it, the midpoint the mean of the two cells the face separates — all three are genuine points on the resolved seafloor along the face segment.

Read more…
porous_narrow_3d rdb_ocean_porous Subroutine

Multiply a face-staggered per-layer field by the open-area fraction: arr <- arr * por.

Read more…
porous_open_width rdb_ocean_porous Function

Open WIDTH fraction of a face at interface height eta (dimensionless, in [0, 1]). Zero when the interface is at or below the deepest along-face point, one when it is above the shallowest. A degenerate face (d_max <= d_min, i.e. a flat along-face seafloor) reduces to the binary open/closed step, so the fit never divides by zero.

porous_stats_are_ordered rdb_ocean_porous Function

.true. iff every face satisfies d_min <= d_avg <= d_max, the invariant the whole fit rests on (m = (d_avg-d_min)/(d_max-d_min) must lie in [0,1]).

Read more…
porous_update_face_areas rdb_ocean_porous Subroutine

Recompute the layer-averaged open-area fractions from the CURRENT layer thicknesses. Interface-height dependent, so this runs once per RK2 stage on the device.

Read more…
posix_rename rdb_ocean_restart_io Function

Atomically rename oldpath -> newpath via libc rename(2). Returns 0 on success, -1 on error.

post_parse_validate rdb_nml_schema Subroutine

Required-key + cross-check pass shared by the file and buffer parsers, then the error-return / error-stop finalization.

ppm_cell_limiter rdb_continuity Subroutine

Colella-Woodward 1984 eq 1.10 monotonic limiter on the parabolic profile in a single cell. Three branches:

Read more…
ppm_edge_nonuniform rdb_remap_column Subroutine

Colella & Woodward (1984) eq (1.6): the fourth-order interface value between cells 1 and 2 on a NON-UNIFORM stencil h0,h1,h2,h3.

Read more…
ppm_edge_two_cell rdb_remap_column Subroutine

Thickness-weighted two-cell interface value — the non-uniform generalisation of 0.5*(q_l + q_r).

Read more…
ppm_edges_layer rdb_ocean_pressure_force Subroutine

PPM top/bottom edge values of salinity and temperature in ONE layer k: the implicit-h4 interface estimates (ppm_interface_values) + the Colella & Woodward (1984) limiter (ppm_limit_edges). Returns the SHALLOWER edges in *_top, the DEEPER in *_bot (bottom-up).

Read more…
ppm_interface_values rdb_ocean_pressure_force Subroutine

The PPM estimates of salinity and temperature at the interface between layer m (deeper) and m+1 (shallower), 1 <= m <= nz-1, from the four-layer stencil m-1 .. m+2 (thicknesses h0..h3, layer means s0..s3, t0..t3). Interior interfaces (2 <= m <= nz-2) take the implicit-h4 estimate in its explicit form (White & Adcroft 2008 non-uniform stencil, exactly 4th-order on non-uniform layers; matches remap_column_ppm_h4 Step 1 to round-off). The two near-boundary interfaces (m = 1, m = nz-1) take the thickness-weighted (h2) estimate — the linear-exact value at the shared face of two piecewise-linear cells, (q_m h_{m+1} + q_{m+1} h_m)/(h_m + h_{m+1}) (a plain mean biases the thick interior layer’s edge on non-uniform thicknesses); layer m-1 (resp. m+2) is then not referenced.

Read more…
ppm_jump_nonuniform rdb_remap_column Subroutine

Colella & Woodward (1984) eq (1.7) — the thickness-weighted second-order jump delta a across the cell, which eq (1.6) consumes. Returned UNLIMITED, deliberately.

Read more…
ppm_limit_edges rdb_ocean_pressure_force Subroutine

The PPM edge limiter of one interior layer: clip both interface estimates into the monotone bounds of the three adjacent means, flatten a local extremum to PCM, and apply the Colella & Woodward (1984) parabola limiter.

ppm_limit_pos rdb_continuity Subroutine

Positivity-preserving limiter on the PPM reconstruction. Mirrors MOM6’s PPM_limit_pos: when the parabolic fit predicts a minimum interior to the cell that dips below h_min, shrink h_left / h_right toward h_centre so the minimum sits at exactly h_min. Pure scalar form per cell; runs after ppm_cell_limiter so the monotonic-limited reconstruction is the input.

Read more…
ppm_limited_slope rdb_continuity Subroutine

Van Leer monotonized centred slope for cell i. Returns 0 at local extrema (sign change between left and right differences) and the slope-limited centred derivative otherwise. Standard PPM convention; see Colella-Woodward 1984.

Read more…
ppm_mirror_h rdb_continuity Function

Mirror-h at a land neighbour (spec §14 C2 / MOM6’s reflected-coast PPM): substitute the LOCAL cell’s thickness (or tracer) for a LAND neighbour’s held floor value so the PPM parabola sees a flat, reflected coast and the wet-side face value is not biased by the dry column. Branchless: h_out = w_nbr·h_nbr + (1-w_nbr)·h_loc. Wet neighbour (w_nbr=1) ⇒ h_out = h_nbr (literal no-op); land neighbour (w_nbr=0) ⇒ h_out = h_loc.

Read more…
pqm_end_value_h4 rdb_remap_column Subroutine

One-sided 4th-order polynomial fit of the cell averages u to the four boundary layers dz (thicknesses, must be positive), returning the four coefficients csys of the fit (White & Adcroft 2008, appendix; roundoff-safe closed form). csys(1) is the edge VALUE at the boundary interface and csys(2) is the edge SLOPE there.

pqm_solve_diag_dominant rdb_remap_column Subroutine

Diagonally-dominant tridiagonal solve; central diagonal supplied as the OFFSET ac from al + au (full pivot = ac + al + au). Never divides by zero for positive-definite ac, al, au (White & Adcroft 2008).

pressure_above_x rdb_ocean_isopycnal_slopes Function

Surface-relative hydrostatic pressure at the interface K straddled by layer ka (above, surface-side) and ka-1 (below): the interface sits at the BOTTOM of layer ka, so the water column above it is layers ka..nz (bottom-up, k=nz the surface). p = g·ρ₀·Σ_{k’=ka}^{nz} h(k’) — the sum INCLUDES ka (the layer directly above the interface); omitting it shorts the pressure by one layer (~5e5 Pa) and biases pressure-dependent EOS derivatives.

print_banner rdb_banner Subroutine

Print a cute banner to the console when the simulation starts. The subtitle line adapts to the regime: “ocean circulation model” for sim_type == "ocean", the 2D/3D coastal line otherwise (the default).

print_bt_budget rdb_ocean_bt_budget_probe Subroutine

Compute + print the per-region BT-mode budget snapshot.

Read more…
print_gpu_binding rdb_comm_env Subroutine

Per-rank one-shot diagnostic: world rank -> requested device num / actual device num reported by the OpenACC runtime. Lets us confirm that mpirun is binding each rank to its own GPU rather than serialising N ranks on device 0.

print_status_line rdb_driver Subroutine

Print a table-formatted status line with estimated remaining time. When mean_S / mean_T are present, two extra columns are written between Mass and Wall so the multilayer header lines up.

probe_dS rdb_ocean_dyn Subroutine

Debug-gated diagnostic. Pulls h_layer + hTr_S from device and prints max|hTr_S/h_layer - bcdiag_S_ref| over interior columns. Early-returns when bcdiag_enabled = .false. or after bcdiag_step_limit outer steps have completed.

Read more…
probe_h_vs_eta_residual rdb_ocean_dyn Subroutine

Debug probe: print max|sum_k(h_layer) - (H_ref + bt_eta_end)| over interior cells. In Eulerian-z this is forced to zero by apply_bt_correction’s h-rescale. In Lagrangian mode the rescale is skipped, so this residual is what the slow continuity actually drifts to (expected to be FP). Watching how it grows over time across many outer steps is what pins down whether the long-run momentum NaN is FP accumulation in sum_k(h_layer) - H - bt_eta_end.

profiler_disable rdb_profiler Subroutine

Public for the unit-test suite only.

profiler_enable rdb_profiler Subroutine

Public for the unit-test suite only.

profiler_end rdb_profiler Subroutine

Finalise the profiler

profiler_get_time rdb_profiler Function

Accumulated time (s) for a named region. Public for the unit-test suite only.

profiler_init rdb_profiler Subroutine

Initialise the profiler

profiler_report rdb_profiler Subroutine

Print profiling report If root_region is specified, percentages are relative to that region

profiler_reset rdb_profiler Subroutine

Reset all timing data

profiler_start rdb_profiler Subroutine

Start a named profiling region If nvtx_only is true, the region only appears in NVTX timeline, not in text report

profiler_stop rdb_profiler Subroutine

Stop a named profiling region

pseudo_salt_conflicts_ice rdb_ocean_pseudo_salt Function

.true. iff pseudo-salt is enabled alongside the sea-ice model — frazil / basal salt exchange are un-mirrored salinity sources (rdb_ice_frazil.F90, rdb_ice_frazil_uptake.F90, rdb_ice_basal_flux.F90). Drives a configure-time fail-loud abort.

pseudo_salt_conflicts_restore rdb_ocean_pseudo_salt Function

.true. iff pseudo-salt is enabled alongside SSS piston restoring — an un-mirrored salinity source (rdb_ocean_surface_flux.F90 restore branch) that would make the deviation diagnostic measure the restoring term instead of the passive-transport-path error. Drives a configure-time fail-loud abort.

pseudo_salt_needs_thermo_warning rdb_ocean_pseudo_salt Function

.true. iff pseudo-salt is enabled with thermodynamics off. NOT a hard error — pseudo-salt still measures pure transport, a legitimate use — but the caller should warn: without thermodynamics, the tracer never receives the surface salt flux / KPP nonlocal mirrors, so D degenerates to a pure advection/diffusion probe.

push_tok rdb_nml_schema Subroutine

Append a token, growing the buffer as needed.

pv_adv_required_nghost rdb_coriolis_adv Function

Minimum nghost for a PV face-interp scheme: the stencil RADIUS + 1. weno5 (radius 3) -> 4, weno7 (radius 4) -> 5; centered and weno3 (radius 2) keep the nghost>=2 baseline – one rank has no seam, and every decomposed run is already floored at nghost>=3 (ocean_halo_init), which is weno3’s radius + 1 (measured bitwise, 2x2 / 4x1).

Read more…
pv_adv_scheme_is_implemented rdb_coriolis_adv Function

.true. for every wired PV face-interpolation scheme: PV_ADV_CENTERED + PV_ADV_WENO3/WENO5/WENO7. weno5/weno7 additionally require a wider halo (pv_adv_required_nghost), checked separately at configure. PV_ADV_INVALID returns .false. (fail-loud on a typo).

pv_variant_is_implemented rdb_coriolis_adv Function

.true. only for a Coriolis-advection variant that has a real kernel wired into coriolis_adv_compute_tendencies (SADOURNY / SADOURNY_HK / SADOURNY_ENERGY). PV_VARIANT_AL81 returns .false. — the constant is reserved but the Arakawa-Lamb kernel is not yet written, and the AL81 promise (simultaneous energy + enstrophy conservation) must not be silently substituted by the enstrophy-only Sadourny kernel. PV_VARIANT_INVALID also returns .false.. The predicate is the single gate validate_config consumes (PR-6 fail-loud).

raw_sh_xx rdb_ocean_horizontal_viscosity Function

Raw tension strain sh_xx = du/dx − dv/dy at T-cell (i,j), mirroring Phase-1’s gradient form (unmasked — used only by the anisotropic cross term where the all-wet reduction is exact). !$acc routine seq so the stress-assembly do concurrent can call it on-device.

raw_sh_xy rdb_ocean_horizontal_viscosity Function

Raw shear strain sh_xy = dv/dx + du/dy at Bu corner (i,j), mirroring Phase-2’s gradient form. !$acc routine seq for the on-device cross-term loop.

rdb_debug_chksum rdb_ocean_chksum Interface

Grid-location-aware checksum: derives the array extents from grid + loc (no hand-written bounds at the call site), runs the device-side reductions, and emits one CHKSUM row. Resolves by rank — 3D field trio / 2D BT-work variant.

rdb_debug_chksum_2d rdb_ocean_chksum Subroutine

2D twin of rdb_debug_chksum_3d (BT-work fields).

rdb_debug_chksum_3d rdb_ocean_chksum Subroutine

Location-aware 3D checksum: derives (nx, ny) from grid + loc and nz from the array, so a new instrumentation site is one line with no hand-written bounds. Gated by the probe window.

rdb_def_var_1d rdb_io_netcdf Subroutine

Define a 1D variable with working precision type

rdb_flush_logs rdb_ocean_api Subroutine

Flush the buffered log stream (unit 6 / stdout — what pic_logger’s global_logger writes to; it exposes no flush of its own). Call this in a finally around a C entry point if the human-readable log needs to be ordered relative to Python’s own stdout (D4.4) — the ring (above) is still the only channel to trust for the SPECIFIC failure reason.

rdb_ocean_canonical_catalog_name rdb_ocean_api Function

Name of canonical-catalog entry idx (0-based, < the size above).

rdb_ocean_canonical_catalog_size rdb_ocean_api Function

Number of names in the CANONICAL diagnostic catalog (SSH, temperature, salinity, u, v, KE, … — the set register_default_diags MAY register at setup; some entries are gated by another namelist group, e.g. temperature needs &ocean_thermo_nml enable_thermodynamics). No handle required. Use rdb_ocean_get_diag_count/rdb_ocean_list_diags on a live handle to see what actually registered.

rdb_ocean_create_finalize rdb_ocean_api Function

P2.5 phase 2 of 2: complete a handle started by rdb_ocean_create_pending (optionally staged with rdb_ocean_stage_* geometry in between) — runs engine_setup (consuming any staged geometry) through device mapping, exactly like the tail of rdb_ocean_create_from_string.

Read more…
rdb_ocean_create_from_string rdb_ocean_api Function

Build a config from an in-memory namelist string (no filesystem touch), set up the ocean dyn-core exactly as bench_ocean / driver_run_ocean do, map it onto the device, and hand back an opaque handle. On ANY failure, handle_out is c_null_ptr and the partially-built handle (if one was allocated) is freed — never a half-initialised handle escaping to the caller.

rdb_ocean_create_pending rdb_ocean_api Function

P2.5 phase 1 of 2: build + validate a config and allocate a handle EXACTLY like rdb_ocean_create_from_string, but stop there — does NOT run engine_setup or map the device. Claims the single-live-handle guard immediately (a second concurrent create/create_pending is refused from this point on, even though engine_setup has not yet touched any process-global state — the invariant is “one handle mid-create at a time”, not merely “one finished one”).

Read more…
rdb_ocean_derived_catalog_name rdb_ocean_api Function

Name of derived-catalog entry idx (0-based, < the size above).

rdb_ocean_derived_catalog_size rdb_ocean_api Function

Number of names in the DERIVED diagnostic catalog (vorticity_z, ke_total, mld_density, … — rdb_ocean_diag_derived’s static table, opt-in via &ocean_diag_nml diags). No handle required: this is build-time information, reachable before create().

rdb_ocean_destroy rdb_ocean_api Function

success (so a Python __del__ can call this blind). On a live handle: unwind device residency (engine_exit_data) then release the god-state’s host-side allocations + the process-global ocean- halo module state (engine_teardown), then free the handle itself and clear the single-live-handle guard.

rdb_ocean_get_b_ptr rdb_ocean_api Function

Bathymetry (m, POSITIVE DOWN — eta = sum(h) - b): barotropic%b, shape (nx_total, ny_total).

rdb_ocean_get_bt_eta_ptr rdb_ocean_api Function

Sea-surface height (m): dyn%bt_work%bt_eta, shape (nx_total, ny_total). Diagnostic (sum_k(h_layer) - bt_H_ref), not independently settable — write h or b instead.

rdb_ocean_get_diag_count rdb_ocean_api Function

Number of diagnostics REGISTERED on this live instance right now (canonical + derived + anything the &ocean_diag_nml diags token list added) — bounds for rdb_ocean_list_diags’s index argument. This is the “selected” set, as opposed to the two static “available” catalogs above.

rdb_ocean_get_diagnostic_ptr rdb_ocean_api Function

Raw output_buffer for the diagnostic named name (LAYER vgrid: (nx_total, ny_total, nz_ml) for a layered var, (nx_total, ny_total, 1) for a 2D var; a non-LAYER output_vgrid reports the remapped shape, e.g. nz z-levels). OCEAN_STATUS_ERR_NOT_FOUND if name is not currently REGISTERED on this instance (it may still be a legal name on one of the two static catalogs, just gated off or not selected — see rdb_ocean_get_diag_count/ rdb_ocean_list_diags to discover what IS registered).

rdb_ocean_get_grid_info rdb_ocean_api Function

Physical (interior, ghost-excluded) grid shape + ghost width.

rdb_ocean_get_h_layer_ptr rdb_ocean_api Function

Layer thickness (m), cell-centred, FULL extent (ghosts included): multilayer%h_layer, shape (nx_total, ny_total, nz_ml).

rdb_ocean_get_hu_ptr rdb_ocean_api Function

West-face x transport (h*u, m^2/s): multilayer%hu_face_x_layer, same shape/stagger as u_face_x_layer.

rdb_ocean_get_hv_ptr rdb_ocean_api Function

South-face y transport (h*v, m^2/s): multilayer%hv_face_y_layer, same shape/stagger as v_face_y_layer.

rdb_ocean_get_kinetic_energy rdb_ocean_api Function

Total kinetic energy (J, up to the Boussinesq reference-density factor — matches rdb_ocean_get_total_mass’s convention of leaving rho0 out) over the physical interior: sum(0.5 * h_layer * (u_centre^2 + v_centre^2) * areaT), faces averaged to centres — same formula as rdb_ocean_budgets::budget_total_ke, computed inline (weighted by the metrics’ areaT, so it is right on spherical / supergrid / tripolar grids too; grid%dx*grid%dy is only the fallback). Unlike the raw-pointer getters above, this refreshes the host itself — it hands back a NUMBER, not a pointer a caller could otherwise defer syncing for.

rdb_ocean_get_ks_ptr rdb_ocean_api Function

Vertical salt (+ every passive tracer) diffusivity (m^2/s): vmix%ks, shape (nx_total, ny_total, nz_ml+1) (layer INTERFACES). ks ≡ kt unless &ocean_ddiff_nml double diffusion is enabled.

rdb_ocean_get_kt_ptr rdb_ocean_api Function

Vertical heat diffusivity (m^2/s): vmix%kt, shape (nx_total, ny_total, nz_ml+1) (layer INTERFACES).

rdb_ocean_get_kv_ptr rdb_ocean_api Function

Vertical viscosity (m^2/s): vmix%kv, shape (nx_total, ny_total, nz_ml+1) (layer INTERFACES).

rdb_ocean_get_q_heat_ptr rdb_ocean_api Function

Net surface heat flux (W/m^2): h%state%surface_flux%Q_heat. P2 called this the “STANDALONE sf slot” (a separate, minimally- seeded object from ocean_state%surface_flux) because the P1 step call never ran ocean_surface_flux_assemble. P2.4 unifies setup+step across all three callers via the shared engine (rdb_ocean_engine), so rdb_ocean_step now DOES run the assembler (via engine_step_finalize) against this SAME field — a write here is live-consumed the same way the driver’s is. Shape (nx_total, ny_total).

rdb_ocean_get_q_salt_ptr rdb_ocean_api Function

Net surface salt flux: h%state%surface_flux%Q_salt — see rdb_ocean_get_q_heat_ptr for the P2.4 unification note. Shape (nx_total, ny_total).

rdb_ocean_get_rho_layer_ptr rdb_ocean_api Function

In-situ density (kg/m^3): multilayer%rho_layer, same shape as h_layer. Filled by the EOS each thermo step (and by every P2 setter that touches T/S/h).

rdb_ocean_get_step_count rdb_ocean_api Function

Outer-step counter. Reads dyn%outer_step_count directly (the kernel’s own bookkeeping) rather than keeping a second counter on the handle, so there is exactly one source of truth.

rdb_ocean_get_tau_x_ptr rdb_ocean_api Function

East-face wind stress (N/m^2): surface_stress%tau_x, shape (nx_total+1, ny_total).

rdb_ocean_get_tau_y_ptr rdb_ocean_api Function

North-face wind stress (N/m^2): surface_stress%tau_y, shape (nx_total, ny_total+1).

rdb_ocean_get_time rdb_ocean_api Function

Current simulation time (seconds).

rdb_ocean_get_total_mass rdb_ocean_api Function

One scalar diagnostic — total water mass over the physical domain (sum(h_layer * areaT) * RHO0_DIAG) — so a caller can prove the solver actually advanced (and, in a closed quiescent/wall basin, that it is conserving mass) without any state-array accessor (P2). !$acc update self on the leaf array via associate (never the aggregate ocean_state_t/multilayer_state_t) before summing, per the D<->H contract — inert on a host build, load-bearing on GPU.

rdb_ocean_get_tracer_count rdb_ocean_api Function

Number of registered tracers (S, T, + any passive tracers) — bounds for rdb_ocean_list_tracers’s index argument.

rdb_ocean_get_tracer_ptr rdb_ocean_api Function

Raw h*Tr store (NOT concentration — D3.2) for the tracer named name, by NAME (never index — the recovered code had no tracer accessors, and index comparison is already the wrong idiom in the Fortran itself). OCEAN_STATUS_ERR_NOT_FOUND if no registered tracer matches. Shape (nx_total, ny_total, nz_ml).

rdb_ocean_get_u_face_x_layer_ptr rdb_ocean_api Function

West-face x-velocity (m/s): multilayer%u_face_x_layer, shape (nx_total+1, ny_total, nz_ml).

rdb_ocean_get_v_face_y_layer_ptr rdb_ocean_api Function

South-face y-velocity (m/s): multilayer%v_face_y_layer, shape (nx_total, ny_total+1, nz_ml).

rdb_ocean_get_w_interface_ptr rdb_ocean_api Function

Vertical velocity at layer interfaces (m/s): multilayer%w_interface, shape (nx_total, ny_total, nz_ml+1), k=1 bed .. k=nz_ml+1 surface.

rdb_ocean_get_wet_t_ptr rdb_ocean_api Function

Wet mask at T points (1 = wet, 0 = land): metrics%wet_T, shape (nx_total, ny_total). Read-only (no setter — land masking is a configure-time / bathymetry concern).

rdb_ocean_last_error rdb_ocean_api Function

Read the error ring at ring-relative index idx (0 = most recent push). Copies up to cap bytes of the trimmed message into buf, NUL-terminating if room remains, and returns the FULL trimmed message length — a snprintf-style contract: a returned length >= cap means the copy was truncated. Returns 0 (buf untouched) if idx is out of [0, count) or cap <= 0.

Read more…
rdb_ocean_list_diags rdb_ocean_api Function

Name of the registered diagnostic at index idx (0-based). Same snprintf-style contract as rdb_ocean_list_tracers.

rdb_ocean_list_tracers rdb_ocean_api Function

Name of the tracer at registry index idx (0-based). Same snprintf-style contract as rdb_ocean_last_error: copies up to cap bytes, NUL-terminates if room remains, returns the FULL trimmed name length. Returns 0 (buf untouched) on a bad handle, an out-of-range idx, or cap <= 0.

rdb_ocean_refresh_host rdb_ocean_api Function

Lazy device->host refresh of every P2-exposed leaf array, gated on host_is_current (a second call with nothing new on device is a cheap flag check, not a re-copy). !$acc update self runs on LEAF component names only, via associate — never the aggregate ocean_state_t/sub-state derived type (the documented rdb_ocean_dyn.F90:2949 segfault: an aggregate D->H copy overwrites the host allocatable descriptors with DEVICE addresses). Inert on a host-only build (no !$acc support) — see CLAUDE.md’s GPU-verification caveat.

rdb_ocean_required_halo rdb_ocean_api Function

Stateless (no handle required — like rdb_working_precision): the minimum nghost for a given scheme/topology selection, folding the six scattered per-scheme/per-topology minimums behind rdb_ocean_halo_width::required_halo so a Python caller sizing a grid’s halo before create() agrees with what engine_setup will itself enforce. A zero-length scheme string means “unset” (baseline 2), matching the Fortran function’s absent-optional-argument behaviour.

rdb_ocean_set_bathymetry rdb_ocean_api Function

Overwrite bathymetry b (m, POSITIVE DOWN) on the physical interior, fill ghosts, re-wrap the periodic/fold seam, re-derive bt_H_ref = b (the mode-split contract) and re-wrap IT too, then narrow-push b (+ bt_H_ref) — mirrors the init-time sequence at rdb_driver.F90 exactly, so a mid-run perturbation sees the same seam/BT-reference treatment the setup path does. No prognostic slot is touched.

Read more…
rdb_ocean_set_h rdb_ocean_api Function

Overwrite h_layer on the physical interior (k=1 bed .. k=nz surface), narrow-push it, then recompute rho_layer from the new thickness against whatever T/S currently sit on device (pulling the recomputed density back to host so the host stays authoritative). No other prognostic slot is touched.

rdb_ocean_set_heat_flux rdb_ocean_api Function

Overwrite net surface heat flux h%state%surface_flux%Q_heat (W/m^2) on the physical interior, narrow-push. See rdb_ocean_get_q_heat_ptr for the P2.4 unification note.

rdb_ocean_set_salt_flux rdb_ocean_api Function

Overwrite net surface salt flux h%state%surface_flux%Q_salt on the physical interior, narrow-push. See rdb_ocean_get_q_heat_ptr for the P2.4 unification note.

rdb_ocean_set_tracer rdb_ocean_api Function

Set the tracer named name to data (its own units — degC for temperature, PSU for salinity) on the physical interior. Verbatim the recovered ocean_set_tracer_impl sequence, generalised from hardcoded S/T to any registered tracer BY NAME: flush the windowed-advection accumulator -> refresh host (need the LIVE h_layer to form hTr = h_layer*value) -> mutate hTr on the physical interior -> narrow-push hTr -> recompute rho_layer (pulled back to host so it stays authoritative). OCEAN_STATUS_ERR_NOT_FOUND if no registered tracer matches.

rdb_ocean_set_u rdb_ocean_api Function

Overwrite u_face_x_layer on the physical interior faces (nx_p+1 west faces bracketing nx_p physical columns) and narrow-push it. Does NOT re-derive hu_face_x_layer (a separate prognostic transport slot) — that stays whatever it was until the next step recomputes it.

rdb_ocean_set_v rdb_ocean_api Function

Overwrite v_face_y_layer on the physical interior faces (ny_p+1 south faces bracketing ny_p physical rows) and narrow-push it. See rdb_ocean_set_u for the hv_face_y_layer caveat (not re-derived).

rdb_ocean_set_wind rdb_ocean_api Function

Overwrite the C-grid surface wind stress (N/m^2) mid-run: taux_data is (nx_p+1, ny_p) (east faces), tauy_data is (nx_p, ny_p+1) (north faces) over the physical interior; ghost faces are left untouched (0 from init — wall faces see no spurious stress). Narrow-pushes tau_x/tau_y only. Settable repeatedly for a time-varying wind schedule.

rdb_ocean_stage_bathymetry rdb_ocean_api Function

P2.5: stage an interior-sized (nx_p, ny_p) bathymetry array on the PENDING handle c_handle (rdb_ocean_create_pending). Consumed by engine_setup inside rdb_ocean_create_finalize — see rdb_ocean_bathymetry_inject for the sign-normalisation + wet-fraction validation the array goes through THERE (not here: shape can’t be checked against nx_phys/ny_phys until the grid exists, which engine_setup builds).

rdb_ocean_stage_metrics rdb_ocean_api Function

P2.5: stage in-memory MOM6-style supergrid arrays on the PENDING handle c_handle — metrics_assemble_from_supergrid_arrays’s exact layout (x/y: (nxp,nyp) degrees; dx: (nx,nyp) m; dy: (nxp,ny) m; area: (nx,ny) m^2, where nxp=2*nx_phys+1, nyp=2*ny_phys+1, nx=2*nx_phys, ny=2*ny_phys). Consumed inside rdb_ocean_create_finalize, bypassing cfg%ocean%grid%grid_config entirely — exports the SAME assembler the NetCDF supergrid reader and the analytic tripolar generator already use, so this and a mosaic-file grid produce identical metrics for the identical arrays. Shape is validated at create_finalize time (against the grid, which does not exist yet here).

rdb_ocean_stage_topology rdb_ocean_api Function

P2.5: stage Oceananigans-style grid topology (per-dimension periodicity — “the grid owns periodicity”, not the per-edge &ocean_bc_nml tags) on the PENDING handle c_handle. Consumed inside rdb_ocean_create_finalize via ocean_bc_state_set_topology, run AFTER the namelist edge tags are parsed and OVERRIDING whatever they derived for periodic_x/periodic_y (an axis NOT marked periodic here keeps whatever physical BC the namelist gave it).

rdb_ocean_step rdb_ocean_api Function

Advance n_steps fixed-dt (cfg%dt_fixed) outer steps via the shared engine_step / engine_step_ice / engine_step_finalize sequence (P2.4 + P2.4b) — the SAME calls driver_run_ocean’s time loop makes: the dyn-core advance, then sea-ice per-step physics (engine_step_ice — a no-op when &ocean_ice_nml enable = .false., so this is bit-identical to before P2.4b for every non-ice config), then surface-flux-component assembly / the diag step. n_steps <= 0 is a successful no-op (mirrors an empty range, not an error).

rdb_put_var_1d rdb_io_netcdf Subroutine

Write a full 1D array

rdb_put_var_2d_slice rdb_io_netcdf Subroutine

Write a 1D slice into a 2D variable at a given time index

rdb_working_precision rdb_ocean_api Function

Bytes per wp (4 or 8) — so a Python caller resolves float32 vs float64 at load time instead of guessing. No handle needed: this is a build-time constant.

read_config rdb_config Subroutine

Read simulation configuration from a namelist file.

Read more…
read_config_from_string rdb_config Subroutine

In-memory sibling of read_config: build + strict-parse + apply a namelist held entirely in the text buffer (newline- separated), with NO filesystem touch — no temp file, no chdir, no cleanup. Same validation behaviour as the file path (the schema parser and the native &ocean_bc_nml read both run from the in-memory line array); same error stop default and same optional non-aborting ierr as read_config.

read_config_from_string_impl rdb_config Subroutine

Body of read_config_from_string — mirrors read_config_impl with the line array replacing the file unit.

read_config_impl rdb_config Subroutine

Body of read_config: build the strict schema (capturing defaults from the pristine cfg field initialisers), parse the file (validate + apply straight into cfg), run the post-parse time-unit cascade.

read_dims rdb_ocean_z_init Subroutine

Validate the T/S variable’s dims against the model grid and detect whether the file is C-ordered (z, y, x) => needs_transpose = .true. (by the first Fortran dim name). Returns source z-level count nz_src; error-stops on mismatch.

read_field_xyz rdb_ocean_z_init Subroutine

Read this tile’s (nx, ny, nz_src) window of a 3D T/S variable (the file holds the WHOLE grid; the window starts at global cell (io+1, jo+1)) with a start/count read, permuting from the file’s Fortran storage order. On an undecomposed grid the window is the whole variable.

read_group_name rdb_nml_schema Subroutine

Read an identifier starting at (li,col); advance past it.

read_lines rdb_nml_schema Subroutine

Read the whole file into a deferred-len line array.

real_array_default_string rdb_nml_schema Function
real_array_is_default rdb_nml_schema Function
real_array_parse rdb_nml_schema Subroutine
real_array_value_string rdb_nml_schema Function
real_default_string rdb_nml_schema Function
real_is_default rdb_nml_schema Function
real_parse rdb_nml_schema Subroutine
real_value_string rdb_nml_schema Function
recompute_total_area rdb_ocean_diag_mask Subroutine
recon_rho_surf rdb_ocean_pressure_force Function

Recover the layer-mean surface density from the reconstructed pressure-anomaly stack: dpa(nz) = pa(nz) - pa(nz+1) = (rho_surf - rho_ref)gh_surf, so rho_surf = rho_ref + dpa/(g*h). Used only by the gfs_scale Montgomery correction (Pass 5).

recon_rung_for_face rdb_recon_weno Function

Return the highest feasible reconstruction rung for one face.

Read more…
redi_absolute_position rdb_ocean_redi Function

Absolute (pressure) position of neutral surface ks in a column (MOM6 absolute_position): Pint(K) + frac*(Pint(K+1)-Pint(K)).

redi_apply_flux rdb_ocean_redi Subroutine

Public Phase-B entry: apply the neutral-diffusion tracer update for every registered tracer. No-op if absent / uninit / disabled / zero diffusivity. Run at thermo cadence after redi_calc_coeffs and the along-coordinate tracer_hdiff (Redi augments it). Per-face KhTr comes from khtr_u_ext/khtr_v_ext (VarMix) when supplied, else the scalar this%khtr broadcast onto every face.

redi_apply_flux_impl rdb_ocean_redi Subroutine

Flat-impl Phase-B kernel for ONE tracer. Cell-centric double-visit (no-scatter rule on the C-grid): cell (i,j) recomputes the along-neutral flux on each of its four bounding faces and accumulates ONLY into its own dTr; interior-face fluxes are computed twice but no thread writes a neighbour ⇒ race-free. Face sign: the LEFT (west/south) cell of a face gets +Flx into native layer nz+1-KoL; the RIGHT (east/north) cell gets -Flx into nz+1-KoR. The top-down→native flip k=nz+1-Ko is the only k-flip. Flux = dT_layer * hEff * Coef, Coef_u = dtkhtr_udy_cu*idxCu; divergence hTr(k) += dTr(k)/areaT (conservative).

redi_budget_accumulate rdb_ocean_redi Subroutine

budget += hTr - snap (device-side): book the realised Redi increment of one budgeted tracer into its lateral-diffusion budget accumulator (ms%salt_budget_hdiff / heat_budget_hdiff).

redi_build_column rdb_ocean_redi Subroutine

Build one column’s TOP-DOWN interface P/T/S + density derivs from the BOTTOM-UP native column, restricted to the face’s open window kb..kt (nk = kt-kb+1 layers; the whole column 1..nz off the z-level closed-face path). Layer T/S = the I1′ column read (rdb_vl_column_conc: hTr/h on a live layer, the donor’s concentration on a vanished one); interface T/S = PPM edge reconstruction on the flipped window; interface P = surface-relative hydrostatic, seeded with the column ABOVE the window (fillers under an ice draft; nothing — exactly 0 — when kt = nz); dR/dT, dR/dS = -rho² dSV/dX at each interface. Only the first nk+1 entries of the outputs are written.

redi_calc_coeffs rdb_ocean_redi Subroutine

Public entry: fill the Phase-A coefficient arrays. No-op if absent / uninitialised / disabled. Run once per outer step at THERMO cadence (a slow, tracer-independent geometry). Outer-shim: dereference the tracer-registry hTr arrays on the host, pass the flat top-level allocatables to the flat-impl kernels.

redi_calc_coeffs_x rdb_ocean_redi Subroutine

Flat-impl Phase-A u-face kernel. Parallel over (i,j) interior u-faces (i=2..nx); the 2*nz+2 sweep runs serially inside each thread over a column pair (iw=i-1 west, i east). Wall faces and land faces leave the inert (zero/identity) coefficients. The sweep runs on each face’s open window uKb..uKt (1..nz off the z-level closed-face path; module header); a face with no open layer (uKt < uKb) is inert.

redi_calc_coeffs_y rdb_ocean_redi Subroutine

Flat-impl Phase-A v-face kernel — mirror of _x with v-stagger (js=j-1 south, j north), loop j=2..ny, open window vKb..vKt.

redi_face_coeffs rdb_ocean_redi Subroutine

The per-face Phase-A core: build both columns TOP-DOWN on the open window kb..kt (the whole column off the closed-face path), run the sweep on its nk = kt-kb+1 layers, and store PoL/PoR/KoL/KoR/hEff in the FULL top-down frame (Ko + nz - kt). The k-flip is confined to the Phase-B scatter; keeping Po/Ko top-down here lets the flux re-use the sweep’s interface-edge convention with no position arithmetic on the flipped frame. A short window (nk < nz) leaves 2*(nz-nk) trailing surfaces, filled as inert padding: the last surface repeated and hEff = 0, which Phase B skips.

redi_face_const rdb_ocean_redi Subroutine

Broadcast the scalar KhTr val onto every face of dst (n1, n2).

redi_face_copy rdb_ocean_redi Subroutine

Copy a face KhTr field src -> dst (both (n1, n2)), device-side.

redi_face_flux rdb_ocean_redi Subroutine

Accumulate ONE C-grid face’s neutral-surface tracer flux into the owning cell’s dTr. Builds the left/right tracer columns from the READ-ONLY snapshot hTr_in (the live hTr is also written by the loop — reading it would be a do-concurrent read-write race) and loops the ns-1 neutral sublayers. The per-face column locals live in this frame to keep the caller’s loop-body footprint small. is_left: this cell is the LEFT (west/south) column ⇒ +flx into native layer nz+1-KoL; else the RIGHT column ⇒ -flx into nz+1-KoR. (iL,jL)/(iR,jR) index the columns; (fa,fb) the faces. kb..kt is the face’s Phase-A open window (1..nz off the z-level closed-face path): the tracer columns are reconstructed on it alone and the full-frame Ko are read in the window frame (Ko - nz + kt). An empty window, or (use_open) one whose layers are no longer all live on both sides, contributes nothing — both cells of the face take the same decision from the same h.

redi_fv_diff rdb_ocean_redi Function

Second-order centred finite-volume slope of a layer scalar (MOM6 fv_diff; Colella & Woodward 1984). Returns the cell-centred difference across layer k given the three layer thicknesses and values.

redi_interface_scalar rdb_ocean_redi Subroutine

PPM continuous edge reconstruction of a layer scalar to interfaces (MOM6 interface_scalar with i_method=2). edge(1)=surface, edge(nk+1)=bed in the MOM6 top-down sense (see module header on the deferred k-flip).

redi_interpolate_position rdb_ocean_redi Function

Non-dimensional position in [0,1] where the interpolated density difference is zero. Guards the vanished/inverted (Ppos==Pneg) and degenerate (dRhoPos==dRhoNeg) cases device-safely (clamped values, no host I/O).

redi_neutral_positions_continuous rdb_ocean_redi Subroutine

The continuous neutral-surface sweep over a column pair. A single deterministic top→bottom sweep of 2*nk+2 surfaces walking two interface pointers; closed-form linear crossing per step (no inner iteration). Inputs are interface T/S/P + interface dR/dT, dR/dS (nk+1 each). Outputs PoL/PoR (fractional position within layer KoL/KoR) and hEff (harmonic-mean effective thickness between consecutive neutral surfaces; outcrops get hEff=0, not skipped). TOP-DOWN indexing (see module header).

redi_open_window rdb_ocean_redi Subroutine

A face’s OPEN WINDOW from its per-layer ok flags (open .and. live on both sides; module header): kt the topmost ok layer, kb..kt the contiguous ok run counted down from it. No ok layer ⇒ kb = 1, kt = 0 (an empty window, kt < kb).

redi_open_windows_x rdb_ocean_redi Subroutine

Fill every interior u-face’s OPEN WINDOW (&vcoord_nml zfixed_closed_faces; module header): ok(k) = open_u .and. live on both sides (rdb_vl_is_live), then redi_open_window.

redi_open_windows_y rdb_ocean_redi Subroutine

v-face twin of redi_open_windows_x (south j-1, north j).

redi_plm_diff rdb_ocean_redi Subroutine

PLM van-Leer-limited layer-difference array (MOM6 PLM_diff with c_method=2 finite-volume slope, b_method=1 PCM ends) — the slope input to the PPM edge interpolation.

redi_ppm_ave rdb_ocean_redi Function

Mean of a PPM parabola between fractional positions xL,xR in [0,1] (MOM6 ppm_ave). Device-safe: dx<0 / dx>1 FATALs collapse to the dx==0 branch value (no host I/O on device).

redi_ppm_edge rdb_ocean_redi Function

PPM quasi-fourth-order edge value at interface k+1/2 (MOM6 ppm_edge; Colella & Woodward 1984 eq. 1.6).

redi_signum rdb_ocean_redi Function

A true signum: -|a| if x<0, +|a| if x>0, 0 if x==0 (MOM6 signum).

redi_signum1 rdb_ocean_redi Function

signum(1.,x): -1 if x<0, +1 if x>0, 0 if x==0 (MOM6 sign guard).

redi_snapshot rdb_ocean_redi Subroutine

Device-side copy dst = src of a (nx,ny,nz) tracer field.

redi_sublayer_dT rdb_ocean_redi Function

Along-neutral tracer difference for one sublayer (MOM6 neutral_surface_flux continuous branch). TOP-DOWN layer indices (klt/klb = KoL at the surface/bed bound of the sublayer; krt/krb mirror) and fractional positions. Returns dT_layer when the top/bottom/ave/layer triad is sign-consistent, else 0 (the down-gradient guard that prevents up-gradient transport).

redi_tracer_column rdb_ocean_redi Subroutine

Build one column’s TOP-DOWN layer-average tracer Tlay, PPM interface edges Tint, and per-layer limited PPM left/right edges aLe/aRe from the bottom-up native (h, hTr) column (fixed-size NZ_STACK_MAX copies), restricted to the face’s open window kb..kt (1..nz off the z-level closed-face path) — indexed in the WINDOW top-down frame, 1..nk, nk = kt-kb+1. Tlay = the I1′ column read (rdb_vl_column_conc, see redi_build_column). Mirrors MOM6 interface_scalar + ppm_left_right_edge_values.

refill_h_ghost_scaled rdb_ocean_obc_baroclinic Subroutine

Overwrite open-edge h_layer ghost columns with the nearest interior column scaled so Σ_k h_ghost = bt_H_ref(ghost) + η_interior (η_interior = Σ_k h_int − bt_H_ref(int)). x-pass (west/east) over the full j extent (covers corner rows); y-pass (south/north) over the full i extent, reading the already x-filled corner columns — same corner-coverage order as fill_h_layer_ghosts.

refresh_linear_z_impl rdb_ocean_sponge Subroutine

One tracer plane of the linear_z target. Explicit-shape dummies, dims declared first (decl-order hook). ref_tracer is passed WHOLE and indexed by the scalar it inside the kernel — never sliced by the caller (the descriptor-walk trap the dc-assumed-shape hook exists to catch), matching relax_map_tracer_impl.

Read more…
refresh_tracer_ghosts rdb_ocean_dyn Subroutine

Re-fill every tracer’s ghost band from its owners: the halo exchange (MPI seams, and the local periodic wrap on an undecomposed periodic axis — the halo primitive does both), then the tripolar north fold on the rank that owns it. Thickness and velocity are left alone. Collective (every rank calls it).

refuse_open_zfixed_staircase rdb_ocean_setup Subroutine

The zfixed_closed_faces = .false. leg of configure_ocean_closed_faces: refuse vcoord_type = "z_fixed" with OPEN staircase faces over a STEPPED bed.

Read more…
reg_io_ok rdb_ocean_data_input Function

Translate a raw nc_check-style status (0 = ok) from one of the nc_* reader calls in register_common into the caller’s ierr contract: .true. on success; on failure, .false. with ierr = OCEAN_STATUS_ERR_IO when ierr is present (closing ncid first, when given, so a mid-registration failure does not leak the file handle), or error stops with a generic message when ierr is absent — the SPECIFIC reason was already logged by nc_check/fail before this returns, so the legacy (no ierr) log output is unchanged; only the raw error stop text is generic (same idiom as rdb_bathymetry::bathy_io_ok, P0.1 F1/F2).

region_eta_uv rdb_ocean_bt_budget_probe Subroutine

Walk cells (interior x-range, j in [j_lo, j_hi]); collect η extremes, |u|/|v| extremes at surface + bed, and the cell-area-averaged BT KE.

region_power rdb_ocean_bt_budget_probe Subroutine

Cell-centred BT power per region: P = ⟨u_bt·F_u + v_bt·F_v⟩. F_u_3d is per-layer at u-faces, shape (nx+1, ny, nz). Depth-averages with the centred face thickness as weight to get the BT-mode contribution, then dots with bt_ubt/bt_vbt at the same face, then averages east+west (north+south) into the cell.

region_power_drag_implicit rdb_ocean_bt_budget_probe Subroutine

Bottom drag in implicit mode: the slow tendency for u at a face is −rate_u(i,j,k)·u_face_layer(i,j,k) (1/s × m/s → m/s²). We construct that on the fly, depth-mean by face thickness, dot with bt_ubt (and v counterpart), sum the cell-centred result over the region. Sign comes out negative: drag removes BT-mode energy.

register_boundary rdb_config Subroutine

&boundary_nml: per-side BC types, tidal forcing, inflow/ discharge/clamped/sponge/nesting parameters. The four bc_* keys are enums over the bc_type_from_string accepted set.

register_common rdb_ocean_data_input Subroutine

Shared registration body for register_2d/_3d/_segment_2d/_segment_3d. (i0, j0, nx, ny, nz) are FILE-side start/count (already resolved by the caller — plain global-offset slicing for the base variants, degenerate-axis geometry for the segment variants).

register_conv rdb_config Subroutine

&ocean_conv (Brunt-Vaisala-triggered convective adjustment, CVMix_conv-style).

register_ddiff rdb_config Subroutine

&ocean_ddiff (double diffusion: salt fingering + diffusive convection, CVMix_ddiff-style).

register_default_diags rdb_ocean_diag_fills Subroutine

Register the canonical ocean diagnostic variable set. Called once from setup (driver init or test) after state%diag%init. When specs (parsed &ocean_diag_nml diags) is present, each canonical diagnostic consults it: a :off entry skips registration entirely, and :cadence / :op / :coord attributes override the defaults. default_coord (the global &ocean_diag_nml vgrid, default LAYER) sets the output vgrid for layered diagnostics absent a per-diag :coord. Absent specs + LAYER default => the canonical defaults, bit-identical to the legacy behaviour. The canonical set also gains ice_conc / ice_thick when &ocean_ice_nml enable.

register_default_tracers rdb_state Subroutine

Overlay scalar config onto the already-allocated salinity / temperature tracer slots (by reference, so every caller shares the overlay). Does not touch hTr / hTr0 — those are populated by the path’s IC step once h_layer is known.

register_derived rdb_ocean_diag_derived Subroutine

Register ONE derived diagnostic by catalog name (used by apply_diag_selection): look it up and forward to state%diag%register(...) with the catalog metadata + correct buffer shape. Error-stops on an unknown name. coord (a DIAG_VGRID_*) sets the output vgrid for a LAYERED diag + attaches the conservative remap (2D entries ignore it); default LAYER. Remaps INTENSIVE.

register_epbl rdb_config Subroutine

&ocean_epbl (Reichl & Hallberg 2018 energetics-based PBL).

register_foxkemper rdb_config Subroutine

&ocean_foxkemper (Fox-Kemper et al. 2008/2011 mixed-layer-eddy restratification, capability B5).

register_full_3d rdb_ocean_state Subroutine

Register a rank-3 field as a FULL local array (interior + ghosts) — ng=0 over the total extent. See the ghost-cell policy note in ocean_state_build_restart_registry.

register_full_3d_opt rdb_ocean_state Subroutine

register_full_3d, but OPTIONAL on read: a checkpoint written before the field was registered still resumes.

register_gm rdb_config Subroutine

&ocean_gm (Gent-McWilliams thickness diffusion, capability [2]).

register_grid rdb_config Subroutine

&grid_nml: structured-grid geometry.

register_initial_condition rdb_config Subroutine

&initial_condition_nml: coastal IC selector + parameters.

register_kappa_shear rdb_config Subroutine

&ocean_kappa_shear (JHL08 shear-driven interior mixing). Exclusive > 0 bounds (ri_crit, kappa_0, tol_err, prandtl_turb) are left to the configure-time strict checks.

register_logging rdb_config Subroutine

&logging_nml: logger verbosity + status cadence.

register_meke rdb_config Subroutine

&ocean_meke (prognostic mesoscale eddy kinetic energy, [5]).

register_mpi rdb_config Subroutine

&mpi_nml: MPI domain decomposition.

register_nonhydrostatic rdb_config Subroutine

&nonhydrostatic_nml: NH/multilayer switches, CG-Poisson controls, PP81 vmix, KPP knobs, k-eps, Smagorinsky, BPG, mode split. keps_stability and bpg_method are enums.

register_ocean_bc rdb_config Subroutine

&ocean_bc_nml: open-boundary condition config (P4.5 migration off the hand-rolled read_ocean_bc_nml). All defaults reproduce a closed-wall run (bit-identical to nmls that omit this block). The west/east/south/north edge-type enum lists every arm of ocean_bc_type_from_string (rdb_ocean_boundary_types.F90), not just the subset named in the config-type docstring — that function is what the parsed string is actually fed to, and the native reader accepted (and validate_config did not reject) any of its arms on any edge, so the schema must not narrow that.

register_ocean_bdrag rdb_config Subroutine

&ocean_bdrag_nml: bottom-drag selector + coefficients. form enum mirrors parse_bdrag_variant in rdb_ocean_bottom_drag.

register_ocean_bt rdb_config Subroutine

&ocean_bt_nml: split-explicit barotropic substep controls.

register_ocean_cavity_dyn rdb_config Subroutine

&ocean_cavity_dyn (P5.1 static ice-shelf cavity geometry: the prescribed draft + the barotropic datum that absorbs it).

register_ocean_cavity_melt rdb_config Subroutine

&ocean_cavity_melt (P2b ice-shelf basal-melt thermodynamics: the three-equation interface, its exchange law and the far-field sampling depth). The exchange_law and ice_conduction enums MIRROR parse_cavity_exchange_law / parse_cavity_ice_mode in rdb_ocean_cavity_melt — the two lists move together, and validate_config re-checks them belt-and-braces so a RESERVED law is refused by name rather than silently falling through the kernel’s dispatch.

register_ocean_continuity rdb_config Subroutine

&ocean_continuity_nml: continuity-PPM positivity controls.

register_ocean_coriolis rdb_config Subroutine

&ocean_coriolis_nml: Coriolis-advection scheme selector. form enum mirrors parse_pv_variant in rdb_coriolis_adv (canonical names; short aliases hk/energy are not advertised).

register_ocean_data rdb_config Subroutine

&ocean_data_nml: the shared time-varying NetCDF input reader (PR-14). Two knobs, no per-field entries — see ocean_data_config_t. Registration of individual (file, variable, destination) triples is programmatic, via each consumer’s own namelist group calling ocean_data_input_register_2d/_3d at setup.

register_ocean_dataovr rdb_config Subroutine

&ocean_dataovr_nml: file-backed surface forcing (PR-15). Flat per-tag knobs (<tag>_file, <tag>_var, <tag>_scale, <tag>_add) rather than a MOM6-style parallel-array data table — the schema engine has no string-array key type, and the set of recognised tags is fixed by the slots they feed, so a flat layout is both expressible today and self-documenting in docs/generated_nml_knobs.md.

register_ocean_debug rdb_config Subroutine

&ocean_debug_nml: forensic probes (all heavy, all default off).

register_ocean_diag rdb_config Subroutine

&ocean_diag_nml: ocean diag-manager output controls. dt_out is interpreted in time_unit and converted by the post-parse cascade in read_config. vgrid enum is {layer, z_fixed}.

register_ocean_eos rdb_config Subroutine

&ocean_eos_nml: equation-of-state variant selector, the freezing-point (liquidus) coefficient set, and the potential-density reference pressure. eos enum mirrors parse_eos_variant in rdb_eos; tfreeze_set mirrors parse_tfreeze_set in the same module.

register_ocean_forcing rdb_config Subroutine

&ocean_forcing_nml: surface-flux component-set gate (PR-12). One knob, deliberately — components are filled by fillers, not by scalar namelist knobs (that would be a knob-per-component, all dead in v1).

register_ocean_geothermal rdb_config Subroutine

&ocean_geothermal_nml: geothermal bottom-heat-flux switch + scalar flux. Bed-side analogue of the surface heat flux.

register_ocean_grid rdb_config Subroutine

&ocean_grid_nml: horizontal-grid generator + geometry (curvilinear-grid stream). grid_config / coriolis_scheme enums mirror parse_grid_config / parse_coriolis_scheme in rdb_ocean_metrics.

register_ocean_hdiff rdb_config Subroutine

&ocean_hdiff_nml: along-coordinate tracer Laplacian (rdb_ocean_hdiff_tracer). Not the neutral/isopycnal path — that is &ocean_redi_nml, already reachable.

register_ocean_hvisc rdb_config Subroutine

&ocean_hvisc_nml: lateral-viscosity closure + coefficients. lateral_closure enum mirrors parse_lateral_closure in rdb_ocean_lateral_mix.

register_ocean_ic rdb_config Subroutine

&ocean_ic_nml: initial-condition overlay + EOS reference state. ic_config enum mirrors the IC dispatch in rdb_ocean_state (default “” keeps the analytical T(z) IC).

register_ocean_ice rdb_config Subroutine

&ocean_ice_nml: sea-ice model switch + category/layer counts (SIS2 port scaffold) + the PR-3c v1 restoring atmospheric-forcing scalars. Default off ⇒ byte-identical.

register_ocean_ice_ic rdb_config Subroutine

&ocean_ice_ic_nml: sea-ice ANALYTIC initial-condition path (PR 24). Default conc_config="zero" ⇒ byte-identical. "file" is deliberately NOT in the allowed= list — file-backed ICs are PR-14 (v1.1), out of scope here.

register_ocean_isopycnal rdb_config Subroutine

&ocean_isopycnal_nml: grounding-stability controls for the Lagrangian vertical coordinate.

register_ocean_mpi rdb_config Subroutine

&ocean_mpi_nml: multi-rank MPI debug / tuning controls.

register_ocean_pgf rdb_config Subroutine

&ocean_pgf_nml: pressure-gradient-force kernel selector + knobs. form enum mirrors parse_opgf_variant in rdb_ocean_pressure_force.

register_ocean_psurf rdb_config Subroutine

&ocean_psurf (PR-17 atmospheric surface-pressure loading / inverse barometer).

register_ocean_restore rdb_config Subroutine

&ocean_restore_nml: surface buoyancy restoring (MOM6 RESTOREBUOY). Piston-velocity relaxation of top-layer T / S toward scalar targets. Default OFF ⇒ bit-identical.

register_ocean_sponge rdb_config Subroutine

&ocean_sponge_nml: the map-driven sponge (PR-23). Default enable = .false. ⇒ the legacy &ocean_bc_nml band kernels run unchanged ⇒ bit-identical. No damp_max / idamp_file / *_var keys in v1 — those validate and do nothing until PR-23b adds their consumer (CLAUDE.md trap class “dead knobs”).

register_ocean_tdrag rdb_config Subroutine

&ocean_tdrag_nml: ice-shelf TOP-drag selector + coefficients. form enum mirrors parse_tdrag_variant in rdb_ocean_top_drag.

register_ocean_thermo rdb_config Subroutine

&ocean_thermo_nml: thermodynamics switch + scalar surface fluxes.

register_ocean_tides rdb_config Subroutine

&ocean_tides (C1 equilibrium astronomical body-force tide).

register_ocean_topo rdb_config Subroutine

&ocean_topo_nml: basin geometry + surface forcing + Coriolis tilt. topo_config / wind_config enums mirror the dispatch select-cases in rdb_ocean_state / rdb_ocean_setup.

register_ocean_tracers rdb_config Subroutine

&ocean_tracers_nml: prognostic-tracer registry switches.

register_ocean_vdiff rdb_config Subroutine

&ocean_vdiff_nml: backward-Euler vertical-friction folding knobs.

register_ocean_vmix rdb_config Subroutine

&ocean_vmix_nml: vertical-mixing module switches + knobs.

register_ocean_wetdry rdb_config Subroutine

&ocean_wetdry_nml: dynamic wetting/drying for the BT substep. Design + validation numbers: docs/ocean_wetdry_plan.md.

register_ocean_zinit rdb_config Subroutine

&ocean_zinit_nml: z-level T/S initial-condition overlay (A2). Default enable = .false. is a no-op (analytical IC unchanged).

register_one_canonical rdb_ocean_diag_fills Subroutine

Register one canonical diagnostic, applying its specs entry: skip if :off; override cadence / time-op; pick the output vgrid (:coord override, else default_coord, else LAYER) and attach the matching conservative remap. 2D diagnostics (n3 <= 1) ignore any coord request (no vertical to remap). All canonical diagnostics are INTENSIVE (thickness-weighted average on remap).

register_output rdb_config Subroutine

&output_nml: file output + I/O + forcing/restart/gauge files.

register_physics rdb_config Subroutine

&physics_nml: barotropic physics + bottom drag + wind stress.

register_porous rdb_config Subroutine

&ocean_porous (Adcroft 2013 porous barriers: subgrid sill/strait narrowing of the C-grid transport face widths).

register_redi rdb_config Subroutine

&ocean_redi (continuous neutral / along-isopycnal tracer diffusion, capability [3]).

register_sim rdb_config Subroutine

&sim_nml: the simulation regime selector.

register_slopes rdb_config Subroutine

&ocean_slopes (Griffies 1998 isopycnal-slope diagnostics).

register_tag rdb_ocean_data_forcing Subroutine

Register one tag if it names a file, else leave id = 0. Shared time-axis settings come from the group; scale/add are per tag.

register_tidal_mixing rdb_config Subroutine

&ocean_tidal_mixing (St-Laurent/Simmons internal-tide mixing).

register_time rdb_config Subroutine

&time_nml: time-integration controls. t_end is interpreted in time_unit and converted to seconds by the post-parse cascade in read_config; dt_fixed/dt_max stay in seconds. time_unit is a plain string (the cascade validates its set).

register_tracer rdb_config Subroutine

&tracer_nml: salinity + temperature IC/EOS/bounds + sediment.

register_varmix rdb_config Subroutine

&ocean_varmix (spatially-varying GM/Redi coefficients, [4]).

register_vcoord rdb_config Subroutine

&vcoord_nml: vertical-coordinate + ALE-remap controls. vcoord_type / remap_method / zstar_stretching are enums with the canonical sets accepted by the rdb_vcoord parsers.

register_wavespeed rdb_config Subroutine

&ocean_wavespeed (B1 first-baroclinic wave speed + Rd).

registry_clear rdb_ocean_restart Subroutine
registry_entry_found rdb_ocean_restart Function

Was tag actually present in the file the last time this registry was passed to ocean_restart_read_local? .false. before any read, and .false. for an unknown tag (a caller typo is a silent cold-seed, not a crash — callers that care should assert the tag exists via a successful register_* first). See restart_entry_t%found’s docstring for why this is not the same question as optional.

registry_register_2d rdb_ocean_restart Subroutine

Register a rank-2 owned field. arr is the full (ghosted) host array; the owned slice is (ng+1:ng+nx_phys, ng+1:ng+ny_phys).

registry_register_3d rdb_ocean_restart Subroutine

Register a rank-3 owned field. The vertical extent is taken from size(arr,3) (layers or interfaces — both fully owned).

registry_register_scalar rdb_ocean_restart Subroutine

Register a host scalar (rank-0 persistent state, e.g. the Chapman eta_old_chapman_* corner values). Host-only — never device- mapped, so the write path skips update self for it.

relative_drift rdb_console_stats Function

change / init with a zero guard for a never-set baseline.

relax_band_x_impl rdb_ocean_sponge Subroutine

Cosine-ramp tracer relaxation in a west/east sponge band. Explicit-shape dummies (flat-impl + outer-shim — the per-tracer slice is passed by the caller, never dereferenced inside the DC). side = +1 for the west edge (cells wall_face .. wall_face+band-1), side = -1 for the east edge (cells wall_face-1 .. wall_face-band).

Read more…
relax_band_y_impl rdb_ocean_sponge Subroutine

Cosine-ramp tracer relaxation in a south/north sponge band. Mirror of relax_band_x_impl for the y-direction; see its docstring for the optional budget mirror (PR-23).

relax_map_tracer_budget_impl rdb_ocean_sponge Subroutine

relax_map_tracer_impl + mirror the per-cell increment into budget (salt or heat), the S/T budget-instrumented variant — mirrors apply_geothermal_src_impl’s host-shim + flat-impl + budget-mirror shape. delta is the ALGEBRAIC increment hTr_new - hTr_old = (1-decay)*(tgt-hTr_old), written once and used for BOTH the state update and the budget mirror so the two stay exactly consistent (no independent recomputation to drift).

relax_map_tracer_impl rdb_ocean_sponge Subroutine

Relax one tracer’s hTr toward ref_tracer(:,:,:,it)*h_layer at rate idamp_h, no budget mirror (every tracer except S/T — see relax_map_tracer_budget_impl). ref_tracer is passed WHOLE + indexed by the scalar it inside the kernel — never sliced by the caller (§6.4: a device array section of a mapped array is the descriptor-walk trap the dc-assumed-shape hook exists to catch).

relax_map_u_impl rdb_ocean_sponge Subroutine

Relax u_face_x_layer toward u_ref at rate idamp_u. Explicit- shape dummies, dims declared first (decl-order hook). idamp_u(i,j) <= 0 is a bit-exact no-op (Idamp = 0 IS the sponge mask; also guarantees sponge_idamp_zero_is_exact_identity, since decay = exp(-0*dt) = 1.0 exactly would already be a no-op algebraically — the early if skips the arithmetic entirely instead of relying on that).

relax_map_v_impl rdb_ocean_sponge Subroutine

Relax v_face_y_layer toward v_ref at rate idamp_v. Mirror of relax_map_u_impl for the y-direction.

relax_one rdb_ocean_sponge Function

Cosine-ramp implicit relaxation of one cell toward tgt. decay = exp(-strength*alpha*dt), alpha the cosine ramp at band position d; result = hTr_curdecay + tgt(1-decay). Funnels through relax_toward for the shared core algebra (§3.1 / step 10 “one home” — the map-driven kernels derive decay from a per-cell Idamp instead of this band/strength ramp, but both land on the same cur*decay + tgt*(1-decay) update).

relax_toward rdb_ocean_sponge Function

Shared core algebra for BOTH sponge paths: cur*decay + tgt*(1-decay) — the exact solution of dphi/dt = -Idamp*(phi - phi_ref) over one step at constant phi_ref, for whatever decay = exp(-rate*dt) the caller derived (relax_one derives it from the legacy edge/band cosine ramp; the map kernels above derive it directly from a per-cell Idamp). “One home” for the algebra per the plan (§3.1 / step 10).

remap_column rdb_remap_column Subroutine

Dispatch to the requested remapping method.

remap_column_pcm rdb_remap_column Subroutine

Piecewise-constant (donor cell) remap. Diffusive, guaranteed monotone.

remap_column_plm rdb_remap_column Subroutine

Piecewise-linear (minmod-limited) remap. Monotone (no new extrema). Per old layer k: q_hat(xi) = q(k) + slope(k)(2xi - 1), xi in [0,1], slope(k) = 0.5*minmod(q(k+1)-q(k), q(k)-q(k-1)). bnd_extrap (absent/.false. = default) closes the boundary cells with boundary_half_jump instead of the PCM flatten — see remap_column. nonunif (absent/.false. = default) replaces the minmod half-difference — which assumes EQUAL source thicknesses — with the thickness-weighted CW84 (1.7)/(1.8) slope; see plm_slope_nonuniform.

remap_column_ppm rdb_remap_column Subroutine

Piecewise-parabolic (Colella & Woodward 1984) remap. Per old layer k, xi in [0,1]: q_hat(xi) = q_L + xi(q_R - q_L + q6(1 - xi)), q6 = 6q_bar - 3(q_L+q_R) Edge values: 4th-order interp + CW monotonicity limiting; boundary layers fall back to PLM-quality edges, or — under bnd_extrap — to the linear-exact one-sided pair (boundary_half_jump), which zeroes q6 there so the boundary cell carries a straight line. nonunif swaps the (7/12, -1/12) edge estimate — an EQUAL- thickness specialisation — for CW84 (1.6) on the true stencil thicknesses, and the 1|2 / (nz-1)|nz edges for the thickness-weighted two-cell value; see ppm_edge_nonuniform.

remap_column_ppm_h4 rdb_remap_column Subroutine

PPM with non-uniform 4th-order (H4) edge values (White & Adcroft 2008). As remap_column_ppm but the interior edge estimate is the thickness-weighted exactly-4th-order stencil (reduces to PPM’s (7/12,-1/12) on uniform layers), cutting spurious diapycnal mixing per remap (Ilicak et al. 2012). Limiter/reconstruction/integration are identical to PPM. H4 edge algebra is inlined (helper extraction costs 4-6% on this hot kernel). Boundary edges: outermost = PCM, second-from-boundary = non-uniform 3-cell (H3) quadratic; CW limiter clamps all edges to local monotone bounds.

remap_column_pqm rdb_remap_column Subroutine

Piecewise-quartic (PQM_IH4IH3) conservative remap (White & Adcroft 2008). Implicit-h4 edge VALUES + implicit-h3 edge SLOPES (each a diagonally-dominant tridiagonal solve with one-sided 4-cell boundary closure), per-cell quartic, W&A monotonicity limiter, conservative quartic overlap integral. Cuts diapycnal mixing per remap vs PPM/PPM_H4 (Ilicak et al. 2012). Per cell k, xi in [0,1]: q_hat(xi) = a + bxi + cxi^2 + dxi^3 + exi^4. Boundary cells reconstruct as PCM. nz < 5 falls back to REMAP_PPM (W&A boundary closure needs >= 4 cells).

remap_column_preconditions_ok rdb_remap_column Function

Precondition test for one remap column, as a pure predicate so the caller decides what to do about a violation (audit findings V5, V6).

Read more…
remap_fold_filler_defect rdb_ocean_remap Subroutine

On a column that carries a vanished layer (source or target), make the tracer remap conservative EXACTLY, not just on a matched column: the content the remap failed to place, Σ q_src − Σ q_new, is handed to the topmost live target layer (the donor of any fillers above it, so the write-side pool that follows shares it with them).

Read more…
remap_layer_to_density rdb_ocean_diag_fills Subroutine

Conservative layer→DENSITY-space remap (DIAG_VGRID_DENSITY). z_out(:) = monotone-increasing target potential DENSITIES (kg/m³). Per column: layer potential density via device EOS at the diag reference pressure, invert the profile to target-interface depths (invert_density_targets), then remap. Lightest target → surface. is_extensive=.false. ⇒ INTENSIVE (weighted average); .true. ⇒ EXTENSIVE (column integral redistributed across bins, Σ preserved). Public only for the unit-test suite.

remap_layer_to_density_impl rdb_ocean_diag_fills Subroutine

Per-column density-space remap, do concurrent over (j, i). Source column TOP-DOWN + layer potential density (EOS at rho_ref_p), invert profile to interface depths (invert_density_targets), then donor-cell remap. Cells outside the column density range read 0. Intensive/extensive as the z-remap.

Read more…
remap_layer_to_sigma rdb_ocean_diag_fills Subroutine

Layer→fixed-sigma vertical remap (terrain-following output grid). levels(:) are cumulative sigma fractions (0..1, shallow→deep); the m-th output cell spans [levels(m-1), levels(m)] * col_h. Same conservative donor-cell overlap as remap_layer_to_z; see its docstring for the intensive/extensive contract.

remap_layer_to_vcoord_impl rdb_ocean_diag_fills Subroutine

Per-column conservative layer→output-coordinate remap as a do concurrent over (j, i). Builds the source column TOP-DOWN (work index 1 = surface = state k=nz) and the target cells from the levels interface positions (implicit 0 surface), clips both to the column total, then runs the donor-cell overlap integral (remap_column, scheme method) on a common n = max(nz, nz_out) padded partition. Intensive remaps the value directly; extensive divides in / multiplies out by thickness so the column integral redistributes (sum preserved).

Read more…
remap_layer_to_z rdb_ocean_diag_fills Subroutine

Layer→fixed-z vertical remap, CONSERVATIVE (donor-cell overlap via remap_column, scheme diag_remap_method). is_extensive=.false. ⇒ INTENSIVE (thickness-weighted average of overlapping source layers); .true. ⇒ EXTENSIVE (thickness-integrated field — column integral redistributed across targets, Σ preserved when the z-grid spans H). z_out(:) = target INTERFACE depths (m, positive-down, shallow→deep, implicit 0 surface); output cell m spans [z_out(m-1), z_out(m)]. Thicknesses clipped to column total H = Σ h_layer over the LIVE layers (exact conservation; a vanished layer carries zero weight — see remap_layer_to_vcoord_impl); below-seafloor cells read 0. k=1 bed, k=nz surface. Public only for the unit-test suite.

remap_layer_to_zstar rdb_ocean_diag_fills Subroutine

Layer→fixed-z* vertical remap (SSH-tracking stretched-depth output grid). levels(:) are reference interface depths (m, positive-down, shallow→deep); the deepest is the reference total depth H_ref and the per-column grid is stretched by col_h / H_ref. Identical to remap_layer_to_sigma under uniform levels — supply a non-uniform (fine-near-surface) reference for it to differ. Same conservative donor-cell overlap; see remap_layer_to_z for the intensive/extensive contract.

remap_tracer_grounded rdb_ocean_min_thickness Subroutine

Conservative tracer remap gated on the grounded mask. Non-grounded columns are skipped -> hTr byte-unchanged; the concentration divisions only happen on grounded columns.

remap_x_face_grounded rdb_ocean_min_thickness Subroutine

Conservative east-face velocity remap gated on the grounded mask. A face is active iff either adjacent cell is grounded (2 mask loads — no neighbour-column re-scan); inactive faces are left byte-unchanged. Face thickness is the arithmetic mean of the two adjacent cells (outer walls take the single interior cell); the target side reads h_new only where the mask is set — elsewhere h_new ≡ h_old by construction, so h_old is read directly. remap_column preserves the per-face momentum Sigma h_face . u.

remap_x_face_velocity rdb_ocean_remap Subroutine

Flat-impl x-face remap. East faces at i+1/2; u_face_x(1..nx+1) covers west wall (I=1), interior (I=2..nx), east wall (I=nx+1). conserve_ke (default .false.): rescale the baroclinic anomaly so column anomaly KE matches pre-remap, barotropic mean preserved. See rescale_anomaly_ke.

remap_y_face_grounded rdb_ocean_min_thickness Subroutine

Conservative north-face velocity remap, mirror of the x routine.

remap_y_face_velocity rdb_ocean_remap Subroutine

Flat-impl y-face remap, mirror of remap_x_face_velocity. See that routine for the conserve_ke / bnd_extrap / nonunif semantics.

renormalise_meridional_flux_to_vhbt rdb_continuity Subroutine

Apply a uniform per-face velocity correction so Σ_k mass_flux_y_layer(i, j, k) = vhbt(i, j) at every face. Mirror of renormalise_zonal_flux_to_uhbt. See that routine for the skip_walls and has_* (MPI seam, O4 fix) semantics.

renormalise_zonal_flux_to_uhbt rdb_continuity Subroutine

Apply a uniform per-face velocity correction so Σ_k mass_flux_x_layer(i, j, k) = uhbt(i, j) at every face. Helper for continuity_zonal_flux. skip_walls (default true) bypasses the physical-wall faces where mass_flux was zeroed; pass .false. for periodic axes so the wall faces (which carry real transport) are renormalised.

report_throughput rdb_driver Subroutine

Log per-GPU and total horizontal throughput on the root compute rank.

Read more…
required_halo rdb_ocean_halo_width Function

max() over every rule that applies to the given scheme selection — the minimum nghost a grid must carry. Every argument is optional; an absent selector contributes its BASELINE (2, the centered/PPM/non-periodic/single-rank floor), an absent logical contributes nothing (as if .false.).

rescale_anomaly_ke rdb_ocean_remap Subroutine

KE-conserving rescale of a remapped face-velocity column. The column remap conserves momentum (Σ h·u) but not KE; restore it by rescaling ONLY the baroclinic anomaly (Adcroft & Hallberg 2006): scale = sqrt(KE_old_anom/KE_new_anom), clamped to [0, 1.25] u_new(k) = u_bar_new + scale·(u_new(k) - u_bar_new) Barotropic mean u_bar preserved verbatim; degenerate columns untouched.

reset_accumulator rdb_ocean_diag Subroutine

Zero (MEAN), -huge (MAX), or +huge (MIN) the accumulator — so the first accumulate step seeds correctly. Runs on device via the flat-impl shim because v%accumulator is reached through the vars(:) array-of-derived-types indirection that NVHPC can’t follow inside a do concurrent.

reset_bt_rem rdb_barotropic_coupling Subroutine

bt_rem_u/v ≡ 1 (the init value). bt_rem_u/v is otherwise reset only by compute_bt_rem, which only runs when bt_substep_drag is on. compute_bt_rem_wave_drag MULTIPLIES into bt_rem_u/v, so when wave drag is on and bt_substep_drag is off, something must still reset it to 1 each stage — otherwise it compounds geometrically across outer steps (bt_rem = R^n after n stages), silently annihilating the barotropic mode. See src/core/ocean/README.md for the multiplicative-accumulator contract this establishes.

reset_state rdb_nml_schema Subroutine

Reset parse-state (found flags) before a parse.

reset_vanished_layer_velocities rdb_ocean_dyn Subroutine

Zero the per-layer face velocity at any face where BOTH adjacent centre-cell thicknesses are at or below vanish_tol (isopycnal_vanish_tol(angstrom_h) = max(angstrom_h, H_VANISHED)).

Read more…
resolve_bt_halo rdb_config Function

Resolve the &ocean_bt_nml bt_halo sentinel to a concrete march-in width. requested == BT_HALO_AUTO_SENTINEL (-1, the default) => AUTO: 0. The march-in used to switch itself on (BT_HALO_AUTO_WIDTH) on every compatible multi-rank run. It is not bit-reproducible against the serial run over variable bathymetry or with open boundaries (test_ocean_decomp_bitid_mpi), so a default multi-rank run must not pick it: AUTO is off, serial or not. requested >= 0 (user set it explicitly) => returned UNCHANGED; the fail-loud exclusion checks in validate_config police an explicit bt_halo > 0 against an incompatible feature (user asked for the impossible), so the auto-resolution never overrides an explicit 0 or an explicit width. compute_size / exclusion_active no longer change the answer; they stay so the call site (and its exclusion log) keeps its shape for the day the march-in is exact again.

resolve_canonical_spec rdb_ocean_diag_fills Subroutine

Look up canonical diagnostic name in the parsed specs and apply its overrides: skip=.true. if the entry is :off; otherwise time_op / dt_out / coord are overwritten when the entry sets them. No matching entry (or absent specs) leaves the caller’s defaults untouched.

resolve_flux_targets rdb_ocean_data_forcing Subroutine

Pick the heat/salt destination for this run and reject the freshwater tags when the component set they need is absent.

Read more…
resolve_ocean rdb_ocean_api Function

Resolve + verify a handle is a live, fully-initialised ocean simulation. Every query/step entry point funnels through this so the bad-handle and not-yet-initialised cases are reported with one consistent status code each, in one place.

resolve_ocean_pending rdb_ocean_api Function

P2.5: resolve + verify a handle is a live, PENDING (not yet finalised) ocean simulation — the window every rdb_ocean_stage_* geometry-injection call requires. Mirrors resolve_ocean’s shape, checking is_pending instead of is_initialised.

resolve_time_var rdb_ocean_data_input Subroutine

Look up the time coordinate variable by the CF convention (dim name == var name); fall back to a variable literally named “time”. status is nf90_noerr iff found.

restart_io_ok rdb_ocean_restart_io Function

Translate a raw nc_check-style status (0 = ok) from one of the nc_* calls in ocean_restart_write_local into the caller’s ierr contract. Mirrors rdb_bathymetry’s bathy_io_ok / rdb_ocean_diag_netcdf’s diag_io_ok (P0.1 F1 / P7 F1): closes ncid (when given) on failure so a mid-write error does not leak the file handle, sets ierr = OCEAN_STATUS_ERR_IO when present, or error stops with the generic nc_check text when ierr is absent (byte-identical legacy behaviour).

restart_mismatch_kind rdb_ocean_state Function

Map the check-decomp ierr code (INTERNAL 1/2/3 convention — see ocean_restart_check_decomp) to a human-readable kind for the legacy error stop message.

restart_mismatch_status_code rdb_ocean_state Function

Map the check-decomp ierr code (INTERNAL 1/2/3 convention) onto the PUBLIC, collision-free OCEAN_STATUS_ERR_RESTART_* codes returned through ocean_state_restart_read’s ierr (P0.1 review F4).

restore_state rdb_ocean_dyn Subroutine

Copy the *_0 save buffers back into h_layer / u_face_x_layer / v_face_y_layer — the pred_corr between-stage reset (SPEC §2): the predictor’s provisional up/vp/hp are DISCARDED (only u_av/v_av/ h_av survive it), and the corrector advances from u^n / h^n. Tracers are untouched by the predictor (TR_MODE_NONE + no thermodynamics), so no tracer restore is needed.

rk2_average rdb_ocean_dyn Subroutine

State <- 0.5 * (state_0 + state) for h_layer, u_face_x_layer, v_face_y_layer. Tracer averages are done by the caller.

rk2_average_field_3d rdb_ocean_dyn Subroutine

current <- 0.5 * (saved + current) on the device. Same bare-array shim rationale as copy_field_3d.

roquet_pcm_dpa_face rdb_ocean_pressure_force Subroutine

Cross-face 5-point Boole quadrature of the layer dpa for a PCM column pair under Roquet SpV (intx_dpa / inty_dpa): the Roquet twin of wright_pcm_dpa_face, and boole_dpa_face_pcm with the factored vertical rule roquet_pcm_dpa_intz at the three interior sub-columns (same sub-column T/S / height / thickness interpolation, same weights and summation order). 3 T/S polynomials + 15 pressure Horners per face per layer, against 15 full generic-EOS calls.

roquet_pcm_dpa_intz rdb_ocean_pressure_force Subroutine

Vertical integral of the Roquet et al. (2015) SpV in-situ density anomaly over one constant-T/S (PCM) layer: the 5-point Boole rule of boole_dpa_intz_layer (MOM6 int_density_dz_generic_pcm, which is also what MOM6 runs for ROQUET_SPV under a Boussinesq PGF), with the EOS FACTORED.

Read more…
roquet_recon_dpa_face rdb_ocean_pressure_force Subroutine

boole_dpa_face (the reconstruct-for-pressure cross-face 5-point Boole rule) with the Roquet vertical rule roquet_recon_dpa_intz at the three interior sub-columns – identical sub-columns, weights and summation order; the end points are the columns’ own dpa. 15 inlined Roquet evaluations per face per layer.

roquet_recon_dpa_intz rdb_ocean_pressure_force Subroutine

boole_dpa_intz_layer (the reconstruct-for-pressure in-layer 5-point Boole rule over a PLM / PPM T/S profile) specialised to Roquet SpV: the same five sub-points, weights and summation order, with the density 1/SV from this module’s copy of the SpV value (rdb_roq_ts_coeffs + rdb_roq_spv_p, rdb_roquet_spv.inc) – no eos_t handle, no per-point variant dispatch, and a body the compiler inlines into the kernel. T and S vary through the layer, so unlike roquet_pcm_dpa_intz there is no (T, S) hoist: each point is a full EOS evaluation.

roquet_spv_point rdb_eos Subroutine

Fused Roquet et al. (2015) SpV evaluation at a point, in MODEL variables (potential temperature T_pt degC, practical salinity S_sp PSU, pressure p Pa). Returns specific volume sv (m^3/kg) and the analytic sensitivities w.r.t. the MODEL variables (dsv_dt_model = dSV/dPT, dsv_ds_model = dSV/dSP) so the variant-agnostic consumers (which work in PT, SP) get the correct chain-ruled derivatives.

Read more…
roquet_spv_ts_coeffs rdb_eos Subroutine

The (T, S)-dependent coefficients of the Roquet et al. (2015) SpV polynomial viewed as a polynomial in PRESSURE, in model variables (potential temperature T_pt degC, practical salinity S_sp PSU):

Read more…
roquet_spv_value rdb_eos Function

VALUE-ONLY Roquet et al. (2015) specific volume (m^3/kg) at a point, model variables (PT degC, SP PSU, p Pa). The same number as roquet_spv_point’s sv without the dSV/dT, dSV/dS and PT->CT chain-rule work that a density-only consumer (rho_layer, eos_density_point) would discard – roughly half the arithmetic.

run_continuity_chain rdb_ocean_dyn Subroutine

The slow horizontal continuity + tracer chain (ghost fills → constrained continuity+tracer split → reservoirs → halo/wrap → tracer hdiff → Redi → vertical advection), extracted verbatim from run_stage_split so the pred_corr path can run it AFTER the velocity update + implicit friction (the forward-backward pairing, SPEC §2 C8/§1 fact 5) while the historical ssp_rk2 path keeps it before the applies (bit-identical). h_only selects the predictor’s TR_MODE_NONE (SPEC §2 P9); mass_out_weight is the per-call budget weight (0.5 per SSP stage; 0 for the discarded predictor state, 1 for the corrector).

run_gm_step rdb_ocean_dyn Subroutine

Gent-McWilliams thickness diffusion as its OWN sequential operator, run once per outer step AFTER the dynamics (the stage loop and, under ssp_rk2, the stage average) — where MOM6 calls thickness_diffuse after step_MOM_dyn_split_RK2, every dynamics step:

Read more…
run_meke_step rdb_ocean_dyn Subroutine

Thin dispatcher: call meke_step only when the MEKE slot is present AND enabled, forwarding the (also-optional) VarMix + wavespeed slots so the feedback seam + length scales engage when those are on. meke_step itself no-ops on enable=.false.; this guard avoids the call (and the present-propagation noise) when the slot is absent. hv%ke_diss (the lateral-viscosity KE dissipation rate) is forwarded for the frictional source; it is 0 unless hv%compute_ke_diss is set (and meke%frcoeff<0 ignores it) ⇒ inert by default.

run_stage rdb_ocean_dyn Subroutine

One FE stage of the multilayer step. Order of operations:

Read more…
run_stage_split rdb_ocean_dyn Subroutine

One FE stage of the split-explicit step. See the ocean_dyn_step_split header for the design.

safe_cos rdb_safe_math Function

cos(x). Plain elemental inline around the intrinsic; see safe_exp and the module docstring.

safe_cos_polynomial rdb_safe_math Function

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. cos(x) via the same Cody-Waite reduction; the quadrant map is shifted by 1 vs sin:

Read more…
safe_exp rdb_safe_math Function

exp(x). Plain elemental inline around the intrinsic — zero overhead, codegen identical to writing exp(x) directly. No production module calls this today (PR-8 removed the RDB_BITWISE_REPRO dispatch that once routed it to safe_exp_polynomial, which enabled nothing); see the module docstring.

safe_exp_polynomial rdb_safe_math Function

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Cody-Waite range reduction x = k*ln(2) + r, |r| ≤ ln(2)/2, followed by a 14-term Horner Taylor on exp(r) and an IEEE-exact 2^k multiply via scale(). Max relative error ≈ 2-3 ULP across [-709, 709].

Read more…
safe_log rdb_safe_math Function

log(x) (natural log). Plain elemental inline around the intrinsic; see safe_exp and the module docstring.

safe_log_polynomial rdb_safe_math Function

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. log(x) via IEEE exponent extraction + atanh-form series.

Read more…
safe_pow rdb_safe_math Function

Non-integer exponent only. For integer exponents (a**2, a**3, …), write the multiplication out — the compiler unrolls those and they’re already deterministic. Plain elemental inline around the intrinsic; see safe_exp and the module docstring.

safe_pow_polynomial rdb_safe_math Function

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. base^exponent via the identity base^exponent = exp(exponent * log(base)) Routes through the polynomial log and exp paths so the result is deterministic across builds.

Read more…
safe_sin rdb_safe_math Function

sin(x). Plain elemental inline around the intrinsic; see safe_exp and the module docstring.

safe_sin_polynomial rdb_safe_math Function

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. sin(x) via Cody-Waite reduction mod π/2 and a 9-term Horner Taylor on the reduced argument. The quadrant k mod 4 picks sin vs cos and a sign:

Read more…
safe_sqrt rdb_safe_math Function

IEEE-correctly-rounded by mandate, so the intrinsic is already bit-identical across compliant compilers.

save_state rdb_ocean_dyn Subroutine

Copy h_layer, u_face_x_layer, v_face_y_layer into the *_0 save buffers on the multilayer state. Per-tracer hTr is saved by the caller via copy_field_3d (the registry has to be walked on the host).

scan_vanished_one_impl rdb_multilayer_state Subroutine

Flat-impl of the I1′ scan for ONE tracer. Per column: find the topmost live layer, then walk DOWN carrying the nearest live layer above — the donor map rdb_vl_merge_content / rdb_vl_column_conc use — and test each filler against its donor’s hTr/h.

schema_add_external_group rdb_nml_schema Subroutine

Register a group name the schema knows exists but does NOT validate (its body is skipped silently).

schema_add_group rdb_nml_schema Subroutine

MOVE a locally-built group into the schema — g is consumed (allocatables transferred). Move semantics on purpose: intrinsic assignment deep-copies the polymorphic key boxes, which NVHPC miscompiles (heap corruption); move_alloc transfers descriptors only. Error stop on duplicate name.

schema_find_group rdb_nml_schema Function

Index of name in the schema’s groups, 0 if absent.

schema_is_external rdb_nml_schema Function

True if name is a registered external group.

schema_parse rdb_nml_schema Subroutine

Parse and validate the namelist file at path.

Read more…
schema_parse_lines rdb_nml_schema Subroutine

In-memory sibling of schema_parse: validate + apply a namelist already held as a lines(:) character array (no file touch). Same error-return convention as schema_parse.

schema_render_json rdb_nml_schema Subroutine

Emit the schema as JSON: one object per group, nesting one object per key. This is the ONLY thing tools/gen_python_config.py reads – it parses no Fortran source, mirroring the precedent schema_render_markdown already set for docs/generated_nml_knobs.md. &ocean_bc_nml is NOT here – it is registered via add_external_group (see rdb_config.F90), so it carries no keys on this schema; python/rdb/_config_bc.py is a hand-written stub with its own drift test (see docs D5.7).

schema_render_markdown rdb_nml_schema Subroutine

Render the schema as Markdown: per group a heading, doc line, and a knob table.

schema_write_doc_all rdb_nml_schema Subroutine

Write every group and key as valid namelist with aligned docs.

schema_write_doc_short rdb_nml_schema Subroutine

Write only non-default keys (MOM6 parameter_doc.short). Groups with no non-default keys are omitted entirely.

scratch_3d_buffer_bytes rdb_scratch_3d Function

Counted allocatable footprint of the 3D scratch buffer slot (0 when unallocated).

scratch_3d_buffer_destroy rdb_scratch_3d Subroutine
scratch_3d_buffer_enter_data rdb_scratch_3d Subroutine

Type-bound wrapper — keeps buf%enter_data() call sites working. Delegates to the non-polymorphic impl so the OpenMP map base is the heap object (see the impl + the public-decl comment above).

scratch_3d_buffer_enter_data_impl rdb_scratch_3d Subroutine

Attach the scratch payload to the device holding the HOST payload: zero from init (allocate(..., source = 0.0_wp)), or whatever a warm-restart read restored into it before the map. The zero half is a contract, not an implementation detail: a consumer whose producer was SKIPPED this step is entitled to read zero on a cold start, and it must read zero on BOTH toolchains (see the inline note below for the pred_corr predictor that does exactly that). type(...) (not class) dummy on purpose: a by-reference non-polymorphic dummy aliases the heap object, so copyin(this%data) attaches against a heap base — no polymorphic stack box for AMD to reject.

Read more…
scratch_3d_buffer_exit_data rdb_scratch_3d Subroutine

Type-bound wrapper — see scratch_3d_buffer_enter_data.

scratch_3d_buffer_exit_data_impl rdb_scratch_3d Subroutine

Release the scratch payload from the device. No copyout — scratch contents are per-step intermediates with no host-side meaning. No-op when never allocated (mirrors scratch_3d_buffer_enter_data_impl’s gate).

scratch_3d_buffer_init rdb_scratch_3d Subroutine

Allocate the host-side storage at (n1, n2, n3), zero-filled. GPU attachment is a separate step via enter_data — init runs before the device exists in the typical init-then-enter-data sequence.

seed_baroclinic_jet_ic rdb_ocean_state Subroutine

Two-layer reduced-gravity baroclinic-instability IC — a geostrophically-balanced tanh jet in the upper (surface) layer of a spherical re-entrant channel, plus a front-localised sech² meander seed that the instability grows. Reproduces the bc_inst spec (SIM_DETAILS.md §5), mapped to Roundabout’s bottom-up layer convention (k=1 bed, k=nz surface). The spec’s layers FLIP:

Read more…
seed_cavity_draft rdb_ocean_state Subroutine

Fill metrics%z_draft (and its cover_frac companion) from &ocean_cavity_dyn_nml, then cross-validate the geometry against the seeded bathymetry. Runs from ocean_state_seed_from_cfg IMMEDIATELY after the bathymetry and BEFORE the layer split and the wet-mask seed, which both read b − z_draft.

Read more…
seed_eady_ic rdb_ocean_state Subroutine

Eady-front overlay IC. Assumes flat bottom + uniform layer split already in place from ocean_state_seed_from_cfg.

Read more…
seed_geostrophic_adjustment_ic rdb_ocean_state Subroutine

Rossby’s classic geostrophic-adjustment problem. Overlays a Gaussian SSH bump on a flat-bottom, single-layer (barotropic) state at rest: η(x, y) = A · exp(-r² / L²) h(i, j) = b(i, j) + η(i, j) u = v = 0 where r is the radial distance from the bump centre.

Read more…
seed_h_layer_uniform_impl rdb_ocean_state Subroutine

Even-split layer thickness per column. Pulled into a flat-impl so the do concurrent body works on plain allocatables — the outer shim reaches the multilayer + barotropic slot components once on the host.

Read more…
seed_h_layer_uniform_z_impl rdb_ocean_state Subroutine

thickness_config = "uniform_z": MOM6 initialize_thickness_uniform port. Lays uniform z interfaces over the GLOBAL max_depth, clips them bottom-up against the local bathymetry, and collapses whatever will not fit to a minimum-thickness floor:

Read more…
seed_land_face_vel_2d_impl rdb_ocean_state Subroutine

2D (barotropic) variant of seed_land_face_vel_impl.

seed_land_face_vel_impl rdb_ocean_state Subroutine

Zero a per-layer face field ((nf1,nf2,nz)) at land faces (wet_face==0). wet_face is the matching wet_u/wet_v.

seed_land_h_floor_impl rdb_ocean_state Subroutine

Floor land-cell layer thickness to H_VANISHED (never 0 ⇒ no 1/0 in any per-layer divide). Wet cells untouched.

seed_land_tracer_hold_impl rdb_ocean_state Subroutine

Zero the extensive tracer content hTr on land T-cells (wet_mask == 0). Wet cells untouched (bit-identical when wet_mask ≡ 1).

Read more…
seed_tracer_stratified_impl rdb_ocean_state Subroutine

Seed hTr(i,j,k) = t_layer(k) * h_layer(i,j,k) for the per-layer stratified-IC tracer (temperature). t_layer(:) is a small 1D array pre-computed on host.

seed_tracer_uniform_impl rdb_ocean_state Subroutine

Seed hTr = const * h_layer for a uniform-IC tracer (salinity).

seed_ts_from_zfile rdb_ocean_z_init Subroutine

Read T/S from the configured z-level NetCDF and overwrite the tracer slots with the depth-interpolated profiles. Wet columns interpolate; dry columns get the namelist land-fill constants. Must be called AFTER bathymetry, the uniform h_layer seed, and wet_mask are in place. Takes the multilayer slot directly (not the full ocean state) to avoid a circular dependency.

seed_ts_linear_z rdb_ocean_z_init Subroutine

Seed T and S from the ANALYTIC affine geopotential profiles T(z) = lin_t_ref + lin_dt_dz*z, S(z) = lin_s_ref + lin_ds_dz*z (z positive UP, zero at the z = 0 datum), sampled at each layer centre’s TRUE geopotential depth and written as hTr = value * h_layer.

Read more…
seed_wet_mask_impl rdb_ocean_state Subroutine

1.0 where b >= cutoff (ocean), 0.0 elsewhere (land). Default (absent land_cutoff): cutoff = LAND_DEPTH_THRESHOLD (byte-identical to the pre-v2 path). When land_cutoff is present, a column is land iff b < land_cutoff; the wetdry-aware seed passes land_cutoff = -land_margin so intertidal columns (bed above rest MSL but below the flood headroom) stay wet_mask=1 and the dynamic wd_wet_dyn gate handles their wetting/drying.

seed_wrap_static_2d rdb_ocean_state Subroutine

Fill the seam ghosts of a static, cell-centred 2-D geometry field (bathymetry, ice draft, cover fraction) from their periodic / north-fold images, on the host, at seed time.

Read more…
seed_zinit_overlay rdb_ocean_state Subroutine

Dispatch the &ocean_zinit_nml T/S overlay across its two axes: the profile SOURCE ("file" — the pre-regridded NetCDF reader; "linear" — the analytic affine lin_* profile) and whether a cavity draft is present.

Read more…
segment_geometry rdb_ocean_data_input Subroutine

Degenerate-axis + along-edge slab geometry for an OBC-segment registration. i0/j0/nx/ny are FILE-side (start, count); dest_i0/dest_j0 are where the slab lands in the consumer’s staging array.

set_bathymetry_double_drake rdb_ocean_state Subroutine

“Double Drake” idealised supercontinent (Ferreira, Marshall & Campin 2010, J. Climate): a flat-bottom global ocean at max_depth with TWO thin meridional wall-continents 90° of longitude apart, each running from the north pole down to a southern-channel latitude, leaving a reentrant circumpolar channel (Drake-Passage analogue) to the south. Used as the static-land-mask integration showcase on a spherical periodic-x sector grid.

Read more…
set_bathymetry_island rdb_ocean_state Subroutine

Flat-bottom basin at max_depth everywhere, except a central square of LAND (b = 0, well below LAND_DEPTH_THRESHOLD). The land square is centred on the physical domain and spans the central 2*half_frac fraction of each axis (e.g. half_frac=0.2 ⇒ the middle 40 % is land). half_frac is taken from &ocean_topo_nml slope_scale at the call site (no new knob).

Read more…
set_bathymetry_isomip_plus rdb_ocean_state Subroutine

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules.

Read more…
set_bathymetry_neverworld2 rdb_ocean_state Subroutine

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules.

Read more…
set_bathymetry_seamount rdb_ocean_state Subroutine

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Fill b(:,:) with a centred Gaussian seamount bathymetry:

Read more…
set_bathymetry_spoon rdb_ocean_state Subroutine

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Fill b(:,:) with the MOM6 spoon bathymetry. In Cartesian terms (we collapse MOM6’s lat/lon factors of R_earth · π / 180 into a direct meters scale), the local depth is

Read more…
set_cor_ref_velocity rdb_barotropic_coupling Subroutine

Fill bt_work%cor_ref_u/v — the barotropic velocity at which subtract_fast_cor_ref evaluates the Coriolis/advection reference it removes from the substep forcing (MOM6 ubt_Cor/vbt_Cor).

Read more…
set_diag_mask_vanished rdb_ocean_diag_fills Subroutine

Enable / disable masking of vanished (no-water) remap target cells to DIAG_MISSING_VALUE (host only). Default off.

set_diag_remap_method rdb_ocean_diag_fills Subroutine

Seed the module-level diagnostic remap reconstruction (host only).

set_draft_flat rdb_ocean_cavity Subroutine

Uniform draft draft inside the shelf box [x0,x1] x [y0,y1], zero outside it (open ocean, including everything beyond the calving front at x1). Any bound at or beyond CAVITY_BOUND_INF is ignored — the shelf is then open on that side, which is what the namelist defaults ask for.

Read more…
set_draft_linear rdb_ocean_cavity Subroutine

Linear-in-x draft z_draft = draft0 + slope*(x - x0) inside the shelf box, clipped at 0 from below (a formula that would lift the ice base above the sea surface is open water, not negative ice), and zero outside the box.

Read more…
set_fast_forcing_eta_pf rdb_barotropic_coupling Subroutine

The barotropic substep’s frozen forcing under the MOM6 split (&ocean_bt_nml bc_pgf_forcing, default on):

Read more…
set_local_BT_cont_types rdb_barotropic_coupling Subroutine

Populate bt_work%BTCL_u/v — the per-face flux-closure coefficients consumed by find_uhbt — from the current h_layer. Upstream-h-sum approach: FA_u_W0=FA_u_E0=Σ_k h_face (centred); FA_u_WW=Σ_k h_layer(west) and FA_u_EE=Σ_k h_layer(east) (saturated-regime upstream draw); uBT_WW/EE = ±VOL_CFL·dx/dt_outer pin the saturation velocity; uh_crv/uh_* are the C¹-matching coefficients (Hallberg & Adcroft 2009). No-op when use_bt_cont_type = .false. (BTCL_u/v unallocated).

setup_failed rdb_ocean_engine Function

.true. iff ierr is present and non-OK — the “shall I return early” test used after every ierr-threaded call in engine_setup. When ierr is absent the callee already error stopped on failure, so this is always .false. here.

shape_matches_interior rdb_ocean_api Function

True iff (nx_p, ny_p, nz_p) matches the live handle’s physical interior shape (grid%nx_phys, grid%ny_phys, multilayer%nz_ml) — the shape every P2 3D setter’s caller- supplied array must have.

sin_reduced rdb_safe_math Function

Horner sin Taylor on |r| ≤ π/4. sin(r) = r * P(r²) where P is the odd-power polynomial in r² — avoids computing r¹, r³, r⁵… separately. 9 terms (highest power r¹⁷) gives < 1e-18 truncation error.

skip_to_slash rdb_nml_schema Subroutine

Advance past the next ‘/’ (group terminator); recovery aid.

snapshot_column_concentration rdb_ocean_sponge Subroutine

Fill one water column’s reference concentration from hTr/h, falling back to the nearest massive layer (h > H_VANISHED) for any vanished layer — bed-up pass first, then a surface-down pass to backfill any vanished layers below the first massive one. Plain host loop (called from a host do i,j loop, never do concurrent — this is configure-time setup, not a per-step kernel).

snapshot_eta_PF rdb_barotropic_coupling Subroutine

Snapshot bt_eta into eta_PF — the free-surface height the slow PGF sees this stage. Later differenced by compute_e_anom.

snapshot_u_prev_east rdb_ocean_obc_baroclinic Subroutine

Snapshot u at the first interior face (i_e-1) into u_prev_east.

snapshot_u_prev_west rdb_ocean_obc_baroclinic Subroutine

Snapshot u at the first interior face (i_w+1) into u_prev_west.

snapshot_v_prev_north rdb_ocean_obc_baroclinic Subroutine

Snapshot v at the first interior face (j_n-1) into u_prev_north.

snapshot_v_prev_south rdb_ocean_obc_baroclinic Subroutine

Snapshot v at the first interior face (j_s+1) into u_prev_south.

sort_real rdb_ocean_bathymetry_inject Subroutine

Plain insertion sort. a is at most a few hundred cells in every realistic setup-time call (and correctness, not speed, is what matters for a diagnostic median) — no need for anything fancier.

spherical_quad_area rdb_ocean_metrics Function

Area (m^2) of a spherical quadrilateral with the four corners (1,2,3,4 counter-clockwise) given in degrees, via L’Huilier’s theorem on the two triangles (1,2,3) and (1,3,4).

spherical_tri_area rdb_ocean_metrics Function

Area (m^2) of a spherical triangle (corners in degrees) via the spherical-excess form of L’Huilier’s theorem. Side lengths are angular (great-circle distance / r).

split_to_lines rdb_config Subroutine

Split a newline-separated buffer into a fixed-len character array (one record per line, trailing CR stripped) for internal-file reads + the schema line walker.

sponge_add_band_x rdb_ocean_setup Subroutine

Add a cosine-ramp Idamp band for a west/east (x-normal) sponge edge into the three maps, SUMMING onto whatever is already there (§3.2 corner composition). Offsets reproduce rdb_ocean_sponge::ocean_sponge_apply{,_tracers} exactly: idamp_h/idamp_v share the cell-column offset; idamp_u (the x-normal face) sits one further column in for the west edge (side = +1) and shares the offset for the east edge (side = -1) — the legacy kernel’s own asymmetry (see Risk 2 of the plan), reproduced verbatim so damp_source="band" matches today’s band exactly.

sponge_add_band_y rdb_ocean_setup Subroutine

Mirror of sponge_add_band_x for a south/north (y-normal) sponge edge: idamp_h/idamp_u share the row offset; idamp_v (the y-normal face) sits one further row in for the south edge (side = +1) and shares the offset for the north edge (side = -1).

sponge_band_alpha rdb_ocean_sponge Function

Shape factor of the damp_source="band" ramp at cell offset d (0 = hard against the sponge-tagged wall) for a band of band cells. The per-cell rate is sponge_strength * alpha.

Read more…
sponge_ramp_is_valid rdb_config Function

.true. iff &ocean_sponge_nml ramp names a band shape the damp_source="band" filler implements.

sponge_relax_band_x_tracer rdb_ocean_sponge Subroutine

Host dispatch for one tracer’s relax_band_x_impl call: routes the salinity/temperature budget mirror (PR-23) so the legacy band sponge’s tracer sink is instrumented exactly like the map-driven path, without threading an if-branch into every one of the four edge blocks in ocean_sponge_apply_tracers.

sponge_relax_band_y_tracer rdb_ocean_sponge Subroutine

Mirror of sponge_relax_band_x_tracer for the y-direction.

sponge_source_is_implemented rdb_config Function

.true. iff &ocean_sponge_nml damp_source names a source that is actually filled. "file" is a recognised name (PR-23b, needs the PR-14 reader) but has no kernel yet — a source with no filler must abort, not silently build an all-zero map (the lateral_closure_is_implemented idiom).

Read more…
sponge_target_is_implemented rdb_config Function

.true. iff &ocean_sponge_nml target_source names a reference state that is actually filled: "ic" (snapshot of the seeded initial condition) or "linear_z" (analytic affine geopotential profile, re-evaluated on the live layer geometry). "file" is recognised but has no reader yet (PR-23b).

stress_scratch_ensure rdb_ice_ocean_coupler Subroutine

Lazily (re)allocate + device-map the per-step tau-blend scratch (F6). Size change tears down and rebuilds. Never called inside a per-substep loop (this whole coupler runs once per outer step).

string_default_string rdb_nml_schema Function
string_is_default rdb_nml_schema Function
string_parse rdb_nml_schema Subroutine
string_to_c rdb_ocean_restart_io Function

Pack a Fortran string into a null-terminated c_char array.

string_value_string rdb_nml_schema Function
strip_comment rdb_nml_schema Function

Remove a trailing ! comment, respecting single/double quotes.

strip_nml rdb_nml_schema Function

Drop a trailing _nml suffix (namelist files spell groups &<name>_nml; the schema stores the bare <name>).

sturm_count rdb_ocean_wave_speed Function

Number of Sturm-sequence sign changes (eigenvalues < lam) via the three-term determinant recursion with dynamic rescaling.

substep_drag_ignores_bdrag_form rdb_config Function

Is &ocean_bt_nml substep_drag blind to the configured bottom drag?

Read more…
subtract_fast_cor_ref rdb_barotropic_coupling Subroutine

Subtract the fast-loop Coriolis + vector-invariant advection, evaluated at the reference barotropic velocity bt_work%cor_ref_u/cor_ref_v (filled by set_cor_ref_velocity), from the substep forcing F_bt_u_fast/F_bt_v_fast.

Read more…
suggest rdb_nml_schema Function

Build a ” (did you mean ‘x’?)” fragment if a close candidate exists (distance <= max(2, len/3)); else empty.

sum_slow_tendencies_into_F_slow rdb_barotropic_coupling Subroutine

Sum the per-kernel slow-tendency scratch buffers into a single (bt_work%F_slow_u, bt_work%F_slow_v) field per face per layer. Reads pgf%dpdx_face, cor%pv_flux_x, hv%du_visc, bd%du_drag, ss%du_stress and their v counterparts — all already at the matching u-face / v-face shape. Each kernel must have run its compute step before this is called.

Read more…
supergrid_angle_dx_from_geography rdb_ocean_metrics Function

Grid rotation (DEGREES, counter-clockwise from true east — MOM6’s angle_dx sense) at every T node (2i, 2j) of a supergrid, from the node geography alone: the direction of the local +i axis is the chord from the cell’s west-face node (2i-1, 2j) to its east-face node (2i+1, 2j), projected onto a local east/north plane (dx_east = dlon*cos(lat), dy_north = dlat). Other nodes are left at zero (nothing reads them). Used where the mosaic has no angle_dx and by the analytic tripolar generator.

supergrid_ghost_fill_2d rdb_ocean_metrics Subroutine

Fill ghost rows/columns by constant extrapolation, for a T-point array (nx_total, ny_total). Interior = [ng+1, ng+ni] x [ng+1, ng+nj].

supergrid_ghost_fill_bu rdb_ocean_metrics Subroutine

Ghost fill for Bu arrays (nx_total+1, ny_total+1). Physical i-range [ng+1, ng+ni+1], j-range [ng+1, ng+nj+1].

supergrid_ghost_fill_cu rdb_ocean_metrics Subroutine

Ghost fill for Cu arrays (nx_total+1, ny_total). Physical i-range is [ng+1, ng+ni+1] (ni+1 faces), j-range [ng+1, ng+nj].

supergrid_ghost_fill_cv rdb_ocean_metrics Subroutine

Ghost fill for Cv arrays (nx_total, ny_total+1). Physical i-range [ng+1, ng+ni], j-range [ng+1, ng+nj+1].

supergrid_io_ok rdb_ocean_metrics Function

Translate a raw nc_check-style status (0 = ok) from one of the nc_* reader calls in metrics_fill_from_supergrid into the caller’s ierr contract: .true. on success; on failure, returns .false. with ierr = OCEAN_STATUS_ERR_IO when ierr is present (closing ncid first, when given, so a mid-read failure does not leak the file handle), or error stops with the SAME generic text nc_check itself would have used had the caller’s ierr never been threaded through — this is what keeps the legacy (no ierr) behaviour byte-identical while unblocking the ierr-present return path (F1/F2 of the P0.1 review).

supergrid_top_row_folds rdb_ocean_metrics Function

.true. iff the supergrid’s top node row is a TRIPOLAR FOLD LINE: every node m coincides geographically with its mirror nxp + 1 - m (MOM6’s fold pairing, T(i, nj+1) = T(ni+1-i, nj)). Points are compared as unit vectors on the sphere, so longitude is modulo 360 and irrelevant at the geographic pole (the OM_1deg fold row crosses 90N with its two copies stored at longitudes 180 deg apart). A lon-lat top row fails this everywhere except at the self-conjugate middle node, so the test cannot be passed by accident. Tolerance: a 1e-7 chord (~0.6 m on the Earth; MOM6 mosaics pair to round-off).

surfstress_apply_impl rdb_ocean_surface_stress Subroutine
surfstress_compute_impl rdb_ocean_surface_stress Subroutine

Flat-array surface-stress kernel. Explicit-shape dummies so NVHPC stdpar can compile the device kernel against static bounds.

surfstress_distributed_impl rdb_ocean_surface_stress Subroutine

DIRECT_STRESS branch — distribute the wind stress across the top hmix_stress metres of the column. For each face, walk layers from k = nz (surface) down to k = 1, accumulating thickness; the surface boundary layer (SBL) is the set of layers whose top sits within hmix_stress of the free surface. The acceleration per layer is:

Read more…
sw_pe_cost_shape rdb_ocean_surface_flux Function

In-layer potential-energy-cost shape function Phi(tau) for the EPBL TKE ledger, tau = h/zeta the in-layer optical depth of a single band. It is the fraction of the pure-skin PE cost that homogenising an EXPONENTIALLY distributed in-layer heating actually incurs (Paulson & Simpson 1977 profile; the EPBL energetics of Reichl & Hallberg 2018):

Read more…
sw_source_is_implemented rdb_ocean_surface_flux Function

Fail-loud predicate for the &ocean_thermo_nml sw_source selector — validate_config aborts on any string this rejects. The two recognised sources are the net-heat legacy path and the PR-12 q_sw component.

sw_transmission rdb_ocean_surface_flux Function

Two-band (Paulson & Simpson 1977) normalised downward irradiance transmission at depth d below the free surface, T(d) = R·exp(-d/zeta1) + (1-R)·exp(-d/zeta2), T(0) = 1. This is THE single shared definition — the SW deposition kernel, the KPP MXL_SW/LV1_SW boundary-layer correction, and the EPBL in-layer PE-cost ledger all consume it, so the three consumers cannot disagree about where the sunlight went. Marked !$acc routine seq so it inlines into same-module device kernels and is callable from cross-module do concurrent kernels.

tags_north_fold rdb_ocean_setup Function

.true. iff &ocean_bc_nml north = "tripolar_fold".

tags_periodic_x rdb_ocean_setup Function

.true. iff &ocean_bc_nml tags BOTH west and east periodic — the rule ocean_bc_state_init applies, for callers that run before configure_ocean_bc (the grid metrics).

tdrag_variant_is_implemented rdb_ocean_top_drag Function

.true. only for a top-drag variant with a real kernel. The single gate validate_config consumes.

tfreeze_ib_impl rdb_ocean_diag_derived Subroutine
thermal_driving_impl rdb_ocean_diag_derived Subroutine

T_far − eos_freezing_point(eos, S_far, p_top). The liquidus comes off the SAME eos_t handle the solve used (&ocean_eos_nml tfreeze_set), never a local copy of the coefficients — the two sets differ by ~0.03 degC, which is enough to flip the sign of this field.

tidal_mixing_column_kernel rdb_ocean_tidal_mixing Subroutine

Per-column St-Laurent flux-bookkeeping sweep. One do concurrent (j, i) over owned cells; each column is a serial upward sweep k=1(bed) -> nz(surface) over fixed-size local() arrays (register-resident). Bottom-up global indexing throughout — no surface-down flip (the decay anchors at the bed).

Read more…
tidal_mixing_compute rdb_ocean_tidal_mixing Subroutine

Run tidal mixing over the domain: fill this%kd_int (interface diffusivity). Call at thermo cadence with the thermo dt. Outer shim: dereferences the tracer-registry hTr arrays on the host (the array-of-DT indirection blocks NVHPC device codegen), then forwards to the column kernel. dt is unused (the steady diagnostic Kd does not integrate in time) but carried for signature parity with the other interior closures.

tidal_mixing_is_inert rdb_ocean_tidal_mixing Function

.true. iff tidal mixing is enabled but has no energy source (PR-6 fail-loud): enable .and. e_uniform <= 0 .and. .not. e_compute. The bottom-intensified diffusivity Kd ∝ E, so a zero prescribed e_uniform with the e_compute estimator off makes Kd ≡ 0 exactly — the closure runs its whole flux sweep for nothing. e_compute=.true. supplies E internally, so that is NOT inert; a disabled closure is not “inert” either (it is simply off). Drives a configure abort.

tidal_mixing_merge_into_kt rdb_ocean_tidal_mixing Subroutine

Fold the tidal diffusivity into the vmix interface fields, ADDITIVELY (interior-diffusivity semantics; St Laurent tidal mixing is an interior source like kappa-shear). Called EVERY stage (PP81 rewrites kv/kt each stage; kd_int itself refreshes at thermo cadence). Interior interfaces only — K=1 (bed) and K=nzp1 (surface) stay zero in both source and target.

tide_name_index rdb_ocean_tide_astro Function

Catalog index (1..TIDES_CATALOG_SIZE) of a constituent name, matched case-insensitively; -1 if unknown.

tides_build_struct rdb_ocean_tides Subroutine

Build the (nx,ny,3) cos/sin spatial-structure arrays from cell- centre latitude/longitude (degrees), via the angle-sum fold cos(theta + nlambda) = cos(theta)cos(nlambda) - sin(theta)sin(n*lambda). Plain host loop over all cells incl. ghosts (before enter_data). slice 1 diurnal (n=1): G1 = sin(2 phi) slice 2 semidiurnal(n=2): G2 = cos^2 phi slice 3 long-period(n=0): G0 = 1/2 - 3/2 sin^2 phi

tides_configure_astronomy rdb_ocean_tides Subroutine

Allocate the active-constituent arrays + 2D fields and fill the catalog copies + astronomy (phase0, nodal f/u) at the reference and nodal reference day numbers. Host-side setup (before enter_data). cat_idx(1:nconst) are catalog indices (1..TIDES_CATALOG_SIZE).

tides_update_eta_eq rdb_ocean_tides Subroutine

Refresh eta_eq(x,y) for the current outer-step time t (s). Host recomputes the nconst amplitude scalars, pushes them to the device, then a do concurrent fills eta_eq with no per-cell trig and no reduction. Held static across the inner barotropic substep loop.

tides_update_eta_eq_impl rdb_ocean_tides Subroutine

Flat-impl device fill (explicit-shape dummies — no descriptor walk). eta_eq(i,j) = sum_c amp_cos(c)cos_struct(i,j,m) + amp_sin(c)sin_struct(i,j,m), m = species_c(c). Contiguous index (i) innermost.

tides_update_eta_sal rdb_ocean_tides Subroutine

Refresh the combined seam field eta_forcing for the current outer step. Scalar self-attraction & loading (C2): when use_sal, eta_sal = beta_sal*eta_current and eta_forcing = eta_eq + eta_sal; otherwise eta_forcing = eta_eq (bit-identical to C1). eta_current is the lagged (stage-start, previous outer step) barotropic surface elevation. Host does no work; the fill is a single explicit-shape do concurrent. Must be called AFTER tides_update_eta_eq (reads the fresh eta_eq).

tides_update_eta_sal_impl rdb_ocean_tides Subroutine

Flat-impl device fill (explicit-shape dummies). Loop-invariant use_sal branch kept INSIDE the single do concurrent (one launch, uniform branch is ~free). Off ⇒ pure copy of eta_eq into eta_forcing ⇒ bit-identical. Contiguous index (i) innermost.

top_drag_fill_face_cover_impl rdb_ocean_top_drag Subroutine

Project the cell-centred cover_frac onto velocity faces with the OR rule (see the module docstring for why OR and not AND at a calving front). Host-side, once, at configure.

Read more…
top_drag_stress_mag_impl rdb_ocean_top_drag Subroutine

Cell-centred magnitude of the top stress (N/m^2), for the later ustar_shelf consumer:

Read more…
top_drag_tendencies_impl rdb_ocean_top_drag Subroutine

Flat device kernel: explicit-shape dummies, no derived-type dereference inside the do concurrent.

Read more…
topo_length_to_grid_units rdb_ocean_state Function

Convert a metres length scale (slope_scale / half_width) into the GRID coordinate units the formula bathymetry setters operate in. Cartesian grids carry positions in metres, so the scale passes through unchanged. Spherical / supergrid / tripolar grids carry positions in DEGREES, so the metres scale is converted to degrees of latitude (meridional metres-per-degree = rad_earth · π/180). This keeps the seamount/spoon length scale commensurate with the grid coordinate; without it a metres scale divided by a degrees position underflows the Gaussian/exponential and the basin collapses flat. Zonal cells are narrower by cos(lat), so a degree-isotropic bump is mildly elongated zonally in physical space — acceptable for these idealised topographies; the degeneracy is what this fixes.

tracer_advect rdb_continuity Subroutine

Test-only (no production caller): unsplit 2-D tracer advection, the reference oracle for split tracer_advect_zonal/_meridional. Per-layer PPM tracer advection — iterates over the tracer registry on the multilayer C-grid state and forwards each tracer’s hTr array to the flat-impl below. Extendable by construction: appending a new entry to ms%tracers(:) (BGC, sediment, passive scalar) drops it in without touching this routine. Per-tracer behaviour gates on tracer_t%do_horizontal_advection — set to .false. for tracers that should be diagnostic / forced externally.

Read more…
tracer_advect_meridional rdb_continuity Subroutine

Meridional half of the direction-split tracer advection. Reads the post-zonal h_layer (since continuity_apply_zonal has already updated h in the split flow) and the just-computed mass_flux_y_layer from continuity_meridional_flux.

Read more…
tracer_advect_meridional_one_impl rdb_continuity Subroutine

Meridional half of tracer_advect_one_impl. Same shape as the zonal impl, applied to y. In the split flow, h here is the post-zonal-apply thickness so the Tr = hTr/h reconstruction stays consistent with what continuity used in continuity_meridional_flux. iareaT = inv_dy on uniform metrics; mass_flux_y carries dx_cv. Mirror-T at land neighbours (C2); bit-identical for all-wet.

Read more…
tracer_advect_one_impl rdb_continuity Subroutine

One-tracer PPM advection. Flat-impl: takes bare 3D arrays (no derived-type deref inside do-concurrent), so NVHPC stdpar handles it cleanly even for tracers stored in an array-of-derived-types registry.

Read more…
tracer_advect_vertical rdb_ocean_vertical_advection Subroutine

Apply first-order upwind-in-z vertical advection to every registered tracer, then update h_layer by the same vertical mass-flux divergence. Updating h is what makes the kernel CWC-consistent — uniform T = hTr/h stays uniform regardless of how divergent the w field is.

Read more…
tracer_advect_vertical_one_impl rdb_ocean_vertical_advection Subroutine

Flat-impl first-order upwind-in-z vertical advection for one tracer. Two passes:

Read more…
tracer_advect_zonal rdb_continuity Subroutine

Zonal half of the direction-split tracer advection. Mirrors tracer_advect but updates hTr using only the x-direction tracer mass flux. Companion to tracer_advect_meridional. Both are called interleaved with the continuity substeps by continuity_tracer_step_split to preserve CWC.

Read more…
tracer_advect_zonal_one_impl rdb_continuity Subroutine

Zonal half of tracer_advect_one_impl. Same three-pass pattern (PPM reconstruction → upwind pick into tracer mass flux → forward-Euler update) but only the x-direction half. Reads the input h for the Tr = hTr/h reconstruction. The tracer transport mass_flux_x·Tr_face inherits dy_cu, and the divergence closes with iareaT (= inv_dx on uniform). Mirror-T at land neighbours (C2): a held land column’s tracer is reflected to the local cell so the wet-side face value is unbiased; bit-identical for all-wet (wet_T≡1).

Read more…
tracer_bytes rdb_tracer Function

Counted allocatable footprint of one tracer (hTr + RK2 save).

tracer_destroy rdb_tracer Subroutine
tracer_hdiff rdb_ocean_hdiff_tracer Subroutine

Iterate the tracer registry and apply constant-kappa_h horizontal Laplacian diffusion to every tracer whose do_horizontal_diffusion flag is set. Outer-shim: forwards each tracer’s hTr to the flat-impl below. Reuses the same scratch buffers across all tracers in one call.

Read more…
tracer_hdiff_one_impl rdb_ocean_hdiff_tracer Subroutine

Four-pass flat-impl horizontal-Laplacian tracer diffusion in conservative curvilinear form (design §2, mirrors continuity):

Read more…
tracer_index_by_name rdb_ocean_api Function

Registry index (1-based) of the tracer named name, or 0 if none matches. Name comparison is trim-both-sides (registry names are fixed-length character(len=32)).

tracer_init rdb_tracer Subroutine

Allocate hTr / hTr0 at the multilayer grid size, zero-filled. Caller is responsible for populating the prognostic field (e.g. hTr = h_layer * tr_init) after layer thicknesses are set.

tracer_recon_required_nghost rdb_recon_weno Function

Minimum nghost required for a given TRACER_RECON_* code.

tracer_recon_support_status rdb_recon_weno Function

Decide whether a parsed tracer_recon code is honoured on this config, independent of the multilayer nghost/use_ppm_tracer quality guards (those apply only once this returns OK for a weno rung). Factored out as a pure predicate so the fail-loud decision is unit-testable without triggering error stop.

Read more…
tripolar_node_latlon rdb_ocean_metrics Subroutine

Geographic (lat, lon) of supergrid node (m,n). Below the join (lon-lat corner latitude <= phi_join) it is plain lon-lat; above, the bipolar cap map (s = fraction of the cap row span).

tripolar_supergrid_arrays rdb_ocean_metrics Subroutine

The in-memory MOM6-style supergrid of the analytic tripolar grid (node geography, great-circle edge lengths, spherical sub-cell areas) that metrics_fill_tripolar assembles. Public so a test can write the very same grid as a mosaic file and check that the NetCDF reader reproduces the generator’s metrics, ghosts included.

try_get_bathymetry_var rdb_bathymetry Subroutine

Try to find the bathymetry variable by common names

two_dp rdb_mem_report Function

Format a real to exactly two decimal places without leading blanks (write with an f edit descriptor, then adjustl + trim).

uhbt_to_ubt rdb_bt_cont_type Function

Invert find_uhbt: recover u from a target transport uhbt. Saturated branches close in one line; cubic branches use Newton + bisection fallback to tol·|uhbt|. Hallberg & Adcroft (2009).

uniform_diag_levels rdb_ocean_engine Function

nz uniform cumulative fractions (m/nz, m=1..nz) — the auto sigma / z* output grid when no explicit levels are configured. Moved from rdb_driver (P2.4).

upcase2 rdb_ocean_tide_astro Function

Uppercase the first two characters of a token.

update_lay_enth rdb_ice_column Subroutine

Conservative per-layer implicit enthalpy update — SIS2 update_lay_enth (SIS2_ice_thm.F90:704-945), closed-form branches only. Port of prototype sis2_column.py:58-135. Four solution branches (massless layer; pin-to-max with banked extra_enth; fresh sice==0 linear; salty quadratic), then the three-way explicit-vs-conservation-inverted flux bookkeeping (prototype :117-133, incl. the denom > 0 guard).

Read more…
update_reservoir_meridional_north rdb_ocean_obc_baroclinic Subroutine

Update reservoir for the north open edge. Wall-face index = j_n+1; interior cell = j_n. Outward normal = +y: u_n = +mass_flux_y(i,j_n+1,k)/max(h,hmin).

update_reservoir_meridional_south rdb_ocean_obc_baroclinic Subroutine

Update reservoir for the south open edge. Wall-face index = j_s; interior cell = j_s. Outward normal = -y: u_n = -mass_flux_y(i,j_s,k)/max(h,hmin).

update_reservoir_zonal_east rdb_ocean_obc_baroclinic Subroutine

Update reservoir for the east open edge. Wall-face index for mass flux = i_e+1 (east face of the last physical cell i_e). Interior cell = i_e. Outward normal at east = +x: u_n = +mass_flux_x(i_e+1,j,k)/max(h,hmin).

update_reservoir_zonal_west rdb_ocean_obc_baroclinic Subroutine

Update reservoir for the west open edge. Wall-face/interior cell = i_w. Outward normal = -x: u_n = -mass_flux_x(i_w,j,k)/max(h,hmin).

use_insitu_pcm rdb_ocean_pressure_force Function

Does the FV_MOM6 constant-by-layer branch take the IN-SITU density path (compute_fv_mom6_insitu_pcm_impl)? Only when it can change the answer: the knob is on, there is an EOS handle and T/S to evaluate it on, and the EOS depends on pressure. For the linear EOS ms%rho_layer already IS the in-situ density, so the legacy path runs, bit-identical.

validate_config rdb_config Subroutine

Validate configuration parameters after reading

Read more…
varmix_assemble rdb_ocean_varmix Function

Assembly chain in the load-bearing order: background + Visbeck addend, THEN Res_fn scale, THEN clamp. kh_max <= 0 ⇒ no upper cap.

varmix_compute rdb_ocean_varmix Subroutine

Fill res_fn_*, sn_*, khth_*, khtr_* (the pre-CFL base face coefficients) from the static grid terms, the slopes/N^2 slot, and the first-mode wave speed cg1. No-op when disabled / the deps are absent. The CFL cap is applied downstream by GM.

varmix_compute_impl rdb_ocean_varmix Subroutine

Flat-impl VarMix kernel (explicit-shape; NVHPC descriptor-walk-free). Three phases: (1) Res_fn at faces (cg1 interpolated to faces or the centre-Res_fn averaged, per interp_res), (2) Eady SN at u/v faces (thickness-weighted column reductions with the orthogonal slope folded into S^2, scalar accumulators — SN is final, no SN_v combine), (3) the assembly (Visbeck addend, Res_fn scale, clamp) into the KhTh/KhTr base.

varmix_dfdx_vface rdb_ocean_varmix Function

Cross-face df/dx at a v-face (j interior): average of the centred x-derivatives in the south (j-1) and north (j) rows.

varmix_dfdy_uface rdb_ocean_varmix Function

Cross-face df/dy at a u-face (i interior): average of the two centred y-derivatives in the west (i-1) and east (i) columns, clamped at the j edges (one-sided / zero there).

varmix_res_fn rdb_ocean_varmix Function

Divide-free resolution function for power p (even). p=2: dx_term/(dx_term + (alpha*cg1)^2); general even p: dx_term^(p/2)/(dx_term^(p/2) + (alpha*cg1)^p). dx_term = f2_dx2 + cg1*beta_dx2. -> 1 where unresolved, -> 0 where Ld>>dx.

varmix_sn_u rdb_ocean_varmix Subroutine

Thickness-weighted Eady growth rate at u-faces (own component). Interior u-face (i=2..nx) pairs centre columns iw=i-1 (west) and i (east). Interior interfaces K=2..nz; H_geom = sqrt(sqrt(h_iw,k * h_i,k) * sqrt(h_iw,k-1 * h_i,k-1)). S2 = slope_x^2 + the four corner slope_y^2 h-weighted to the u-face; S2 optionally limited. SN_u = sum sqrt(S2*N2)*H_geom / sum H_geom.

varmix_sn_v rdb_ocean_varmix Subroutine

Thickness-weighted Eady growth rate at v-faces (mirror of varmix_sn_u). Interior v-face (j=2..ny) pairs js=j-1 (south) + j.

vcoord_cleanup rdb_vcoord Subroutine

Deallocate all arrays. Safe to call on uninitialised instances.

vcoord_enter_data rdb_vcoord Subroutine

Map read-only coordinate arrays to GPU.

vcoord_exit_data rdb_vcoord Subroutine

Unmap coordinate arrays from GPU.

vcoord_h_min_is_coherent rdb_vcoord Function

Is zstar_h_min coherent with the contract coord_type gives it?

Read more…
vcoord_h_min_role rdb_vcoord Function

Which of the TWO contracts zstar_h_min carries for coord_type.

Read more…
vcoord_init rdb_vcoord Subroutine

Initialise a vertical coordinate definition. Allocates + populates dsig_target for the given type. Unknown types: error stop.

vcoord_needs_remap rdb_vcoord Function

Returns .true. if this coordinate type requires conservative vertical remapping after the barotropic step. Pure sigma does not — layers are simply rescaled by dsig(k) * H.

vcoord_target_dz_column rdb_vcoord Subroutine

Compute target layer thicknesses for a single water column. Pure, called from do concurrent (one thread per column).

Read more…
vcoord_target_dz_column_zstar_full rdb_vcoord Subroutine

Compute target layer thicknesses for VCOORD_ZSTAR_FULL. Inputs: z_ref_col(0:nz) local reference (top-down, 0=surface, nz=h_bed); H current total depth (m) = h_bed + η; h_min vanishing-layer floor (m). Output: dz(1:nz) ROMS-ordered (dz(1) bottom, dz(nz) surface), sum(dz) = H exactly, vanishing rows set to h_min. Surface layer absorbs η; if H < h_bed the deepest layers clip to h_min and the surface is trimmed to keep sum = H.

vcoord_type_name rdb_ocean_state Function

Human-readable tag for a VCOORD_* enum (mismatch messages only; the integer enum is what is validated).

vdiff_apply_momentum rdb_ocean_vdiff Subroutine

Backward-Euler vertical viscosity applied to ms%u_face_x_layer and ms%v_face_y_layer. Per-face h_face averaged from the two abutting cell columns.

Read more…
vdiff_apply_tracers rdb_ocean_vdiff Subroutine

Backward-Euler vertical diffusivity on every registered tracer. Each tracer is converted to T = hTr/h, the tridiagonal solve runs, then hTr = T*h is reconstituted. h_layer is untouched. Per-tracer do_vertical_diffusion flag gates participation.

Read more…
vdiff_bbl_configure rdb_ocean_vdiff Subroutine

Latch the MOM6 per-face bottom boundary layer (bbl_per_face) from the bottom-drag configuration and size its workspace. Called once at configure, BEFORE enter_data, by rdb_ocean_setup when bbl_glue is on. MOM6 set_visc_init is the parameter map:

Read more…
vdiff_set_viscous_bbl rdb_ocean_vdiff Subroutine

MOM6 set_viscous_BBL (the BOTTOMDRAGLAW branch): the per-face bottom-boundary-layer viscosity kv_bbl_u/v and thickness bbl_thick_u/v that the vertical-friction glue reads. Called ONCE per outer step, before the stage loop, from the state at the start of the step — MOM6 calls it once per step, from step_MOM_dynamics, before the predictor. No-op unless bbl_glue .and. bbl_per_face.

Read more…
vhbt_to_vbt rdb_bt_cont_type Function

Meridional mirror of uhbt_to_ubt.

visc_rem_halo_refresh rdb_ocean_dyn Subroutine

Exchange bt_work%visc_rem_u/v face halos right after production — MOM6’s pass_visc_rem group pass, run after every one of the three vertvisc_remnant calls. MPI halo first, then the periodic wrap, then the tripolar fold — the same ordering contract every other seam fill in this module follows (ocean_halo_exchange_ml_state then ocean_periodic_wrap_state then ocean_fold_wrap_state). visc_rem is a POSITIVE SCALAR on a face (the viscous-remnant fraction), not a true-vector flux component, so the fold uses ocean_fold_wrap_visc_rem (copy across the seam), NOT ocean_fold_wrap_stress’s negate-on-fold vector contract. bc absent (e.g. a direct unit-test call with no boundary state) ⇒ periodic wrap + fold are skipped; the halo exchange itself is unconditional (no-op on 1 rank, D0).

visc_rem_precompute rdb_ocean_dyn Subroutine

Refresh bt_work%visc_rem_u/v from the CURRENT stage state BEFORE the barotropic forcing assembly (PGF_BUG.md §9) — the MOM6-order parity (vertvisc_coef runs before btstep every stage). The stage-end producer alone leaves visc_rem at its init value (≡ 1) for the whole first stage, so the rem-weighted F_bt degenerates to the plain mean exactly when the spurious grounded-layer PGF is at its ballistic worst, and the Δu corrector then deposits the spurious column-mean into wet layers. Remnant-only vdiff call: builds the same matrix the stage-end solve will build (kv one stage stale — benign; the thickness field, which the BBL glue keys on, is current) and does NOT touch the velocities. Vertex kappa-shear: the corner Kv source enters this matrix too (same operator as the stage-end momentum solve — a remnant built without it would weight the BT corrector with a different friction operator than the one actually applied).

vmix_add_kv_ml_invz2 rdb_ocean_vmix Subroutine

Augment this%kv with an extra near-surface viscosity:

Read more…
vmix_apply_convection rdb_ocean_vmix Subroutine

Brunt-Vaisala-triggered convective adjustment – a CONTRIBUTOR into kv/kt (see the module docstring for the full physics and the D1-D4 divergences from MOM6’s MOM_CVMix_conv). Early- returns when conv_enable is off (bit-identical). bl_depth (m, positive down) is the caller’s active surface-boundary-layer depth: pass this%bl_depth under KPP / no BL scheme, epbl%mld under EPBL – both are permanently-zero, device-resident fields when their owning scheme is off, so either is a free “no BL scheme -> mask nothing” default (z_int(k) >= 0 for every interior interface).

vmix_apply_in_stage rdb_ocean_dyn Subroutine

Bundle the per-stage vmix closure / KPP overlay / KV_ML_INVZ2 / assembly gate / vdiff dispatch into one routine so the run_stage drivers can call vmix_apply_in_stage(grid, dyn, vmix, vd, ss, ms, dt, sf) instead of carrying 30 lines of nested if-branching.

Read more…
vmix_apply_kpp_overlay rdb_ocean_vmix Subroutine

Thin host-side shim over vmix_kpp_overlay_impl — same signature as before this PR, so the call site in rdb_ocean_dyn.F90 is unchanged. Selects the shortwave irradiance source HOST-SIDE (sf%sw_from_qsw): the PR-12 q_sw component is allocated only under use_components, so it is only ever passed on the branch guarded by the host flag (validate_config forces enable_components when sw_source="q_sw", making this total). sf%has_sw is passed as the sw_active gate — false ⇒ the _impl’s B_0 reduces to the unmodified legacy source line, bit-for-bit.

Read more…
vmix_apply_nonlocal_tendencies rdb_ocean_vmix Subroutine

Apply the KPP non-local (counter-gradient) tracer tendency computed by vmix_apply_kpp_overlay. Updates hT, hS from the divergence of gamma_t / gamma_s at interfaces:

Read more…
vmix_assemble rdb_ocean_vmix Subroutine

The single downstream gate of the vmix diffusivity assembly — the set_diffusivity-style stage that every interior and overlay closure feeds into before vdiff consumes kv/kt/ks.

Read more…
vmix_assemble_clip_henyey_impl rdb_ocean_vmix Subroutine

vmix_assemble_clip_impl with the Henyey latitude factor (henyey_lat_factor_impl) scaling the two SCALAR TRACER background floors, each then floored at the minimum diffusivity:

Read more…
vmix_assemble_clip_impl rdb_ocean_vmix Subroutine

Floor + ceiling on interior interfaces k = 2..nzp1-1. Explicit- shape args so the do concurrent stays descriptor-walk free.

vmix_assemble_clip_profile_impl rdb_ocean_vmix Subroutine

C7 floor + ceiling: same as vmix_assemble_clip_impl but the tracer floor is the per-interface Bryan-Lewis kd_bg field and the momentum floor is prandtl·kd_bg (MOM6 background Prandtl tie). Interior interfaces k = 2..nzp1-1.

vmix_bkgnd_fill_impl rdb_ocean_vmix Subroutine

Fill the per-interface Bryan & Lewis (1979) JGR 84:2503 background tracer-diffusivity profile from the CURRENT column interface depths.

Read more…
vmix_compute_pp81 rdb_ocean_vmix Subroutine

Pacanowski-Philander (1981) Richardson-number closure. Inlined kernel — keeps the do concurrent body adjacent to its derived-type accesses. We tried the outer-shim + _impl pattern but NVHPC’s stdpar codegen produced more descriptor-marshalling memcpys at the shim boundary than the direct-access form generates inside the kernel. Direct ms%foo(i,j,k) access is what other working hot-path kernels (continuity, coriolis_adv, the barotropic substep) use; the shim pattern was an experiment that didn’t help here.

vmix_convection_impl rdb_ocean_vmix Subroutine

Flat, explicit-shape kernel (the “vmix incident” module – assumed-shape dummies here produced 1.4M per-launch descriptor- walk memcpys; explicit-shape only, no exceptions). Interior interfaces k = 2..nzp1-1 only; boundary interfaces k=1 (bed) and k=nzp1 (surface) stay at the closed-BC zero and are never touched (same contract as PP81 / vmix_add_kv_ml_invz2).

Read more…
vmix_guard_impl rdb_ocean_vmix Subroutine

Count negative or NaN diffusivities across interior interfaces. A reduction over fresh scratch — uses !$acc parallel loop reduction (the project rule for device reductions; bare count/sum over device data can silently return 0).

vmix_interior_closure_is_implemented rdb_ocean_vmix Function

.true. only for VMIX_INTERIOR_PP81 — the one interior closure with a real kernel today. VMIX_INTERIOR_LARGE94 and VMIX_INTERIOR_CVMIX are declared-but-unimplemented reservations (no kernel); selecting one would leave kv/kt stale (no interior mixing at all). interior_closure has no namelist key yet, so this is defence-in-depth (PR-6) for the next code/config consumer that sets it — the predicate is the gate.

vmix_kpp_overlay_impl rdb_ocean_vmix Subroutine

KPP boundary-layer overlay on top of the interior closure already in this%kv / this%kt. Phase 1 was shear-driven only; Phase 2 added the convective velocity scale w_* and γ_T/γ_S non-local transport; Phase 3 (this revision) adds the V_t² unresolved-turbulence term in the bulk-Ri denominator (LMD94 eq 23). Surface BL is now feature- complete except for Langmuir / Stokes enhancement.

Read more…
vmix_resolve_kd_min rdb_ocean_vmix Function

Resolve the bkgnd_kd_min “unset” sentinel to the reference default HENYEY_KD_MIN_FRAC * kt_bg (MOM6 KD_MIN, default 0.01*KD). A NEGATIVE kd_min means “not set by the user”; zero and positive values are taken literally, so kd_min = 0 is a legal way to ask for no floor at all.

Read more…
vmix_seed_backgrounds rdb_ocean_vmix Subroutine

Seed kv_bg/kt_bg/ks_bg and the kv/kt/ks/kd_bg arrays from the current pp81_nu_bg/pp81_kappa_bg fields, then zero the closed-BC boundary interfaces on kv/ks. Extracted out of ocean_vmix_init (§2E structural invariant: kv_bg == pp81_nu_bg, kt_bg == ks_bg == pp81_kappa_bg, so vmix_assemble’s background floor is a no-op for the shipped PP81 closure) so BOTH the initial seed and the &ocean_vmix_nml pp81_* config-copy re-derive consistently — a bare field copy without this call would leave the assembly floor clamped against the OLD (type-default) background even after a user sets a new one. Requires kv/kt/ks/kd_bg already allocated (true after init; the config-copy call runs strictly after init_from_config).

vmix_smooth_121_impl rdb_ocean_vmix Subroutine

One in-plane 1-2-1 horizontal smoothing pass on interior interfaces k = 2..nzp1-1. Wet-mask aware: contributions from dry neighbours (wet_mask == 0) are excluded and the 9-point stencil weight is renormalised over the wet cells only. A dry centre column (wet_mask(i,j) == 0) is left unchanged — no leakage into or out of dry cells.

Read more…
vmix_split_ddiff_eos_impl rdb_ocean_vmix Subroutine

buoyancy_coeffs = "eos" twin of vmix_split_ddiff_impl — the SAME CVMix closed forms, the same branch structure, the same outputs; the only change is where α and β come from.

Read more…
vmix_split_ddiff_impl rdb_ocean_vmix Subroutine

Double-diffusion split. Replaces ks := kt with the asymmetric ks = kt_pre + kd_extra_s ; kt = kt_pre + kd_extra_t both from the SAME pre-split kt (read into kt_pre before either write). CVMix cvmix_coeffs_ddiff algebra (Large et al. 1994 fingering; Marmorino-Caldwell 1976 / Kelley 1990 convection).

Read more…
vmix_split_kd_heat_salt rdb_ocean_vmix Subroutine

Analogue of MOM6’s heat/salt diffusivity split. Derives the per-tracer diffusivities from the assembled interior/boundary- layer diffusivity: Kd_heat = Kd_int + Kd_extra_T -> kt Kd_salt = Kd_int + Kd_extra_S -> ks kt holds Kd_int on entry (every contributor writes it). No double-diffusion contributor exists yet, so Kd_extra_{T,S} = 0 and the split reduces to ks := kt => bit-identical. PR-33 extends this to ks = kt + kd_extra_s ; kt = kt + kd_extra_t BOTH computed from the SAME pre-split kt – read kt into a local before writing it, or the kt update poisons the ks update.

Read more…
vmix_split_kd_heat_salt_impl rdb_ocean_vmix Subroutine

Explicit-shape args so the do concurrent stays descriptor-walk free (assumed-shape dummies in a do concurrent make NVHPC walk descriptors per launch – this runs every stage).

volcfl_face rdb_continuity Function

MOM6 swept-volume continuity-PPM face thickness (Lin & Rood / MOM_continuity_PPM flux_elem). Integrates the donor cell’s reconstructed parabola over the swept volume rather than sampling the edge value, adding the O(CFL) correction:

Read more…
warn_unknown_bc rdb_config Subroutine

Warn if a BC string does not match any known type

water_column_impl rdb_ocean_diag_derived Subroutine
wave_drag_roughness_proxy rdb_ocean_setup Subroutine

form="roughness_proxy" filler — a DOCUMENTED PLACEHOLDER for Jayne & St Laurent (2001)’s subgrid <h^2>, not a substitute for it (that needs PR-14’s file reader or PR-30’s field-valued roughness). Estimates the subgrid topographic-height variance from the RESOLVED 2-delta bathymetry increment: _proxy(i,j) = 1/4*[(b(i+1,j)-b(i-1,j))^2 + (b(i,j+1)-b(i,j-1))^2] then r_H = 1/2*kappa*min(<h^2>_proxy, h2_max)*N_bot. b is bottom elevation, positive UP (rdb_barotropic_state.F90) — differences are sign-independent. Zero on land (wet_T==0) and on the ghost ring (the 2-delta stencil is unavailable there; a formula-bathymetry path that leaves ghosts unfilled would otherwise manufacture a spurious cliff at the ghost seam — CLAUDE.md “Formula bathymetry setters must fill ghost rows”).

wavespeed_cg1_column rdb_ocean_wave_speed Subroutine

First-baroclinic wave speed for ONE column. h_rak/rho_rak are in Roundabout ordering (k=1 bed, k=nz surface), fixed-size NZ_STACK_MAX arrays; only 1..nz are read. Returns cg1 (m/s), 0 for land / homogeneous / kc<2 / sub-floor columns. Gathers+flips surface-down, backtracking convective merge, symmetric tridiag, fixed-budget Sturm-count bisection.

wavespeed_compute rdb_ocean_wave_speed Subroutine

Fill this%cg1, this%rd, this%rd_over_dx over the domain. rho_layer is a top-level allocatable that reaches the device directly, so no outer-shim tracer dereference is needed (unlike EPBL/kappa-shear). Call at the n_wavespeed cadence. Host guards + dereference here; the explicit-shape do concurrent kernel lives in wavespeed_compute_impl (outer-shim + flat-impl pattern — mirrors varmix_compute).

wavespeed_compute_impl rdb_ocean_wave_speed Subroutine

Flat-impl wavespeed kernel (explicit-shape; NVHPC descriptor-walk-free). Per-column Sturm-Liouville solve (wavespeed_cg1_column) + the deformation-radius blend (wavespeed_rd), then the metres-denominated resolution ratio rd_over_dx = rd / dxT.

wavespeed_rd rdb_ocean_wave_speed Function

Smooth equatorial Rd blend: Rd = cg1/sqrt(f^2 + 2betacg1). Reduces to cg1/|f| away from the equator and sqrt(cg1/(2*beta)) at f=0; a small inside-sqrt guard + denominator floor handle f = beta = 0.

weno3_recon rdb_coriolis_adv Function

3rd-order WENO-Z reconstruction of a corner quantity onto the face between q0 and qp1, upwind-biased on the sign of the advecting velocity adv_vel (MOM6 weno_three_h_weight_reconstruction). Blends a central candidate c0 (ideal weight 2/3) with an upwind-side linear extrapolation c1 (1/3); the WENO-Z nonlinear factor (1+tau/b)^2 collapses the weight of whichever candidate straddles a PV front. In smooth flow -> the fixed upwind-biased 3rd-order stencil; across a jump -> the ENO (non-oscillatory) branch. f-baked absolute vorticity is passed in (rdb’s vector-invariant form multiplies the result by the thickness- weighted face velocity, so there is no separate h-divide – the mass-weighting lives in that velocity, not in a PV*vh product).

Read more…
weno5_face_swept rdb_recon_weno Function

WENO5-Z swept-average face value (u > 0, upwind cell = q0).

Read more…
weno5_recon rdb_coriolis_adv Function

5th-order WENO-Z reconstruction (MOM6 weno_five_h_weight_reconstruction) of a 6-point corner stencil onto the face between the two central points q3,q4, upwind-biased on adv_vel. Three 3-point candidates blended by WENO-Z (ideal weights 3/10, 3/5, 1/10; tau = |b0-b2|). Applied to the absolute vorticity directly (see weno3_recon). Radius 3 (nghost>=3).

weno7_face_swept rdb_recon_weno Function

WENO7-Z swept-average face value (u > 0, upwind cell = q0).

Read more…
weno7_recon rdb_coriolis_adv Function

7th-order WENO-Z reconstruction (MOM6 weno_seven_h_weight_reconstruction) of an 8-point corner stencil onto the face between the two central points q4,q5, upwind-biased on adv_vel. Four 4-point candidates blended by WENO-Z (ideal weights 4/35, 18/35, 12/35, 1/35; Balsara-Shu smoothness; tau = |(b0-b3) + 3(b1-b2)|). Applied to the absolute vorticity directly. Radius 4 (nghost>=4).

weno9_face_swept rdb_recon_weno Function

WENO9-Z swept-average face value (u > 0, upwind cell = q0).

Read more…
weno_face_conc_x rdb_continuity Function

Swept-average WENO donor concentration at a zonal face. cc is the donor cell (i-index), d = +1 (u>0, downwind toward +i) or d = -1 (u<0, downwind toward -i). Gathers the mirrored/clamped stencil in downwind-positive order and dispatches to the coastal swept-average face helper at the highest feasible rung.

weno_face_conc_y rdb_continuity Function

Meridional analogue of weno_face_conc_x. cc is the donor cell (j-index); the stencil steps along j with d = +1 (u>0) / -1 (u<0).

wide_halo_guards rdb_ocean_halo Subroutine

Fail-loud validation for wide halo entry points. Called at the top of every *_wide public routine.

wrap360 rdb_ocean_tide_astro Function

Fold an angle in degrees to the canonical residue [0,360). (Fortran mod returns the sign of the argument, so a negative polynomial value needs the +360 canonicalisation.)

wright_pcm_dpa_face rdb_ocean_pressure_force Subroutine

Cross-face 5-point Boole quadrature of the layer dpa for a PCM column pair with the ANALYTIC Wright vertical integral at every lateral sub-column (MOM6 int_density_dz_wright, intx_dpa / inty_dpa). The Wright twin of boole_dpa_face_pcm, with the same sub-column definition: the end points are the columns’ own dpa_l / dpa_r; the three interior sub-columns interpolate the interface height and thickness linearly in the cross-face fraction and T/S with the near-bottom mass-weighted fractions wtT_L = wl*hwt_ll + wr*hwt_rl, wtT_R = wl*hwt_lr + wr*hwt_rr.

Read more…
wright_pcm_dpa_intz rdb_ocean_pressure_force Subroutine

ANALYTIC vertical integral of the Wright (1997) in-situ density anomaly over one constant-T/S (PCM) layer — MOM6 int_density_dz_wright (reduced-range coefficients, MOM6 EQN_OF_STATE = "WRIGHT" / "WRIGHT_RED", the set rdb_eos carries). Replaces the 5-point Boole quadrature of boole_dpa_intz_layer (5 generic-EOS evaluations) with one polynomial evaluation, one division pair and a short series.

Read more…
wright_rho rdb_ocean_pressure_force Function

Wright (1997) in-situ density (kg/m^3) – term for term the Wright branch of eos_density_point, without the handle.

write_key_json rdb_nml_schema Subroutine

Write one key as a JSON object. A select type over the concrete key recovers the kind-specific fields (vmin/vmax, allowed(:), array size) that nml_key_t’s abstract interface does not carry – the one place this walk needs the concrete type (schema_render_markdown does not, since default_string() is polymorphic).

write_key_line rdb_nml_schema Subroutine

Write one aligned key = value ! [units] doc line. When short_only, skip default-valued keys (and leave wrote_any).

z_fixed_nominal_dz rdb_vcoord Subroutine

Nominal layer thicknesses of a VCOORD_Z_FIXED column, SURFACE FIRST (dz(1) is the top layer) — the order MOM6 writes ALE_COORDINATE_CONFIG = "PARAM:..." lists and vgrid files in. The caller flips to the bottom-up state convention.

Read more…
zero3_impl rdb_ocean_diag_derived Subroutine

Device-side zero of buf (seeds column sums / clean bail-out).

zfixed_cavity_nu_h_below_envelope rdb_config Function

Is the constant harmonic viscosity below the z_fixed x cavity lower envelope ZFIXED_CAVITY_NU_H_MIN? The predicate behind validate_config’s WARNING (never a refusal — the vcoord stability matrix runs this combination inviscid on purpose).

Read more…
zinit_dims_ok rdb_ocean_z_init Function

match (nx_phys, ny_phys). Returns .false. on mismatch or I/O error; does NOT error stop — safe from test code.

zinit_io_ok rdb_ocean_z_init Function

Translate a raw nc_check-style status (0 = ok) from one of the nc_* reader calls in seed_ts_from_zfile/read_dims into the caller’s ierr contract: .true. on success; on failure, .false. with ierr = OCEAN_STATUS_ERR_IO when ierr is present (closing ncid first, when given, so a mid-read failure does not leak the file handle), or error stops with the SAME generic text nc_check itself would have used had ierr never been threaded through — keeps the legacy (no ierr) behaviour byte-identical while unblocking the ierr-present return path (F1/F2 of the P0.1 review).

zstar_full_build_column rdb_vcoord Subroutine

Build a per-column reference z-level pattern for VCOORD_ZSTAR_FULL. Output z_ref_col(0:nz) monotonically increasing (positive-down), z_ref_col(0)=0 surface, z_ref_col(nz)=h_bed. Built top-down; the caller handles ROMS ordering. Top n_surf_use layers use the stretching mode (log/uniform) toward h_surf_target; below that uniform to the bed; degenerate (h_bed≤0, nz≤0) ⇒ uniform.