| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | private, | parameter | :: | RHO0_DIAG | = | 1025.0_wp |
Reference density used ONLY to give the total-mass diagnostic
( |
| logical, | private, | save | :: | g_handle_live | = | .false. |
True from a successful create() until destroy(). Guards the single-
live-ocean-handle invariant (see module header). Module- |
Name of canonical-catalog entry idx (0-based, < the size above).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=c_int), | intent(in), | value | :: | idx | ||
| character(kind=c_char, len=1), | intent(out) | :: | buf(cap) | |||
| integer(kind=c_int), | intent(in), | value | :: | cap |
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.
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(inout) | :: | c_handle |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(kind=c_char, len=1), | intent(in) | :: | nml_text(nml_len) | |||
| integer(kind=c_int), | intent(in), | value | :: | nml_len | ||
| type(c_ptr), | intent(out) | :: | handle_out |
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”).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(kind=c_char, len=1), | intent(in) | :: | nml_text(nml_len) | |||
| integer(kind=c_int), | intent(in), | value | :: | nml_len | ||
| type(c_ptr), | intent(out) | :: | handle_out |
Name of derived-catalog entry idx (0-based, < the size above).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=c_int), | intent(in), | value | :: | idx | ||
| character(kind=c_char, len=1), | intent(out) | :: | buf(cap) | |||
| integer(kind=c_int), | intent(in), | value | :: | cap |
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().
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(inout) | :: | c_handle |
Bathymetry (m, POSITIVE DOWN — eta = sum(h) - b):
barotropic%b, shape (nx_total, ny_total).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | gen |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | gen |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| integer(kind=c_int), | intent(out) | :: | count_out |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| character(kind=c_char, len=1), | intent(in) | :: | name(name_len) | |||
| integer(kind=c_int), | intent(in), | value | :: | name_len | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
Physical (interior, ghost-excluded) grid shape + ghost width.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | nghost |
Layer thickness (m), cell-centred, FULL extent (ghosts included):
multilayer%h_layer, shape (nx_total, ny_total, nz_ml).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
West-face x transport (h*u, m^2/s): multilayer%hu_face_x_layer,
same shape/stagger as u_face_x_layer.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
South-face y transport (h*v, m^2/s): multilayer%hv_face_y_layer,
same shape/stagger as v_face_y_layer.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(out) | :: | ke_out |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
Vertical heat diffusivity (m^2/s): vmix%kt, shape
(nx_total, ny_total, nz_ml+1) (layer INTERFACES).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
Vertical viscosity (m^2/s): vmix%kv, shape
(nx_total, ny_total, nz_ml+1) (layer INTERFACES).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | gen |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | gen |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| integer(kind=c_int), | intent(out) | :: | step_out |
East-face wind stress (N/m^2): surface_stress%tau_x, shape
(nx_total+1, ny_total).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | gen |
North-face wind stress (N/m^2): surface_stress%tau_y, shape
(nx_total, ny_total+1).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | gen |
Current simulation time (seconds).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(out) | :: | t_out |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(out) | :: | m_out |
Number of registered tracers (S, T, + any passive tracers) —
bounds for rdb_ocean_list_tracers’s index argument.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| integer(kind=c_int), | intent(out) | :: | count_out |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| character(kind=c_char, len=1), | intent(in) | :: | name(name_len) | |||
| integer(kind=c_int), | intent(in), | value | :: | name_len | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
West-face x-velocity (m/s): multilayer%u_face_x_layer, shape
(nx_total+1, ny_total, nz_ml).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
South-face y-velocity (m/s): multilayer%v_face_y_layer, shape
(nx_total, ny_total+1, nz_ml).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | gen |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer(kind=c_int), | intent(in), | value | :: | idx | ||
| character(kind=c_char, len=1), | intent(out) | :: | buf(cap) | |||
| integer(kind=c_int), | intent(in), | value | :: | cap |
Name of the registered diagnostic at index idx (0-based).
Same snprintf-style contract as rdb_ocean_list_tracers.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| integer(kind=c_int), | intent(in), | value | :: | idx | ||
| character(kind=c_char, len=1), | intent(out) | :: | buf(cap) | |||
| integer(kind=c_int), | intent(in), | value | :: | cap |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| integer(kind=c_int), | intent(in), | value | :: | idx | ||
| character(kind=c_char, len=1), | intent(out) | :: | buf(cap) | |||
| integer(kind=c_int), | intent(in), | value | :: | cap |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(kind=c_char, len=1), | intent(in) | :: | pv_adv_scheme(pv_adv_scheme_len) | |||
| integer(kind=c_int), | intent(in), | value | :: | pv_adv_scheme_len | ||
| character(kind=c_char, len=1), | intent(in) | :: | tracer_recon(tracer_recon_len) | |||
| integer(kind=c_int), | intent(in), | value | :: | tracer_recon_len | ||
| integer(kind=c_int), | intent(in), | value | :: | periodic | ||
| integer(kind=c_int), | intent(in), | value | :: | tripolar_fold | ||
| integer(kind=c_int), | intent(in), | value | :: | decomposed | ||
| integer(kind=c_int), | intent(in), | value | :: | kappa_shear_at_vertex |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(in) | :: | b_data(nx_p,ny_p) | |||
| integer(kind=c_int), | intent(in), | value | :: | nx_p | ||
| integer(kind=c_int), | intent(in), | value | :: | ny_p |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(in) | :: | h_data(nx_p,ny_p,nz_p) | |||
| integer(kind=c_int), | intent(in), | value | :: | nx_p | ||
| integer(kind=c_int), | intent(in), | value | :: | ny_p | ||
| integer(kind=c_int), | intent(in), | value | :: | nz_p |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(in) | :: | q_data(nx_p,ny_p) | |||
| integer(kind=c_int), | intent(in), | value | :: | nx_p | ||
| integer(kind=c_int), | intent(in), | value | :: | ny_p |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(in) | :: | q_data(nx_p,ny_p) | |||
| integer(kind=c_int), | intent(in), | value | :: | nx_p | ||
| integer(kind=c_int), | intent(in), | value | :: | ny_p |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| character(kind=c_char, len=1), | intent(in) | :: | name(name_len) | |||
| integer(kind=c_int), | intent(in), | value | :: | name_len | ||
| real(kind=c_double), | intent(in) | :: | data(nx_p,ny_p,nz_p) | |||
| integer(kind=c_int), | intent(in), | value | :: | nx_p | ||
| integer(kind=c_int), | intent(in), | value | :: | ny_p | ||
| integer(kind=c_int), | intent(in), | value | :: | nz_p |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(in) | :: | u_data(nx_p+1,ny_p,nz_p) | |||
| integer(kind=c_int), | intent(in), | value | :: | nx_p | ||
| integer(kind=c_int), | intent(in), | value | :: | ny_p | ||
| integer(kind=c_int), | intent(in), | value | :: | nz_p |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(in) | :: | v_data(nx_p,ny_p+1,nz_p) | |||
| integer(kind=c_int), | intent(in), | value | :: | nx_p | ||
| integer(kind=c_int), | intent(in), | value | :: | ny_p | ||
| integer(kind=c_int), | intent(in), | value | :: | nz_p |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(in) | :: | taux_data(nx_p+1,ny_p) | |||
| real(kind=c_double), | intent(in) | :: | tauy_data(nx_p,ny_p+1) | |||
| integer(kind=c_int), | intent(in), | value | :: | nx_p | ||
| integer(kind=c_int), | intent(in), | value | :: | ny_p |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(in) | :: | b_data(nx_p,ny_p) | |||
| integer(kind=c_int), | intent(in), | value | :: | nx_p | ||
| integer(kind=c_int), | intent(in), | value | :: | ny_p | ||
| integer(kind=c_int), | intent(in), | value | :: | convention |
|
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| real(kind=c_double), | intent(in) | :: | x(nxp,nyp) | |||
| real(kind=c_double), | intent(in) | :: | y(nxp,nyp) | |||
| real(kind=c_double), | intent(in) | :: | dx(nx,nyp) | |||
| real(kind=c_double), | intent(in) | :: | dy(nxp,ny) | |||
| real(kind=c_double), | intent(in) | :: | area(nx,ny) | |||
| integer(kind=c_int), | intent(in), | value | :: | nxp | ||
| integer(kind=c_int), | intent(in), | value | :: | nyp | ||
| integer(kind=c_int), | intent(in), | value | :: | nx | ||
| integer(kind=c_int), | intent(in), | value | :: | ny |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| integer(kind=c_int), | intent(in), | value | :: | periodic_x |
Nonzero = periodic on that axis. |
|
| integer(kind=c_int), | intent(in), | value | :: | periodic_y |
Nonzero = periodic on that axis. |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in), | value | :: | c_handle | ||
| integer(kind=c_int), | intent(in), | value | :: | n_steps |
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.
sum_k sum_ij f(i,j,k)*area(i,j) over the physical interior.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | f(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | area(:,:) | |||
| integer, | intent(in) | :: | ng | |||
| integer, | intent(in) | :: | nxp | |||
| integer, | intent(in) | :: | nyp |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_handle_t), | intent(in), | pointer | :: | h |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in) | :: | c_handle | |||
| type(ocean_handle_t), | intent(out), | pointer | :: | h |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(in) | :: | c_handle | |||
| type(ocean_handle_t), | intent(out), | pointer | :: | h |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_handle_t), | intent(in), | pointer | :: | h | ||
| integer(kind=c_int), | intent(in) | :: | nx_p | |||
| integer(kind=c_int), | intent(in) | :: | ny_p | |||
| integer(kind=c_int), | intent(in) | :: | nz_p |
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)).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_handle_t), | intent(in), | pointer | :: | h | ||
| character(len=*), | intent(in) | :: | name |
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.
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | text | |||
| type(c_ptr), | intent(out) | :: | c_handle | |||
| type(ocean_handle_t), | intent(out), | pointer | :: | h | ||
| integer(kind=c_int), | intent(out) | :: | status |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(kind=c_char, len=1), | intent(in) | :: | c_str(c_len) | |||
| integer(kind=c_int), | intent(in) | :: | c_len | |||
| character(len=:), | intent(out), | allocatable | :: | f_str |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(inout) | :: | c_handle | |||
| type(ocean_handle_t), | intent(inout), | pointer | :: | h | ||
| integer(kind=c_int), | intent(out) | :: | status |
2D counterpart of fill_getter_3d.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | gen | |||
| real(kind=wp), | intent(in), | pointer | :: | arr(:,:) | ||
| integer, | intent(in) | :: | step |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(c_ptr), | intent(out) | :: | ptr | |||
| integer(kind=c_int), | intent(out) | :: | nx | |||
| integer(kind=c_int), | intent(out) | :: | ny | |||
| integer(kind=c_int), | intent(out) | :: | nz | |||
| integer(kind=c_int), | intent(out) | :: | gen | |||
| real(kind=wp), | intent(in), | pointer | :: | arr(:,:,:) | ||
| integer, | intent(in) | :: | step |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_handle_t), | intent(inout), | pointer | :: | h |