Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
Dune::Fufem::AffineConstraints< BV, V, MI, C > Class Template Reference

Class to handle affine constraints on a subset of DOFs. More...

#include <dune/fufem/constraints/affineconstraints.hh>

Public Types

using BitVector = BV
 
using Vector = V
 
using MultiIndex = MI
 
using Coefficient = C
 
using LinearTermRow = std::map< MI, Coefficient >
 
using LinearTerm = std::unordered_map< MultiIndex, LinearTermRow, MultiIndexHash, MultiIndexEquals >
 
using ConstantTerm = Vector
 

Public Member Functions

 AffineConstraints ()=default
 
 AffineConstraints (const AffineConstraints &)=default
 
 AffineConstraints (AffineConstraints &&)=default
 
 AffineConstraints (BitVector &&isConstrained, Vector &&constantTerm)
 Construct from bit vector and vector.
 
 AffineConstraints (const BitVector &isConstrained, const Vector &constantTerm)
 Construct from bit vector and vector.
 
template<class MultiIndexType >
bool isConstrained (const MultiIndexType &i) const
 Check if i-th DOF is constrained.
 
const BitVectorisConstrained () const
 Const access to bit-vector marking constrained DOFs.
 
BitVectorisConstrained ()
 Mutable access to bit-vector marking constrained DOFs.
 
const LinearTermlinearTerm () const
 Const access to linear part of affine map.
 
LinearTermlinearTerm ()
 Mutable access to linear part of affine map.
 
template<class MultiIndexType >
const LinearTermRowlinearTerm (const MultiIndexType &i) const
 Const access to i-th row of linear part of affine map.
 
const ConstantTermconstantTerm () const
 Const access to constant part of affine map.
 
ConstantTermconstantTerm ()
 Mutable access to constant part of affine map.
 
template<class MultiIndexType >
const auto & constantTerm (const MultiIndexType &i) const
 Const access to i-th row of constant part of affine map.
 
template<class MultiIndexType >
auto & constantTerm (const MultiIndexType &i)
 Mutable access to i-th row of constant part of affine map.
 
template<class Vector >
void interpolate (Vector &v) const
 Interpolate vector according to affine constraints.
 
template<class Vector >
void interpolateHomogeneously (Vector &v) const
 Interpolate vector according to affine constraints.
 
template<class MatrixPatternBackend , class Basis >
void extendMatrixPattern (MatrixPatternBackend &patternBackend, const Basis &basis) const
 Extend matrix pattern for a constrained basis.
 
template<class Matrix >
void constrainMatrix (Matrix &A) const
 Constrain matrix to a constrained basis.
 
template<class Vector >
void constrainVector (Vector &b) const
 Constrain vector to a constrained basis.
 
template<class Vector >
void constrainVectorHomogeneously (Vector &b) const
 Constrain vector to a constrained basis.
 
template<class Matrix , class Vector >
void constrainLinearSystem (Matrix &A, Vector &b) const
 Constrain linear system affine subspace satisfying the constraints.
 
template<class Matrix , class Vector >
void constrainLinearSystemHomogeneously (Matrix &A, Vector &b) const
 Constrain linear system affine subspace satisfying the constraints.
 
void report () const
 Report the constraints to std::cout.
 
bool check () const
 Check constraints for consistency.
 
void resolveDependencies ()
 Resolve dependencies of constrained DOFs on other constrained DOFs.
 

Detailed Description

template<class BV, class V, class MI, class C = double>
class Dune::Fufem::AffineConstraints< BV, V, MI, C >

Class to handle affine constraints on a subset of DOFs.

This class handles affine constraints of the form

\[ x_i = \sum_{j\in \mathcal{I}} L_{ij} x_j + c_i \qquad i \in \mathcal{I}\]

or in short \( x = L x + c\) for a square matrix \( L \) where all indices are from the index set \(\mathcal{I}\). For exposition purposes we assume that \( \mathcal{I}=\{1,...,n\} \) while the implementation supports multi-indices as provided by the global bases in dune-functions. Under this assumption we have \(L \in \mathbb{R}^{n \times n} \) and \(c \in \mathbb{R}^n\). The main purpose of the AffineConstraints class is to simplify the handling of problems in the constrained affine subspace

