meke_backscatter_apply Subroutine

public pure subroutine meke_backscatter_apply(grid, metrics, this, dt, ah_face_x, ah_face_y)

Inject the MEKE harmonic backscatter into the per-face resolved harmonic viscosity (capability Gap 2, v1). Subtracts a face-average of the cell-centred ku field from ah_face_x/ah_face_y so the NET coefficient A_net = A_resolved − Ku can go NEGATIVE — that negative viscosity is the energy return into the momentum tendency (the hvisc Laplacian kernel reads these same face fields).

STABILITY: a negative explicit Laplacian viscosity AMPLIFIES grid-scale modes — a pure negative Laplacian is unconditionally unstable (g = 1 + |A|·dt·k² > 1). The floor does NOT by itself make the operator stable; it bounds the negative mode’s GROWTH RATE so a co-present POSITIVE biharmonic (Smag_AH / nu_4 / leith_biharm) can dissipate the grid-scale mode the backscatter feeds. The net magnitude is floored at the forward-Euler bound |A|·dt·(idx²+idy²) ≤ backscatter_cfl·0.5, i.e. A_floor = −backscatter_cfl·0.5/(dt·(idx²+idy²)) per face (backscatter_cfl = 0.8 safety; MOM6 BACKSCATTER_UNDERBOUND analogue). Result: ah_face <- max(A_resolved − Ku, A_floor). A biharmonic backstop is therefore MANDATORY when backscatter is on — enforced fail-loud at configure (validate_config).

No-op (bit-identical) when backscatter is off or the slot is uninitialised. GPU-resident: explicit-shape flat-impl dispatch. Run AFTER ocean_lateral_mix_compute (which fills ah_face_*) and BEFORE ocean_horizontal_viscosity_compute_tendencies consumes them. Uses the PREVIOUS thermo step’s ku (a one-step lag, like the kh→KhTh feedback) — meke_step refreshes ku once per outer step.

REQUIRES a flow-aware lateral closure (&ocean_hvisc_nml lateral_closure = leith/smag ⇒ LMIX_*): the hvisc Laplacian only reads ah_face_* when closure /= LMIX_NONE. With the default scalar-nu_h path the modified faces are never consumed, so backscatter has no effect (it is still bit-identical when off).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_meke_t), intent(in) :: this
real(kind=wp), intent(in) :: dt
real(kind=wp), intent(inout) :: ah_face_x(:,:,:)
real(kind=wp), intent(inout) :: ah_face_y(:,:,:)

Calls

proc~~meke_backscatter_apply~~CallsGraph proc~meke_backscatter_apply meke_backscatter_apply proc~meke_backscatter_apply_impl meke_backscatter_apply_impl proc~meke_backscatter_apply->proc~meke_backscatter_apply_impl local local proc~meke_backscatter_apply_impl->local

Called by

proc~~meke_backscatter_apply~~CalledByGraph proc~meke_backscatter_apply meke_backscatter_apply proc~run_stage_split run_stage_split proc~run_stage_split->proc~meke_backscatter_apply proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~run_stage_split proc~engine_step engine_step proc~engine_step->proc~ocean_dyn_step_split proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

Type Visibility Attributes Name Initial
integer, private :: nx
integer, private :: ny
integer, private :: nz

Source Code

   pure subroutine meke_backscatter_apply(grid, metrics, this, dt, ah_face_x, ah_face_y)
      !! Inject the MEKE harmonic backscatter into the per-face resolved
      !! harmonic viscosity (capability Gap 2, v1).  Subtracts a face-average
      !! of the cell-centred `ku` field from `ah_face_x`/`ah_face_y` so the
      !! NET coefficient `A_net = A_resolved − Ku` can go NEGATIVE — that
      !! negative viscosity is the energy return into the momentum tendency
      !! (the hvisc Laplacian kernel reads these same face fields).
      !!
      !! STABILITY: a negative explicit Laplacian viscosity AMPLIFIES
      !! grid-scale modes — a pure negative Laplacian is unconditionally
      !! unstable (`g = 1 + |A|·dt·k² > 1`).  The floor does NOT by itself
      !! make the operator stable; it bounds the negative mode's GROWTH
      !! RATE so a co-present POSITIVE biharmonic (Smag_AH / `nu_4` /
      !! `leith_biharm`) can dissipate the grid-scale mode the backscatter
      !! feeds.  The net magnitude is floored at the forward-Euler bound
      !! `|A|·dt·(idx²+idy²) ≤ backscatter_cfl·0.5`, i.e.
      !! `A_floor = −backscatter_cfl·0.5/(dt·(idx²+idy²))` per face
      !! (`backscatter_cfl = 0.8` safety; MOM6 `BACKSCATTER_UNDERBOUND`
      !! analogue).  Result: `ah_face <- max(A_resolved − Ku, A_floor)`.
      !! A biharmonic backstop is therefore MANDATORY when `backscatter`
      !! is on — enforced fail-loud at configure (`validate_config`).
      !!
      !! No-op (bit-identical) when `backscatter` is off or the slot is
      !! uninitialised.  GPU-resident: explicit-shape flat-impl dispatch.
      !! Run AFTER `ocean_lateral_mix_compute` (which fills `ah_face_*`) and
      !! BEFORE `ocean_horizontal_viscosity_compute_tendencies` consumes them.
      !! Uses the PREVIOUS thermo step's `ku` (a one-step lag, like the
      !! kh→KhTh feedback) — `meke_step` refreshes `ku` once per outer step.
      !!
      !! REQUIRES a flow-aware lateral closure (`&ocean_hvisc_nml
      !! lateral_closure` = `leith`/`smag` ⇒ `LMIX_*`): the hvisc Laplacian
      !! only reads `ah_face_*` when `closure /= LMIX_NONE`.  With the
      !! default scalar-`nu_h` path the modified faces are never consumed,
      !! so backscatter has no effect (it is still bit-identical when off).
      type(hgrid_t), intent(in) :: grid
      type(ocean_metrics_t), intent(in) :: metrics
      type(ocean_meke_t), intent(in) :: this
      real(wp), intent(in) :: dt
      real(wp), intent(inout) :: ah_face_x(:, :, :)
      real(wp), intent(inout) :: ah_face_y(:, :, :)
      integer :: nx, ny, nz

      if (.not. this%is_init) return
      if (.not. this%backscatter) return
      if (.not. allocated(this%ku)) return
      nx = grid%nx_total
      ny = grid%ny_total
      nz = size(ah_face_x, 3)
      if (this%nx_total /= nx .or. this%ny_total /= ny) return

      call meke_backscatter_apply_impl(nx, ny, nz, dt, BACKSCATTER_CFL, this%ku, &
                                       metrics%idxCu, metrics%idyCu, &
                                       metrics%idxCv, metrics%idyCv, &
                                       ah_face_x, ah_face_y)
   end subroutine meke_backscatter_apply