12#include <Eigen/PardisoSupport>
15#ifdef USE_EIGEN_UNSUPPORTED
18#include <unsupported/Eigen/IterativeSolvers>
19#include <unsupported/Eigen/src/IterativeSolvers/Scaling.h>
39#ifdef USE_EIGEN_UNSUPPORTED
42 b = scaling_->LeftScaling().cwiseProduct(b);
46 auto const success =
solveImpl(b, x, opt);
48#ifdef USE_EIGEN_UNSUPPORTED
51 x = scaling_->RightScaling().cwiseProduct(x);
70 linear_solver_behaviour =
83#ifdef USE_EIGEN_UNSUPPORTED
87 scaling_ = std::make_unique<
88 Eigen::IterScaling<EigenMatrix::RawMatrixType>>();
89 scaling_->computeRef(A);
93 return computeImpl(A, opt, linear_solver_behaviour);
106#ifdef USE_EIGEN_UNSUPPORTED
107 std::unique_ptr<Eigen::IterScaling<EigenMatrix::RawMatrixType>> scaling_;
116template <
class T_SOLVER>
122 INFO(
"-> solve with Eigen direct linear solver {:s}",
126 if (
solver_.info() != Eigen::Success || x.hasNaN())
128 ERR(
"Failed during Eigen linear solve");
137 linear_solver_behaviour)
override
139 INFO(
"-> compute with Eigen direct linear solver {:s}",
141 if (!A.isCompressed())
147 if (
solver_.info() != Eigen::Success)
149 ERR(
"Failed during Eigen linear solver initialization");
160#ifdef USE_EIGEN_UNSUPPORTED
164template <
typename Solver>
165void setRestartImpl(Solver&,
int const)
167 DBUG(
"-> restart is not implemented for this linear solver.");
170template <
typename Matrix,
typename Precon>
171void setRestartImpl(Eigen::GMRES<Matrix, Precon>& solver,
int const restart)
173 solver.set_restart(restart);
174 INFO(
"-> set restart value: {:d}", solver.get_restart());
178template <
typename Solver>
179void setLImpl(Solver&,
int const)
181 DBUG(
"-> setL() is not implemented for this linear solver.");
184template <
typename Matrix,
typename Precon>
185void setLImpl(Eigen::BiCGSTABL<Matrix, Precon>& solver,
int const l)
190template <
typename Matrix,
typename Precon>
191void setLImpl(Eigen::IDRSTABL<Matrix, Precon>& solver,
int const l)
197template <
typename Solver>
198void setSImpl(Solver&,
int const)
200 DBUG(
"-> setS() is not implemented for this linear solver.");
203template <
typename Matrix,
typename Precon>
204void setSImpl(Eigen::IDRS<Matrix, Precon>& solver,
int const s)
209template <
typename Matrix,
typename Precon>
210void setSImpl(Eigen::IDRSTABL<Matrix, Precon>& solver,
int const s)
216template <
typename Solver>
217void setAngleImpl(Solver&,
double const)
219 DBUG(
"-> setAngle() is not implemented for this linear solver.");
222template <
typename Matrix,
typename Precon>
223void setAngleImpl(Eigen::IDRS<Matrix, Precon>& solver,
double const angle)
225 solver.setAngle(angle);
229template <
typename Solver>
230void setSmoothingImpl(Solver&,
bool const)
232 DBUG(
"-> setSmoothing() is not implemented for this linear solver.");
235template <
typename Matrix,
typename Precon>
236void setSmoothingImpl(Eigen::IDRS<Matrix, Precon>& solver,
bool const smoothing)
238 solver.setSmoothing(smoothing);
242template <
typename Solver>
243void setResidualUpdateImpl(Solver&,
bool const)
245 DBUG(
"-> setResidualUpdate() is not implemented for this linear solver.");
248template <
typename Matrix,
typename Precon>
249void setResidualUpdateImpl(Eigen::IDRS<Matrix, Precon>& solver,
250 bool const residual_update)
252 solver.setResidualUpdate(residual_update);
259template <
class T_SOLVER>
267 INFO(
"-> compute with Eigen iterative linear solver {:s} (precon {:s})",
273#ifdef USE_EIGEN_UNSUPPORTED
283 T_SOLVER>::setResidualUpdate(opt.residualupdate);
288 if (!m.isCompressed())
296 switch (linear_solver_behaviour)
314 "If NumLib::LinearSolverBehaviour::REUSE is set then "
315 "EigenLinearSolver::compute() should never be executed");
318 if (
solver_.info() != Eigen::Success)
320 ERR(
"Failed during Eigen linear solver initialization");
329 INFO(
"-> solve with Eigen iterative linear solver {:s} (precon {:s})",
333 x =
solver_.solveWithGuess(b, x);
334 INFO(
"\t iteration: {:d}/{:d}",
solver_.iterations(),
338 if (
solver_.info() != Eigen::Success)
340 ERR(
"Failed during Eigen linear solve");
350#ifdef USE_EIGEN_UNSUPPORTED
351 void setRestart(
int const restart) { setRestartImpl(
solver_, restart); }
352 void setL(
int const l) { setLImpl(
solver_, l); }
353 void setS(
int const s) { setSImpl(
solver_,
s); }
354 void setAngle(
double const angle) { setAngleImpl(
solver_, angle); }
355 void setSmoothing(
bool const smoothing)
357 setSmoothingImpl(
solver_, smoothing);
359 void setResidualUpdate(
bool const residual_update)
361 setResidualUpdateImpl(
solver_, residual_update);
366template <
template <
typename,
typename>
class Solver,
typename Precon>
371 return std::make_unique<Slv>();
374template <
template <
typename,
typename>
class Solver>
382 Eigen::IdentityPreconditioner>();
385 Solver, Eigen::DiagonalPreconditioner<double>>();
388 Solver, Eigen::LeastSquareDiagonalPreconditioner<double>>();
394 Eigen::IncompleteLUT<double>>();
396 OGS_FATAL(
"Invalid Eigen preconditioner type.");
400template <
typename Mat,
typename Precon>
403template <
typename Mat,
typename Precon>
406template <
typename Mat,
typename Precon>
408 Eigen::ConjugateGradient<Mat, Eigen::Lower | Eigen::Upper, Precon>;
422#ifdef USE_EIGEN_UNSUPPORTED
423#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
426 OGS_FATAL(
"BiCGSTABL requires at least Eigen version 3.4.90");
430 "The code is not compiled with the Eigen unsupported modules. "
431 "Linear solver type BiCGSTABL is not available.");
436 switch (triangular_matrix_type)
453#ifdef USE_EIGEN_UNSUPPORTED
457 "The code is not compiled with the Eigen unsupported modules. "
458 "Linear solver type GMRES is not available.");
463#ifdef USE_EIGEN_UNSUPPORTED
464#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
467 OGS_FATAL(
"IDRS requires at least Eigen version 3.4.90");
471 "The code is not compiled with the Eigen unsupported modules. "
472 "Linear solver type IDRS is not available.");
477#ifdef USE_EIGEN_UNSUPPORTED
478#if EIGEN_VERSION_AT_LEAST(3, 4, 90)
481 OGS_FATAL(
"IDRSTABL requires at least Eigen version 3.4.90");
485 "The code is not compiled with the Eigen unsupported modules. "
486 "Linear solver type IDRSTABL is not available.");
490 OGS_FATAL(
"Invalid Eigen iterative linear solver type. Aborting.");
504 case EigenOption::SolverType::SparseLU:
507 Eigen::SparseLU<Matrix, Eigen::COLAMDOrdering<int>>;
508 solver_ = std::make_unique<
509 details::EigenDirectLinearSolver<SolverType>>();
510 can_solve_rectangular_ = false;
522 option_.triangular_matrix_type);
529 option_.triangular_matrix_type);
535 using SolverType = Eigen::PardisoLU<EigenMatrix::RawMatrixType>;
536 solver_.reset(new details::EigenDirectLinearSolver<SolverType>);
537 can_solve_rectangular_ = false;
541 "The code is not compiled with Intel MKL. Linear solver type "
542 "PardisoLU is not available.");
547 OGS_FATAL(
"Invalid Eigen linear solver type. Aborting.");
550EigenLinearSolver::~EigenLinearSolver() =
default;
556 INFO(
"------------------------------------------------------------------");
557 INFO(
"*** Eigen solver compute()");
564 INFO(
"------------------------------------------------------------------");
565 INFO(
"*** Eigen solver solve()");
575 linear_solver_behaviour) &&
583 !
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.