version 3.11-dev
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
istlsolvers.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12#ifndef DUMUX_LINEAR_ISTL_SOLVERS_HH
13#define DUMUX_LINEAR_ISTL_SOLVERS_HH
14
15#include <memory>
16#include <variant>
17
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>
30
40
41#include <dune/istl/foreach.hh>
42
44
51template<class M>
52constexpr std::size_t preconditionerBlockLevel() noexcept
53{
55}
56
57template<template<class,class,class,int> class Preconditioner, int blockLevel = 1>
59{
60public:
61 template<class TL, class M>
62 auto operator() (TL typeList, const M& matrix, const Dune::ParameterTree& config)
63 {
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;
70 }
71};
72
73template<template<class,class,class> class Preconditioner>
75{
76 template<class TL, class M>
77 auto operator() (TL typeList, const M& matrix, const Dune::ParameterTree& config)
78 {
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;
85 }
86};
87
88using IstlAmgPreconditionerFactory = Dune::AMGCreator;
89
90template<class M, bool convert = false>
91struct MatrixForSolver { using type = M; };
92
93template<class M>
94struct MatrixForSolver<M, true>
95{ using type = std::decay_t<decltype(MatrixConverter<M>::multiTypeToBCRSMatrix(std::declval<M>()))>; };
96
97template<class V, bool convert = false>
98struct VectorForSolver { using type = V; };
99
100template<class V>
101struct VectorForSolver<V, true>
102{ using type = std::decay_t<decltype(VectorConverter<V>::multiTypeToBlockVector(std::declval<V>()))>; };
103
104template<class LSTraits, class LATraits, bool convert, bool parallel = LSTraits::canCommunicate>
106
107template<class LSTraits, class LATraits, bool convert>
108struct MatrixOperator<LSTraits, LATraits, convert, true>
109{
112#if HAVE_MPI
113 using type = std::variant<
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>
117 >;
118#else
119 using type = std::variant<
120 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>
121 >;
122#endif
123};
124
125template<class LSTraits, class LATraits, bool convert>
126struct MatrixOperator<LSTraits, LATraits, convert, false>
127{
130 using type = std::variant<
131 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>
132 >;
133};
134
135} // end namespace Dumux::Detail::IstlSolvers
136
137namespace Dumux::Detail {
138
139struct IstlSolverResult : public Dune::InverseOperatorResult
140{
141 IstlSolverResult() = default;
144
145 IstlSolverResult(const Dune::InverseOperatorResult& o) : InverseOperatorResult(o) {}
146 IstlSolverResult(Dune::InverseOperatorResult&& o) : InverseOperatorResult(std::move(o)) {}
147
148 operator bool() const { return this->converged; }
149};
150
155template<class LinearSolverTraits, class LinearAlgebraTraits,
156 class InverseOperator, class PreconditionerFactory,
157 bool convertMultiTypeLATypes = false>
159{
160 using Matrix = typename LinearAlgebraTraits::Matrix;
161 using XVector = typename LinearAlgebraTraits::Vector;
162 using BVector = typename LinearAlgebraTraits::Vector;
163 using Scalar = typename InverseOperator::real_type;
164
165 using ScalarProduct = Dune::ScalarProduct<typename InverseOperator::domain_type>;
166
167 static constexpr bool convertMultiTypeVectorAndMatrix
168 = convertMultiTypeLATypes && isMultiTypeBlockVector<XVector>::value;
172 // a variant type that can hold sequential, overlapping, and non-overlapping operators
173 using MatrixOperatorHolder = typename Detail::IstlSolvers::MatrixOperator<
174 LinearSolverTraits, LinearAlgebraTraits, convertMultiTypeVectorAndMatrix
175 >::type;
176
177#if HAVE_MPI
178 using Comm = Dune::OwnerOverlapCopyCommunication<Dune::bigunsignedint<96>, int>;
180#endif
181
182 using ParameterInitializer = std::variant<std::string, Dune::ParameterTree>;
183public:
184
188 IstlIterativeLinearSolver(const ParameterInitializer& params = "")
189 {
190 if (Dune::MPIHelper::getCommunication().size() > 1)
191 DUNE_THROW(Dune::InvalidStateException, "Using sequential constructor for parallel run. Use signature with gridView and dofMapper!");
192
193 initializeParameters_(params);
194 solverCategory_ = Dune::SolverCategory::sequential;
195 scalarProduct_ = std::make_shared<ScalarProduct>();
196 }
197
201 template <class GridView, class DofMapper>
202 IstlIterativeLinearSolver(const GridView& gridView,
203 const DofMapper& dofMapper,
204 const ParameterInitializer& params = "")
205 {
206 initializeParameters_(params, gridView.comm());
207#if HAVE_MPI
208 solverCategory_ = Detail::solverCategory<LinearSolverTraits>(gridView);
210 {
211
212 if (solverCategory_ != Dune::SolverCategory::sequential)
213 {
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_);
218 }
219 else
220 scalarProduct_ = std::make_shared<ScalarProduct>();
221 }
222 else
223 scalarProduct_ = std::make_shared<ScalarProduct>();
224#else
225 solverCategory_ = Dune::SolverCategory::sequential;
226 scalarProduct_ = std::make_shared<ScalarProduct>();
227#endif
228 }
229
230#if HAVE_MPI
234 template <class GridView, class DofMapper>
235 IstlIterativeLinearSolver(std::shared_ptr<Comm> communication,
236 std::shared_ptr<ScalarProduct> scalarProduct,
237 const GridView& gridView,
238 const DofMapper& dofMapper,
239 const ParameterInitializer& params = "")
240 {
241 initializeParameters_(params, gridView.comm());
242 solverCategory_ = Detail::solverCategory(gridView);
243 scalarProduct_ = scalarProduct;
244 communication_ = communication;
246 {
247 if (solverCategory_ != Dune::SolverCategory::sequential)
248 {
249 parallelHelper_ = std::make_shared<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
250 parallelHelper_->createParallelIndexSet(communication);
251 }
252 }
253 }
254#endif
255
259 IstlSolverResult solve(Matrix& A, XVector& x, BVector& b)
260 { return solveSequentialOrParallel_(A, x, b); }
261
265 void setMatrix(std::shared_ptr<Matrix> A)
266 {
267 linearOperator_ = makeParallelOrSequentialLinearOperator_(std::move(A));
268 solver_ = constructPreconditionedSolver_(linearOperator_);
269 }
270
275 void setMatrix(Matrix& A)
276 { setMatrix(Dune::stackobject_to_shared_ptr(A)); }
277
281 IstlSolverResult solve(XVector& x, BVector& b) const
282 {
283 if (!solver_)
284 DUNE_THROW(Dune::InvalidStateException, "Called solve(x, b) but no linear operator has been set");
285
286 return solveSequentialOrParallel_(x, b, *solver_);
287 }
288
292 Scalar norm(const XVector& x) const
293 {
294#if HAVE_MPI
296 {
297 if (solverCategory_ == Dune::SolverCategory::nonoverlapping)
298 {
299 auto y(x); // make a copy because the vector needs to be made consistent
300 using GV = typename LinearSolverTraits::GridView;
301 using DM = typename LinearSolverTraits::DofMapper;
302 ParallelVectorHelper<GV, DM, LinearSolverTraits::dofCodim> vectorHelper(parallelHelper_->gridView(), parallelHelper_->dofMapper());
303 vectorHelper.makeNonOverlappingConsistent(y);
304 return scalarProduct_->norm(y);
305 }
306 }
307#endif
308 if constexpr (convertMultiTypeVectorAndMatrix)
309 {
311 return scalarProduct_->norm(y);
312 }
313 else
314 return scalarProduct_->norm(x);
315 }
316
320 const std::string& name() const
321 {
322 return name_;
323 }
324
328 void setResidualReduction(double residReduction)
329 {
330 params_["reduction"] = std::to_string(residReduction);
331
332 // reconstruct the solver with new parameters
333 if (solver_)
334 solver_ = constructPreconditionedSolver_(linearOperator_);
335 }
336
340 void setMaxIter(std::size_t maxIter)
341 {
342 params_["maxit"] = std::to_string(maxIter);
343
344 // reconstruct the solver with new parameters
345 if (solver_)
346 solver_ = constructPreconditionedSolver_(linearOperator_);
347 }
348
354 void setParams(const ParameterInitializer& params)
355 {
356#if HAVE_MPI
357 if (communication_)
358 initializeParameters_(params, communication_->communicator());
359 else
360 initializeParameters_(params);
361#else
362 initializeParameters_(params);
363#endif
364
365 // reconstruct the solver with new parameters
366 if (solver_)
367 solver_ = constructPreconditionedSolver_(linearOperator_);
368 }
369
370private:
371
372 void initializeParameters_(const ParameterInitializer& params)
373 {
374 if (std::holds_alternative<std::string>(params))
375 params_ = Dumux::LinearSolverParameters<LinearSolverTraits>::createParameterTree(std::get<std::string>(params));
376 else
377 params_ = std::get<Dune::ParameterTree>(params);
378 }
379
380 template <class Comm>
381 void initializeParameters_(const ParameterInitializer& params, const Comm& comm)
382 {
383 initializeParameters_(params);
384
385 // disable verbose output on all ranks except rank 0
386 if (comm.rank() != 0)
388 }
389
390 MatrixOperatorHolder makeSequentialLinearOperator_(std::shared_ptr<Matrix> A)
391 {
392 using SequentialTraits = typename LinearSolverTraits::template Sequential<MatrixForSolver, XVectorForSolver>;
393 if constexpr (convertMultiTypeVectorAndMatrix)
394 {
395 // create the BCRS matrix the IterativeSolver backend can handle
396 auto M = std::make_shared<MatrixForSolver>(MatrixConverter<Matrix>::multiTypeToBCRSMatrix(*A));
397 return std::make_shared<typename SequentialTraits::LinearOperator>(M);
398 }
399 else
400 {
401 return std::make_shared<typename SequentialTraits::LinearOperator>(A);
402 }
403 }
404
405 template<class ParallelTraits>
406 MatrixOperatorHolder makeParallelLinearOperator_(std::shared_ptr<Matrix> A, ParallelTraits = {})
407 {
408#if HAVE_MPI
409 // make matrix consistent
410 prepareMatrixParallel<LinearSolverTraits, ParallelTraits>(*A, *parallelHelper_);
411 return std::make_shared<typename ParallelTraits::LinearOperator>(std::move(A), *communication_);
412#else
413 DUNE_THROW(Dune::InvalidStateException, "Calling makeParallelLinearOperator for sequential run");
414#endif
415 }
416
417 MatrixOperatorHolder makeParallelOrSequentialLinearOperator_(std::shared_ptr<Matrix> A)
418 {
419 return executeSequentialOrParallel_(
420 [&]{ return makeSequentialLinearOperator_(std::move(A)); },
421 [&](auto traits){ return makeParallelLinearOperator_(std::move(A), traits); }
422 );
423 }
424
425 MatrixOperatorHolder makeSequentialLinearOperator_(Matrix& A)
426 { return makeSequentialLinearOperator_(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
427
428 MatrixOperatorHolder makeParallelOrSequentialLinearOperator_(Matrix& A)
429 { return makeParallelOrSequentialLinearOperator_(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
430
431 template<class ParallelTraits>
432 MatrixOperatorHolder makeParallelLinearOperator_(Matrix& A, ParallelTraits = {})
433 { return makeParallelLinearOperator_<ParallelTraits>(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
434
435 IstlSolverResult solveSequential_(Matrix& A, XVector& x, BVector& b)
436 {
437 // construct solver from linear operator
438 auto linearOperatorHolder = makeSequentialLinearOperator_(A);
439 auto solver = constructPreconditionedSolver_(linearOperatorHolder);
440
441 return solveSequential_(x, b, *solver);
442 }
443
444 IstlSolverResult solveSequential_(XVector& x, BVector& b, InverseOperator& solver) const
445 {
446 Dune::InverseOperatorResult result;
447 if constexpr (convertMultiTypeVectorAndMatrix)
448 {
449 // create the vector the IterativeSolver backend can handle
450 BVectorForSolver bTmp = VectorConverter<BVector>::multiTypeToBlockVector(b);
451
452 // create a block vector to which the linear solver writes the solution
453 XVectorForSolver y(bTmp.size());
454
455 // solve linear system
456 solver.apply(y, bTmp, result);
457
458 // copy back the result y into x
459 if (result.converged)
461 }
462 else
463 {
464 // solve linear system
465 solver.apply(x, b, result);
466 }
467
468 return result;
469 }
470
471 IstlSolverResult solveSequentialOrParallel_(Matrix& A, XVector& x, BVector& b)
472 {
473 return executeSequentialOrParallel_(
474 [&]{ return solveSequential_(A, x, b); },
475 [&](auto traits){ return solveParallel_(A, x, b, traits); }
476 );
477 }
478
479 IstlSolverResult solveSequentialOrParallel_(XVector& x, BVector& b, InverseOperator& solver) const
480 {
481 return executeSequentialOrParallel_(
482 [&]{ return solveSequential_(x, b, solver); },
483 [&](auto traits){ return solveParallel_(x, b, solver, traits); }
484 );
485 }
486
487 template<class ParallelTraits>
488 IstlSolverResult solveParallel_(Matrix& A, XVector& x, BVector& b, ParallelTraits = {})
489 {
490 // construct solver from linear operator
491 auto linearOperatorHolder = makeParallelLinearOperator_<ParallelTraits>(A);
492 auto solver = constructPreconditionedSolver_(linearOperatorHolder);
493 return solveParallel_<ParallelTraits>(x, b, *solver);
494 }
495
496 template<class ParallelTraits>
497 IstlSolverResult solveParallel_(XVector& x, BVector& b, InverseOperator& solver, ParallelTraits = {}) const
498 {
499#if HAVE_MPI
500 // make right hand side consistent
501 prepareVectorParallel<LinearSolverTraits, ParallelTraits>(b, *parallelHelper_);
502
503 // solve linear system
504 Dune::InverseOperatorResult result;
505 solver.apply(x, b, result);
506 return result;
507#else
508 DUNE_THROW(Dune::InvalidStateException, "Calling makeParallelLinearOperator for sequential run");
509#endif
510 }
511
512
513 std::shared_ptr<InverseOperator> constructPreconditionedSolver_(MatrixOperatorHolder& ops)
514 {
515 return std::visit([&](auto&& op)
516 {
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);
523#else
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);
526#endif
527
528#if HAVE_MPI
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);
532#else
533 if constexpr (OpTraits::isParallel)
534 {
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);
541 }
542#endif
543#endif
544 return std::make_shared<InverseOperator>(op, scalarProduct_, prec, params_);
545 }, ops);
546 }
547
548 template<class Seq, class Par>
549 decltype(auto) executeSequentialOrParallel_(Seq&& sequentialAction, Par&& parallelAction) const
550 {
551#if HAVE_MPI
552 // For Dune::MultiTypeBlockMatrix there is currently no generic way
553 // of handling parallelism, we therefore can only solve these types of systems sequentially
554 if constexpr (isMultiTypeBlockMatrix<Matrix>::value || !LinearSolverTraits::canCommunicate)
555 return sequentialAction();
556 else
557 {
558 switch (solverCategory_)
559 {
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");
569 }
570 }
571#else
572 return sequentialAction();
573#endif
574 }
575
576#if HAVE_MPI
577 std::shared_ptr<const ParallelHelper> parallelHelper_;
578 std::shared_ptr<Comm> communication_;
579#endif
580
581 Dune::SolverCategory::Category solverCategory_;
582 std::shared_ptr<ScalarProduct> scalarProduct_;
583
584 // for stored solvers (reuse matrix)
585 MatrixOperatorHolder linearOperator_;
586 // for stored solvers (reuse matrix)
587 std::shared_ptr<InverseOperator> solver_;
588
589 Dune::ParameterTree params_;
590 std::string name_;
591};
592
593} // end namespace Dumux::Detail
594
595namespace Dumux {
596
613template<class LSTraits, class LATraits>
615 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
616 Dune::BiCGSTABSolver<typename LATraits::SingleTypeVector>,
618 // the Dune::ILU preconditioners don't accept multi-type matrices
619 /*convert multi-type istl types?*/ true
620 >;
621
638template<class LSTraits, class LATraits>
640 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
641 Dune::RestartedGMResSolver<typename LATraits::SingleTypeVector>,
643 // the Dune::ILU preconditioners don't accept multi-type matrices
644 /*convert multi-type istl types?*/ true
645 >;
646
664template<class LSTraits, class LATraits>
666 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
667 Dune::BiCGSTABSolver<typename LATraits::Vector>,
669 >;
670
687template<class LSTraits, class LATraits>
689 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
690 Dune::CGSolver<typename LATraits::Vector>,
692 >;
693
707template<class LSTraits, class LATraits>
709 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
710 Dune::BiCGSTABSolver<typename LATraits::SingleTypeVector>,
712 // the AMG preconditioner doesn't accept multi-type matrices
713 /*convert multi-type istl types?*/ true
714 >;
715
728template<class LSTraits, class LATraits>
730 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
731 Dune::CGSolver<typename LATraits::SingleTypeVector>,
733 // the AMG preconditioner doesn't accept multi-type matrices
734 /*convert multi-type istl types?*/ true
735 >;
736
751template<class LSTraits, class LATraits>
753 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
754 Dune::BiCGSTABSolver<typename LATraits::Vector>,
756 >;
757
758} // end namespace Dumux
759
760namespace Dumux::Detail {
761
766template<class LSTraits, class LATraits, template<class M> class Solver,
767 bool convertMultiTypeVectorAndMatrix = isMultiTypeBlockVector<typename LATraits::Vector>::value>
769{
770 using Matrix = typename LATraits::Matrix;
771 using XVector = typename LATraits::Vector;
772 using BVector = typename LATraits::Vector;
773
777 using InverseOperator = Dune::InverseOperator<XVectorForSolver, BVectorForSolver>;
778public:
780
784 IstlSolverResult solve(const Matrix& A, XVector& x, const BVector& b)
785 {
786 return solve_(A, x, b);
787 }
788
792 IstlSolverResult solve(XVector& x, const BVector& b)
793 {
794 if (!solver_)
795 DUNE_THROW(Dune::InvalidStateException, "Called solve(x, b) but no linear operator has been set");
796
797 return solve_(x, b, *solver_);
798 }
799
803 void setMatrix(std::shared_ptr<Matrix> A)
804 {
805 if constexpr (convertMultiTypeVectorAndMatrix)
806 matrix_ = std::make_shared<MatrixForSolver>(MatrixConverter<Matrix>::multiTypeToBCRSMatrix(A));
807 else
808 matrix_ = A;
809
810 solver_ = std::make_shared<Solver<MatrixForSolver>>(*matrix_);
811 }
812
817 void setMatrix(Matrix& A)
818 { setMatrix(Dune::stackobject_to_shared_ptr(A)); }
819
823 std::string name() const
824 {
825 return "Direct solver";
826 }
827
828private:
829 IstlSolverResult solve_(const Matrix& A, XVector& x, const BVector& b)
830 {
831 // support dune-istl multi-type block vector/matrix by copying
832 if constexpr (convertMultiTypeVectorAndMatrix)
833 {
835 Solver<MatrixForSolver> solver(AA, this->verbosity() > 0);
836 return solve_(x, b, solver);
837 }
838 else
839 {
840 Solver<MatrixForSolver> solver(A, this->verbosity() > 0);
841 return solve_(x, b, solver);
842 }
843 }
844
845 IstlSolverResult solve_(XVector& x, const BVector& b, InverseOperator& solver) const
846 {
847 Dune::InverseOperatorResult result;
848
849 if constexpr (convertMultiTypeVectorAndMatrix)
850 {
852 XVectorForSolver xx(bb.size());
853 solver.apply(xx, bb, result);
854 checkResult_(xx, result);
855 if (result.converged)
857 return result;
858 }
859 else
860 {
861 BVectorForSolver bTmp(b);
862 solver.apply(x, bTmp, result);
863 checkResult_(x, result);
864 return result;
865 }
866 }
867
868
869 void checkResult_(XVectorForSolver& x, Dune::InverseOperatorResult& result) const
870 {
871 flatVectorForEach(x, [&](auto&& entry, std::size_t){
872 using std::isnan, std::isinf;
873 if (isnan(entry) || isinf(entry))
874 result.converged = false;
875 });
876 }
877
879 std::shared_ptr<MatrixForSolver> matrix_;
881 std::shared_ptr<InverseOperator> solver_;
882};
883
884} // end namespace Dumux::Detail
885
886#if HAVE_SUPERLU
887#include <dune/istl/superlu.hh>
888
889namespace Dumux {
890
899template<class LSTraits, class LATraits>
900using SuperLUIstlSolver = Detail::DirectIstlSolver<LSTraits, LATraits, Dune::SuperLU>;
901
902} // end namespace Dumux
903
904#endif // HAVE_SUPERLU
905
906#if HAVE_UMFPACK
907#include <dune/istl/umfpack.hh>
908
909namespace Dumux {
910
919template<class LSTraits, class LATraits>
920using UMFPackIstlSolver = Detail::DirectIstlSolver<LSTraits, LATraits, Dune::UMFPack, false>;
921
922} // end namespace Dumux
923
924#endif // HAVE_UMFPACK
925
926#endif
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 &params="")
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 &params="")
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 &params)
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 &params="")
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
auto operator()(TL typeList, const M &matrix, const Dune::ParameterTree &config)
Definition: istlsolvers.hh:62
Definition: parallelhelpers.hh:29
Base class for linear solvers.
Definition: solver.hh:27
LinearSolver(const std::string &paramGroup="")
Construct the solver.
Definition: solver.hh:43
int verbosity() const
the verbosity level
Definition: solver.hh:82
static void disableVerbosity(Dune::ParameterTree &params)
Definition: linearsolverparameters.hh:97
static Dune::ParameterTree createParameterTree(const std::string &paramGroup="")
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
Definition: adapt.hh:17
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.
Solver category.
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(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.