14#ifndef DUMUX_LINEAR_ISTL_SOLVERFACTORYBACKEND_HH
15#define DUMUX_LINEAR_ISTL_SOLVERFACTORYBACKEND_HH
19#include <dune/common/parallel/mpihelper.hh>
20#include <dune/common/parametertree.hh>
25#include <dune/istl/preconditioners.hh>
26#include <dune/istl/paamg/amg.hh>
30#include <dune/istl/solvers.hh>
31#include <dune/istl/solverfactory.hh>
54template<
class LinearOperator>
55int initSolverFactoriesForMultiTypeBlockMatrix()
57 using M =
typename LinearOperator::matrix_type;
58 using X =
typename LinearOperator::range_type;
59 using Y =
typename LinearOperator::domain_type;
60 using TL = Dune::TypeList<M,X,Y>;
61 auto& dsfac = Dune::DirectSolverFactory<M,X,Y>::instance();
62 Dune::addRegistryToFactory<TL>(dsfac, Dumux::MultiTypeBlockMatrixDirectSolverTag{});
63 auto& pfac = Dune::PreconditionerFactory<LinearOperator,X,Y>::instance();
64 Dune::addRegistryToFactory<TL>(pfac, Dumux::MultiTypeBlockMatrixPreconditionerTag{});
65 using TLS = Dune::TypeList<X,Y>;
66 auto& isfac = Dune::IterativeSolverFactory<X,Y>::instance();
67 return Dune::addRegistryToFactory<TLS>(isfac, Dune::IterativeSolverTag{});
78template<
class Matrix,
class LinearOperator>
82 initSolverFactoriesForMultiTypeBlockMatrix<LinearOperator>();
84 Dune::initSolverFactories<LinearOperator>();
95template <
class LinearSolverTraits>
105 [[deprecated(
"Use new IstlSolverFactoryBackend<LinearSolverTraits, LinearAlgebraTraits> with 2nd template parameter. Will be removed after 3.7.")]]
108 , isParallel_(
Dune::MPIHelper::getCommunication().size() > 1)
111 DUNE_THROW(Dune::InvalidStateException,
"Using sequential constructor for parallel run. Use signature with gridView and dofMapper!");
114 initializeParameters_();
124 [[deprecated(
"Use new IstlSolverFactoryBackend<LinearSolverTraits, LinearAlgebraTraits> with 2nd template parameter. Will be removed after 3.7.")]]
126 const typename LinearSolverTraits::DofMapper& dofMapper,
130 , isParallel_(
Dune::MPIHelper::getCommunication().size() > 1)
134 initializeParameters_();
137 parallelHelper_ = std::make_unique<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
148 const typename LinearSolverTraits::DofMapper& dofMapper)
152 parallelHelper_ = std::make_unique<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
163 template<
class Matrix,
class Vector>
164 bool solve(Matrix& A, Vector& x, Vector& b)
167 solveSequentialOrParallel_(A, x, b);
169 solveSequential_(A, x, b);
172 return result_.converged;
175 const Dune::InverseOperatorResult&
result()
const
180 const std::string&
name()
const
187 void initializeParameters_()
190 checkMandatoryParameters_();
191 name_ = params_.get<std::string>(
"preconditioner.type") +
"-preconditioned " + params_.get<std::string>(
"type");
192 if (params_.get<
int>(
"verbose", 0) > 0)
193 std::cout <<
"Initialized linear solver of type: " << name_ << std::endl;
196 void checkMandatoryParameters_()
198 if (!params_.hasKey(
"type"))
199 DUNE_THROW(Dune::InvalidStateException,
"Solver factory needs \"LinearSolver.Type\" parameter to select the solver");
201 if (!params_.hasKey(
"preconditioner.type"))
202 DUNE_THROW(Dune::InvalidStateException,
"Solver factory needs \"LinearSolver.Preconditioner.Type\" parameter to select the preconditioner");
206 template<
class Matrix,
class Vector>
207 void solveSequentialOrParallel_(Matrix& A, Vector& x, Vector& b)
216 if (LinearSolverTraits::isNonOverlapping(parallelHelper_->gridView()))
218 using PTraits =
typename LinearSolverTraits::template ParallelNonoverlapping<Matrix, Vector>;
219 solveParallel_<PTraits>(A, x, b);
223 using PTraits =
typename LinearSolverTraits::template ParallelOverlapping<Matrix, Vector>;
224 solveParallel_<PTraits>(A, x, b);
228 solveSequential_(A, x, b);
232 solveSequential_(A, x, b);
236 template<
class ParallelTraits,
class Matrix,
class Vector>
237 void solveParallel_(Matrix& A, Vector& x, Vector& b)
239 using Comm =
typename ParallelTraits::Comm;
240 using LinearOperator =
typename ParallelTraits::LinearOperator;
241 using ScalarProduct =
typename ParallelTraits::ScalarProduct;
244 initSolverFactories<Matrix, LinearOperator>();
246 std::shared_ptr<Comm> comm;
247 std::shared_ptr<LinearOperator> linearOperator;
248 std::shared_ptr<ScalarProduct> scalarProduct;
249 prepareLinearAlgebraParallel<LinearSolverTraits, ParallelTraits>(A, b, comm, linearOperator, scalarProduct, *parallelHelper_);
252 auto solver = getSolverFromFactory_(linearOperator);
255 solver->apply(x, b, result_);
259 template<
class Matrix,
class Vector>
260 void solveSequential_(Matrix& A, Vector& x, Vector& b)
263 using Traits =
typename LinearSolverTraits::template Sequential<Matrix, Vector>;
264 using LinearOperator =
typename Traits::LinearOperator;
265 auto linearOperator = std::make_shared<LinearOperator>(A);
268 initSolverFactories<Matrix, LinearOperator>();
271 auto solver = getSolverFromFactory_(linearOperator);
274 solver->apply(x, b, result_);
277 template<
class LinearOperator>
278 auto getSolverFromFactory_(std::shared_ptr<LinearOperator>& fop)
280 try {
return Dune::getSolverFromFactory(fop, params_); }
281 catch(Dune::Exception& e)
283 std::cerr <<
"Could not create solver with factory" << std::endl;
284 std::cerr << e.what() << std::endl;
289 const std::string paramGroup_;
291 std::unique_ptr<ParallelISTLHelper<LinearSolverTraits>> parallelHelper_;
293 bool isParallel_ =
false;
296 Dune::InverseOperatorResult result_;
297 Dune::ParameterTree params_;
301template <
class LinearSolverTraits,
class LinearAlgebraTraits>
306 using ScalarProduct = Dune::ScalarProduct<Vector>;
308 using Comm = Dune::OwnerOverlapCopyCommunication<Dune::bigunsignedint<96>,
int>;
319 , isParallel_(
Dune::MPIHelper::getCommunication().size() > 1)
322 DUNE_THROW(Dune::InvalidStateException,
"Using sequential constructor for parallel run. Use signature with gridView and dofMapper!");
325 initializeParameters_();
326 scalarProduct_ = std::make_shared<ScalarProduct>();
327 solverCategory_ = Dune::SolverCategory::sequential;
338 const typename LinearSolverTraits::DofMapper& dofMapper,
342 , isParallel_(gridView.comm().size() > 1)
346 initializeParameters_();
348 solverCategory_ = Detail::solverCategory<LinearSolverTraits>(gridView);
349 if (solverCategory_ != Dune::SolverCategory::sequential)
351 parallelHelper_ = std::make_unique<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
352 comm_ = std::make_shared<Comm>(gridView.comm(), solverCategory_);
353 scalarProduct_ = Dune::createScalarProduct<Vector>(*comm_, solverCategory_);
354 parallelHelper_->createParallelIndexSet(*comm_);
357 scalarProduct_ = std::make_shared<ScalarProduct>();
359 solverCategory_ = Dune::SolverCategory::sequential;
360 scalarProduct_ = std::make_shared<ScalarProduct>();
371 bool solve(Matrix& A, Vector& x, Vector& b)
374 solveSequentialOrParallel_(A, x, b);
376 solveSequential_(A, x, b);
379 return result_.converged;
382 const Dune::InverseOperatorResult&
result()
const
387 const std::string&
name()
const
397 if (solverCategory_ == Dune::SolverCategory::nonoverlapping)
400 using GV =
typename LinearSolverTraits::GridView;
401 using DM =
typename LinearSolverTraits::DofMapper;
404 return scalarProduct_->norm(y);
408 return scalarProduct_->norm(x);
413 void initializeParameters_()
416 checkMandatoryParameters_();
417 name_ = params_.get<std::string>(
"preconditioner.type") +
"-preconditioned " + params_.get<std::string>(
"type");
418 if (params_.get<
int>(
"verbose", 0) > 0)
419 std::cout <<
"Initialized linear solver of type: " << name_ << std::endl;
422 void checkMandatoryParameters_()
424 if (!params_.hasKey(
"type"))
425 DUNE_THROW(Dune::InvalidStateException,
"Solver factory needs \"LinearSolver.Type\" parameter to select the solver");
427 if (!params_.hasKey(
"preconditioner.type"))
428 DUNE_THROW(Dune::InvalidStateException,
"Solver factory needs \"LinearSolver.Preconditioner.Type\" parameter to select the preconditioner");
432 void solveSequentialOrParallel_(Matrix& A, Vector& x, Vector& b)
441 if (LinearSolverTraits::isNonOverlapping(parallelHelper_->gridView()))
443 using PTraits =
typename LinearSolverTraits::template ParallelNonoverlapping<Matrix, Vector>;
444 solveParallel_<PTraits>(A, x, b);
448 using PTraits =
typename LinearSolverTraits::template ParallelOverlapping<Matrix, Vector>;
449 solveParallel_<PTraits>(A, x, b);
453 solveSequential_(A, x, b);
457 solveSequential_(A, x, b);
461 template<
class ParallelTraits>
462 void solveParallel_(Matrix& A, Vector& x, Vector& b)
464 using LinearOperator =
typename ParallelTraits::LinearOperator;
467 initSolverFactories<Matrix, LinearOperator>();
469 prepareLinearAlgebraParallel<LinearSolverTraits, ParallelTraits>(A, b, *parallelHelper_);
470 auto linearOperator = std::make_shared<LinearOperator>(A, *comm_);
473 auto solver = getSolverFromFactory_(linearOperator);
476 solver->apply(x, b, result_);
480 void solveSequential_(Matrix& A, Vector& x, Vector& b)
483 using Traits =
typename LinearSolverTraits::template Sequential<Matrix, Vector>;
484 using LinearOperator =
typename Traits::LinearOperator;
485 auto linearOperator = std::make_shared<LinearOperator>(A);
488 initSolverFactories<Matrix, LinearOperator>();
491 auto solver = getSolverFromFactory_(linearOperator);
494 solver->apply(x, b, result_);
497 template<
class LinearOperator>
498 auto getSolverFromFactory_(std::shared_ptr<LinearOperator>& fop)
500 try {
return Dune::getSolverFromFactory(fop, params_); }
501 catch(Dune::Exception& e)
503 std::cerr <<
"Could not create solver with factory" << std::endl;
504 std::cerr << e.what() << std::endl;
509 const std::string paramGroup_;
511 std::unique_ptr<ParallelISTLHelper<LinearSolverTraits>> parallelHelper_;
512 std::shared_ptr<Comm> comm_;
514 bool isParallel_ =
false;
517 std::shared_ptr<ScalarProduct> scalarProduct_;
518 Dune::SolverCategory::Category solverCategory_;
519 Dune::InverseOperatorResult result_;
520 Dune::ParameterTree params_;
Definition: istlsolverfactorybackend.hh:303
IstlSolverFactoryBackend(const typename LinearSolverTraits::GridView &gridView, const typename LinearSolverTraits::DofMapper &dofMapper, const std::string ¶mGroup="")
Construct the backend for parallel or sequential runs.
Definition: istlsolverfactorybackend.hh:337
const std::string & name() const
Definition: istlsolverfactorybackend.hh:387
bool solve(Matrix &A, Vector &x, Vector &b)
Solve a linear system.
Definition: istlsolverfactorybackend.hh:371
const Dune::InverseOperatorResult & result() const
Definition: istlsolverfactorybackend.hh:382
IstlSolverFactoryBackend(const std::string ¶mGroup="")
Construct the backend for the sequential case only.
Definition: istlsolverfactorybackend.hh:317
Scalar norm(const Vector &x) const
Definition: istlsolverfactorybackend.hh:392
Definition: istlsolverfactorybackend.hh:97
const std::string & name() const
Definition: istlsolverfactorybackend.hh:180
const Dune::InverseOperatorResult & result() const
Definition: istlsolverfactorybackend.hh:175
OldIstlSolverFactoryBackend(const std::string ¶mGroup="")
Construct the backend for the sequential case only.
Definition: istlsolverfactorybackend.hh:106
OldIstlSolverFactoryBackend(const typename LinearSolverTraits::GridView &gridView, const typename LinearSolverTraits::DofMapper &dofMapper, const std::string ¶mGroup="")
Construct the backend for parallel or sequential runs.
Definition: istlsolverfactorybackend.hh:125
bool solve(Matrix &A, Vector &x, Vector &b)
Solve a linear system.
Definition: istlsolverfactorybackend.hh:164
void updateAfterGridAdaption(const typename LinearSolverTraits::GridView &gridView, const typename LinearSolverTraits::DofMapper &dofMapper)
Update the solver after grid adaption.
Definition: istlsolverfactorybackend.hh:147
Base class for linear solvers.
Definition: solver.hh:27
const std::string & paramGroup() const
the parameter group for getting parameter from the parameter tree
Definition: solver.hh:78
double Scalar
Definition: solver.hh:31
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:47
Definition: parallelhelpers.hh:476
void makeNonOverlappingConsistent(Dune::BlockVector< Block, Alloc > &v) const
Make a vector consistent for non-overlapping domain decomposition methods.
Definition: parallelhelpers.hh:484
typename Detail::IstlSolverFactoryBackendImplHelper< sizeof...(T)>::template type< T... > IstlSolverFactoryBackend
A linear solver using the dune-istl solver factory to choose the solver and preconditioner at runtime...
Definition: istlsolverfactorybackend.hh:548
The specialized Dumux macro and tag for the ISTL registry to choose the solver and preconditioner at ...
Generates a parameter tree required for the linear solvers and precondioners of the Dune ISTL.
Type traits to be used with matrix types.
static constexpr bool canCommunicate
Definition: gridcapabilities.hh:51
void initSolverFactories()
Initialize the solver factories for regular matrices or MultiTypeBlockMatrices.
Definition: istlsolverfactorybackend.hh:79
Definition: common/pdesolver.hh:24
Provides a helper class for nonoverlapping decomposition.
Dumux preconditioners for iterative solvers.
Base class for linear solvers.
Definition: istlsolverfactorybackend.hh:526
V Vector
Definition: linearalgebratraits.hh:53
M Matrix
Definition: linearalgebratraits.hh:52
Helper type to determine whether a given type is a Dune::MultiTypeBlockMatrix.
Definition: matrix.hh:37
Helper type to determine whether a given type is a Dune::MultiTypeBlockVector.
Definition: vector.hh:22
Type traits to be used with vector types.