AMDiS  0.3
The Adaptive Multi-Dimensional Simulation Toolbox
HyprePrecon.hpp
1 #pragma once
2 
3 #if AMDIS_HAS_HYPRE && HAVE_MPI
4 
5 #include <HYPRE.h>
6 
7 #include <dune/common/unused.hh>
8 #include <amdis/linearalgebra/mtl/PreconditionerInterface.hpp>
9 #include <amdis/linearalgebra/mtl/itl/hypre.hpp>
10 
11 namespace AMDiS
12 {
14 
55  template <class Mat, class Vec>
56  class HyprePrecon
57  : public PreconditionerInterface<Mat, Vec>
58  {
59  using M = typename Mat::BaseMatrix;
60  using X = typename Vec::BaseVector;
61  using Y = typename Vec::BaseVector;
62 
63  using Self = HyprePrecon;
64  using Super = PreconditionerInterface<Mat, Vec>;
65 
66  public:
68  struct Creator : CreatorInterfaceName<Super>
69  {
70  std::unique_ptr<Super> createWithString(std::string prefix) override
71  {
72  return std::make_unique<Self>(prefix);
73  }
74  };
75 
76  public:
77  HyprePrecon(std::string const& prefix)
78  {
79  // read HYPRE parameters
80  int maxIter = 1, cycleMode = -1, interpolation = -1, relaxation = -1, info = 1;
81  Parameters::get(prefix + "->max iteration", maxIter);
82  Parameters::get(prefix + "->cycle mode", cycleMode);
83  Parameters::get(prefix + "->interpolation type", interpolation);
84  Parameters::get(prefix + "->relax type", relaxation);
85  Parameters::get(prefix + "->info", info);
86 
87  config_.maxIter(maxIter);
88  config_.interpolationType(interpolation);
89  config_.relaxType(relaxation);
90  config_.cycle(cycleMode);
91  config_.printLevel(info);
92  }
93 
95  void init(M const& mat) override
96  {
97  hypreMatrix_.init(mat);
98  HYPRE_IJMatrixGetObject(hypreMatrix_, (void**)(&matrix_));
99  HYPRE_BoomerAMGCreate(&solver_);
100 
101  // apply solver parameters
102  config_(solver_);
103 
104  mtl::dense_vector<double> swap(1, 0.0);
105  mtl::HypreParVector x(swap);
106  HYPRE_BoomerAMGSetup(solver_, matrix_, x, x);
107 
108  solverCreated_ = true;
109  }
110 
112  void exit() override
113  {
114  if (solverCreated_)
115  HYPRE_BoomerAMGDestroy(solver_);
116  solverCreated_ = false;
117  }
118 
120  void solve(X const& in, Y& out) const override
121  {
122  assert(solverCreated_);
123  mtl::HypreParVector x(in); // use b as initial guess
124  mtl::HypreParVector b(in);
125 
126  [[maybe_unused]] int error = HYPRE_BoomerAMGSolve(solver_, matrix_, b, x);
127  assert(error != 0);
128 
129  // write output back to MTL vector
130  mtl::convert(x.getHypreVector(), out);
131  }
132 
134  void adjoint_solve(X const& in, Y& out) const override
135  {
136  assert(solverCreated_);
137  mtl::HypreParVector x(in); // use b as initial guess
138  mtl::HypreParVector b(in);
139 
140  [[maybe_unused]] int error = HYPRE_BoomerAMGSolveT(solver_, matrix_, b, x);
141  assert(error != 0);
142 
143  // write output back to MTL vector
144  mtl::convert(x.getHypreVector(), out);
145  }
146 
147  private:
148  mtl::HypreMatrix hypreMatrix_;
149  HYPRE_ParCSRMatrix matrix_;
150  HYPRE_Solver solver_;
151 
152  mtl::AMGConfigurator config_;
153  bool solverCreated_ = false;
154  };
155 
156 } // end namespace AMDiS
157 
158 #endif // AMDIS_HAS_HYPRE && HAVE_MPI
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
static std::optional< T > get(std::string const &key)
Get parameter-values from parameter-tree.
Definition: Initfile.hpp:25
void info(int noInfoLevel, std::string const &str, Args &&... args)
prints a message, if Environment::infoLevel() >= noInfoLevel
Definition: Output.hpp:105
void init(int &argc, char **&argv, std::string const &initFileName="")
Initialized the Environment for MPI.
Definition: AMDiS.hpp:29
auto X()
Generator for CoordsFunction.
Definition: CoordsGridFunction.hpp:123