rdb_barotropic_coupling Module


Uses

  • module~~rdb_barotropic_coupling~~UsesGraph module~rdb_barotropic_coupling rdb_barotropic_coupling ieee_arithmetic ieee_arithmetic module~rdb_barotropic_coupling->ieee_arithmetic module~rdb_barotropic_workstate rdb_barotropic_workstate module~rdb_barotropic_coupling->module~rdb_barotropic_workstate module~rdb_constants rdb_constants module~rdb_barotropic_coupling->module~rdb_constants module~rdb_coriolis_adv rdb_coriolis_adv module~rdb_barotropic_coupling->module~rdb_coriolis_adv module~rdb_grid rdb_grid module~rdb_barotropic_coupling->module~rdb_grid module~rdb_multilayer_state rdb_multilayer_state module~rdb_barotropic_coupling->module~rdb_multilayer_state module~rdb_ocean_bottom_drag rdb_ocean_bottom_drag module~rdb_barotropic_coupling->module~rdb_ocean_bottom_drag module~rdb_ocean_boundary_types rdb_ocean_boundary_types module~rdb_barotropic_coupling->module~rdb_ocean_boundary_types module~rdb_ocean_horizontal_viscosity rdb_ocean_horizontal_viscosity module~rdb_barotropic_coupling->module~rdb_ocean_horizontal_viscosity module~rdb_ocean_metrics rdb_ocean_metrics module~rdb_barotropic_coupling->module~rdb_ocean_metrics module~rdb_ocean_pressure_force rdb_ocean_pressure_force module~rdb_barotropic_coupling->module~rdb_ocean_pressure_force module~rdb_ocean_surface_stress rdb_ocean_surface_stress module~rdb_barotropic_coupling->module~rdb_ocean_surface_stress module~rdb_ocean_top_drag rdb_ocean_top_drag module~rdb_barotropic_coupling->module~rdb_ocean_top_drag module~rdb_barotropic_workstate->module~rdb_constants module~rdb_barotropic_workstate->module~rdb_grid iso_fortran_env iso_fortran_env module~rdb_barotropic_workstate->iso_fortran_env module~rdb_mem_report rdb_mem_report module~rdb_barotropic_workstate->module~rdb_mem_report pic_types pic_types module~rdb_constants->pic_types module~rdb_coriolis_adv->module~rdb_constants module~rdb_coriolis_adv->module~rdb_grid module~rdb_coriolis_adv->module~rdb_multilayer_state module~rdb_coriolis_adv->module~rdb_ocean_metrics module~rdb_coriolis_adv->iso_fortran_env module~rdb_barotropic_state rdb_barotropic_state module~rdb_coriolis_adv->module~rdb_barotropic_state module~rdb_coriolis_adv->module~rdb_mem_report module~rdb_ocean_porous rdb_ocean_porous module~rdb_coriolis_adv->module~rdb_ocean_porous module~rdb_scratch_3d rdb_scratch_3d module~rdb_coriolis_adv->module~rdb_scratch_3d module~rdb_grid->module~rdb_constants module~rdb_multilayer_state->module~rdb_constants module~rdb_multilayer_state->module~rdb_grid module~rdb_multilayer_state->iso_fortran_env module~rdb_efp rdb_efp module~rdb_multilayer_state->module~rdb_efp module~rdb_error_ring rdb_error_ring module~rdb_multilayer_state->module~rdb_error_ring module~rdb_multilayer_state->module~rdb_mem_report module~rdb_tracer rdb_tracer module~rdb_multilayer_state->module~rdb_tracer pic_logger pic_logger module~rdb_multilayer_state->pic_logger module~rdb_ocean_bottom_drag->module~rdb_constants module~rdb_ocean_bottom_drag->module~rdb_grid module~rdb_ocean_bottom_drag->module~rdb_multilayer_state module~rdb_ocean_bottom_drag->module~rdb_ocean_metrics module~rdb_ocean_bottom_drag->iso_fortran_env module~rdb_ocean_bottom_drag->module~rdb_mem_report module~rdb_ocean_bottom_drag->module~rdb_scratch_3d module~rdb_ocean_boundary_types->module~rdb_constants module~rdb_ocean_boundary_types->module~rdb_grid module~rdb_ocean_boundary_types->iso_fortran_env module~rdb_ocean_boundary_types->module~rdb_mem_report module~rdb_ocean_status rdb_ocean_status module~rdb_ocean_boundary_types->module~rdb_ocean_status module~rdb_ocean_tide_astro rdb_ocean_tide_astro module~rdb_ocean_boundary_types->module~rdb_ocean_tide_astro pic_ascii pic_ascii module~rdb_ocean_boundary_types->pic_ascii module~rdb_ocean_boundary_types->pic_logger module~rdb_ocean_horizontal_viscosity->module~rdb_constants module~rdb_ocean_horizontal_viscosity->module~rdb_grid module~rdb_ocean_horizontal_viscosity->module~rdb_multilayer_state module~rdb_ocean_horizontal_viscosity->module~rdb_ocean_metrics module~rdb_ocean_horizontal_viscosity->iso_fortran_env module~rdb_ocean_horizontal_viscosity->module~rdb_mem_report module~rdb_ocean_lateral_mix rdb_ocean_lateral_mix module~rdb_ocean_horizontal_viscosity->module~rdb_ocean_lateral_mix module~rdb_ocean_horizontal_viscosity->module~rdb_scratch_3d module~rdb_ocean_metrics->module~rdb_constants module~rdb_ocean_metrics->module~rdb_grid module~rdb_ocean_metrics->iso_fortran_env module~rdb_ocean_metrics->module~rdb_error_ring module~rdb_io_netcdf rdb_io_netcdf module~rdb_ocean_metrics->module~rdb_io_netcdf module~rdb_ocean_metrics->module~rdb_mem_report module~rdb_ocean_bipolar rdb_ocean_bipolar module~rdb_ocean_metrics->module~rdb_ocean_bipolar module~rdb_ocean_fold rdb_ocean_fold module~rdb_ocean_metrics->module~rdb_ocean_fold module~rdb_ocean_metrics->module~rdb_ocean_status netcdf netcdf module~rdb_ocean_metrics->netcdf module~rdb_ocean_metrics->pic_logger pic_strings pic_strings module~rdb_ocean_metrics->pic_strings module~rdb_ocean_pressure_force->module~rdb_constants module~rdb_ocean_pressure_force->module~rdb_grid module~rdb_ocean_pressure_force->module~rdb_multilayer_state module~rdb_ocean_pressure_force->module~rdb_ocean_metrics module~rdb_ocean_pressure_force->iso_fortran_env module~rdb_eos rdb_eos module~rdb_ocean_pressure_force->module~rdb_eos module~rdb_ocean_pressure_force->module~rdb_mem_report module~rdb_ocean_pgf_reconstruct rdb_ocean_pgf_reconstruct module~rdb_ocean_pressure_force->module~rdb_ocean_pgf_reconstruct module~rdb_ocean_pressure_force->module~rdb_scratch_3d module~rdb_ocean_surface_stress->module~rdb_constants module~rdb_ocean_surface_stress->module~rdb_grid module~rdb_ocean_surface_stress->module~rdb_multilayer_state module~rdb_ocean_surface_stress->iso_fortran_env module~rdb_ocean_surface_stress->module~rdb_mem_report module~rdb_ocean_surface_stress->module~rdb_scratch_3d module~rdb_ocean_top_drag->module~rdb_constants module~rdb_ocean_top_drag->module~rdb_grid module~rdb_ocean_top_drag->module~rdb_multilayer_state module~rdb_ocean_top_drag->iso_fortran_env module~rdb_ocean_top_drag->module~rdb_mem_report module~rdb_ocean_top_drag->module~rdb_scratch_3d module~rdb_barotropic_state->module~rdb_constants module~rdb_barotropic_state->module~rdb_grid module~rdb_barotropic_state->iso_fortran_env module~rdb_barotropic_state->module~rdb_mem_report module~rdb_efp->ieee_arithmetic module~rdb_efp->iso_fortran_env module~rdb_eos->module~rdb_constants module~rdb_eos->module~rdb_grid module~rdb_error_ring->pic_logger module~rdb_io_netcdf->module~rdb_constants module~rdb_io_netcdf->iso_fortran_env module~rdb_io_netcdf->module~rdb_error_ring module~rdb_io_netcdf->netcdf module~rdb_io_netcdf->pic_logger module~rdb_io_netcdf->pic_strings iso_c_binding iso_c_binding module~rdb_io_netcdf->iso_c_binding module~rdb_mem_report->module~rdb_constants module~rdb_mem_report->iso_fortran_env module~rdb_mem_report->pic_logger module~rdb_mem_report->pic_strings module~rdb_ocean_bipolar->module~rdb_constants module~rdb_ocean_fold->module~rdb_constants module~rdb_ocean_lateral_mix->module~rdb_constants module~rdb_ocean_lateral_mix->module~rdb_grid module~rdb_ocean_lateral_mix->module~rdb_multilayer_state module~rdb_ocean_lateral_mix->module~rdb_ocean_metrics module~rdb_ocean_lateral_mix->iso_fortran_env module~rdb_ocean_lateral_mix->module~rdb_mem_report module~rdb_ocean_lateral_mix->module~rdb_scratch_3d module~rdb_ocean_pgf_reconstruct->module~rdb_constants module~rdb_ocean_pgf_reconstruct->module~rdb_eos module~rdb_ocean_porous->ieee_arithmetic module~rdb_ocean_porous->module~rdb_constants module~rdb_ocean_tide_astro->module~rdb_constants module~rdb_ocean_tide_astro->iso_fortran_env module~rdb_scratch_3d->module~rdb_constants module~rdb_scratch_3d->iso_fortran_env module~rdb_scratch_3d->module~rdb_mem_report module~rdb_tracer->module~rdb_constants module~rdb_tracer->module~rdb_grid module~rdb_tracer->iso_fortran_env module~rdb_tracer->module~rdb_mem_report

