26#ifndef DUMUX_LINEAR_ISTL_SOLVERFACTORYBACKEND_HH
27#define DUMUX_LINEAR_ISTL_SOLVERFACTORYBACKEND_HH
30#include <dune/common/version.hh>
31#if DUNE_VERSION_GTE(DUNE_ISTL,2,7)
33#include <dune/common/version.hh>
34#include <dune/common/parallel/mpihelper.hh>
35#include <dune/common/parametertree.hh>
40#include <dune/istl/preconditioners.hh>
41#include <dune/istl/paamg/amg.hh>
45#include <dune/istl/solvers.hh>
46#include <dune/istl/solverfactory.hh>
66template<
class LinearOperator>
67int initSolverFactoriesForMultiTypeBlockMatrix()
69 using M =
typename LinearOperator::matrix_type;
70 using X =
typename LinearOperator::range_type;
71 using Y =
typename LinearOperator::domain_type;
72 using TL = Dune::TypeList<M,X,Y>;
73 auto& dsfac = Dune::DirectSolverFactory<M,X,Y>::instance();
74 Dune::addRegistryToFactory<TL>(dsfac, Dumux::MultiTypeBlockMatrixDirectSolverTag{});
75#if DUNE_VERSION_GT(DUNE_ISTL,2,7)
76 auto& pfac = Dune::PreconditionerFactory<LinearOperator,X,Y>::instance();
78 auto& pfac = Dune::PreconditionerFactory<M,X,Y>::instance();
80 Dune::addRegistryToFactory<TL>(pfac, Dumux::MultiTypeBlockMatrixPreconditionerTag{});
81 using TLS = Dune::TypeList<X,Y>;
82 auto& isfac = Dune::IterativeSolverFactory<X,Y>::instance();
83 return Dune::addRegistryToFactory<TLS>(isfac, Dune::IterativeSolverTag{});
94template<
class Matrix,
class LinearOperator>
95void initSolverFactories()
97 if constexpr (isMultiTypeBlockMatrix<Matrix>::value)
98 initSolverFactoriesForMultiTypeBlockMatrix<LinearOperator>();
100#if DUNE_VERSION_GT(DUNE_ISTL,2,7)
101 Dune::initSolverFactories<LinearOperator>();
104 using X =
typename LinearOperator::range_type;
105 using Y =
typename LinearOperator::domain_type;
106 Dune::initSolverFactories<Matrix, X, Y>();
118template <
class LinearSolverTraits>
119class IstlSolverFactoryBackend :
public LinearSolver
128 IstlSolverFactoryBackend(
const std::string& paramGroup =
"")
129 : paramGroup_(paramGroup)
130 , isParallel_(
Dune::MPIHelper::getCollectiveCommunication().size() > 1)
133 DUNE_THROW(Dune::InvalidStateException,
"Using sequential constructor for parallel run. Use signature with gridView and dofMapper!");
145 IstlSolverFactoryBackend(
const typename LinearSolverTraits::GridView& gridView,
146 const typename LinearSolverTraits::DofMapper& dofMapper,
147 const std::string& paramGroup =
"")
148 : paramGroup_(paramGroup)
150 , parallelHelper_(std::make_unique<ParallelISTLHelper<
LinearSolverTraits>>(gridView, dofMapper))
151 , isParallel_(
Dune::MPIHelper::getCollectiveCommunication().size() > 1)
164 template<
class Matrix,
class Vector>
165 bool solve(Matrix& A, Vector& x, Vector& b)
168 solveSequentialOrParallel_(A, x, b);
170 solveSequential_(A, x, b);
173 return result_.converged;
181 checkMandatoryParameters_();
182 name_ = params_.get<std::string>(
"preconditioner.type") +
"-preconditioned " + params_.get<std::string>(
"type");
183 if (params_.get<
int>(
"verbose", 0) > 0)
184 std::cout <<
"Initialized linear solver of type: " << name_ << std::endl;
187 const Dune::InverseOperatorResult& result()
const
192 const std::string& name()
const
199 void checkMandatoryParameters_()
201 if (!params_.hasKey(
"type"))
202 DUNE_THROW(Dune::InvalidStateException,
"Solver factory needs \"LinearSolver.Type\" parameter to select the solver");
204 if (!params_.hasKey(
"preconditioner.type"))
205 DUNE_THROW(Dune::InvalidStateException,
"Solver factory needs \"LinearSolver.Preconditioner.Type\" parameter to select the preconditioner");
209 template<
class Matrix,
class Vector>
210 void solveSequentialOrParallel_(Matrix& A, Vector& x, Vector& b)
215 if constexpr (LinearSolverTraits::canCommunicate && !isMultiTypeBlockMatrix<Matrix>::value)
219 if (LinearSolverTraits::isNonOverlapping(parallelHelper_->gridView()))
221 using PTraits =
typename LinearSolverTraits::template ParallelNonoverlapping<Matrix, Vector>;
222 solveParallel_<PTraits>(A, x, b);
226 using PTraits =
typename LinearSolverTraits::template ParallelOverlapping<Matrix, Vector>;
227 solveParallel_<PTraits>(A, x, b);
231 solveSequential_(A, x, b);
235 solveSequential_(A, x, b);
239 template<
class ParallelTraits,
class Matrix,
class Vector>
240 void solveParallel_(Matrix& A, Vector& x, Vector& b)
242#if DUNE_VERSION_GT_REV(DUNE_ISTL,2,7,0)
243 using Comm =
typename ParallelTraits::Comm;
244 using LinearOperator =
typename ParallelTraits::LinearOperator;
245 using ScalarProduct =
typename ParallelTraits::ScalarProduct;
249 initSolverFactories<Matrix, LinearOperator>();
250 parallelHelper_->initGhostsAndOwners();
253 std::shared_ptr<Comm> comm;
254 std::shared_ptr<LinearOperator> linearOperator;
255 std::shared_ptr<ScalarProduct> scalarProduct;
256 prepareLinearAlgebraParallel<LinearSolverTraits, ParallelTraits>(A, b, comm, linearOperator, scalarProduct, *parallelHelper_);
259 auto solver = getSolverFromFactory_(linearOperator);
262 solver->apply(x, b, result_);
264 DUNE_THROW(Dune::NotImplemented,
"Parallel solvers only available for dune-istl > 2.7.0");
269 template<
class Matrix,
class Vector>
270 void solveSequential_(Matrix& A, Vector& x, Vector& b)
273 using Traits =
typename LinearSolverTraits::template Sequential<Matrix, Vector>;
274 using LinearOperator =
typename Traits::LinearOperator;
275 auto linearOperator = std::make_shared<LinearOperator>(A);
278 initSolverFactories<Matrix, LinearOperator>();
281 auto solver = getSolverFromFactory_(linearOperator);
284 solver->apply(x, b, result_);
287 template<
class LinearOperator>
288 auto getSolverFromFactory_(std::shared_ptr<LinearOperator>& fop)
290 try {
return Dune::getSolverFromFactory(fop, params_); }
291 catch(Dune::Exception& e)
293 std::cerr <<
"Could not create solver with factory" << std::endl;
294 std::cerr << e.what() << std::endl;
299 const std::string paramGroup_;
301 std::unique_ptr<ParallelISTLHelper<LinearSolverTraits>> parallelHelper_;
303 bool isParallel_ =
false;
306 Dune::InverseOperatorResult result_;
307 Dune::ParameterTree params_;
314#warning "Generic dune-istl solver factory backend needs dune-istl >= 2.7!"
Type traits to be used with matrix types.
Generates a parameter tree required for the linear solvers and precondioners of the Dune ISTL.
Provides a helper class for nonoverlapping decomposition.
Dumux preconditioners for iterative solvers.
Base class for linear solvers.
LinearSolverTraitsImpl< GridGeometry, GridGeometry::discMethod > LinearSolverTraits
The type traits required for using the IstlFactoryBackend.
Definition: linearsolvertraits.hh:72
Definition: common/pdesolver.hh:35
static Dune::ParameterTree createParameterTree(const std::string ¶mGroup="")
Create a tree containing parameters required for the linear solvers and precondioners of the Dune IST...
Definition: linearsolverparameters.hh:46