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>>();
396 Eigen::IncompleteLUT<double>>();
398 OGS_FATAL(
"Invalid Eigen preconditioner type.");
402template <
typename Mat,
typename Precon>
416#ifdef USE_EIGEN_UNSUPPORTED
417#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
420 OGS_FATAL(
"BiCGSTABL requires at least Eigen version 3.4.90");
424 "The code is not compiled with the Eigen unsupported modules. "
425 "Linear solver type BiCGSTABL is not available.");
434#ifdef USE_EIGEN_UNSUPPORTED
438 "The code is not compiled with the Eigen unsupported modules. "
439 "Linear solver type GMRES is not available.");
444#ifdef USE_EIGEN_UNSUPPORTED
445#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
448 OGS_FATAL(
"IDRS requires at least Eigen version 3.4.90");
452 "The code is not compiled with the Eigen unsupported modules. "
453 "Linear solver type IDRS is not available.");
458#ifdef USE_EIGEN_UNSUPPORTED
459#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
462 OGS_FATAL(
"IDRSTABL requires at least Eigen version 3.4.90");
466 "The code is not compiled with the Eigen unsupported modules. "
467 "Linear solver type IDRSTABL is not available.");
471 OGS_FATAL(
"Invalid Eigen iterative linear solver type. Aborting.");
485 case EigenOption::SolverType::SparseLU:
488 Eigen::SparseLU<Matrix, Eigen::COLAMDOrdering<int>>;
489 solver_ = std::make_unique<
490 details::EigenDirectLinearSolver<SolverType>>();
505 using SolverType = Eigen::PardisoLU<EigenMatrix::RawMatrixType>;
506 solver_.reset(new details::EigenDirectLinearSolver<SolverType>);
510 "The code is not compiled with Intel MKL. Linear solver type "
511 "PardisoLU is not available.");
516 OGS_FATAL(
"Invalid Eigen linear solver type. Aborting.");
519EigenLinearSolver::~EigenLinearSolver() =
default;
521bool EigenLinearSolver::compute(
525 INFO(
"------------------------------------------------------------------");
526 INFO(
"*** Eigen solver compute()");
528 return solver_->compute(A.
getRawMatrix(), option_, linear_solver_behaviour);
533 INFO(
"------------------------------------------------------------------");
534 INFO(
"*** Eigen solver solve()");
539bool EigenLinearSolver::solve(
544 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)
EigenLinearSolver(std::string const &solver_name, EigenOption const &option)
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.