![]() |
Dune-Fufem 2.11-git
|
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 BitVector & | isConstrained () const |
| Const access to bit-vector marking constrained DOFs. | |
| BitVector & | isConstrained () |
| Mutable access to bit-vector marking constrained DOFs. | |
| const LinearTerm & | linearTerm () const |
| Const access to linear part of affine map. | |
| LinearTerm & | linearTerm () |
| Mutable access to linear part of affine map. | |
| template<class MultiIndexType > | |
| const LinearTermRow & | linearTerm (const MultiIndexType &i) const |
| Const access to i-th row of linear part of affine map. | |
| const ConstantTerm & | constantTerm () const |
| Const access to constant part of affine map. | |
| ConstantTerm & | constantTerm () |
| 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
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
| using Dune::Fufem::AffineConstraints< BV, V, MI, C >::BitVector = BV |
◆ Coefficient
| using Dune::Fufem::AffineConstraints< BV, V, MI, C >::Coefficient = C |
◆ ConstantTerm
| using Dune::Fufem::AffineConstraints< BV, V, MI, C >::ConstantTerm = Vector |
◆ LinearTerm
| using Dune::Fufem::AffineConstraints< BV, V, MI, C >::LinearTerm = std::unordered_map<MultiIndex, LinearTermRow, MultiIndexHash, MultiIndexEquals> |
◆ LinearTermRow
| using Dune::Fufem::AffineConstraints< BV, V, MI, C >::LinearTermRow = std::map<MI, Coefficient> |
◆ MultiIndex
| using Dune::Fufem::AffineConstraints< BV, V, MI, C >::MultiIndex = MI |
◆ Vector
| using Dune::Fufem::AffineConstraints< BV, V, MI, C >::Vector = V |
Constructor & Destructor Documentation
◆ AffineConstraints() [1/5]
|
default |
◆ AffineConstraints() [2/5]
|
default |
◆ AffineConstraints() [3/5]
|
default |
◆ AffineConstraints() [4/5]
|
inline |
Construct from bit vector and vector.
◆ AffineConstraints() [5/5]
|
inline |
Construct from bit vector and vector.
Member Function Documentation
◆ check()
|
inline |
Check constraints for consistency.
This will check if all constrained DOFs are interpolated from non-constrained ones only.
◆ constantTerm() [1/4]
|
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]
|
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]
|
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]
|
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()
|
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()
|
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()
|
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()
|
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()
|
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()
|
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()
|
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()
|
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]
|
inline |
Mutable access to bit-vector marking constrained DOFs.
◆ isConstrained() [2/3]
|
inline |
Const access to bit-vector marking constrained DOFs.
◆ isConstrained() [3/3]
|
inline |
Check if i-th DOF is constrained.
◆ linearTerm() [1/3]
|
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]
|
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]
|
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()
|
inline |
Report the constraints to std::cout.
◆ 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:
