compute_bt_rem_wave_drag Subroutine

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)


Calls

proc~~compute_bt_rem_wave_drag~~CallsGraph proc~compute_bt_rem_wave_drag compute_bt_rem_wave_drag local local proc~compute_bt_rem_wave_drag->local proc~bt_rem_wave_drag_open_impl bt_rem_wave_drag_open_impl proc~compute_bt_rem_wave_drag->proc~bt_rem_wave_drag_open_impl proc~bt_rem_wave_drag_open_impl->local

Called by

proc~~compute_bt_rem_wave_drag~~CalledByGraph proc~compute_bt_rem_wave_drag compute_bt_rem_wave_drag proc~run_stage_split run_stage_split proc~run_stage_split->proc~compute_bt_rem_wave_drag 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
real(kind=wp), private :: htot_face
integer, private :: i
integer, private :: j
integer, private :: k
integer, private :: nx
integer, private :: ny
integer, private :: nz

Source Code

   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).
      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(wp), intent(in) :: dt_inner   !! BT-substep dt (s)

      integer :: i, j, k, nx, ny, nz
      real(wp) :: htot_face

      nx = grid%nx_total
      ny = grid%ny_total
      nz = ms%nz_ml

      if (metrics%use_closed_faces) then
         call bt_rem_wave_drag_open_impl(nx, ny, nz, ms%h_layer, metrics%open_u, &
                                         metrics%open_v, bt_work%lwd_drag_u, &
                                         bt_work%lwd_drag_v, dt_inner, &
                                         bt_work%bt_rem_u, bt_work%bt_rem_v)
         return
      end if

      do concurrent(j=1:ny, i=2:nx) local(k, htot_face)
         htot_face = 0.0_wp
         do k = 1, nz
            htot_face = htot_face + 0.5_wp*(ms%h_layer(i - 1, j, k) + ms%h_layer(i, j, k))
         end do
         if (htot_face > 0.0_wp) then
            bt_work%bt_rem_u(i, j) = bt_work%bt_rem_u(i, j)* &
                                     (htot_face/(htot_face + bt_work%lwd_drag_u(i, j)*dt_inner))
         end if
      end do

      do concurrent(j=2:ny, i=1:nx) local(k, htot_face)
         htot_face = 0.0_wp
         do k = 1, nz
            htot_face = htot_face + 0.5_wp*(ms%h_layer(i, j - 1, k) + ms%h_layer(i, j, k))
         end do
         if (htot_face > 0.0_wp) then
            bt_work%bt_rem_v(i, j) = bt_work%bt_rem_v(i, j)* &
                                     (htot_face/(htot_face + bt_work%lwd_drag_v(i, j)*dt_inner))
         end if
      end do
   end subroutine compute_bt_rem_wave_drag