apply_orlanski_south Subroutine

private pure subroutine apply_orlanski_south(v_layer, rx, v_prev, nx_total, ny_total, nz, j_s, i0, i1, rx_max, gamma_u, tau_in, tau_out, dt, v_data)

Orlanski radiation for the south open edge (Orlanski 1976). Interior face J = j_s+1 (1st), J-1 = j_s+2 (2nd). Outward normal = -y. dhdx = v(j_s+1) - v(j_s+2) (southward gradient).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: v_layer(nx_total,ny_total+1,nz)
real(kind=wp), intent(inout) :: rx(nx_total,nz)
real(kind=wp), intent(in) :: v_prev(nx_total,nz)
integer, intent(in) :: nx_total
integer, intent(in) :: ny_total
integer, intent(in) :: nz
integer, intent(in) :: j_s
integer, intent(in) :: i0
integer, intent(in) :: i1
real(kind=wp), intent(in) :: rx_max
real(kind=wp), intent(in) :: gamma_u
real(kind=wp), intent(in) :: tau_in
real(kind=wp), intent(in) :: tau_out
real(kind=wp), intent(in) :: dt
real(kind=wp), intent(in) :: v_data

Calls

proc~~apply_orlanski_south~~CallsGraph proc~apply_orlanski_south apply_orlanski_south local local proc~apply_orlanski_south->local

Called by

proc~~apply_orlanski_south~~CalledByGraph proc~apply_orlanski_south apply_orlanski_south proc~ocean_obc_apply_baroclinic ocean_obc_apply_baroclinic proc~ocean_obc_apply_baroclinic->proc~apply_orlanski_south proc~run_stage_split run_stage_split proc~run_stage_split->proc~ocean_obc_apply_baroclinic 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

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: dhdt_ik
real(kind=wp), private :: dhdx_ik
real(kind=wp), private :: g2
integer, private :: i
integer, private :: k
real(kind=wp), private :: rx_new
real(kind=wp), private :: rx_raw
real(kind=wp), private :: tau
real(kind=wp), private :: v_b
real(kind=wp), private :: v_int_1

Source Code

   pure subroutine apply_orlanski_south(v_layer, &
                                        rx, v_prev, &
                                        nx_total, ny_total, nz, &
                                        j_s, i0, i1, &
                                        rx_max, gamma_u, &
                                        tau_in, tau_out, dt, v_data)
      !! Orlanski radiation for the south open edge (Orlanski 1976).
      !! Interior face J = j_s+1 (1st), J-1 = j_s+2 (2nd).
      !! Outward normal = -y.  dhdx = v(j_s+1) - v(j_s+2) (southward gradient).
      integer, intent(in) :: nx_total, ny_total, nz
      real(wp), intent(inout) :: v_layer(nx_total, ny_total + 1, nz)
      real(wp), intent(inout) :: rx(nx_total, nz)
      real(wp), intent(in)    :: v_prev(nx_total, nz)
      integer, intent(in) :: j_s, i0, i1
      real(wp), intent(in) :: rx_max, gamma_u, tau_in, tau_out, dt, v_data

      integer  :: i, k
      real(wp) :: v_int_1
      real(wp) :: dhdt_ik, dhdx_ik, rx_raw, rx_new, v_b
      real(wp) :: tau, g2

      do concurrent(i=i0:i1) &
         local(k, v_int_1, dhdt_ik, dhdx_ik, rx_raw, rx_new, v_b, tau, g2)

         do k = 1, nz
            v_int_1 = v_layer(i, j_s + 1, k)

            ! South edge: outward = -y; dhdx = v(j_s+1) - v(j_s+2).
            dhdt_ik = v_prev(i, k) - v_int_1
            dhdx_ik = v_int_1 - v_layer(i, j_s + 2, k)

            if (dhdt_ik*dhdx_ik > 0.0_wp) then
               rx_raw = min(dhdt_ik/dhdx_ik, rx_max)
            else
               rx_raw = 0.0_wp
            end if

            rx_new = (1.0_wp - gamma_u)*rx(i, k) + gamma_u*rx_raw
            rx(i, k) = rx_new

            ! Per-layer anchor — see the west kernel's comment.
            v_b = (v_layer(i, j_s, k) + rx_new*v_int_1)/(1.0_wp + rx_new)

            if (dhdt_ik*dhdx_ik <= 0.0_wp) then
               tau = tau_in
            else
               tau = tau_out
            end if
            if (tau > 0.0_wp) then
               g2 = dt/(tau + dt)
               v_b = (1.0_wp - g2)*v_b + g2*v_data
            end if

            v_layer(i, j_s, k) = v_b
         end do
      end do
   end subroutine apply_orlanski_south