\[ V_{L,c} = \{ x\,|\, x = L x+c\}.\]

We assume that the index set can be decomposed according to \(\mathcal{I}= \mathcal{I}_C \cup \mathcal{I}_N\) into disjoint subsets \(\mathcal{I}_C\) and \(\mathcal{I}_N\) of constrained and non-constrained indices, respectively. The constrained and non-constrained indices should satisfy the following two assumptions:

  • For any non-constrained index \(i\in \mathcal{I}_N\) we have (using the Kronecker delta) \( L_{ij} = \delta_{ij} \forall j\in\mathcal{I} \) and \(c_i=0\).
  • For any constrained index \(i\in \mathcal{I}_C\) we have \(L_{ii}=L_{ij}=0 \forall j\in\mathcal{I}_C\).

Then any constrained value \(x_i\) with \(i\in\mathcal{I}_C\) can be interpolated from \(c_i\) and the non-constrained values \(x_j\) according to

\[ x_i = \sum_{i\in \mathcal{I}} L_{ij}x_j + c_i = \sum_{i\in \mathcal{I}_N} L_{ij}x_j + c_i. \]

Under these assumptions we furthermore have \(L^2 = L\) and \(L c=0\), i.e. \(L\) is a linear projection and \(c\) is in the kernel of \(L\). Then the affine map \( \Psi:\mathbb{R}^n \to V_{L,c}\) given by \(v \mapsto \Psi(x) = L x +c\) is a surjective projection into \(V_{L,c}\) which can be written as

\[ \begin{align*}V_{L,c} =\{x\,|\, x = \Psi(x) \} = \{\Psi(x)\,|\, x\in \mathbb{R}^N\} = \operatorname{ran}(\Psi). \end{align*}\]

Now consider a linear variational problem

\[ u \in V_{L,c}: \qquad \langle A u, v \rangle = \langle b, v \rangle \qquad \forall v \in V_{L,0} \]

in the affine subspace \( V_{L,c}\). Using the decomposition \(u= u_0 + c\) with \( u_0 = L u_0 = L u \in V_{L,0} \) this can be written as

\[ u_0 \in V_{L,0}: \qquad \langle A u_0, v \rangle = \langle b - A c, v \rangle \qquad \forall v \in V_{L,0}. \]

Since \(L:V_{L,0} \to V_{L,0}\) is a linear projection, we find that \(u_0\) solves

\[ u_0 \in \mathbb{R}^n: \qquad \langle L^T A L u_0, v \rangle = \langle L^T(b - A c), v \rangle \qquad \forall v \in \mathbb{R}^n \]

The matrix \( L^T A L\) is obviously singular, since it is zero on \(\operatorname{ker}(L) = (V_{L,0})^\perp\). Hence this system does not have a unique solution. Assuming that \(A\) is regular on \(V_{L,0}\), i.e. \(\operatorname{ker} (A) \subset \operatorname{ker}(L)\) we know that the solution is at least unique in \(V_{L,0}\). To regularize the problem we consider the reduced identity matrix \( \hat{I} \in \mathbb{R}^{n \times n}\) with \(\hat{I}_{ij} = \delta_{ij}\) if \(i,j \in \mathcal{I}_C\) and \(\hat{I}_{ij} = 0\) if \(i\in \mathcal{I}_N\) or \(j\in \mathcal{I}_N\). From \(L\hat{I} = 0 = \hat{I}L^T\) it follows, that the system

\[ \hat{u} \in \mathbb{R}^n: \qquad \langle \hat{A}, v \rangle = \langle \hat{b}, v \rangle \qquad \forall v \in \mathbb{R}^n \]

with \( \hat{A} = L^T A L + \hat{I} \) and \(\hat{b} = L^T(b-A c) + c\) is equivalent to the constrained problem in the sense that \(u_0 = L \hat{u}\). Hence we can solve the constrained problem by solving

\[ \hat{A}\hat{u} = \hat{b} \]

and then setting \(u = \Psi(\hat{u}) = L\hat{u} + c = L u_0 + c\).

