apply_orlanski_north Subroutine

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

Orlanski radiation for the north open edge (Orlanski 1976). Interior face J = j_n-1 (1st), J-1 = j_n-2 (2nd). Outward normal = +y. dhdx = v(j_n-1) - v(j_n-2) (northward 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_n
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_north~~CallsGraph proc~apply_orlanski_north apply_orlanski_north local local proc~apply_orlanski_north->local

Called by

proc~~apply_orlanski_north~~CalledByGraph proc~apply_orlanski_north apply_orlanski_north proc~ocean_obc_apply_baroclinic ocean_obc_apply_baroclinic proc~ocean_obc_apply_baroclinic->proc~apply_orlanski_north 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_north(v_layer, &
                                        rx, v_prev, &
                                        nx_total, ny_total, nz, &
                                        j_n, i0, i1, &
                                        rx_max, gamma_u, &
                                        tau_in, tau_out, dt, v_data)
      !! Orlanski radiation for the north open edge (Orlanski 1976).
      !! Interior face J = j_n-1 (1st), J-1 = j_n-2 (2nd).
      !! Outward normal = +y.  dhdx = v(j_n-1) - v(j_n-2) (northward 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_n, 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_n - 1, k)

            ! North edge: outward = +y; dhdx = v(j_n-1) - v(j_n-2).
            dhdt_ik = v_prev(i, k) - v_int_1
            dhdx_ik = v_int_1 - v_layer(i, j_n - 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_n, 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_n, k) = v_b
         end do
      end do
   end subroutine apply_orlanski_north