From 0344fff12ed5d39d672b20fb246318ebb33f03c3 Mon Sep 17 00:00:00 2001 From: Norihiro Watanabe <norihiro.watanabe@ufz.de> Date: Wed, 2 Nov 2016 11:25:38 +0100 Subject: [PATCH] [Math/Eigen] support scaling --- MathLib/LinAlg/Eigen/EigenLinearSolver.cpp | 25 ++++++++++++++++++++++ MathLib/LinAlg/Eigen/EigenOption.cpp | 3 +++ MathLib/LinAlg/Eigen/EigenOption.h | 4 ++++ 3 files changed, 32 insertions(+) diff --git a/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp b/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp index 858987d7f8e..f308a482925 100644 --- a/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp +++ b/MathLib/LinAlg/Eigen/EigenLinearSolver.cpp @@ -15,6 +15,10 @@ #include <Eigen/PardisoSupport> #endif +#ifdef USE_EIGEN_UNSUPPORTED +#include <unsupported/Eigen/src/IterativeSolvers/Scaling.h> +#endif + #include "BaseLib/ConfigTree.h" #include "EigenVector.h" #include "EigenMatrix.h" @@ -224,6 +228,13 @@ void EigenLinearSolver::setOption(BaseLib::ConfigTree const& option) ptSolver->getConfigParameterOptional<int>("max_iteration_step")) { _option.max_iterations = *max_iteration_step; } +#ifdef USE_EIGEN_UNSUPPORTED + if (auto scaling = + //! \ogs_file_param{linear_solver__eigen__scaling} + ptSolver->getConfigParameterOptional<int>("scaling")) { + _option.scaling = static_cast<bool>(*scaling); + } +#endif } bool EigenLinearSolver::solve(EigenMatrix &A, EigenVector& b, EigenVector &x) @@ -231,8 +242,22 @@ bool EigenLinearSolver::solve(EigenMatrix &A, EigenVector& b, EigenVector &x) INFO("------------------------------------------------------------------"); INFO("*** Eigen solver computation"); +#ifdef USE_EIGEN_UNSUPPORTED + std::unique_ptr<Eigen::IterScaling<EigenMatrix::RawMatrixType>> scal; + if (_option.scaling) + { + INFO("-> scale"); + scal.reset(new Eigen::IterScaling<EigenMatrix::RawMatrixType>()); + scal->computeRef(A.getRawMatrix()); + b.getRawVector() = scal->LeftScaling().cwiseProduct(b.getRawVector()); + } +#endif auto const success = _solver->solve(A.getRawMatrix(), b.getRawVector(), x.getRawVector(), _option); +#ifdef USE_EIGEN_UNSUPPORTED + if (scal) + x.getRawVector() = scal->RightScaling().cwiseProduct(x.getRawVector()); +#endif INFO("------------------------------------------------------------------"); diff --git a/MathLib/LinAlg/Eigen/EigenOption.cpp b/MathLib/LinAlg/Eigen/EigenOption.cpp index 8bd700d93b6..4fa228a245a 100644 --- a/MathLib/LinAlg/Eigen/EigenOption.cpp +++ b/MathLib/LinAlg/Eigen/EigenOption.cpp @@ -19,6 +19,9 @@ EigenOption::EigenOption() precon_type = PreconType::NONE; max_iterations = static_cast<int>(1e6); error_tolerance = 1.e-16; +#ifdef USE_EIGEN_UNSUPPORTED + scaling = false; +#endif } EigenOption::SolverType EigenOption::getSolverType(const std::string &solver_name) diff --git a/MathLib/LinAlg/Eigen/EigenOption.h b/MathLib/LinAlg/Eigen/EigenOption.h index 70b4329908f..46ccf4d4d09 100644 --- a/MathLib/LinAlg/Eigen/EigenOption.h +++ b/MathLib/LinAlg/Eigen/EigenOption.h @@ -43,6 +43,10 @@ struct EigenOption final int max_iterations; /// Error tolerance double error_tolerance; +#ifdef USE_EIGEN_UNSUPPORTED + /// Scaling the coefficient matrix and the RHS bector + bool scaling; +#endif /// Constructor /// -- GitLab