The present class supports this approach as follows: The pair \((A,b)\) can be transformed to \((\hat{A}, \hat{b})\) using the method constrainLinearSystem(A,b). Since this is an inplace operation extendMatrixPattern(...) can be used before, to ensure that the pattern of the matrix is large enough to also store \(\hat{A}\). Once the system is solved, \(\hat{u}\) can be transformed to \(u=\Psi(\hat{u})\) using interpolate(u) which is again an inplace operation.

Warning
This class is still experimental and the interface may change.

Member Typedef Documentation

◆ BitVector

template<class BV , class V , class MI , class C = double>
using Dune::Fufem::AffineConstraints< BV, V, MI, C >::BitVector = BV

◆ Coefficient

template<class BV , class V , class MI , class C = double>
using Dune::Fufem::AffineConstraints< BV, V, MI, C >::Coefficient = C

◆ ConstantTerm

template<class BV , class V , class MI , class C = double>
using Dune::Fufem::AffineConstraints< BV, V, MI, C >::ConstantTerm = Vector

◆ LinearTerm

template<class BV , class V , class MI , class C = double>
using Dune::Fufem::AffineConstraints< BV, V, MI, C >::LinearTerm = std::unordered_map<MultiIndex, LinearTermRow, MultiIndexHash, MultiIndexEquals>

◆ LinearTermRow

template<class BV , class V , class MI , class C = double>
using Dune::Fufem::AffineConstraints< BV, V, MI, C >::LinearTermRow = std::map<MI, Coefficient>

◆ MultiIndex

template<class BV , class V , class MI , class C = double>
using Dune::Fufem::AffineConstraints< BV, V, MI, C >::MultiIndex = MI

◆ Vector

template<class BV , class V , class MI , class C = double>
using Dune::Fufem::AffineConstraints< BV, V, MI, C >::Vector = V

Constructor & Destructor Documentation

◆ AffineConstraints() [1/5]

template<class BV , class V , class MI , class C = double>
Dune::Fufem::AffineConstraints< BV, V, MI, C >::AffineConstraints ( )
default

◆ AffineConstraints() [2/5]

template<class BV , class V , class MI , class C = double>
Dune::Fufem::AffineConstraints< BV, V, MI, C >::AffineConstraints ( const AffineConstraints< BV, V, MI, C > &  )
default

◆ AffineConstraints() [3/5]

template<class BV , class V , class MI , class C = double>
Dune::Fufem::AffineConstraints< BV, V, MI, C >::AffineConstraints ( AffineConstraints< BV, V, MI, C > &&  )
default

◆ AffineConstraints() [4/5]

template<class BV , class V , class MI , class C = double>
Dune::Fufem::AffineConstraints< BV, V, MI, C >::AffineConstraints ( BitVector &&  isConstrained,
Vector &&  constantTerm 
)
inline

Construct from bit vector and vector.

◆ AffineConstraints() [5/5]

template<class BV , class V , class MI , class C = double>
Dune::Fufem::AffineConstraints< BV, V, MI, C >::AffineConstraints ( const BitVector isConstrained,
const Vector constantTerm 
)
inline

Construct from bit vector and vector.

Member Function Documentation

◆ check()

template<class BV , class V , class MI , class C = double>
bool Dune::Fufem::AffineConstraints< BV, V, MI, C >::check ( ) const
inline

Check constraints for consistency.

This will check if all constrained DOFs are interpolated from non-constrained ones only.

◆ constantTerm() [1/4]

template<class BV , class V , class MI , class C = double>
ConstantTerm & Dune::Fufem::AffineConstraints< BV, V, MI, C >::constantTerm ( )
inline

Mutable access to constant part of affine map.

Assuming that the affine constraints are written as \( x = L x + c\) the result represents the vector \(c\).

◆ constantTerm() [2/4]

template<class BV , class V , class MI , class C = double>
const ConstantTerm & Dune::Fufem::AffineConstraints< BV, V, MI, C >::constantTerm ( ) const
inline

Const access to constant part of affine map.

Assuming that the affine constraints are written as \( x = L x + c\) the result represents the vector \(c\).

◆ constantTerm() [3/4]

template<class BV , class V , class MI , class C = double>
template<class MultiIndexType >
auto & Dune::Fufem::AffineConstraints< BV, V, MI, C >::constantTerm ( const MultiIndexType &  i)
inline