Used by

  • module~~rdb_barotropic_coupling~~UsedByGraph module~rdb_barotropic_coupling rdb_barotropic_coupling module~rdb_ocean_dyn rdb_ocean_dyn module~rdb_ocean_dyn->module~rdb_barotropic_coupling module~rdb_driver rdb_driver module~rdb_driver->module~rdb_ocean_dyn module~rdb_ocean_engine rdb_ocean_engine module~rdb_driver->module~rdb_ocean_engine module~rdb_ocean_state rdb_ocean_state module~rdb_driver->module~rdb_ocean_state module~rdb_ocean_api rdb_ocean_api module~rdb_ocean_api->module~rdb_ocean_dyn module~rdb_ocean_api->module~rdb_ocean_engine module~rdb_handle rdb_handle module~rdb_ocean_api->module~rdb_handle module~rdb_ocean_diag_derived rdb_ocean_diag_derived module~rdb_ocean_api->module~rdb_ocean_diag_derived module~rdb_ocean_diag_fills rdb_ocean_diag_fills module~rdb_ocean_api->module~rdb_ocean_diag_fills module~rdb_ocean_engine->module~rdb_ocean_dyn module~rdb_ocean_setup rdb_ocean_setup module~rdb_ocean_engine->module~rdb_ocean_setup module~rdb_ocean_engine->module~rdb_ocean_state module~rdb_ocean_engine->module~rdb_ocean_diag_derived module~rdb_ocean_engine->module~rdb_ocean_diag_fills module~rdb_ocean_setup->module~rdb_ocean_dyn module~rdb_ocean_setup->module~rdb_ocean_state module~rdb_ocean_state->module~rdb_ocean_dyn module~rdb_handle->module~rdb_ocean_engine module~rdb_handle->module~rdb_ocean_state module~rdb_ocean_diag_derived->module~rdb_ocean_state module~rdb_ocean_diag_derived->module~rdb_ocean_diag_fills module~rdb_ocean_diag_fills->module~rdb_ocean_state

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private, parameter :: BTC_H_NEGLECT = 1.0e-10_wp
real(kind=wp), private, parameter :: BTC_VOL_CFL = 0.5_wp
real(kind=wp), private, parameter :: VISC_REM_SUBROUNDOFF = 1.0e-30_wp

