Variant dispatch on bare 3D arrays — the state-agnostic body of
ocean_eos_compute (the shim hosted in
rdb_ocean_eos_compute), which forwards the multilayer state’s
registry arrays here. Kept free of state-type dependencies so
the dispatch stays callable from a bare array context. All impls
evaluate at the SINGLE, HORIZONTALLY UNIFORM reference pressure
eos%p_ref (&ocean_eos_nml p_ref, default 0 ⇒ surface/potential
density) with the H_VANISHED vanishing-layer fallback to
eos%rho0.
rho_layer is a POTENTIAL density and its reference pressure
MUST stay horizontally uniform. Its consumers difference it
ALONG a layer (the Montgomery PGF’s rho_layer(i) −
rho_layer(i−1), the FV-lite / FV-MOM6-PCM integrands) and
VERTICALLY (the vmix N² builders). A reference pressure that
varied with (i,j) — e.g. one carrying a sloping ice-shelf load —
would give two columns of IDENTICAL water at the same geopotential
depth densities differing by ∂ρ/∂p · Δp_top (≈ 4.5e-7 × 5e6 ≈
2 kg/m³ across a calving front), i.e. a large, entirely spurious
along-layer density gradient and therefore a spurious PGF. The
surface load belongs in the IN-SITU pressure builders instead
(&ocean_psurf_nml in_eos → multilayer_state_t%p_top, consumed
by eos_wright_pgf_column_sweep_impl), never here.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(eos_t), | intent(in) | :: | eos | |||
| real(kind=wp), | intent(in) | :: | h_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hS_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(in) | :: | hT_layer(nx,ny,nz) | |||
| real(kind=wp), | intent(out) | :: | rho_layer(nx,ny,nz) | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| integer, | intent(in) | :: | nz |
subroutine eos_compute_arrays(eos, h_layer, hS_layer, hT_layer, & rho_layer, nx, ny, nz) !! Variant dispatch on bare 3D arrays — the state-agnostic body of !! `ocean_eos_compute` (the shim hosted in !! `rdb_ocean_eos_compute`), which forwards the multilayer state's !! registry arrays here. Kept free of state-type dependencies so !! the dispatch stays callable from a bare array context. All impls !! evaluate at the SINGLE, HORIZONTALLY UNIFORM reference pressure !! `eos%p_ref` (`&ocean_eos_nml p_ref`, default 0 ⇒ surface/potential !! density) with the `H_VANISHED` vanishing-layer fallback to !! `eos%rho0`. !! !! **`rho_layer` is a POTENTIAL density and its reference pressure !! MUST stay horizontally uniform.** Its consumers difference it !! ALONG a layer (the Montgomery PGF's `rho_layer(i) − !! rho_layer(i−1)`, the FV-lite / FV-MOM6-PCM integrands) and !! VERTICALLY (the vmix N² builders). A reference pressure that !! varied with `(i,j)` — e.g. one carrying a sloping ice-shelf load — !! would give two columns of IDENTICAL water at the same geopotential !! depth densities differing by `∂ρ/∂p · Δp_top` (≈ 4.5e-7 × 5e6 ≈ !! 2 kg/m³ across a calving front), i.e. a large, entirely spurious !! along-layer density gradient and therefore a spurious PGF. The !! surface load belongs in the IN-SITU pressure builders instead !! (`&ocean_psurf_nml in_eos` → `multilayer_state_t%p_top`, consumed !! by `eos_wright_pgf_column_sweep_impl`), never here. type(eos_t), intent(in) :: eos integer, intent(in) :: nx, ny, nz real(wp), intent(in) :: h_layer(nx, ny, nz) real(wp), intent(in) :: hS_layer(nx, ny, nz) real(wp), intent(in) :: hT_layer(nx, ny, nz) real(wp), intent(out) :: rho_layer(nx, ny, nz) select case (eos%variant) case (EOS_VARIANT_LINEAR) call eos_linear_impl(h_layer, hS_layer, hT_layer, rho_layer, & eos%rho0, eos%beta_S, eos%S_ref, & eos%alpha_T, eos%T_ref, & nx, ny, nz) case (EOS_VARIANT_WRIGHT_97) call eos_wright_impl(h_layer, hS_layer, hT_layer, rho_layer, & eos%rho0, eos%p_ref, & nx, ny, nz) case (EOS_VARIANT_ROQUET_SPV) call eos_roquet_spv_impl(h_layer, hS_layer, hT_layer, rho_layer, & eos%rho0, eos%p_ref, & nx, ny, nz) case default error stop "eos_compute_arrays: unknown eos%variant" end select end subroutine eos_compute_arrays