AMDiS  0.1
The Adaptive Multi-Dimensional Simulation Toolbox
PreconCreator.hpp
1 #pragma once
2 
3 #include <amdis/CreatorInterface.hpp>
4 #include <amdis/CreatorMap.hpp>
5 #include <amdis/linearalgebra/istl/AMGPrecon.hpp>
6 #include <amdis/linearalgebra/istl/CreatorInterfaces.hpp>
7 #include <amdis/linearalgebra/istl/PreconWrapper.hpp>
8 #include <amdis/linearalgebra/istl/precompiled/Preconditioners.hpp>
9 
10 namespace AMDiS
11 {
12  namespace tag
13  {
14  struct bjacobi {};
15  struct solver {};
16  }
17 
19 
26  template <class Model, class Traits>
28  : public ISTLPreconCreatorInterface<Traits>
29  {
30  using Interface = ISTLPreconCreatorInterface<Traits>;
31  struct Creator : CreatorInterfaceName<Interface>
32  {
33  std::unique_ptr<Interface> createWithString(std::string prefix) override
34  {
35  return std::make_unique<Model>(prefix);
36  }
37  };
38 
39  explicit ISTLPreconCreator(std::string const& prefix)
40  {
41  Parameters::get(prefix + "->relaxation", w_);
42  Parameters::get(prefix + "->iterations", iter_);
43  }
44 
45  protected:
46  double w_ = 1.0;
47  int iter_ = 1;
48  };
49 
50 
52 
56  template <class Precon, class Traits>
58  : public ISTLPreconCreator<PreconCreator<Precon,Traits>, Traits>
59  {
61  using Super::Super; // inheriting constructor
62 
63  std::unique_ptr<typename Traits::Prec>
64  create(typename Traits::M const& mat, [[maybe_unused]] typename Traits::Comm const& comm) const override
65  {
66  return std::make_unique<Precon>(mat, this->iter_, this->w_);
67  }
68  };
69 
70 
72  template <class X, class Y, class Traits>
73  struct PreconCreator<Dune::Richardson<X, Y>, Traits>
74  : public ISTLPreconCreator<PreconCreator<Dune::Richardson<X, Y>, Traits>, Traits>
75  {
77  using Super::Super; // inheriting constructor
78 
79  std::unique_ptr<typename Traits::Prec>
80  create([[maybe_unused]] typename Traits::M const& mat, [[maybe_unused]] typename Traits::Comm const& comm) const override
81  {
82  using Precon = Dune::Richardson<X, Y>;
83  return std::make_unique<Precon>(this->w_);
84  }
85  };
86 
87 
89  template <class M, class X, class Y, class Traits>
90  struct PreconCreator<Dune::SeqILDL<M, X, Y>, Traits>
91  : public ISTLPreconCreator<PreconCreator<Dune::SeqILDL<M, X, Y>, Traits>, Traits>
92  {
94  using Super::Super; // inheriting constructor
95 
96  std::unique_ptr<typename Traits::Prec>
97  create(typename Traits::M const& mat, [[maybe_unused]] typename Traits::Comm const& comm) const override
98  {
99  using Precon = Dune::SeqILDL<M, X, Y>;
100  return std::make_unique<Precon>(mat, this->w_);
101  }
102  };
103 
104 
106 
110  template <class M, class X, class Y, class Comm, class Traits>
111  struct PreconCreator<Dune::ParSSOR<M, X, Y, Comm>, Traits>
112  : public ISTLPreconCreator<PreconCreator<Dune::ParSSOR<M,X,Y,Comm>, Traits>, Traits>
113  {
115  using Super::Super; // inheriting constructor
116 
117  std::unique_ptr<typename Traits::Prec>
118  create(typename Traits::M const& mat, typename Traits::Comm const& comm) const override
119  {
120  test_exit(Dune::SolverCategory::category(comm) == Dune::SolverCategory::overlapping,
121  "Dune::ParSSOR preconditioner can be used with overlapping domain decomposition.");
122 
123  using Precon = Dune::ParSSOR<M,X,Y,Comm>;
124  return std::make_unique<Precon>(mat, this->iter_, this->w_, comm.get());
125  }
126  };
127 
128 
130 
138  template <class Traits>
139  struct PreconCreator<tag::solver, Traits>
140  : public ISTLPreconCreator<PreconCreator<tag::solver, Traits>, Traits>
141  {
143 
144  explicit PreconCreator(std::string const& prefix)
145  : Super(prefix)
146  {
147  std::string solver = "default";
148  Parameters::get(prefix + "->solver", solver);
149 
151  auto* creator = named(CreatorMap::getCreator(solver, prefix + "->solver"));
152  solverCreator_ = creator->createWithString(prefix + "->solver");
153  assert(solverCreator_);
154  }
155 
156  std::unique_ptr<typename Traits::Prec>
157  create(typename Traits::M const& mat, typename Traits::Comm const& comm) const override
158  {
159  using InverseOp = Dune::InverseOperator<typename Traits::X, typename Traits::Y>;
160  using Precon = Dune::InverseOperator2Preconditioner<InverseOp>;
161  using Wrapper = PreconWrapper<Precon, InverseOp>;
162  return std::make_unique<Wrapper>(solverCreator_->create(mat, comm));
163  }
164 
165  private:
166  std::shared_ptr<ISTLSolverCreatorInterface<Traits>> solverCreator_;
167  };
168 
169 
171 
182  template <class Traits>
183  struct PreconCreator<tag::bjacobi, Traits>
184  : public ISTLPreconCreator<PreconCreator<tag::bjacobi, Traits>, Traits>
185  {
188 
189  explicit PreconCreator(std::string const& prefix)
190  : Super(prefix)
191  {
192  std::string subPrecon = "default";
193  Parameters::get(prefix + "->sub precon", subPrecon);
194 
196  auto* creator = named(CreatorMap::getCreator(subPrecon, prefix + "->sub precon"));
197  subPreconCreator_ = creator->createWithString(prefix + "->sub precon");
198  assert(subPreconCreator_);
199  }
200 
201  std::unique_ptr<typename Traits::Prec>
202  create(typename Traits::M const& mat, typename Traits::Comm const& comm) const override
203  {
204  return Traits::ParPrecCreator::create(Dune::SolverCategory::category(comm),
205  subPreconCreator_->create(mat, comm.sequential()),
206  comm);
207  }
208 
209  private:
210  std::shared_ptr<ISTLPreconCreatorInterface<SeqTraits>> subPreconCreator_;
211  };
212 
213 
215 
229  template <class Traits>
231  {
232  using M = typename Traits::M;
233  using X = typename Traits::X;
234  using Y = typename Traits::Y;
235 
236  template <class Precon>
237  using PreconCreator = typename AMDiS::PreconCreator<Precon, Traits>::Creator;
238 
240  using FTraits = Dune::FieldTraits<typename M::field_type>;
241 
242  public:
243  static void init()
244  {
245  auto jacobi = new PreconCreator<Dune::SeqJac<M,X,Y>>;
246  Map::addCreator("diag", jacobi);
247  Map::addCreator("jacobi", jacobi);
248 
249  auto gs = new PreconCreator<Dune::SeqGS<M,X,Y>>;
250  Map::addCreator("gs", gs);
251  Map::addCreator("gauss_seidel", gs);
252 
253  auto sor = new PreconCreator<Dune::SeqSOR<M,X,Y>>;
254  Map::addCreator("sor", sor);
255 
256  auto ssor = new PreconCreator<Dune::SeqSSOR<M,X,Y>>;
257  Map::addCreator("ssor", ssor);
258 
259  init_ilu(std::is_arithmetic<typename FTraits::field_type>{});
260  init_amg(std::is_same<typename FTraits::real_type, double>{});
261 
262  auto richardson = new PreconCreator<Dune::Richardson<X,Y>>;
263  Map::addCreator("richardson", richardson);
264  Map::addCreator("default", richardson);
265 
266  auto solver = new PreconCreator<tag::solver>;
267  Map::addCreator("solver", solver);
268 
269  init_bjacobi(Types<TYPEOF(std::declval<typename Traits::Comm>().get())>{}, Dune::PriorityTag<10>{});
270  }
271 
272  static void init_ilu(std::false_type)
273  {
274  warning("ILU preconditioners not created for the matrix with field_type = {}.",
275  Dune::className<typename FTraits::field_type>());
276  }
277 
278  static void init_ilu(std::true_type)
279  {
280  auto ilu = new PreconCreator<Dune::SeqILU<M,X,Y>>;
281  Map::addCreator("ilu", ilu);
282  Map::addCreator("ilu0", ilu);
283 
284  auto ildl = new PreconCreator<Dune::SeqILDL<M,X,Y>>;
285  Map::addCreator("ildl", ildl);
286  }
287 
288  static void init_amg(std::false_type)
289  {
290  warning("AMG preconditioners not created for the matrix with real_type = {}.",
291  Dune::className<typename FTraits::real_type>());
292  }
293 
294  static void init_amg(std::true_type)
295  {
297  Map::addCreator("amg", amg);
299  Map::addCreator("fastamg", fastamg);
301  Map::addCreator("kamg", kamg);
302  }
303 
304  static void init_bjacobi(Types<Dune::Amg::SequentialInformation>, Dune::PriorityTag<2>) {}
305 
306  template <class Comm>
307  static void init_bjacobi(Types<Comm>, Dune::PriorityTag<1>)
308  {
309  auto pssor = new PreconCreator<Dune::ParSSOR<M,X,Y,Comm>>;
310  Map::addCreator("pssor", pssor);
311 
312  auto bjacobi = new PreconCreator<tag::bjacobi>;
313  Map::addCreator("bjacobi", bjacobi);
314  }
315  };
316 
317  // extern template declarations:
319 
320 } // end namespace AMDiS
Definition: CreatorInterfaces.hpp:11
Definition: Traits.hpp:59
Definition: PreconCreator.hpp:15
A variadic type list.
Definition: TypeTraits.hpp:88
std::unique_ptr< Interface > createWithString(std::string prefix) override
Must be implemented by sub classes of CreatorInterfaceName. Creates a new instance of the sub class o...
Definition: PreconCreator.hpp:33
Interface for creators with name.
Definition: CreatorInterface.hpp:42
A CreatorMap is used to construct objects, which types depends on key words determined at run time...
Definition: CreatorMap.hpp:29
Contains all classes needed for solving linear and non linear equation systems.
Definition: AdaptBase.hpp:6
Definition: PreconCreator.hpp:31
Default precon creator.
Definition: PreconCreator.hpp:57
Definition: PreconCreator.hpp:14
static std::optional< T > get(std::string const &key)
Get parameter-values from parameter-tree.
Definition: Initfile.hpp:25
CreatorInterfaceName< BaseClass > * named(CreatorInterface< BaseClass > *ptr)
cast a ptr of CreatorInterface to CreatorInterfaceName
Definition: CreatorInterface.hpp:64
Definition: CreatorMap.hpp:16
A creator for AMGPrecon, reads the smoother type from initfile:
Definition: AMGPrecon.hpp:166
static CreatorInterface< BaseClass > * getCreator(std::string key, std::string initFileStr)
Creates a object of the type corresponding to key.
Definition: CreatorMap.hpp:44
Definition: PreconWrapper.hpp:20
Base class for precon creators,.
Definition: PreconCreator.hpp:27
void init(int &argc, char **&argv, std::string const &initFileName="")
Initialized the Environment for MPI.
Definition: AMDiS.hpp:29
void test_exit(bool condition, std::string const &str, Args &&... args)
test for condition and in case of failure print message and exit
Definition: Output.hpp:163