AMDiS 2.10
The Adaptive Multi-Dimensional Simulation Toolbox
UmfpackRunner.hpp
1#pragma once
2
3#if HAVE_SUITESPARSE_UMFPACK
4
5#include <algorithm>
6#include <string>
7
8#include <dune/istl/solver.hh>
9
10#include <boost/numeric/mtl/operation/two_norm.hpp>
11#include <boost/numeric/mtl/interface/umfpack_solve.hpp>
12
13#include <amdis/linearalgebra/mtl/Traits.hpp>
14#include <amdis/linearalgebra/LinearSolverInterface.hpp>
15#include <amdis/Output.hpp>
16
17namespace AMDiS
18{
28 template <class M, class X, class Y>
30 : public LinearSolverInterface<M,X,Y>
31 {
32 using Self = UmfpackRunner;
33 using SolverType = mtl::mat::umfpack::solver<M>;
34
35 public:
36 struct Creator final : CreatorInterfaceName<LinearSolverInterface<M,X,Y>>
37 {
38 std::unique_ptr<LinearSolverInterface<M,X,Y>>
39 createWithString(std::string prefix) final
40 {
41 return std::make_unique<Self>(prefix);
42 }
43 };
44
45 public:
47 UmfpackRunner(std::string const& prefix)
48 {
49 Parameters::get(prefix + "->store symbolic", storeSymbolic_);
50 Parameters::get(prefix + "->symmetric strategy", symmetricStrategy_);
51 Parameters::get(prefix + "->alloc init", allocInit_);
52 }
53
55 void init(M const& A) override
56 {
57 try {
58 if (bool(solver_) && storeSymbolic_)
59 solver_->update_numeric();
60 else
61 solver_ = std::make_shared<SolverType>(A, symmetricStrategy_, allocInit_);
62 } catch (mtl::mat::umfpack::error const& e) {
63 umfpack_error_exit("factorize", e.code);
64 }
65 }
66
68 void finish() override {}
69
71 void apply(X& x, Y const& b, Dune::InverseOperatorResult& stat) override
72 {
73 test_exit(bool(solver_), "UmfpackRunner must be initialized.");
74 Dune::Timer t;
75 int code = 0;
76 try {
77 code = (*solver_)(x, b);
78 } catch (mtl::mat::umfpack::error& e) {
79 umfpack_error_exit("solve", e.code);
80 }
81
82 stat.iterations = 1;
83 stat.converged = (code == UMFPACK_OK);
84 stat.elapsed = t.elapsed();
85 }
86
87 protected:
88 static void umfpack_error_exit(std::string solutionPhase, int code)
89 {
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."}
107 };
108
109 error_exit("UMFPACK_ERROR({}, {}) = {}", solutionPhase, code, error_message[code]);
110 }
111
112 protected:
113 std::shared_ptr<SolverType> solver_;
114
115 bool storeSymbolic_ = false;
116 int symmetricStrategy_ = 0;
117 double allocInit_ = 0.7;
118 };
119
120} // end namespace AMDiS
121
122#endif // HAVE_SUITESPARSE_UMFPACK
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