version 3.11-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-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 OI, class M>
62 auto operator() (OI opInfo, const M& matrix, const Dune::ParameterTree& config)
63 {
64#if DUNE_VERSION_LT(DUNE_ISTL,2,11)
65 using Matrix = typename Dune::TypeListElement<0, decltype(opInfo)>::type;
66 using Domain = typename Dune::TypeListElement<1, decltype(opInfo)>::type;
67 using Range = typename Dune::TypeListElement<2, decltype(opInfo)>::type;
68#else
69 using OpInfo = std::decay_t<decltype(opInfo)>;
70 using Matrix = typename OpInfo::matrix_type;
71 using Domain = typename OpInfo::domain_type;
72 using Range = typename OpInfo::range_type;
73#endif
74 std::shared_ptr<Dune::Preconditioner<Domain, Range>> preconditioner
75 = std::make_shared<Preconditioner<Matrix, Domain, Range, blockLevel>>(matrix, config);
76 return preconditioner;
77 }
78};
79
80template<template<class,class,class> class Preconditioner>
82{
83 template<class OI, class M>
84 auto operator() (OI opInfo, const M& matrix, const Dune::ParameterTree& config)
85 {
86#if DUNE_VERSION_LT(DUNE_ISTL,2,11)
87 using Matrix = typename Dune::TypeListElement<0, decltype(opInfo)>::type;
88 using Domain = typename Dune::TypeListElement<1, decltype(opInfo)>::type;
89 using Range = typename Dune::TypeListElement<2, decltype(opInfo)>::type;
90#else
91 using OpInfo = std::decay_t<decltype(opInfo)>;
92 using Matrix = typename OpInfo::matrix_type;
93 using Domain = typename OpInfo::domain_type;
94 using Range = typename OpInfo::range_type;
95#endif
96 std::shared_ptr<Dune::Preconditioner<Domain, Range>> preconditioner
97 = std::make_shared<Preconditioner<Matrix, Domain, Range>>(matrix, config);
98 return preconditioner;
99 }
100};
101
102using IstlAmgPreconditionerFactory = Dune::AMGCreator;
103
104template<class M, bool convert = false>
105struct MatrixForSolver { using type = M; };
106
107template<class M>
108struct MatrixForSolver<M, true>
109{ using type = std::decay_t<decltype(MatrixConverter<M>::multiTypeToBCRSMatrix(std::declval<M>()))>; };
110
111template<class V, bool convert = false>
112struct VectorForSolver { using type = V; };
113
114template<class V>
115struct VectorForSolver<V, true>
116{ using type = std::decay_t<decltype(VectorConverter<V>::multiTypeToBlockVector(std::declval<V>()))>; };
117
118template<class LSTraits, class LATraits, bool convert, bool parallel = LSTraits::canCommunicate>
120
121template<class LSTraits, class LATraits, bool convert>
122struct MatrixOperator<LSTraits, LATraits, convert, true>
123{
126#if HAVE_MPI
127 using type = std::variant<
128 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>,
129 std::shared_ptr<typename LSTraits::template ParallelOverlapping<M, V>::LinearOperator>,
130 std::shared_ptr<typename LSTraits::template ParallelNonoverlapping<M, V>::LinearOperator>
131 >;
132#else
133 using type = std::variant<
134 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>
135 >;
136#endif
137};
138
139template<class LSTraits, class LATraits, bool convert>
140struct MatrixOperator<LSTraits, LATraits, convert, false>
141{
144 using type = std::variant<
145 std::shared_ptr<typename LSTraits::template Sequential<M, V>::LinearOperator>
146 >;
147};
148
149} // end namespace Dumux::Detail::IstlSolvers
150
151namespace Dumux::Detail {
152
153struct IstlSolverResult : public Dune::InverseOperatorResult
154{
155 IstlSolverResult() = default;
158
159 IstlSolverResult(const Dune::InverseOperatorResult& o) : InverseOperatorResult(o) {}
160 IstlSolverResult(Dune::InverseOperatorResult&& o) : InverseOperatorResult(std::move(o)) {}
161
162 operator bool() const { return this->converged; }
163};
164
169template<class LinearSolverTraits, class LinearAlgebraTraits,
170 class InverseOperator, class PreconditionerFactory,
171 bool convertMultiTypeLATypes = false>
173{
174 using Matrix = typename LinearAlgebraTraits::Matrix;
175 using XVector = typename LinearAlgebraTraits::Vector;
176 using BVector = typename LinearAlgebraTraits::Vector;
177 using Scalar = typename InverseOperator::real_type;
178
179 using ScalarProduct = Dune::ScalarProduct<typename InverseOperator::domain_type>;
180
181 static constexpr bool convertMultiTypeVectorAndMatrix
182 = convertMultiTypeLATypes && isMultiTypeBlockVector<XVector>::value;
186 // a variant type that can hold sequential, overlapping, and non-overlapping operators
187 using MatrixOperatorHolder = typename Detail::IstlSolvers::MatrixOperator<
188 LinearSolverTraits, LinearAlgebraTraits, convertMultiTypeVectorAndMatrix
189 >::type;
190
191#if HAVE_MPI
192 using Comm = Dune::OwnerOverlapCopyCommunication<Dune::bigunsignedint<96>, int>;
194#endif
195
196 using ParameterInitializer = std::variant<std::string, Dune::ParameterTree>;
197public:
198
202 IstlIterativeLinearSolver(const ParameterInitializer& params = "")
203 {
204 if (Dune::MPIHelper::getCommunication().size() > 1)
205 DUNE_THROW(Dune::InvalidStateException, "Using sequential constructor for parallel run. Use signature with gridView and dofMapper!");
206
207 initializeParameters_(params);
208 solverCategory_ = Dune::SolverCategory::sequential;
209 scalarProduct_ = std::make_shared<ScalarProduct>();
210 }
211
215 template <class GridView, class DofMapper>
216 IstlIterativeLinearSolver(const GridView& gridView,
217 const DofMapper& dofMapper,
218 const ParameterInitializer& params = "")
219 {
220 initializeParameters_(params, gridView.comm());
221#if HAVE_MPI
222 solverCategory_ = Detail::solverCategory<LinearSolverTraits>(gridView);
223 if constexpr (LinearSolverTraits::canCommunicate)
224 {
225
226 if (solverCategory_ != Dune::SolverCategory::sequential)
227 {
228 parallelHelper_ = std::make_shared<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
229 communication_ = std::make_shared<Comm>(gridView.comm(), solverCategory_);
230 scalarProduct_ = Dune::createScalarProduct<XVector>(*communication_, solverCategory_);
231 parallelHelper_->createParallelIndexSet(*communication_);
232 }
233 else
234 scalarProduct_ = std::make_shared<ScalarProduct>();
235 }
236 else
237 scalarProduct_ = std::make_shared<ScalarProduct>();
238#else
239 solverCategory_ = Dune::SolverCategory::sequential;
240 scalarProduct_ = std::make_shared<ScalarProduct>();
241#endif
242 }
243
244#if HAVE_MPI
248 template <class GridView, class DofMapper>
249 IstlIterativeLinearSolver(std::shared_ptr<Comm> communication,
250 std::shared_ptr<ScalarProduct> scalarProduct,
251 const GridView& gridView,
252 const DofMapper& dofMapper,
253 const ParameterInitializer& params = "")
254 {
255 initializeParameters_(params, gridView.comm());
256 solverCategory_ = Detail::solverCategory(gridView);
257 scalarProduct_ = scalarProduct;
258 communication_ = communication;
259 if constexpr (LinearSolverTraits::canCommunicate)
260 {
261 if (solverCategory_ != Dune::SolverCategory::sequential)
262 {
263 parallelHelper_ = std::make_shared<ParallelISTLHelper<LinearSolverTraits>>(gridView, dofMapper);
264 parallelHelper_->createParallelIndexSet(communication);
265 }
266 }
267 }
268#endif
269
273 IstlSolverResult solve(Matrix& A, XVector& x, BVector& b)
274 { return solveSequentialOrParallel_(A, x, b); }
275
279 void setMatrix(std::shared_ptr<Matrix> A)
280 {
281 linearOperator_ = makeParallelOrSequentialLinearOperator_(std::move(A));
282 solver_ = constructPreconditionedSolver_(linearOperator_);
283 }
284
289 void setMatrix(Matrix& A)
290 { setMatrix(Dune::stackobject_to_shared_ptr(A)); }
291
295 IstlSolverResult solve(XVector& x, BVector& b) const
296 {
297 if (!solver_)
298 DUNE_THROW(Dune::InvalidStateException, "Called solve(x, b) but no linear operator has been set");
299
300 return solveSequentialOrParallel_(x, b, *solver_);
301 }
302
306 Scalar norm(const XVector& x) const
307 {
308#if HAVE_MPI
309 if constexpr (LinearSolverTraits::canCommunicate)
310 {
311 if (solverCategory_ == Dune::SolverCategory::nonoverlapping)
312 {
313 auto y(x); // make a copy because the vector needs to be made consistent
314 using GV = typename LinearSolverTraits::GridView;
315 using DM = typename LinearSolverTraits::DofMapper;
316 ParallelVectorHelper<GV, DM, LinearSolverTraits::dofCodim> vectorHelper(parallelHelper_->gridView(), parallelHelper_->dofMapper());
317 vectorHelper.makeNonOverlappingConsistent(y);
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"] = std::to_string(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
404 MatrixOperatorHolder makeSequentialLinearOperator_(std::shared_ptr<Matrix> A)
405 {
406 using SequentialTraits = typename LinearSolverTraits::template Sequential<MatrixForSolver, XVectorForSolver>;
407 if constexpr (convertMultiTypeVectorAndMatrix)
408 {
409 // create the BCRS matrix the IterativeSolver backend can handle
410 auto M = std::make_shared<MatrixForSolver>(MatrixConverter<Matrix>::multiTypeToBCRSMatrix(*A));
411 return std::make_shared<typename SequentialTraits::LinearOperator>(M);
412 }
413 else
414 {
415 return std::make_shared<typename SequentialTraits::LinearOperator>(A);
416 }
417 }
418
419 template<class ParallelTraits>
420 MatrixOperatorHolder makeParallelLinearOperator_(std::shared_ptr<Matrix> A, ParallelTraits = {})
421 {
422#if HAVE_MPI
423 // make matrix consistent
424 prepareMatrixParallel<LinearSolverTraits, ParallelTraits>(*A, *parallelHelper_);
425 return std::make_shared<typename ParallelTraits::LinearOperator>(std::move(A), *communication_);
426#else
427 DUNE_THROW(Dune::InvalidStateException, "Calling makeParallelLinearOperator for sequential run");
428#endif
429 }
430
431 MatrixOperatorHolder makeParallelOrSequentialLinearOperator_(std::shared_ptr<Matrix> A)
432 {
433 return executeSequentialOrParallel_(
434 [&]{ return makeSequentialLinearOperator_(std::move(A)); },
435 [&](auto traits){ return makeParallelLinearOperator_(std::move(A), traits); }
436 );
437 }
438
439 MatrixOperatorHolder makeSequentialLinearOperator_(Matrix& A)
440 { return makeSequentialLinearOperator_(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
441
442 MatrixOperatorHolder makeParallelOrSequentialLinearOperator_(Matrix& A)
443 { return makeParallelOrSequentialLinearOperator_(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
444
445 template<class ParallelTraits>
446 MatrixOperatorHolder makeParallelLinearOperator_(Matrix& A, ParallelTraits = {})
447 { return makeParallelLinearOperator_<ParallelTraits>(Dune::stackobject_to_shared_ptr<Matrix>(A)); }
448
449 IstlSolverResult solveSequential_(Matrix& A, XVector& x, BVector& b)
450 {
451 // construct solver from linear operator
452 auto linearOperatorHolder = makeSequentialLinearOperator_(A);
453 auto solver = constructPreconditionedSolver_(linearOperatorHolder);
454
455 return solveSequential_(x, b, *solver);
456 }
457
458 IstlSolverResult solveSequential_(XVector& x, BVector& b, InverseOperator& solver) const
459 {
460 Dune::InverseOperatorResult result;
461 if constexpr (convertMultiTypeVectorAndMatrix)
462 {
463 // create the vector the IterativeSolver backend can handle
464 BVectorForSolver bTmp = VectorConverter<BVector>::multiTypeToBlockVector(b);
465
466 // create a block vector to which the linear solver writes the solution
467 XVectorForSolver y(bTmp.size());
468
469 // solve linear system
470 solver.apply(y, bTmp, result);
471
472 // copy back the result y into x
473 if (result.converged)
475 }
476 else
477 {
478 // solve linear system
479 solver.apply(x, b, result);
480 }
481
482 return result;
483 }
484
485 IstlSolverResult solveSequentialOrParallel_(Matrix& A, XVector& x, BVector& b)
486 {
487 return executeSequentialOrParallel_(
488 [&]{ return solveSequential_(A, x, b); },
489 [&](auto traits){ return solveParallel_(A, x, b, traits); }
490 );
491 }
492
493 IstlSolverResult solveSequentialOrParallel_(XVector& x, BVector& b, InverseOperator& solver) const
494 {
495 return executeSequentialOrParallel_(
496 [&]{ return solveSequential_(x, b, solver); },
497 [&](auto traits){ return solveParallel_(x, b, solver, traits); }
498 );
499 }
500
501 template<class ParallelTraits>
502 IstlSolverResult solveParallel_(Matrix& A, XVector& x, BVector& b, ParallelTraits = {})
503 {
504 // construct solver from linear operator
505 auto linearOperatorHolder = makeParallelLinearOperator_<ParallelTraits>(A);
506 auto solver = constructPreconditionedSolver_(linearOperatorHolder);
507 return solveParallel_<ParallelTraits>(x, b, *solver);
508 }
509
510 template<class ParallelTraits>
511 IstlSolverResult solveParallel_(XVector& x, BVector& b, InverseOperator& solver, ParallelTraits = {}) const
512 {
513#if HAVE_MPI
514 // make right hand side consistent
515 prepareVectorParallel<LinearSolverTraits, ParallelTraits>(b, *parallelHelper_);
516
517 // solve linear system
518 Dune::InverseOperatorResult result;
519 solver.apply(x, b, result);
520 return result;
521#else
522 DUNE_THROW(Dune::InvalidStateException, "Calling makeParallelLinearOperator for sequential run");
523#endif
524 }
525
526
527 std::shared_ptr<InverseOperator> constructPreconditionedSolver_(MatrixOperatorHolder& ops)
528 {
529 return std::visit([&](auto&& op)
530 {
531 using LinearOperator = typename std::decay_t<decltype(op)>::element_type;
532 const auto& params = params_.sub("preconditioner");
533 using Prec = Dune::Preconditioner<typename LinearOperator::domain_type, typename LinearOperator::range_type>;
534#if DUNE_VERSION_GTE(DUNE_ISTL,2,11)
535 using OpTraits = Dune::OperatorTraits<LinearOperator>;
536 std::shared_ptr<Prec> prec = PreconditionerFactory{}(OpTraits{}, op, params);
537#else
538 using TL = Dune::TypeList<typename LinearOperator::matrix_type, typename LinearOperator::domain_type, typename LinearOperator::range_type>;
539 std::shared_ptr<Prec> prec = PreconditionerFactory{}(TL{}, op, params);
540#endif
541
542#if HAVE_MPI
543#if DUNE_VERSION_LT(DUNE_ISTL,2,11)
544 if (prec->category() != op->category() && prec->category() == Dune::SolverCategory::sequential)
545 prec = Dune::wrapPreconditioner4Parallel(prec, op);
546#else
547 if constexpr (OpTraits::isParallel)
548 {
549 using Comm = typename OpTraits::comm_type;
550 const Comm& comm = OpTraits::getCommOrThrow(op);
551 if (op->category() == Dune::SolverCategory::overlapping && prec->category() == Dune::SolverCategory::sequential)
552 prec = std::make_shared<Dune::BlockPreconditioner<typename OpTraits::domain_type, typename OpTraits::range_type,Comm> >(prec, comm);
553 else if (op->category() == Dune::SolverCategory::nonoverlapping && prec->category() == Dune::SolverCategory::sequential)
554 prec = std::make_shared<Dune::NonoverlappingBlockPreconditioner<Comm, Prec> >(prec, comm);
555 }
556#endif
557#endif
558 return std::make_shared<InverseOperator>(op, scalarProduct_, prec, params_);
559 }, ops);
560 }
561
562 template<class Seq, class Par>
563 decltype(auto) executeSequentialOrParallel_(Seq&& sequentialAction, Par&& parallelAction) const
564 {
565#if HAVE_MPI
566 // For Dune::MultiTypeBlockMatrix there is currently no generic way
567 // of handling parallelism, we therefore can only solve these types of systems sequentially
568 if constexpr (isMultiTypeBlockMatrix<Matrix>::value || !LinearSolverTraits::canCommunicate)
569 return sequentialAction();
570 else
571 {
572 switch (solverCategory_)
573 {
574 case Dune::SolverCategory::sequential:
575 return sequentialAction();
576 case Dune::SolverCategory::nonoverlapping:
577 using NOTraits = typename LinearSolverTraits::template ParallelNonoverlapping<Matrix, XVector>;
578 return parallelAction(NOTraits{});
579 case Dune::SolverCategory::overlapping:
580 using OTraits = typename LinearSolverTraits::template ParallelOverlapping<Matrix, XVector>;
581 return parallelAction(OTraits{});
582 default: DUNE_THROW(Dune::InvalidStateException, "Unknown solver category");
583 }
584 }
585#else
586 return sequentialAction();
587#endif
588 }
589
590#if HAVE_MPI
591 std::shared_ptr<const ParallelHelper> parallelHelper_;
592 std::shared_ptr<Comm> communication_;
593#endif
594
595 Dune::SolverCategory::Category solverCategory_;
596 std::shared_ptr<ScalarProduct> scalarProduct_;
597
598 // for stored solvers (reuse matrix)
599 MatrixOperatorHolder linearOperator_;
600 // for stored solvers (reuse matrix)
601 std::shared_ptr<InverseOperator> solver_;
602
603 Dune::ParameterTree params_;
604 std::string name_;
605};
606
607} // end namespace Dumux::Detail
608
609namespace Dumux {
610
627template<class LSTraits, class LATraits>
629 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
630 Dune::BiCGSTABSolver<typename LATraits::SingleTypeVector>,
632 // the Dune::ILU preconditioners don't accept multi-type matrices
633 /*convert multi-type istl types?*/ true
634 >;
635
652template<class LSTraits, class LATraits>
654 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
655 Dune::RestartedGMResSolver<typename LATraits::SingleTypeVector>,
657 // the Dune::ILU preconditioners don't accept multi-type matrices
658 /*convert multi-type istl types?*/ true
659 >;
660
678template<class LSTraits, class LATraits>
680 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
681 Dune::BiCGSTABSolver<typename LATraits::Vector>,
683 >;
684
701template<class LSTraits, class LATraits>
703 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
704 Dune::CGSolver<typename LATraits::Vector>,
706 >;
707
721template<class LSTraits, class LATraits>
723 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
724 Dune::BiCGSTABSolver<typename LATraits::SingleTypeVector>,
726 // the AMG preconditioner doesn't accept multi-type matrices
727 /*convert multi-type istl types?*/ true
728 >;
729
742template<class LSTraits, class LATraits>
744 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
745 Dune::CGSolver<typename LATraits::SingleTypeVector>,
747 // the AMG preconditioner doesn't accept multi-type matrices
748 /*convert multi-type istl types?*/ true
749 >;
750
765template<class LSTraits, class LATraits>
767 Detail::IstlIterativeLinearSolver<LSTraits, LATraits,
768 Dune::BiCGSTABSolver<typename LATraits::Vector>,
770 >;
771
772} // end namespace Dumux
773
774namespace Dumux::Detail {
775
780template<class LSTraits, class LATraits, template<class M> class Solver,
781 bool convertMultiTypeVectorAndMatrix = isMultiTypeBlockVector<typename LATraits::Vector>::value>
783{
784 using Matrix = typename LATraits::Matrix;
785 using XVector = typename LATraits::Vector;
786 using BVector = typename LATraits::Vector;
787
791 using InverseOperator = Dune::InverseOperator<XVectorForSolver, BVectorForSolver>;
792public:
794
798 IstlSolverResult solve(const Matrix& A, XVector& x, const BVector& b)
799 {
800 return solve_(A, x, b);
801 }
802
806 IstlSolverResult solve(XVector& x, const BVector& b)
807 {
808 if (!solver_)
809 DUNE_THROW(Dune::InvalidStateException, "Called solve(x, b) but no linear operator has been set");
810
811 return solve_(x, b, *solver_);
812 }
813
817 void setMatrix(std::shared_ptr<Matrix> A)
818 {
819 if constexpr (convertMultiTypeVectorAndMatrix)
820 matrix_ = std::make_shared<MatrixForSolver>(MatrixConverter<Matrix>::multiTypeToBCRSMatrix(A));
821 else
822 matrix_ = A;
823
824 solver_ = std::make_shared<Solver<MatrixForSolver>>(*matrix_);
825 }
826
831 void setMatrix(Matrix& A)
832 { setMatrix(Dune::stackobject_to_shared_ptr(A)); }
833
837 std::string name() const
838 {
839 return "Direct solver";
840 }
841
842private:
843 IstlSolverResult solve_(const Matrix& A, XVector& x, const BVector& b)
844 {
845 // support dune-istl multi-type block vector/matrix by copying
846 if constexpr (convertMultiTypeVectorAndMatrix)
847 {
849 Solver<MatrixForSolver> solver(AA, this->verbosity() > 0);
850 return solve_(x, b, solver);
851 }
852 else
853 {
854 Solver<MatrixForSolver> solver(A, this->verbosity() > 0);
855 return solve_(x, b, solver);
856 }
857 }
858
859 IstlSolverResult solve_(XVector& x, const BVector& b, InverseOperator& solver) const
860 {
861 Dune::InverseOperatorResult result;
862
863 if constexpr (convertMultiTypeVectorAndMatrix)
864 {
866 XVectorForSolver xx(bb.size());
867 solver.apply(xx, bb, result);
868 checkResult_(xx, result);
869 if (result.converged)
871 return result;
872 }
873 else
874 {
875 BVectorForSolver bTmp(b);
876 solver.apply(x, bTmp, result);
877 checkResult_(x, result);
878 return result;
879 }
880 }
881
882
883 void checkResult_(XVectorForSolver& x, Dune::InverseOperatorResult& result) const
884 {
885 flatVectorForEach(x, [&](auto&& entry, std::size_t){
886 using std::isnan, std::isinf;
887 if (isnan(entry) || isinf(entry))
888 result.converged = false;
889 });
890 }
891
893 std::shared_ptr<MatrixForSolver> matrix_;
895 std::shared_ptr<InverseOperator> solver_;
896};
897
898} // end namespace Dumux::Detail
899
900#if HAVE_SUPERLU
901#include <dune/istl/superlu.hh>
902
903namespace Dumux {
904
913template<class LSTraits, class LATraits>
914using SuperLUIstlSolver = Detail::DirectIstlSolver<LSTraits, LATraits, Dune::SuperLU>;
915
916} // end namespace Dumux
917
918#endif // HAVE_SUPERLU
919
920#if HAVE_UMFPACK
921#include <dune/istl/umfpack.hh>
922
923namespace Dumux {
924
933template<class LSTraits, class LATraits>
934using UMFPackIstlSolver = Detail::DirectIstlSolver<LSTraits, LATraits, Dune::UMFPack, false>;
935
936} // end namespace Dumux
937
938#endif // HAVE_UMFPACK
939
940#endif
Direct dune-istl linear solvers.
Definition: istlsolvers.hh:783
void setMatrix(std::shared_ptr< Matrix > A)
Set the matrix A of the linear system Ax = b for reuse.
Definition: istlsolvers.hh:817
IstlSolverResult solve(const Matrix &A, XVector &x, const BVector &b)
Solve the linear system Ax = b.
Definition: istlsolvers.hh:798
std::string name() const
name of the linear solver
Definition: istlsolvers.hh:837
void setMatrix(Matrix &A)
Set the matrix A of the linear system Ax = b for reuse.
Definition: istlsolvers.hh:831
IstlSolverResult solve(XVector &x, const BVector &b)
Solve the linear system Ax = b using the matrix set with setMatrix.
Definition: istlsolvers.hh:806
Standard dune-istl iterative linear solvers.
Definition: istlsolvers.hh:173
IstlIterativeLinearSolver(const ParameterInitializer &params="")
Constructor for sequential solvers.
Definition: istlsolvers.hh:202
void setMatrix(Matrix &A)
Set the matrix A of the linear system Ax = b for reuse.
Definition: istlsolvers.hh:289
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:216
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:273
void setMatrix(std::shared_ptr< Matrix > A)
Set the matrix A of the linear system Ax = b for reuse.
Definition: istlsolvers.hh:279
IstlSolverResult solve(XVector &x, BVector &b) const
Solve the linear system Ax = b where A has been set with setMatrix.
Definition: istlsolvers.hh:295
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:249
Scalar norm(const XVector &x) const
Compute the 2-norm of vector x.
Definition: istlsolvers.hh:306
auto operator()(OI opInfo, 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:102
Definition: cvfelocalresidual.hh:28
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:154
IstlSolverResult(IstlSolverResult &&)=default
IstlSolverResult(const Dune::InverseOperatorResult &o)
Definition: istlsolvers.hh:159
IstlSolverResult(Dune::InverseOperatorResult &&o)
Definition: istlsolvers.hh:160
IstlSolverResult(const IstlSolverResult &)=default
std::decay_t< decltype(MatrixConverter< M >::multiTypeToBCRSMatrix(std::declval< M >()))> type
Definition: istlsolvers.hh:109
Definition: istlsolvers.hh:105
M type
Definition: istlsolvers.hh:105
typename VectorForSolver< typename LATraits::Vector, convert >::type V
Definition: istlsolvers.hh:143
std::variant< std::shared_ptr< typename LSTraits::template Sequential< M, V >::LinearOperator > > type
Definition: istlsolvers.hh:146
typename MatrixForSolver< typename LATraits::Matrix, convert >::type M
Definition: istlsolvers.hh:142
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:131
typename VectorForSolver< typename LATraits::Vector, convert >::type V
Definition: istlsolvers.hh:125
typename MatrixForSolver< typename LATraits::Matrix, convert >::type M
Definition: istlsolvers.hh:124
Definition: istlsolvers.hh:119
std::decay_t< decltype(VectorConverter< V >::multiTypeToBlockVector(std::declval< V >()))> type
Definition: istlsolvers.hh:116
Definition: istlsolvers.hh:112
V type
Definition: istlsolvers.hh:112
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.