apply_orlanski_west Subroutine

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

Orlanski radiation for the west open edge (Orlanski 1976). Interior face index I = i_w+1 (1st), I-1 = i_w+2 (2nd). Outward normal = -x. dhdx = u(i_w+1) - u(i_w+2) (westward gradient). rx updated in-place; u_prev NOT updated here (done by the caller after all edges are set).

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_w
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_west~~CallsGraph proc~apply_orlanski_west apply_orlanski_west local local proc~apply_orlanski_west->local

Called by

proc~~apply_orlanski_west~~CalledByGraph proc~apply_orlanski_west apply_orlanski_west proc~ocean_obc_apply_baroclinic ocean_obc_apply_baroclinic proc~ocean_obc_apply_baroclinic->proc~apply_orlanski_west 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_west(u_layer, &
                                       rx, u_prev, &
                                       nx_total, ny_total, nz, &
                                       i_w, j0, j1, &
                                       rx_max, gamma_u, &
                                       tau_in, tau_out, dt, u_data)
      !! Orlanski radiation for the west open edge (Orlanski 1976).
      !! Interior face index I = i_w+1 (1st), I-1 = i_w+2 (2nd).
      !! Outward normal = -x.  dhdx = u(i_w+1) - u(i_w+2) (westward gradient).
      !! rx updated in-place; u_prev NOT updated here (done by the caller
      !! after all edges are set).
      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_w, 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_w + 1, j, k)  ! first interior face velocity

            ! West edge: outward = -x; dhdx = u(i_w+1) - u(i_w+2).
            dhdt_jk = u_prev(j, k) - u_int_1
            dhdx_jk = u_int_1 - u_layer(i_w + 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

            ! Running-mean update (gamma_u = 1 = instant, no memory).
            rx_new = (1.0_wp - gamma_u)*rx(j, k) + gamma_u*rx_raw
            rx(j, k) = rx_new

            ! Semi-implicit boundary update: u_b = (u_b_old + rx*u_int_1)/(1+rx).
            ! Anchors on the wall face's OWN per-layer value, so rx=0 leaves the
            ! baroclinic structure untouched (anchoring on BT velocity would
            ! collapse the boundary shear every quiet phase).
            u_b = (u_layer(i_w, j, k) + rx_new*u_int_1)/(1.0_wp + rx_new)

            ! Optional nudging: "incoming" = dhdt*dhdx <= 0 ⟹ tau_in.
            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_w, j, k) = u_b
         end do
      end do
   end subroutine apply_orlanski_west