DUNE PDELab (git)

solverfactory.hh
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
14#include <dune/common/std/type_traits.hh>
16#include <dune/common/parameterizedobject.hh>
17
18#include <dune/istl/solverregistry.hh>
19#include <dune/istl/common/registry.hh>
20#include <dune/istl/solver.hh>
21#include <dune/istl/schwarz.hh>
22#include <dune/istl/novlpschwarz.hh>
23
24namespace 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>
42 struct OperatorTraits{
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;
52 using solver_type = InverseOperator<domain_type, range_type>;
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>>
59 getAssembledOpOrThrow(std::shared_ptr<LinearOperator<domain_type, range_type>> op){
60 std::shared_ptr<AssembledLinearOperator<matrix_type, domain_type, range_type>> aop
61 = std::dynamic_pointer_cast<AssembledLinearOperator<matrix_type, domain_type, range_type>>(op);
62 if(aop)
63 return aop;
64 DUNE_THROW(NoAssembledOperator, "Failed to cast to AssembledLinearOperator. Please pass in an AssembledLinearOperator.");
65 }
66
67 static const comm_type& getCommOrThrow(std::shared_ptr<LinearOperator<domain_type, range_type>> op){
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 template<class Operator>
88 struct [[deprecated("Please change to the new solverfactory interface.")]]
89 TypeListElement<0, OperatorTraits<Operator>>{
90 using type [[deprecated]] = typename OperatorTraits<Operator>::matrix_type;
91 using Type [[deprecated]] = type;
92 };
93 template<class Operator>
94 struct [[deprecated("Please change to the new solverfactory interface.")]]
95 TypeListElement<1, OperatorTraits<Operator>>{
96 using type [[deprecated]] = typename OperatorTraits<Operator>::domain_type;
97 using Type [[deprecated]] = type;
98 };
99 template<class Operator>
100 struct [[deprecated("Please change to the new solverfactory interface.")]]
101 TypeListElement<2, OperatorTraits<Operator>>{
102 using type [[deprecated]] = typename OperatorTraits<Operator>::range_type;
103 using Type [[deprecated]] = type;
104 };
105
106 // initSolverFactories differs in different compilation units, so we have it
107 // in an anonymous namespace
108 namespace {
109
115 template<class O>
116 int initSolverFactories(){
117 using OpInfo = OperatorTraits<O>;
119 addRegistryToFactory<OpInfo>(pfac, PreconditionerTag{});
121 return addRegistryToFactory<OpInfo>(isfac, SolverTag{});
122 }
123 } // end anonymous namespace
124
148 template<class Operator>
149 std::shared_ptr<InverseOperator<typename Operator::domain_type,
150 typename Operator::range_type>>
151 getSolverFromFactory(std::shared_ptr<Operator> op, const ParameterTree& config,
153 {
154 if(prec){
155 PreconditionerFactory<Operator>::instance().define("__passed at runtime__",
156 [=](auto...){
157 return prec;
158 });
159 ParameterTree config_tmp = config;
160 config_tmp.sub("preconditioner")["type"] = std::string("__passed at runtime__");
162 create(config.get<std::string>("type"),op, config_tmp);
163 }
165 create(config.get<std::string>("type"),op, config);
166 }
167
168 class UnknownSolverCategory : public InvalidStateException{};
172 template<class Operator>
173 std::shared_ptr<Preconditioner<typename Operator::domain_type,
174 typename Operator::range_type>>
175 getPreconditionerFromFactory(std::shared_ptr<Operator> op,
176 const ParameterTree& config){
177 using Domain = typename Operator::domain_type;
178 using Range = typename Operator::range_type;
179 std::string prec_type = config.get<std::string>("type");
180 std::shared_ptr<Preconditioner<typename Operator::domain_type,
181 typename Operator::range_type>> prec = PreconditionerFactory<Operator>::instance().create(prec_type, op, config);
182 if constexpr (OperatorTraits<Operator>::isParallel){
183 using Comm = typename OperatorTraits<Operator>::comm_type;
184 const Comm& comm = OperatorTraits<Operator>::getCommOrThrow(op);
185 if(op->category() == SolverCategory::overlapping && prec->category() == SolverCategory::sequential)
186 return std::make_shared<BlockPreconditioner<Domain,Range,Comm> >(prec, comm);
187 else if(op->category() == SolverCategory::nonoverlapping && prec->category() == SolverCategory::sequential)
188 return std::make_shared<NonoverlappingBlockPreconditioner<Comm, Preconditioner<Domain, Range>> >(prec, comm);
189 }
190 return prec;
191 }
192
196} // end namespace Dune
197
198
199#endif
Nonoverlapping parallel preconditioner.
Definition: novlpschwarz.hh:276
Hierarchical structure of string parameters.
Definition: parametertree.hh:37
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: parametertree.cc:188
ParameterTree & sub(const std::string &sub)
get substructure by name
Definition: parametertree.cc:106
Base class for matrix free definition of preconditioners.
Definition: preconditioner.hh:33
static DUNE_EXPORT T & instance()
Get the instance of the singleton.
Definition: singleton.hh:70
Define general, extensible interface for inverse operators.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
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:175
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:151
Dune namespace.
Definition: alignedallocator.hh:13
A hierarchical structure of string parameters.
Useful wrapper for creating singletons.
@ sequential
Category for sequential solvers.
Definition: solvercategory.hh:25
@ nonoverlapping
Category for non-overlapping solvers.
Definition: solvercategory.hh:27
@ overlapping
Category for overlapping solvers.
Definition: solvercategory.hh:29
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 24, 23:30, 2024)