version 3.11-dev
Loading...
Searching...
No Matches
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 <type_traits>
17#include <variant>
18
19#include <dune/common/exceptions.hh>
20#include <dune/common/math.hh>
21#include <dune/common/shared_ptr.hh>
22#include <dune/common/version.hh>
23#include <dune/common/parallel/indexset.hh>
24#include <dune/common/parallel/mpicommunication.hh>
25#include <dune/grid/common/capabilities.hh>
26#include <dune/istl/solvers.hh>
27#include <dune/istl/solverfactory.hh>
28#include <dune/istl/owneroverlapcopy.hh>
29#include <dune/istl/scalarproducts.hh>
30#include <dune/istl/paamg/amg.hh>
31#include <dune/istl/paamg/pinfo.hh>
32
33#include <dumux/io/format.hh>
43
44#include <dune/istl/foreach.hh>
45
47
54template<class M>
55constexpr std::size_t preconditionerBlockLevel() noexcept
56{
58}
59
60template<template<class,class,class,int> class Preconditioner, int blockLevel = 1>
62{
63public:
64 template<class OI, class M>
65 auto operator() (OI opInfo, const M& matrix, const Dune::ParameterTree& config)
66 {
67#if DUNE_VERSION_LT(DUNE_ISTL,2,11)
68 using Matrix = typename Dune::TypeListElement<0, decltype(opInfo)>::type;
69 using Domain = typename Dune::TypeListElement<1, decltype(opInfo)>::type;
70 using Range = typename Dune::TypeListElement<2, decltype(opInfo)>::type;
71#else
72 using OpInfo = std::decay_t<decltype(opInfo)>;
73 using Matrix = typename OpInfo::matrix_type;
74 using Domain = typename OpInfo::domain_type;
75 using Range = typename OpInfo::range_type;
76#endif
77 std::shared_ptr<Dune::Preconditioner<Domain, Range>> preconditioner
78 = std::make_shared<Preconditioner<Matrix, Domain, Range, blockLevel>>(matrix, config);
79 return preconditioner;
80 }
81};
82
83template<template<class,class,class> class Preconditioner>
85{
86 template<class OI, class M>
87 auto operator() (OI opInfo, const M& matrix, const Dune::ParameterTree& config)
88 {
89#if DUNE_VERSION_LT(DUNE_ISTL,2,11)
90 using Matrix = typename Dune::TypeListElement<0, decltype(opInfo)>::type;
91 using Domain = typename Dune::TypeListElement<1, decltype(opInfo)>::type;
92 using Range = typename Dune::TypeListElement<2, decltype(opInfo)>::type;
93#else
94 using OpInfo = std::decay_t<decltype(opInfo)>;
95 using Matrix = typename OpInfo::matrix_type;
96 using Domain = typename OpInfo::domain_type;
97 using Range = typename OpInfo::range_type;
98#endif
99 std::shared_ptr<Dune::Preconditioner<Domain, Range>> preconditioner
100 = std::make_shared<Preconditioner<Matrix, Domain, Range>>(matrix, config);
101 return preconditioner;
102 }
103};
104
105using IstlAmgPreconditionerFactory = Dune::AMGCreator;
106
107template<class M, bool convert = false>
108struct MatrixForSolver { using type = M; };
109
110template<class M>
111struct MatrixForSolver<M, true>
112{ using type = std::decay_t<decltype(MatrixConverter<M>::multiTypeToBCRSMatrix(std::declval<M>()))>; };
113
114template<class V, bool convert = false>
115struct VectorForSolver { using type = V; };
116
117template<class V>
118struct VectorForSolver<V, true>
119{ using type = std::decay_t<decltype(VectorConverter<V>::multiTypeToBlockVector(std::declval<V>()))>; };
120
121template<class LSTraits, class LATraits, bool convert, bool parallel = LSTraits::canCommunicate>
123
124template<class LSTraits, class LATraits, bool convert>
125struct MatrixOperator<LSTraits, LATraits, convert, true>
126{
129#if HAVE_MPI
130 using type = std::variant<
131 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>,
132 std::shared_ptr<typename LSTraits::template ParallelOverlapping<M, V>::LinearOperator>,
133 std::shared_ptr<typename LSTraits::template ParallelNonoverlapping<M, V>::LinearOperator>
134 >;
135#else
136 using type = std::variant<
137 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>
138 >;
139#endif
140};
141
142template<class LSTraits, class LATraits, bool convert>
143struct MatrixOperator<LSTraits, LATraits, convert, false>
144{
147 using type = std::variant<
148 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>
149 >;
150};
151
152} // end namespace Dumux::Detail::IstlSolvers
153
154namespace Dumux::Detail {
155
156struct IstlSolverResult : public Dune::InverseOperatorResult
157{
158 IstlSolverResult() = default;
161
162 IstlSolverResult(const Dune::InverseOperatorResult& o) : InverseOperatorResult(o) {}
163 IstlSolverResult(Dune::InverseOperatorResult&& o) : InverseOperatorResult(std::move(o)) {}
164
165 operator bool() const { return this->converged; }
166};
167
172template<class LinearSolverTraits, class LinearAlgebraTraits,
173 class InverseOperator, class PreconditionerFactory,
174 bool convertMultiTypeLATypes = false>
176{
177 using Matrix = typename LinearAlgebraTraits::Matrix;
178 using XVector = typename LinearAlgebraTraits::Vector;
179 using BVector = typename LinearAlgebraTraits::Vector;
180 using Scalar = typename InverseOperator::real_type;
181
182 using ScalarProduct = Dune::ScalarProduct<typename InverseOperator::domain_type>;
183
184 static constexpr bool convertMultiTypeVectorAndMatrix
185 = convertMultiTypeLATypes && isMultiTypeBlockVector<XVector>::value;
189 // a variant type that can hold sequential, overlapping, and non-overlapping operators
190 using MatrixOperatorHolder = typename Detail::IstlSolvers::MatrixOperator<
191 LinearSolverTraits, LinearAlgebraTraits, convertMultiTypeVectorAndMatrix
192 >::type;
193
194#if HAVE_MPI
195 using Comm = Dune::OwnerOverlapCopyCommunication<Dune::bigunsignedint<96>, int>;
196 using ParallelHelper = ParallelISTLHelper<LinearSolverTraits>;
197#endif
198
199 using ParameterInitializer = std::variant<std::string, Dune::ParameterTree>;
200public:
201
205 IstlIterativeLinearSolver(const ParameterInitializer& params = "")
206 {
207 if (Dune::MPIHelper::getCommunication().size() > 1)
208 DUNE_THROW(Dune::InvalidStateException, "Using sequential constructor for parallel run. Use signature with gridView and dofMapper!");
209
210 initializeParameters_(params);
211 solverCategory_ = Dune::SolverCategory::sequential;
212 scalarProduct_ = std::make_shared<ScalarProduct>();
213 }
214
218 template <class GridView, class DofMapper>
219 IstlIterativeLinearSolver(const GridView& gridView,
220 const DofMapper& dofMapper,
221 const ParameterInitializer& params = "")
222 {
223 initializeParameters_(params, gridView.comm());
224 configureCommunication_(gridView, dofMapper);
225 }
226
227#if HAVE_MPI
231 template <class GridView, class DofMapper>
232 IstlIterativeLinearSolver(std::shared_ptr<Comm> communication,
233 std::shared_ptr<ScalarProduct> scalarProduct,
234 const GridView& gridView,
235 const DofMapper& dofMapper,
236 const ParameterInitializer& params = "")
237 {
238 initializeParameters_(params, gridView.comm());
239 solverCategory_ = Detail::solverCategory(gridView);
240 scalarProduct_ = scalarProduct;
241 communication_ = communication;
242 if constexpr (LinearSolverTraits::canCommunicate)
243 {
244 if (solverCategory_ != Dune::SolverCategory::sequential)
245 buildParallelHelper_(gridView, dofMapper, *communication_);
246 }
247 }
248#endif
249
258 template <class GridView, class DofMapper>
259 void updateAfterGridAdaption(const GridView& gridView, const DofMapper& dofMapper)
260 { configureCommunication_(gridView, dofMapper); }
261
265 IstlSolverResult solve(Matrix& A, XVector& x, BVector& b)
266 { return solveSequentialOrParallel_(A, x, b); }
267
271 void setMatrix(std::shared_ptr<Matrix> A)
272 {
273 linearOperator_ = makeParallelOrSequentialLinearOperator_(std::move(A));
274 solver_ = constructPreconditionedSolver_(linearOperator_);
275 }
276
281 void setMatrix(Matrix& A)
282 { setMatrix(Dune::stackobject_to_shared_ptr(A)); }
283
287 IstlSolverResult solve(XVector& x, BVector& b) const
288 {
289 if (!solver_)
290 DUNE_THROW(Dune::InvalidStateException, "Called solve(x, b) but no linear operator has been set");
291
292 return solveSequentialOrParallel_(x, b, *solver_);
293 }
294
298 Scalar norm(const XVector& x) const
299 {
300#if HAVE_MPI
301 if constexpr (LinearSolverTraits::canCommunicate)
302 {
303 if (solverCategory_ == Dune::SolverCategory::nonoverlapping)
304 {
305 auto y(x); // make a copy because the vector needs to be made consistent
306 using GV = typename LinearSolverTraits::GridView;
307 using DM = typename LinearSolverTraits::DofMapper;
308 if constexpr (requires { LinearSolverTraits::dofCodims; })
309 {
310 MultiCodimParallelVectorHelper<GV, DM> vectorHelper(parallelHelper_->gridView(), parallelHelper_->dofMapper());
311 vectorHelper.makeNonOverlappingConsistent(y, LinearSolverTraits::dofCodims);
312 }
313 else
314 {
315 ParallelVectorHelper<GV, DM, LinearSolverTraits::dofCodim> vectorHelper(parallelHelper_->gridView(), parallelHelper_->dofMapper());
316 vectorHelper.makeNonOverlappingConsistent(y);
317 }
318 return scalarProduct_->norm(y);
319 }
320 }
321#endif
322 if constexpr (convertMultiTypeVectorAndMatrix)
323 {
325 return scalarProduct_->norm(y);
326 }
327 else
328 return scalarProduct_->norm(x);
329 }
330
334 const std::string& name() const
335 {
336 return name_;
337 }
338
342 void setResidualReduction(double residReduction)
343 {
344 params_["reduction"] = Fmt::format("{}", residReduction);
345
346 // reconstruct the solver with new parameters
347 if (solver_)
348 solver_ = constructPreconditionedSolver_(linearOperator_);
349 }
350
354 void setMaxIter(std::size_t maxIter)
355 {
356 params_["maxit"] = std::to_string(maxIter);
357
358 // reconstruct the solver with new parameters
359 if (solver_)
360 solver_ = constructPreconditionedSolver_(linearOperator_);
361 }
362
368 void setParams(const ParameterInitializer& params)
369 {
370#if HAVE_MPI
371 if (communication_)
372 initializeParameters_(params, communication_->communicator());
373 else
374 initializeParameters_(params);
375#else
376 initializeParameters_(params);
377#endif
378
379 // reconstruct the solver with new parameters
380 if (solver_)
381 solver_ = constructPreconditionedSolver_(linearOperator_);
382 }
383
384private:
385
386 void initializeParameters_(const ParameterInitializer& params)
387 {
388 if (std::holds_alternative<std::string>(params))
389 params_ = Dumux::LinearSolverParameters<LinearSolverTraits>::createParameterTree(std::get<std::string>(params));
390 else
391 params_ = std::get<Dune::ParameterTree>(params);
392 }
393
394 template <class Comm>
395 void initializeParameters_(const ParameterInitializer& params, const Comm& comm)
396 {
397 initializeParameters_(params);
398
399 // disable verbose output on all ranks except rank 0
400 if (comm.rank() != 0)
402 }
403
410 template <class GridView, class DofMapper>
411 void configureCommunication_(const GridView& gridView, const DofMapper& dofMapper)
412 {
413#if HAVE_MPI
414 solverCategory_ = Detail::solverCategory<LinearSolverTraits>(gridView);
415 if constexpr (LinearSolverTraits::canCommunicate)
416 {
417 if (solverCategory_ == Dune::SolverCategory::sequential)
418 scalarProduct_ = std::make_shared<ScalarProduct>();
419 else
420 {
421 communication_ = std::make_shared<Comm>(gridView.comm(), solverCategory_);
422 scalarProduct_ = Dune::createScalarProduct<XVector>(*communication_, solverCategory_);
423 buildParallelHelper_(gridView, dofMapper, *communication_);
424 }
425 }
426 else
427 scalarProduct_ = std::make_shared<ScalarProduct>();
428#else
429 solverCategory_ = Dune::SolverCategory::sequential;
430 scalarProduct_ = std::make_shared<ScalarProduct>();
431#endif
432 linearOperator_ = MatrixOperatorHolder{};
433 solver_ = nullptr;
434 }
435
436#if HAVE_MPI
438 template <class GridView, class DofMapper>
439 void buildParallelHelper_(const GridView& gridView, const DofMapper& dofMapper, Comm& comm)
440 {
441 parallelHelper_ = std::make_shared<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
442 parallelHelper_->createParallelIndexSet(comm);
443 }
444#endif
445
446 MatrixOperatorHolder makeSequentialLinearOperator_(std::shared_ptr<Matrix> A)
447 {
448 using SequentialTraits = typename LinearSolverTraits::template Sequential<MatrixForSolver, XVectorForSolver>;
449 if constexpr (convertMultiTypeVectorAndMatrix)
450 {
451 // create the BCRS matrix the IterativeSolver backend can handle
452 auto M = std::make_shared<MatrixForSolver>(MatrixConverter<Matrix>::multiTypeToBCRSMatrix(*A));
453 return std::make_shared<typename SequentialTraits::LinearOperator>(M);
454 }
455 else
456 {
457 return std::make_shared<typename SequentialTraits::LinearOperator>(A);
458 }
459 }
460
461 template<class ParallelTraits>
462 MatrixOperatorHolder makeParallelLinearOperator_(std::shared_ptr<Matrix> A, ParallelTraits = {})
463 {
464#if HAVE_MPI
465 // make matrix consistent
467 return std::make_shared<typename ParallelTraits::LinearOperator>(std::move(A), *communication_);
468#else
469 DUNE_THROW(Dune::InvalidStateException, "Calling makeParallelLinearOperator for sequential run");
470#endif
471 }
472
473 MatrixOperatorHolder makeParallelOrSequentialLinearOperator_(std::shared_ptr<Matrix> A)
474 {
475 return executeSequentialOrParallel_(
476 [&]{ return makeSequentialLinearOperator_(std::move(A)); },
477 [&](auto traits){ return makeParallelLinearOperator_(std::move(A), traits); }
478 );
479 }
480
481 MatrixOperatorHolder makeSequentialLinearOperator_(Matrix& A)
482 { return makeSequentialLinearOperator_(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
483
484 MatrixOperatorHolder makeParallelOrSequentialLinearOperator_(Matrix& A)
485 { return makeParallelOrSequentialLinearOperator_(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
486
487 template<class ParallelTraits>
488 MatrixOperatorHolder makeParallelLinearOperator_(Matrix& A, ParallelTraits = {})
489 { return makeParallelLinearOperator_<ParallelTraits>(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
490
491 IstlSolverResult solveSequential_(Matrix& A, XVector& x, BVector& b)
492 {
493 // construct solver from linear operator
494 auto linearOperatorHolder = makeSequentialLinearOperator_(A);
495 auto solver = constructPreconditionedSolver_(linearOperatorHolder);
496
497 return solveSequential_(x, b, *solver);
498 }
499
500 IstlSolverResult solveSequential_(XVector& x, BVector& b, InverseOperator& solver) const
501 {
502 Dune::InverseOperatorResult result;
503 if constexpr (convertMultiTypeVectorAndMatrix)
504 {
505 // create the vector the IterativeSolver backend can handle
506 BVectorForSolver bTmp = VectorConverter<BVector>::multiTypeToBlockVector(b);
507
508 // create a block vector to which the linear solver writes the solution
509 XVectorForSolver y(bTmp.size());
510
511 // solve linear system
512 solver.apply(y, bTmp, result);
513
514 // copy back the result y into x
515 if (result.converged)
517 }
518 else
519 {
520 // solve linear system
521 solver.apply(x, b, result);
522 }
523
524 return result;
525 }
526
527 IstlSolverResult solveSequentialOrParallel_(Matrix& A, XVector& x, BVector& b)
528 {
529 return executeSequentialOrParallel_(
530 [&]{ return solveSequential_(A, x, b); },
531 [&](auto traits){ return solveParallel_(A, x, b, traits); }
532 );
533 }
534
535 IstlSolverResult solveSequentialOrParallel_(XVector& x, BVector& b, InverseOperator& solver) const
536 {
537 return executeSequentialOrParallel_(
538 [&]{ return solveSequential_(x, b, solver); },
539 [&](auto traits){ return solveParallel_(x, b, solver, traits); }
540 );
541 }
542
543 template<class ParallelTraits>
544 IstlSolverResult solveParallel_(Matrix& A, XVector& x, BVector& b, ParallelTraits = {})
545 {
546 // construct solver from linear operator
547 auto linearOperatorHolder = makeParallelLinearOperator_<ParallelTraits>(A);
548 auto solver = constructPreconditionedSolver_(linearOperatorHolder);
549 return solveParallel_<ParallelTraits>(x, b, *solver);
550 }
551
552 template<class ParallelTraits>
553 IstlSolverResult solveParallel_(XVector& x, BVector& b, InverseOperator& solver, ParallelTraits = {}) const
554 {
555#if HAVE_MPI
556 // make right hand side consistent
558
559 // solve linear system
560 Dune::InverseOperatorResult result;
561 solver.apply(x, b, result);
562 return result;
563#else
564 DUNE_THROW(Dune::InvalidStateException, "Calling makeParallelLinearOperator for sequential run");
565#endif
566 }
567
568
569 std::shared_ptr<InverseOperator> constructPreconditionedSolver_(MatrixOperatorHolder& ops)
570 {
571 return std::visit([&](auto&& op)
572 {
573 using LinearOperator = typename std::decay_t<decltype(op)>::element_type;
574 const auto& params = params_.sub("preconditioner");
575 using Prec = Dune::Preconditioner<typename LinearOperator::domain_type, typename LinearOperator::range_type>;
576#if DUNE_VERSION_GTE(DUNE_ISTL,2,11)
577 using OpTraits = Dune::OperatorTraits<LinearOperator>;
578 std::shared_ptr<Prec> prec = PreconditionerFactory{}(OpTraits{}, op, params);
579#else
580 using TL = Dune::TypeList<typename LinearOperator::matrix_type, typename LinearOperator::domain_type, typename LinearOperator::range_type>;
581 std::shared_ptr<Prec> prec = PreconditionerFactory{}(TL{}, op, params);
582#endif
583
584#if HAVE_MPI
585#if DUNE_VERSION_LT(DUNE_ISTL,2,11)
586 if (prec->category() != op->category() && prec->category() == Dune::SolverCategory::sequential)
587 prec = Dune::wrapPreconditioner4Parallel(prec, op);
588#else
589 if constexpr (OpTraits::isParallel)
590 {
591 using Comm = typename OpTraits::comm_type;
592 const Comm& comm = OpTraits::getCommOrThrow(op);
593 if (op->category() == Dune::SolverCategory::overlapping && prec->category() == Dune::SolverCategory::sequential)
594 prec = std::make_shared<Dune::BlockPreconditioner<typename OpTraits::domain_type, typename OpTraits::range_type,Comm> >(prec, comm);
595 else if (op->category() == Dune::SolverCategory::nonoverlapping && prec->category() == Dune::SolverCategory::sequential)
596 prec = std::make_shared<Dune::NonoverlappingBlockPreconditioner<Comm, Prec> >(prec, comm);
597 }
598#endif
599#endif
600 return std::make_shared<InverseOperator>(op, scalarProduct_, prec, params_);
601 }, ops);
602 }
603
604 template<class Seq, class Par>
605 decltype(auto) executeSequentialOrParallel_(Seq&& sequentialAction, Par&& parallelAction) const
606 {
607#if HAVE_MPI
608 // For Dune::MultiTypeBlockMatrix there is currently no generic way
609 // of handling parallelism, we therefore can only solve these types of systems sequentially
610 if constexpr (isMultiTypeBlockMatrix<Matrix>::value || !LinearSolverTraits::canCommunicate)
611 return sequentialAction();
612 else
613 {
614 switch (solverCategory_)
615 {
616 case Dune::SolverCategory::sequential:
617 return sequentialAction();
618 case Dune::SolverCategory::nonoverlapping:
619 using NOTraits = typename LinearSolverTraits::template ParallelNonoverlapping<Matrix, XVector>;
620 return parallelAction(NOTraits{});
621 case Dune::SolverCategory::overlapping:
622 using OTraits = typename LinearSolverTraits::template ParallelOverlapping<Matrix, XVector>;
623 return parallelAction(OTraits{});
624 default: DUNE_THROW(Dune::InvalidStateException, "Unknown solver category");
625 }
626 }
627#else
628 return sequentialAction();
629#endif
630 }
631
632#if HAVE_MPI
633 std::shared_ptr<const ParallelHelper> parallelHelper_;
634 std::shared_ptr<Comm> communication_;
635#endif
636
637 Dune::SolverCategory::Category solverCategory_;
638 std::shared_ptr<ScalarProduct> scalarProduct_;
639
640 // for stored solvers (reuse matrix)
641 MatrixOperatorHolder linearOperator_;
642 // for stored solvers (reuse matrix)
643 std::shared_ptr<InverseOperator> solver_;
644
645 Dune::ParameterTree params_;
646 std::string name_;
647};
648
649} // end namespace Dumux::Detail
650
651namespace Dumux {
652
669template<class LSTraits, class LATraits>
671 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
672 Dune::BiCGSTABSolver<typename LATraits::SingleTypeVector>,
674 // the Dune::ILU preconditioners don't accept multi-type matrices
675 /*convert multi-type istl types?*/ true
676 >;
677
694template<class LSTraits, class LATraits>
696 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
697 Dune::RestartedGMResSolver<typename LATraits::SingleTypeVector>,
699 // the Dune::ILU preconditioners don't accept multi-type matrices
700 /*convert multi-type istl types?*/ true
701 >;
702
720template<class LSTraits, class LATraits>
722 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
723 Dune::BiCGSTABSolver<typename LATraits::Vector>,
725 >;
726
743template<class LSTraits, class LATraits>
745 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
746 Dune::CGSolver<typename LATraits::Vector>,
748 >;
749
763template<class LSTraits, class LATraits>
765 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
766 Dune::BiCGSTABSolver<typename LATraits::SingleTypeVector>,
768 // the AMG preconditioner doesn't accept multi-type matrices
769 /*convert multi-type istl types?*/ true
770 >;
771
784template<class LSTraits, class LATraits>
786 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
787 Dune::CGSolver<typename LATraits::SingleTypeVector>,
789 // the AMG preconditioner doesn't accept multi-type matrices
790 /*convert multi-type istl types?*/ true
791 >;
792
808template<class LSTraits, class LATraits>
810 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
811 Dune::RestartedGMResSolver<typename LATraits::SingleTypeVector>,
813 // the AMG preconditioner doesn't accept multi-type matrices
814 /*convert multi-type istl types?*/ true
815 >;
816
831template<class LSTraits, class LATraits>
833 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
834 Dune::BiCGSTABSolver<typename LATraits::Vector>,
836 >;
837
838} // end namespace Dumux
839
840namespace Dumux::Detail {
841
846template<class LSTraits, class LATraits, template<class M> class Solver,
847 bool convertMultiTypeVectorAndMatrix = isMultiTypeBlockVector<typename LATraits::Vector>::value>
849{
850 using Matrix = typename LATraits::Matrix;
851 using XVector = typename LATraits::Vector;
852 using BVector = typename LATraits::Vector;
853
857 using InverseOperator = Dune::InverseOperator<XVectorForSolver, BVectorForSolver>;
858public:
860
864 IstlSolverResult solve(const Matrix& A, XVector& x, const BVector& b)
865 {
866 return solve_(A, x, b);
867 }
868
872 IstlSolverResult solve(XVector& x, const BVector& b)
873 {
874 if (!solver_)
875 DUNE_THROW(Dune::InvalidStateException, "Called solve(x, b) but no linear operator has been set");
876
877 return solve_(x, b, *solver_);
878 }
879
883 void setMatrix(std::shared_ptr<Matrix> A)
884 {
885 if constexpr (convertMultiTypeVectorAndMatrix)
886 matrix_ = std::make_shared<MatrixForSolver>(MatrixConverter<Matrix>::multiTypeToBCRSMatrix(A));
887 else
888 matrix_ = A;
889
890 solver_ = std::make_shared<Solver<MatrixForSolver>>(*matrix_);
891 }
892
897 void setMatrix(Matrix& A)
898 { setMatrix(Dune::stackobject_to_shared_ptr(A)); }
899
903 std::string name() const
904 {
905 return "Direct solver";
906 }
907
908private:
909 IstlSolverResult solve_(const Matrix& A, XVector& x, const BVector& b)
910 {
911 // support dune-istl multi-type block vector/matrix by copying
912 if constexpr (convertMultiTypeVectorAndMatrix)
913 {
915 Solver<MatrixForSolver> solver(AA, this->verbosity() > 0);
916 return solve_(x, b, solver);
917 }
918 else
919 {
920 Solver<MatrixForSolver> solver(A, this->verbosity() > 0);
921 return solve_(x, b, solver);
922 }
923 }
924
925 IstlSolverResult solve_(XVector& x, const BVector& b, InverseOperator& solver) const
926 {
927 Dune::InverseOperatorResult result;
928
929 if constexpr (convertMultiTypeVectorAndMatrix)
930 {
932 XVectorForSolver xx(bb.size());
933 solver.apply(xx, bb, result);
934 checkResult_(xx, result);
935 if (result.converged)
937 return result;
938 }
939 else
940 {
941 BVectorForSolver bTmp(b);
942 solver.apply(x, bTmp, result);
943 checkResult_(x, result);
944 return result;
945 }
946 }
947
948
949 void checkResult_(XVectorForSolver& x, Dune::InverseOperatorResult& result) const
950 {
951 flatVectorForEach(x, [&](auto&& entry, std::size_t){
952 if (Dune::isNaN(entry) || Dune::isInf(entry))
953 result.converged = false;
954 });
955 }
956
958 std::shared_ptr<MatrixForSolver> matrix_;
960 std::shared_ptr<InverseOperator> solver_;
961};
962
963} // end namespace Dumux::Detail
964
965#if HAVE_SUPERLU
966#include <dune/istl/superlu.hh>
967
968namespace Dumux {
969
978template<class LSTraits, class LATraits>
980
981} // end namespace Dumux
982
983#endif // HAVE_SUPERLU
984
985#if HAVE_UMFPACK
986#include <dune/istl/umfpack.hh>
987
988namespace Dumux {
989
998template<class LSTraits, class LATraits>
1000
1001} // end namespace Dumux
1002
1003#endif // HAVE_UMFPACK
1004
1005#endif
Direct dune-istl linear solvers.
Definition istlsolvers.hh:849
void setMatrix(std::shared_ptr< Matrix > A)
Set the matrix A of the linear system Ax = b for reuse.
Definition istlsolvers.hh:883
IstlSolverResult solve(const Matrix &A, XVector &x, const BVector &b)
Solve the linear system Ax = b.
Definition istlsolvers.hh:864
std::string name() const
name of the linear solver
Definition istlsolvers.hh:903
void setMatrix(Matrix &A)
Set the matrix A of the linear system Ax = b for reuse.
Definition istlsolvers.hh:897
LinearSolver(const std::string &paramGroup="")
Construct the solver.
Definition solver.hh:43
IstlSolverResult solve(XVector &x, const BVector &b)
Solve the linear system Ax = b using the matrix set with setMatrix.
Definition istlsolvers.hh:872
Standard dune-istl iterative linear solvers.
Definition istlsolvers.hh:176
IstlIterativeLinearSolver(const ParameterInitializer &params="")
Constructor for sequential solvers.
Definition istlsolvers.hh:205
void setMatrix(Matrix &A)
Set the matrix A of the linear system Ax = b for reuse.
Definition istlsolvers.hh:281
void setResidualReduction(double residReduction)
Set the residual reduction tolerance.
Definition istlsolvers.hh:342
void setMaxIter(std::size_t maxIter)
Set the maximum number of linear solver iterations.
Definition istlsolvers.hh:354
IstlIterativeLinearSolver(const GridView &gridView, const DofMapper &dofMapper, const ParameterInitializer &params="")
Constructor for parallel and sequential solvers.
Definition istlsolvers.hh:219
const std::string & name() const
The name of the linear solver.
Definition istlsolvers.hh:334
void setParams(const ParameterInitializer &params)
Set the linear solver parameters.
Definition istlsolvers.hh:368
IstlSolverResult solve(Matrix &A, XVector &x, BVector &b)
Solve the linear system Ax = b.
Definition istlsolvers.hh:265
void updateAfterGridAdaption(const GridView &gridView, const DofMapper &dofMapper)
Update the solver after the grid and its dof distribution changed, e.g. after grid adaption or dynami...
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:271
IstlSolverResult solve(XVector &x, BVector &b) const
Solve the linear system Ax = b where A has been set with setMatrix.
Definition istlsolvers.hh:287
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:232
Scalar norm(const XVector &x) const
Compute the 2-norm of vector x.
Definition istlsolvers.hh:298
auto operator()(OI opInfo, const M &matrix, const Dune::ParameterTree &config)
Definition istlsolvers.hh:65
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
static auto multiTypeToBCRSMatrix(const MultiTypeBlockMatrix &A)
Converts the matrix to a type the IterativeSolverBackend can handle.
Definition matrixconverter.hh:47
Definition parallelhelpers.hh:579
void makeNonOverlappingConsistent(Dune::BlockVector< Block, Alloc > &v, const std::bitset< numCodims > &activeCodims) const
Make a vector consistent for non-overlapping domain decomposition methods.
Definition parallelhelpers.hh:587
Definition parallelhelpers.hh:521
void makeNonOverlappingConsistent(Dune::BlockVector< Block, Alloc > &v) const
Make a vector consistent for non-overlapping domain decomposition methods.
Definition parallelhelpers.hh:529
static void retrieveValues(MultiTypeBlockVector &x, const BlockVector &y)
Copies the entries of a Dune::BlockVector to a Dune::MultiTypeBlockVector.
Definition matrixconverter.hh:232
static auto multiTypeToBlockVector(const MultiTypeBlockVector &b)
Converts a Dune::MultiTypeBlockVector to a plain 1x1 Dune::BlockVector.
Definition matrixconverter.hh:206
Formatting based on the fmt-library which implements std::format of C++20.
Detail::IstlIterativeLinearSolver< LSTraits, LATraits, Dune::BiCGSTABSolver< typename LATraits::Vector >, Detail::IstlSolvers::IstlDefaultBlockLevelPreconditionerFactory< Dumux::SeqUzawa > > UzawaBiCGSTABIstlSolver
An Uzawa preconditioned BiCGSTAB solver using dune-istl.
Definition istlsolvers.hh:832
constexpr std::size_t preconditionerBlockLevel() noexcept
Returns the block level for the preconditioner for a given matrix.
Definition istlsolvers.hh:55
Detail::IstlIterativeLinearSolver< LSTraits, LATraits, Dune::RestartedGMResSolver< typename LATraits::SingleTypeVector >, Detail::IstlSolvers::IstlDefaultBlockLevelPreconditionerFactory< Dune::SeqILU >, true > ILURestartedGMResIstlSolver
An ILU preconditioned GMres solver using dune-istl.
Definition istlsolvers.hh:695
Detail::IstlIterativeLinearSolver< LSTraits, LATraits, Dune::BiCGSTABSolver< typename LATraits::Vector >, Detail::IstlSolvers::IstlDefaultBlockLevelPreconditionerFactory< Dune::SeqSSOR > > SSORBiCGSTABIstlSolver
An SSOR-preconditioned BiCGSTAB solver using dune-istl.
Definition istlsolvers.hh:721
Detail::IstlIterativeLinearSolver< LSTraits, LATraits, Dune::RestartedGMResSolver< typename LATraits::SingleTypeVector >, Detail::IstlSolvers::IstlAmgPreconditionerFactory, true > AMGRestartedGMResIstlSolver
An AMG preconditioned GMRes solver using dune-istl.
Definition istlsolvers.hh:809
Detail::IstlIterativeLinearSolver< LSTraits, LATraits, Dune::BiCGSTABSolver< typename LATraits::SingleTypeVector >, Detail::IstlSolvers::IstlDefaultBlockLevelPreconditionerFactory< Dune::SeqILU >, true > ILUBiCGSTABIstlSolver
An ILU preconditioned BiCGSTAB solver using dune-istl.
Definition istlsolvers.hh:670
Detail::IstlIterativeLinearSolver< LSTraits, LATraits, Dune::BiCGSTABSolver< typename LATraits::SingleTypeVector >, Detail::IstlSolvers::IstlAmgPreconditionerFactory, true > AMGBiCGSTABIstlSolver
An AMG preconditioned BiCGSTAB solver using dune-istl.
Definition istlsolvers.hh:764
Detail::ParallelISTLHelperImpl< LinearSolverTraits, LinearSolverTraits::canCommunicate > ParallelISTLHelper
A parallel helper class providing a parallel decomposition of all degrees of freedom.
Definition parallelhelpers.hh:514
Detail::IstlIterativeLinearSolver< LSTraits, LATraits, Dune::CGSolver< typename LATraits::SingleTypeVector >, Detail::IstlSolvers::IstlAmgPreconditionerFactory, true > AMGCGIstlSolver
An AMG preconditioned CG solver using dune-istl.
Definition istlsolvers.hh:785
Detail::IstlIterativeLinearSolver< LSTraits, LATraits, Dune::CGSolver< typename LATraits::Vector >, Detail::IstlSolvers::IstlDefaultBlockLevelPreconditionerFactory< Dune::SeqSSOR > > SSORCGIstlSolver
An SSOR-preconditioned CG solver using dune-istl.
Definition istlsolvers.hh:744
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:46
Dune::AMGCreator IstlAmgPreconditionerFactory
Definition istlsolvers.hh:105
Definition linearalgebratraits.hh:21
Definition cvfelocalresidual.hh:25
Dune::SolverCategory::Category solverCategory(const GridView &gridView)
Definition solvercategory.hh:20
Definition adapt.hh:17
void prepareMatrixParallel(Matrix &A, ParallelHelper &pHelper)
Prepare a matrix for parallel solvers.
Definition parallelhelpers.hh:1410
LinearSolverTraitsImpl< GridGeometry, typename GridGeometry::DiscretizationMethod > LinearSolverTraits
The type traits required for using the IstlFactoryBackend.
Definition linearsolvertraits.hh:39
void prepareVectorParallel(Vector &b, ParallelHelper &pHelper)
Prepare a vector for parallel solvers.
Definition parallelhelpers.hh:1441
Provides a helper class for nonoverlapping decomposition.
Dumux preconditioners for iterative solvers.
Base class for linear solvers.
Solver category.
Definition istlsolvers.hh:157
IstlSolverResult(IstlSolverResult &&)=default
IstlSolverResult(const Dune::InverseOperatorResult &o)
Definition istlsolvers.hh:162
IstlSolverResult(Dune::InverseOperatorResult &&o)
Definition istlsolvers.hh:163
IstlSolverResult(const IstlSolverResult &)=default
std::decay_t< decltype(MatrixConverter< M >::multiTypeToBCRSMatrix(std::declval< M >()))> type
Definition istlsolvers.hh:112
Definition istlsolvers.hh:108
M type
Definition istlsolvers.hh:108
typename VectorForSolver< typename LATraits::Vector, convert >::type V
Definition istlsolvers.hh:146
std::variant< std::shared_ptr< typename LSTraits::template Sequential< M, V >::LinearOperator > > type
Definition istlsolvers.hh:147
typename MatrixForSolver< typename LATraits::Matrix, convert >::type M
Definition istlsolvers.hh:145
typename VectorForSolver< typename LATraits::Vector, convert >::type V
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:130
typename MatrixForSolver< typename LATraits::Matrix, convert >::type M
Definition istlsolvers.hh:127
Definition istlsolvers.hh:122
std::decay_t< decltype(VectorConverter< V >::multiTypeToBlockVector(std::declval< V >()))> type
Definition istlsolvers.hh:119
Definition istlsolvers.hh:115
V type
Definition istlsolvers.hh:115
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.