Functions

public pure function pgf_free_surface_gravity(pgf) result(g_pf)

The gravity of the free-surface term the slow layer PGF CARRIES, i.e. −∂⟨PGF⟩/∂(∇η) for a uniform-density column (m/s²):

Read more…

Arguments

Type IntentOptional Attributes Name
type(ocean_pressure_force_t), intent(in) :: pgf

Return Value real(kind=wp)


Subroutines

public pure subroutine add_top_drag_into_F_slow(bt_work, td, ms)

Add the ice-shelf top-drag tendency into the already-summed slow forcing. Separate from sum_slow_tendencies_into_F_slow (rather than a sixth term in it) for one reason: the top-drag slot is OPTIONAL all the way down the driver chain, and the sum above must stay a single unconditional kernel with no present branch inside its do concurrent.

Read more…

Arguments

Type IntentOptional Attributes Name
type(barotropic_workstate_t), intent(inout) :: bt_work
type(ocean_top_drag_t), intent(in) :: td
type(multilayer_state_t), intent(in) :: ms

public pure subroutine apply_bt_correction(bt_work, ms, dt, metrics, skip_h_rescale, grid, use_bc_pgf, use_visc_rem, scale, n_nonfin, n_inner)

Replace the bt mode in the per-layer face velocities with the barotropic-substep end-step value, adding Δu·wt_k to every layer, Δu = u_bt_end − u_bt_at_n − dt·F_bt_u (same for v). Split-explicit convention (Hallberg 2009): momentum uses the END-of-step barotropic velocity; layer continuity earlier used the time-mean transports. Both legs of the corrector use the same end-step anchor (mismatched anchors overshoot the gravity-wave phase speed). Also rescales h_layer uniformly so the column total matches H_ref + η_end. hTr is deliberately NOT rescaled (would break exact tracer mass conservation; T = hTr/h drifts by O((η_end−η*_slow)/H) per step).

Read more…

Arguments

Type IntentOptional Attributes Name
type(barotropic_workstate_t), intent(in) :: bt_work
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
type(ocean_metrics_t), intent(in) :: metrics

Curvilinear horizontal metrics — read by the bc-PGF retro-correction (use_bc_pgf = .true. divides the e_anom gradient by idxCu/idyCv), and the carrier of the z-level closed-face mask.

Read more…
logical, intent(in), optional :: skip_h_rescale
type(hgrid_t), intent(in), optional :: grid
logical, intent(in), optional :: use_bc_pgf
logical, intent(in), optional :: use_visc_rem

