weno3_recon Function

public pure function weno3_recon(qm1, q0, qp1, qp2, adv_vel) result(qf)

3rd-order WENO-Z reconstruction of a corner quantity onto the face between q0 and qp1, upwind-biased on the sign of the advecting velocity adv_vel (MOM6 weno_three_h_weight_reconstruction). Blends a central candidate c0 (ideal weight 2/3) with an upwind-side linear extrapolation c1 (1/3); the WENO-Z nonlinear factor (1+tau/b)^2 collapses the weight of whichever candidate straddles a PV front. In smooth flow -> the fixed upwind-biased 3rd-order stencil; across a jump -> the ENO (non-oscillatory) branch. f-baked absolute vorticity is passed in (rdb’s vector-invariant form multiplies the result by the thickness- weighted face velocity, so there is no separate h-divide – the mass-weighting lives in that velocity, not in a PV*vh product).

Branchless apart from the upwind sign pick and MOM6’s exact divide-guard (|b| <= eps*tau -> degenerate factor), both scalar per-lane predicates – GPU-safe in do concurrent.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: qm1
real(kind=wp), intent(in) :: q0
real(kind=wp), intent(in) :: qp1
real(kind=wp), intent(in) :: qp2
real(kind=wp), intent(in) :: adv_vel

Return Value real(kind=wp)


Calls

proc~~weno3_recon~~CallsGraph proc~weno3_recon weno3_recon proc~fac_weno fac_weno proc~weno3_recon->proc~fac_weno

Called by

proc~~weno3_recon~~CalledByGraph proc~weno3_recon weno3_recon proc~coriolis_adv_compute_tendencies_sadourny coriolis_adv_compute_tendencies_sadourny proc~coriolis_adv_compute_tendencies_sadourny->proc~weno3_recon proc~coriolis_adv_compute_tendencies coriolis_adv_compute_tendencies proc~coriolis_adv_compute_tendencies->proc~coriolis_adv_compute_tendencies_sadourny proc~run_stage run_stage proc~run_stage->proc~coriolis_adv_compute_tendencies proc~run_stage_split run_stage_split proc~run_stage_split->proc~coriolis_adv_compute_tendencies proc~ocean_dyn_step ocean_dyn_step proc~ocean_dyn_step->proc~run_stage 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 proc~engine_step->proc~ocean_dyn_step_split

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: b0
real(kind=wp), private :: b1
real(kind=wp), private :: c0
real(kind=wp), private :: c1
real(kind=wp), private :: f0
real(kind=wp), private :: f1
real(kind=wp), private :: sinv
real(kind=wp), private :: tau
real(kind=wp), private :: w0
real(kind=wp), private :: w1

Source Code

   pure function weno3_recon(qm1, q0, qp1, qp2, adv_vel) result(qf)
      !! 3rd-order WENO-Z reconstruction of a corner quantity onto the face
      !! between `q0` and `qp1`, upwind-biased on the sign of the advecting
      !! velocity `adv_vel` (MOM6 `weno_three_h_weight_reconstruction`).
      !! Blends a central candidate `c0` (ideal weight 2/3) with an
      !! upwind-side linear extrapolation `c1` (1/3); the WENO-Z nonlinear
      !! factor `(1+tau/b)^2` collapses the weight of whichever candidate
      !! straddles a PV front.  In smooth flow -> the fixed upwind-biased
      !! 3rd-order stencil; across a jump -> the ENO (non-oscillatory)
      !! branch.  `f`-baked absolute vorticity is passed in (rdb's
      !! vector-invariant form multiplies the result by the thickness-
      !! weighted face velocity, so there is no separate `h`-divide -- the
      !! mass-weighting lives in that velocity, not in a PV*vh product).
      !!
      !! Branchless apart from the upwind sign pick and MOM6's exact
      !! divide-guard (`|b| <= eps*tau` -> degenerate factor), both scalar
      !! per-lane predicates -- GPU-safe in `do concurrent`.
      !$acc routine seq
      real(wp), intent(in) :: qm1, q0, qp1, qp2
      real(wp), intent(in) :: adv_vel
      real(wp) :: qf
      real(wp) :: c0, c1, b0, b1, tau, w0, w1, f0, f1, sinv

      if (adv_vel > 0.0_wp) then
         c0 = 0.5_wp*(q0 + qp1)
         c1 = 0.5_wp*(-qm1 + 3.0_wp*q0)
         b0 = (q0 - qp1)**2
         b1 = (qm1 - q0)**2
      else
         c0 = 0.5_wp*(qp1 + q0)
         c1 = 0.5_wp*(-qp2 + 3.0_wp*qp1)
         b0 = (qp1 - q0)**2
         b1 = (qp2 - qp1)**2
      end if

      tau = abs(b0 - b1)
      f0 = fac_weno(tau, b0)
      f1 = fac_weno(tau, b1)
      w0 = (2.0_wp/3.0_wp)*f0
      w1 = (1.0_wp/3.0_wp)*f1
      sinv = 1.0_wp/(w0 + w1)
      qf = (w0*c0 + w1*c1)*sinv
   end function weno3_recon