Dune Core Modules (unstable)

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 // 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{});
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);
164 if constexpr (OperatorTraits<Operator>::isParallel){
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
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 DUNE_THROW(E,...)
Definition: exceptions.hh:314
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
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
Dune namespace
Definition: alignedallocator.hh:13
A hierarchical structure of string parameters.
Useful wrapper for creating singletons.
Define general, extensible interface for inverse operators.
@ 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 & Uni Heidelberg  |  generated with Hugo v0.111.3 (Jan 9, 23:34, 2026)