Weight the fold by visc_rem/⟨visc_rem⟩_h. RETIRED as a live namelist path (&ocean_bt_nml correction_visc_rem is fail-loud at configure, D1 follow-up — MOM6’s accel_layer_u never weights this fold) but the kernel dispatch stays, for its own direct unit tests. Default .false. ⇒ the uniform fold, which visc_rem_chain also uses.

real(kind=wp), intent(in), optional :: scale

Multiplier on the Δu correction (default 1, bit-identical). The pred_corr PREDICTOR passes BE so the provisional velocity is up = u + dt_pred·(u_bc_accel + u_accel_bt) with dt_pred = BE·dt (SPEC §2 P8) — the tendency applies are scaled by BE at their call sites, and this scales the barotropic-increment leg to match.

integer, intent(out), optional :: n_nonfin

Count of faces whose barotropic-correction Δ (bt_*_end − *_at_n − dt·F_bt) is NON-FINITE. In a supercritical hot state the BT substep loop can reach Inf on at-floor columns, and the fold’s finite − Inf mints NaN into the layer velocity; the guard SKIPS the fold write for such a face (leaving its velocity as-is for the truncation’s NaN-catch backstop) and this counts it loudly. 0 on a healthy run.

integer, intent(in), optional :: n_inner

Barotropic substeps per outer step. REQUIRED when bt_work%bt_rescale_strong_drag is on (PR-2, MOM6 RESCALE_STRONG_DRAG): bt_strong_drag’s rational-approximation bt_rem does not satisfy bt_rem**n_in == av_rem exactly (unlike the plain power form, which does by construction), so the Δu/Δv correction is rescaled by min(bt_rem**n_in/av_rem, 1.0) before being distributed into the layers — keeping the correction consistent with the TRUE depth-mean remnant. Ignored when bt_rescale_strong_drag is off.

public pure subroutine compute_bt_rem(grid, bt_work, ms, metrics, r_linear, hbbl, dt_inner)

Per-face multiplicative damping factor for the BT-substep velocity update (linear-drag branch): bt_rem_face = Htot_face / (Htot_face + r·hbbl·dt_inner) applied as ubt_new = bt_rem_u·(ubt_old + dt_inner·forces) each inner step. When the bt_substep_drag knob is off this must NOT be called and the workspace stays at 1 (no-op, bit-identical).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work
type(multilayer_state_t), intent(in) :: ms
type(ocean_metrics_t), intent(in) :: metrics

REQUIRED (see derive_bt_from_layers). Under &vcoord_nml zfixed_closed_faces Htot_face is the OPEN-column face depth Σ_k h_face·open — the column ubt is the mean of and the one the fast loop transports on — so the bed stress r·hbbl·ubt is spread over the depth that actually carries the barotropic momentum. The full-column depth would under-damp a partially closed face by its closed fraction. .false. (the default) ⇒ the original loops, textually unchanged; open_* is never named.

real(kind=wp), intent(in) :: r_linear

Linear drag rate at the bed (1/s)

real(kind=wp), intent(in) :: hbbl

BBL thickness over which drag acts (m)

real(kind=wp), intent(in) :: dt_inner

BT-substep dt (s)

public pure subroutine compute_bt_rem_from_visc_rem(grid, bt_work, ms, metrics, n_inner)

PR-2 (bt-rem-from-av-rem): build bt_rem_u/v from the SAME viscous remnant the layered momentum solve uses, MOM6’s barotropic solver. Dispatched the same way as compute_bt_rem — a RESETTER, mutually exclusive at configure with bt_substep_drag (D2, double-counted bed drag) and with bt_halo > 0 (validate_config) — so this and compute_bt_rem/ reset_bt_rem never both run for the same stage; src/core/ ocean/README.md’s “exactly one resets, everything else MULTIPLIES” contract gets this as its third resetter.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work
type(multilayer_state_t), intent(in) :: ms
type(ocean_metrics_t), intent(in) :: metrics

REQUIRED — see derive_bt_from_layers/face_depth_mean_u.

integer, intent(in) :: n_inner

