| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | public, | parameter | :: | H_CAVITY_FLOOR | = | 2.0_wp*H_VANISHED |
Thickness (m) a clamped top-layer WITHDRAWAL is allowed to leave
behind — one full marker ABOVE
|
Ice-shelf basal-melt slot: the 2-D interface state plus the parameter bundles the kernel is called with.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=wp), | public, | allocatable | :: | active(:,:) |
Composed solve mask (0/1): |
||
| real(kind=wp), | public | :: | cdrag_top | = | 2.5e-3_wp |
Top drag coefficient for the MELT friction velocity only. |
|
| real(kind=wp), | public, | allocatable | :: | comp_scale(:,:) |
Per-cell top-layer thickness RATIO |
||
| real(kind=wp), | public | :: | comp_withdrawal_step | = | 0.0_wp |
Thickness (m) the compensation sink removed from each open -ocean column this thermo step; zero when compensation is off. |
|
| type(ocean_cavity_const_t), | public | :: | const |
Thermodynamic + turbulence constants. Flat POD, left at the
ISOMIP+ protocol values (Asay-Davis et al. (2016) Table 4):
|
|||
| logical, | public | :: | enable | = | .false. |
|
|
| real(kind=wp), | public, | allocatable | :: | f_cor(:,:) |
Cell-centred Coriolis parameter (1/s), from the same
|
||
| real(kind=wp), | public | :: | far_field_depth | = | 10.0_wp |
Thickness (m) below the ice base the far field is averaged over. See the module docstring: metres, not layers. |
|
| integer, | public | :: | freshwater | = | CAVITY_FW_VIRTUAL |
|
|
| real(kind=wp), | public, | allocatable | :: | gamma_s(:,:) |
Haline exchange velocity (m/s), same convention. |
||
| real(kind=wp), | public, | allocatable | :: | gamma_t(:,:) |
Thermal exchange velocity (m/s) the column’s solve converged
on — NOT |
||
| type(ocean_cavity_ice_t), | public | :: | ice |
Ice-conduction selector + |
|||
| logical, | public | :: | is_init | = | .false. |
Set by |
|
| real(kind=wp), | public, | allocatable | :: | melt(:,:) |
Canonical melt mass flux (kg/m^2/s), > 0 melting. |
||
| real(kind=wp), | public | :: | melt_volume_step | = | 0.0_wp |
Domain-integrated meltwater VOLUME (m^3) added this thermo step over the INTERIOR (ghosts excluded, globally combined). Diagnostic + the input the compensation sink spends. |
|
| integer, | public | :: | n_no_root_step | = | 0 |
Active columns returning |
|
| integer(kind=int64), | public | :: | n_no_root_total | = | 0_int64 |
Running total of |
|
| integer, | public | :: | n_nonfinite_step | = | 0 |
Active columns returning |
|
| integer, | public | :: | n_not_converged_step | = | 0 |
Active columns returning |
|
| integer(kind=int64), | public | :: | n_not_converged_total | = | 0_int64 |
Running total, drained to the console like
|
|
| integer, | public | :: | n_other_step | = | 0 |
Active columns returning any other non-OK status
( |
|
| integer(kind=int64), | public | :: | n_other_total | = | 0_int64 |
Running total of every other non-OK, non-fatal status. |
|
| integer, | public | :: | n_thin_step | = | 0 |
Columns this thermo step whose top layer could NOT give up
the thickness the real-mass path asked of it without falling
through |
|
| integer(kind=int64), | public | :: | n_thin_total | = | 0_int64 |
Running total of |
|
| real(kind=wp), | public | :: | open_area | = | 0.0_wp |
Interior wet area (m^2) the ice does NOT cover, globally combined — the denominator of the uniform sink. |
|
| type(ocean_cavity_exchange_t), | public | :: | par |
Exchange-law selector + coefficients. Flat POD; its
|
|||
| real(kind=wp), | public, | allocatable | :: | q_ocean(:,:) |
Turbulent heat flux ocean → interface (W/m^2), > 0 cools the ocean. |
||
| real(kind=wp), | public | :: | rho0 | = | 1035.0_wp |
Boussinesq reference density (kg/m^3) — THE density that
converts the melt MASS flux into a thickness tendency, and
the same one |
|
| real(kind=wp), | public, | allocatable | :: | s_b(:,:) |
Interface salinity (g/kg). |
||
| real(kind=wp), | public, | allocatable | :: | s_far(:,:) |
Far-field salinity (g/kg), same average. |
||
| real(kind=wp), | public | :: | s_ice | = | 0.0_wp |
Ice salinity (g/kg). |
|
| integer, | public, | allocatable | :: | status(:,:) |
|
||
| real(kind=wp), | public, | allocatable | :: | t_b(:,:) |
Interface temperature (degC), on the liquidus. |
||
| real(kind=wp), | public, | allocatable | :: | t_far(:,:) |
Far-field temperature (degC), thickness-weighted over
|
||
| real(kind=wp), | public, | allocatable | :: | u_far(:,:) |
Far-field x velocity at the cell CENTRE (m/s), same average. |
||
| real(kind=wp), | public | :: | u_tide | = | 1.0e-2_wp |
RMS tidal velocity (m/s) in the melt |
|
| real(kind=wp), | public, | allocatable | :: | ustar(:,:) |
Melt friction velocity (m/s). |
||
| real(kind=wp), | public | :: | ustar_min | = | 1.0e-4_wp |
Friction-velocity floor (m/s). |
|
| real(kind=wp), | public, | allocatable | :: | v_far(:,:) |
Far-field y velocity at the cell CENTRE (m/s), same average. |
||
| integer, | public | :: | volume_comp | = | CAVITY_VC_NONE |
|
| procedure, public, non_overridable :: bytes => ocean_cavity_flux_bytes | |
| procedure, public, non_overridable :: destroy => ocean_cavity_flux_destroy | |
| procedure, public, non_overridable :: enter_data => ocean_cavity_flux_enter_data | |
| procedure, public, non_overridable :: exit_data => ocean_cavity_flux_exit_data | |
| procedure, public, non_overridable :: init => ocean_cavity_flux_init |
The uniform per-unit-area thickness the uniform_open_ocean
sink removes: vol_melt/area_open, and exactly zero when there
is no open ocean to remove it from (a fully ice-covered domain —
the sink then does nothing rather than dividing by zero, and the
volume stays in, which the mass budget reports honestly as a
growing total).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=wp), | intent(in) | :: | vol_melt |
Meltwater volume this step (m^3); either sign. |
||
| real(kind=wp), | intent(in) | :: | area_open |
Uncovered wet area (m^2), >= 0. |
Is this step’s clamped-withdrawal tally a FAIL-LOUD condition?
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | n_thin |
|
Is this step’s status tally a FAIL-LOUD condition?
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | n_nonfinite |
|
Counted allocatable footprint (0 when unallocated). One
arr_bytes term per array — add one here when an array joins
the type.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_cavity_flux_t), | intent(in) | :: | this |
The volume_compensation = "uniform_open_ocean" sink: remove
dw metres of the top layer from every wet cell the ice does
NOT cover, the removed parcel carrying that cell’s own T and
S so no concentration there changes.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx |
First dimension (ghosts included). |
||
| integer, | intent(in) | :: | ny |
Second dimension. |
||
| integer, | intent(in) | :: | nz |
Layer count; only |
||
| real(kind=wp), | intent(in) | :: | dw |
Thickness (m) to remove from each open-ocean column. |
||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) |
Static wet (1) / land (0) mask. |
||
| real(kind=wp), | intent(in) | :: | cover_frac(nx,ny) |
Ice-cover fraction (v1 binary). |
||
| real(kind=wp), | intent(inout) | :: | h_layer(nx,ny,nz) |
Layer thickness (m). |
||
| real(kind=wp), | intent(inout) | :: | hTr_S(nx,ny,nz) |
|
||
| real(kind=wp), | intent(inout) | :: | hTr_T(nx,ny,nz) |
|
||
| real(kind=wp), | intent(inout) | :: | salt_budget(nx,ny,nz) |
|
||
| real(kind=wp), | intent(inout) | :: | heat_budget(nx,ny,nz) |
|
||
| real(kind=wp), | intent(out) | :: | scale(nx,ny) |
|
||
| integer, | intent(out) | :: | n_thin |
Columns whose withdrawal had to be clamped. |
Apply the compensation sink’s top-layer ratio to one PASSIVE
tracer’s load. Unconditional (scale = 1 off the sink), so
there is no mask branch inside the kernel.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx |
First dimension. |
||
| integer, | intent(in) | :: | ny |
Second dimension. |
||
| integer, | intent(in) | :: | nz |
Layer count. |
||
| real(kind=wp), | intent(in) | :: | scale(nx,ny) |
|
||
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) |
The tracer’s |
Thickness-weighted mean of (T, S, u, v) over far_depth
METRES below the ice base, with a PARTIAL last layer.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx |
First dimension (ghosts included). |
||
| integer, | intent(in) | :: | ny |
Second dimension. |
||
| integer, | intent(in) | :: | nz |
Layer count; |
||
| real(kind=wp), | intent(in) | :: | far_depth |
Sampling thickness (m), > 0. |
||
| real(kind=wp), | intent(in) | :: | cover(nx,ny) |
Ice-cover fraction (v1 binary). |
||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) |
Static wet (1) / land (0) mask. |
||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) |
Layer thickness (m). |
||
| real(kind=wp), | intent(in) | :: | hTr_T(nx,ny,nz) |
|
||
| real(kind=wp), | intent(in) | :: | hTr_S(nx,ny,nz) |
|
||
| real(kind=wp), | intent(in) | :: | u_face_x(nx+1,ny,nz) |
Zonal face velocity (m/s). |
||
| real(kind=wp), | intent(in) | :: | v_face_y(nx,ny+1,nz) |
Meridional face velocity (m/s). |
||
| real(kind=wp), | intent(out) | :: | active(nx,ny) |
Composed solve mask, 0 or 1. |
||
| real(kind=wp), | intent(out) | :: | t_far(nx,ny) |
Sampled temperature (degC); 0 where inactive. |
||
| real(kind=wp), | intent(out) | :: | s_far(nx,ny) |
Sampled salinity (g/kg); 0 where inactive. |
||
| real(kind=wp), | intent(out) | :: | u_far(nx,ny) |
Sampled centred x velocity (m/s); 0 where inactive. |
||
| real(kind=wp), | intent(out) | :: | v_far(nx,ny) |
Sampled centred y velocity (m/s); 0 where inactive. |
Fill the two OWNED surface-flux components from the solved
interface. FULL OVERWRITE of the whole plane, never += —
the same rule the sea-ice coupler’s fillers follow, and for the
same reason (a += ratchets across outer steps with no bound).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx |
First dimension (ghosts included). |
||
| integer, | intent(in) | :: | ny |
Second dimension. |
||
| real(kind=wp), | intent(in) | :: | s_ice |
Ice salinity (g/kg). |
||
| real(kind=wp), | intent(in) | :: | active(nx,ny) |
Composed solve mask. |
||
| real(kind=wp), | intent(in) | :: | melt(nx,ny) |
Melt mass flux (kg/m^2/s), > 0 melting. |
||
| real(kind=wp), | intent(in) | :: | q_ocean(nx,ny) |
Ocean → interface heat flux (W/m^2). |
||
| real(kind=wp), | intent(in) | :: | s_far(nx,ny) |
Far-field salinity the solve used (g/kg). |
||
| real(kind=wp), | intent(out) | :: | heat_cavity(nx,ny) |
Heat component (W/m^2), positive down into the ocean. |
||
| real(kind=wp), | intent(out) | :: | salt_cavity(nx,ny) |
Virtual salt component, positive salinifies. |
The real-mass top-layer source: add the meltwater VOLUME to
h_layer at the first LIVE layer k_top(i,j), replace the
virtual salt flux the assembler
stamped with the real advective salt w*s_ice, and add the
enthalpy dh*T_b — mirroring both tracer increments into the
existing surface budget contributors.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx |
First dimension (ghosts included). |
||
| integer, | intent(in) | :: | ny |
Second dimension. |
||
| integer, | intent(in) | :: | nz |
Layer count; |
||
| real(kind=wp), | intent(in) | :: | dt_over_rho0 |
|
||
| real(kind=wp), | intent(in) | :: | inv_rho0_dt |
The same |
||
| real(kind=wp), | intent(in) | :: | s_ice |
Ice salinity (g/kg). |
||
| real(kind=wp), | intent(in) | :: | active(nx,ny) |
Composed solve mask; 1 only on covered, wet, sampled columns. |
||
| real(kind=wp), | intent(in) | :: | melt(nx,ny) |
Melt mass flux (kg/m^2/s), > 0 melting. |
||
| real(kind=wp), | intent(in) | :: | s_far(nx,ny) |
Far-field salinity (g/kg) the solve used. The VIRTUAL salt
component |
||
| real(kind=wp), | intent(in) | :: | t_b(nx,ny) |
Interface temperature (degC): the temperature the meltwater joins the column at. |
||
| real(kind=wp), | intent(inout) | :: | h_layer(nx,ny,nz) |
Layer thickness (m); only |
||
| real(kind=wp), | intent(inout) | :: | hTr_S(nx,ny,nz) |
|
||
| real(kind=wp), | intent(inout) | :: | hTr_T(nx,ny,nz) |
|
||
| real(kind=wp), | intent(inout) | :: | salt_budget(nx,ny,nz) |
|
||
| real(kind=wp), | intent(inout) | :: | heat_budget(nx,ny,nz) |
|
||
| integer, | intent(in) | :: | k_top(nx,ny) |
|
||
| integer, | intent(out) | :: | n_thin |
Columns whose withdrawal had to be clamped. |
The pseudo-salt mirror of cavity_mass_apply_impl’s SALT
increment, with no budget accumulation — budget_id = NONE, so
it must not touch salt_budget_surface.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx |
First dimension. |
||
| integer, | intent(in) | :: | ny |
Second dimension. |
||
| integer, | intent(in) | :: | nz |
Layer count. |
||
| real(kind=wp), | intent(in) | :: | dt_over_rho0 |
|
||
| real(kind=wp), | intent(in) | :: | inv_rho0_dt |
The same |
||
| real(kind=wp), | intent(in) | :: | s_ice |
Ice salinity (g/kg). |
||
| real(kind=wp), | intent(in) | :: | active(nx,ny) |
Composed solve mask. |
||
| real(kind=wp), | intent(in) | :: | melt(nx,ny) |
Melt mass flux (kg/m^2/s). |
||
| real(kind=wp), | intent(in) | :: | s_far(nx,ny) |
Far-field salinity (g/kg); the virtual component being undone is rebuilt from it, exactly as in the sibling. |
||
| real(kind=wp), | intent(inout) | :: | hTr(nx,ny,nz) |
Pseudo-salt |
||
| integer, | intent(in) | :: | k_top(nx,ny) |
The SAME first-live-layer index the salt branch used — the mirror’s whole contract is that its increment is bit-identical to salinity’s, which includes landing on the same row. |
The two INTERIOR integrals the mass budget and the compensation sink need, reduced on device in one pass:
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx |
First dimension (ghosts included). |
||
| integer, | intent(in) | :: | ny |
Second dimension. |
||
| integer, | intent(in) | :: | nghost |
Halo width to exclude on every side. |
||
| real(kind=wp), | intent(in) | :: | dt_over_rho0 |
|
||
| real(kind=wp), | intent(in) | :: | active(nx,ny) |
Composed solve mask. |
||
| real(kind=wp), | intent(in) | :: | wet_mask(nx,ny) |
Static wet (1) / land (0) mask. |
||
| real(kind=wp), | intent(in) | :: | cover_frac(nx,ny) |
Ice-cover fraction (v1 binary). |
||
| real(kind=wp), | intent(in) | :: | melt(nx,ny) |
Melt mass flux (kg/m^2/s). |
||
| real(kind=wp), | intent(in) | :: | areaT(nx,ny) |
Cell area (m^2). |
||
| real(kind=wp), | intent(out) | :: | vol_melt |
Meltwater volume this step (m^3). |
||
| real(kind=wp), | intent(out) | :: | area_open |
Uncovered wet area (m^2). |
Reduce the per-column status plane into four counts, ON DEVICE.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx |
First dimension. |
||
| integer, | intent(in) | :: | ny |
Second dimension. |
||
| real(kind=wp), | intent(in) | :: | active(nx,ny) |
Composed solve mask. |
||
| integer, | intent(in) | :: | status(nx,ny) |
|
||
| integer, | intent(out) | :: | n_nonfinite |
Count of |
||
| integer, | intent(out) | :: | n_not_converged |
Count of |
||
| integer, | intent(out) | :: | n_no_root |
Count of |
||
| integer, | intent(out) | :: | n_other |
Count of every other non-OK status. |
One cavity basal-melt update: sample the far field, solve the three-equation interface on every covered column, deliver the two owned surface-flux components, and account for the solver status.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(hgrid_t), | intent(in) | :: | grid |
Horizontal grid (for |
||
| type(ocean_cavity_flux_t), | intent(inout) | :: | cav |
The cavity-melt slot. |
||
| type(ocean_metrics_t), | intent(in) | :: | metrics |
Reads |
||
| type(multilayer_state_t), | intent(in) | :: | ms |
Reads |
||
| type(eos_t), | intent(in) | :: | eos |
Shared EOS handle — the liquidus. Flat POD, by value. |
||
| type(ocean_surface_flux_t), | intent(inout) | :: | sf |
Writes |
||
| logical, | intent(in), | optional | :: | active |
Thermo-cadence gate. Present-and-false ⇒ early return;
absent ⇒ run (the |
The real-freshwater MASS update — one call, at the THERMO
cadence, from inside the RK2 stage immediately after
ocean_surface_flux_apply_tracers.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(hgrid_t), | intent(in) | :: | grid |
Horizontal grid ( |
||
| type(ocean_metrics_t), | intent(in) | :: | metrics |
Reads |
||
| type(ocean_cavity_flux_t), | intent(inout) | :: | cav |
The cavity-melt slot; reads |
||
| type(multilayer_state_t), | intent(inout) | :: | ms |
Writes |
||
| real(kind=wp), | intent(in) | :: | dt |
Thermo timestep (s) — the same |
||
| real(kind=wp), | intent(in) | :: | weight |
Per-stage weight for the |
||
| logical, | intent(in), | optional | :: | active |
Thermo-cadence gate. Present-and-false ⇒ early return; absent ⇒ run. |
Release the slot. is_init is cleared FIRST.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_cavity_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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_cavity_flux_t), | intent(inout) | :: | this |
copyin (not create) throughout: f_cor carries a
configure-time host fill that MUST reach the device, and the
rest carry the zero init promised on both toolchains.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_cavity_flux_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_cavity_flux_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_cavity_flux_t), | intent(inout) | :: | this |
Allocate the slot. Gated on enable (latched by
ocean_state_init_from_config before this runs), so a run
without a cavity pays fourteen (1,1) placeholders.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_cavity_flux_t), | intent(inout) | :: | this | |||
| type(hgrid_t), | intent(in) | :: | grid |