ocean_pgf_config_t Derived Type

type, public :: ocean_pgf_config_t


Inherited by

type~~ocean_pgf_config_t~~InheritedByGraph type~ocean_pgf_config_t ocean_pgf_config_t type~ocean_config_t ocean_config_t type~ocean_config_t->type~ocean_pgf_config_t pgf type~config_t config_t type~config_t->type~ocean_config_t ocean type~ocean_handle_t ocean_handle_t type~ocean_handle_t->type~config_t cfg

Components

Type Visibility Attributes Name Initial
real(kind=wp), public :: cfl_trunc = 0.0_wp

Advective-CFL velocity truncation threshold (nondimensional). When > 0, faces with |u|·dt/dx > cfl_trunc are clipped to 0.9·cfl_trunc·dx/dt (runs before the maxvel cap). Default 0.0 = disabled (bit-identical).

character(len=16), public :: form = "mont"

Pressure-gradient kernel variant. “mont” (default) is the Boussinesq Montgomery-potential form — general purpose (valid over sloping bathymetry and every vcoord), algebraically identical to “fv_lite” on columns of equal layer thickness, and exact at rest in isopycnal columns; it is also the cheapest, since it builds no pressure stack. “fv_lite” and “fv_wright” are the FV sigma-aware kernels. “fv_lite” carries the SAME physics content as “mont” (layer-mean rho, no in-layer quadrature) and differs from it only where layer thicknesses are UNEQUAL across a face — there the two are different discretisations of the same term, neither exact. “gprime” is the reduced-gravity layered PGF (NK = 2 only). “fv_mom6” is the faithful FV-Bouss port (used by gfs_scale).

real(kind=wp), public :: gfs_scale = 1.0_wp

Free-surface gravity scaling for the FV_MOM6 PGF. Default 1.0 = no reduction. When < 1, applies a Montgomery dM correction and evolves η at the reduced gravity. Active only under form = "fv_mom6".

real(kind=wp), public :: gprime_gfs = 9.81_wp

Free-surface gravity (m/s²) for the gprime PGF.

real(kind=wp), public :: gprime_gint = 0.0098_wp

Internal-interface reduced gravity (m/s²) for the gprime PGF.

logical, public :: insitu_density = .true.

FV_MOM6 constant-by-layer (PCM) density at its IN-SITU pressure p = -g*rho0*z (MOM6 int_density_dz_generic_pcm; MOM6 parity, default). .false. = the legacy integral of the POTENTIAL density ms%rho_layer at the uniform &ocean_eos_nml p_ref, which loses the pressure dependence of the horizontal density gradient away from p_ref (on the global 1-degree spin-up: Drake Passage ~80 Sv against MOM6’s ~155 Sv). Consulted only by form = "fv_mom6" with reconstruct_for_pressure = .false. and a PRESSURE-DEPENDENT EOS (wright, roquet_spv); for linear in-situ and potential density coincide and the legacy path runs, bit-identical.

Cost (global 1-degree, 5 days, one V100; .false.: ocean_pgf 1.09 s, time loop 54.2 s): * wright — the layer integral is ANALYTIC (MOM6 int_density_dz_wright): one polynomial evaluation per layer and per cross-face sub-column. ocean_pgf 1.86 s, time loop 55.0 s (+1.5 %). * roquet_spv — no closed form (the integrand 1/SV(p) is rational in depth); the 5-point Boole rule of MOM6 int_density_dz_generic_pcm, with the (T, S) part of the EOS evaluated ONCE per sub-column (roquet_pcm_dpa_intz, the SpV value inlined from rdb_roquet_spv.inc) and only the pressure Horner per Boole point. ocean_pgf 2.55 s (was 10.73 s, then 3.64 s with the (T, S) part an out-of-line call), time loop 55.8 s (+3 %, was 63.9 s): 1.36x Wright. Both run their integrals one GPU thread per CELL, not per column.

logical, public :: mass_weight = .false.

