redi_plm_diff Subroutine

private pure subroutine redi_plm_diff(nk, h, s, diff)

PLM van-Leer-limited layer-difference array (MOM6 PLM_diff with c_method=2 finite-volume slope, b_method=1 PCM ends) — the slope input to the PPM edge interpolation.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nk
real(kind=wp), intent(in) :: h(nk)

layer thicknesses

real(kind=wp), intent(in) :: s(nk)

layer scalar values

real(kind=wp), intent(out) :: diff(nk)

limited layer difference (PCM ends)


Calls

proc~~redi_plm_diff~~CallsGraph proc~redi_plm_diff redi_plm_diff 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_plm_diff~~CalledByGraph proc~redi_plm_diff redi_plm_diff proc~redi_interface_scalar redi_interface_scalar proc~redi_interface_scalar->proc~redi_plm_diff proc~redi_build_column redi_build_column proc~redi_build_column->proc~redi_interface_scalar proc~redi_tracer_column redi_tracer_column proc~redi_tracer_column->proc~redi_interface_scalar proc~redi_face_coeffs redi_face_coeffs proc~redi_face_coeffs->proc~redi_build_column proc~redi_face_flux redi_face_flux proc~redi_face_flux->proc~redi_tracer_column proc~redi_apply_flux_impl redi_apply_flux_impl proc~redi_apply_flux_impl->proc~redi_face_flux 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_apply_flux redi_apply_flux proc~redi_apply_flux->proc~redi_apply_flux_impl 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

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: diff_c
real(kind=wp), private :: diff_l
real(kind=wp), private :: diff_r
integer, private :: k

Source Code

   pure subroutine redi_plm_diff(nk, h, s, diff)
      !$acc routine seq
      integer, intent(in) :: nk
      real(wp), intent(in) :: h(nk)     !! layer thicknesses
      real(wp), intent(in) :: s(nk)     !! layer scalar values
      real(wp), intent(out) :: diff(nk)  !! limited layer difference (PCM ends)
      integer :: k
      real(wp) :: diff_l, diff_r, diff_c

      do k = 2, nk - 1
         if ((h(k + 1) + h(k))*(h(k - 1) + h(k)) > 0.0_wp) then
            diff_c = redi_fv_diff(h(k - 1), h(k), h(k + 1), s(k - 1), s(k), s(k + 1))
            diff_l = 2.0_wp*(s(k) - s(k - 1))
            diff_r = 2.0_wp*(s(k + 1) - s(k))
            if (redi_signum(1.0_wp, diff_l)*redi_signum(1.0_wp, diff_r) <= 0.0_wp) then
               diff(k) = 0.0_wp   ! PCM for local extrema
            else
               diff(k) = sign(min(abs(diff_l), abs(diff_c), abs(diff_r)), diff_c)
            end if
         else
            diff(k) = 0.0_wp      ! PCM next to vanished layers
         end if
      end do
      diff(1) = 0.0_wp            ! b_method=1: PCM top
      diff(nk) = 0.0_wp          ! b_method=1: PCM bottom
   end subroutine redi_plm_diff