14#include <dune/common/exceptions.hh>
17#include <Eigen/SparseCore>
28MAKE_ENUM(
SolverTypeTag, none, si_ConjugateGradient, si_LeastSquaresConjugateGradient, si_BiCGSTAB, sd_SimplicialLLT,
29 sd_SimplicialLDLT, sd_SparseLU, sd_SparseQR, sd_CholmodSupernodalLLT, sd_UmfPackLU, sd_SuperLU,
30 d_PartialPivLU, d_FullPivLU, d_HouseholderQR, d_ColPivHouseholderQR, d_FullPivHouseholderQR,
31 d_CompleteOrthogonalDecomposition, d_LLT, d_LDLT);
49template <
typename ST =
double>
71 std::swap(lhs.solverimpl_, rhs.solverimpl_);
72 std::swap(lhs.solverTypeTag_, rhs.solverTypeTag_);
105 virtual ~SolverBase() =
default;
112 virtual void solve(Eigen::VectorX<ScalarType>& x,
const Eigen::VectorX<ScalarType>&)
const = 0;
113 virtual void solve(Eigen::MatrixX2<ScalarType>& x,
const Eigen::MatrixX2<ScalarType>&)
const = 0;
114 virtual void solve(Eigen::MatrixX3<ScalarType>& x,
const Eigen::MatrixX3<ScalarType>&)
const = 0;
115 virtual void solve(Eigen::MatrixX<ScalarType>& x,
const Eigen::MatrixX<ScalarType>&)
const = 0;
118 template <
typename Solver>
119 struct SolverImpl :
public SolverBase
121 using SolverBase::analyzePattern;
124 if constexpr (
requires(Solver sol) { sol.analyzePattern(A); })
125 solver.analyzePattern(A);
129 if constexpr (
requires(Solver sol) { sol.factorize(A); })
136 if constexpr (
requires(Solver sol) { sol.compute(A); } && std::is_base_of_v<Eigen::SolverBase<Solver>, Solver>)
140 if constexpr (std::is_base_of_v<Eigen::SparseSolverBase<Solver>, Solver>)
143 DUNE_THROW(Dune::NotImplemented,
"This solver does not support solving with sparse matrices.");
147 if constexpr (std::is_base_of_v<Eigen::SolverBase<Solver>, Solver>)
150 DUNE_THROW(Dune::NotImplemented,
"This solver does not support solving with dense matrices.");
153 void solve(Eigen::VectorX<ScalarType>& x,
const Eigen::VectorX<ScalarType>& b)
const final { x = solver.solve(b); }
155 void solve(Eigen::MatrixX2<ScalarType>& x,
const Eigen::MatrixX2<ScalarType>& b)
const final {
159 void solve(Eigen::MatrixX3<ScalarType>& x,
const Eigen::MatrixX3<ScalarType>& b)
const final {
163 void solve(Eigen::MatrixX<ScalarType>& x,
const Eigen::MatrixX<ScalarType>& b)
const final { x = solver.solve(b); }
168 std::unique_ptr<SolverBase> solverimpl_;
178 template <
typename MatrixType>
179 requires std::is_same_v<MatrixType, DenseMatrixType> || std::is_same_v<MatrixType, SparseMatrixType>
190 template <
typename MatrixType>
191 requires std::is_same_v<MatrixType, DenseMatrixType> || std::is_same_v<MatrixType, SparseMatrixType>
193 solverimpl_->analyzePattern(A);
201 template <
typename MatrixType>
202 requires std::is_same_v<MatrixType, DenseMatrixType> || std::is_same_v<MatrixType, SparseMatrixType>
204 solverimpl_->factorize(A);
212 void solve(Eigen::VectorX<ScalarType>& x,
const Eigen::VectorX<ScalarType>& b) { solverimpl_->solve(x, b); }
219 void solve(Eigen::MatrixX3<ScalarType>& x,
const Eigen::MatrixX3<ScalarType>& b) { solverimpl_->solve(x, b); }
225 void solve(Eigen::MatrixX2<ScalarType>& x,
const Eigen::MatrixX2<ScalarType>& b) { solverimpl_->solve(x, b); }
232 void solve(Eigen::MatrixX<ScalarType>& x,
const Eigen::MatrixX<ScalarType>& b) { solverimpl_->solve(x, b); }
Implementation of the make enum macro.
#define MAKE_ENUM(type,...)
Macro to create an enumeration with a string conversion function.The macro creates an enum class with...
Definition: makeenum.hh:40
Definition: assemblermanipulatorbuildingblocks.hh:22
MatrixTypeTag
Enumeration representing different matrix types (Dense or Sparse).
Definition: linearsolver.hh:38
SolverTypeTag
Enumeration representing different solver types.
Definition: linearsolver.hh:31
A type-erased class which wraps most of the linear solvers available in Eigen.
Definition: linearsolver.hh:51
friend void swap(LinearSolverTemplate &lhs, LinearSolverTemplate &rhs) noexcept
Definition: linearsolver.hh:70
LinearSolverTemplate & compute(const MatrixType &A)
Compute the factorization of the matrix.
Definition: linearsolver.hh:180
LinearSolverTemplate()=default
LinearSolverTemplate(const SolverTypeTag &solverTypeTag)
Constructor for LinearSolverTemplate.
LinearSolverTemplate & operator=(LinearSolverTemplate &&other) noexcept=default
Move assignment operator.
LinearSolverTemplate(const LinearSolverTemplate &other)
Copy constructor.
Definition: linearsolver.hh:89
void solve(Eigen::MatrixX3< ScalarType > &x, const Eigen::MatrixX3< ScalarType > &b)
Solve the linear system for a n times 3 matrix.
Definition: linearsolver.hh:219
~LinearSolverTemplate()=default
Destructor for LinearSolverTemplate.
void solve(Eigen::MatrixX< ScalarType > &x, const Eigen::MatrixX< ScalarType > &b)
Solve the linear system for a n times n matrix.
Definition: linearsolver.hh:232
void analyzePattern(const MatrixType &A)
Analyze the pattern of the matrix.
Definition: linearsolver.hh:192
LinearSolverTemplate(LinearSolverTemplate &&other) noexcept=default
Move constructor.
Eigen::MatrixX< ScalarType > DenseMatrixType
Definition: linearsolver.hh:55
LinearSolverTemplate & operator=(const LinearSolverTemplate &other)
Copy assignment operator.
Definition: linearsolver.hh:79
ST ScalarType
Definition: linearsolver.hh:53
Eigen::SparseMatrix< ScalarType > SparseMatrixType
Definition: linearsolver.hh:54
void factorize(const MatrixType &A)
Factorize the matrix.
Definition: linearsolver.hh:203
void solve(Eigen::VectorX< ScalarType > &x, const Eigen::VectorX< ScalarType > &b)
Solve the linear system for a vector.
Definition: linearsolver.hh:212
void solve(Eigen::MatrixX2< ScalarType > &x, const Eigen::MatrixX2< ScalarType > &b)
Solve the linear system for a n times 2 matrix.
Definition: linearsolver.hh:225