AMDiS  0.3
The Adaptive Multi-Dimensional Simulation Toolbox
SolverCreator.hpp
1 #pragma once
2 
3 #include <memory>
4 
5 #include <Eigen/IterativeLinearSolvers>
6 #include <Eigen/MetisSupport>
7 #include <Eigen/SparseLU>
8 #include <Eigen/SuperLUSupport>
9 #include <Eigen/UmfPackSupport>
10 #include <unsupported/Eigen/IterativeSolvers>
11 
12 #include <amdis/CreatorMap.hpp>
13 #include <amdis/Initfile.hpp>
14 #include <amdis/Output.hpp>
15 
16 #include <amdis/linearalgebra/LinearSolver.hpp>
17 #include <amdis/linearalgebra/eigen/DirectRunner.hpp>
18 #include <amdis/linearalgebra/eigen/IterativeRunner.hpp>
19 #include <amdis/linearalgebra/eigen/Traits.hpp>
20 
21 namespace AMDiS
22 {
23  template <class Mat, class Vec, template <class> class IterativeSolver>
25  : public CreatorInterfaceName<LinearSolverInterface<Mat,Vec>>
26  {
27  template <class Precon>
28  using SolverCreator
30 
32  using M = typename Mat::BaseMatrix;
33  using Scalar = typename M::Scalar;
34 
35  std::unique_ptr<SolverBase> createWithString(std::string prefix) override
36  {
37  // get creator string for preconditioner
38  std::string precon = "no";
39  Parameters::get(prefix + "->precon->name", precon);
40 
41  if (precon == "diag" ||
42  precon == "jacobi")
43  {
44  auto creator = SolverCreator<Eigen::DiagonalPreconditioner<Scalar>>{};
45  return creator.createWithString(prefix);
46  }
47  else if (precon == "ilu")
48  {
49  auto creator = SolverCreator<Eigen::IncompleteLUT<Scalar>>{};
50  return creator.createWithString(prefix);
51  }
52  else if (precon == "ic")
53  {
54  return createIncompleteCholesky(prefix);
55  }
56  else {
57  auto creator = SolverCreator<Eigen::IdentityPreconditioner>{};
58  return creator.createWithString(prefix);
59  }
60  }
61 
62 
63  template <class Ordering>
64  using IncompleteCholesky =
65  SolverCreator<Eigen::IncompleteCholesky<Scalar, Eigen::Lower|Eigen::Upper, Ordering>>;
66 
67  std::unique_ptr<SolverBase> createIncompleteCholesky(std::string prefix) const
68  {
69  std::string ordering = "amd";
70  Parameters::get(prefix + "->precon->ordering", ordering);
71 
72  if (ordering == "amd") {
73  using AMD = Eigen::AMDOrdering<typename M::StorageIndex>;
74  return IncompleteCholesky<AMD>{}.createWithString(prefix);
75  }
76  else {
77  using NATURAL = Eigen::NaturalOrdering<typename M::StorageIndex>;
78  return IncompleteCholesky<NATURAL>{}.createWithString(prefix);
79  }
80  }
81  };
82 
84 
94  template <class Mat, class Vec>
96  {
98  using M = typename Mat::BaseMatrix;
99 
100  template <template <class> class IterativeSolver>
101  using SolverCreator
103 
104  template <template <class> class DirectSolver>
105  struct RunnerCreator
106  {
107  template <class M, class V>
109  };
110 
111  template <template <class> class DirectSolver>
112  using DirectSolverCreator
114 
116  template <class Precon>
117  using CG = Eigen::ConjugateGradient<M, Eigen::Lower|Eigen::Upper, Precon>;
118 
119  template <class Precon>
120  using BCGS = Eigen::BiCGSTAB<M, Precon>;
121 
122  template <class Precon>
123  using MINRES = Eigen::MINRES<M, Eigen::Lower|Eigen::Upper, Precon>;
124 
125  template <class Precon>
126  using GMRES = Eigen::GMRES<M, Precon>;
127 
128  template <class Precon>
129  using DGMRES = Eigen::DGMRES<M, Precon>;
130  // @}
131 
132  using Map = CreatorMap<SolverBase>;
133 
134  public:
135  static void init()
136  {
137  // conjugate gradient solver
138  auto cg = new SolverCreator<CG>;
139  Map::addCreator("cg", cg);
140 
141  // bi-conjugate gradient stabilized solver
142  auto bicgstab = new SolverCreator<BCGS>;
143  Map::addCreator("bicgstab", bicgstab);
144  Map::addCreator("bcgs", bicgstab);
145 
146  // Minimal Residual Algorithm (for symmetric matrices)
147  auto minres = new SolverCreator<MINRES>;
148  Map::addCreator("minres", minres);
149 
150  // Generalized Minimal Residual Algorithm
151  auto gmres = new SolverCreator<GMRES>;
152  Map::addCreator("gmres", gmres);
153 
154  // Restarted GMRES with deflation.
155  auto dgmres = new SolverCreator<DGMRES>;
156  Map::addCreator("dgmres", dgmres);
157 
158  // default iterative solver
159  Map::addCreator("default", gmres);
160 
161  init_direct(std::is_same<typename Dune::FieldTraits<typename M::Scalar>::real_type, double>{});
162  }
163 
164  static void init_direct(std::false_type) {}
165  static void init_direct(std::true_type)
166  {
167 #if HAVE_SUITESPARSE_UMFPACK
168  // sparse LU factorization and solver based on UmfPack
169  auto umfpack = new DirectSolverCreator<Eigen::UmfPackLU>;
170  Map::addCreator("umfpack", umfpack);
171 #endif
172 
173 #if HAVE_SUPERLU
174  // sparse direct LU factorization and solver based on the SuperLU library
175  auto superlu = new DirectSolverCreator<Eigen::SuperLU>;
176  Map::addCreator("superlu", superlu);
177 #endif
178 
179  // default direct solvers
180 #if HAVE_SUITESPARSE_UMFPACK
181  Map::addCreator("direct", umfpack);
182 #elif HAVE_SUPERLU
183  Map::addCreator("direct", superlu);
184 #endif
185  }
186  };
187 
188 } // end namespace AMDiS
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: DirectRunner.hpp:18
static std::optional< T > get(std::string const &key)
Get parameter-values from parameter-tree.
Definition: Initfile.hpp:25
Abstract base class for linear solvers.
Definition: LinearSolverInterface.hpp:27
Wrapper class for various solvers. These solvers are parametrized by MatrixType and VectorType...
Definition: LinearSolver.hpp:25
Definition: CreatorMap.hpp:16
std::unique_ptr< SolverBase > createWithString(std::string prefix) override
Must be implemented by sub classes of CreatorInterfaceName. Creates a new instance of the sub class o...
Definition: SolverCreator.hpp:35
Default solver creator for iterative solvers.
Definition: SolverCreator.hpp:24
void init(int &argc, char **&argv, std::string const &initFileName="")
Initialized the Environment for MPI.
Definition: AMDiS.hpp:29