redi_face_flux Subroutine

private pure subroutine redi_face_flux(nz, ns, nxc, nyc, nfa, nfb, h_layer, hTr_in, iL, jL, iR, jR, fa, fb, PoL, PoR, KoL, KoR, hEff, kb, kt, use_open, coef, is_left, dTr)

Accumulate ONE C-grid face’s neutral-surface tracer flux into the owning cell’s dTr. Builds the left/right tracer columns from the READ-ONLY snapshot hTr_in (the live hTr is also written by the loop — reading it would be a do-concurrent read-write race) and loops the ns-1 neutral sublayers. The per-face column locals live in this frame to keep the caller’s loop-body footprint small. is_left: this cell is the LEFT (west/south) column ⇒ +flx into native layer nz+1-KoL; else the RIGHT column ⇒ -flx into nz+1-KoR. (iL,jL)/(iR,jR) index the columns; (fa,fb) the faces. kb..kt is the face’s Phase-A open window (1..nz off the z-level closed-face path): the tracer columns are reconstructed on it alone and the full-frame Ko are read in the window frame (Ko - nz + kt). An empty window, or (use_open) one whose layers are no longer all live on both sides, contributes nothing — both cells of the face take the same decision from the same h.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nz
integer, intent(in) :: ns
integer, intent(in) :: nxc
integer, intent(in) :: nyc
integer, intent(in) :: nfa
integer, intent(in) :: nfb
real(kind=wp), intent(in) :: h_layer(nxc,nyc,nz)
real(kind=wp), intent(in) :: hTr_in(nxc,nyc,nz)
integer, intent(in) :: iL
integer, intent(in) :: jL
integer, intent(in) :: iR
integer, intent(in) :: jR
integer, intent(in) :: fa
integer, intent(in) :: fb
real(kind=wp), intent(in) :: PoL(nfa,nfb,ns)
real(kind=wp), intent(in) :: PoR(nfa,nfb,ns)
integer, intent(in) :: KoL(nfa,nfb,ns)
integer, intent(in) :: KoR(nfa,nfb,ns)
real(kind=wp), intent(in) :: hEff(nfa,nfb,ns-1)
integer, intent(in) :: kb
integer, intent(in) :: kt
logical, intent(in) :: use_open
real(kind=wp), intent(in) :: coef
logical, intent(in) :: is_left
real(kind=wp), intent(inout) :: dTr(nz)

Calls

proc~~redi_face_flux~~CallsGraph proc~redi_face_flux redi_face_flux proc~redi_sublayer_dt redi_sublayer_dT proc~redi_face_flux->proc~redi_sublayer_dt proc~redi_tracer_column redi_tracer_column proc~redi_face_flux->proc~redi_tracer_column rdb_vl_is_live rdb_vl_is_live proc~redi_face_flux->rdb_vl_is_live proc~redi_ppm_ave redi_ppm_ave proc~redi_sublayer_dt->proc~redi_ppm_ave proc~redi_signum1 redi_signum1 proc~redi_sublayer_dt->proc~redi_signum1 proc~redi_interface_scalar redi_interface_scalar proc~redi_tracer_column->proc~redi_interface_scalar proc~redi_tracer_column->proc~redi_signum1 rdb_vl_column_conc rdb_vl_column_conc proc~redi_tracer_column->rdb_vl_column_conc proc~redi_plm_diff redi_plm_diff proc~redi_interface_scalar->proc~redi_plm_diff proc~redi_ppm_edge redi_ppm_edge proc~redi_interface_scalar->proc~redi_ppm_edge proc~redi_fv_diff redi_fv_diff proc~redi_plm_diff->proc~redi_fv_diff proc~redi_signum redi_signum proc~redi_plm_diff->proc~redi_signum

Called by

proc~~redi_face_flux~~CalledByGraph proc~redi_face_flux redi_face_flux proc~redi_apply_flux_impl redi_apply_flux_impl proc~redi_apply_flux_impl->proc~redi_face_flux proc~redi_apply_flux redi_apply_flux proc~redi_apply_flux->proc~redi_apply_flux_impl proc~run_continuity_chain run_continuity_chain proc~run_continuity_chain->proc~redi_apply_flux proc~run_stage_split run_stage_split proc~run_stage_split->proc~run_continuity_chain proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~run_stage_split

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: TiL(NZ_STACK_MAX+1)
real(kind=wp), private :: TiR(NZ_STACK_MAX+1)
real(kind=wp), private :: TlL(NZ_STACK_MAX)
real(kind=wp), private :: TlR(NZ_STACK_MAX)
real(kind=wp), private :: aLL(NZ_STACK_MAX)
real(kind=wp), private :: aLR(NZ_STACK_MAX)
real(kind=wp), private :: aRL(NZ_STACK_MAX)
real(kind=wp), private :: aRR(NZ_STACK_MAX)
real(kind=wp), private :: dtdiff
real(kind=wp), private :: flx
real(kind=wp), private :: hcL(NZ_STACK_MAX)
real(kind=wp), private :: hcR(NZ_STACK_MAX)
integer, private :: k
integer, private :: knat
integer, private :: koff
integer, private :: ks
integer, private :: nk
real(kind=wp), private :: trcL(NZ_STACK_MAX)
real(kind=wp), private :: trcR(NZ_STACK_MAX)

