SpECTRE  v2024.04.12
LinearSolver::Schwarz Namespace Reference

Items related to the Schwarz linear solver. More...

Namespaces

namespace  Actions
 Actions related to the Schwarz solver.
 
namespace  OptionTags
 Option tags related to the Schwarz solver.
 
namespace  Tags
 Tags related to the Schwarz solver.
 

Classes

struct  ElementCenteredSubdomainData
 Data on an element-centered subdomain. More...
 
struct  ElementCenteredSubdomainDataIterator
 Iterate over LinearSolver::Schwarz::ElementCenteredSubdomainData More...
 
class  OverlapIterator
 Iterate over grid points in a region that extends partially into the volume. More...
 
struct  Schwarz
 An additive Schwarz subdomain solver for linear systems of equations \(Ax=b\). More...
 
class  SubdomainOperator
 Abstract base class for the subdomain operator, i.e. the linear operator restricted to an element-centered Schwarz subdomain. More...
 

Typedefs

template<size_t Dim>
using OverlapId = DirectionalId< Dim >
 Identifies a subdomain region that overlaps with another element.
 
template<size_t Dim, typename ValueType >
using OverlapMap = DirectionalIdMap< Dim, ValueType >
 Data structure that can store the ValueType on each possible overlap of an element-centered subdomain with its neighbors. Overlaps are identified by their OverlapId.
 

Functions

template<size_t Dim, typename LhsTagsList , typename RhsTagsList >
decltype(auto) operator+ (ElementCenteredSubdomainData< Dim, LhsTagsList > lhs, const ElementCenteredSubdomainData< Dim, RhsTagsList > &rhs)
 
template<size_t Dim, typename LhsTagsList , typename RhsTagsList >
decltype(auto) operator- (ElementCenteredSubdomainData< Dim, LhsTagsList > lhs, const ElementCenteredSubdomainData< Dim, RhsTagsList > &rhs)
 
template<size_t Dim, typename TagsList >
decltype(auto) operator* (const double scalar, ElementCenteredSubdomainData< Dim, TagsList > data)
 
template<size_t Dim, typename TagsList >
decltype(auto) operator* (ElementCenteredSubdomainData< Dim, TagsList > data, const double scalar)
 
template<size_t Dim, typename TagsList >
decltype(auto) operator/ (ElementCenteredSubdomainData< Dim, TagsList > data, const double scalar)
 
template<size_t Dim, typename TagsList >
std::ostreamoperator<< (std::ostream &os, const ElementCenteredSubdomainData< Dim, TagsList > &subdomain_data)
 
template<size_t Dim, typename TagsList >
bool operator== (const ElementCenteredSubdomainData< Dim, TagsList > &lhs, const ElementCenteredSubdomainData< Dim, TagsList > &rhs)
 
template<size_t Dim, typename TagsList >
bool operator!= (const ElementCenteredSubdomainData< Dim, TagsList > &lhs, const ElementCenteredSubdomainData< Dim, TagsList > &rhs)
 
size_t overlap_extent (size_t volume_extent, size_t max_overlap)
 The number of points that an overlap extends into the volume_extent More...
 
template<size_t Dim>
size_t overlap_num_points (const Index< Dim > &volume_extents, size_t overlap_extent, size_t overlap_dimension)
 Total number of grid points in an overlap region that extends overlap_extent points into the volume_extents from either side in the overlap_dimension More...
 
double overlap_width (size_t overlap_extent, const DataVector &collocation_points)
 Width of an overlap extending overlap_extent points into the collocation_points from either side. More...
 
template<size_t Dim, typename VolumeTagsList , typename OverlapTagsList >
void add_overlap_data (const gsl::not_null< Variables< VolumeTagsList > * > volume_data, const Variables< OverlapTagsList > &overlap_data, const Index< Dim > &volume_extents, const size_t overlap_extent, const Direction< Dim > &direction)
 Add the overlap_data to the volume_data
 
DataVector extruding_weight (const DataVector &logical_coords, double width, const Side &side)
 Weights for the solution on an element-centered subdomain, decreasing from 1 to 0.5 towards the side over the logical distance width, and further to 0 over the same distance outside the element. More...
 