Mutable access to i-th row of constant part of affine map.

Assuming that the affine constraints are written as \( x = L x + c\) the result represents the i-th row of the vector \(c\).

◆ constantTerm() [4/4]

template<class BV , class V , class MI , class C = double>
template<class MultiIndexType >
const auto & Dune::Fufem::AffineConstraints< BV, V, MI, C >::constantTerm ( const MultiIndexType &  i) const
inline

Const access to i-th row of constant part of affine map.

Assuming that the affine constraints are written as \( x = L x + c\) the result represents the i-th row of the vector \(c\).

◆ constrainLinearSystem()

template<class BV , class V , class MI , class C = double>
template<class Matrix , class Vector >
void Dune::Fufem::AffineConstraints< BV, V, MI, C >::constrainLinearSystem ( Matrix A,
Vector b 
) const
inline

Constrain linear system affine subspace satisfying the constraints.

Assuming that the affine constraints are written as \( x = L x + c\) this overwrites the given vector \(b\) by \(L^T(b-A c) + c\) and the matrix \(A\) by \(L^T A L + \hat{I}\) where \(\hat{I}\) is the identity matrix constrained to the kernel of \(L\).

◆ constrainLinearSystemHomogeneously()

template<class BV , class V , class MI , class C = double>
template<class Matrix , class Vector >
void Dune::Fufem::AffineConstraints< BV, V, MI, C >::constrainLinearSystemHomogeneously ( Matrix A,
Vector b 
) const
inline

Constrain linear system affine subspace satisfying the constraints.

Assuming that the affine constraints are written as \( x = L x + c\) this overwrites the given vector \(b\) by \(L^T b\) and the matrix \(A\) by \(L^T A L + \hat{I}\) where \(\hat{I}\) is the identity matrix constrained to the kernel of \(L\). This corresponds to the behavior of constrainLinearSystem in the case of homogeneous constraints with \(c=0\).

◆ constrainMatrix()

template<class BV , class V , class MI , class C = double>
template<class Matrix >
void Dune::Fufem::AffineConstraints< BV, V, MI, C >::constrainMatrix ( Matrix A) const
inline

Constrain matrix to a constrained basis.

Assuming that the affine constraints are written as \( x = L x + c\) this overwrites the given matrix \(A\) by \(L^T A L+\hat{I}\) where \(\hat{I}\) is the identity matrix constrained to the kernel of \(L\) given by the constrained rows.

◆ constrainVector()

template<class BV , class V , class MI , class C = double>
template<class Vector >
void Dune::Fufem::AffineConstraints< BV, V, MI, C >::constrainVector ( Vector b) const
inline

Constrain vector to a constrained basis.

Assuming that the affine constraints are written as \( x = L x + c\) this overwrites the given vector \(b\) by \(L^T b + c\).

◆ constrainVectorHomogeneously()

template<class BV , class V , class MI , class C = double>
template<class Vector >
void Dune::Fufem::AffineConstraints< BV, V, MI, C >::constrainVectorHomogeneously ( Vector b) const
inline

Constrain vector to a constrained basis.

Assuming that the affine constraints are written as \( x = L x + c\) this overwrites the given vector \(b\) by \(L^T b\). This corresponds to the behavior of constrainVector in the case of homogeneous constraints with \(c=0\).

◆ extendMatrixPattern()

template<class BV , class V , class MI , class C = double>
template<class MatrixPatternBackend , class Basis >
void Dune::Fufem::AffineConstraints< BV, V, MI, C >::extendMatrixPattern ( MatrixPatternBackend &  patternBackend,
const Basis &  basis 
) const
inline

Extend matrix pattern for a constrained basis.

Assuming that the affine constraints are written as \( x = L x + c\) and the given pattern is able to store a sparse matrix \(A\) this enlarges the pattern for storing \(L^T A L\).

◆ interpolate()

template<class BV , class V , class MI , class C = double>
template<class Vector >
void Dune::Fufem::AffineConstraints< BV, V, MI, C >::interpolate ( Vector v) const
inline

Interpolate vector according to affine constraints.

Assuming that the affine constraints are written as \( x = L x + c\) this overwrites the given vector \(v\) by \(L v+c\).

