13#include <Eigen/Sparse>
19#include <Eigen/PardisoSupport>
22#ifdef USE_EIGEN_UNSUPPORTED
25#include <unsupported/Eigen/IterativeSolvers>
26#include <unsupported/Eigen/src/IterativeSolvers/Scaling.h>
46#ifdef USE_EIGEN_UNSUPPORTED
49 b = scaling_->LeftScaling().cwiseProduct(b);
53 auto const success =
solveImpl(b, x, opt);
55#ifdef USE_EIGEN_UNSUPPORTED
58 x = scaling_->RightScaling().cwiseProduct(x);
77 linear_solver_behaviour =
90#ifdef USE_EIGEN_UNSUPPORTED
94 scaling_ = std::make_unique<
95 Eigen::IterScaling<EigenMatrix::RawMatrixType>>();
96 scaling_->computeRef(A);
100 return computeImpl(A, opt, linear_solver_behaviour);
111#ifdef USE_EIGEN_UNSUPPORTED
112 std::unique_ptr<Eigen::IterScaling<EigenMatrix::RawMatrixType>> scaling_;
121template <
class T_SOLVER>
127 INFO(
"-> solve with Eigen direct linear solver {:s}",
131 if (
solver_.info() != Eigen::Success || x.hasNaN())
133 ERR(
"Failed during Eigen linear solve");
142 linear_solver_behaviour)
override
144 INFO(
"-> compute with Eigen direct linear solver {:s}",
146 if (!A.isCompressed())
152 if (
solver_.info() != Eigen::Success)
154 ERR(
"Failed during Eigen linear solver initialization");
165#ifdef USE_EIGEN_UNSUPPORTED
169template <
typename Solver>
170void setRestartImpl(Solver&,
int const)
172 DBUG(
"-> restart is not implemented for this linear solver.");
175template <
typename Matrix,
typename Precon>
176void setRestartImpl(Eigen::GMRES<Matrix, Precon>& solver,
int const restart)
178 solver.set_restart(restart);
179 INFO(
"-> set restart value: {:d}", solver.get_restart());
183template <
typename Solver>
184void setLImpl(Solver&,
int const)
186 DBUG(
"-> setL() is not implemented for this linear solver.");
189template <
typename Matrix,
typename Precon>
190void setLImpl(Eigen::BiCGSTABL<Matrix, Precon>& solver,
int const l)
195template <
typename Matrix,
typename Precon>
196void setLImpl(Eigen::IDRSTABL<Matrix, Precon>& solver,
int const l)
202template <
typename Solver>
203void setSImpl(Solver&,
int const)
205 DBUG(
"-> setS() is not implemented for this linear solver.");
208template <
typename Matrix,
typename Precon>
209void setSImpl(Eigen::IDRS<Matrix, Precon>& solver,
int const s)
214template <
typename Matrix,
typename Precon>
215void setSImpl(Eigen::IDRSTABL<Matrix, Precon>& solver,
int const s)
221template <
typename Solver>
222void setAngleImpl(Solver&,
double const)
224 DBUG(
"-> setAngle() is not implemented for this linear solver.");
227template <
typename Matrix,
typename Precon>
228void setAngleImpl(Eigen::IDRS<Matrix, Precon>& solver,
double const angle)
230 solver.setAngle(angle);
234template <
typename Solver>
235void setSmoothingImpl(Solver&,
bool const)
237 DBUG(
"-> setSmoothing() is not implemented for this linear solver.");
240template <
typename Matrix,
typename Precon>
241void setSmoothingImpl(Eigen::IDRS<Matrix, Precon>& solver,
bool const smoothing)
243 solver.setSmoothing(smoothing);
247template <
typename Solver>
248void setResidualUpdateImpl(Solver&,
bool const)
250 DBUG(
"-> setResidualUpdate() is not implemented for this linear solver.");
253template <
typename Matrix,
typename Precon>
254void setResidualUpdateImpl(Eigen::IDRS<Matrix, Precon>& solver,
255 bool const residual_update)
257 solver.setResidualUpdate(residual_update);
264template <
class T_SOLVER>
272 INFO(
"-> compute with Eigen iterative linear solver {:s} (precon {:s})",
278#ifdef USE_EIGEN_UNSUPPORTED
288 T_SOLVER>::setResidualUpdate(opt.residualupdate);
293 if (!m.isCompressed())
301 switch (linear_solver_behaviour)
319 "If NumLib::LinearSolverBehaviour::REUSE is set then "
320 "EigenLinearSolver::compute() should never be executed");
323 if (
solver_.info() != Eigen::Success)
325 ERR(
"Failed during Eigen linear solver initialization");
334 INFO(
"-> solve with Eigen iterative linear solver {:s} (precon {:s})",
338 x =
solver_.solveWithGuess(b, x);
339 INFO(
"\t iteration: {:d}/{:d}",
solver_.iterations(),
343 if (
solver_.info() != Eigen::Success)
345 ERR(
"Failed during Eigen linear solve");
355#ifdef USE_EIGEN_UNSUPPORTED
356 void setRestart(
int const restart) { setRestartImpl(
solver_, restart); }
357 void setL(
int const l) { setLImpl(
solver_, l); }
358 void setS(
int const s) { setSImpl(
solver_,
s); }
359 void setAngle(
double const angle) { setAngleImpl(
solver_, angle); }
360 void setSmoothing(
bool const smoothing)
362 setSmoothingImpl(
solver_, smoothing);
364 void setResidualUpdate(
bool const residual_update)
366 setResidualUpdateImpl(
solver_, residual_update);
371template <
template <
typename,
typename>
class Solver,
typename Precon>
376 return std::make_unique<Slv>();
379template <
template <
typename,
typename>
class Solver>
387 Eigen::IdentityPreconditioner>();
390 Solver, Eigen::DiagonalPreconditioner<double>>();
393 Solver, Eigen::LeastSquareDiagonalPreconditioner<double>>();
399 Eigen::IncompleteLUT<double>>();
401 OGS_FATAL(
"Invalid Eigen preconditioner type.");
405template <
typename Mat,
typename Precon>
419#ifdef USE_EIGEN_UNSUPPORTED
420#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
423 OGS_FATAL(
"BiCGSTABL requires at least Eigen version 3.4.90");
427 "The code is not compiled with the Eigen unsupported modules. "
428 "Linear solver type BiCGSTABL is not available.");
442#ifdef USE_EIGEN_UNSUPPORTED
446 "The code is not compiled with the Eigen unsupported modules. "
447 "Linear solver type GMRES is not available.");
452#ifdef USE_EIGEN_UNSUPPORTED
453#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
456 OGS_FATAL(
"IDRS requires at least Eigen version 3.4.90");
460 "The code is not compiled with the Eigen unsupported modules. "
461 "Linear solver type IDRS is not available.");
466#ifdef USE_EIGEN_UNSUPPORTED
467#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
470 OGS_FATAL(
"IDRSTABL requires at least Eigen version 3.4.90");
474 "The code is not compiled with the Eigen unsupported modules. "
475 "Linear solver type IDRSTABL is not available.");
479 OGS_FATAL(
"Invalid Eigen iterative linear solver type. Aborting.");
496 Eigen::SparseLU<Matrix, Eigen::COLAMDOrdering<int>>;
520 using SolverType = Eigen::PardisoLU<EigenMatrix::RawMatrixType>;
526 "The code is not compiled with Intel MKL. Linear solver type "
527 "PardisoLU is not available.");
532 OGS_FATAL(
"Invalid Eigen linear solver type. Aborting.");
541 INFO(
"------------------------------------------------------------------");
542 INFO(
"*** Eigen solver compute()");
549 INFO(
"------------------------------------------------------------------");
550 INFO(
"*** Eigen solver solve()");
560 linear_solver_behaviour) &&
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
bool compute(Matrix &A, EigenOption &opt, MathLib::LinearSolverBehaviour linear_solver_behaviour)
EigenMatrix::RawMatrixType Matrix
EigenVector::RawVectorType Vector
virtual bool computeImpl(Matrix &A, EigenOption &opt, MathLib::LinearSolverBehaviour const linear_solver_behaviour)=0
virtual bool solveImpl(Vector const &b, Vector &x, EigenOption &opt)=0
virtual ~EigenLinearSolverBase()=default
bool is_first_compute_call_
bool solve(Vector &b, Vector &x, EigenOption &opt)
bool compute(EigenMatrix &A, MathLib::LinearSolverBehaviour const linear_solver_behaviour)
bool solve(EigenVector &b, EigenVector &x)
EigenLinearSolver(std::string const &solver_name, EigenOption const &option)
bool can_solve_rectangular_
std::unique_ptr< EigenLinearSolverBase > solver_
Eigen::SparseMatrix< double, Eigen::RowMajor > RawMatrixType
RawMatrixType & getRawMatrix()
Global vector based on Eigen vector.
Eigen::VectorXd RawVectorType
RawVectorType & getRawVector()
return a raw Eigen vector object
Template class for Eigen direct linear solvers.
bool solveImpl(Vector const &b, Vector &x, EigenOption &opt) override
bool computeImpl(Matrix &A, EigenOption &opt, MathLib::LinearSolverBehaviour const linear_solver_behaviour) override
Template class for Eigen iterative linear solvers.
bool solveImpl(Vector const &b, Vector &x, EigenOption &opt) override
bool computeImpl(Matrix &A, EigenOption &opt, MathLib::LinearSolverBehaviour const linear_solver_behaviour) override
std::unique_ptr< EigenLinearSolverBase > createIterativeSolver()
Eigen::ConjugateGradient< Mat, Eigen::Lower, Precon > EigenCGSolver
Option for Eigen sparse solver.
PreconType precon_type
Preconditioner type.
static std::string getSolverName(SolverType const solver_type)
return a linear solver name from the solver type
PreconType
Preconditioner type.
SolverType solver_type
Linear solver type.
double error_tolerance
Error tolerance.
static std::string getPreconName(PreconType const precon_type)
return a preconditioner name from the preconditioner type
int max_iterations
Maximum iteration count.