Composes every type the ocean dynamical core needs into a single
object the driver builds and passes around for sim_type='ocean'
runs. Each component owns its allocations + bound init/destroy.
GPU mapping is dispatched via the free ocean_state_enter_data /
ocean_state_exit_data orchestrator below — adding a slot
requires wiring it into both.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | public, | parameter | :: | ISOMIP_B0 | = | -150.0_wp |
|
| real(kind=wp), | public, | parameter | :: | ISOMIP_B2 | = | -728.8_wp |
|
| real(kind=wp), | public, | parameter | :: | ISOMIP_B4 | = | 343.91_wp |
|
| real(kind=wp), | public, | parameter | :: | ISOMIP_B6 | = | -50.57_wp |
|
| real(kind=wp), | public, | parameter | :: | ISOMIP_DC | = | 500.0_wp |
|
| real(kind=wp), | public, | parameter | :: | ISOMIP_FC | = | 4.0e3_wp |
|
| real(kind=wp), | public, | parameter | :: | ISOMIP_WC | = | 24.0e3_wp |
|
| real(kind=wp), | public, | parameter | :: | ISOMIP_XBAR | = | 300.0e3_wp |
|
| real(kind=wp), | public, | parameter | :: | ISOMIP_ZB_DEEP | = | -720.0_wp |
|
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| type(barotropic_state_t), | public | :: | barotropic |
Depth-integrated C-grid prognostic state. |
|||
| type(ocean_bc_state_t), | public | :: | bc |
Per-edge OBC config + per-step boundary data. Defaults to
all-OBC_WALL (closed wall) until config opens an edge or a
data source populates the |
|||
| type(ocean_bottom_drag_t), | public | :: | bdrag |
Bottom-drag kernel (linear Rayleigh or quadratic log-layer). Acts on the k=1 layer only. |
|||
| type(ocean_cavity_flux_t), | public | :: | cavity_flux |
Ice-shelf basal-melt slot ( |
|||
| integer, | public | :: | column_stride | = | 1 |
Outer tile size for column-local kernels. 1 = column,
|
|
| type(continuity_t), | public | :: | continuity |
Continuity-PPM kernel state. |
|||
| type(coriolis_adv_t), | public | :: | coriolis_adv |
PV-conserving Coriolis+advection kernel state. |
|||
| type(ocean_data_forcing_t), | public | :: | data_forcing |
File-backed surface forcing (PR-15) — the |
|||
| type(ocean_data_input_t), | public | :: | data_input |
The shared time-varying NetCDF input reader (PR-14). NetCDF-
only (mirrors |
|||
| type(ocean_diag_t), | public | :: | diag |
Diagnostics manager (registry + remap + I/O server hand-off). |
|||
| type(ocean_dyn_t), | public | :: | dyn |
Split-explicit RK2 driver state. |
|||
| logical, | public | :: | enable_ideal_age | = | .false. |
MOM6 |
|
| logical, | public | :: | enable_pseudo_salt | = | .false. |
|
|
| type(eos_t), | public | :: | eos |
Equation of state (Wright by default). |
|||
| type(ocean_epbl_t), | public | :: | epbl | ||||
| type(ocean_gm_t), | public | :: | gm |
Gent-McWilliams thickness diffusion. Injects eddy bolus
thickness transports into the continuity mass fluxes before
the divergence; reads |
|||
| type(ocean_hdiff_tracer_t), | public | :: | hdiff_tracer |
Constant-coefficient Laplacian horizontal-tracer-diffusion
kernel. Tracer-side counterpart of |
|||
| type(ocean_horizontal_viscosity_t), | public | :: | hvisc |
Constant-coefficient Laplacian horizontal-viscosity kernel.
Reads scalar |
|||
| type(ocean_sea_ice_t), | public | :: | ice |
Gated sea-ice slot (SIS2 port, |
|||
| logical, | public | :: | is_init | = | .false. |
True once every nested slot has been initialised + GPU
attached. Set only after the last child |
|
| type(ocean_kappa_shear_t), | public | :: | kshear |
Energetics-based PBL. Mutually exclusive with the KPP
overlay; folds its interface diffusivity into |
|||
| type(ocean_lateral_mix_t), | public | :: | lateral_mix |
Lateral mixing closure (Leith / Smagorinsky / biharmonic); supplies face viscosity coefficients. |
|||
| type(ocean_meke_t), | public | :: | meke |
Prognostic mesoscale eddy kinetic energy. Evolves a 2D
eddy-energy field sourced by |
|||
| type(ocean_metrics_t), | public | :: | metrics |
Orthogonal curvilinear horizontal metrics (lengths, areas,
inverses, geography, hvisc ratio bundle). Filled by
|
|||
| type(ocean_mle_t), | public | :: | mle |
Fox-Kemper mixed-layer-eddy restratification. Injects
ML-confined overturning transports into the continuity mass
fluxes before the divergence; reads |
|||
| type(multilayer_state_t), | public | :: | multilayer |
Per-layer C-grid prognostic state. |
|||
| type(ocean_obc_t), | public | :: | obc |
Open-boundary nest from parent run. |
|||
| type(ocean_p_surf_t), | public | :: | p_surf |
Atmospheric surface-pressure loading / inverse barometer
(PR-17). Folds |
|||
| type(ocean_pressure_force_t), | public | :: | pressure_force |
FV pressure-force kernel state. |
|||
| type(ocean_redi_t), | public | :: | redi |
Redi continuous neutral (along-isopycnal) tracer diffusion.
Two-phase: |
|||
| type(ocean_restart_t), | public | :: | restart |
Restart / checkpoint manager. |
|||
| type(ocean_slopes_t), | public | :: | slopes |
Isopycnal (neutral) slope diagnostics (Griffies 1998) at C-grid interfaces — gates the mesoscale-eddy params. Diagnostic, default off; refreshed at thermo cadence. |
|||
| type(ocean_sponge_t), | public | :: | sponge |
Map-driven sponge (PR-23): per-cell |
|||
| type(ocean_surface_flux_t), | public | :: | surface_flux |
Surface heat + salt flux slot. 2D |
|||
| type(ocean_surface_stress_t), | public | :: | surface_stress |
Surface wind-stress kernel. Acts on the k=nz layer only. |
|||
| type(ocean_top_drag_t), | public | :: | tdrag |
Ice-shelf TOP-drag kernel ( |
|||
| type(ocean_tides_t), | public | :: | tides |
Equilibrium + SAL + internal-tide drag. |
|||
| logical, | public | :: | use_multilayer | = | .true. |
Whether the 3D multilayer state is active (always true on the ocean path; flag exposed for symmetry with the coastal state and so 2D-only debug runs can disable it later). |
|
| logical, | public | :: | use_nonhydrostatic | = | .false. |
NH-on-ocean toggle. Phase 5f. |
|
| type(ocean_varmix_t), | public | :: | varmix |
Spatially-varying GM/Redi coefficient fields. Produces the
pre-CFL base |
|||
| type(ocean_vcoord_t), | public | :: | vcoord |
Vertical-coordinate config + per-step ALE remap state.
Defaults to |
|||
| type(ocean_vdiff_t), | public | :: | vdiff |
Backward-Euler vertical-diffusion solver (Thomas tridiagonal
per column) for momentum + tracers, using the eddy
coefficients in |
|||
| type(ocean_vertical_advection_t), | public | :: | vert_advect |
Vertical advection: diagnoses |
|||
| type(ocean_vmix_t), | public | :: | vmix |
Vertical mixing (KPP + interior closure). |
|||
| type(ocean_tidal_mixing_t), | public | :: | vmix_tidal |
St-Laurent/Simmons internal-tide interior diapycnal mixing.
INTERIOR closure: its Kd adds to the surface PBL +
PP81/background/kappa-shear via the additive merge each stage;
|
|||
| type(ocean_wave_speed_t), | public | :: | wavespeed |
First-baroclinic wave speed + Rossby deformation radius. Diagnostic, default off. |
| procedure, public, non_overridable :: bytes => ocean_state_bytes | |
| procedure, public, non_overridable :: destroy => ocean_state_destroy | |
| procedure, public, non_overridable :: init => ocean_state_init | |
| procedure, public, non_overridable :: init_from_config => ocean_state_init_from_config |
Along-flow bedrock elevation, Asay-Davis et al. (2016) Eq. (2):
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | x |
Across-flow bedrock elevation, Asay-Davis et al. (2016) Eq. (4):
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | y | |||
| real(kind=wp), | intent(in) | :: | y_len |
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:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | rho_lightest |
Surface (lightest) layer density [kg/m³]. |
||
| real(kind=wp), | intent(in) | :: | rho_range |
Top-to-bottom density contrast [kg/m³]. |
||
| integer, | intent(in) | :: | nz_ml |
Number of layers. |
Single source of truth for “is the grounded-layer PGF gate armed?”
(&ocean_isopycnal_nml pgf_skip_nonoverlap →
ocean_pressure_force_t%skip_nonoverlap).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(config_t), | intent(in) | :: | cfg | |||
| integer, | intent(in) | :: | variant |
|
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | length_m | |||
| character(len=*), | intent(in) | :: | grid_config | |||
| real(kind=wp), | intent(in) | :: | rad_earth |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | bound_m | |||
| real(kind=wp), | intent(in) | :: | per_metre |
Grid units per metre (1 on Cartesian). |
1/(1 + exp(t)), saturated instead of overflowing.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | t |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | x | |||
| real(kind=wp), | intent(in) | :: | L |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | x | |||
| real(kind=wp), | intent(in) | :: | L |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_state_t), | intent(in) | :: | this |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | code |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | code |
Human-readable tag for a VCOORD_* enum (mismatch messages only; the integer enum is what is validated).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | code |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(multilayer_state_t), | intent(inout) | :: | ms | |||
| real(kind=wp), | intent(in) | :: | layer_rho_init(:) | |||
| integer, | intent(in) | :: | nz_ml | |||
| integer, | intent(out), | optional | :: | ierr |
Non-zero when the non-sentinel count mismatches |
Walk the ocean god state and register every field that must checkpoint for a bit-exact step-(N+1) resume (ROADMAP A1).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(in), | target | :: | state | ||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(restart_registry_t), | intent(inout) | :: | reg |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout) | :: | state |
Reverse of ocean_state_enter_data. Walk components first,
parent struct last.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout) | :: | state |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout), | target | :: | state | ||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(decomp_t), | intent(in) | :: | decomp | |||
| character(len=*), | intent(in) | :: | filename | |||
| real(kind=wp), | intent(out) | :: | t | |||
| integer, | intent(out) | :: | step | |||
| integer, | intent(out), | optional | :: | ierr |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout), | target | :: | state | ||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(decomp_t), | intent(in) | :: | decomp | |||
| character(len=*), | intent(in) | :: | filename | |||
| real(kind=wp), | intent(in) | :: | t | |||
| integer, | intent(in) | :: | step | |||
| integer, | intent(out), | optional | :: | ierr |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout) | :: | state | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(config_t), | intent(in) | :: | cfg | |||
| integer, | intent(out), | optional | :: | ierr |
Non-zero on an initial-condition configuration/data failure
when present; absent behaves as today ( |
|
| real(kind=wp), | intent(in), | optional | :: | injected_b(:,:) |
P2.5 pre-create geometry injection: interior-sized
|
|
| integer, | intent(in), | optional | :: | injected_b_convention |
REQUIRED alongside |
|
| logical, | intent(in), | optional | :: | periodic_x |
Grid topology the static geometry is wrapped with (see
|
|
| logical, | intent(in), | optional | :: | periodic_y |
As |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout) | :: | state | |||
| type(hgrid_t), | intent(in) | :: | grid |
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:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout) | :: | state | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(config_t), | intent(in) | :: | cfg | |||
| integer, | intent(out), | optional | :: | ierr |
Non-zero on a baroclinic-jet IC configuration conflict when
present; absent behaves as today ( |
Eady-front overlay IC. Assumes flat bottom + uniform layer
split already in place from ocean_state_seed_from_cfg.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout) | :: | state | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(config_t), | intent(in) | :: | cfg | |||
| integer, | intent(out), | optional | :: | ierr |
Non-zero on an Eady-IC configuration conflict when present;
absent behaves as today ( |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout) | :: | state | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(config_t), | intent(in) | :: | cfg | |||
| integer, | intent(out), | optional | :: | ierr |
Non-zero on a geostrophic-adjustment IC configuration conflict
when present; absent behaves as today ( |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | h_layer(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | b(:,:) | |||
| integer, | intent(in) | :: | nz_ml | |||
| logical, | intent(in), | optional | :: | apply_wetdry_floor |
When present and .true., floor each seeded layer to |
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:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | h_layer(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | b(:,:) | |||
| integer, | intent(in) | :: | nz_ml | |||
| real(kind=wp), | intent(in) | :: | max_depth |
Global basin depth the z interfaces are laid over ( |
||
| real(kind=wp), | intent(in) | :: | angstrom_h |
Isopycnal minimum-thickness floor ( |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | b(:,:) | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| real(kind=wp), | intent(in) | :: | max_depth | |||
| real(kind=wp), | intent(in) | :: | half_frac |
Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | b(:,:) | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| real(kind=wp), | intent(in) | :: | max_depth |
Deep clip (m, positive down) = |
||
| real(kind=wp), | intent(in) | :: | x_origin |
Absolute MISMIP+ x (m) of the domain’s west edge. Protocol (ISOMIP+): 320e3. |
||
| real(kind=wp), | intent(in) | :: | m_per_grid |
Metres per grid coordinate unit (1 on Cartesian). |
Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | b(:,:) | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| real(kind=wp), | intent(in) | :: | max_depth | |||
| real(kind=wp), | intent(in) | :: | nl_continent_amp | |||
| real(kind=wp), | intent(in) | :: | nl_roughness_amp | |||
| real(kind=wp), | intent(in) | :: | min_depth |
Floor on the resulting depth (m). The fractional-depth formula
produces b in [0, ~1.1*max_depth]; the |
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:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | b(:,:) | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| real(kind=wp), | intent(in) | :: | max_depth | |||
| real(kind=wp), | intent(in) | :: | peak_depth | |||
| real(kind=wp), | intent(in) | :: | half_width |
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
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | b(:,:) | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| real(kind=wp), | intent(in) | :: | max_depth | |||
| real(kind=wp), | intent(in) | :: | edge_depth | |||
| real(kind=wp), | intent(in) | :: | slope_scale |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_state_t), | intent(inout) | :: | this |
Build the grid/vcoord/tracer fingerprint validated on resume (review #7).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(in) | :: | state | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(ocean_restart_metadata_t), | intent(out) | :: | meta |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_state_t), | intent(inout) | :: | this | |||
| type(hgrid_t), | intent(in) | :: | grid |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_state_t), | intent(inout) | :: | this | |||
| type(config_t), | intent(in) | :: | cfg | |||
| type(hgrid_t), | intent(in) | :: | grid |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout), | target | :: | state | ||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(decomp_t), | intent(in) | :: | decomp | |||
| character(len=*), | intent(in) | :: | filename | |||
| real(kind=wp), | intent(in) | :: | t | |||
| integer, | intent(in) | :: | step | |||
| character(len=*), | intent(in) | :: | drop_tag | |||
| integer, | intent(out), | optional | :: | ierr |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(restart_registry_t), | intent(inout) | :: | reg | |||
| character(len=*), | intent(in) | :: | tag | |||
| real(kind=wp), | intent(in), | target | :: | arr(:,:,:) |
register_full_3d, but OPTIONAL on read: a checkpoint written
before the field was registered still resumes.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(restart_registry_t), | intent(inout) | :: | reg | |||
| character(len=*), | intent(in) | :: | tag | |||
| real(kind=wp), | intent(in), | target | :: | arr(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout) | :: | state | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(config_t), | intent(in) | :: | cfg | |||
| integer, | intent(out) | :: | ierr |
2D (barotropic) variant of seed_land_face_vel_impl.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(:,:) | |||
| real(kind=wp), | intent(in) | :: | wet_face(:,:) |
Zero a per-layer face field ((nf1,nf2,nz)) at land faces
(wet_face==0). wet_face is the matching wet_u/wet_v.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | wet_face(:,:) | |||
| integer, | intent(in) | :: | nz |
Floor land-cell layer thickness to H_VANISHED (never 0 ⇒ no
1/0 in any per-layer divide). Wet cells untouched.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | h_layer(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | wet_mask(:,:) | |||
| integer, | intent(in) | :: | nz |
Zero the extensive tracer content hTr on land T-cells
(wet_mask == 0). Wet cells untouched (bit-identical when
wet_mask ≡ 1).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | wet_mask(:,:) | |||
| integer, | intent(in) | :: | nz |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | h_layer(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | t_layer(:) | |||
| integer, | intent(in) | :: | nz_ml |
Seed hTr = const * h_layer for a uniform-IC tracer (salinity).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | h_layer(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | tracer_const | |||
| integer, | intent(in) | :: | nz_ml |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | wet_mask(:,:) | |||
| real(kind=wp), | intent(in) | :: | b(:,:) | |||
| real(kind=wp), | intent(in), | optional | :: | land_cutoff |
When present, a column is land iff |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | fld(:,:) |
Cell-centred field, shape |
||
| type(hgrid_t), | intent(in) | :: | grid | |||
| logical, | intent(in) | :: | per_x |
West/east edges are periodic. |
||
| logical, | intent(in) | :: | per_y |
South/north edges are periodic. |
||
| logical, | intent(in) | :: | north_fold |
North edge is the tripolar fold. |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout) | :: | state | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(config_t), | intent(in) | :: | cfg | |||
| integer, | intent(out), | optional | :: | ierr |
Threaded straight through to the seeder; an ABSENT |
|
| real(kind=wp), | intent(in), | optional | :: | z_top(:,:) |
Column-top depth (m, positive down), FULL ghosted shape, in
place of |
“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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | b(:,:) | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| real(kind=wp), | intent(in) | :: | max_depth | |||
| real(kind=wp), | intent(in) | :: | half_frac |