Set the per-variable weights w_v >= 0 of the gate energy g_e = sum_v w_v E_tot,e,v, where E_tot,e,v is the exact L2 energy of variable v on the reference element.
E_tot is a convex quadratic functional of the state, so g_e with these weights is a discrete quadratic entropy integral over the element: taking w from the diagonal of the entropy Hessian makes the gate an entropy (energy) measure rather than a raw sum of squared variables, which is what makes it meaningful for a system whose variables carry different units and magnitudes. For LinearEuler3D, whose entropy density is 0.5rho0(u^2 + v^2 + w^2) + 0.5*P^2/(rho0 c^2) and whose variables 5 and 6 are the time-constant background fields c and rho0,
w = [ 0.5rho0, 0.5rho0, 0.5rho0, 0.5/(rho0c0**2), 0.0, 0.0 ]
is the entropy-weighted gate, and the zero weights keep the (large) background fields from setting the scale.
size(w) must equal the solution's nVar at Estimate time. Every weight must be >= 0 and at least one must be > 0, else no element would ever clear the gate. Note that a weight on a variable outside the driving-variable selection makes Estimate transform that variable too (it is needed for the gate), which costs one extra modal transform per element per such variable.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(RefinementIndicator3D_t), | intent(inout) | :: | this | |||
| real(kind=prec), | intent(in) | :: | w(:) |
subroutine SetEnergyWeights_RefinementIndicator3D_t(this,w)
!! Set the per-variable weights w_v >= 0 of the gate energy g_e = sum_v w_v E_tot,e,v, where
!! E_tot,e,v is the exact L2 energy of variable v on the reference element.
!!
!! E_tot is a convex quadratic functional of the state, so g_e with these weights is a
!! discrete quadratic entropy integral over the element: taking w from the diagonal of the
!! entropy Hessian makes the gate an entropy (energy) measure rather than a raw sum of
!! squared variables, which is what makes it meaningful for a system whose variables carry
!! different units and magnitudes. For LinearEuler3D, whose entropy density is
!! 0.5*rho0*(u^2 + v^2 + w^2) + 0.5*P^2/(rho0 c^2) and whose variables 5 and 6 are the
!! time-constant background fields c and rho0,
!!
!! w = [ 0.5*rho0, 0.5*rho0, 0.5*rho0, 0.5/(rho0*c0**2), 0.0, 0.0 ]
!!
!! is the entropy-weighted gate, and the zero weights keep the (large) background fields from
!! setting the scale.
!!
!! size(w) must equal the solution's nVar at Estimate time. Every weight must be >= 0 and at
!! least one must be > 0, else no element would ever clear the gate. Note that a weight on a
!! variable outside the driving-variable selection makes Estimate transform that variable too
!! (it is needed for the gate), which costs one extra modal transform per element per such
!! variable.
implicit none
class(RefinementIndicator3D_t),intent(inout) :: this
real(prec),intent(in) :: w(:)
! Local
integer :: v
logical :: anyPositive
if(size(w) < 1) then
print*,__FILE__,':',__LINE__, &
' : Error : SetEnergyWeights requires at least one weight.'
stop 1
endif
anyPositive = .false.
do v = 1,size(w)
if(w(v) < 0.0_prec) then
print*,__FILE__,':',__LINE__, &
' : Error : energy weights must be non-negative.'
stop 1
endif
if(w(v) > 0.0_prec) anyPositive = .true.
enddo
if(.not. anyPositive) then
print*,__FILE__,':',__LINE__, &
' : Error : at least one energy weight must be positive.'
stop 1
endif
if(this%nVarWeights /= size(w)) then
if(associated(this%energyWeight)) deallocate(this%energyWeight)
allocate(this%energyWeight(1:size(w)))
this%nVarWeights = size(w)
endif
do v = 1,size(w)
this%energyWeight(v) = w(v)
enddo
this%energyWeightsSet = .true.
endsubroutine SetEnergyWeights_RefinementIndicator3D_t