FinalizeIndicator Subroutine

public subroutine FinalizeIndicator(this, energyScale)

Second phase of an estimate, shared by every backend so that the flags are identical whichever computed the spectra: apply the amplitude gate, take the log10 and set the refine/keep/coarsen flags.

On entry indicator(iel) holds the RAW smoothness ratio S_e from the first phase and gate(iel) the element's gate energy; on exit indicator(iel) = log10(max(S_e,epsilon)) with S_e forced to zero on quiescent elements. Nothing outside Estimate observes the intermediate state.

Elements inside the energy hysteresis band keep their true spectral sigma_e - it stays a faithful diagnostic of the spectrum - but have their flag forced to SELF_AMR_KEEP. So for those elements the flag is deliberately NOT the value thresholding sigma_e would give; that is the whole point of the band.

Arguments

TypeIntentOptionalAttributesName
class(RefinementIndicator3D_t), intent(inout) :: this
real(kind=prec), intent(in) :: energyScale

Called by

proc~~finalizeindicator~~CalledByGraph proc~finalizeindicator FinalizeIndicator proc~estimate_refinementindicator3d_t Estimate_RefinementIndicator3D_t proc~estimate_refinementindicator3d_t->proc~finalizeindicator proc~estimate_refinementindicator3d Estimate_RefinementIndicator3D proc~estimate_refinementindicator3d->proc~finalizeindicator

Contents

Source Code


Source Code

  subroutine FinalizeIndicator(this,energyScale)
    !! Second phase of an estimate, shared by every backend so that the flags are identical
    !! whichever computed the spectra: apply the amplitude gate, take the log10 and set the
    !! refine/keep/coarsen flags.
    !!
    !! On entry indicator(iel) holds the RAW smoothness ratio S_e from the first phase and
    !! gate(iel) the element's gate energy; on exit indicator(iel) = log10(max(S_e,epsilon)) with
    !! S_e forced to zero on quiescent elements. Nothing outside Estimate observes the intermediate
    !! state.
    !!
    !! Elements inside the energy hysteresis band keep their true spectral sigma_e - it stays a
    !! faithful diagnostic of the spectrum - but have their flag forced to SELF_AMR_KEEP. So for
    !! those elements the flag is deliberately NOT the value thresholding sigma_e would give; that
    !! is the whole point of the band.
    implicit none
    class(RefinementIndicator3D_t),intent(inout) :: this
    real(prec),intent(in) :: energyScale
    ! Local
    integer :: iel
    real(prec) :: effFloor,effSignificant,se

    ! The absolute term is the safety net for a field that is identically zero; the relative term
    ! is what releases low-amplitude (but far-above-epsilon) residue behind a passing front.
    effFloor = max(epsilon(1.0_prec),this%relativeEnergyFloor*energyScale)
    ! Upper edge of the band; never below the lower edge, so a degenerate band stays degenerate
    ! even when the absolute term is what sets the lower edge.
    effSignificant = max(effFloor,this%significantEnergyFloor*energyScale)

    do iel = 1,this%nElem
      if(this%gate(iel) <= effFloor) then
        se = 0.0_prec ! quiescent at the scale of the field: perfectly resolved
      else
        se = this%indicator(iel)
      endif
      this%indicator(iel) = log10(max(se,epsilon(1.0_prec)))
      if(this%gate(iel) > effFloor .and. this%gate(iel) <= effSignificant) then
        ! Inside the energy hysteresis band: too weak to justify spending levels on, too strong to
        ! declare resolved. Holding the mesh here is what keeps an element whose amplitude drifts
        ! across the gate from flipping REFINE <-> COARSEN on successive epochs.
        this%flag(iel) = SELF_AMR_KEEP
      elseif(this%indicator(iel) > this%refineThreshold) then
        this%flag(iel) = SELF_AMR_REFINE
      elseif(this%indicator(iel) < this%coarsenThreshold) then
        this%flag(iel) = SELF_AMR_COARSEN
      else
        this%flag(iel) = SELF_AMR_KEEP
      endif
    enddo

  endsubroutine FinalizeIndicator