14#ifndef DUMUX_LINEAR_ISTL_SOLVERFACTORYBACKEND_HH
15#define DUMUX_LINEAR_ISTL_SOLVERFACTORYBACKEND_HH
19#include <dune/common/version.hh>
20#include <dune/common/parallel/mpihelper.hh>
21#include <dune/common/parametertree.hh>
26#include <dune/istl/preconditioners.hh>
27#include <dune/istl/paamg/amg.hh>
31#include <dune/istl/solvers.hh>
32#include <dune/istl/solverfactory.hh>
56template<
class LinearOperator>
57int initSolverFactoriesForMultiTypeBlockMatrix()
59#if DUNE_VERSION_LT(DUNE_ISTL,2,11)
60 using M =
typename LinearOperator::matrix_type;
61 using X =
typename LinearOperator::range_type;
62 using Y =
typename LinearOperator::domain_type;
63 using TL = Dune::TypeList<M,X,Y>;
64 auto& dsfac = Dune::DirectSolverFactory<M,X,Y>::instance();
65 Dune::addRegistryToFactory<TL>(dsfac, Dumux::MultiTypeBlockMatrixDirectSolverTag{});
66 auto& pfac = Dune::PreconditionerFactory<LinearOperator,X,Y>::instance();
67 Dune::addRegistryToFactory<TL>(pfac, Dumux::MultiTypeBlockMatrixPreconditionerTag{});
68 using TLS = Dune::TypeList<X,Y>;
69 auto& isfac = Dune::IterativeSolverFactory<X,Y>::instance();
70 return Dune::addRegistryToFactory<TLS>(isfac, Dune::IterativeSolverTag{});
72 using OpTraits = Dune::OperatorTraits<LinearOperator>;
73 auto& pfac = Dune::PreconditionerFactory<LinearOperator>::instance();
74 Dune::addRegistryToFactory<OpTraits>(pfac, Dumux::MultiTypeBlockMatrixPreconditionerTag{});
75 auto& sfac = Dune::SolverFactory<LinearOperator>::instance();
76 return Dune::addRegistryToFactory<OpTraits>(sfac, Dumux::MultiTypeBlockMatrixSolverTag{});
88template<
class Matrix,
class LinearOperator>
92 initSolverFactoriesForMultiTypeBlockMatrix<LinearOperator>();
94 Dune::initSolverFactories<LinearOperator>();
103template <
class LinearSolverTraits,
class LinearAlgebraTraits>
108 using ScalarProduct = Dune::ScalarProduct<Vector>;
110 using Comm = Dune::OwnerOverlapCopyCommunication<Dune::bigunsignedint<96>,
int>;
121 , isParallel_(
Dune::MPIHelper::getCommunication().size() > 1)
124 DUNE_THROW(Dune::InvalidStateException,
"Using sequential constructor for parallel run. Use signature with gridView and dofMapper!");
127 initializeParameters_();
128 scalarProduct_ = std::make_shared<ScalarProduct>();
129 solverCategory_ = Dune::SolverCategory::sequential;
140 const typename LinearSolverTraits::DofMapper& dofMapper,
144 , isParallel_(gridView.comm().size() > 1)
148 initializeParameters_();
150 solverCategory_ = Detail::solverCategory<LinearSolverTraits>(gridView);
151 if (solverCategory_ != Dune::SolverCategory::sequential)
153 parallelHelper_ = std::make_unique<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
154 comm_ = std::make_shared<Comm>(gridView.comm(), solverCategory_);
155 scalarProduct_ = Dune::createScalarProduct<Vector>(*comm_, solverCategory_);
156 parallelHelper_->createParallelIndexSet(*comm_);
159 scalarProduct_ = std::make_shared<ScalarProduct>();
161 solverCategory_ = Dune::SolverCategory::sequential;
162 scalarProduct_ = std::make_shared<ScalarProduct>();
173 bool solve(Matrix& A, Vector& x, Vector& b)
176 solveSequentialOrParallel_(A, x, b);
178 solveSequential_(A, x, b);
181 return result_.converged;
184 const Dune::InverseOperatorResult&
result()
const
189 const std::string&
name()
const
199 if (solverCategory_ == Dune::SolverCategory::nonoverlapping)
202 using GV =
typename LinearSolverTraits::GridView;
203 using DM =
typename LinearSolverTraits::DofMapper;
206 return scalarProduct_->norm(y);
210 return scalarProduct_->norm(x);
215 void initializeParameters_()
218 checkMandatoryParameters_();
219 name_ = params_.get<std::string>(
"preconditioner.type") +
"-preconditioned " + params_.get<std::string>(
"type");
220 if (params_.get<
int>(
"verbose", 0) > 0)
221 std::cout <<
"Initialized linear solver of type: " << name_ << std::endl;
224 void checkMandatoryParameters_()
226 if (!params_.hasKey(
"type"))
227 DUNE_THROW(Dune::InvalidStateException,
"Solver factory needs \"LinearSolver.Type\" parameter to select the solver");
229 if (!params_.hasKey(
"preconditioner.type"))
230 DUNE_THROW(Dune::InvalidStateException,
"Solver factory needs \"LinearSolver.Preconditioner.Type\" parameter to select the preconditioner");
234 void solveSequentialOrParallel_(Matrix& A, Vector& x, Vector& b)
243 if (LinearSolverTraits::isNonOverlapping(parallelHelper_->gridView()))
245 using PTraits =
typename LinearSolverTraits::template ParallelNonoverlapping<Matrix, Vector>;
246 solveParallel_<PTraits>(A, x, b);
250 using PTraits =
typename LinearSolverTraits::template ParallelOverlapping<Matrix, Vector>;
251 solveParallel_<PTraits>(A, x, b);
255 solveSequential_(A, x, b);
259 solveSequential_(A, x, b);
263 template<
class ParallelTraits>
264 void solveParallel_(Matrix& A, Vector& x, Vector& b)
266 using LinearOperator =
typename ParallelTraits::LinearOperator;
269 initSolverFactories<Matrix, LinearOperator>();
271 prepareLinearAlgebraParallel<LinearSolverTraits, ParallelTraits>(A, b, *parallelHelper_);
272 auto linearOperator = std::make_shared<LinearOperator>(A, *comm_);
275 apply_(linearOperator, x, b);
279 void solveSequential_(Matrix& A, Vector& x, Vector& b)
282 using Traits =
typename LinearSolverTraits::template Sequential<Matrix, Vector>;
283 using LinearOperator =
typename Traits::LinearOperator;
284 auto linearOperator = std::make_shared<LinearOperator>(A);
287 initSolverFactories<Matrix, LinearOperator>();
290 apply_(linearOperator, x, b);
293 template<
class LinearOperator>
294 auto getSolverFromFactory_(std::shared_ptr<LinearOperator>& fop)
297 return Dune::getSolverFromFactory(fop, params_);
298 }
catch(Dune::Exception& e) {
299 std::cerr <<
"Dune::Exception during solver construction: " << e.what() << std::endl;
300 return std::decay_t<decltype(Dune::getSolverFromFactory(fop, params_))>();
304 template<
class LinearOperator>
305 void apply_(std::shared_ptr<LinearOperator>& fop, Vector& x, Vector& b)
307 auto solver = getSolverFromFactory_(fop);
311 bool success =
static_cast<bool>(solver);
313 int successRemote = success;
315 successRemote = comm_->communicator().min(success);
318 DUNE_THROW(Dune::Exception,
"Could not create ISTL solver");
319 else if (!successRemote)
320 DUNE_THROW(Dune::Exception,
"Could not create ISTL solver on remote process");
323 DUNE_THROW(Dune::Exception,
"Could not create ISTL solver");
327 solver->apply(x, b, result_);
330 const std::string paramGroup_;
332 std::unique_ptr<ParallelISTLHelper<LinearSolverTraits>> parallelHelper_;
333 std::shared_ptr<Comm> comm_;
335 bool isParallel_ =
false;
338 std::shared_ptr<ScalarProduct> scalarProduct_;
339 Dune::SolverCategory::Category solverCategory_;
340 Dune::InverseOperatorResult result_;
341 Dune::ParameterTree params_;
A linear solver using the dune-istl solver factory to choose the solver and preconditioner at runtime...
Definition: istlsolverfactorybackend.hh:105
const std::string & name() const
Definition: istlsolverfactorybackend.hh:189
IstlSolverFactoryBackend(const std::string ¶mGroup="")
Construct the backend for the sequential case only.
Definition: istlsolverfactorybackend.hh:119
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:139
bool solve(Matrix &A, Vector &x, Vector &b)
Solve a linear system.
Definition: istlsolverfactorybackend.hh:173
Scalar norm(const Vector &x) const
Definition: istlsolverfactorybackend.hh:194
const Dune::InverseOperatorResult & result() const
Definition: istlsolverfactorybackend.hh:184
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
The specialized Dumux macro and tag for the ISTL registry to choose the solver and preconditioner at ...
The specialized Dumux tag for the ISTL registry including only ISTL solvers compatible with MultiType...
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:89
Definition: common/pdesolver.hh:24
Provides a helper class for nonoverlapping decomposition.
Dumux preconditioners for iterative solvers.
Base class for linear solvers.
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.