Per-variable fill procedures the diag manager invokes on cadence-fire;
the bridge between the diag manager and ocean_state_t. Each fill
select type-casts the class(*) state handle back to
ocean_state_t and populates a pre-allocated buffer. Face-staggered
fields (u_face_x, v_face_y) are averaged to cell centres so every
default variable is (nx, ny, nz).
Defaults: SSH (m), temperature (°C), salinity (PSU), u/v_centre (m/s),
ke (m²/s²); conditionally ice_conc (1) / ice_thick (m) when
&ocean_ice_nml enable.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=16), | private, | parameter | :: | CANONICAL_DIAG_NAMES(N_CANONICAL_DIAGS) | = | [character(len=16)::"SSH", "temperature", "salinity", "age", "u", "v", "KE", "MLD_EPBL", "Kd_EPBL", "Kd_KSHEAR", "ice_conc", "ice_thick", "pseudo_salt", "pseudo_salt_diff"] |
The single source of truth for |
| integer, | private, | parameter | :: | N_CANONICAL_DIAGS | = | 14 | |
| real(kind=wp), | private, | parameter | :: | VANISHED_TARGET_FLOOR | = | 1.0e-10_wp |
Target-cell thickness at/below which the cell is treated as overlapping no water (below-bottom / pinched-out). Tiny absolute floor: catches the exactly-zero below-bottom cells (and z*/sigma cells in a dry column) without masking genuinely thin overlaps. |
| logical, | private, | save | :: | diag_mask_vanished | = | .false. |
When |
| integer, | private, | save | :: | diag_remap_method | = | REMAP_PPM |
Reconstruction for the conservative diagnostic vertical remap
( |
Name of canonical-catalog entry i (1-based). Public for the P7
discoverability C ABI and the unit-test suite.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | i |
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.
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name |
Query the vanished-masking mode (used by the registration path to
tag non-layer diagnostics with has_missing for the NetCDF writer).
.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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name |
Map a &ocean_diag_nml diag_remap_scheme string to the REMAP_*
enum; returns -1 for an unrecognised name (caller fails loud).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | coord | |||
| procedure(diag_remap_proc), | intent(out), | pointer | :: | remap |
Layer ideal age = tracers(idx_age)%hTr / h_layer (s). Read-out only;
registered when &ocean_tracers_nml enable_ideal_age (idx_age > 0).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
EPBL active-mixing-layer depth (m) into the k=1 plane.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
Layer salinity, same pattern as temperature.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
C-grid u-face → cell centre by simple 2-point average.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout), | target | :: | state | ||
| real(kind=wp), | intent(in), | optional | :: | dt_out | ||
| type(diag_spec_t), | intent(in), | optional | :: | specs(:) | ||
| integer, | intent(in), | optional | :: | default_coord |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(in) | :: | z_out(:) | |||
| real(kind=wp), | intent(in) | :: | layer_buf(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | output_buf(:,:,:) | |||
| logical, | intent(in) | :: | is_extensive |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(in) | :: | levels(:) | |||
| real(kind=wp), | intent(in) | :: | layer_buf(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | output_buf(:,:,:) | |||
| logical, | intent(in) | :: | is_extensive |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(in) | :: | z_out(:) | |||
| real(kind=wp), | intent(in) | :: | layer_buf(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | output_buf(:,:,:) | |||
| logical, | intent(in) | :: | is_extensive |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(*), | intent(in) | :: | state_handle | |||
| real(kind=wp), | intent(in) | :: | levels(:) | |||
| real(kind=wp), | intent(in) | :: | layer_buf(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | output_buf(:,:,:) | |||
| logical, | intent(in) | :: | is_extensive |
Enable / disable masking of vanished (no-water) remap target cells
to DIAG_MISSING_VALUE (host only). Default off.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| logical, | intent(in) | :: | flag |
Seed the module-level diagnostic remap reconstruction (host only).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | method |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | field(:,:) | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | ncat | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| real(kind=wp), | intent(in) | :: | wet_T(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | part_size(nx,ny,0:ncat) | |||
| real(kind=wp), | intent(in) | :: | m_ice(nx,ny,ncat) | |||
| logical, | intent(in) | :: | emit_thick | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | kd_int(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | u_face(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | v_face(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | h(:,:) | |||
| real(kind=wp), | intent(in) | :: | b(:,:) | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | h_layer(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | b(:,:) | |||
| integer, | intent(in) | :: | nz_ml | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
Shared flat-impl for any tracer concentration field.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | h_layer(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | hTr(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | u_face(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | v_face(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | buf(:,:,:) |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_state_t), | intent(inout), | target | :: | state | ||
| type(diag_spec_t), | intent(in), | optional | :: | specs(:) | ||
| integer, | intent(in) | :: | default_coord | |||
| real(kind=wp), | intent(in) | :: | dtout | |||
| character(len=*), | intent(in) | :: | name | |||
| character(len=*), | intent(in) | :: | units | |||
| procedure(diag_fill_proc) | :: | fill | ||||
| integer, | intent(in) | :: | n3 | |||
| integer, | intent(in) | :: | def_op | |||
| character(len=*), | intent(in) | :: | long_name | |||
| character(len=*), | intent(in), | optional | :: | standard_name |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | h_layer(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | hT(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | hS(:,:,:) | |||
| type(eos_t), | intent(in) | :: | eos | |||
| real(kind=wp), | intent(in) | :: | rho_ref_p | |||
| real(kind=wp), | intent(in) | :: | rho_tgt(:) | |||
| real(kind=wp), | intent(in) | :: | layer_buf(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | output_buf(:,:,:) | |||
| logical, | intent(in) | :: | is_extensive | |||
| integer, | intent(in) | :: | method |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | coord_type | |||
| real(kind=wp), | intent(in) | :: | h_layer(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | levels(:) | |||
| real(kind=wp), | intent(in) | :: | layer_buf(:,:,:) | |||
| real(kind=wp), | intent(inout) | :: | output_buf(:,:,:) | |||
| logical, | intent(in) | :: | is_extensive | |||
| integer, | intent(in) | :: | method | |||
| logical, | intent(in) | :: | mask_vanished | |||
| real(kind=wp), | intent(in) | :: | missing |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(diag_spec_t), | intent(in), | optional | :: | specs(:) | ||
| character(len=*), | intent(in) | :: | name | |||
| integer, | intent(inout) | :: | time_op | |||
| real(kind=wp), | intent(inout) | :: | dt_out | |||
| integer, | intent(inout) | :: | coord | |||
| logical, | intent(out) | :: | skip |