From eb38c414ab3e17b33bfc5ba685c9a5a925f4b2d0 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de> Date: Tue, 17 Mar 2020 12:15:28 +0100 Subject: [PATCH] [istlsolverfactorybackend] Introduce init-function for dumux-specific preconditioners * check matrix type, chose appropriate function (dune or dumux) * MultiTypeBlock matrix only works sequnetially so far --- dumux/linear/istlsolverfactorybackend.hh | 56 ++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/dumux/linear/istlsolverfactorybackend.hh b/dumux/linear/istlsolverfactorybackend.hh index 776ba71309..2de5db9694 100644 --- a/dumux/linear/istlsolverfactorybackend.hh +++ b/dumux/linear/istlsolverfactorybackend.hh @@ -37,16 +37,63 @@ // preconditioners #include <dune/istl/preconditioners.hh> #include <dune/istl/paamg/amg.hh> +#include "preconditioners.hh" // solvers #include <dune/istl/solvers.hh> #include <dune/istl/solverfactory.hh> +#include <dumux/common/typetraits/matrix.hh> #include <dumux/linear/solver.hh> #include <dumux/linear/parallelhelpers.hh> namespace Dumux { +// initSolverFactoriesForMultiTypeBlockMatrix differs in different compilation units, +// so we have it in an anonymous namespace +namespace { + +/*! + * \brief Initializes the direct solvers, preconditioners and iterative solvers in + * the factories with the corresponding Matrix and Vector types. + * \note We currently consider only direct solvers and preconditioners provided by + * Dumux which, unlike the ones implemented in Dune, also support MultiTypeBlockMatrices. + * \note This function could be removed once Dune::initSolverFactories supports MultiTypeBlockMatrices. + * \tparam LinearOperator the linear operator type + */ +template<class LinearOperator> +int initSolverFactoriesForMultiTypeBlockMatrix() +{ + using M = typename LinearOperator::matrix_type; + using X = typename LinearOperator::range_type; + using Y = typename LinearOperator::domain_type; + using TL = Dune::TypeList<M,X,Y>; + auto& dsfac = Dune::DirectSolverFactory<M,X,Y>::instance(); + Dune::addRegistryToFactory<TL>(dsfac, Dumux::MultiTypeBlockMatrixDirectSolverTag{}); + auto& pfac = Dune::PreconditionerFactory<LinearOperator,X,Y>::instance(); + Dune::addRegistryToFactory<TL>(pfac, Dumux::MultiTypeBlockMatrixPreconditionerTag{}); + using TLS = Dune::TypeList<X,Y>; + auto& isfac = Dune::IterativeSolverFactory<X,Y>::instance(); + return Dune::addRegistryToFactory<TLS>(isfac, Dune::IterativeSolverTag{}); +} +} // end namespace + +/*! + * \brief Initialize the solver factories for regular matrices or MultiTypeBlockMatrices + * \tparam Matrix the matrix + * \tparam LinearOperator the linear operator + * + * \note This function could be removed once Dune::initSolverFactories supports MultiTypeBlockMatrices. + */ +template<class Matrix, class LinearOperator> +void initSolverFactories() +{ + if constexpr (isMultiTypeBlockMatrix<Matrix>::value) + initSolverFactoriesForMultiTypeBlockMatrix<LinearOperator>(); + else + Dune::initSolverFactories<LinearOperator>(); +} + /*! * \ingroup Linear * \brief A linear solver using the dune-istl solver factory @@ -148,7 +195,10 @@ private: template<class Matrix, class Vector> void solveSequentialOrParallel_(Matrix& A, Vector& x, Vector& b) { - if constexpr (LinearSolverTraits::canCommunicate) + // Dune::MultiTypeBlockMatrix does not provide a ColIterator which is needed by Dune::NonoverlappingSchwarzOperator. + // We therefore can only solve these types of systems sequentially. + // TODO: This can be adapted once the situation in Dune ISTL changes. + if constexpr (LinearSolverTraits::canCommunicate && !isMultiTypeBlockMatrix<Matrix>::value) { if (isParallel_) { @@ -181,7 +231,7 @@ private: if (firstCall_) { - Dune::initSolverFactories<LinearOperator>(); + initSolverFactories<Matrix, LinearOperator>(); parallelHelper_->initGhostsAndOwners(); } @@ -207,7 +257,7 @@ private: auto linearOperator = std::make_shared<LinearOperator>(A); if (firstCall_) - Dune::initSolverFactories<LinearOperator>(); + initSolverFactories<Matrix, LinearOperator>(); // construct solver auto solver = getSolverFromFactory_(linearOperator); -- GitLab