ocean_channel_drag_apply_tendencies Subroutine

public 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).

Arguments

Type IntentOptional Attributes Name
type(ocean_bottom_drag_t), intent(in) :: this
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
logical, intent(in), optional :: no_wait

Called by

proc~~ocean_channel_drag_apply_tendencies~~CalledByGraph proc~ocean_channel_drag_apply_tendencies ocean_channel_drag_apply_tendencies proc~run_stage run_stage proc~run_stage->proc~ocean_channel_drag_apply_tendencies proc~run_stage_split run_stage_split proc~run_stage_split->proc~ocean_channel_drag_apply_tendencies proc~ocean_dyn_step ocean_dyn_step proc~ocean_dyn_step->proc~run_stage 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 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 :: i
integer, private :: j
integer, private :: k
logical, private :: lwait
integer, private :: nx_face
integer, private :: nx_vface
integer, private :: ny_face
integer, private :: ny_uface
integer, private :: nz

Source Code

   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