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_();
 
  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)
 
  239        if constexpr (LinearSolverTraits::canCommunicate && !isMultiTypeBlockMatrix<Matrix>::value)
 
  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;
 
  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);
 
  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_;
 
 
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
const std::string & paramGroup() const
the parameter group for getting parameter from the parameter tree
Definition solver.hh:78
LinearSolver(const std::string ¶mGroup="")
Construct the solver.
Definition solver.hh:43
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.
Dune::SolverCategory::Category solverCategory(const GridView &gridView)
Definition solvercategory.hh:20
void prepareLinearAlgebraParallel(Matrix &A, Vector &b, ParallelHelper &pHelper)
Prepare linear algebra variables for parallel solvers.
Definition parallelhelpers.hh:905
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.