DataVector intruding_weight (const DataVector &logical_coords, double width, const Side &side)
 Weights for the intruding solution of a neighboring element-centered subdomain, increasing from 0 to 0.5 towards the side over the logical distance width, and further to 1 over the same distance outside the element. More...
 
template<size_t Dim, typename DataType , typename... TensorStructure>
void data_on_overlap (const gsl::not_null< Tensor< DataType, TensorStructure... > * > restricted_tensor, const Tensor< DataType, TensorStructure... > &tensor, const Index< Dim > &volume_extents, const size_t overlap_extent, const Direction< Dim > &direction)
 The part of the tensor data that lies within the overlap region.
 
template<size_t Dim, typename DataType , typename... TensorStructure>
Tensor< DataType, TensorStructure... > data_on_overlap (const Tensor< DataType, TensorStructure... > &tensor, const Index< Dim > &volume_extents, const size_t overlap_extent, const Direction< Dim > &direction)
 The part of the tensor data that lies within the overlap region.
 
template<size_t Dim, typename OverlapTagsList , typename VolumeTagsList >
void data_on_overlap (const gsl::not_null< Variables< OverlapTagsList > * > overlap_data, const Variables< VolumeTagsList > &volume_data, const Index< Dim > &volume_extents, const size_t overlap_extent, const Direction< Dim > &direction)
 The part of the tensor data that lies within the overlap region.
 
template<size_t Dim, typename TagsList >
Variables< TagsList > data_on_overlap (const Variables< TagsList > &volume_data, const Index< Dim > &volume_extents, const size_t overlap_extent, const Direction< Dim > &direction)
 The part of the tensor data that lies within the overlap region.
 
template<size_t Dim, typename ExtendedTagsList , typename OverlapTagsList >
void extended_overlap_data (const gsl::not_null< Variables< ExtendedTagsList > * > extended_data, const Variables< OverlapTagsList > &overlap_data, const Index< Dim > &volume_extents, const size_t overlap_extent, const Direction< Dim > &direction)
 Extend the overlap data to the full mesh by filling it with zeros outside the overlap region.
 
template<size_t Dim, typename TagsList >
Variables< TagsList > extended_overlap_data (const Variables< TagsList > &overlap_data, const Index< Dim > &volume_extents, const size_t overlap_extent, const Direction< Dim > &direction)
 Extend the overlap data to the full mesh by filling it with zeros outside the overlap region.
 
template<size_t Dim>
void element_weight (gsl::not_null< Scalar< DataVector > * > element_weight, const tnsr::I< DataVector, Dim, Frame::ElementLogical > &logical_coords, const std::array< double, Dim > &overlap_widths, const std::unordered_set< Direction< Dim > > &external_boundaries)
 Weights for data on the central element of an element-centered subdomain. More...
 
template<size_t Dim>
Scalar< DataVectorelement_weight (const tnsr::I< DataVector, Dim, Frame::ElementLogical > &logical_coords, const std::array< double, Dim > &overlap_widths, const std::unordered_set< Direction< Dim > > &external_boundaries)
 Weights for data on the central element of an element-centered subdomain. More...
 
template<size_t Dim>
void intruding_weight (gsl::not_null< Scalar< DataVector > * > weight, const tnsr::I< DataVector, Dim, Frame::ElementLogical > &logical_coords, const Direction< Dim > &direction, const std::array< double, Dim > &overlap_widths, size_t num_intruding_overlaps, const std::unordered_set< Direction< Dim > > &external_boundaries)
 Weights for data on overlap regions intruding into an element-centered subdomain. More...
 
template<size_t Dim>
Scalar< DataVectorintruding_weight (const tnsr::I< DataVector, Dim, Frame::ElementLogical > &logical_coords, const Direction< Dim > &direction, const std::array< double, Dim > &overlap_widths, size_t num_intruding_overlaps, const std::unordered_set< Direction< Dim > > &external_boundaries)
 Weights for data on overlap regions intruding into an element-centered subdomain. More...
 

Detailed Description

Items related to the Schwarz linear solver.

See also
LinearSolver::Schwarz::Schwarz

Function Documentation

