AMDiS  2.10
The Adaptive Multi-Dimensional Simulation Toolbox
ISTLSolverCreator.hpp
1 #pragma once
2 
3 #include <memory>
4 
5 #include <dune/common/version.hh>
6 
7 #include <dune/common/ftraits.hh>
8 #include <dune/istl/solvers.hh>
9 #include <dune/istl/solvertype.hh>
10 
11 #if HAVE_SUITESPARSE_UMFPACK
12 #include <dune/istl/umfpack.hh>
13 #endif
14 #if HAVE_SUITESPARSE_LDL
15 #include <dune/istl/ldl.hh>
16 #endif
17 #if HAVE_SUITESPARSE_SPQR
18 #include <dune/istl/spqr.hh>
19 #endif
20 #if HAVE_SUPERLU
21 #include <dune/istl/superlu.hh>
22 #endif
23 
24 #include <amdis/CreatorMap.hpp>
25 #include <amdis/Environment.hpp>
26 #include <amdis/Initfile.hpp>
27 #include <amdis/Output.hpp>
28 
29 #include <amdis/linearalgebra/istl/ISTLPreconCreator.hpp>
30 #include <amdis/linearalgebra/istl/SolverWrapper.hpp>
31 #include <amdis/linearalgebra/istl/Traits.hpp>
32 #include <amdis/linearalgebra/istl/precompiled/Solvers.hpp>
33 
34 namespace AMDiS
35 {
36  namespace tag
37  {
38  template <class Traits>
39  struct solver {};
40 
41  // forward declaration
42  template <class Traits>
43  struct preconditioner;
44  }
45 
47 
53  template <class Traits>
54  class ISTLSolverCreatorBase
55  : public CreatorInterface<tag::solver<Traits>>
56  {
57  using X = typename Traits::X;
58  using Y = typename Traits::Y;
59 
60  std::unique_ptr<tag::solver<Traits>> create() final { return {}; };
61 
62  public:
64  virtual void init(std::string const& prefix)
65  {
66  if (Environment::mpiRank() == 0)
67  Parameters::get(prefix + "->info", info_);
68  }
69 
70  virtual std::unique_ptr<Dune::InverseOperator<X,Y>>
71  createSolver(typename Traits::M const& A, typename Traits::Comm const& comm) const = 0;
72 
73  protected:
74  int info_ = 0;
75  };
76 
77 
79 
87  template <class Traits>
89  : public ISTLSolverCreatorBase<Traits>
90  {
92 
93  using real_type = typename Dune::FieldTraits<typename Traits::M::field_type>::real_type;
94 
95  public:
96  void init(std::string const& prefix) override
97  {
98  Super::init(prefix);
99 
100  maxIter_ = Parameters::get<int>(prefix + "->maxit").value_or(
101  Parameters::get<int>(prefix + "->max iteration").value_or(maxIter_));
102  rTol_ = Parameters::get<real_type>(prefix + "->reduction").value_or(
103  Parameters::get<real_type>(prefix + "->relative tolerance").value_or(rTol_));
104 
105  std::string precon = "default";
106  Parameters::get(prefix + "->precon", precon);
107 
109  auto* creator = CreatorMap::get(precon, prefix + "->precon");
110  preconCreator_ = dynamic_cast<ISTLPreconCreatorBase<Traits>*>(creator);
111  assert(preconCreator_ != nullptr);
112  preconCreator_->init(prefix + "->precon");
113  }
114 
115  protected:
116  template <class Solver, class... Args>
117  auto create_impl(typename Traits::M const& mat, typename Traits::Comm const& comm, Args&&... args) const
118  {
119  auto cat = Dune::SolverCategory::category(comm);
120  auto sp = Traits::ScalProdCreator::create(cat, comm);
121  auto linOp = Traits::LinOpCreator::create(cat, mat, comm);
122 
123  assert(preconCreator_ != nullptr);
124  auto precon = preconCreator_->createPrecon(mat, comm);
125  return std::make_unique<IterativeSolverWrapper<Solver>>(
126  std::move(linOp), std::move(sp), std::move(precon), FWD(args)...);
127  }
128 
129  protected:
130  int maxIter_ = 500;
131  real_type rTol_ = 1.e-6;
132  ISTLPreconCreatorBase<Traits>* preconCreator_ = nullptr;
133  };
134 
135 
137 
141  template <class Solver, class Traits>
143  : public ISTLIterativeSolverCreatorBase<Traits>
144  {
146  using Interface = typename Traits::Solver;
147 
148  public:
149  std::unique_ptr<Interface>
150  createSolver(typename Traits::M const& mat, typename Traits::Comm const& comm) const override
151  {
152  return this->template create_impl<Solver>(mat, comm, this->rTol_, this->maxIter_, this->info_);
153  }
154  };
155 
156 
158 
165  template <class Solver, class Traits>
168  {
170  using Interface = typename Traits::Solver;
171 
172  public:
173  void init(std::string const& prefix) override
174  {
175  Super::init(prefix);
176  Parameters::get(prefix + "->restart", restart_);
177  }
178 
179  std::unique_ptr<Interface>
180  createSolver(typename Traits::M const& mat, typename Traits::Comm const& comm) const override
181  {
182  return this->template create_impl<Solver>(mat, comm, this->rTol_, restart_, this->maxIter_, this->info_);
183  }
184 
185  private:
186  int restart_ = 30;
187  };
188 
189  template <class X, class Y, class Traits>
192  {};
193 
194  template <class X, class Y, class Traits>
195  struct IterativeSolverCreator<Dune::RestartedFlexibleGMResSolver<X,Y>, Traits>
196  : public GMResSolverCreator<Dune::RestartedFlexibleGMResSolver<X,Y>, Traits>
197  {};
198 
199 
201 
208  template <class Solver, class Traits>
210  : public ISTLIterativeSolverCreatorBase<Traits>
211  {
213  using Interface = typename Traits::Solver;
214 
215  public:
216  void init(std::string const& prefix) override
217  {
218  Super::init(prefix);
219  Parameters::get(prefix + "->restart", restart_);
220  }
221 
222  std::unique_ptr<Interface>
223  createSolver(typename Traits::M const& mat, typename Traits::Comm const& comm) const override
224  {
225  return this->template create_impl<Solver>(mat, comm, this->rTol_, this->maxIter_, this->info_, restart_);
226  }
227 
228  private:
229  int restart_ = 30;
230  };
231 
232  template <class X, class Traits>
235  {};
236 
237  template <class X, class Traits>
238  struct IterativeSolverCreator<Dune::RestartedFCGSolver<X>, Traits>
239  : public PCGSolverCreator<Dune::RestartedFCGSolver<X>, Traits>
240  {};
241 
242  template <class X, class Traits>
243  struct IterativeSolverCreator<Dune::CompleteFCGSolver<X>, Traits>
244  : public PCGSolverCreator<Dune::CompleteFCGSolver<X>, Traits>
245  {};
246 
247 
249 
259  template <class Solver, class Traits>
261  : public ISTLSolverCreatorBase<Traits>
262  {
264 
265  void init(std::string const& prefix) override
266  {
267  Super::init(prefix);
268  Parameters::get(prefix + "->reuse vector", reuseVector_);
269  }
270 
271  std::unique_ptr<typename Traits::Solver>
272  createSolver(typename Traits::M const& mat, typename Traits::Comm const& comm) const override
273  {
274  test_exit(Dune::SolverCategory::category(comm) == Dune::SolverCategory::sequential,
275  "Direct solver can be used as sequential solver only.");
276  return std::make_unique<Solver>(mat, this->info_, reuseVector_);
277  }
278 
279  protected:
280  bool reuseVector_ = true;
281  };
282 
283 
284  template <class Solver, class Traits>
285  using ISTLSolverCreator = std::conditional_t<Dune::IsDirectSolver<Solver>::value,
288 
289 } // end namespace AMDiS
static CreatorInterface< BaseClass > * get(std::string key, std::string initFileStr)
Creates a object of the type corresponding to key.
Definition: CreatorMap.hpp:44
Base class for solver creators,.
Definition: ISTLPreconCreator.hpp:132
A CreatorMap is used to construct objects, which types depends on key words determined at run time...
Definition: CreatorMap.hpp:29
Definition: AdaptBase.hpp:6
Solver creator for iterative GMRes-like solvers.
Definition: ISTLSolverCreator.hpp:166
Base class for precon creators,.
Definition: ISTLPreconCreator.hpp:39
void init(std::string const &prefix) override
Prepare the solver for the creation.
Definition: ISTLSolverCreator.hpp:173
static std::optional< T > get(std::string const &key)
Get parameter-values from parameter-tree.
Definition: Initfile.hpp:25
void init(std::string const &prefix) override
Prepare the solver for the creation.
Definition: ISTLSolverCreator.hpp:265
void init(std::string const &prefix) override
Prepare the solver for the creation.
Definition: ISTLSolverCreator.hpp:216
Default creator for direct solvers.
Definition: ISTLSolverCreator.hpp:260
virtual void init(std::string const &prefix)
Prepare the solver for the creation.
Definition: ISTLSolverCreator.hpp:64
Base solver creator for iterative solvers.
Definition: ISTLSolverCreator.hpp:88
Default solver creator for iterative solvers.
Definition: Solvers.hpp:24
Solver creator for iterative CG-like solvers.
Definition: ISTLSolverCreator.hpp:209
void init(std::string const &prefix) override
Prepare the solver for the creation.
Definition: ISTLSolverCreator.hpp:96
static int mpiRank()
Return the MPI_Rank of the current processor.
Definition: Environment.hpp:68