AMDiS  2.10
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 <amdis/Initfile.hpp>
8 #include <amdis/linearalgebra/mtl/PreconditionerInterface.hpp>
9 #include <amdis/linearalgebra/mtl/itl/hypre.hpp>
10 
11 namespace AMDiS
12 {
14 
55  template <class M, class X, class Y>
56  class HyprePrecon
57  : public PreconditionerInterface<M,X,Y>
58  {
59  using Self = HyprePrecon;
60  using Super = PreconditionerInterface<M,X,Y>;
61 
62  public:
64  struct Creator : CreatorInterfaceName<Super>
65  {
66  std::unique_ptr<Super> createWithString(std::string prefix) override
67  {
68  return std::make_unique<Self>(prefix);
69  }
70  };
71 
72  public:
73  HyprePrecon(std::string const& prefix)
74  {
75  // read HYPRE parameters
76  int maxIter = 1, cycleMode = -1, interpolation = -1, relaxation = -1, info = 1;
77  Parameters::get(prefix + "->max iteration", maxIter);
78  Parameters::get(prefix + "->cycle mode", cycleMode);
79  Parameters::get(prefix + "->interpolation type", interpolation);
80  Parameters::get(prefix + "->relax type", relaxation);
81  Parameters::get(prefix + "->info", info);
82 
83  config_.maxIter(maxIter);
84  config_.interpolationType(interpolation);
85  config_.relaxType(relaxation);
86  config_.cycle(cycleMode);
87  config_.printLevel(info);
88  }
89 
91  void init(M const& mat) override
92  {
93  hypreMatrix_.init(mat);
94  HYPRE_IJMatrixGetObject(hypreMatrix_, (void**)(&matrix_));
95  HYPRE_BoomerAMGCreate(&solver_);
96 
97  // apply solver parameters
98  config_(solver_);
99 
100  mtl::dense_vector<double> swap(1, 0.0);
101  mtl::HypreParVector x(swap);
102  HYPRE_BoomerAMGSetup(solver_, matrix_, x, x);
103 
104  solverCreated_ = true;
105  }
106 
108  void finish() override
109  {
110  if (solverCreated_)
111  HYPRE_BoomerAMGDestroy(solver_);
112  solverCreated_ = false;
113  }
114 
116  void solve(X const& in, Y& out) const override
117  {
118  assert(solverCreated_);
119  mtl::HypreParVector x(in); // use b as initial guess
120  mtl::HypreParVector b(in);
121 
122  [[maybe_unused]] int error = HYPRE_BoomerAMGSolve(solver_, matrix_, b, x);
123  assert(error != 0);
124 
125  // write output back to MTL vector
126  mtl::convert(x.getHypreVector(), out);
127  }
128 
130  void adjoint_solve(X const& in, Y& out) const override
131  {
132  assert(solverCreated_);
133  mtl::HypreParVector x(in); // use b as initial guess
134  mtl::HypreParVector b(in);
135 
136  [[maybe_unused]] int error = HYPRE_BoomerAMGSolveT(solver_, matrix_, b, x);
137  assert(error != 0);
138 
139  // write output back to MTL vector
140  mtl::convert(x.getHypreVector(), out);
141  }
142 
143  private:
144  mtl::HypreMatrix hypreMatrix_;
145  HYPRE_ParCSRMatrix matrix_;
146  HYPRE_Solver solver_;
147 
148  mtl::AMGConfigurator config_;
149  bool solverCreated_ = false;
150  };
151 
152 } // end namespace AMDiS
153 
154 #endif // AMDIS_HAS_HYPRE && HAVE_MPI
Definition: AdaptBase.hpp:6
static std::optional< T > get(std::string const &key)
Get parameter-values from parameter-tree.
Definition: Initfile.hpp:25