FV_MOM6 shelf-break mass-weighting. When .true., biases the layer density in the horizontal pressure integral toward the thinner column at unequal-depth faces, cancelling the spurious bottom-layer PGF. Reduces to bit-identical on aligned columns. Default .false.. Active only under form = "fv_mom6".

real(kind=wp), public :: maxvel = 0.0_wp

Velocity-truncation clamp (m/s): u = sign(u)·min(|u|, maxvel) after each outer dyn step. Default 0 = disabled.

logical, public :: p_top_in_bc = .false.

Add the top-of-column load multilayer_state_t%p_top (Pa) to the FV_MOM6 pressure-stack surface boundary condition: pa(nz+1) = rho_ref*g*eta_geo + p_top. Default .false. => pa(nz+1) = rho_ref*g*eta_geo, bit-identical to every run before this knob existed.

WHY IT IS NOT A DOUBLE COUNT. A depth-uniform p_top perturbs EVERY layer’s PFu by the same -(1/rho_0)*grad p_top (the theorem in compute_fv_mom6_impl’s docstring). Under the MOM6 split (&ocean_bt_nml bc_pgf_forcing, default) the depth mean of the layer PGF forces the barotropic mode, so the p_surf part of p_top is shed from that forcing as g*grad(eta_ib) and the eta_forcing seam carries it once; the static p_ice_ref part cancels inside pa(nz+1) against the datum-shifted eta_geo. (The legacy split subtracted the whole depth mean, so there the uniform piece cancelled identically.) On the UNSPLIT driver (n_inner = 0) there is no seam, so this term is the load’s ONLY path into the momentum.

What it buys where the load is LARGE (an ice-shelf draft, 5e6 Pa): pa is built as an anomaly about rho_ref*g*z, and with the load cancelled inside pa(nz+1) against rho_ref*g*eta_geo the whole stack stays O(1e4 Pa) instead of O(5e6 Pa), which shrinks the h_neglect face-divisor leak by the same factor.

FV_MOM6 ONLY (both the PCM and the reconstruct_for_pressure branch) — validate_config refuses it for any other form, which carries no pa stack to inject into. Orthogonal to &ocean_psurf_nml in_eos: that knob puts the same p_top into the EOS’s IN-SITU pressure ARGUMENTS, this one into the PGF’s pressure BOUNDARY CONDITION. Either, both or neither. p_top itself is produced today only by the &ocean_psurf_nml seam, so with enable = .false. it is the zero array and this knob is inert — a warning says so rather than leaving it silent.

integer, public :: recon_scheme = 1

In-layer reconstruction scheme: 1 = PLM, 2 = PPM. Mirrors MOM6 Recon_Scheme. Only consulted when reconstruct_for_pressure = .true..

logical, public :: reconstruct_for_pressure = .false.

FV_MOM6 in-layer T/S reconstruction (Adcroft, Hallberg & Harrison 2008; White, Adcroft & Hallberg 2009). .false. (default) uses layer-mean (PCM) density ⇒ bit-identical. .true. builds each layer’s pressure anomaly via a 5-point Boole quadrature of a monotone PLM/PPM T/S profile. Active only under form = "fv_mom6" (fail-loud at configure otherwise).

Cost: 5 EOS evaluations per layer + 15 per face per layer (T and S vary through the layer, so no closed form and no hoisting), each inlined into a kernel that runs one GPU thread per CELL (edges, layer and face integrals alike). Global 1-degree PPM, 5 days, one V100: ocean_pgf 3.5 s under wright (was 13.7 s, then 6.0 s), 6.6 s under roquet_spv (was 14.6 s, then 12.4 s) — against 1.9 / 2.5 s for the PCM in-situ default.


