Holds the vertical-coordinate configuration and the per-step
target grid that the ALE remap step relamps multilayer.h_layer
+ every multilayer.tracers(t)%hTr onto. The coastal path has
VCOORD_SIGMA, VCOORD_ZSIGMA, VCOORD_ZSTAR, VCOORD_ZSTAR_SIGMA,
VCOORD_ZSTAR_FULL plus rdb_remap_column; this module is the
C-grid counterpart for the ocean dynamical core.
Phase 5g build-out status (this commit, Layer 2):
target_h(nx, ny, nz_ml) is allocated on init + bound to the
device via enter_data / exit_data.compute_target_h(this, total_h, eta) populates target_h
per the current coord_type. Working bodies:
VCOORD_EULERIAN_Z — H · dsig(k) (η ignored)
VCOORD_SIGMA — (H + η) · dsig(k)
VCOORD_ZSTAR — MOM6 z: the z_fixed nominal profile
dilated by (H + η)/H over bed fillers
VCOORD_ZSIGMA — smoothstep blend(sigma, fixed z-levels)
VCOORD_ZSTAR_SIGMA — smoothstep blend(sigma, z-lite)
VCOORD_ZSTAR_FULL — per-column z_ref + vanishing-layer floorsbuild_zref_full(this, h_bed) populates z_ref(:, :, 0:nz_ml)
per column from local bathymetry. Call once at init (or any
time the bathymetry changes); the per-step compute_target_h
then walks the cached z_ref table.ocean_dyn_step_split) is NOT wired yet —
simulation state is untouched. External callers can invoke
compute_target_h / build_zref_full to inspect the target
grid without advancing dynamics.Collaborator hand-off — remaining Phase 5g work (Layer 3):
1. Driver wiring in ocean_dyn_step_split: call
compute_target_h(total_h_2d, dyn%bt_work%bt_eta) then invoke the
remap kernel on multilayer.h_layer + each tracers(t)%hTr
+ face velocities. Recompute bt_eta from the new sum of
h_layer - bt_H_ref.
2. Face-velocity remap adapter — MOM6 reconstructs u at centres,
remaps, then projects back to faces with a divergence-free
correction. Donor-cell on (h·u)_face is the simpler
fallback.
3. VANISHING_LAYER_TOL-gated CWC for VCOORD_ZSTAR_FULL,
lifted from the coastal multilayer kernels.
See docs/ROADMAP_OCEAN.md Phase 5g for the full scope.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private, | parameter | :: | HYCOM_FLOOR_PROFILE | = | 2 |
Floor at |
| integer, | private, | parameter | :: | HYCOM_FLOOR_SIGMA | = | 0 |
Floor at |
| integer, | private, | parameter | :: | HYCOM_FLOOR_UNIFORM | = | 1 |
Floor at |
| integer, | private, | parameter | :: | NR_ITERS | = | 8 |
Fixed (GPU-uniform) Newton iteration budget for the density→depth inversion. Unrolled, no data-dependent while. |
| real(kind=wp), | private, | parameter | :: | NR_OFFSET | = | 1.0e-6_wp |
Out-of-range nudge applied only when the boundary gradient ≈ 0. |
| real(kind=wp), | private, | parameter | :: | NR_TOL | = | 1.0e-12_wp |
Newton convergence tolerance — tested on |delta| AFTER xi += delta. |
| real(kind=wp), | private, | parameter | :: | Z_FIXED_BED_PARTIAL_MIN | = | H_VANISHED |
Minimum LIVE partial BOTTOM cell thickness for What it closes. The bed branch used to floor its partial
cell at Why not |
| real(kind=wp), | private, | parameter | :: | Z_FIXED_TOP_PARTIAL_FRAC | = | 0.1_wp |
Minimum PARTIAL TOP CELL thickness, as a fraction of the nominal
layer spacing The two thresholds differ on purpose and the asymmetry is the
honest one: the bed’s threshold is |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| logical, | public | :: | check_vanished_content | = | .false. |
|
|
| integer, | public | :: | coord_type | = | VCOORD_EULERIAN_Z |
Selected vertical-coordinate variant. |
|
| real(kind=wp), | public, | allocatable | :: | dsig(:) |
Per-layer σ-fraction. Sums to 1.0; size |
||
| logical, | public | :: | is_init | = | .false. |
True between |
|
| integer, | public | :: | nx_total | = | 0 |
Total i-extent of |
|
| integer, | public | :: | ny_total | = | 0 |
Total j-extent of |
|
| integer, | public | :: | nz_ml | = | 0 |
Number of active layers. |
|
| real(kind=wp), | public | :: | regrid_time_scale | = | 0.0_wp |
Grid time-filter timescale τ (s) for the ALE regrid. After
|
|
| logical, | public | :: | remap_boundary_extrap | = | .false. |
Close the ALE remap’s reconstruction at the two boundary cells
( |
|
| logical, | public | :: | remap_check_preconditions | = | .false. |
Assert the ALE remap’s column preconditions once per remap and fail loud on a violation (audit findings V5, V6). |
|
| real(kind=wp), | public, | allocatable | :: | remap_conc_s(:,:,:) |
Layer-mean S concentration scratch for |
||
| real(kind=wp), | public, | allocatable | :: | remap_conc_t(:,:,:) |
Layer-mean T concentration scratch for the |
||
| real(kind=wp), | public, | allocatable | :: | remap_h_old(:,:,:) |
Snapshot of |
||
| real(kind=wp), | public, | allocatable | :: | remap_h_ref(:,:) |
H reference (total_h − bt_eta) scratch, shape |
||
| integer, | public | :: | remap_method | = | REMAP_PPM |
ALE remap reconstruction order (REMAP_PCM/PLM/PPM/PPM_H4/PQM).
PQM falls back to PPM for nz < 5 (see |
|
| logical, | public | :: | remap_nonuniform_weights | = | .false. |
Use the non-uniform-grid reconstruction weights in the ALE
remap’s PLM slope and PPM edge estimate — Colella & Woodward
(1984) eqs (1.6)-(1.8) — instead of their equal-thickness
specialisations ( |
|
| real(kind=wp), | public, | allocatable | :: | remap_total_h(:,:) |
Column-total h_layer scratch, shape |
||
| logical, | public | :: | remap_vel_conserve_ke | = | .false. |
Enable the KE-conserving rescale of the remapped layer
velocities. After the per-face column remap (which already
conserves |
|
| real(kind=wp), | public | :: | rho_ref_pressure | = | 2.0e7_wp |
Reference pressure (Pa, default 2e7 = 2000 dbar) for the
potential density that defines the |
|
| real(kind=wp), | public, | allocatable | :: | rho_target(:) |
Target interface potential densities (kg/m³), shape |
||
| real(kind=wp), | public, | allocatable | :: | target_h(:,:,:) |
Target layer thickness (m), shape |
||
| real(kind=wp), | public, | allocatable | :: | z_fixed_dz(:) |
|
||
| real(kind=wp), | public | :: | z_fixed_h_ref | = | 0.0_wp |
Total reference depth (m) for |
|
| logical, | public | :: | z_fixed_use_profile | = | .false. |
|
|
| real(kind=wp), | public, | allocatable | :: | z_fixed_zi(:) |
|
||
| real(kind=wp), | public, | allocatable | :: | z_ref(:,:,:) |
Per-column z* reference (m), shape |
||
| real(kind=wp), | public, | allocatable | :: | z_ref_global(:) |
Global reference z-interfaces (m, positive-down), shape
|
||
| real(kind=wp), | public, | allocatable | :: | z_top(:,:) |
Geopotential depth of the column top (m, positive down),
shape |
||
| logical, | public | :: | zfixed_closed_faces | = | .false. |
|
|
| real(kind=wp), | public | :: | zsigma_blend_width | = | 100.0_wp |
Smoothstep blend width (m) above the transition depth. |
|
| real(kind=wp), | public | :: | zsigma_depth_transition | = | 200.0_wp |
Sigma → z* transition depth (m) for |
|
| real(kind=wp), | public | :: | zstar_h_min | = | 1.0e-4_wp |
Bed-side vanishing-layer floor (m). Two contracts, picked by
the coordinate family — see |
|
| real(kind=wp), | public | :: | zstar_h_surf_target | = | 5.0_wp |
Surface-layer thickness anchor for |
|
| integer, | public | :: | zstar_n_surf | = | 0 |
Number of fine near-surface layers for ZSTAR_FULL. ≤ 0 = auto-pick (max(1, nz_ml/3)). |
|
| integer, | public | :: | zstar_stretching | = | STRETCH_UNIFORM |
Stretching mode for ZSTAR_FULL. |
| procedure, public, non_overridable :: build_zref_full => ocean_vcoord_build_zref_full | |
| procedure, public, non_overridable :: bytes => ocean_vcoord_bytes | |
| procedure, public, non_overridable :: compute_target_h => ocean_vcoord_compute_target_h | |
| procedure, public, non_overridable :: compute_target_h_rho => ocean_vcoord_compute_target_h_rho | |
| procedure, public, non_overridable :: destroy => ocean_vcoord_destroy | |
| procedure, public, non_overridable :: enter_data => ocean_vcoord_enter_data | |
| procedure, public, non_overridable :: exit_data => ocean_vcoord_exit_data | |
| procedure, public, non_overridable :: init => ocean_vcoord_init |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | target_h(nx,ny,nz) |
The |
||
| real(kind=wp), | intent(in) | :: | total_h(nx,ny) |
Column reference thickness ( |
||
| real(kind=wp), | intent(in) | :: | dy_cu(nx+1,ny) |
Land-masked u-face width. |
||
| real(kind=wp), | intent(in) | :: | dx_cv(nx,ny+1) |
Land-masked v-face width. |
||
| integer, | intent(in) | :: | nx |
i-extent of the CENTRE arrays (total, incl. halos). |
||
| integer, | intent(in) | :: | ny |
j-extent of the CENTRE arrays (total, incl. halos). |
||
| integer, | intent(in) | :: | nz |
Number of layers; |
||
| integer, | intent(in) | :: | i0 |
Owned cell range ( |
||
| integer, | intent(in) | :: | i1 |
Owned cell range ( |
||
| integer, | intent(in) | :: | j0 |
Owned cell range ( |
||
| integer, | intent(in) | :: | j1 |
Owned cell range ( |
||
| real(kind=wp), | intent(in) | :: | h_vanished |
Inert-filler marker ( |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | open_u(nx+1,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | open_v(nx,ny+1,nz) | |||
| real(kind=wp), | intent(in) | :: | target_h(nx,ny,nz) | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz | |||
| real(kind=wp), | intent(in) | :: | h_vanished |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_vcoord_t), | intent(in) | :: | this |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nk | |||
| real(kind=wp), | intent(in) | :: | hc(nk) | |||
| real(kind=wp), | intent(in) | :: | rhoc(nk) | |||
| integer, | intent(in) | :: | n_int | |||
| real(kind=wp), | intent(in) | :: | rho_tgt(n_int) | |||
| real(kind=wp), | intent(out) | :: | z_new(n_int+2) |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(out) | :: | open_u(nx+1,ny,nz) |
u-face 0/1 open mask. |
||
| real(kind=wp), | intent(out) | :: | open_v(nx,ny+1,nz) |
v-face 0/1 open mask. |
||
| real(kind=wp), | intent(in) | :: | target_h(nx,ny,nz) |
The |
||
| integer, | intent(in) | :: | nx |
i-extent of the CENTRE arrays (total, incl. halos). |
||
| integer, | intent(in) | :: | ny |
j-extent of the CENTRE arrays (total, incl. halos). |
||
| integer, | intent(in) | :: | nz |
Number of layers; |
||
| real(kind=wp), | intent(in) | :: | h_vanished |
Inert-filler marker ( |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_vcoord_t), | intent(in) | :: | vc |
The vertical-coordinate slot (coord_type + every table). |
||
| real(kind=wp), | intent(inout) | :: | target_h(nx,ny,nz) |
Target thickness at |
||
| real(kind=wp), | intent(in) | :: | total_h(nx,ny) |
Reference column thickness (m) — |
||
| integer, | intent(in) | :: | nx |
i-extent (total, incl. halos). |
||
| integer, | intent(in) | :: | ny |
j-extent (total, incl. halos). |
||
| integer, | intent(in) | :: | nz |
Number of layers; |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(out) | :: | k_bot(nx,ny) |
Cell-centred first live layer counting up from the bed. |
||
| integer, | intent(out) | :: | k_bot_u(nx+1,ny) |
u-face twin. |
||
| integer, | intent(out) | :: | k_bot_v(nx,ny+1) |
v-face twin. |
||
| real(kind=wp), | intent(in) | :: | target_h(nx,ny,nz) |
Layer thickness (m) the live/filler pattern is read from —
the |
||
| integer, | intent(in) | :: | nx |
i-extent of the CENTRE arrays (total, incl. halos). |
||
| integer, | intent(in) | :: | ny |
j-extent of the CENTRE arrays (total, incl. halos). |
||
| integer, | intent(in) | :: | nz |
Number of layers; |
||
| real(kind=wp), | intent(in) | :: | h_vanished |
Inert-filler marker ( |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(out) | :: | k_top(nx,ny) |
Cell-centred first live layer. |
||
| integer, | intent(out) | :: | k_top_u(nx+1,ny) |
u-face twin. |
||
| integer, | intent(out) | :: | k_top_v(nx,ny+1) |
v-face twin. |
||
| real(kind=wp), | intent(in) | :: | target_h(nx,ny,nz) |
Layer thickness (m) the live/filler pattern is read from —
the |
||
| integer, | intent(in) | :: | nx |
i-extent of the CENTRE arrays (total, incl. halos). |
||
| integer, | intent(in) | :: | ny |
j-extent of the CENTRE arrays (total, incl. halos). |
||
| integer, | intent(in) | :: | nz |
Number of layers; |
||
| real(kind=wp), | intent(in) | :: | h_vanished |
Inert-filler marker ( |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_vcoord_t), | intent(inout) | :: | this | |||
| real(kind=wp), | intent(in) | :: | dz_surface_first(:) |
Nominal thicknesses (m), |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(out) | :: | target_h(nx,ny,nz) |
Target layer thickness (m). |
||
| real(kind=wp), | intent(in) | :: | total_h(nx,ny) |
Column reference thickness |
||
| real(kind=wp), | intent(in) | :: | eta(nx,ny) |
Free-surface anomaly |
||
| real(kind=wp), | intent(in) | :: | z_top(nx,ny) |
Geopotential depth of the column top (m, positive down,
|
||
| integer, | intent(in) | :: | nx |
i-extent of every array (total, incl. halos). |
||
| integer, | intent(in) | :: | ny |
j-extent of every array (total, incl. halos). |
||
| integer, | intent(in) | :: | nz |
Number of layers; |
||
| real(kind=wp), | intent(in) | :: | h_nominal |
Nominal layer spacing |
||
| logical, | intent(in) | :: | use_profile |
Take the nominal interfaces from |
||
| real(kind=wp), | intent(in) | :: | zi(0:nz) |
Nominal interface depths (m), bottom-up, |
||
| real(kind=wp), | intent(in) | :: | dz_nom(nz) |
Nominal layer thicknesses (m), bottom-up. Read only when
|
||
| real(kind=wp), | intent(in) | :: | h_min |
Inert-filler thickness ( |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(out) | :: | target_h(nx,ny,nz) |
Target layer thickness (m). |
||
| real(kind=wp), | intent(in) | :: | total_h(nx,ny) |
Column reference thickness |
||
| real(kind=wp), | intent(in) | :: | eta(nx,ny) |
Free-surface anomaly |
||
| real(kind=wp), | intent(in) | :: | z_top(nx,ny) |
Geopotential depth of the column top (m, positive down). |
||
| integer, | intent(in) | :: | nx |
i-extent of every array (total, incl. halos). |
||
| integer, | intent(in) | :: | ny |
j-extent of every array (total, incl. halos). |
||
| integer, | intent(in) | :: | nz |
Number of layers; |
||
| real(kind=wp), | intent(in) | :: | h_nominal |
Nominal layer spacing (m), |
||
| real(kind=wp), | intent(in) | :: | h_min |
Inert-filler thickness. |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(out) | :: | target_h(nx,ny,nz) |
Target layer thickness (m), bottom-up. |
||
| real(kind=wp), | intent(in) | :: | total_h(nx,ny) |
Column reference thickness |
||
| real(kind=wp), | intent(in) | :: | eta(nx,ny) |
Free-surface anomaly |
||
| integer, | intent(in) | :: | nx |
i-extent of every array (total, incl. halos). |
||
| integer, | intent(in) | :: | ny |
j-extent of every array (total, incl. halos). |
||
| integer, | intent(in) | :: | nz |
Number of layers; |
||
| real(kind=wp), | intent(in) | :: | h_nominal |
Uniform nominal spacing |
||
| logical, | intent(in) | :: | use_profile |
Take the nominal interfaces from |
||
| real(kind=wp), | intent(in) | :: | zi(0:nz) |
Nominal interface depths (m), bottom-up, |
||
| real(kind=wp), | intent(in) | :: | h_min |
Inert-filler thickness ( |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_vcoord_t), | intent(inout) | :: | this | |||
| real(kind=wp), | intent(in) | :: | h_bed(:,:) |
Bed depth at cell centres (m, positive-down). |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_vcoord_t), | intent(inout) | :: | this | |||
| real(kind=wp), | intent(in) | :: | total_h(:,:) | |||
| real(kind=wp), | intent(in) | :: | eta(:,:) |
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 η.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_vcoord_t), | intent(inout) | :: | this | |||
| real(kind=wp), | intent(in) | :: | total_h(:,:) |
Column-total depth H(i, j) (m). |
||
| real(kind=wp), | intent(in) | :: | eta(:,:) |
Free-surface anomaly η(i, j) (m). |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_vcoord_t), | intent(inout) | :: | this | |||
| real(kind=wp), | intent(in) | :: | total_h(:,:) | |||
| real(kind=wp), | intent(in) | :: | eta(:,:) | |||
| real(kind=wp), | intent(in) | :: | T(:,:,:) | |||
| real(kind=wp), | intent(in) | :: | S(:,:,:) | |||
| type(eos_t), | intent(in) | :: | eos | |||
| logical, | intent(in), | optional | :: | hybrid |
Enable the HYCOM hybrid deltas (default |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_vcoord_t), | intent(inout) | :: | this | |||
| real(kind=wp), | intent(in) | :: | total_h(:,:) |
Column reference depth H(i, j) (m). Caller passes the live column total (sum of h_layer) so the new grid spans it exactly. |
||
| real(kind=wp), | intent(in) | :: | eta(:,:) |
Free-surface anomaly η(i, j) (m). Added to |
||
| real(kind=wp), | intent(in) | :: | T(:,:,:) |
Layer-mean potential temperature concentration (°C), |
||
| real(kind=wp), | intent(in) | :: | S(:,:,:) |
Layer-mean salinity concentration (PSU), |
||
| type(eos_t), | intent(in) | :: | eos |
Shared device-resident EOS handle (flat POD, by value). |
||
| logical, | intent(in) | :: | hybrid |
|
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_vcoord_t), | intent(inout) | :: | this |
Map every host allocatable onto the device. Idempotent guard
via is_init.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_vcoord_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_vcoord_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_vcoord_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_vcoord_t), | intent(inout) | :: | this |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in), | value | :: | coord_type |
|
|
| integer, | intent(in), | value | :: | nx |
i-extent of every horizontal array (total, incl. halos). |
|
| integer, | intent(in), | value | :: | ny |
j-extent of every horizontal array (total, incl. halos). |
|
| integer, | intent(in), | value | :: | nz |
Number of layers; |
|
| real(kind=wp), | intent(inout) | :: | target_h(nx,ny,nz) |
Target layer thickness (m), bottom-up. |
||
| real(kind=wp), | intent(in) | :: | total_h(nx,ny) |
Column-total depth H (m). |
||
| real(kind=wp), | intent(in) | :: | eta(nx,ny) |
Free-surface anomaly η (m). |
||
| real(kind=wp), | intent(in) | :: | dsig(nz) |
Nominal layer fractions, bottom-up. |
||
| real(kind=wp), | intent(in) | :: | z_ref_global(0:nz) |
Global reference interface depths (ZSIGMA / ZSTAR_SIGMA). |
||
| real(kind=wp), | intent(in) | :: | z_ref(nx,ny,0:nz) |
Per-column reference interface depths (ZSTAR_FULL). |
||
| real(kind=wp), | intent(in), | value | :: | zsigma_depth_transition |
Sigma → z* transition depth (m). |
|
| real(kind=wp), | intent(in), | value | :: | zsigma_blend_width |
Smoothstep blend width (m). |
|
| real(kind=wp), | intent(in), | value | :: | zstar_h_min |
Vanished-layer thickness (m). |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_vcoord_t), | intent(inout) | :: | this | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| integer, | intent(in), | optional | :: | nz_ml |
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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in), | value | :: | nx |
i-extent of every horizontal array (total, incl. halos). |
|
| integer, | intent(in), | value | :: | ny |
j-extent of every horizontal array (total, incl. halos). |
|
| integer, | intent(in), | value | :: | nz |
Number of layers; |
|
| real(kind=wp), | intent(inout) | :: | target_h(nx,ny,nz) |
Target layer thickness (m), bottom-up. |
||
| real(kind=wp), | intent(in) | :: | remap_h_old(nx,ny,nz) |
Pre-remap layer thickness snapshot (m), bottom-up. |
||
| real(kind=wp), | intent(in) | :: | total_h(nx,ny) |
Column reference depth H (m). |
||
| real(kind=wp), | intent(in) | :: | eta(nx,ny) |
Free-surface anomaly η (m). |
||
| real(kind=wp), | intent(in) | :: | t_conc(nx,ny,nz) |
Layer-mean potential temperature (°C), bottom-up. |
||
| real(kind=wp), | intent(in) | :: | s_conc(nx,ny,nz) |
Layer-mean salinity (PSU), bottom-up. |
||
| real(kind=wp), | intent(in) | :: | dsig(nz) |
Nominal layer fractions, bottom-up ( |
||
| real(kind=wp), | intent(in) | :: | floor_dz(nz) |
HYCOM z* nominal layer thicknesses (m), bottom-up
( |
||
| real(kind=wp), | intent(in) | :: | rho_target(0:nz) |
Target potential densities (kg/m³), |
||
| type(eos_t), | intent(in) | :: | eos |
Shared EOS handle (flat POD). |
||
| real(kind=wp), | intent(in), | value | :: | p_ref |
Coordinate reference pressure (Pa) — |
|
| real(kind=wp), | intent(in), | value | :: | h_min |
Pre-compaction strip threshold (m) — |
|
| real(kind=wp), | intent(in), | value | :: | h_floor_eff |
Min-thickness inflation floor (m), |
|
| logical, | intent(in), | value | :: | hybrid |
|
|
| integer, | intent(in), | value | :: | floor_mode |
HYCOM z* floor source: |
|
| real(kind=wp), | intent(in), | value | :: | h_nominal |
Uniform z* nominal thickness (m) for |
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).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in), | value | :: | i |
Column i-index. |
|
| integer, | intent(in), | value | :: | j |
Column j-index. |
|
| integer, | intent(in), | value | :: | nx |
i-extent of every horizontal array (total, incl. halos). |
|
| integer, | intent(in), | value | :: | ny |
j-extent of every horizontal array (total, incl. halos). |
|
| integer, | intent(in), | value | :: | nz |
Number of layers; |
|
| real(kind=wp), | intent(inout) | :: | target_h(nx,ny,nz) |
Target layer thickness (m), bottom-up. |
||
| real(kind=wp), | intent(in) | :: | remap_h_old(nx,ny,nz) |
Pre-remap layer thickness snapshot (m), bottom-up. |
||
| real(kind=wp), | intent(in) | :: | total_h(nx,ny) |
Column reference depth H (m). |
||
| real(kind=wp), | intent(in) | :: | eta(nx,ny) |
Free-surface anomaly η (m). |
||
| real(kind=wp), | intent(in) | :: | t_conc(nx,ny,nz) |
Layer-mean potential temperature (°C), bottom-up. |
||
| real(kind=wp), | intent(in) | :: | s_conc(nx,ny,nz) |
Layer-mean salinity (PSU), bottom-up. |
||
| real(kind=wp), | intent(in) | :: | dsig(nz) |
Nominal layer fractions, bottom-up ( |
||
| real(kind=wp), | intent(in) | :: | floor_dz(nz) |
HYCOM z* nominal layer thicknesses (m), bottom-up
( |
||
| real(kind=wp), | intent(in) | :: | rho_target(0:nz) |
Target potential densities (kg/m³), |
||
| type(eos_t), | intent(in) | :: | eos |
Shared EOS handle (flat POD). |
||
| real(kind=wp), | intent(in), | value | :: | p_ref |
Coordinate reference pressure (Pa) — |
|
| real(kind=wp), | intent(in), | value | :: | h_min |
Pre-compaction strip threshold (m) — |
|
| real(kind=wp), | intent(in), | value | :: | h_floor_eff |
Min-thickness inflation floor (m), |
|
| logical, | intent(in), | value | :: | hybrid |
|
|
| integer, | intent(in), | value | :: | floor_mode |
HYCOM z* floor source: |
|
| real(kind=wp), | intent(in), | value | :: | h_nominal |
Uniform z* nominal thickness (m) for |