Closed valeriabarra closed 2 years ago
Having looked at this a bit, it looks like the Trixi team have already added a stage callback mechanism to OrdinaryDiffEq: https://trixi-framework.github.io/Trixi.jl/stable/callbacks/#Stage-callbacks (thanks @ranocha!)
The SSP coefficients of the methods can be queried as ssp_coefficient(alg). All explicit SSP methods take two optional arguments
SSPXY(stage_limiter!, step_limiter!)
, wherestage_limiter!
andstep_limiter!
are functions taking arguments of the formlimiter!(u, integrator, p, t)
. Here, u is the new solution value (updated inplace) after an explicit Euler stage / the whole time step , integrator the ODE integrator, and t the current time. These limiters can be used to enforce physical constraints, e.g. the positivity preserving limiters of Zhang and Shu (Zhang, Xiangxiong, and Chi-Wang Shu. "Maximum-principle-satisfying and positivity-preserving high-order schemes for conservation laws: survey and new developments." Proceedings of the Royal Society of London A: Mathematical, Physical and Engineering Sciences. The Royal Society, 2011.).
Thanks for these pointers! I'm going to check OrdinaryDiffEq's limiter interface and how this Zhang-Shu limiter differs from the suggested one from Guba et al. (At a very first glance. Xhang-Shu seems to be formulated for DG and FV-WENO discretizations)
But I can see how they used the stage callbacks. Thanks
Yes, I think that should work. I added this limiter interface specifically for hyperbolic PDE discretizations. All explicit SSPRK methods should support them and many additional RK methods designed for hyperbolic PDEs, too. Feel free to ping me if anything is unclear.
Okay, having looked at the OrdinaryDiffEqs docs and source code, as well as DiffEqCallbacks.jl's docs, and from the very useful example on how to define new callbacks by the Trixi team, I think I have a clearer understanding of what we want to do.
We most certainly want to set both the stage_limiter!
and step_limiter!
. My current understanding from the Guba paper is that stage_limiter!
will not have the DSS internal call, while the step_limiter!
will. We can group them (together with additional optional callbacks, like for viz and other queries) in a CallbackSet
that is then passed to the solve
call. Thanks again for the pointer and to the Trixi team for writing such a useful example!
Skeleton started in this branch valeria/opt-based-limiters
@simonbyrne for Point 2.c) above, would you agree that it would be easier to extract values of a Field ρ
over an elem e
, say ρ_e
, and then simply find its integral using sum(ρ_e)
, than overriding an element-wise sum
method?
For 2.b), would this Quadprog package be ok? I'm not sure if I can use it with our Fields
, both scalar-valued and vector-valued fields
@simonbyrne for Point 2.c) above, would you agree that it would be easier to extract values of a Field
ρ
over an eleme
, sayρ_e
, and then simply find its integral usingsum(ρ_e)
, than overriding an element-wisesum
method?
I think so: hopefully sum(slab(field, e))
should work (but I'm not sure).
For 2.b), would this Quadprog package be ok? I'm not sure if I can use it with our
Fields
, both scalar-valued and vector-valued fields
Possibly? The easiest option initially is probably to pull out the underlying array (using parent
). Once you get it to work, we can then try to figure out a nicer interface.
since it is local to each element, they are solved independently and the problem is fairly small do you need a full blown ipsolver? would it be possible to construct the linear system directly and do a fixed number of newton iterations?
Implement element-local bounds-preserving limiters. Two limiters, one quasimonotone (OP1) and one sign-preserving (OP2) to prevent negative values of ρ, are defined in the reference paper Guba et al, "Optimization-based limiters for the spectral element method", JCP 2014. These limiters use a local element reconstruction, where quasimonotone and sign-preserving properties are defined with respect to the element nodal values (Gauss-Lobatto nodes).
Each limiter defined in Guba et al. solves a constraint optimization problem completely local to each element (plus neighboring elements to determine suitable min/max bound constraints see Figure below). These are least squares optimization problems with equality and inequality constraints for the reconstructions.
To find the new time step limited quantity of interest (a tracer mixing ratio),
qⁿ⁺¹
, we first split a forward/explicit time step into 2 steps. (This algorithm works for any explicit RK scheme. If the bounds-preserving property is preferred, then can use a Strong Stability Preserving RK-SSP scheme.)q*
, defined locally in each element (may not be continuous across elements).q*
with a second intermediate approximation, denoted byq**
. The simplest, least accurateq**
can be the element average ofq*
. To find a better, higher-accurate approximation we want to find the optimal closest approximation ofq**
toq*
, which requires solving a standard quadratic program (QP), where we minimize the quadratic objective function (i.e., least-square, density-weighted distance betweenq*
andq**
), subject to linear constraints. Hence, we construct the QP, by constrainingq**
by the the min/max of the quantity q,qⁿₘᵢₙ
andqⁿₘₐₓ
, as given by the previous time stepn
, within the given element and its neighboring elements (i.e., over all nodal nodes in the stencil used to compute∇q
).Rough plan and current questions:
ODEProblem
. One is astage_callback
applied at each RK stage (whoserhs
function is not DSS'ed ?) and one is astep_callback
applied at the end of each new (n+1
) step (which includes the DSS step).Quadprog.jl
?)sum(ρ)_e
, for elemente
(or perhaps, more simply, extract the Field values over eleme
,ρ_e
, and just usesum(ρ_e)
).