AMDiS  2.10
The Adaptive Multi-Dimensional Simulation Toolbox
Solvers.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/LinearSolverInterface.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 M, class X, class Y, template <class> class IterativeSolver>
25  : public CreatorInterfaceName<LinearSolverInterface<M,X,Y>>
26  {
28  using T = typename M::Scalar;
29 
30  template <class Precon>
32 
33  template <class Ordering>
34  using IncompleteCholesky =
36 
37  std::unique_ptr<SolverBase> createWithString(std::string prefix) override
38  {
39  // get creator string for preconditioner
40  std::string precon = "no";
41  Parameters::get(prefix + "->precon->name", precon);
42 
43  if (precon == "diag" || precon == "jacobi") {
44  return std::make_unique<Solver<Eigen::DiagonalPreconditioner<T>>>(prefix);
45  }
46  else if (precon == "ilu") {
47  return std::make_unique<Solver<Eigen::IncompleteLUT<T>>>(prefix);
48  }
49  else if (precon == "ic") {
50  std::string ordering = "amd";
51  Parameters::get(prefix + "->precon->ordering", ordering);
52 
53  if (ordering == "amd") {
54  using AMD = Eigen::AMDOrdering<typename M::StorageIndex>;
55  return std::make_unique<IncompleteCholesky<AMD>>(prefix);
56  }
57  else {
58  using NATURAL = Eigen::NaturalOrdering<typename M::StorageIndex>;
59  return std::make_unique<IncompleteCholesky<NATURAL>>(prefix);
60  }
61  }
62  else {
63  return std::make_unique<Solver<Eigen::IdentityPreconditioner>>(prefix);
64  }
65  }
66  };
67 
69 
79  template <class M, class X, class Y>
81  {
82  template <template <class> class IterativeSolver>
83  using SolverCreator
85 
86  template <template <class> class DirectSolver>
87  using DirectSolverCreator
89 
91  template <class Precon>
92  using CG = Eigen::ConjugateGradient<M, Eigen::Lower|Eigen::Upper, Precon>;
93 
94  template <class Precon>
95  using BCGS = Eigen::BiCGSTAB<M, Precon>;
96 
97  template <class Precon>
98  using MINRES = Eigen::MINRES<M, Eigen::Lower|Eigen::Upper, Precon>;
99 
100  template <class Precon>
101  using GMRES = Eigen::GMRES<M, Precon>;
102 
103  template <class Precon>
104  using DGMRES = Eigen::DGMRES<M, Precon>;
105  // @}
106 
108  using Map = CreatorMap<SolverBase>;
109 
110  public:
111  static void init()
112  {
113  // conjugate gradient solver
114  auto cg = new SolverCreator<CG>;
115  Map::addCreator("cg", cg);
116 
117  // bi-conjugate gradient stabilized solver
118  auto bicgstab = new SolverCreator<BCGS>;
119  Map::addCreator("bicgstab", bicgstab);
120  Map::addCreator("bcgs", bicgstab);
121 
122  // Minimal Residual Algorithm (for symmetric matrices)
123  auto minres = new SolverCreator<MINRES>;
124  Map::addCreator("minres", minres);
125 
126  // Generalized Minimal Residual Algorithm
127  auto gmres = new SolverCreator<GMRES>;
128  Map::addCreator("gmres", gmres);
129 
130  // Restarted GMRES with deflation.
131  auto dgmres = new SolverCreator<DGMRES>;
132  Map::addCreator("dgmres", dgmres);
133 
134  // default iterative solver
135  Map::addCreator("default", gmres);
136 
137  init_direct(std::is_same<typename Dune::FieldTraits<typename M::Scalar>::real_type, double>{});
138  }
139 
140  static void init_direct(std::false_type) {}
141  static void init_direct(std::true_type)
142  {
143 #if HAVE_SUITESPARSE_UMFPACK
144  // sparse LU factorization and solver based on UmfPack
145  auto umfpack = new DirectSolverCreator<Eigen::UmfPackLU>;
146  Map::addCreator("umfpack", umfpack);
147 #endif
148 
149 #if HAVE_SUPERLU
150  // sparse direct LU factorization and solver based on the SuperLU library
151  auto superlu = new DirectSolverCreator<Eigen::SuperLU>;
152  Map::addCreator("superlu", superlu);
153 #endif
154 
155  // default direct solvers
156 #if HAVE_SUITESPARSE_UMFPACK
157  Map::addCreator("direct", umfpack);
158 #elif HAVE_SUPERLU
159  Map::addCreator("direct", superlu);
160 #endif
161  }
162  };
163 
164 } // end namespace AMDiS
Definition: DirectRunner.hpp:26
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
Definition: AdaptBase.hpp:6
static std::optional< T > get(std::string const &key)
Get parameter-values from parameter-tree.
Definition: Initfile.hpp:25
Definition: IterativeRunner.hpp:14
Definition: LinearSolverInterface.hpp:8
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: Solvers.hpp:37
Default solver creator for iterative solvers.
Definition: Solvers.hpp:24
void init(std::string const &prefix) override
Prepare the solver for the creation.
Definition: ISTLSolverCreator.hpp:96