redi_face_coeffs Subroutine

private pure subroutine redi_face_coeffs(nz, ns, kb, kt, hL, tL, sL, hR, tR, sR, eos, PoLo, PoRo, KoLo, KoRo, hEffo)

The per-face Phase-A core: build both columns TOP-DOWN on the open window kb..kt (the whole column off the closed-face path), run the sweep on its nk = kt-kb+1 layers, and store PoL/PoR/KoL/KoR/hEff in the FULL top-down frame (Ko + nz - kt). The k-flip is confined to the Phase-B scatter; keeping Po/Ko top-down here lets the flux re-use the sweep’s interface-edge convention with no position arithmetic on the flipped frame. A short window (nk < nz) leaves 2*(nz-nk) trailing surfaces, filled as inert padding: the last surface repeated and hEff = 0, which Phase B skips.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nz
integer, intent(in) :: ns
integer, intent(in) :: kb

Native (bottom-up) open window, 1 <= kb <= kt <= nz.

integer, intent(in) :: kt

Native (bottom-up) open window, 1 <= kb <= kt <= nz.

real(kind=wp), intent(in) :: hL(nz)
real(kind=wp), intent(in) :: tL(nz)
real(kind=wp), intent(in) :: sL(nz)
real(kind=wp), intent(in) :: hR(nz)
real(kind=wp), intent(in) :: tR(nz)
real(kind=wp), intent(in) :: sR(nz)
type(eos_t), intent(in) :: eos
real(kind=wp), intent(out) :: PoLo(ns)
real(kind=wp), intent(out) :: PoRo(ns)
integer, intent(out) :: KoLo(ns)
integer, intent(out) :: KoRo(ns)
real(kind=wp), intent(out) :: hEffo(ns-1)

Calls

proc~~redi_face_coeffs~~CallsGraph proc~redi_face_coeffs redi_face_coeffs proc~redi_build_column redi_build_column proc~redi_face_coeffs->proc~redi_build_column proc~redi_neutral_positions_continuous redi_neutral_positions_continuous proc~redi_face_coeffs->proc~redi_neutral_positions_continuous proc~eos_density_specvol_derivs eos_density_specvol_derivs proc~redi_build_column->proc~eos_density_specvol_derivs proc~redi_interface_scalar redi_interface_scalar proc~redi_build_column->proc~redi_interface_scalar rdb_vl_column_conc rdb_vl_column_conc proc~redi_build_column->rdb_vl_column_conc proc~redi_absolute_position redi_absolute_position proc~redi_neutral_positions_continuous->proc~redi_absolute_position proc~redi_interpolate_position redi_interpolate_position proc~redi_neutral_positions_continuous->proc~redi_interpolate_position proc~roquet_spv_point roquet_spv_point proc~eos_density_specvol_derivs->proc~roquet_spv_point 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_coeffs~~CalledByGraph proc~redi_face_coeffs redi_face_coeffs proc~redi_calc_coeffs_x redi_calc_coeffs_x proc~redi_calc_coeffs_x->proc~redi_face_coeffs proc~redi_calc_coeffs_y redi_calc_coeffs_y proc~redi_calc_coeffs_y->proc~redi_face_coeffs proc~redi_calc_coeffs redi_calc_coeffs proc~redi_calc_coeffs->proc~redi_calc_coeffs_x proc~redi_calc_coeffs->proc~redi_calc_coeffs_y proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~redi_calc_coeffs 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 :: Pl(NZ_STACK_MAX+1)
real(kind=wp), private :: Pr(NZ_STACK_MAX+1)
real(kind=wp), private :: Sli(NZ_STACK_MAX+1)
real(kind=wp), private :: Sri(NZ_STACK_MAX+1)
real(kind=wp), private :: Tli(NZ_STACK_MAX+1)
real(kind=wp), private :: Tri(NZ_STACK_MAX+1)
real(kind=wp), private :: dRdSl(NZ_STACK_MAX+1)
real(kind=wp), private :: dRdSr(NZ_STACK_MAX+1)
real(kind=wp), private :: dRdTl(NZ_STACK_MAX+1)
real(kind=wp), private :: dRdTr(NZ_STACK_MAX+1)
integer, private :: koff
integer, private :: ks
integer, private :: nk
integer, private :: nsw
real(kind=wp), private :: pa_to_h

