dune-istl 2.12-git
Loading...
Searching...
No Matches
solverregistry.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_SOLVERREGISTRY_HH
7#define DUNE_ISTL_SOLVERREGISTRY_HH
8
12#include <dune/istl/solver.hh>
13
14#define DUNE_REGISTER_PRECONDITIONER(name, ...) \
15 DUNE_REGISTRY_PUT(PreconditionerTag, name, __VA_ARGS__)
16
17#define DUNE_REGISTER_SOLVER(name, ...) \
18 DUNE_REGISTRY_PUT(SolverTag, name, __VA_ARGS__)
19
20namespace Dune{
21
26 namespace {
27 struct PreconditionerTag {};
28 struct SolverTag {};
29 }
30
33
34 /* This exception is thrown, when the requested solver is in the factory but
35 cannot be instantiated for the required template parameters
36 */
38
39 namespace Impl {
40 /* The sequential relaxation preconditioners registered via
41 defaultPreconditionerBlockLevelCreator (ssor, sor, gs, jac, dilu, ilu)
42 and defaultPreconditionerCreator (ildl) operate by iterating over the
43 rows and columns of the matrix. Registered creators are instantiated
44 for every operator type passed to initSolverFactories(), whether or not
45 the preconditioner is ever selected, so they must not hard-error for
46 matrix types that do not provide this interface (e.g. GPU-resident
47 matrices). This concept detects the required interface; creators use it
48 to throw UnsupportedType at runtime instead.
49 */
50 template<class M>
51 concept RowIterableMatrix = requires(const M& m)
52 {
53 typename M::ConstRowIterator;
54 typename M::ConstColIterator;
55 { m.begin().index() }; // row iterators provide their row index
56 { (*m.begin()).begin().index() }; // column iterators provide their column index
57 };
58 } // namespace Impl
59
60 template<template<class,class,class,int>class Preconditioner, int blockLevel=1>
62 return [](auto opInfo, const auto& linearOperator, const Dune::ParameterTree& config)
63 {
64 using OpInfo = std::decay_t<decltype(opInfo)>;
65 using Matrix = typename OpInfo::matrix_type;
66 using Domain = typename OpInfo::domain_type;
67 using Range = typename OpInfo::range_type;
69 if constexpr (!OpInfo::isAssembled){
70 DUNE_THROW(NoAssembledOperator, "Could not obtain matrix from operator. Please pass in an AssembledLinearOperator.");
71 } else if constexpr (!Impl::RowIterableMatrix<Matrix>) {
73 "This preconditioner iterates over the matrix rows and columns, "
74 "which is not supported by " << className<Matrix>() << ".");
75 } else {
76 const auto& A = opInfo.getAssembledOpOrThrow(linearOperator);
77 // const Matrix& matrix = A->getmat();
78 preconditioner
79 = std::make_shared<Preconditioner<Matrix, Domain, Range, blockLevel>>(A, config);
80 }
81 return preconditioner;
82 };
83 }
84
85 template<template<class,class,class>class Preconditioner>
87 return [](auto opInfo, const auto& linearOperator, const Dune::ParameterTree& config)
88 {
89 using OpInfo = std::decay_t<decltype(opInfo)>;
90 using Matrix = typename OpInfo::matrix_type;
91 using Domain = typename OpInfo::domain_type;
92 using Range = typename OpInfo::range_type;
94 if constexpr (!OpInfo::isAssembled){
95 DUNE_THROW(NoAssembledOperator, "Could not obtain matrix from operator. Please pass in an AssembledLinearOperator.");
96 } else if constexpr (!Impl::RowIterableMatrix<Matrix>) {
98 "This preconditioner iterates over the matrix rows and columns, "
99 "which is not supported by " << className<Matrix>() << ".");
100 } else {
101 const auto& A = opInfo.getAssembledOpOrThrow(linearOperator);
102 // const Matrix& matrix = A->getmat();
103 preconditioner
104 = std::make_shared<Preconditioner<Matrix, Domain, Range>>(A, config);
105 }
106 return preconditioner;
107 };
108 }
109
110 template<template<class...>class Solver>
112 return [](auto opInfo,
113 const auto& linearOperator,
114 const Dune::ParameterTree& config)
115 {
116 using OpInfo = std::decay_t<decltype(opInfo)>;
117 using Operator = typename OpInfo::operator_type;
118 using Domain = typename OpInfo::domain_type;
119 using Range = typename OpInfo::range_type;
120 std::shared_ptr<Operator> _op = std::dynamic_pointer_cast<Operator>(linearOperator);
121 std::shared_ptr<Preconditioner<Domain,Range>> preconditioner = getPreconditionerFromFactory(_op, config.sub("preconditioner"));
122 std::shared_ptr<ScalarProduct<Range>> scalarProduct = opInfo.getScalarProduct(linearOperator);
124 = std::make_shared<Solver<Domain>>(linearOperator, scalarProduct, preconditioner, config);
125 return solver;
126 };
127 }
128
130} // end namespace Dune
131
132#endif // DUNE_ISTL_SOLVERREGISTRY_HH
Define general, extensible interface for inverse operators.
auto defaultIterativeSolverCreator()
Definition solverregistry.hh:111
auto defaultPreconditionerBlockLevelCreator()
Definition solverregistry.hh:61
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
auto defaultPreconditionerCreator()
Definition solverregistry.hh:86
iterator begin()
static constexpr size_type M()
#define DUNE_THROW(E,...)
constexpr std::size_t blockLevel()
Determine the block level of a possibly nested vector/matrix type.
Definition blocklevel.hh:176
A generic dynamic dense matrix.
Definition matrix.hh:561
This exception is thrown if the requested solver or preconditioner needs an assembled matrix.
Definition solverregistry.hh:32
Definition solverregistry.hh:37
Definition solverregistry.hh:129