Map-driven sponge state: per-cell Idamp [1/s] + a 3-D reference
state. See the module docstring for the physics + the MOM6
divergences. Value-semantics slot (no CS pointer, no
associated(CS) guards) per src/core/ocean/README.md.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=16), | public | :: | damp_source | = | "band" |
How |
|
| logical, | public | :: | enable | = | .false. |
Master switch. Default |
|
| real(kind=wp), | public, | allocatable | :: | idamp_h(:,:) |
Inverse damping time for tracers + (deferred) thickness, 1/s,
shape |
||
| real(kind=wp), | public, | allocatable | :: | idamp_u(:,:) |
Inverse damping time for |
||
| real(kind=wp), | public, | allocatable | :: | idamp_v(:,:) |
Inverse damping time for |
||
| integer, | public | :: | idx_s | = | 0 |
Tracer-registry index of salinity; see |
|
| integer, | public | :: | idx_t | = | 0 |
Tracer-registry index of temperature, latched at configure so
the per-step refresh needs no registry walk (and no
array-of-derived-types device indirection). |
|
| logical, | public | :: | is_init | = | .false. |
True once |
|
| real(kind=wp), | public | :: | lin_ds_dz | = | 0.0_wp |
|
|
| real(kind=wp), | public | :: | lin_dt_dz | = | 0.0_wp |
|
|
| real(kind=wp), | public | :: | lin_s_ref | = | 35.0_wp |
|
|
| real(kind=wp), | public | :: | lin_t_ref | = | 0.0_wp |
|
|
| integer, | public | :: | n_tracers | = | 0 |
Registered tracer count — sizes |
|
| real(kind=wp), | public, | allocatable | :: | ref_tracer(:,:,:,:) |
Reference tracer CONCENTRATION (not |
||
| logical, | public | :: | relax_h | = | .false. |
Interior-interface thickness damping. NOT IMPLEMENTED in PR-23
v1 (deferred to PR-23b alongside the file-backed targets —
|
|
| logical, | public | :: | relax_tracers | = | .true. |
Relax every registered tracer’s concentration toward
|
|
| logical, | public | :: | relax_uv | = | .true. |
Relax |
|
| character(len=16), | public | :: | target_source | = | "ic" |
Reference-state source. |
|
| real(kind=wp), | public, | allocatable | :: | u_ref(:,:,:) |
Reference x-velocity, shape |
||
| real(kind=wp), | public, | allocatable | :: | v_ref(:,:,:) |
Reference y-velocity, shape |
||
| real(kind=wp), | public, | allocatable | :: | z_top(:,:) |
Geopotential DEPTH of the top of the water column (m, positive
down), shape |
Counted allocatable footprint (0 when enable=.false. — every
array is unallocated then). tools/check_bytes_accounting.py
reconciles this against the measured device mapping.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_sponge_t), | intent(in) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_sponge_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; copied verbatim from
rdb_ocean_surface_flux.F90).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_sponge_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_sponge_t), | intent(inout) | :: | this |
Allocate the maps + reference-state arrays. Call ONLY when
this%enable (the gated-closure convention, mirroring
epbl/kshear/…) — the caller sets enable before calling, and
ocean_state_init only reaches this when this%enable is
.true. (see rdb_ocean_state.F90). ref_tracer is sized at
max(n_tracers, 1) so an as-yet-empty tracer registry never
trips a zero-extent allocate.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_sponge_t), | intent(inout) | :: | this | |||
| type(hgrid_t), | intent(in) | :: | grid | |||
| integer, | intent(in) | :: | nz_ml | |||
| integer, | intent(in) | :: | n_tracers |
type :: ocean_sponge_t !! Map-driven sponge state: per-cell `Idamp` [1/s] + a 3-D reference !! state. See the module docstring for the physics + the MOM6 !! divergences. Value-semantics slot (no `CS` pointer, no !! `associated(CS)` guards) per `src/core/ocean/README.md`. logical :: is_init = .false. !! True once `init` has run (only called when `enable`, mirroring !! the gated-closure convention — epbl/kshear/... — so a disabled !! sponge never allocates the (potentially large) `ref_tracer`). logical :: enable = .false. !! Master switch. Default `.false.` ⇒ the legacy band kernels run !! unchanged ⇒ existing nmls + tests are bit-identical. logical :: relax_uv = .true. !! Relax `u_face_x_layer`/`v_face_y_layer` toward `u_ref`/`v_ref`. !! Default `.true.` matches the legacy path (momentum is the one !! thing today's sponge always damps); MOM6's `SPONGE_UV` defaults !! `.false.` — a deliberate divergence to preserve legacy parity. logical :: relax_tracers = .true. !! Relax every registered tracer's concentration toward !! `ref_tracer`. logical :: relax_h = .false. !! Interior-interface thickness damping. NOT IMPLEMENTED in PR-23 !! v1 (deferred to PR-23b alongside the file-backed targets — !! `docs/plans/PLAN_PR23_real_sponge.md` §14 Q1); `enable=.true., !! relax_h=.true.` aborts fail-loud at `validate_config`. character(len=16) :: damp_source = "band" !! How `idamp_h`/`idamp_u`/`idamp_v` are filled. `"band"` (only !! value implemented in v1): cosine ramp from every !! `bc%<edge>%bc_type == OBC_SPONGE` edge tag, summed at overlaps !! (§3.2 of the plan). `"file"` recognised but aborts at !! `validate_config` (PR-23b, needs the PR-14 reader). character(len=16) :: target_source = "ic" !! Reference-state source. `"ic"`: !! `ocean_sponge_snapshot_reference` copies the seeded initial !! condition. `"linear_z"`: the analytic affine geopotential !! profile below, re-evaluated on the LIVE layer geometry by !! `ocean_sponge_refresh_target` once per outer step — see that !! routine's docstring for why re-evaluated rather than frozen. !! `"file"` recognised but aborts at `validate_config` (PR-23b). real(wp) :: lin_t_ref = 0.0_wp !! `target_source="linear_z"`: T (degC) at the `z = 0` datum. real(wp) :: lin_dt_dz = 0.0_wp !! `target_source="linear_z"`: dT/dz (degC/m), **z positive UP**. real(wp) :: lin_s_ref = 35.0_wp !! `target_source="linear_z"`: S (PSU) at the `z = 0` datum. real(wp) :: lin_ds_dz = 0.0_wp !! `target_source="linear_z"`: dS/dz (PSU/m), z positive UP. integer :: idx_t = 0 !! Tracer-registry index of temperature, latched at configure so !! the per-step refresh needs no registry walk (and no !! array-of-derived-types device indirection). `0` = not !! registered ⇒ the temperature refresh is skipped. integer :: idx_s = 0 !! Tracer-registry index of salinity; see `idx_t`. integer :: n_tracers = 0 !! Registered tracer count — sizes `ref_tracer`'s 4th dimension. real(wp), allocatable :: idamp_h(:, :) !! Inverse damping time for tracers + (deferred) thickness, 1/s, !! shape `(nx_total, ny_total)`. Zero outside the sponge and in !! every ghost cell — `Idamp = 0` IS the sponge mask (no separate !! width/extent bookkeeping). real(wp), allocatable :: idamp_u(:, :) !! Inverse damping time for `u_face_x_layer`, 1/s, shape !! `(nx_total+1, ny_total)` (matches the u-face stagger). real(wp), allocatable :: idamp_v(:, :) !! Inverse damping time for `v_face_y_layer`, 1/s, shape !! `(nx_total, ny_total+1)` (matches the v-face stagger). real(wp), allocatable :: ref_tracer(:, :, :, :) !! Reference tracer CONCENTRATION (not `hTr`) — PSU, degC, ... per !! the registered tracer's own units — shape `(nx_total, ny_total, !! nz, n_tracers)`, indexed by the multilayer tracer-registry !! index (matches `ms%idx_salinity` / `ms%idx_temperature`). real(wp), allocatable :: u_ref(:, :, :) !! Reference x-velocity, shape `(nx_total+1, ny_total, nz)` — !! matches `ms%u_face_x_layer`. real(wp), allocatable :: v_ref(:, :, :) !! Reference y-velocity, shape `(nx_total, ny_total+1, nz)` — !! matches `ms%v_face_y_layer`. real(wp), allocatable :: z_top(:, :) !! Geopotential DEPTH of the top of the water column (m, positive !! down), shape `(nx_total, ny_total)`. `0` in the open ocean (the !! free-surface datum), `metrics%z_draft(i,j)` under an ice shelf. !! Latched ONCE at configure — the draft is static by design — so !! the per-step `linear_z` refresh is self-contained and the !! sponge slot never has to reach into `ocean_metrics_t`. Same !! role `z_top` plays in `rdb_ocean_z_init::build_z_ctr`; without !! it a geopotential target would land `z_draft` metres too !! shallow on every shelf column and tilt with the ice base. contains procedure, non_overridable :: init => ocean_sponge_init procedure, non_overridable :: destroy => ocean_sponge_destroy procedure, non_overridable :: enter_data => ocean_sponge_enter_data procedure, non_overridable :: exit_data => ocean_sponge_exit_data procedure, non_overridable :: bytes => ocean_sponge_bytes end type ocean_sponge_t