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