◆ element_weight() [1/2]

template<size_t Dim>
Scalar< DataVector > LinearSolver::Schwarz::element_weight ( const tnsr::I< DataVector, Dim, Frame::ElementLogical > &  logical_coords,
const std::array< double, Dim > &  overlap_widths,
const std::unordered_set< Direction< Dim > > &  external_boundaries 
)

Weights for data on the central element of an element-centered subdomain.

Constructs the weighting field

\begin{equation} W(\boldsymbol{\xi}) = \prod^d_{i=0} w(\xi^i) \end{equation}

where \(w(\xi^i)\) is the one-dimensional weighting function described in LinearSolver::Schwarz::extruding_weight and \(\xi^i\) are the element-logical coordinates (see Eq. (41) in [186]).

◆ element_weight() [2/2]

template<size_t Dim>
void LinearSolver::Schwarz::element_weight ( gsl::not_null< Scalar< DataVector > * >  element_weight,
const tnsr::I< DataVector, Dim, Frame::ElementLogical > &  logical_coords,
const std::array< double, Dim > &  overlap_widths,
const std::unordered_set< Direction< Dim > > &  external_boundaries 
)

Weights for data on the central element of an element-centered subdomain.

Constructs the weighting field

\begin{equation} W(\boldsymbol{\xi}) = \prod^d_{i=0} w(\xi^i) \end{equation}

where \(w(\xi^i)\) is the one-dimensional weighting function described in LinearSolver::Schwarz::extruding_weight and \(\xi^i\) are the element-logical coordinates (see Eq. (41) in [186]).

◆ extruding_weight()

DataVector LinearSolver::Schwarz::extruding_weight ( const DataVector logical_coords,
double  width,
const Side side 
)

Weights for the solution on an element-centered subdomain, decreasing from 1 to 0.5 towards the side over the logical distance width, and further to 0 over the same distance outside the element.

The weighting function over a full element-centered subdomain is

\begin{equation} w(\xi) = \frac{1}{2}\left( \phi\left( \frac{\xi + 1}{\delta} \right) - \phi\left( \frac{\xi - 1}{\delta} \right) \right) \end{equation}

where \(\phi(\xi)\) is a second-order smoothstep, i.e. the quintic polynomial

\begin{align*} \phi(\xi) = \begin{cases} \mathrm{sign}(\xi) \quad \text{for} \quad |\xi| > 1 \\ \frac{1}{8}\left(15\xi - 10\xi^3 + 3\xi^5\right) \end{cases} \end{align*}

(see Eq. (39) in [186]).

The LinearSolver::Schwarz::extruding_weight and LinearSolver::Schwarz::intruding_weight functions each compute one of the two terms in \(w(\xi)\). For example, consider an element-centered subdomain A that overlaps with a neighboring element-centered subdomain B. To combine solutions on A and B to a weighted solution on A, multiply the solution on A with the extruding_weight and the solution on B with the intruding_weight, both evaluated at the logical coordinates in A and at the side of A that faces B.

◆ intruding_weight() [1/3]

DataVector LinearSolver::Schwarz::intruding_weight ( const DataVector logical_coords,
double  width,
const Side side 
)

Weights for the intruding solution of a neighboring element-centered subdomain, increasing from 0 to 0.5 towards the side over the logical distance width, and further to 1 over the same distance outside the element.

See also
LinearSolver::Schwarz::extruding_weight

◆ intruding_weight() [2/3]

template<size_t Dim>
Scalar< DataVector > LinearSolver::Schwarz::intruding_weight ( const tnsr::I< DataVector, Dim, Frame::ElementLogical > &  logical_coords,
const Direction< Dim > &  direction,
const std::array< double, Dim > &  overlap_widths,
size_t  num_intruding_overlaps,
const std::unordered_set< Direction< Dim > > &  external_boundaries 
)

Weights for data on overlap regions intruding into an element-centered subdomain.

Constructs the weighting field \(W(\xi)\) as described in LinearSolver::Schwarz::element_weight for the data that overlaps with the central element of an element-centered subdomain. The weights are constructed in such a way that all weights at a grid point sum to one, i.e. the weight is conserved. The logical_coords are the element-logical coordinates of the central element.

