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);
113#ifdef USE_EIGEN_UNSUPPORTED
114 std::unique_ptr<Eigen::IterScaling<EigenMatrix::RawMatrixType>> scaling_;
123template <
class T_SOLVER>
129 INFO(
"-> solve with Eigen direct linear solver {:s}",
133 if (
solver_.info() != Eigen::Success || x.hasNaN())
135 ERR(
"Failed during Eigen linear solve");
144 linear_solver_behaviour)
override
146 INFO(
"-> compute with Eigen direct linear solver {:s}",
148 if (!A.isCompressed())
154 if (
solver_.info() != Eigen::Success)
156 ERR(
"Failed during Eigen linear solver initialization");
167#ifdef USE_EIGEN_UNSUPPORTED
171template <
typename Solver>
172void setRestartImpl(Solver&,
int const)
174 DBUG(
"-> restart is not implemented for this linear solver.");
177template <
typename Matrix,
typename Precon>
178void setRestartImpl(Eigen::GMRES<Matrix, Precon>& solver,
int const restart)
180 solver.set_restart(restart);
181 INFO(
"-> set restart value: {:d}", solver.get_restart());
185template <
typename Solver>
186void setLImpl(Solver&,
int const)
188 DBUG(
"-> setL() is not implemented for this linear solver.");
191template <
typename Matrix,
typename Precon>
192void setLImpl(Eigen::BiCGSTABL<Matrix, Precon>& solver,
int const l)
197template <
typename Matrix,
typename Precon>
198void setLImpl(Eigen::IDRSTABL<Matrix, Precon>& solver,
int const l)
204template <
typename Solver>
205void setSImpl(Solver&,
int const)
207 DBUG(
"-> setS() is not implemented for this linear solver.");
210template <
typename Matrix,
typename Precon>
211void setSImpl(Eigen::IDRS<Matrix, Precon>& solver,
int const s)
216template <
typename Matrix,
typename Precon>
217void setSImpl(Eigen::IDRSTABL<Matrix, Precon>& solver,
int const s)
223template <
typename Solver>
224void setAngleImpl(Solver&,
double const)
226 DBUG(
"-> setAngle() is not implemented for this linear solver.");
229template <
typename Matrix,
typename Precon>
230void setAngleImpl(Eigen::IDRS<Matrix, Precon>& solver,
double const angle)
232 solver.setAngle(angle);
236template <
typename Solver>
237void setSmoothingImpl(Solver&,
bool const)
239 DBUG(
"-> setSmoothing() is not implemented for this linear solver.");
242template <
typename Matrix,
typename Precon>
243void setSmoothingImpl(Eigen::IDRS<Matrix, Precon>& solver,
bool const smoothing)
245 solver.setSmoothing(smoothing);
249template <
typename Solver>
250void setResidualUpdateImpl(Solver&,
bool const)
252 DBUG(
"-> setResidualUpdate() is not implemented for this linear solver.");
255template <
typename Matrix,
typename Precon>
256void setResidualUpdateImpl(Eigen::IDRS<Matrix, Precon>& solver,
257 bool const residual_update)
259 solver.setResidualUpdate(residual_update);
266template <
class T_SOLVER>
274 INFO(
"-> compute with Eigen iterative linear solver {:s} (precon {:s})",
280#ifdef USE_EIGEN_UNSUPPORTED
290 T_SOLVER>::setResidualUpdate(opt.residualupdate);
295 if (!m.isCompressed())
303 switch (linear_solver_behaviour)
321 "If NumLib::LinearSolverBehaviour::REUSE is set then "
322 "EigenLinearSolver::compute() should never be executed");
325 if (
solver_.info() != Eigen::Success)
327 ERR(
"Failed during Eigen linear solver initialization");
336 INFO(
"-> solve with Eigen iterative linear solver {:s} (precon {:s})",
340 x =
solver_.solveWithGuess(b, x);
341 INFO(
"\t iteration: {:d}/{:d}",
solver_.iterations(),
345 if (
solver_.info() != Eigen::Success)
347 ERR(
"Failed during Eigen linear solve");
357#ifdef USE_EIGEN_UNSUPPORTED
358 void setRestart(
int const restart) { setRestartImpl(
solver_, restart); }
359 void setL(
int const l) { setLImpl(
solver_, l); }
360 void setS(
int const s) { setSImpl(
solver_,
s); }
361 void setAngle(
double const angle) { setAngleImpl(
solver_, angle); }
362 void setSmoothing(
bool const smoothing)
364 setSmoothingImpl(
solver_, smoothing);
366 void setResidualUpdate(
bool const residual_update)
368 setResidualUpdateImpl(
solver_, residual_update);
373template <
template <
typename,
typename>
class Solver,
typename Precon>
378 return std::make_unique<Slv>();
381template <
template <
typename,
typename>
class Solver>
389 Eigen::IdentityPreconditioner>();
392 Solver, Eigen::DiagonalPreconditioner<double>>();
395 Solver, Eigen::LeastSquareDiagonalPreconditioner<double>>();
401 Eigen::IncompleteLUT<double>>();
403 OGS_FATAL(
"Invalid Eigen preconditioner type.");
407template <
typename Mat,
typename Precon>
410template <
typename Mat,
typename Precon>
413template <
typename Mat,
typename Precon>
415 Eigen::ConjugateGradient<Mat, Eigen::Lower | Eigen::Upper, Precon>;
429#ifdef USE_EIGEN_UNSUPPORTED
430#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
433 OGS_FATAL(
"BiCGSTABL requires at least Eigen version 3.4.90");
437 "The code is not compiled with the Eigen unsupported modules. "
438 "Linear solver type BiCGSTABL is not available.");
443 switch (triangular_matrix_type)
460#ifdef USE_EIGEN_UNSUPPORTED
464 "The code is not compiled with the Eigen unsupported modules. "
465 "Linear solver type GMRES is not available.");
470#ifdef USE_EIGEN_UNSUPPORTED
471#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
474 OGS_FATAL(
"IDRS requires at least Eigen version 3.4.90");
478 "The code is not compiled with the Eigen unsupported modules. "
479 "Linear solver type IDRS is not available.");
484#ifdef USE_EIGEN_UNSUPPORTED
485#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
488 OGS_FATAL(
"IDRSTABL requires at least Eigen version 3.4.90");
492 "The code is not compiled with the Eigen unsupported modules. "
493 "Linear solver type IDRSTABL is not available.");
497 OGS_FATAL(
"Invalid Eigen iterative linear solver type. Aborting.");
511 case EigenOption::SolverType::SparseLU:
514 Eigen::SparseLU<Matrix, Eigen::COLAMDOrdering<int>>;
515 solver_ = std::make_unique<
516 details::EigenDirectLinearSolver<SolverType>>();
517 can_solve_rectangular_ = false;
529 option_.triangular_matrix_type);
536 option_.triangular_matrix_type);
542 using SolverType = Eigen::PardisoLU<EigenMatrix::RawMatrixType>;
543 solver_.reset(new details::EigenDirectLinearSolver<SolverType>);
544 can_solve_rectangular_ = false;
548 "The code is not compiled with Intel MKL. Linear solver type "
549 "PardisoLU is not available.");
554 OGS_FATAL(
"Invalid Eigen linear solver type. Aborting.");
557EigenLinearSolver::~EigenLinearSolver() =
default;
563 INFO(
"------------------------------------------------------------------");
564 INFO(
"*** Eigen solver compute()");
571 INFO(
"------------------------------------------------------------------");
572 INFO(
"*** Eigen solver solve()");
582 linear_solver_behaviour) &&
590 !
solver_->didComputeAtLeastOnce();
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
bool didComputeAtLeastOnce() const
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 willCompute(MathLib::LinearSolverBehaviour const linear_solver_behaviour) const
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
Eigen::ConjugateGradient< Mat, Eigen::Lower, Precon > EigenCGSolverL
Eigen::ConjugateGradient< Mat, Eigen::Lower|Eigen::Upper, Precon > EigenCGSolverLU
std::unique_ptr< EigenLinearSolverBase > createIterativeSolver()
Eigen::ConjugateGradient< Mat, Eigen::Upper, Precon > EigenCGSolverU
Option for Eigen sparse solver.
TriangularMatrixType
triangular matrix type
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.