3#if HAVE_SUITESPARSE_UMFPACK
8#include <dune/istl/solver.hh>
10#include <boost/numeric/mtl/operation/two_norm.hpp>
11#include <boost/numeric/mtl/interface/umfpack_solve.hpp>
13#include <amdis/linearalgebra/mtl/Traits.hpp>
14#include <amdis/linearalgebra/LinearSolverInterface.hpp>
15#include <amdis/Output.hpp>
28 template <
class M,
class X,
class Y>
33 using SolverType = mtl::mat::umfpack::solver<M>;
38 std::unique_ptr<LinearSolverInterface<M,X,Y>>
41 return std::make_unique<Self>(prefix);
55 void init(M
const& A)
override
58 if (
bool(solver_) && storeSymbolic_)
59 solver_->update_numeric();
61 solver_ = std::make_shared<SolverType>(A, symmetricStrategy_, allocInit_);
62 }
catch (mtl::mat::umfpack::error
const& e) {
63 umfpack_error_exit(
"factorize", e.code);
71 void apply(X& x, Y
const& b, Dune::InverseOperatorResult& stat)
override
73 test_exit(
bool(solver_),
"UmfpackRunner must be initialized.");
77 code = (*solver_)(x, b);
78 }
catch (mtl::mat::umfpack::error& e) {
79 umfpack_error_exit(
"solve", e.code);
83 stat.converged = (code == UMFPACK_OK);
84 stat.elapsed = t.elapsed();
88 static void umfpack_error_exit(std::string solutionPhase,
int code)
90 static std::map<int, std::string> error_message = {
91 {UMFPACK_OK,
"UMFPACK was successful"},
92 {UMFPACK_WARNING_singular_matrix,
"Matrix is singular. There are exact zeros on the diagonal."},
93 {UMFPACK_WARNING_determinant_underflow,
"The determinant is nonzero, but smaller in magnitude than the smallest positive floating-point number."},
94 {UMFPACK_WARNING_determinant_overflow,
"The determinant is larger in magnitude than the largest positive floating-point number (IEEE Inf)."},
95 {UMFPACK_ERROR_out_of_memory,
"Not enough memory. The ANSI C malloc or realloc routine failed."},
96 {UMFPACK_ERROR_invalid_Numeric_object,
"Invalid Numeric object."},
97 {UMFPACK_ERROR_invalid_Symbolic_object,
"Invalid Symbolic object."},
98 {UMFPACK_ERROR_argument_missing,
"Some required arguments are missing."},
99 {UMFPACK_ERROR_n_nonpositive,
"The number of rows or columns of the matrix must be greater than zero."},
100 {UMFPACK_ERROR_invalid_matrix,
"The matrix is invalid."},
101 {UMFPACK_ERROR_different_pattern,
"The pattern of the matrix has changed between the symbolic and numeric factorization."},
102 {UMFPACK_ERROR_invalid_system,
"The sys argument provided to one of the solve routines is invalid."},
103 {UMFPACK_ERROR_invalid_permutation,
"The permutation vector provided as input is invalid."},
104 {UMFPACK_ERROR_file_IO,
"Error in file IO"},
105 {UMFPACK_ERROR_ordering_failed,
"The ordering method failed."},
106 {UMFPACK_ERROR_internal_error,
"An internal error has occurred, of unknown cause."}
109 error_exit(
"UMFPACK_ERROR({}, {}) = {}", solutionPhase, code, error_message[code]);
113 std::shared_ptr<SolverType> solver_;
115 bool storeSymbolic_ =
false;
116 int symmetricStrategy_ = 0;
117 double allocInit_ = 0.7;
Interface for creators with name.
Definition: CreatorInterface.hpp:44
static std::optional< T > get(std::string const &key)
Get parameter-values from parameter-tree.
Definition: Initfile.hpp:25
Definition: LinearSolverInterface.hpp:9
Wrapper for the external UMFPACK solver
Definition: UmfpackRunner.hpp:31
void init(M const &A) override
Implements LinearSolverInterface::init()
Definition: UmfpackRunner.hpp:55
void apply(X &x, Y const &b, Dune::InverseOperatorResult &stat) override
Implements LinearSolverInterface::apply()
Definition: UmfpackRunner.hpp:71
UmfpackRunner(std::string const &prefix)
Constructor. Reads UMFPACK parameters from initfile.
Definition: UmfpackRunner.hpp:47
void finish() override
Implements LinearSolverInterface::finish()
Definition: UmfpackRunner.hpp:68
Definition: UmfpackRunner.hpp:37
std::unique_ptr< LinearSolverInterface< M, X, Y > > createWithString(std::string prefix) final
Must be implemented by sub classes of CreatorInterfaceName. Creates a new instance of the sub class o...
Definition: UmfpackRunner.hpp:39