subroutine ocean_channel_drag_apply_tendencies(this, ms, dt, no_wait)
!! Apply the per-layer side drag IMPLICITLY:
!! `u <- u / (1 + dt·lambda_side_u)`,
!! `v <- v / (1 + dt·lambda_side_v)`.
!! The implicit (backward-Euler) form is unconditionally stable on
!! thin layers where an explicit `u - dt·lambda·u` would overshoot.
!! `lambda ≡ 0` (default-off / all-wet / flat-bottom) ⇒ division by
!! `1` ⇒ exact no-op. `no_wait` semantics mirror
!! `ocean_bottom_drag_apply_tendencies`. Not `pure` (async/wait).
type(ocean_bottom_drag_t), intent(in) :: this
type(multilayer_state_t), intent(inout) :: ms
real(wp), intent(in) :: dt
logical, intent(in), optional :: no_wait
integer :: i, j, k, nx_face, ny_uface, nx_vface, ny_face, nz
logical :: lwait
lwait = .true.
if (present(no_wait)) lwait = .not. no_wait
nx_face = size(ms%u_face_x_layer, 1)
ny_uface = size(ms%u_face_x_layer, 2)
nx_vface = size(ms%v_face_y_layer, 1)
ny_face = size(ms%v_face_y_layer, 2)
nz = ms%nz_ml
!$acc kernels async(1)
do concurrent(k=1:nz, j=1:ny_uface, i=1:nx_face)
ms%u_face_x_layer(i, j, k) = ms%u_face_x_layer(i, j, k)/ &
(1.0_wp + dt*this%lambda_side_u%data(i, j, k))
end do
do concurrent(k=1:nz, j=1:ny_face, i=1:nx_vface)
ms%v_face_y_layer(i, j, k) = ms%v_face_y_layer(i, j, k)/ &
(1.0_wp + dt*this%lambda_side_v%data(i, j, k))
end do
!$acc end kernels
if (lwait) then
!$acc wait(1)
end if
end subroutine ocean_channel_drag_apply_tendencies