Namespaces | Classes | Enumerations | Functions
Limiters

Limiters to control shocks and surfaces in the solution. More...

Namespaces

 Limiters
 Things relating to limiting.
 

Classes

class  Limiters::Krivodonova< VolumeDim, tmpl::list< Tags... > >
 An implementation of the Krivodonova limiter. More...
 
struct  Limiters::Tags::LimiterCommunicationTag< Metavariables >
 The inbox tag for limiter communication. More...
 
struct  Limiters::Actions::Limit< Metavariables >
 Receive limiter data from neighbors, then apply limiter. More...
 
struct  Limiters::Actions::SendData< Metavariables >
 Send local data needed for limiting. More...
 
class  Limiters::Minmod< VolumeDim, tmpl::list< Tags... > >
 A general minmod slope limiter. More...
 
class  Limiters::Weno< VolumeDim, tmpl::list< Tags... > >
 A compact-stencil WENO limiter for DG. More...
 

Enumerations

enum  Limiters::MinmodType { LambdaPi1, LambdaPiN, Muscl }
 Possible types of the minmod slope limiter and/or troubled-cell indicator. More...
 
enum  Limiters::WenoType { Hweno, SimpleWeno }
 Possible types of the WENO limiter. More...
 

Functions

template<typename Tag , size_t VolumeDim, typename Package >
void Limiters::hweno_modified_neighbor_solution (const gsl::not_null< db::item_type< Tag > *> modified_tensor, const db::item_type< Tag > &local_tensor, const Element< VolumeDim > &element, const Mesh< VolumeDim > &mesh, const LimiterNeighborData< VolumeDim, Package > &neighbor_data, const std::pair< Direction< VolumeDim >, ElementId< VolumeDim >> &primary_neighbor) noexcept
 Compute the HWENO modified solution for a particular tensor from a particular neighbor element. More...
 

Detailed Description

Limiters to control shocks and surfaces in the solution.

Enumeration Type Documentation

◆ MinmodType

enum Limiters::MinmodType
strong

Possible types of the minmod slope limiter and/or troubled-cell indicator.

See also
Limiters::Minmod for a description and reference.

◆ WenoType

enum Limiters::WenoType
strong

Possible types of the WENO limiter.

See also
Limiters::Weno for a description and references.

Function Documentation

◆ hweno_modified_neighbor_solution()

template<typename Tag , size_t VolumeDim, typename Package >
void Limiters::hweno_modified_neighbor_solution ( const gsl::not_null< db::item_type< Tag > *>  modified_tensor,
const db::item_type< Tag > &  local_tensor,
const Element< VolumeDim > &  element,
const Mesh< VolumeDim > &  mesh,
const LimiterNeighborData< VolumeDim, Package > &  neighbor_data,
const std::pair< Direction< VolumeDim >, ElementId< VolumeDim >> &  primary_neighbor 
)
noexcept

Compute the HWENO modified solution for a particular tensor from a particular neighbor element.

The HWENO limiter reconstructs a new solution from the linear combination of the local DG solution and a "modified" solution from each neighbor element. This function computes the modified solution for a particular tensor and neighbor, following Section 3 of [48].

The modified solution associated with a particular neighbor (the "primary" neighbor) is obtained by solving a constrained fit over the local element, the primary neighbor, and the other ("secondary") neighbors of the local element. This fit seeks to minimize in a least-squared sense:

  1. The distance between the modified solution and the original solution on the primary neighbor.
  2. The distance between the cell average of the modified solution and the cell average of the original solution on each secondary neighbor. Note however that one secondary neighbor (or, rarely, several) is excluded from this minimization: the secondary neighbor(s) where the original solution has the most different cell average from the local element. This helps to prevent an outlier (e.g., near a shock) from biasing the fit.

The constraint on the minimization is the following: the cell average of the modified solution on the local element must equal the cell average of the local element's original solution.

Below we give the mathematical form of the constraints described above and show how these are translated into a numerical algorithm.

Consider an element \(I_0\) with neighbors \(I_1, I_2, ...\). For a given tensor component \(u\), the values on each of these elements are \(u^{(0)}, u^{(1)}, u^{(2)}, ...\). Taking for the sake of example the primary neighbor to be \(I_1\), the modified solution \(\phi\) must minimize

\[ \chi^2 = \int_{I_1} (\phi - u^{(1)})^2 dV + \sum_{\ell \in L} \left( \int_{I_{\ell}} ( \phi - u^{(\ell)} ) dV \right)^2, \]

