Surface-pressure loading for the ocean C-grid dyn-core (PR-17). An
atmospheric surface pressure p_surf(x,y) (Pa) adds a depth-uniform
acceleration -(1/rho0) grad(p_surf) to the horizontal momentum
(Wunsch & Stammer 1997). Because the term is depth-independent it is
a purely BAROTROPIC forcing: it drives the free surface and, at rest,
integrates to the equilibrium inverse-barometer response
eta_ib = -p_surf/(rho0 g) + const (~1 cm depression per hPa of
atmospheric high; Ponte 2006 for the closed-domain mean removal).
It lands on the SAME eta_forcing seam the equilibrium body tide and
scalar SAL compose through: the barotropic substep drives
-g grad(eta - eta_forcing), so folding
eta_ib = -p_surf/(rho0 g_bt) into the seam gives the momentum an
extra -g grad(eta) - (1/rho0) grad(p_surf) exactly. eta_ib and the
combined seam field eta_seam = eta_ib [+ eta_tide] are cell-centred
2-D fields in metres, differenced on the identical two-point stencil
the SSH uses, so the discrete inverse-barometer balance
eta = eta_ib + const is an exact discrete steady state.
Sign: eta_ib = -p_surf/(rho0 g) — a high depresses the surface, a low
bulges it. Gravity is bt_work%g_bt (what the barotropic substep that
consumes the seam actually runs on), NOT rdb_constants:GRAVITY; the
caller passes it in so eta_ib scales with the ocean’s own dynamics.
p_surf (the assembled total, Pa, >= 0) is consumed read-only from
the surface-forcing type (ocean_surface_flux_t) — this module adds no
forcing field of its own, and does not write p_surf (the dyn step
holds sf intent(in)). With no ice mass-loading the assembly
p_surf = p_surf_atm is a configure-time seed (set_p_surf_const
fills both) since p_surf_atm is static; when sea-ice loading lands
(PR-18) its ice_ocean_mass_load overwrites p_surf = p_surf_atm +
g_load*mis via its own inout access earlier in the same outer step,
and this module reads whatever p_surf then holds. Adcroft et al.
(2019) levitating surface-load convention.
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| logical, | public | :: | enable | = | .false. |
Master switch (default off => bit-identical). |
|
| real(kind=wp), | public, | allocatable | :: | eta_ib(:,:) |
(nx,ny) inverse-barometer elevation |
||
| real(kind=wp), | public, | allocatable | :: | eta_seam(:,:) |
(nx,ny) combined seam field |
||
| logical, | public | :: | in_eos | = | .false. |
Also hand the assembled |
|
| logical, | public | :: | is_init | = | .false. |
True between |
|
| real(kind=wp), | public | :: | rho0 | = | 1035.0_wp |
Boussinesq reference density (kg/m^3). Assigned from
|
| procedure, public, non_overridable :: bytes => ocean_p_surf_bytes | |
| procedure, public, non_overridable :: destroy => ocean_p_surf_destroy | |
| procedure, public, non_overridable :: enter_data => ocean_p_surf_enter_data | |
| procedure, public, non_overridable :: exit_data => ocean_p_surf_exit_data | |
| procedure, public, non_overridable :: init => ocean_p_surf_init |
Counted allocatable footprint of the p_surf 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_p_surf_t), | intent(in) | :: | this |
Allocate eta_ib/eta_seam (host, before enter_data). No-op when
.not. enable (bit-identical; zero extra device memory). Mirrors
tides_configure_astronomy.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_p_surf_t), | intent(inout) | :: | this | |||
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny |
Refresh the combined seam field eta_seam for the current outer
step from the assembled total surface pressure p_surf (read-only;
see the module header for where the assembly happens): fold
eta_ib = -p_surf/(rho0 g_bt) into eta_seam = eta_ib [+ eta_tide].
g_bt is the barotropic-substep gravity (bt_work%g_bt), passed in
at call time so the seam scales with the ocean’s own dynamics.
eta_tide (optional) is the equilibrium-tide + scalar-SAL seam,
added when the tide is on. Host does one reciprocal; the fill is a
single explicit-shape do concurrent. p_surf is the
device-resident ocean_surface_flux_t%p_surf component array.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_p_surf_t), | intent(inout) | :: | this | |||
| real(kind=wp), | intent(in) | :: | p_surf(:,:) | |||
| real(kind=wp), | intent(in) | :: | g_bt | |||
| real(kind=wp), | intent(in), | optional | :: | eta_tide(:,:) |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_p_surf_t), | intent(inout) | :: | this |
Attach the device-resident seam arrays. Only when enabled.
select-type -> non-poly _impl (AMD libomptarget class-box rule).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_p_surf_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_p_surf_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_p_surf_t), | intent(inout) | :: | this |
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(ocean_p_surf_t), | intent(inout) | :: | this |
Minimal init — the real allocation happens in p_surf_configure
once the namelist is available (host, before enter_data).
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(ocean_p_surf_t), | intent(inout) | :: | this | |||
| type(hgrid_t), | intent(in) | :: | grid |
Flat-impl device fill (explicit-shape dummies — no descriptor walk).
eta_ib(i,j) = -p_surf(i,j)*i_rho0_g and
eta_seam(i,j) = eta_ib(i,j) [+ eta_tide(i,j)]. Loop-invariant
use_tide branch kept INSIDE the single do concurrent (one
launch, uniform branch is ~free). Contiguous index (i) innermost.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | nx | |||
| integer, | intent(in) | :: | ny | |||
| real(kind=wp), | intent(in) | :: | i_rho0_g | |||
| real(kind=wp), | intent(in) | :: | p_surf(nx,ny) | |||
| real(kind=wp), | intent(out) | :: | eta_ib(nx,ny) | |||
| real(kind=wp), | intent(out) | :: | eta_seam(nx,ny) | |||
| logical, | intent(in) | :: | use_tide | |||
| real(kind=wp), | intent(in), | optional | :: | eta_tide(nx,ny) |