| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | public, | parameter | :: | SEAWATER_CP | = | 3992.0_wp | |
| real(kind=wp), | private, | parameter | :: | SECONDS_PER_DAY | = | 86400.0_wp |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | public, | allocatable | :: | Q_heat(:,:) |
2D net surface heat flux (W/m^2, positive downward),
shape |
||
| real(kind=wp), | public | :: | Q_heat_const | = | 0.0_wp |
Scalar fill source for |
|
| real(kind=wp), | public, | allocatable | :: | Q_salt(:,:) |
2D net surface salt flux (kg salt/m^2/s, positive salinifies),
shape |
||
| real(kind=wp), | public | :: | Q_salt_const | = | 0.0_wp |
Scalar fill source for |
|
| real(kind=wp), | public | :: | cp | = | SEAWATER_CP |
Specific heat capacity (J/kg/K). |
|
| real(kind=wp), | public, | allocatable | :: | evap(:,:) |
Evaporative mass flux (kg/m^2/s, <= 0 — MOM6 convention,
|
||
| real(kind=wp), | public, | allocatable | :: | fprec(:,:) |
Frozen precipitation / snowfall (kg/m^2/s, >= 0). |
||
| real(kind=wp), | public, | allocatable | :: | frunoff(:,:) |
Frozen (calving/ice) runoff (kg/m^2/s, >= 0). |
||
| real(kind=wp), | public | :: | h_min | = | 1.0e-3_wp |
Floor on the surface-layer thickness in the |
|
| logical, | public | :: | has_heat | = | .false. |
True when |
|
| logical, | public | :: | has_mass_flux | = | .false. |
Host-side latch — set by a filler after writing ANY of
|
|
| logical, | public | :: | has_q_sw | = | .false. |
Host-side latch — set by a filler after writing |
|
| logical, | public | :: | has_restore_S | = | .false. |
True when SSS restoring is active ( |
|
| logical, | public | :: | has_restore_T | = | .false. |
True when SST restoring is active ( |
|
| logical, | public | :: | has_salt | = | .false. |
True when |
|
| logical, | public | :: | has_sw | = | .false. |
True when shortwave penetration is active (set by
|
|
| real(kind=wp), | public, | allocatable | :: | heat_added(:,:) |
Restoring / flux-adjustment / “other” net heat term not
decomposed into the radiative/turbulent bands above (W/m^2,
either sign; MOM6 |
||
| real(kind=wp), | public, | allocatable | :: | heat_cavity(:,:) |
Ice-shelf cavity basal-melt heat component (W/m^2, same
positive-DOWN-into-the-ocean convention as every other heat
band; |
||
| real(kind=wp), | public, | allocatable | :: | heat_content_fprec(:,:) |
Enthalpy carried by |
||
| real(kind=wp), | public, | allocatable | :: | heat_content_frunoff(:,:) |
Enthalpy carried by |
||
| real(kind=wp), | public, | allocatable | :: | heat_content_lprec(:,:) |
Enthalpy carried by |
||
| real(kind=wp), | public, | allocatable | :: | heat_content_lrunoff(:,:) |
Enthalpy carried by |
||
| real(kind=wp), | public, | allocatable | :: | heat_content_massin(:,:) |
Assembler output — do NOT write. Sum of the six
|
||
| real(kind=wp), | public, | allocatable | :: | heat_content_massout(:,:) |
Assembler output — do NOT write. |
||
| real(kind=wp), | public, | allocatable | :: | heat_content_seaice_melt(:,:) |
Enthalpy carried by |
||
| real(kind=wp), | public, | allocatable | :: | heat_content_vprec(:,:) |
Enthalpy carried by |
||
| logical, | public | :: | is_init | = | .false. |
True between |
|
| real(kind=wp), | public, | allocatable | :: | lprec(:,:) |
Liquid precipitation (kg/m^2/s, >= 0 into the ocean). |
||
| real(kind=wp), | public, | allocatable | :: | lrunoff(:,:) |
Liquid river runoff (kg/m^2/s, >= 0). |
||
| real(kind=wp), | public, | allocatable | :: | p_surf(:,:) |
Assembled total (Pa, >= 0) — |
||
| real(kind=wp), | public, | allocatable | :: | p_surf_atm(:,:) |
Input component. Atmospheric surface-pressure load (Pa, >= 0). Filled by an external reader / configure-time scalar seed — the sea-ice path never writes this field. Ships zeroed with no consumer in this PR (the inverse- barometer PGF fold is a same-release-cycle follow-up). |
||
| real(kind=wp), | public | :: | q_assembled | = | 0.0_wp |
Host latch, 1 once |
|
| real(kind=wp), | public, | allocatable | :: | q_lat(:,:) |
Latent heat flux (W/m^2, typically < 0, positive down). |
||
| real(kind=wp), | public, | allocatable | :: | q_lw(:,:) |
Net longwave (W/m^2, typically < 0, positive down). |
||
| real(kind=wp), | public, | allocatable | :: | q_sens(:,:) |
Sensible heat flux (W/m^2, typically < 0, positive down). |
||
| real(kind=wp), | public, | allocatable | :: | q_sw(:,:) |
Shortwave into the ocean (W/m^2, >= 0, positive down). |
||
| real(kind=wp), | public | :: | restore_S_target | = | 0.0_wp |
Scalar target SSS (PSU). |
|
| real(kind=wp), | public | :: | restore_T_target | = | 0.0_wp |
Scalar target SST (degC). Read by-value into the device
|
|
| real(kind=wp), | public | :: | restore_piston_S | = | 0.0_wp |
SSS piston velocity (m/s). |
|
| real(kind=wp), | public | :: | restore_piston_T | = | 0.0_wp |
SST piston velocity (m/s), seeded from |
|
| real(kind=wp), | public | :: | rho0 | = | 1035.0_wp |
Boussinesq reference density (kg/m^3) — the |
|
| real(kind=wp), | public, | allocatable | :: | salt_cavity(:,:) |
Ice-shelf cavity basal-melt salt component, same units
and sign as |
||
| real(kind=wp), | public, | allocatable | :: | salt_flux(:,:) |
Net surface salt-flux COMPONENT (kg salt/m^2/s, positive
salinifies) — a filler writes this (e.g. the ice brine
coupler); the assembler adds |
||
| real(kind=wp), | public, | allocatable | :: | seaice_melt(:,:) |
Sea-ice melt-water mass flux (kg/m^2/s, >0 = melt into the ocean, <0 = formation / freezing withdraws mass). |
||
| real(kind=wp), | public | :: | sw_band_ratio | = | 0.58_wp |
Band-1 weight |
|
| logical, | public | :: | sw_from_qsw | = | .false. |
Selects the irradiance source for shortwave penetration and
the boundary-layer SW coupling. |
|
| real(kind=wp), | public | :: | sw_pen_frac | = | 0.0_wp |
Penetrating fraction of |
|
| real(kind=wp), | public | :: | sw_zeta1 | = | 0.35_wp |
Band-1 e-folding depth (m) — the rapidly-absorbed red/near-IR band. |
|
| real(kind=wp), | public | :: | sw_zeta2 | = | 23.0_wp |
Band-2 e-folding depth (m) — the slowly-absorbed blue/green band. |
|
| logical, | public | :: | use_components | = | .false. |
Master gate ( |
|
| real(kind=wp), | public, | allocatable | :: | vprec(:,:) |
Virtual precipitation (kg/m^2/s, either sign — SSS-restoring
convention; NOT wired to the restoring kernel in v1, see
|
| procedure, public, non_overridable :: bytes => ocean_surface_flux_bytes | |
| procedure, public, non_overridable :: destroy => ocean_surfflux_destroy | |
| procedure, public, non_overridable :: enter_data => ocean_surfflux_enter_data | |
| procedure, public, non_overridable :: exit_data => ocean_surfflux_exit_data | |
| procedure, public, non_overridable :: init => ocean_surfflux_init | |
| procedure, public, non_overridable :: set_components => ocean_surfflux_set_components | |
| procedure, public, non_overridable :: set_p_surf_const => ocean_surfflux_set_p_surf_const | |
| procedure, public, non_overridable :: set_restore => ocean_surfflux_set_restore | |
| procedure, public, non_overridable :: set_surface_flux_const => ocean_surfflux_set_const | |
| procedure, public, non_overridable :: set_sw_penetration => ocean_surfflux_set_sw |
In-layer potential-energy-cost shape function Phi(tau) for the
EPBL TKE ledger, tau = h/zeta the in-layer optical depth of a
single band. It is the fraction of the pure-skin PE cost that
homogenising an EXPONENTIALLY distributed in-layer heating
actually incurs (Paulson & Simpson 1977 profile; the EPBL
energetics of Reichl & Hallberg 2018):
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | tau |
Fail-loud predicate for the &ocean_thermo_nml sw_source
selector — validate_config aborts on any string this rejects.
The two recognised sources are the net-heat legacy path and the
PR-12 q_sw component.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | name |
Two-band (Paulson & Simpson 1977) normalised downward
irradiance transmission at depth d below the free surface,
T(d) = R·exp(-d/zeta1) + (1-R)·exp(-d/zeta2), T(0) = 1.
This is THE single shared definition — the SW deposition
kernel, the KPP MXL_SW/LV1_SW boundary-layer correction, and
the EPBL in-layer PE-cost ledger all consume it, so the three
consumers cannot disagree about where the sunlight went. Marked
!$acc routine seq so it inlines into same-module device kernels
and is callable from cross-module do concurrent kernels.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | d | |||
| real(kind=wp), | intent(in) | :: | R | |||
| real(kind=wp), | intent(in) | :: | zeta1 | |||
| real(kind=wp), | intent(in) | :: | zeta2 |
Counted allocatable footprint of the surface flux slot (0 when unallocated). One arr_bytes term per array — add a term here when a new allocatable joins the type.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(in) | :: | this |
Mask the STATIC scalar Q_heat / Q_salt fill with the
ice-shelf cover, for the use_components = .false. path only.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_surface_flux_t), | intent(inout) | :: | sf | |||
| real(kind=wp), | intent(in) | :: | cover_frac(:,:) |
Ice-cover fraction at cell centres ( |
Additive correction that redistributes the penetrating
shortwave fraction of Q_heat through the upper water column
as a two-band exponential (Paulson & Simpson 1977; Jerlov
types), instead of leaving all of it deposited at the surface
layer by ocean_surface_flux_apply_tracers.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(ocean_surface_flux_t), | intent(in), | optional | :: | sf |
Optional — absent ⇒ no-op (no forcing configured). |
|
| type(multilayer_state_t), | intent(inout) | :: | ms | |||
| real(kind=wp), | intent(in) | :: | dt | |||
| logical, | intent(in), | optional | :: | active |
Optional thermo-cadence gate. Present-and-false ⇒ early return; absent ⇒ kernel runs. |
|
| real(kind=wp), | intent(in), | optional | :: | cover_frac(:,:) |
Optional ice-shelf cover fraction ( |
Add the surface heat + salt fluxes directly to the top
tracer layer. Operates in hTr space (concentration·
thickness): for temperature
d(hT_top)/dt = Q_heat(i,j) / (rho_0 · cp)
For salinity
d(hS_top)/dt = Q_salt(i,j) / rho_0
(Both expressed in units that match the hTr convention:
hTr = T·h so the forcing has units of T·h/s = K·m/s.
Q_heat / (rho_0·cp) has units (W/m^2)/(kg/m^3·J/kg/K) =
K·m/s ✓.)
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(ocean_surface_flux_t), | intent(in), | optional | :: | sf |
Optional — when absent the kernel is a no-op (no surface forcing configured). |
|
| type(multilayer_state_t), | intent(inout) | :: | ms | |||
| real(kind=wp), | intent(in) | :: | dt | |||
| logical, | intent(in), | optional | :: | active |
Optional gate (thermo cadence). Absent ⇒ kernel runs; present-and-false ⇒ early return. |
|
| real(kind=wp), | intent(in), | optional | :: | wet_dyn(:,:) |
Optional DYNAMIC cell wet mask (wet/dry,
docs/ocean_wetdry_plan.md §4.4) composed multiplicatively
with the static |
The single gate that derives Q_heat/Q_salt from the
component set (§3.1/§3.3 of the PR-12 plan) — the exact analogue
of vmix_assemble: fillers contribute components, this routine
alone derives the net fields every downstream kernel reads. A
no-op unless sf%use_components — with components off, Q_heat
/ Q_salt are exactly what set_surface_flux_const (or a
field-override path) left them, byte-for-byte.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(ocean_surface_flux_t), | intent(inout) | :: | sf | |||
| type(multilayer_state_t), | intent(in) | :: | ms | |||
| logical, | intent(in), | optional | :: | active |
Optional thermo-cadence gate. Present-and-false ⇒ early
return; absent ⇒ kernel runs (matches
|
|
| real(kind=wp), | intent(in), | optional | :: | cover_frac(:,:) |
Optional ice-shelf cover fraction ( |
Surface buoyancy restoring (MOM6 RESTOREBUOY): relax the
top-layer (k = nz) temperature / salinity toward scalar
targets with a piston velocity p [m/s]. Unlike
ocean_surface_flux_apply_tracers (which reads a pre-filled
static Q_* field), the restoring flux is DYNAMIC — it depends
on the live SST / SSS each thermo step — so it is computed
in-kernel from (target - surface_concentration) rather than a
stored field. This keeps the const-flux path byte-for-byte
unchanged and adds no second device sync of Q_*.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(ocean_surface_flux_t), | intent(in), | optional | :: | sf |
Optional — absent ⇒ no-op (no forcing configured). |
|
| type(multilayer_state_t), | intent(inout) | :: | ms | |||
| real(kind=wp), | intent(in) | :: | dt | |||
| logical, | intent(in), | optional | :: | active |
Optional thermo-cadence gate. Present-and-false ⇒ early return; absent ⇒ kernel runs. |
|
| real(kind=wp), | intent(in), | optional | :: | cover_frac(:,:) |
Optional ice-shelf cover fraction ( |
Ice-shelf-cover twin of apply_surface_restore_2d_impl: the
open-water factor 1 - cover_frac composes multiplicatively
with wet_mask, so a covered column receives EXACTLY zero
restoring — and, because the same factor multiplies the budget
mirror, exactly zero restoring shows up in the heat/salt
surface budget there too. Separate _impl, not an in-loop
present() test (house idiom).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) | |||
| real(kind=wp), | intent(inout) | :: | budget(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | cover_frac(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | dt_piston | |||
| real(kind=wp), | intent(in) | :: | tgt | |||
| real(kind=wp), | intent(in) | :: | h_min | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Stamp the per-step restoring increment dt·p·(target - surf)·
wet_mask onto the top layer (k = nz) of a tracer’s hTr array
and mirror it into the matching budget contributor.
Explicit-shape dummies so NVHPC stdpar compiles device kernels
against static bounds.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) | |||
| real(kind=wp), | intent(inout) | :: | budget(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | dt_piston | |||
| real(kind=wp), | intent(in) | :: | tgt | |||
| real(kind=wp), | intent(in) | :: | h_min | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Wet/dry variant of apply_surface_src_2d_impl: the DYNAMIC cell
wet mask composes multiplicatively with the static one, so a
dynamically dry column (total depth below &ocean_wetdry_nml
dry_depth) receives NO surface flux — heating a mm-scale
residual sliver would blow its temperature up
(docs/ocean_wetdry_plan.md §4.4). Separate _impl (not an
in-loop optional test): the knob-off path keeps the original
kernel untouched, byte-identical.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) | |||
| real(kind=wp), | intent(inout) | :: | budget(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | wet_dyn(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | Q_field(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | inv_scale | |||
| integer, | intent(in) | :: | k_top(nx,ny) |
See |
||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Wet/dry NOBUDGET twin — see apply_surface_src_2d_nobudget_impl
and apply_surface_src_2d_dyn_impl.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | wet_dyn(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | Q_field(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | inv_scale | |||
| integer, | intent(in) | :: | k_top(nx,ny) |
See |
||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Stamp inv_scale · Q_field(i,j) · wet_mask(i,j) onto the first
LIVE layer (k_top(i,j)) of a tracer’s hTr array, mirror into
the matching budget contributor. Explicit-shape dummies so
NVHPC stdpar can compile device kernels against static bounds.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) | |||
| real(kind=wp), | intent(inout) | :: | budget(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | Q_field(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | inv_scale | |||
| integer, | intent(in) | :: | k_top(nx,ny) |
|
||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Byte-for-byte copy of apply_surface_src_2d_impl with the
budget dummy and its accumulation line removed — the
pseudo-salt mirror of salinity’s surface flux, which by
contract (budget_id = TRACER_BUDGET_NONE) must not touch
salt_budget_surface. Separate _impl, not an in-loop
present(budget) test (house idiom, see
apply_surface_src_2d_dyn_impl’s docstring) — this keeps the
production S/T impl untouched and the increment hTr receives
bit-identical to salinity’s.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | Q_field(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | inv_scale | |||
| integer, | intent(in) | :: | k_top(nx,ny) |
See |
||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Ice-shelf-cover twin of apply_sw_penetration_impl: the
open-water factor 1 - cover_frac composes multiplicatively
with wet_mask into the column irradiance I0, so a fully
covered column neither removes the surface lump nor deposits a
profile — it is left EXACTLY untouched. Separate _impl, not
an in-loop present() test (house idiom, see
apply_surface_src_2d_dyn_impl) — the cover-off path keeps the
original kernel byte-identical.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) | |||
| real(kind=wp), | intent(inout) | :: | budget(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| integer, | intent(in) | :: | k_bot(nx,ny) |
|
||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | cover_frac(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | sw_src(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | inv_scale | |||
| real(kind=wp), | intent(in) | :: | sw_pen_frac | |||
| real(kind=wp), | intent(in) | :: | R | |||
| real(kind=wp), | intent(in) | :: | zeta1 | |||
| real(kind=wp), | intent(in) | :: | zeta2 | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Per-column two-band shortwave redistribution. Explicit-shape
dummies so NVHPC stdpar compiles device kernels against static
bounds. Difference form (I(d_top) - I(d_bot)) — no division
by h, so a vanishing layer (h → 0 ⇒ d_top == d_bot) absorbs
zero automatically with no guard. The transmission T(d) is
the shared sw_transmission (same-module ⇒ inlined by NVHPC),
so the deposition and the boundary-layer coupling cannot diverge.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) | |||
| real(kind=wp), | intent(inout) | :: | budget(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| integer, | intent(in) | :: | k_bot(nx,ny) |
|
||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | sw_src(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | inv_scale | |||
| real(kind=wp), | intent(in) | :: | sw_pen_frac | |||
| real(kind=wp), | intent(in) | :: | R | |||
| real(kind=wp), | intent(in) | :: | zeta1 | |||
| real(kind=wp), | intent(in) | :: | zeta2 | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Allocate the 22-field component set + the two p_surf* fields,
all source=0.0_wp, shape (nx_total, ny_total). Private —
called only from set_components.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this | |||
| type(hgrid_t), | intent(in) | :: | grid |
Ice-shelf-cover twin of ocean_surfflux_assemble_impl: the
open-water factor open_f = 1 - cover_frac multiplies the
ATMOSPHERIC group and NOT the cavity group. Grouping, spelt
out because it is the whole point of this kernel:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | heat_content_massin(nx,ny) | |||
| real(kind=wp), | intent(inout) | :: | heat_content_massout(nx,ny) | |||
| real(kind=wp), | intent(inout) | :: | Q_heat(nx,ny) | |||
| real(kind=wp), | intent(inout) | :: | Q_salt(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | q_sw(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | q_lw(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | q_lat(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | q_sens(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_added(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_cavity(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_lprec(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_fprec(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_vprec(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_lrunoff(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_frunoff(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_seaice_melt(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | evap(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | salt_flux(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | salt_cavity(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | hTr_T(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | cover_frac(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | Q_heat_const | |||
| real(kind=wp), | intent(in) | :: | Q_salt_const | |||
| real(kind=wp), | intent(in) | :: | cp | |||
| real(kind=wp), | intent(in) | :: | h_min | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Flat do concurrent kernel — explicit-shape dummies, integer
dims declared first (decl-order, ifx #8586). See
ocean_surface_flux_assemble for the physics; this is the
arithmetic verbatim.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | heat_content_massin(nx,ny) | |||
| real(kind=wp), | intent(inout) | :: | heat_content_massout(nx,ny) | |||
| real(kind=wp), | intent(inout) | :: | Q_heat(nx,ny) | |||
| real(kind=wp), | intent(inout) | :: | Q_salt(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | q_sw(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | q_lw(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | q_lat(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | q_sens(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_added(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_cavity(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_lprec(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_fprec(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_vprec(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_lrunoff(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_frunoff(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | heat_content_seaice_melt(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | evap(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | salt_flux(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | salt_cavity(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | hTr_T(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | Q_heat_const | |||
| real(kind=wp), | intent(in) | :: | Q_salt_const | |||
| real(kind=wp), | intent(in) | :: | cp | |||
| real(kind=wp), | intent(in) | :: | h_min | |||
| integer, | intent(in) | :: | nz | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Flat do concurrent kernel behind
ocean_surface_flux_apply_cover_const — explicit-shape dummies,
integer dims first (decl-order, ifx #8586).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(inout) | :: | Q_heat(nx,ny) | |||
| real(kind=wp), | intent(inout) | :: | Q_salt(nx,ny) | |||
| real(kind=wp), | intent(in) | :: | cover_frac(nx,ny) | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Deallocate the component set (no-op on an already-unallocated
slot — every deallocate is if (allocated(...))-guarded).
Shared by destroy and by set_components re-entry.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this |
Type-bound wrapper — delegates to the non-polymorphic impl so the device-attach map base is the heap object, not a polymorphic stack box (AMD libomptarget cross-slot-overlap fix).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_surface_flux_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_surface_flux_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this | |||
| type(hgrid_t), | intent(in) | :: | grid |
Configure-time gate for the PR-12 component set
(&ocean_forcing_nml enable_components). init runs before the
namelist gate is known, so allocation happens HERE rather than in
init: enable = .false. (default) leaves use_components
false and allocates nothing — bit-identical, zero extra device
memory. enable = .true. allocates the full component set
(source=0.0_wp) and flips the gate so
ocean_surface_flux_assemble stops early-returning. Must be
called BEFORE enter_data (rdb_ocean_state.F90’s orchestrator)
so the freshly-allocated arrays get mapped. Re-entrant: calling
again with a different enable deallocates first.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| logical, | intent(in) | :: | enable |
Fill Q_heat / Q_salt uniformly from scalar values and set
the has_heat / has_salt flags so the apply-tracers kernel
fires. Mirrors set_wind_stress_const on the stress side.
Host only — call enter_data afterwards (or !$acc update
device if already mapped) to sync to the GPU.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this | |||
| real(kind=wp), | intent(in) | :: | q_heat_val | |||
| real(kind=wp), | intent(in) | :: | q_salt_val |
Seed the atmospheric surface-pressure INPUT component
p_surf_atm (Pa) uniformly from a scalar namelist value (PR-17
&ocean_psurf_nml p_surf_const). Full overwrite of the pristine
atmospheric base; the assembled total p_surf is built from it
once per outer step in p_surf_update_seam. No-op when the
component set is not allocated (use_components=.false.) — the
&ocean_psurf_nml enable guard in validate_config already
requires enable_components=.true., so a live consumer never hits
the no-op. Host only — call enter_data afterwards (or !$acc
update device if already mapped) to sync to the GPU.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this | |||
| real(kind=wp), | intent(in) | :: | p_surf_val |
Seed the surface buoyancy restoring (MOM6 RESTOREBUOY)
parameters and set the has_restore_T / has_restore_S gates.
Sibling to set_surface_flux_const / set_sw_penetration —
kept separate so existing callers are unchanged. The piston
velocities arrive in m/day (the MOM6 FLUXCONST_* unit) and
are converted to MKS m/s here. Effective-enable guard:
has_restore_* = enable_* .and. piston /= 0, so an enabled
switch with a zero piston is a silent no-op (rather than
restoring everything toward the 0-degC / 0-PSU default target).
Host only; all knobs are read host-side as by-value arguments to
the device _impl, so no extra device sync beyond copyin(this).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this | |||
| logical, | intent(in) | :: | enable_T | |||
| logical, | intent(in) | :: | enable_S | |||
| real(kind=wp), | intent(in) | :: | piston_t_day | |||
| real(kind=wp), | intent(in) | :: | piston_s_day | |||
| real(kind=wp), | intent(in) | :: | T_target | |||
| real(kind=wp), | intent(in) | :: | S_target |
Seed the shortwave-penetration band parameters and set the
has_sw gate (sw_pen_frac /= 0). Sibling to
set_surface_flux_const — kept separate so existing callers of
the heat/salt setter are unchanged. Host only; the scalars are
read host-side by the apply kernel (they parameterise the
by-value arguments passed into the device _impl), so no extra
device sync is needed beyond the existing copyin(this).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_surface_flux_t), | intent(inout) | :: | this | |||
| real(kind=wp), | intent(in) | :: | sw_pen_frac | |||
| real(kind=wp), | intent(in) | :: | sw_band_ratio | |||
| real(kind=wp), | intent(in) | :: | sw_zeta1 | |||
| real(kind=wp), | intent(in) | :: | sw_zeta2 | |||
| character(len=*), | intent(in), | optional | :: | sw_source |