subject to the constaint

\[ C = \int_{I_0} ( \phi - u^{(0)} ) dV = 0. \]

where \(\ell\) ranges over a subset \(L\) of the secondary neighbors. \(L\) excludes the one (or more) secondary neighbor(s) where the mean of \(u\) is the most different from the mean of \(u^{(0)}\). Typically, only one secondary neighbor is excluded, so \(L\) contains two fewer neighbors than the total number of neighbors to the element. Note that in 1D, this implies that \(L\) is the empty set; for each modified solution, one neighbor is the primary neighbor and the other is the excluded neighbor.

The integrals are evaluated by quadrature. We denote the quadrature weights by \(w_s\) and the values of some data \(X\) at the quadrature nodes by \(X_s\). We use subscripts \(r,s\) to denote quadrature nodes on the neighbor and local elements, respectively. The minimization becomes

\[ \chi^2 = \sum_r w^{(1)}_r ( \phi_r - u^{(1)}_r )^2 + \sum_{\ell \in L} \left( \sum_r w^{(\ell)}_r ( \phi_r - u^{(\ell)}_r ) \right)^2, \]

subject to the constraint

\[ C = \sum_s w^{(0)}_s ( \phi_s - u^{(0)}_s ) = 0. \]

Note that \(\phi\) is a function defined on the local element \(I_0\), and so is fully represented by its values \(\phi_s\) at the quadrature points on this element. When evaluating \(\phi\) on element \(I_{\ell}\), we obtain the function values \(\phi_r\) by polynomial extrapolation, \(\phi_r = \sum_s \mathcal{I}^{(\ell)}_{rs} \phi_s\), where \(\mathcal{I}^{(\ell)}_{rs}\) is the interpolation/extrapolation matrix that interpolates data defined at grid points \(x_s\) and evaluates it at grid points \(x_r\) of \(I_{\ell}\). Thus,

\[ \chi^2 = \sum_r w^{(1)}_r \left( \sum_s \mathcal{I}^{(1)}_{rs} \phi_s - u^{(1)}_r \right)^2 + \sum_{\ell \in L} \left( \sum_r w^{(\ell)}_r \left( \sum_s \mathcal{I}^{(\ell)}_{rs} \phi_s - u^{(\ell)}_r \right) \right)^2. \]

The solution to this optimization problem is found in the standard way, using a Lagrange multiplier \(\lambda\) to impose the constraint:

\[ 0 = \frac{d}{d \phi_s} \left( \chi^2 + \lambda C \right). \]

Working out the differentiation with respect to \(\phi_s\) leads to the linear problem that must be inverted to obtain the solution,

\[ 0 = A_{st} \phi_t - b_s - \lambda w^{(0)}_s, \]

where

\begin{align*} A_{st} &= \sum_r \left( w^{(1)}_r \mathcal{I}^{(1)}_{rs} \mathcal{I}^{(1)}_{rt} \right) + \sum_{\ell \in L} \left( \sum_r \left( w^{(\ell)}_r \mathcal{I}^{(\ell)}_{rt} \right) \cdot \sum_r \left( w^{(\ell)}_r \mathcal{I}^{(\ell)}_{rs} \right) \right) \\ b_s &= \sum_r \left( w^{(1)}_r u^{(1)}_r \mathcal{I}^{(1)}_{rs} \right) + \sum_{\ell \in L} \left( \sum_r \left( w^{(\ell)}_r u^{(\ell)}_r \right) \cdot \sum_r \left( w^{(\ell)}_r \mathcal{I}^{(\ell)}_{rs} \right) \right). \end{align*}

Finally, the solution to the constrained fit is

\begin{align*} \lambda &= - \frac{ \sum_s w^{(0)}_s \left( (A^{-1})_{st} b_t - u^{(0)}_s \right) }{ \sum_s w^{(0)}_s (A^{-1})_{st} w^{(0)}_t } \\ \phi_s &= (A^{-1})_{st} ( b_t + \lambda w^{(0)}_t ). \end{align*}

Note that the matrix \(A\) does not depend on the values of the tensor \(u\), so its inverse \(A^{-1}\) can be precomputed and stored.

Warning
Note also that the implementation currently does not support h- or p-refinement; this is checked by some assertions. The implementation is untested for grids where elements are curved, and it should not be expected to work in these cases.