pure subroutine meke_drag(nx, ny, sdt_damp, damping, cdrag, uscale, rho0, &
i_mass, bottom_fac2, u_bbl2, meke)
!! Implicit (backward-Euler) bottom-drag half-step.
!! drag_rate = rho0*i_mass*sqrt(cdrag^2*(max(0,2*bf2*E)+u_bbl2+uscale^2)) [1/s]
!! damp_rate = damping + drag_rate*bf2 ; =0 where E<0
!! E <- E/(1 + sdt_damp*damp_rate)
!! `rho0*i_mass` = rho0/(Sum_k rho_k*h_k) ~= 1/depth_tot [1/m], so
!! drag_rate ~= cdrag*|U_d|/H -- the MOM6 `GV%H_to_RZ * I_mass` factor.
!! Without it drag_rate is m^3/(kg*s), not a
!! rate. `i_mass=0` on dry columns still gives `drag_rate=0`.
!! `u_bbl2` is the resolved bed-layer speed² (MOM6 `drag_rate_visc`);
!! it is 0 unless `use_bbl_drag` is set, so the default is bit-identical.
integer, intent(in) :: nx, ny
real(wp), intent(in) :: sdt_damp, damping, cdrag, uscale, rho0
real(wp), intent(in) :: i_mass(nx, ny)
real(wp), intent(in) :: bottom_fac2(nx, ny)
real(wp), intent(in) :: u_bbl2(nx, ny)
real(wp), intent(inout) :: meke(nx, ny)
integer :: i, j
real(wp) :: drag_rate, damp_rate, cd2, e
cd2 = cdrag*cdrag
do concurrent(j=1:ny, i=1:nx) local(drag_rate, damp_rate, e)
e = meke(i, j)
drag_rate = (rho0*i_mass(i, j))*sqrt(cd2*(max(0.0_wp, 2.0_wp*bottom_fac2(i, j)*e) &
+ u_bbl2(i, j) + uscale*uscale))
damp_rate = damping + drag_rate*bottom_fac2(i, j)
if (e < 0.0_wp) damp_rate = 0.0_wp
meke(i, j) = e/(1.0_wp + sdt_damp*damp_rate)
end do
end subroutine meke_drag