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
11namespace 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
static std::optional< T > get(std::string const &key)
Get parameter-values from parameter-tree.
Definition: Initfile.hpp:25