This function assumes that corner- and edge-neighbors of the central element are not part of the subdomain, which means that no contributions from those neighbors are expected although the weighting field is non-zero in overlap regions with those neighbors. Therefore, to retain conservation we must account for this missing weight by adding it to the central element, to the intruding overlaps from face-neighbors, or split it between the two. We choose to add the weight to the intruding overlaps, since that's where information from the corner- and edge-regions propagates through in a DG context.

◆ intruding_weight() [3/3]

template<size_t Dim>
void LinearSolver::Schwarz::intruding_weight ( gsl::not_null< Scalar< DataVector > * >  weight,
const tnsr::I< DataVector, Dim, Frame::ElementLogical > &  logical_coords,
const Direction< Dim > &  direction,
const std::array< double, Dim > &  overlap_widths,
size_t  num_intruding_overlaps,
const std::unordered_set< Direction< Dim > > &  external_boundaries 
)

Weights for data on overlap regions intruding into an element-centered subdomain.

Constructs the weighting field \(W(\xi)\) as described in LinearSolver::Schwarz::element_weight for the data that overlaps with the central element of an element-centered subdomain. The weights are constructed in such a way that all weights at a grid point sum to one, i.e. the weight is conserved. The logical_coords are the element-logical coordinates of the central element.

This function assumes that corner- and edge-neighbors of the central element are not part of the subdomain, which means that no contributions from those neighbors are expected although the weighting field is non-zero in overlap regions with those neighbors. Therefore, to retain conservation we must account for this missing weight by adding it to the central element, to the intruding overlaps from face-neighbors, or split it between the two. We choose to add the weight to the intruding overlaps, since that's where information from the corner- and edge-regions propagates through in a DG context.

◆ overlap_extent()

size_t LinearSolver::Schwarz::overlap_extent ( size_t  volume_extent,
size_t  max_overlap 
)

The number of points that an overlap extends into the volume_extent

In a dimension where an element has volume_extent points, the overlap extent is the largest number under these constraints:

  • It is at most max_overlap.
  • It is smaller than the volume_extent.

This means the overlap extent is always smaller than the volume_extent. The reason for this constraint is that we define the width of the overlap as the element-logical coordinate distance from the face of the element to the first collocation point outside the overlap extent. Therefore, even an overlap region that covers the full element in width does not include the collocation point on the opposite side of the element.

Here's a few notes on the definition of the overlap extent and width:

  • A typical smooth weighting function goes to zero at the overlap width, so if the grid points located at the overlap width were included in the subdomain, their solutions would not contribute to the weighted sum of subdomain solutions.
  • Defining the overlap width as the distance to the first point outside the overlap extent makes it non-zero even for a single point of overlap into a Gauss-Lobatto grid (which has points located at the element face).
  • Boundary contributions for many (but not all) discontinuous Galerkin schemes on Gauss-Lobatto grids are limited to the grid points on the element face, e.g. for a DG operator that is pre-multiplied by the mass matrix, or one where boundary contributions are lifted using the diagonal mass-matrix approximation. Not including the grid points facing away from the subdomain in the overlap allows to ignore that face altogether in the subdomain operator.

◆ overlap_num_points()

template<size_t Dim>
size_t LinearSolver::Schwarz::overlap_num_points ( const Index< Dim > &  volume_extents,
size_t  overlap_extent,
size_t  overlap_dimension 
)

Total number of grid points in an overlap region that extends overlap_extent points into the volume_extents from either side in the overlap_dimension

The overlap region has overlap_extent points in the overlap_dimension, and volume_extents points in the other dimensions. The number of grid points returned by this function is the product of these extents.

◆ overlap_width()

double LinearSolver::Schwarz::overlap_width ( size_t  overlap_extent,
const DataVector collocation_points 
)

Width of an overlap extending overlap_extent points into the collocation_points from either side.

The "width" of an overlap is the element-logical coordinate distance from the element boundary to the first collocation point outside the overlap region in the overlap dimension, i.e. the dimension perpendicular to the element face. See LinearSolver::Schwarz::overlap_extent for details.

This function assumes the collocation_points are mirrored around 0.