Source Code

   pure subroutine redi_face_coeffs(nz, ns, kb, kt, hL, tL, sL, hR, tR, sR, eos, &
                                    PoLo, PoRo, KoLo, KoRo, hEffo)
      !! The per-face Phase-A core: build both columns TOP-DOWN on the open
      !! window `kb..kt` (the whole column off the closed-face path), run the
      !! sweep on its `nk = kt-kb+1` layers, and store PoL/PoR/KoL/KoR/hEff in
      !! the FULL top-down frame (`Ko + nz - kt`).  The k-flip is confined to
      !! the Phase-B scatter; keeping Po/Ko top-down here lets the flux re-use
      !! the sweep's interface-edge convention with no position arithmetic on
      !! the flipped frame.  A short window (`nk < nz`) leaves `2*(nz-nk)`
      !! trailing surfaces, filled as inert padding: the last surface
      !! repeated and `hEff = 0`, which Phase B skips.
      !$acc routine seq
      integer, intent(in) :: nz, ns
      integer, intent(in) :: kb, kt
         !! Native (bottom-up) open window, `1 <= kb <= kt <= nz`.
      real(wp), intent(in) :: hL(nz), tL(nz), sL(nz), hR(nz), tR(nz), sR(nz)
      type(eos_t), intent(in) :: eos
      real(wp), intent(out) :: PoLo(ns), PoRo(ns), hEffo(ns - 1)
      integer, intent(out) :: KoLo(ns), KoRo(ns)
      real(wp) :: Pl(NZ_STACK_MAX + 1), Tli(NZ_STACK_MAX + 1), Sli(NZ_STACK_MAX + 1)
      real(wp) :: dRdTl(NZ_STACK_MAX + 1), dRdSl(NZ_STACK_MAX + 1)
      real(wp) :: Pr(NZ_STACK_MAX + 1), Tri(NZ_STACK_MAX + 1), Sri(NZ_STACK_MAX + 1)
      real(wp) :: dRdTr(NZ_STACK_MAX + 1), dRdSr(NZ_STACK_MAX + 1)
      real(wp) :: pa_to_h
      integer :: ks, nk, nsw, koff

      nk = kt - kb + 1
      nsw = 2*nk + 2
      koff = nz - kt
      call redi_build_column(nz, kb, kt, hL, tL, sL, eos, Pl, Tli, Sli, dRdTl, dRdSl)
      call redi_build_column(nz, kb, kt, hR, tR, sR, eos, Pr, Tri, Sri, dRdTr, dRdSr)

      call redi_neutral_positions_continuous(nk, Pl, Tli, Sli, dRdTl, dRdSl, &
                                             Pr, Tri, Sri, dRdTr, dRdSr, &
                                             PoLo, PoRo, KoLo, KoRo, hEffo)
      ! The continuous sweep computes hEff from interface-PRESSURE differences
      ! (Pa, since the position coordinate is the hydrostatic pressure
      ! g*rho0*h), but the flux divergence and Coef consume hEff in THICKNESS
      ! units (m).  Convert Pa -> m by dividing by H_to_pa = g*rho0 (MOM6
      ! neutral_diffusion lines ~588: uhEff /= H_to_pa).  Po/Ko stay TOP-DOWN;
      ! the only k-flip is the Phase-B scatter.
      pa_to_h = 1.0_wp/(GRAVITY*eos%rho0)
      do ks = 1, nsw - 1
         hEffo(ks) = hEffo(ks)*pa_to_h
      end do
      ! Window frame -> full top-down frame (`koff = 0` off the closed-face
      ! path), then the inert padding of a short window.
      if (koff /= 0) then
         do ks = 1, nsw
            KoLo(ks) = KoLo(ks) + koff
            KoRo(ks) = KoRo(ks) + koff
         end do
      end if
      do ks = nsw + 1, ns
         PoLo(ks) = PoLo(nsw)
         PoRo(ks) = PoRo(nsw)
         KoLo(ks) = KoLo(nsw)
         KoRo(ks) = KoRo(nsw)
         hEffo(ks - 1) = 0.0_wp
      end do
   end subroutine redi_face_coeffs