Source Code

   type :: ocean_pgf_config_t
      character(len=16) :: form = "mont"
         !! Pressure-gradient kernel variant.  "mont" (default) is the
         !! Boussinesq Montgomery-potential form — general purpose (valid over
         !! sloping bathymetry and every vcoord), algebraically identical to
         !! "fv_lite" on columns of equal layer thickness, and exact at rest in
         !! isopycnal columns; it is also the cheapest, since it builds no
         !! pressure stack.  "fv_lite" and "fv_wright" are the FV sigma-aware
         !! kernels.  "fv_lite" carries the SAME physics content as "mont"
         !! (layer-mean rho, no in-layer quadrature) and differs from it only
         !! where layer thicknesses are UNEQUAL across a face — there the two
         !! are different discretisations of the same term, neither exact.
         !! "gprime" is the reduced-gravity layered PGF (NK = 2 only).
         !! "fv_mom6" is the faithful FV-Bouss port (used by `gfs_scale`).
      real(wp) :: gprime_gfs = 9.81_wp
         !! Free-surface gravity (m/s²) for the gprime PGF.
      real(wp) :: gprime_gint = 0.0098_wp
         !! Internal-interface reduced gravity (m/s²) for the gprime PGF.
      real(wp) :: gfs_scale = 1.0_wp
         !! Free-surface gravity scaling for the FV_MOM6 PGF.  Default 1.0
         !! = no reduction.  When < 1, applies a Montgomery `dM` correction
         !! and evolves η at the reduced gravity.  Active only under
         !! `form = "fv_mom6"`.
      real(wp) :: maxvel = 0.0_wp
         !! Velocity-truncation clamp (m/s): `u = sign(u)·min(|u|, maxvel)`
         !! after each outer dyn step.  Default 0 = disabled.
      real(wp) :: cfl_trunc = 0.0_wp
         !! Advective-CFL velocity truncation threshold (nondimensional).
         !! When > 0, faces with `|u|·dt/dx > cfl_trunc` are clipped to
         !! `0.9·cfl_trunc·dx/dt` (runs before the `maxvel` cap).  Default
         !! 0.0 = disabled (bit-identical).
      logical :: mass_weight = .false.
         !! FV_MOM6 shelf-break mass-weighting.  When `.true.`, biases the
         !! layer density in the horizontal pressure integral toward the
         !! thinner column at unequal-depth faces, cancelling the spurious
         !! bottom-layer PGF.  Reduces to bit-identical on aligned columns.
         !! Default `.false.`.  Active only under `form = "fv_mom6"`.
      logical :: reconstruct_for_pressure = .false.
         !! FV_MOM6 in-layer T/S reconstruction (Adcroft, Hallberg &
         !! Harrison 2008; White, Adcroft & Hallberg 2009).  `.false.`
         !! (default) uses layer-mean (PCM) density ⇒ bit-identical.
         !! `.true.` builds each layer's pressure anomaly via a 5-point
         !! Boole quadrature of a monotone PLM/PPM T/S profile.  Active only
         !! under `form = "fv_mom6"` (fail-loud at configure otherwise).
         !!
         !! Cost: 5 EOS evaluations per layer + 15 per face per layer (T and
         !! S vary through the layer, so no closed form and no hoisting),
         !! each inlined into a kernel that runs one GPU thread per CELL
         !! (edges, layer and face integrals alike).  Global 1-degree PPM,
         !! 5 days, one V100: `ocean_pgf` 3.5 s under `wright` (was 13.7 s,
         !! then 6.0 s), 6.6 s under `roquet_spv` (was 14.6 s, then
         !! 12.4 s) — against 1.9 / 2.5 s for the PCM in-situ default.
      integer :: recon_scheme = 1
         !! In-layer reconstruction scheme: 1 = PLM, 2 = PPM.  Mirrors
         !! MOM6 `Recon_Scheme`.  Only consulted when
         !! `reconstruct_for_pressure = .true.`.
      logical :: insitu_density = .true.
         !! FV_MOM6 constant-by-layer (PCM) density at its IN-SITU pressure
         !! `p = -g*rho0*z` (MOM6 `int_density_dz_generic_pcm`; MOM6
         !! parity, default).  `.false.` = the legacy integral of the
         !! POTENTIAL density `ms%rho_layer` at the uniform
         !! `&ocean_eos_nml p_ref`, which loses the pressure dependence of
         !! the horizontal density gradient away from `p_ref` (on the global
         !! 1-degree spin-up: Drake Passage ~80 Sv against MOM6's ~155 Sv).
         !! Consulted only by `form = "fv_mom6"` with
         !! `reconstruct_for_pressure = .false.` and a PRESSURE-DEPENDENT
         !! EOS (`wright`, `roquet_spv`); for `linear` in-situ and
         !! potential density coincide and the legacy path runs,
         !! bit-identical.
         !!
         !! Cost (global 1-degree, 5 days, one V100; `.false.`: `ocean_pgf`
         !! 1.09 s, time loop 54.2 s):
         !!   * `wright` — the layer integral is ANALYTIC (MOM6
         !!     `int_density_dz_wright`): one polynomial evaluation per layer
         !!     and per cross-face sub-column.  `ocean_pgf` 1.86 s, time loop
         !!     55.0 s (+1.5 %).
         !!   * `roquet_spv` — no closed form (the integrand `1/SV(p)` is
         !!     rational in depth); the 5-point Boole rule of MOM6
         !!     `int_density_dz_generic_pcm`, with the (T, S) part of the EOS
         !!     evaluated ONCE per sub-column (`roquet_pcm_dpa_intz`, the SpV
         !!     value inlined from `rdb_roquet_spv.inc`) and only the
         !!     pressure Horner per Boole point.  `ocean_pgf` 2.55 s (was
         !!     10.73 s, then 3.64 s with the (T, S) part an out-of-line
         !!     call), time loop 55.8 s (+3 %, was 63.9 s): 1.36x Wright.
         !! Both run their integrals one GPU thread per CELL, not per column.
      logical :: p_top_in_bc = .false.
         !! Add the top-of-column load `multilayer_state_t%p_top` (Pa) to
         !! the FV_MOM6 pressure-stack surface boundary condition:
         !! `pa(nz+1) = rho_ref*g*eta_geo + p_top`.  Default `.false.` =>
         !! `pa(nz+1) = rho_ref*g*eta_geo`, bit-identical to every run
         !! before this knob existed.
         !!
         !! WHY IT IS NOT A DOUBLE COUNT.  A depth-uniform `p_top`
         !! perturbs EVERY layer's `PFu` by the same `-(1/rho_0)*grad
         !! p_top` (the theorem in `compute_fv_mom6_impl`'s docstring).
         !! Under the MOM6 split (`&ocean_bt_nml bc_pgf_forcing`,
         !! default) the depth mean of the layer PGF forces the barotropic
         !! mode, so the `p_surf` part of `p_top` is shed from that
         !! forcing as `g*grad(eta_ib)` and the `eta_forcing` seam carries
         !! it once; the static `p_ice_ref` part cancels inside `pa(nz+1)`
         !! against the datum-shifted `eta_geo`.  (The legacy split
         !! subtracted the whole depth mean, so there the uniform piece
         !! cancelled identically.)  On the UNSPLIT driver (`n_inner = 0`)
         !! there is no seam, so this term is the load's ONLY path into
         !! the momentum.
         !!
         !! What it buys where the load is LARGE (an ice-shelf draft,
         !! `5e6 Pa`): `pa` is built as an anomaly about `rho_ref*g*z`,
         !! and with the load cancelled inside `pa(nz+1)` against
         !! `rho_ref*g*eta_geo` the whole stack stays `O(1e4 Pa)` instead
         !! of `O(5e6 Pa)`, which shrinks the `h_neglect` face-divisor
         !! leak by the same factor.
         !!
         !! FV_MOM6 ONLY (both the PCM and the `reconstruct_for_pressure`
         !! branch) — `validate_config` refuses it for any other `form`,
         !! which carries no `pa` stack to inject into.  Orthogonal to
         !! `&ocean_psurf_nml in_eos`: that knob puts the same `p_top`
         !! into the EOS's IN-SITU pressure ARGUMENTS, this one into the
         !! PGF's pressure BOUNDARY CONDITION.  Either, both or neither.
         !! `p_top` itself is produced today only by the `&ocean_psurf_nml`
         !! seam, so with `enable = .false.` it is the zero array and this
         !! knob is inert — a warning says so rather than leaving it
         !! silent.
   end type ocean_pgf_config_t