apply_orlanski_east Subroutine

private pure subroutine apply_orlanski_east(u_layer, rx, u_prev, nx_total, ny_total, nz, i_e, j0, j1, rx_max, gamma_u, tau_in, tau_out, dt, u_data)

Orlanski radiation for the east open edge (Orlanski 1976). Interior face index I = i_e-1 (1st), I-1 = i_e-2 (2nd). Outward normal = +x. dhdx = u(i_e-1) - u(i_e-2) (eastward gradient).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(inout) :: u_layer(nx_total+1,ny_total,nz)
real(kind=wp), intent(inout) :: rx(ny_total,nz)
real(kind=wp), intent(in) :: u_prev(ny_total,nz)
integer, intent(in) :: nx_total
integer, intent(in) :: ny_total
integer, intent(in) :: nz
integer, intent(in) :: i_e
integer, intent(in) :: j0
integer, intent(in) :: j1
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) :: u_data

Calls

proc~~apply_orlanski_east~~CallsGraph proc~apply_orlanski_east apply_orlanski_east local local proc~apply_orlanski_east->local

Called by

proc~~apply_orlanski_east~~CalledByGraph proc~apply_orlanski_east apply_orlanski_east proc~ocean_obc_apply_baroclinic ocean_obc_apply_baroclinic proc~ocean_obc_apply_baroclinic->proc~apply_orlanski_east 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_jk
real(kind=wp), private :: dhdx_jk
real(kind=wp), private :: g2
integer, private :: j
integer, private :: k
real(kind=wp), private :: rx_new
real(kind=wp), private :: rx_raw
real(kind=wp), private :: tau
real(kind=wp), private :: u_b
real(kind=wp), private :: u_int_1

Source Code

   pure subroutine apply_orlanski_east(u_layer, &
                                       rx, u_prev, &
                                       nx_total, ny_total, nz, &
                                       i_e, j0, j1, &
                                       rx_max, gamma_u, &
                                       tau_in, tau_out, dt, u_data)
      !! Orlanski radiation for the east open edge (Orlanski 1976).
      !! Interior face index I = i_e-1 (1st), I-1 = i_e-2 (2nd).
      !! Outward normal = +x.  dhdx = u(i_e-1) - u(i_e-2) (eastward gradient).
      integer, intent(in) :: nx_total, ny_total, nz
      real(wp), intent(inout) :: u_layer(nx_total + 1, ny_total, nz)
      real(wp), intent(inout) :: rx(ny_total, nz)
      real(wp), intent(in)    :: u_prev(ny_total, nz)
      integer, intent(in) :: i_e, j0, j1
      real(wp), intent(in) :: rx_max, gamma_u, tau_in, tau_out, dt, u_data

      integer  :: j, k
      real(wp) :: u_int_1
      real(wp) :: dhdt_jk, dhdx_jk, rx_raw, rx_new, u_b
      real(wp) :: tau, g2

      do concurrent(j=j0:j1) &
         local(k, u_int_1, dhdt_jk, dhdx_jk, rx_raw, rx_new, u_b, tau, g2)

         do k = 1, nz
            u_int_1 = u_layer(i_e - 1, j, k)

            ! East edge: outward = +x; dhdx = u(i_e-1) - u(i_e-2).
            dhdt_jk = u_prev(j, k) - u_int_1
            dhdx_jk = u_int_1 - u_layer(i_e - 2, j, k)

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

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

            ! Per-layer anchor — see the west kernel's comment.
            u_b = (u_layer(i_e, j, k) + rx_new*u_int_1)/(1.0_wp + rx_new)

            if (dhdt_jk*dhdx_jk <= 0.0_wp) then
               tau = tau_in
            else
               tau = tau_out
            end if
            if (tau > 0.0_wp) then
               g2 = dt/(tau + dt)
               u_b = (1.0_wp - g2)*u_b + g2*u_data
            end if

            u_layer(i_e, j, k) = u_b
         end do
      end do
   end subroutine apply_orlanski_east