Barotropic substeps per outer step (MOM6 nstep; must be

Read more…

public pure subroutine compute_bt_rem_wave_drag(grid, bt_work, ms, metrics, dt_inner)

MULTIPLIES the Egbert & Ray (2001) / Jayne & St Laurent (2001) linear (Rayleigh) barotropic wave drag into bt_rem_u/v: bt_rem_u *= Htot_face / (Htot_face + lwd_drag_u·dt_inner) lwd_drag_u/v is a static, face-resident piston velocity [m/s] built once at configure by configure_ocean_wave_drag. Uses the IDENTICAL Htot_face expression as compute_bt_rem (reuse, not a second H_tot). Composes with substep_drag exactly as MOM6 composes lin_drag_u with the viscous remnant. Htot_face <= 0 ⇒ leave bt_rem unmodified (MOM6’s guard).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work
type(multilayer_state_t), intent(in) :: ms
type(ocean_metrics_t), intent(in) :: metrics

REQUIRED. Under &vcoord_nml zfixed_closed_faces Htot_face = Σ_k h_face·open — the same OPEN-column depth compute_bt_rem uses there, so the “identical Htot_face” contract above holds on both paths: the piston velocity r_H damps the column that carries ubt, at the rate r_H/H_open. .false. ⇒ the original loops, unchanged.

real(kind=wp), intent(in) :: dt_inner

BT-substep dt (s)

public pure subroutine compute_e_anom(bt_work)

SSH anomaly = 0.5·(bt_eta_end + bt_eta) − eta_PF: the part of η the BT substep produced beyond what the slow PGF saw. Zero at steady state.

Arguments

Type IntentOptional Attributes Name
type(barotropic_workstate_t), intent(inout) :: bt_work

public pure subroutine compute_gtot_faces(grid, bt_work, ms, metrics)

Face-centred depth-weighted column averages of pbce (gtot_E/W/N/S). Wall cells fall back to pbce(:,:,nz). By construction Σ_k h_face(k)·(pbce(k) − gtot_face) = 0 per column, making the bc-PGF Δu correction depth-mean zero – UNDER THE SAME h_face/weight derive_bt_from_layers and apply_bt_correction’s folds use.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work
type(multilayer_state_t), intent(in) :: ms
type(ocean_metrics_t), intent(in) :: metrics

REQUIRED, like every other frhat call site’s metrics – see derive_bt_from_layers’s docstring for why an optional here is the defect class, not a defect.

public pure subroutine compute_h_face_upstream(grid, bt_work, ms, metrics)

Per-face upstream column-sum thickness h_face_up_x/y(I,j) = Σ_k h_layer(I_upstream,j,k) used by the BT chain when use_upstream_h_face = .true.. First-order upwind pick by face-velocity sign (sampled at the top of the outer step). Wall faces use the single available cell. No-op when the knob is off.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work
type(multilayer_state_t), intent(in) :: ms
type(ocean_metrics_t), intent(in) :: metrics

REQUIRED, for the reason derive_bt_from_layers gives: an optional dummy that silently selects the full-column branch is how the pred_corr Coriolis-reference defect shipped.

Read more…

public pure subroutine compute_pbce(grid, bt_work, pgf, ms)

Per-layer pressure-anomaly gravity coefficient (m/s²): the response of layer k’s pressure to a unit change in η. Montgomery form, bottom-up convention (k=1 bed, k=nz surface): pbce(:,:,nz) = g·ρ_ref/ρ_0 do k = nz-1, 1, -1 g_prime_K = g·(rho_layer(k+1) − rho_layer(k))/ρ_0 pbce(:,:,k) = pbce(:,:,k+1) + g_prime_K·(e_top_of_k − e_bed)/H Uniform-density column ⇒ pbce−gtot ≡ 0 ⇒ bc-PGF correction a no-op. Reads pgf%e_face; requires pgf%variant == OPGF_VARIANT_FV_MOM6 (other variants don’t fill e_face). validate_config and configure_ocean_pgf refuse correction_bc_pgf with any other form, so the error stop below is a backstop for direct callers.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work
type(ocean_pressure_force_t), intent(in) :: pgf
type(multilayer_state_t), intent(in) :: ms

public pure subroutine derive_bt_from_layers(grid, bt_work, ms, metrics)

Populate bt_eta, bt_ubt, bt_vbt from the current multilayer state. bt_H_ref must already be set. bt_eta = Σ_k h_layer − H_ref; bt_ubt = Σ_k(u·h_face)/Σ_k h_face. Face thickness averages the two abutting columns (wall faces use the single cell). With use_upstream_h_face, the interior face-h is the first-order upwind pick — consistent with compute_h_face_upstream.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work
type(multilayer_state_t), intent(in) :: ms
type(ocean_metrics_t), intent(in) :: metrics

REQUIRED — and required on purpose. Under &vcoord_nml zfixed_closed_faces a CLOSED layer carries no transport, so it must not dilute the face mean either: the weight becomes h_face·open and ubt is the OPEN-column depth mean. That is not a refinement, it is a consistency requirement: the barotropic substep transports on ubt·FA·dy_cu_bt with dy_cu_bt narrowed by the open fraction, so the ubt the fast loop integrates ALREADY means “the open-column mean”. Deriving ubt_at_n from the full column would make the fold’s Δu = ubt_end − ubt_at_n − dt·F_bt a difference between two different quantities — diluted by 0.5·h_live per one-sided-filler layer, which at a partial face is not small.

Read more…

public pure subroutine face_depth_mean_rem_u(grid, F_3d, h_layer, rem, F_mean_2d, nz, metrics, n_inner, href, scheme)

face_depth_mean_u with MOM6 wt_u weighting (&ocean_bt_nml forcing_visc_rem): the weight is h_face·visc_rem(k) instead of h_face, so layers the implicit vertical-friction solve will immediately damp (grounded sliver stacks under the BBL glue, visc_rem → 0) contribute nothing to the barotropic forcing. Without this the spurious grounded-layer PGF’s depth-mean drives the fast loop ballistically even after the layer velocities themselves are glued (PGF_BUG.md §9). Denominator falls back to zero-output on an all-remnant-zero column (the substep should not force an immobilized column).

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
real(kind=wp), intent(in) :: F_3d(:,:,:)
real(kind=wp), intent(in) :: h_layer(:,:,:)
real(kind=wp), intent(in) :: rem(:,:,:)
real(kind=wp), intent(out) :: F_mean_2d(:,:)
integer, intent(in) :: nz
type(ocean_metrics_t), intent(in) :: metrics

REQUIRED (see face_depth_mean_u): the weight becomes h_face·visc_rem·open. It must match derive_bt_from_layers and apply_bt_correction or the dt·F_bt the fold subtracts is not what the fast loop integrated. Note a CLOSED layer’s visc_rem is ~1, not 0 — the closed-face vdiff decoupling leaves it uncoupled, so visc_rem alone does NOT stand in for the mask here. Knob off ⇒ the ORIGINAL loop, byte-identical.

integer, intent(in) :: n_inner

Barotropic substep count (MOM6 nstep); Instep = 1/n_inner in the wt_u floor. max(n_inner, 1) guards the unsplit (n_inner = 0) configuration.

real(kind=wp), intent(in) :: href(:,:)
integer, intent(in) :: scheme

A FRHAT_* constant. See face_depth_mean_u.

public pure subroutine face_depth_mean_rem_v(grid, F_3d, h_layer, rem, F_mean_2d, nz, metrics, n_inner, href, scheme)

Symmetric v-face counterpart of face_depth_mean_rem_u — same MOM6 wt_u floor, ieee_is_finite-guarded the same way.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
real(kind=wp), intent(in) :: F_3d(:,:,:)
real(kind=wp), intent(in) :: h_layer(:,:,:)
real(kind=wp), intent(in) :: rem(:,:,:)
real(kind=wp), intent(out) :: F_mean_2d(:,:)
integer, intent(in) :: nz
type(ocean_metrics_t), intent(in) :: metrics

REQUIRED (see face_depth_mean_u): the weight becomes h_face·visc_rem·open. It must match derive_bt_from_layers and apply_bt_correction or the dt·F_bt the fold subtracts is not what the fast loop integrated. Note a CLOSED layer’s visc_rem is ~1, not 0 — the closed-face vdiff decoupling leaves it uncoupled, so visc_rem alone does NOT stand in for the mask here. Knob off ⇒ the ORIGINAL loop, byte-identical.

integer, intent(in) :: n_inner

Barotropic substep count (MOM6 nstep); see face_depth_mean_rem_u.

real(kind=wp), intent(in) :: href(:,:)
integer, intent(in) :: scheme

A FRHAT_* constant. See face_depth_mean_u.

public pure subroutine face_depth_mean_u(grid, F_3d, h_layer, F_mean_2d, nz, metrics, href, scheme)

Depth-average a u-face 3D field, weighted by the per-layer face thickness frhat_h_face_step returns (&ocean_bt_nml frhat_scheme; FRHAT_ARITHMETIC = the plain mean of the two abutting cell columns’ h_layer values, today’s default; the argument is otherwise unchanged). Writes to a 2D field at the same u-face shape. Wall faces (i=1, nx+1) fall back to the single available cell (frhat_h_face_step degenerates there for either scheme — see its docstring).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
real(kind=wp), intent(in) :: F_3d(:,:,:)
real(kind=wp), intent(in) :: h_layer(:,:,:)
real(kind=wp), intent(out) :: F_mean_2d(:,:)
integer, intent(in) :: nz
type(ocean_metrics_t), intent(in) :: metrics

REQUIRED. Under &vcoord_nml zfixed_closed_faces every depth mean in the split chain MUST use the same weights derive_bt_from_layers and apply_bt_correction use — h_face·open — or the dt·F_bt the fold subtracts back out is not the quantity the fast loop integrated, and the difference survives as a permanent per-face bias.

Read more…
real(kind=wp), intent(in) :: href(:,:)

Reference column depth (m), barotropic_workstate_t%bt_H_ref — REQUIRED for the same reason metrics is: every call site has a bt_work to hand, and an omitted/mismatched href would silently change FRHAT_HYBRID’s answer. Unused under FRHAT_ARITHMETIC but still dereferenced (no branch to skip it), so it must be a real, fully-sized array on every call, never a placeholder.

integer, intent(in) :: scheme

A FRHAT_* constant (rdb_constants; &ocean_bt_nml frhat_scheme, via bt_work%frhat_scheme).

public pure subroutine face_depth_mean_v(grid, F_3d, h_layer, F_mean_2d, nz, metrics, href, scheme)

Symmetric v-face counterpart of face_depth_mean_u.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
real(kind=wp), intent(in) :: F_3d(:,:,:)
real(kind=wp), intent(in) :: h_layer(:,:,:)
real(kind=wp), intent(out) :: F_mean_2d(:,:)
integer, intent(in) :: nz
type(ocean_metrics_t), intent(in) :: metrics

REQUIRED. See face_depth_mean_u for the argument and for why it is not optional; knob off ⇒ the ORIGINAL loop, byte-identical.

real(kind=wp), intent(in) :: href(:,:)
integer, intent(in) :: scheme

A FRHAT_* constant. See face_depth_mean_u.

public pure subroutine mask_bt_rem(grid, metrics, bt_work)

Fold the static land face masks into the BT-substep damping factor (bt_rem_u(land)=0 ⇒ no velocity across a land face). Runs every outer step AFTER compute_bt_rem (which resets bt_rem each step, so the mask must be re-applied). All-wet ⇒ wet_u/v≡1 ⇒ no-op (bit-identical).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(barotropic_workstate_t), intent(inout) :: bt_work

public pure subroutine reset_bt_rem(grid, bt_work)

bt_rem_u/v ≡ 1 (the init value). bt_rem_u/v is otherwise reset only by compute_bt_rem, which only runs when bt_substep_drag is on. compute_bt_rem_wave_drag MULTIPLIES into bt_rem_u/v, so when wave drag is on and bt_substep_drag is off, something must still reset it to 1 each stage — otherwise it compounds geometrically across outer steps (bt_rem = R^n after n stages), silently annihilating the barotropic mode. See src/core/ocean/README.md for the multiplicative-accumulator contract this establishes.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work

public pure subroutine set_cor_ref_velocity(grid, bt_work, ms, from_u_av, metrics, n_inner)

Fill bt_work%cor_ref_u/v — the barotropic velocity at which subtract_fast_cor_ref evaluates the Coriolis/advection reference it removes from the substep forcing (MOM6 ubt_Cor/vbt_Cor).

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work
type(multilayer_state_t), intent(in) :: ms
logical, intent(in) :: from_u_av

.true. under split_scheme = "pred_corr".

type(ocean_metrics_t), intent(in) :: metrics

The closed-face mask carrier, REQUIRED — see the paragraph above, and face_depth_mean_u’s own metrics docstring. Knob off ⇒ the depth means take their original branch and this is byte-identical.

integer, intent(in), optional :: n_inner

Barotropic substep count, forwarded to face_depth_mean_rem_u/v’s MOM6 wt_u floor when bt_forcing_visc_rem is on. Optional (defaults to 1) ONLY so call sites that never set forcing_visc_rem (that branch is then never taken) need not be touched — a real forcing_visc_rem run must pass the true value or the floor’s Instep is wrong.

public pure subroutine set_fast_forcing_eta_pf(grid, metrics, bt_work, nx, ny, g_pf, eta_seam, use_seam)

The barotropic substep’s frozen forcing under the MOM6 split (&ocean_bt_nml bc_pgf_forcing, default on):

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(barotropic_workstate_t), intent(inout) :: bt_work
integer, intent(in) :: nx
integer, intent(in) :: ny
real(kind=wp), intent(in) :: g_pf
real(kind=wp), intent(in) :: eta_seam(nx,ny)
logical, intent(in) :: use_seam

public pure subroutine set_local_BT_cont_types(grid, metrics, bt_work, ms, dt_outer)

Populate bt_work%BTCL_u/v — the per-face flux-closure coefficients consumed by find_uhbt — from the current h_layer. Upstream-h-sum approach: FA_u_W0=FA_u_E0=Σ_k h_face (centred); FA_u_WW=Σ_k h_layer(west) and FA_u_EE=Σ_k h_layer(east) (saturated-regime upstream draw); uBT_WW/EE = ±VOL_CFL·dx/dt_outer pin the saturation velocity; uh_crv/uh_* are the C¹-matching coefficients (Hallberg & Adcroft 2009). No-op when use_bt_cont_type = .false. (BTCL_u/v unallocated).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(barotropic_workstate_t), intent(inout) :: bt_work
type(multilayer_state_t), intent(in) :: ms
real(kind=wp), intent(in) :: dt_outer

public pure subroutine snapshot_eta_PF(bt_work)

Snapshot bt_eta into eta_PF — the free-surface height the slow PGF sees this stage. Later differenced by compute_e_anom.

Arguments

Type IntentOptional Attributes Name
type(barotropic_workstate_t), intent(inout) :: bt_work

public pure subroutine subtract_fast_cor_ref(grid, metrics, bt_work, f_corner, bc_w, bc_e, bc_s, bc_n, has_w, has_e, has_s, has_n)

Subtract the fast-loop Coriolis + vector-invariant advection, evaluated at the reference barotropic velocity bt_work%cor_ref_u/cor_ref_v (filled by set_cor_ref_velocity), from the substep forcing F_bt_u_fast/F_bt_v_fast.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(barotropic_workstate_t), intent(inout) :: bt_work
real(kind=wp), intent(in) :: f_corner(grid%nx_total+1,grid%ny_total+1)
integer, intent(in) :: bc_w

Per-edge OBC tags (OBC_WALL when no bc present).

integer, intent(in) :: bc_e

Per-edge OBC tags (OBC_WALL when no bc present).

integer, intent(in) :: bc_s

Per-edge OBC tags (OBC_WALL when no bc present).

integer, intent(in) :: bc_n

Per-edge OBC tags (OBC_WALL when no bc present).

logical, intent(in) :: has_w

Physical-edge flags (.false. at an MPI seam).

logical, intent(in) :: has_e

Physical-edge flags (.false. at an MPI seam).

logical, intent(in) :: has_s

Physical-edge flags (.false. at an MPI seam).

logical, intent(in) :: has_n

Physical-edge flags (.false. at an MPI seam).

public pure subroutine sum_slow_tendencies_into_F_slow(bt_work, pgf, cor, hv, bd, ss, ms)

Sum the per-kernel slow-tendency scratch buffers into a single (bt_work%F_slow_u, bt_work%F_slow_v) field per face per layer. Reads pgf%dpdx_face, cor%pv_flux_x, hv%du_visc, bd%du_drag, ss%du_stress and their v counterparts — all already at the matching u-face / v-face shape. Each kernel must have run its compute step before this is called.

Read more…

Arguments

Type IntentOptional Attributes Name
type(barotropic_workstate_t), intent(inout) :: bt_work
type(ocean_pressure_force_t), intent(in) :: pgf
type(coriolis_adv_t), intent(in) :: cor
type(ocean_horizontal_viscosity_t), intent(in) :: hv
type(ocean_bottom_drag_t), intent(in) :: bd
type(ocean_surface_stress_t), intent(in) :: ss
type(multilayer_state_t), intent(in) :: ms

private pure subroutine bt_rem_open_impl(nx, ny, nz, h_layer, open_u, open_v, drag_dt, bt_rem_u, bt_rem_v)

compute_bt_rem under &vcoord_nml zfixed_closed_faces: the same H/(H + r·hbbl·dt_inner) with H = Σ_k h_face·open (the OPEN-column centred face depth, the weight face_depth_mean_* uses). A face whose every layer is closed has H = 0 and keeps bt_rem = 1, exactly like a dry face on the original path (it carries no barotropic transport: dy_cu_bt = 0 there).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz
real(kind=wp), intent(in) :: h_layer(nx,ny,nz)
real(kind=wp), intent(in) :: open_u(nx+1,ny,nz)
real(kind=wp), intent(in) :: open_v(nx,ny+1,nz)
real(kind=wp), intent(in) :: drag_dt

r_linear·hbbl·dt_inner (m).

real(kind=wp), intent(inout) :: bt_rem_u(nx+1,ny)
real(kind=wp), intent(inout) :: bt_rem_v(nx,ny+1)

private pure subroutine bt_rem_wave_drag_open_impl(nx, ny, nz, h_layer, open_u, open_v, lwd_u, lwd_v, dt_inner, bt_rem_u, bt_rem_v)

compute_bt_rem_wave_drag under &vcoord_nml zfixed_closed_faces: MULTIPLIES H/(H + r_H·dt_inner) into bt_rem with the OPEN-column face depth H = Σ_k h_face·open (the bt_rem_open_impl depth). H <= 0 (every layer closed) ⇒ unmodified, MOM6’s guard.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz
real(kind=wp), intent(in) :: h_layer(nx,ny,nz)
real(kind=wp), intent(in) :: open_u(nx+1,ny,nz)
real(kind=wp), intent(in) :: open_v(nx,ny+1,nz)
real(kind=wp), intent(in) :: lwd_u(nx+1,ny)
real(kind=wp), intent(in) :: lwd_v(nx,ny+1)
real(kind=wp), intent(in) :: dt_inner
real(kind=wp), intent(inout) :: bt_rem_u(nx+1,ny)
real(kind=wp), intent(inout) :: bt_rem_v(nx,ny+1)

private pure subroutine h_face_upstream_open_impl(nx, ny, nz, use_por, h_layer, u_face, v_face, open_u, open_v, por_u, por_v, dy_cu, dx_cv, dy_cu_bt, dx_cv_bt, h_up_x, h_up_y)

OPEN-column upstream face thickness, for upstream_h_face under &vcoord_nml zfixed_closed_faces.

Read more…

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz
logical, intent(in) :: use_por
real(kind=wp), intent(in) :: h_layer(nx,ny,nz)
real(kind=wp), intent(in) :: u_face(nx+1,ny,nz)
real(kind=wp), intent(in) :: v_face(nx,ny+1,nz)
real(kind=wp), intent(in) :: open_u(nx+1,ny,nz)
real(kind=wp), intent(in) :: open_v(nx,ny+1,nz)
real(kind=wp), intent(in) :: por_u(nx+1,ny,nz)
real(kind=wp), intent(in) :: por_v(nx,ny+1,nz)
real(kind=wp), intent(in) :: dy_cu(nx+1,ny)
real(kind=wp), intent(in) :: dx_cv(nx,ny+1)
real(kind=wp), intent(in) :: dy_cu_bt(nx+1,ny)
real(kind=wp), intent(in) :: dx_cv_bt(nx,ny+1)
real(kind=wp), intent(inout) :: h_up_x(nx+1,ny)
real(kind=wp), intent(inout) :: h_up_y(nx,ny+1)