AMDiS  2.10
The Adaptive Multi-Dimensional Simulation Toolbox
UmfpackRunner.hpp
1 #pragma once
2 
3 #ifdef HAVE_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 
17 namespace 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_UMFPACK
void finish() override
Implements LinearSolverInterface::finish()
Definition: UmfpackRunner.hpp:68
Definition: UmfpackRunner.hpp:36
Interface for creators with name.
Definition: CreatorInterface.hpp:42
Definition: AdaptBase.hpp:6
Definition: UmfpackRunner.hpp:29
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
static std::optional< T > get(std::string const &key)
Get parameter-values from parameter-tree.
Definition: Initfile.hpp:25
Definition: LinearSolverInterface.hpp:8
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 init(M const &A) override
Implements LinearSolverInterface::init()
Definition: UmfpackRunner.hpp:55