version 3.10-dev
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-FileCopyrightInfo: 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);
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);
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 initializeParameters_(params);
357
358 // reconstruct the solver with new parameters
359 if (solver_)
360 solver_ = constructPreconditionedSolver_(linearOperator_);
361 }
362
363private:
364
365 void initializeParameters_(const ParameterInitializer& params)
366 {
367 if (std::holds_alternative<std::string>(params))
368 params_ = Dumux::LinearSolverParameters<LinearSolverTraits>::createParameterTree(std::get<std::string>(params));
369 else
370 params_ = std::get<Dune::ParameterTree>(params);
371 }
372
373 MatrixOperatorHolder makeSequentialLinearOperator_(std::shared_ptr<Matrix> A)
374 {
375 using SequentialTraits = typename LinearSolverTraits::template Sequential<MatrixForSolver, XVectorForSolver>;
376 if constexpr (convertMultiTypeVectorAndMatrix)
377 {
378 // create the BCRS matrix the IterativeSolver backend can handle
379 auto M = std::make_shared<MatrixForSolver>(MatrixConverter<Matrix>::multiTypeToBCRSMatrix(*A));
380 return std::make_shared<typename SequentialTraits::LinearOperator>(M);
381 }
382 else
383 {
384 return std::make_shared<typename SequentialTraits::LinearOperator>(A);
385 }
386 }
387
388 template<class ParallelTraits>
389 MatrixOperatorHolder makeParallelLinearOperator_(std::shared_ptr<Matrix> A, ParallelTraits = {})
390 {
391#if HAVE_MPI
392 // make matrix consistent
393 prepareMatrixParallel<LinearSolverTraits, ParallelTraits>(*A, *parallelHelper_);
394 return std::make_shared<typename ParallelTraits::LinearOperator>(std::move(A), *communication_);
395#else
396 DUNE_THROW(Dune::InvalidStateException, "Calling makeParallelLinearOperator for sequential run");
397#endif
398 }
399
400 MatrixOperatorHolder makeParallelOrSequentialLinearOperator_(std::shared_ptr<Matrix> A)
401 {
402 return executeSequentialOrParallel_(
403 [&]{ return makeSequentialLinearOperator_(std::move(A)); },
404 [&](auto traits){ return makeParallelLinearOperator_(std::move(A), traits); }
405 );
406 }
407
408 MatrixOperatorHolder makeSequentialLinearOperator_(Matrix& A)
409 { return makeSequentialLinearOperator_(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
410
411 MatrixOperatorHolder makeParallelOrSequentialLinearOperator_(Matrix& A)
412 { return makeParallelOrSequentialLinearOperator_(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
413
414 template<class ParallelTraits>
415 MatrixOperatorHolder makeParallelLinearOperator_(Matrix& A, ParallelTraits = {})
416 { return makeParallelLinearOperator_<ParallelTraits>(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
417
418 IstlSolverResult solveSequential_(Matrix& A, XVector& x, BVector& b)
419 {
420 // construct solver from linear operator
421 auto linearOperatorHolder = makeSequentialLinearOperator_(A);
422 auto solver = constructPreconditionedSolver_(linearOperatorHolder);
423
424 return solveSequential_(x, b, *solver);
425 }
426
427 IstlSolverResult solveSequential_(XVector& x, BVector& b, InverseOperator& solver) const
428 {
429 Dune::InverseOperatorResult result;
430 if constexpr (convertMultiTypeVectorAndMatrix)
431 {
432 // create the vector the IterativeSolver backend can handle
433 BVectorForSolver bTmp = VectorConverter<BVector>::multiTypeToBlockVector(b);
434
435 // create a block vector to which the linear solver writes the solution
436 XVectorForSolver y(bTmp.size());
437
438 // solve linear system
439 solver.apply(y, bTmp, result);
440
441 // copy back the result y into x
442 if (result.converged)
444 }
445 else
446 {
447 // solve linear system
448 solver.apply(x, b, result);
449 }
450
451 return result;
452 }
453
454 IstlSolverResult solveSequentialOrParallel_(Matrix& A, XVector& x, BVector& b)
455 {
456 return executeSequentialOrParallel_(
457 [&]{ return solveSequential_(A, x, b); },
458 [&](auto traits){ return solveParallel_(A, x, b, traits); }
459 );
460 }
461
462 IstlSolverResult solveSequentialOrParallel_(XVector& x, BVector& b, InverseOperator& solver) const
463 {
464 return executeSequentialOrParallel_(
465 [&]{ return solveSequential_(x, b, solver); },
466 [&](auto traits){ return solveParallel_(x, b, solver, traits); }
467 );
468 }
469
470 template<class ParallelTraits>
471 IstlSolverResult solveParallel_(Matrix& A, XVector& x, BVector& b, ParallelTraits = {})
472 {
473 // construct solver from linear operator
474 auto linearOperatorHolder = makeParallelLinearOperator_<ParallelTraits>(A);
475 auto solver = constructPreconditionedSolver_(linearOperatorHolder);
476 return solveParallel_<ParallelTraits>(x, b, *solver);
477 }
478
479 template<class ParallelTraits>
480 IstlSolverResult solveParallel_(XVector& x, BVector& b, InverseOperator& solver, ParallelTraits = {}) const
481 {
482#if HAVE_MPI
483 // make right hand side consistent
484 prepareVectorParallel<LinearSolverTraits, ParallelTraits>(b, *parallelHelper_);
485
486 // solve linear system
487 Dune::InverseOperatorResult result;
488 solver.apply(x, b, result);
489 return result;
490#else
491 DUNE_THROW(Dune::InvalidStateException, "Calling makeParallelLinearOperator for sequential run");
492#endif
493 }
494
495
496 std::shared_ptr<InverseOperator> constructPreconditionedSolver_(MatrixOperatorHolder& ops)
497 {
498 return std::visit([&](auto&& op)
499 {
500 using LinearOperator = typename std::decay_t<decltype(op)>::element_type;
501 const auto& params = params_.sub("preconditioner");
502 using Prec = Dune::Preconditioner<typename LinearOperator::domain_type, typename LinearOperator::range_type>;
503#if DUNE_VERSION_GTE(DUNE_ISTL,2,11)
504 using OpTraits = Dune::OperatorTraits<LinearOperator>;
505 std::shared_ptr<Prec> prec = PreconditionerFactory{}(OpTraits{}, op, params);
506#else
507 using TL = Dune::TypeList<typename LinearOperator::matrix_type, typename LinearOperator::domain_type, typename LinearOperator::range_type>;
508 std::shared_ptr<Prec> prec = PreconditionerFactory{}(TL{}, op, params);
509#endif
510
511#if HAVE_MPI
512#if DUNE_VERSION_LT(DUNE_ISTL,2,11)
513 if (prec->category() != op->category() && prec->category() == Dune::SolverCategory::sequential)
514 prec = Dune::wrapPreconditioner4Parallel(prec, op);
515#else
516 if constexpr (OpTraits::isParallel)
517 {
518 using Comm = typename OpTraits::comm_type;
519 const Comm& comm = OpTraits::getCommOrThrow(op);
520 if (op->category() == Dune::SolverCategory::overlapping && prec->category() == Dune::SolverCategory::sequential)
521 prec = std::make_shared<Dune::BlockPreconditioner<typename OpTraits::domain_type, typename OpTraits::range_type,Comm> >(prec, comm);
522 else if (op->category() == Dune::SolverCategory::nonoverlapping && prec->category() == Dune::SolverCategory::sequential)
523 prec = std::make_shared<Dune::NonoverlappingBlockPreconditioner<Comm, Prec> >(prec, comm);
524 }
525#endif
526#endif
527 return std::make_shared<InverseOperator>(op, scalarProduct_, prec, params_);
528 }, ops);
529 }
530
531 template<class Seq, class Par>
532 decltype(auto) executeSequentialOrParallel_(Seq&& sequentialAction, Par&& parallelAction) const
533 {
534#if HAVE_MPI
535 // For Dune::MultiTypeBlockMatrix there is currently no generic way
536 // of handling parallelism, we therefore can only solve these types of systems sequentially
537 if constexpr (isMultiTypeBlockMatrix<Matrix>::value || !LinearSolverTraits::canCommunicate)
538 return sequentialAction();
539 else
540 {
541 switch (solverCategory_)
542 {
543 case Dune::SolverCategory::sequential:
544 return sequentialAction();
545 case Dune::SolverCategory::nonoverlapping:
546 using NOTraits = typename LinearSolverTraits::template ParallelNonoverlapping<Matrix, XVector>;
547 return parallelAction(NOTraits{});
548 case Dune::SolverCategory::overlapping:
549 using OTraits = typename LinearSolverTraits::template ParallelOverlapping<Matrix, XVector>;
550 return parallelAction(OTraits{});
551 default: DUNE_THROW(Dune::InvalidStateException, "Unknown solver category");
552 }
553 }
554#else
555 return sequentialAction();
556#endif
557 }
558
559#if HAVE_MPI
560 std::shared_ptr<const ParallelHelper> parallelHelper_;
561 std::shared_ptr<Comm> communication_;
562#endif
563
564 Dune::SolverCategory::Category solverCategory_;
565 std::shared_ptr<ScalarProduct> scalarProduct_;
566
567 // for stored solvers (reuse matrix)
568 MatrixOperatorHolder linearOperator_;
569 // for stored solvers (reuse matrix)
570 std::shared_ptr<InverseOperator> solver_;
571
572 Dune::ParameterTree params_;
573 std::string name_;
574};
575
576} // end namespace Dumux::Detail
577
578namespace Dumux {
579
596template<class LSTraits, class LATraits>
598 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
599 Dune::BiCGSTABSolver<typename LATraits::SingleTypeVector>,
601 // the Dune::ILU preconditioners don't accept multi-type matrices
602 /*convert multi-type istl types?*/ true
603 >;
604
621template<class LSTraits, class LATraits>
623 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
624 Dune::RestartedGMResSolver<typename LATraits::SingleTypeVector>,
626 // the Dune::ILU preconditioners don't accept multi-type matrices
627 /*convert multi-type istl types?*/ true
628 >;
629
647template<class LSTraits, class LATraits>
649 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
650 Dune::BiCGSTABSolver<typename LATraits::Vector>,
652 >;
653
670template<class LSTraits, class LATraits>
672 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
673 Dune::CGSolver<typename LATraits::Vector>,
675 >;
676
690template<class LSTraits, class LATraits>
692 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
693 Dune::BiCGSTABSolver<typename LATraits::SingleTypeVector>,
695 // the AMG preconditioner doesn't accept multi-type matrices
696 /*convert multi-type istl types?*/ true
697 >;
698
711template<class LSTraits, class LATraits>
713 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
714 Dune::CGSolver<typename LATraits::SingleTypeVector>,
716 // the AMG preconditioner doesn't accept multi-type matrices
717 /*convert multi-type istl types?*/ true
718 >;
719
734template<class LSTraits, class LATraits>
736 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
737 Dune::BiCGSTABSolver<typename LATraits::Vector>,
739 >;
740
741} // end namespace Dumux
742
743namespace Dumux::Detail {
744
749template<class LSTraits, class LATraits, template<class M> class Solver,
750 bool convertMultiTypeVectorAndMatrix = isMultiTypeBlockVector<typename LATraits::Vector>::value>
752{
753 using Matrix = typename LATraits::Matrix;
754 using XVector = typename LATraits::Vector;
755 using BVector = typename LATraits::Vector;
756
760 using InverseOperator = Dune::InverseOperator<XVectorForSolver, BVectorForSolver>;
761public:
763
767 IstlSolverResult solve(const Matrix& A, XVector& x, const BVector& b)
768 {
769 return solve_(A, x, b);
770 }
771
775 IstlSolverResult solve(XVector& x, const BVector& b)
776 {
777 if (!solver_)
778 DUNE_THROW(Dune::InvalidStateException, "Called solve(x, b) but no linear operator has been set");
779
780 return solve_(x, b, *solver_);
781 }
782
786 void setMatrix(std::shared_ptr<Matrix> A)
787 {
788 if constexpr (convertMultiTypeVectorAndMatrix)
789 matrix_ = std::make_shared<MatrixForSolver>(MatrixConverter<Matrix>::multiTypeToBCRSMatrix(A));
790 else
791 matrix_ = A;
792
793 solver_ = std::make_shared<Solver<MatrixForSolver>>(*matrix_);
794 }
795
800 void setMatrix(Matrix& A)
801 { setMatrix(Dune::stackobject_to_shared_ptr(A)); }
802
806 std::string name() const
807 {
808 return "Direct solver";
809 }
810
811private:
812 IstlSolverResult solve_(const Matrix& A, XVector& x, const BVector& b)
813 {
814 // support dune-istl multi-type block vector/matrix by copying
815 if constexpr (convertMultiTypeVectorAndMatrix)
816 {
818 Solver<MatrixForSolver> solver(AA, this->verbosity() > 0);
819 return solve_(x, b, solver);
820 }
821 else
822 {
823 Solver<MatrixForSolver> solver(A, this->verbosity() > 0);
824 return solve_(x, b, solver);
825 }
826 }
827
828 IstlSolverResult solve_(XVector& x, const BVector& b, InverseOperator& solver) const
829 {
830 Dune::InverseOperatorResult result;
831
832 if constexpr (convertMultiTypeVectorAndMatrix)
833 {
835 XVectorForSolver xx(bb.size());
836 solver.apply(xx, bb, result);
837 checkResult_(xx, result);
838 if (result.converged)
840 return result;
841 }
842 else
843 {
844 BVectorForSolver bTmp(b);
845 solver.apply(x, bTmp, result);
846 checkResult_(x, result);
847 return result;
848 }
849 }
850
851
852 void checkResult_(XVectorForSolver& x, Dune::InverseOperatorResult& result) const
853 {
854 flatVectorForEach(x, [&](auto&& entry, std::size_t){
855 using std::isnan, std::isinf;
856 if (isnan(entry) || isinf(entry))
857 result.converged = false;
858 });
859 }
860
862 std::shared_ptr<MatrixForSolver> matrix_;
864 std::shared_ptr<InverseOperator> solver_;
865};
866
867} // end namespace Dumux::Detail
868
869#if HAVE_SUPERLU
870#include <dune/istl/superlu.hh>
871
872namespace Dumux {
873
882template<class LSTraits, class LATraits>
883using SuperLUIstlSolver = Detail::DirectIstlSolver<LSTraits, LATraits, Dune::SuperLU>;
884
885} // end namespace Dumux
886
887#endif // HAVE_SUPERLU
888
889#if HAVE_UMFPACK
890#include <dune/istl/umfpack.hh>
891
892namespace Dumux {
893
902template<class LSTraits, class LATraits>
903using UMFPackIstlSolver = Detail::DirectIstlSolver<
904 LSTraits, LATraits, Dune::UMFPack
905#if DUNE_VERSION_GTE(DUNE_ISTL,2,10)
906 , false // no need to convert multi-type matrix anymore
907#endif
908>;
909
910} // end namespace Dumux
911
912#endif // HAVE_UMFPACK
913
914#endif
Direct dune-istl linear solvers.
Definition: istlsolvers.hh:752
void setMatrix(std::shared_ptr< Matrix > A)
Set the matrix A of the linear system Ax = b for reuse.
Definition: istlsolvers.hh:786
IstlSolverResult solve(const Matrix &A, XVector &x, const BVector &b)
Solve the linear system Ax = b.
Definition: istlsolvers.hh:767
std::string name() const
name of the linear solver
Definition: istlsolvers.hh:806
void setMatrix(Matrix &A)
Set the matrix A of the linear system Ax = b for reuse.
Definition: istlsolvers.hh:800
IstlSolverResult solve(XVector &x, const BVector &b)
Solve the linear system Ax = b using the matrix set with setMatrix.
Definition: istlsolvers.hh:775
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 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.