dune-istl  2.11
solverfactory.hh
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4 // vi: set et ts=4 sw=2 sts=2:
5 
6 #ifndef DUNE_ISTL_SOLVERFACTORY_HH
7 #define DUNE_ISTL_SOLVERFACTORY_HH
8 
9 #include <unordered_map>
10 #include <functional>
11 #include <memory>
12 
13 #include <dune/common/parametertree.hh>
14 #include <dune/common/std/type_traits.hh>
15 #include <dune/common/singleton.hh>
16 #include <dune/common/parameterizedobject.hh>
17 
20 #include <dune/istl/solver.hh>
21 #include <dune/istl/schwarz.hh>
23 
24 namespace Dune{
29  // Preconditioner factory:
30  template<class OP>
31  using PreconditionerSignature = std::shared_ptr<Preconditioner<typename OP::domain_type,typename OP::range_type>>(const std::shared_ptr<OP>&, const ParameterTree&);
32  template<class OP>
33  using PreconditionerFactory = Singleton<ParameterizedObjectFactory<PreconditionerSignature<OP>>>;
34 
35  // Iterative solver factory
36  template<class OP>
37  using SolverSignature = std::shared_ptr<InverseOperator<typename OP::domain_type,typename OP::range_type>>(const std::shared_ptr<OP>&, const ParameterTree&);
38  template<class OP>
39  using SolverFactory = Singleton<ParameterizedObjectFactory<SolverSignature<OP>>>;
40 
41  template<class Operator>
43  private:
44  template<class O>
45  using _matrix_type = typename O::matrix_type;
46  template<class O>
47  using _comm_type = typename O::communication_type;
48  public:
49  using domain_type = typename Operator::domain_type;
50  using range_type = typename Operator::range_type;
51  using operator_type = Operator;
53  using matrix_type = Std::detected_or_t<int, _matrix_type, Operator>;
54  static constexpr bool isAssembled = !std::is_same<matrix_type, int>::value;
55  using comm_type = Std::detected_or_t<int, _comm_type, Operator>;
56  static constexpr bool isParallel = !std::is_same<comm_type, int>::value;
57 
58  static const std::shared_ptr<AssembledLinearOperator<matrix_type, domain_type, range_type>>
60  std::shared_ptr<AssembledLinearOperator<matrix_type, domain_type, range_type>> aop
62  if(aop)
63  return aop;
64  DUNE_THROW(NoAssembledOperator, "Failed to cast to AssembledLinearOperator. Please pass in an AssembledLinearOperator.");
65  }
66 
68  std::shared_ptr<Operator> _op
69  = std::dynamic_pointer_cast<Operator>(op);
70  if constexpr (isParallel){
71  return _op->getCommunication();
72  }else{
73  DUNE_THROW(NoAssembledOperator, "Could not obtain communication object from operator. Please pass in a parallel operator.");
74  }
75  }
76 
77  static std::shared_ptr<ScalarProduct<domain_type>> getScalarProduct(std::shared_ptr<LinearOperator<domain_type, range_type>> op)
78  {
79  if constexpr (isParallel){
80  return createScalarProduct<domain_type>(getCommOrThrow(op), op->category());
81  }else{
82  return std::make_shared<SeqScalarProduct<domain_type>>();
83  }
84  }
85  };
86 
87  // initSolverFactories differs in different compilation units, so we have it
88  // in an anonymous namespace
89  namespace {
90 
96  template<class O>
97  int initSolverFactories(){
98  using OpInfo = OperatorTraits<O>;
100  addRegistryToFactory<OpInfo>(pfac, PreconditionerTag{});
101  auto& isfac=Dune::SolverFactory<O>::instance();
102  return addRegistryToFactory<OpInfo>(isfac, SolverTag{});
103  }
104  } // end anonymous namespace
105 
130  template<class Operator>
131  std::shared_ptr<InverseOperator<typename Operator::domain_type,
132  typename Operator::range_type>>
133  getSolverFromFactory(std::shared_ptr<Operator> op, const ParameterTree& config,
135  {
136  if(prec){
137  PreconditionerFactory<Operator>::instance().define("__passed at runtime__",
138  [=](auto...){
139  return prec;
140  });
141  ParameterTree config_tmp = config;
142  config_tmp.sub("preconditioner")["type"] = std::string("__passed at runtime__");
144  create(config.get<std::string>("type"),op, config_tmp);
145  }
147  create(config.get<std::string>("type"),op, config);
148  }
149 
150  class UnknownSolverCategory : public InvalidStateException{};
154  template<class Operator>
155  std::shared_ptr<Preconditioner<typename Operator::domain_type,
156  typename Operator::range_type>>
157  getPreconditionerFromFactory(std::shared_ptr<Operator> op,
158  const ParameterTree& config){
159  using Domain = typename Operator::domain_type;
160  using Range = typename Operator::range_type;
161  std::string prec_type = config.get<std::string>("type");
162  std::shared_ptr<Preconditioner<typename Operator::domain_type,
163  typename Operator::range_type>> prec = PreconditionerFactory<Operator>::instance().create(prec_type, op, config);
165  using Comm = typename OperatorTraits<Operator>::comm_type;
166  const Comm& comm = OperatorTraits<Operator>::getCommOrThrow(op);
167  if(op->category() == SolverCategory::overlapping && prec->category() == SolverCategory::sequential)
168  return std::make_shared<BlockPreconditioner<Domain,Range,Comm> >(prec, comm);
169  else if(op->category() == SolverCategory::nonoverlapping && prec->category() == SolverCategory::sequential)
170  return std::make_shared<NonoverlappingBlockPreconditioner<Comm, Preconditioner<Domain, Range>> >(prec, comm);
171  }
172  return prec;
173  }
174 
178 } // end namespace Dune
179 
180 
181 #endif
A linear operator.
Definition: operators.hh:68
std::shared_ptr< InverseOperator< typename OP::domain_type, typename OP::range_type > >(const std::shared_ptr< OP > &, const ParameterTree &) SolverSignature
Definition: solverfactory.hh:37
Definition: solverfactory.hh:42
std::shared_ptr< Preconditioner< typename Operator::domain_type, typename Operator::range_type > > getPreconditionerFromFactory(std::shared_ptr< Operator > op, const ParameterTree &config)
Construct a Preconditioner for a given Operator.
Definition: solverfactory.hh:157
Base class for matrix free definition of preconditioners.
Definition: preconditioner.hh:33
Category for sequential solvers.
Definition: solvercategory.hh:25
typename Operator::range_type range_type
Definition: solverfactory.hh:50
static const std::shared_ptr< AssembledLinearOperator< matrix_type, domain_type, range_type > > getAssembledOpOrThrow(std::shared_ptr< LinearOperator< domain_type, range_type >> op)
Definition: solverfactory.hh:59
static constexpr bool isAssembled
Definition: solverfactory.hh:54
typename Operator::domain_type domain_type
Definition: solverfactory.hh:49
static const comm_type & getCommOrThrow(std::shared_ptr< LinearOperator< domain_type, range_type >> op)
Definition: solverfactory.hh:67
Block parallel preconditioner.
Definition: schwarz.hh:278
static std::shared_ptr< ScalarProduct< domain_type > > getScalarProduct(std::shared_ptr< LinearOperator< domain_type, range_type >> op)
Definition: solverfactory.hh:77
Operator operator_type
Definition: solverfactory.hh:51
std::shared_ptr< InverseOperator< typename Operator::domain_type, typename Operator::range_type > > getSolverFromFactory(std::shared_ptr< Operator > op, const ParameterTree &config, std::shared_ptr< Preconditioner< typename Operator::domain_type, typename Operator::range_type >> prec=nullptr)
Instantiates an InverseOperator from an Operator and a configuration given as a ParameterTree.
Definition: solverfactory.hh:133
Nonoverlapping parallel preconditioner.
Definition: novlpschwarz.hh:275
std::shared_ptr< Preconditioner< typename OP::domain_type, typename OP::range_type > >(const std::shared_ptr< OP > &, const ParameterTree &) PreconditionerSignature
Definition: solverfactory.hh:31
Std::detected_or_t< int, _matrix_type, Operator > matrix_type
Definition: solverfactory.hh:53
Category for overlapping solvers.
Definition: solvercategory.hh:29
Singleton< ParameterizedObjectFactory< SolverSignature< OP > >> SolverFactory
Definition: solverfactory.hh:39
static constexpr bool isParallel
Definition: solverfactory.hh:56
This exception is thrown if the requested solver or preconditioner needs an assembled matrix...
Definition: solverregistry.hh:31
Std::detected_or_t< int, _comm_type, Operator > comm_type
Definition: solverfactory.hh:55
Definition: allocator.hh:11
A linear operator exporting itself in matrix form.
Definition: operators.hh:110
Singleton< ParameterizedObjectFactory< PreconditionerSignature< OP > >> PreconditionerFactory
Definition: solverfactory.hh:33
Abstract base class for all solvers.
Definition: solver.hh:101
Define general, extensible interface for inverse operators.
Category for non-overlapping solvers.
Definition: solvercategory.hh:27
Definition: solverfactory.hh:150