4 #ifndef DUNE_ISTL_SOLVERFACTORY_HH
5 #define DUNE_ISTL_SOLVERFACTORY_HH
7 #include <unordered_map>
11 #include <dune/common/parametertree.hh>
12 #include <dune/common/singleton.hh>
17 #define DUNE_REGISTER_DIRECT_SOLVER(name, ...) \
18 registry_put(DirectSolverTag, name, __VA_ARGS__)
20 #define DUNE_REGISTER_PRECONDITIONER(name, ...) \
21 registry_put(PreconditionerTag, name, __VA_ARGS__)
23 #define DUNE_REGISTER_ITERATIVE_SOLVER(name, ...) \
24 registry_put(IterativeSolverTag, name, __VA_ARGS__)
32 struct DirectSolverTag {};
33 struct PreconditionerTag {};
34 struct IterativeSolverTag {};
37 template<
template<
class,
class,
class,
int>
class Preconditioner,
int l=1>
39 return [](
auto tl,
const auto&
mat,
const Dune::ParameterTree& config)
41 using M =
typename Dune::TypeListElement<0, decltype(tl)>::type;
42 using D =
typename Dune::TypeListElement<1, decltype(tl)>::type;
43 using R =
typename Dune::TypeListElement<2, decltype(tl)>::type;
44 std::shared_ptr<Dune::Preconditioner<D,R>> prec
45 = std::make_shared<Preconditioner<M,D,R,l>>(
mat,config);
50 template<
template<
class,
class,
class>
class Preconditioner>
52 return [](
auto tl,
const auto&
mat,
const Dune::ParameterTree& config)
54 using M =
typename Dune::TypeListElement<0, decltype(tl)>::type;
55 using D =
typename Dune::TypeListElement<1, decltype(tl)>::type;
56 using R =
typename Dune::TypeListElement<2, decltype(tl)>::type;
57 std::shared_ptr<Dune::Preconditioner<D,R>> prec
58 = std::make_shared<Preconditioner<M,D,R>>(
mat,config);
63 template<
template<
class...>
class Solver>
69 const Dune::ParameterTree& config)
71 using D =
typename Dune::TypeListElement<0, decltype(tl)>::type;
72 using R =
typename Dune::TypeListElement<1, decltype(tl)>::type;
73 std::shared_ptr<Dune::InverseOperator<D,R>> solver
74 = std::make_shared<Solver<D>>(op, sp, prec,config);
80 template<
class M,
class X,
class Y>
82 template<
class M,
class X,
class Y>
86 template<
class M,
class X,
class Y>
88 template<
class M,
class X,
class Y>
92 template<
class X,
class Y>
93 using IterativeSolverSignature = std::shared_ptr<InverseOperator<X,Y>>(
const std::shared_ptr<LinearOperator<X,Y>>&,
const std::shared_ptr<ScalarProduct<X>>&,
const std::shared_ptr<Preconditioner<X,Y>>,
const ParameterTree&);
94 template<
class X,
class Y>
108 template<
class M,
class X,
class Y>
109 int initSolverFactories(){
110 using TL = Dune::TypeList<M,X,Y>;
112 addRegistryToFactory<TL>(dsfac, DirectSolverTag{});
114 addRegistryToFactory<TL>(pfac, PreconditionerTag{});
115 using TLS = Dune::TypeList<X,Y>;
117 return addRegistryToFactory<TLS>(isfac, IterativeSolverTag{});
145 template<
class Operator>
147 using Domain =
typename Operator::domain_type;
148 using Range =
typename Operator::range_type;
153 using _matrix_type =
typename O::matrix_type;
154 using matrix_type = Std::detected_or_t<int, _matrix_type, Operator>;
155 static constexpr
bool isAssembled = !std::is_same<matrix_type, int>::value;
157 static const matrix_type* getmat(std::shared_ptr<Operator> op){
158 std::shared_ptr<AssembledLinearOperator<matrix_type, Domain, Range>> aop
159 = std::dynamic_pointer_cast<AssembledLinearOperator<matrix_type, Domain, Range>>(op);
161 return &aop->getmat();
168 static std::shared_ptr<Solver>
get(std::shared_ptr<Operator> op,
169 const ParameterTree& config,
170 std::shared_ptr<Preconditioner> prec =
nullptr){
171 std::string type = config.get<std::string>(
"type");
172 std::shared_ptr<Solver> result;
173 const matrix_type*
mat = getmat(op);
182 DUNE_THROW(Dune::InvalidStateException,
"Solver can not be found in the factory");
185 const ParameterTree& precConfig = config.sub(
"preconditioner");
186 std::string prec_type = precConfig.get<std::string>(
"type");
190 DUNE_THROW(NotImplemented,
"The solver factory is only implemented for sequential solvers yet!");
192 std::shared_ptr<ScalarProduct<Domain>> sp = std::make_shared<SeqScalarProduct<Domain>>();
201 const ParameterTree& config){
202 const matrix_type*
mat = getmat(op);
204 std::string prec_type = config.get<std::string>(
"type");
207 DUNE_THROW(InvalidStateException,
"Cant deduce matrix from Operator. Please pass in an AssembledLinearOperator.");
222 template<
class Operator>
223 std::shared_ptr<InverseOperator<
typename Operator::domain_type,
225 const ParameterTree& config,
227 typename Operator::range_type>> prec =
nullptr){