Source Code

   pure subroutine redi_face_flux(nz, ns, nxc, nyc, nfa, nfb, h_layer, hTr_in, &
                                  iL, jL, iR, jR, fa, fb, &
                                  PoL, PoR, KoL, KoR, hEff, kb, kt, use_open, &
                                  coef, is_left, dTr)
      !$acc routine seq
      !! Accumulate ONE C-grid face's neutral-surface tracer flux into the
      !! owning cell's `dTr`.  Builds the left/right tracer columns from the
      !! READ-ONLY snapshot `hTr_in` (the live `hTr` is also written by the
      !! loop — reading it would be a do-concurrent read-write race) and loops
      !! the `ns-1` neutral sublayers.  The per-face column locals live in this
      !! frame to keep the caller's loop-body footprint small.
      !! `is_left`: this cell is the LEFT (west/south) column ⇒ `+flx` into
      !! native layer `nz+1-KoL`; else the RIGHT column ⇒ `-flx` into
      !! `nz+1-KoR`.  `(iL,jL)`/`(iR,jR)` index the columns; `(fa,fb)` the faces.
      !! `kb..kt` is the face's Phase-A open window (`1..nz` off the z-level
      !! closed-face path): the tracer columns are reconstructed on it alone
      !! and the full-frame `Ko` are read in the window frame (`Ko - nz +
      !! kt`).  An empty window, or (`use_open`) one whose layers are no
      !! longer all live on both sides, contributes nothing — both cells of
      !! the face take the same decision from the same `h`.
      integer, intent(in) :: nz, ns, nxc, nyc, nfa, nfb
      integer, intent(in) :: iL, jL, iR, jR, fa, fb
      real(wp), intent(in) :: h_layer(nxc, nyc, nz), hTr_in(nxc, nyc, nz)
      real(wp), intent(in) :: PoL(nfa, nfb, ns), PoR(nfa, nfb, ns)
      integer, intent(in) :: KoL(nfa, nfb, ns), KoR(nfa, nfb, ns)
      real(wp), intent(in) :: hEff(nfa, nfb, ns - 1)
      integer, intent(in) :: kb, kt
      logical, intent(in) :: use_open
      real(wp), intent(in) :: coef
      logical, intent(in) :: is_left
      real(wp), intent(inout) :: dTr(nz)

      integer :: k, ks, knat, nk, koff
      real(wp) :: hcL(NZ_STACK_MAX), trcL(NZ_STACK_MAX)
      real(wp) :: hcR(NZ_STACK_MAX), trcR(NZ_STACK_MAX)
      real(wp) :: TlL(NZ_STACK_MAX), TiL(NZ_STACK_MAX + 1), aLL(NZ_STACK_MAX), aRL(NZ_STACK_MAX)
      real(wp) :: TlR(NZ_STACK_MAX), TiR(NZ_STACK_MAX + 1), aLR(NZ_STACK_MAX), aRR(NZ_STACK_MAX)
      real(wp) :: dtdiff, flx

      if (kt < kb) return
      if (use_open) then
         do k = kb, kt
            if (.not. (rdb_vl_is_live(h_layer(iL, jL, k)) .and. &
                       rdb_vl_is_live(h_layer(iR, jR, k)))) return
         end do
      end if
      nk = kt - kb + 1
      koff = nz - kt
      do k = 1, nz
         hcL(k) = h_layer(iL, jL, k)
         trcL(k) = hTr_in(iL, jL, k)
         hcR(k) = h_layer(iR, jR, k)
         trcR(k) = hTr_in(iR, jR, k)
      end do
      call redi_tracer_column(kb, kt, hcL, trcL, TlL, TiL, aLL, aRL)
      call redi_tracer_column(kb, kt, hcR, trcR, TlR, TiR, aLR, aRR)
      do ks = 1, ns - 1
         if (hEff(fa, fb, ks) /= 0.0_wp) then
            dtdiff = redi_sublayer_dT(nk, KoL(fa, fb, ks) - koff, KoL(fa, fb, ks + 1) - koff, &
                                      KoR(fa, fb, ks) - koff, KoR(fa, fb, ks + 1) - koff, &
                                      PoL(fa, fb, ks), PoL(fa, fb, ks + 1), &
                                      PoR(fa, fb, ks), PoR(fa, fb, ks + 1), &
                                      TlL, TiL, aLL, aRL, TlR, TiR, aLR, aRR)
            flx = dtdiff*hEff(fa, fb, ks)*coef
            if (is_left) then
               knat = nz + 1 - KoL(fa, fb, ks)
               dTr(knat) = dTr(knat) + flx
            else
               knat = nz + 1 - KoR(fa, fb, ks)
               dTr(knat) = dTr(knat) - flx
            end if
         end if
      end do
   end subroutine redi_face_flux