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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(RefinementIndicator3D_t), | intent(inout) | :: | this | |||
| real(kind=prec), | intent(in) | :: | energyScale |
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