12#ifndef DUMUX_LINEAR_ISTL_SOLVERS_HH
13#define DUMUX_LINEAR_ISTL_SOLVERS_HH
18#include <dune/common/exceptions.hh>
19#include <dune/common/shared_ptr.hh>
20#include <dune/common/version.hh>
21#include <dune/common/parallel/indexset.hh>
22#include <dune/common/parallel/mpicommunication.hh>
23#include <dune/grid/common/capabilities.hh>
24#include <dune/istl/solvers.hh>
25#include <dune/istl/solverfactory.hh>
26#include <dune/istl/owneroverlapcopy.hh>
27#include <dune/istl/scalarproducts.hh>
28#include <dune/istl/paamg/amg.hh>
29#include <dune/istl/paamg/pinfo.hh>
41#include <dune/istl/foreach.hh>
57template<
template<
class,
class,
class,
int>
class Preconditioner,
int blockLevel = 1>
61 template<
class TL,
class M>
62 auto operator() (TL typeList,
const M& matrix,
const Dune::ParameterTree& config)
64 using Matrix =
typename Dune::TypeListElement<0,
decltype(typeList)>::type;
65 using Domain =
typename Dune::TypeListElement<1,
decltype(typeList)>::type;
66 using Range =
typename Dune::TypeListElement<2,
decltype(typeList)>::type;
67 std::shared_ptr<Dune::Preconditioner<Domain, Range>> preconditioner
68 = std::make_shared<Preconditioner<Matrix, Domain, Range, blockLevel>>(matrix, config);
69 return preconditioner;
73template<
template<
class,
class,
class>
class Preconditioner>
76 template<
class TL,
class M>
77 auto operator() (TL typeList,
const M& matrix,
const Dune::ParameterTree& config)
79 using Matrix =
typename Dune::TypeListElement<0,
decltype(typeList)>::type;
80 using Domain =
typename Dune::TypeListElement<1,
decltype(typeList)>::type;
81 using Range =
typename Dune::TypeListElement<2,
decltype(typeList)>::type;
82 std::shared_ptr<Dune::Preconditioner<Domain, Range>> preconditioner
83 = std::make_shared<Preconditioner<Matrix, Domain, Range>>(matrix, config);
84 return preconditioner;
90template<
class M,
bool convert = false>
97template<
class V,
bool convert = false>
104template<
class LSTraits,
class LATraits,
bool convert,
bool parallel = LSTraits::canCommunicate>
107template<
class LSTraits,
class LATraits,
bool convert>
114 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>,
115 std::shared_ptr<typename LSTraits::template ParallelOverlapping<M, V>::LinearOperator>,
116 std::shared_ptr<typename LSTraits::template ParallelNonoverlapping<M, V>::LinearOperator>
119 using type = std::variant<
120 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>
125template<
class LSTraits,
class LATraits,
bool convert>
131 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>
148 operator bool()
const {
return this->converged; }
156 class InverseOperator,
class PreconditionerFactory,
157 bool convertMultiTypeLATypes =
false>
163 using Scalar =
typename InverseOperator::real_type;
165 using ScalarProduct = Dune::ScalarProduct<typename InverseOperator::domain_type>;
167 static constexpr bool convertMultiTypeVectorAndMatrix
178 using Comm = Dune::OwnerOverlapCopyCommunication<Dune::bigunsignedint<96>,
int>;
182 using ParameterInitializer = std::variant<std::string, Dune::ParameterTree>;
190 if (Dune::MPIHelper::getCommunication().size() > 1)
191 DUNE_THROW(Dune::InvalidStateException,
"Using sequential constructor for parallel run. Use signature with gridView and dofMapper!");
193 initializeParameters_(params);
194 solverCategory_ = Dune::SolverCategory::sequential;
195 scalarProduct_ = std::make_shared<ScalarProduct>();
201 template <
class Gr
idView,
class DofMapper>
203 const DofMapper& dofMapper,
204 const ParameterInitializer& params =
"")
206 initializeParameters_(params, gridView.comm());
208 solverCategory_ = Detail::solverCategory<LinearSolverTraits>(gridView);
212 if (solverCategory_ != Dune::SolverCategory::sequential)
214 parallelHelper_ = std::make_shared<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
215 communication_ = std::make_shared<Comm>(gridView.comm(), solverCategory_);
216 scalarProduct_ = Dune::createScalarProduct<XVector>(*communication_, solverCategory_);
217 parallelHelper_->createParallelIndexSet(*communication_);
220 scalarProduct_ = std::make_shared<ScalarProduct>();
223 scalarProduct_ = std::make_shared<ScalarProduct>();
225 solverCategory_ = Dune::SolverCategory::sequential;
226 scalarProduct_ = std::make_shared<ScalarProduct>();
234 template <
class Gr
idView,
class DofMapper>
236 std::shared_ptr<ScalarProduct> scalarProduct,
237 const GridView& gridView,
238 const DofMapper& dofMapper,
239 const ParameterInitializer& params =
"")
241 initializeParameters_(params, gridView.comm());
243 scalarProduct_ = scalarProduct;
244 communication_ = communication;
247 if (solverCategory_ != Dune::SolverCategory::sequential)
249 parallelHelper_ = std::make_shared<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
250 parallelHelper_->createParallelIndexSet(communication);
260 {
return solveSequentialOrParallel_(A, x, b); }
267 linearOperator_ = makeParallelOrSequentialLinearOperator_(std::move(A));
268 solver_ = constructPreconditionedSolver_(linearOperator_);
276 {
setMatrix(Dune::stackobject_to_shared_ptr(A)); }
284 DUNE_THROW(Dune::InvalidStateException,
"Called solve(x, b) but no linear operator has been set");
286 return solveSequentialOrParallel_(x, b, *solver_);
292 Scalar
norm(
const XVector& x)
const
297 if (solverCategory_ == Dune::SolverCategory::nonoverlapping)
300 using GV =
typename LinearSolverTraits::GridView;
301 using DM =
typename LinearSolverTraits::DofMapper;
304 return scalarProduct_->norm(y);
308 if constexpr (convertMultiTypeVectorAndMatrix)
311 return scalarProduct_->norm(y);
314 return scalarProduct_->norm(x);
320 const std::string&
name()
const
330 params_[
"reduction"] = std::to_string(residReduction);
334 solver_ = constructPreconditionedSolver_(linearOperator_);
342 params_[
"maxit"] = std::to_string(maxIter);
346 solver_ = constructPreconditionedSolver_(linearOperator_);
358 initializeParameters_(params, communication_->communicator());
360 initializeParameters_(params);
362 initializeParameters_(params);
367 solver_ = constructPreconditionedSolver_(linearOperator_);
372 void initializeParameters_(
const ParameterInitializer& params)
374 if (std::holds_alternative<std::string>(params))
377 params_ = std::get<Dune::ParameterTree>(params);
380 template <
class Comm>
381 void initializeParameters_(
const ParameterInitializer& params,
const Comm& comm)
383 initializeParameters_(params);
386 if (comm.rank() != 0)
390 MatrixOperatorHolder makeSequentialLinearOperator_(std::shared_ptr<Matrix> A)
392 using SequentialTraits =
typename LinearSolverTraits::template Sequential<MatrixForSolver, XVectorForSolver>;
393 if constexpr (convertMultiTypeVectorAndMatrix)
397 return std::make_shared<typename SequentialTraits::LinearOperator>(M);
401 return std::make_shared<typename SequentialTraits::LinearOperator>(A);
405 template<
class ParallelTraits>
406 MatrixOperatorHolder makeParallelLinearOperator_(std::shared_ptr<Matrix> A, ParallelTraits = {})
410 prepareMatrixParallel<LinearSolverTraits, ParallelTraits>(*A, *parallelHelper_);
411 return std::make_shared<typename ParallelTraits::LinearOperator>(std::move(A), *communication_);
413 DUNE_THROW(Dune::InvalidStateException,
"Calling makeParallelLinearOperator for sequential run");
417 MatrixOperatorHolder makeParallelOrSequentialLinearOperator_(std::shared_ptr<Matrix> A)
419 return executeSequentialOrParallel_(
420 [&]{
return makeSequentialLinearOperator_(std::move(A)); },
421 [&](
auto traits){
return makeParallelLinearOperator_(std::move(A), traits); }
425 MatrixOperatorHolder makeSequentialLinearOperator_(Matrix& A)
426 {
return makeSequentialLinearOperator_(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
428 MatrixOperatorHolder makeParallelOrSequentialLinearOperator_(Matrix& A)
429 {
return makeParallelOrSequentialLinearOperator_(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
431 template<
class ParallelTraits>
432 MatrixOperatorHolder makeParallelLinearOperator_(Matrix& A, ParallelTraits = {})
433 {
return makeParallelLinearOperator_<ParallelTraits>(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
435 IstlSolverResult solveSequential_(Matrix& A, XVector& x, BVector& b)
438 auto linearOperatorHolder = makeSequentialLinearOperator_(A);
439 auto solver = constructPreconditionedSolver_(linearOperatorHolder);
441 return solveSequential_(x, b, *solver);
444 IstlSolverResult solveSequential_(XVector& x, BVector& b, InverseOperator& solver)
const
446 Dune::InverseOperatorResult result;
447 if constexpr (convertMultiTypeVectorAndMatrix)
453 XVectorForSolver y(bTmp.size());
456 solver.apply(y, bTmp, result);
459 if (result.converged)
465 solver.apply(x, b, result);
471 IstlSolverResult solveSequentialOrParallel_(Matrix& A, XVector& x, BVector& b)
473 return executeSequentialOrParallel_(
474 [&]{
return solveSequential_(A, x, b); },
475 [&](
auto traits){
return solveParallel_(A, x, b, traits); }
479 IstlSolverResult solveSequentialOrParallel_(XVector& x, BVector& b, InverseOperator& solver)
const
481 return executeSequentialOrParallel_(
482 [&]{
return solveSequential_(x, b, solver); },
483 [&](
auto traits){
return solveParallel_(x, b, solver, traits); }
487 template<
class ParallelTraits>
488 IstlSolverResult solveParallel_(Matrix& A, XVector& x, BVector& b, ParallelTraits = {})
491 auto linearOperatorHolder = makeParallelLinearOperator_<ParallelTraits>(A);
492 auto solver = constructPreconditionedSolver_(linearOperatorHolder);
493 return solveParallel_<ParallelTraits>(x, b, *solver);
496 template<
class ParallelTraits>
497 IstlSolverResult solveParallel_(XVector& x, BVector& b, InverseOperator& solver, ParallelTraits = {})
const
501 prepareVectorParallel<LinearSolverTraits, ParallelTraits>(b, *parallelHelper_);
504 Dune::InverseOperatorResult result;
505 solver.apply(x, b, result);
508 DUNE_THROW(Dune::InvalidStateException,
"Calling makeParallelLinearOperator for sequential run");
513 std::shared_ptr<InverseOperator> constructPreconditionedSolver_(MatrixOperatorHolder& ops)
515 return std::visit([&](
auto&& op)
517 using LinearOperator =
typename std::decay_t<
decltype(op)>::element_type;
518 const auto& params = params_.sub(
"preconditioner");
519 using Prec = Dune::Preconditioner<typename LinearOperator::domain_type, typename LinearOperator::range_type>;
520#if DUNE_VERSION_GTE(DUNE_ISTL,2,11)
521 using OpTraits = Dune::OperatorTraits<LinearOperator>;
522 std::shared_ptr<Prec> prec = PreconditionerFactory{}(OpTraits{}, op, params);
524 using TL = Dune::TypeList<typename LinearOperator::matrix_type, typename LinearOperator::domain_type, typename LinearOperator::range_type>;
525 std::shared_ptr<Prec> prec = PreconditionerFactory{}(TL{}, op, params);
529#if DUNE_VERSION_LT(DUNE_ISTL,2,11)
530 if (prec->category() != op->category() && prec->category() == Dune::SolverCategory::sequential)
531 prec = Dune::wrapPreconditioner4Parallel(prec, op);
533 if constexpr (OpTraits::isParallel)
535 using Comm =
typename OpTraits::comm_type;
536 const Comm& comm = OpTraits::getCommOrThrow(op);
537 if (op->category() == Dune::SolverCategory::overlapping && prec->category() == Dune::SolverCategory::sequential)
538 prec = std::make_shared<Dune::BlockPreconditioner<typename OpTraits::domain_type, typename OpTraits::range_type,Comm> >(prec, comm);
539 else if (op->category() == Dune::SolverCategory::nonoverlapping && prec->category() == Dune::SolverCategory::sequential)
540 prec = std::make_shared<Dune::NonoverlappingBlockPreconditioner<Comm, Prec> >(prec, comm);
544 return std::make_shared<InverseOperator>(op, scalarProduct_, prec, params_);
548 template<
class Seq,
class Par>
549 decltype(
auto) executeSequentialOrParallel_(Seq&& sequentialAction, Par&& parallelAction)
const
555 return sequentialAction();
558 switch (solverCategory_)
560 case Dune::SolverCategory::sequential:
561 return sequentialAction();
562 case Dune::SolverCategory::nonoverlapping:
563 using NOTraits =
typename LinearSolverTraits::template ParallelNonoverlapping<Matrix, XVector>;
564 return parallelAction(NOTraits{});
565 case Dune::SolverCategory::overlapping:
566 using OTraits =
typename LinearSolverTraits::template ParallelOverlapping<Matrix, XVector>;
567 return parallelAction(OTraits{});
568 default: DUNE_THROW(Dune::InvalidStateException,
"Unknown solver category");
572 return sequentialAction();
577 std::shared_ptr<const ParallelHelper> parallelHelper_;
578 std::shared_ptr<Comm> communication_;
581 Dune::SolverCategory::Category solverCategory_;
582 std::shared_ptr<ScalarProduct> scalarProduct_;
585 MatrixOperatorHolder linearOperator_;
587 std::shared_ptr<InverseOperator> solver_;
589 Dune::ParameterTree params_;
613template<
class LSTraits,
class LATraits>
616 Dune::BiCGSTABSolver<typename LATraits::SingleTypeVector>,
638template<
class LSTraits,
class LATraits>
641 Dune::RestartedGMResSolver<typename LATraits::SingleTypeVector>,
664template<
class LSTraits,
class LATraits>
667 Dune::BiCGSTABSolver<typename LATraits::Vector>,
687template<
class LSTraits,
class LATraits>
690 Dune::CGSolver<typename LATraits::Vector>,
707template<
class LSTraits,
class LATraits>
710 Dune::BiCGSTABSolver<typename LATraits::SingleTypeVector>,
728template<
class LSTraits,
class LATraits>
731 Dune::CGSolver<typename LATraits::SingleTypeVector>,
751template<
class LSTraits,
class LATraits>
754 Dune::BiCGSTABSolver<typename LATraits::Vector>,
766template<
class LSTraits,
class LATraits,
template<
class M>
class Solver,
767 bool convertMultiTypeVectorAndMatrix = isMultiTypeBlockVector<typename LATraits::Vector>::value>
770 using Matrix =
typename LATraits::Matrix;
771 using XVector =
typename LATraits::Vector;
772 using BVector =
typename LATraits::Vector;
777 using InverseOperator = Dune::InverseOperator<XVectorForSolver, BVectorForSolver>;
786 return solve_(A, x, b);
795 DUNE_THROW(Dune::InvalidStateException,
"Called solve(x, b) but no linear operator has been set");
797 return solve_(x, b, *solver_);
805 if constexpr (convertMultiTypeVectorAndMatrix)
810 solver_ = std::make_shared<Solver<MatrixForSolver>>(*matrix_);
818 {
setMatrix(Dune::stackobject_to_shared_ptr(A)); }
825 return "Direct solver";
832 if constexpr (convertMultiTypeVectorAndMatrix)
835 Solver<MatrixForSolver> solver(AA, this->
verbosity() > 0);
836 return solve_(x, b, solver);
840 Solver<MatrixForSolver> solver(A, this->
verbosity() > 0);
841 return solve_(x, b, solver);
845 IstlSolverResult solve_(XVector& x,
const BVector& b, InverseOperator& solver)
const
847 Dune::InverseOperatorResult result;
849 if constexpr (convertMultiTypeVectorAndMatrix)
852 XVectorForSolver xx(bb.size());
853 solver.apply(xx, bb, result);
854 checkResult_(xx, result);
855 if (result.converged)
861 BVectorForSolver bTmp(b);
862 solver.apply(x, bTmp, result);
863 checkResult_(x, result);
869 void checkResult_(XVectorForSolver& x, Dune::InverseOperatorResult& result)
const
871 flatVectorForEach(x, [&](
auto&& entry, std::size_t){
872 using std::isnan, std::isinf;
873 if (isnan(entry) || isinf(entry))
874 result.converged =
false;
879 std::shared_ptr<MatrixForSolver> matrix_;
881 std::shared_ptr<InverseOperator> solver_;
887#include <dune/istl/superlu.hh>
899template<
class LSTraits,
class LATraits>
900using SuperLUIstlSolver = Detail::DirectIstlSolver<LSTraits, LATraits, Dune::SuperLU>;
907#include <dune/istl/umfpack.hh>
919template<
class LSTraits,
class LATraits>
920using UMFPackIstlSolver = Detail::DirectIstlSolver<LSTraits, LATraits, Dune::UMFPack, false>;
Direct dune-istl linear solvers.
Definition: istlsolvers.hh:769
void setMatrix(std::shared_ptr< Matrix > A)
Set the matrix A of the linear system Ax = b for reuse.
Definition: istlsolvers.hh:803
IstlSolverResult solve(const Matrix &A, XVector &x, const BVector &b)
Solve the linear system Ax = b.
Definition: istlsolvers.hh:784
std::string name() const
name of the linear solver
Definition: istlsolvers.hh:823
void setMatrix(Matrix &A)
Set the matrix A of the linear system Ax = b for reuse.
Definition: istlsolvers.hh:817
IstlSolverResult solve(XVector &x, const BVector &b)
Solve the linear system Ax = b using the matrix set with setMatrix.
Definition: istlsolvers.hh:792
Standard dune-istl iterative linear solvers.
Definition: istlsolvers.hh:159
IstlIterativeLinearSolver(const ParameterInitializer ¶ms="")
Constructor for sequential solvers.
Definition: istlsolvers.hh:188
void setMatrix(Matrix &A)
Set the matrix A of the linear system Ax = b for reuse.
Definition: istlsolvers.hh:275
void setResidualReduction(double residReduction)
Set the residual reduction tolerance.
Definition: istlsolvers.hh:328
void setMaxIter(std::size_t maxIter)
Set the maximum number of linear solver iterations.
Definition: istlsolvers.hh:340
IstlIterativeLinearSolver(const GridView &gridView, const DofMapper &dofMapper, const ParameterInitializer ¶ms="")
Constructor for parallel and sequential solvers.
Definition: istlsolvers.hh:202
const std::string & name() const
The name of the linear solver.
Definition: istlsolvers.hh:320
void setParams(const ParameterInitializer ¶ms)
Set the linear solver parameters.
Definition: istlsolvers.hh:354
IstlSolverResult solve(Matrix &A, XVector &x, BVector &b)
Solve the linear system Ax = b.
Definition: istlsolvers.hh:259
void setMatrix(std::shared_ptr< Matrix > A)
Set the matrix A of the linear system Ax = b for reuse.
Definition: istlsolvers.hh:265
IstlSolverResult solve(XVector &x, BVector &b) const
Solve the linear system Ax = b where A has been set with setMatrix.
Definition: istlsolvers.hh:281
IstlIterativeLinearSolver(std::shared_ptr< Comm > communication, std::shared_ptr< ScalarProduct > scalarProduct, const GridView &gridView, const DofMapper &dofMapper, const ParameterInitializer ¶ms="")
Constructor with custom scalar product and communication.
Definition: istlsolvers.hh:235
Scalar norm(const XVector &x) const
Compute the 2-norm of vector x.
Definition: istlsolvers.hh:292
Definition: istlsolvers.hh:59
auto operator()(TL typeList, const M &matrix, const Dune::ParameterTree &config)
Definition: istlsolvers.hh:62
Definition: istlsolvers.hh:75
Definition: parallelhelpers.hh:29
Base class for linear solvers.
Definition: solver.hh:27
LinearSolver(const std::string ¶mGroup="")
Construct the solver.
Definition: solver.hh:43
int verbosity() const
the verbosity level
Definition: solver.hh:82
static void disableVerbosity(Dune::ParameterTree ¶ms)
Definition: linearsolverparameters.hh:97
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
A helper class that converts a Dune::MultiTypeBlockMatrix into a plain Dune::BCRSMatrix TODO: allow b...
Definition: matrixconverter.hh:35
static auto multiTypeToBCRSMatrix(const MultiTypeBlockMatrix &A)
Converts the matrix to a type the IterativeSolverBackend can handle.
Definition: matrixconverter.hh:46
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
static void retrieveValues(MultiTypeBlockVector &x, const BlockVector &y)
Copies the entries of a Dune::BlockVector to a Dune::MultiTypeBlockVector.
Definition: matrixconverter.hh:229
static auto multiTypeToBlockVector(const MultiTypeBlockVector &b)
Converts a Dune::MultiTypeBlockVector to a plain 1x1 Dune::BlockVector.
Definition: matrixconverter.hh:203
constexpr std::size_t preconditionerBlockLevel() noexcept
Returns the block level for the preconditioner for a given matrix.
Definition: istlsolvers.hh:52
Define traits for linear algebra backends.
Generates a parameter tree required for the linear solvers and precondioners of the Dune ISTL.
Type traits to be used with matrix types.
A helper class that converts a Dune::MultiTypeBlockMatrix into a plain Dune::BCRSMatrix.
Definition: istlsolvers.hh:43
Dune::AMGCreator IstlAmgPreconditionerFactory
Definition: istlsolvers.hh:88
Distance implementation details.
Definition: cvfelocalresidual.hh:25
static constexpr bool canCommunicate
Definition: gridcapabilities.hh:51
Dune::SolverCategory::Category solverCategory(const GridView &gridView)
Definition: solvercategory.hh:20
LinearSolverTraitsImpl< GridGeometry, typename GridGeometry::DiscretizationMethod > LinearSolverTraits
The type traits required for using the IstlFactoryBackend.
Definition: linearsolvertraits.hh:37
Provides a helper class for nonoverlapping decomposition.
Dumux preconditioners for iterative solvers.
Base class for linear solvers.
Definition: istlsolvers.hh:140
IstlSolverResult(IstlSolverResult &&)=default
IstlSolverResult(const Dune::InverseOperatorResult &o)
Definition: istlsolvers.hh:145
IstlSolverResult(Dune::InverseOperatorResult &&o)
Definition: istlsolvers.hh:146
IstlSolverResult()=default
IstlSolverResult(const IstlSolverResult &)=default
std::decay_t< decltype(MatrixConverter< M >::multiTypeToBCRSMatrix(std::declval< M >()))> type
Definition: istlsolvers.hh:95
Definition: istlsolvers.hh:91
M type
Definition: istlsolvers.hh:91
typename VectorForSolver< typename LATraits::Vector, convert >::type V
Definition: istlsolvers.hh:129
std::variant< std::shared_ptr< typename LSTraits::template Sequential< M, V >::LinearOperator > > type
Definition: istlsolvers.hh:132
typename MatrixForSolver< typename LATraits::Matrix, convert >::type M
Definition: istlsolvers.hh:128
std::variant< std::shared_ptr< typename LSTraits::template Sequential< M, V >::LinearOperator >, std::shared_ptr< typename LSTraits::template ParallelOverlapping< M, V >::LinearOperator >, std::shared_ptr< typename LSTraits::template ParallelNonoverlapping< M, V >::LinearOperator > > type
Definition: istlsolvers.hh:117
typename VectorForSolver< typename LATraits::Vector, convert >::type V
Definition: istlsolvers.hh:111
typename MatrixForSolver< typename LATraits::Matrix, convert >::type M
Definition: istlsolvers.hh:110
Definition: istlsolvers.hh:105
std::decay_t< decltype(VectorConverter< V >::multiTypeToBlockVector(std::declval< V >()))> type
Definition: istlsolvers.hh:102
Definition: istlsolvers.hh:98
V type
Definition: istlsolvers.hh:98
Definition: linearalgebratraits.hh:51
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.