This computes the values of constrained DOFs using the interpolation weights while non-constrained DOFs remain unchanged. After calling this methods, v satisfies the constraints \( x = L x + c \).

◆ interpolateHomogeneously()

template<class BV , class V , class MI , class C = double>
template<class Vector >
void Dune::Fufem::AffineConstraints< BV, V, MI, C >::interpolateHomogeneously ( Vector v) const
inline

Interpolate vector according to affine constraints.

Assuming that the affine constraints are written as \( x = L x + c\) this overwrites the given vector \(v\) by \(L v\).

This computes the values of constrained DOFs using the interpolation weights while non-constrained DOFs remain unchanged. After calling this methods, v satisfies the homogeneous constraints \( x = L x \). This corresponds to the behavior of interpolate in the case of homogeneous constraints with \(c=0\).

◆ isConstrained() [1/3]

template<class BV , class V , class MI , class C = double>
BitVector & Dune::Fufem::AffineConstraints< BV, V, MI, C >::isConstrained ( )
inline

Mutable access to bit-vector marking constrained DOFs.

◆ isConstrained() [2/3]

template<class BV , class V , class MI , class C = double>
const BitVector & Dune::Fufem::AffineConstraints< BV, V, MI, C >::isConstrained ( ) const
inline

Const access to bit-vector marking constrained DOFs.

◆ isConstrained() [3/3]

template<class BV , class V , class MI , class C = double>
template<class MultiIndexType >
bool Dune::Fufem::AffineConstraints< BV, V, MI, C >::isConstrained ( const MultiIndexType &  i) const
inline

Check if i-th DOF is constrained.

◆ linearTerm() [1/3]

template<class BV , class V , class MI , class C = double>
LinearTerm & Dune::Fufem::AffineConstraints< BV, V, MI, C >::linearTerm ( )
inline

Mutable access to linear part of affine map.

Assuming that the affine constraints are written as \( x = L x + c\) the result represents the sparse matrix \(L - (I-\hat{I})\), i.e., the matrix \(L\) with all the diagonal entries for non-constrained indices in \(\mathcal{I}_N\) set to zero.

◆ linearTerm() [2/3]

template<class BV , class V , class MI , class C = double>
const LinearTerm & Dune::Fufem::AffineConstraints< BV, V, MI, C >::linearTerm ( ) const
inline

Const access to linear part of affine map.

Assuming that the affine constraints are written as \( x = L x + c\) the result represents the sparse matrix \(L - (I-\hat{I})\), i.e., the matrix \(L\) with all the diagonal entries for non-constrained indices in \(\mathcal{I}_N\) set to zero.

◆ linearTerm() [3/3]

template<class BV , class V , class MI , class C = double>
template<class MultiIndexType >
const LinearTermRow & Dune::Fufem::AffineConstraints< BV, V, MI, C >::linearTerm ( const MultiIndexType &  i) const
inline

Const access to i-th row of linear part of affine map.

Assuming that the affine constraints are written as \( x = L x + c\) the result represents the i-th row of the sparse matrix \(L - (I-\hat{I})\), i.e., all the non-diagonal entries of the i-th row of \(L\).

This method should only be used if the i-th DOF is constrained. For non-constrained DOFs this returns an empty range instead of a range with one on the diagonal.

◆ report()

template<class BV , class V , class MI , class C = double>
void Dune::Fufem::AffineConstraints< BV, V, MI, C >::report ( ) const
inline

Report the constraints to std::cout.

◆ resolveDependencies()

template<class BV , class V , class MI , class C = double>
void Dune::Fufem::AffineConstraints< BV, V, MI, C >::resolveDependencies ( )
inline

Resolve dependencies of constrained DOFs on other constrained DOFs.

An AffineConstraints object can be setup by inserting interpolation weights into the linearTerm() and constantTerm(). It may happen that some constrained DOFs are interpolated from DOFs that are constrained themselves which is not supported. To eliminate such cases the resolveDependencies() method will recursively resolve such dependencies such that all constrained DOFs are interpolated from non-constrained ones only. Notice that this requires that there are no cyclic dependencies.


The documentation for this class was generated from the following file: