GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/linear/seqsolverbackend.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 72 76 94.7%
Functions: 22 35 62.9%
Branches: 62 176 35.2%

Line Branch Exec Source
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 //
7 /*!
8 * \file
9 * \ingroup Linear
10 * \brief Dumux sequential linear solver backends
11 */
12 #ifndef DUMUX_SEQ_SOLVER_BACKEND_HH
13 #define DUMUX_SEQ_SOLVER_BACKEND_HH
14
15 #include <type_traits>
16 #include <tuple>
17 #include <utility>
18
19 #include <dune/istl/preconditioners.hh>
20 #include <dune/istl/solvers.hh>
21 #include <dune/istl/io.hh>
22 #include <dune/common/indices.hh>
23 #include <dune/common/hybridutilities.hh>
24
25 #include <dumux/common/parameters.hh>
26 #include <dumux/common/typetraits/matrix.hh>
27 #include <dumux/common/typetraits/utility.hh>
28 #include <dumux/linear/solver.hh>
29 #include <dumux/linear/preconditioners.hh>
30 #include <dumux/linear/linearsolverparameters.hh>
31 #include <dumux/linear/parallelmatrixadapter.hh>
32
33 namespace Dumux {
34
35 /*!
36 * \ingroup Linear
37 * \brief A general solver backend allowing arbitrary preconditioners and solvers.
38 *
39 * This class is used as a base class for specific solver-preconditioner
40 * combinations. Several parameters from the group LinearSolver are read to
41 * customize the solver and preconditioner:
42 *
43 * - Verbosity: determines how verbose the linear solver should print output.
44 * - MaxIterations: the maximum number of iterations for the linear solver.
45 * - ResidualReduction: the threshold for declaration of convergence.
46 * - PreconditionerRelaxation: relaxation parameter for the preconditioner.
47 * - PreconditionerIterations: usually specifies the number of times the
48 * preconditioner is applied. In case of ILU(n),
49 * it specifies the order of the applied ILU.
50 */
51 class IterativePreconditionedSolverImpl
52 {
53 public:
54
55 // solve with generic parameter tree
56 template<class Preconditioner, class Solver, class Matrix, class Vector>
57 static bool solveWithParamTree(const Matrix& A, Vector& x, const Vector& b,
58 const Dune::ParameterTree& params)
59 {
60 // make a linear operator from a matrix
61 using MatrixAdapter = Dune::MatrixAdapter<Matrix, Vector, Vector>;
62 const auto linearOperator = std::make_shared<MatrixAdapter>(A);
63
64 auto precond = std::make_shared<Preconditioner>(linearOperator, params.sub("preconditioner"));
65 Solver solver(linearOperator, precond, params);
66
67 Vector bTmp(b);
68
69 Dune::InverseOperatorResult result;
70 solver.apply(x, bTmp, result);
71
72 return result.converged;
73 }
74 };
75
76 /*!
77 * \ingroup Linear
78 * \brief Returns the block level for the preconditioner for a given matrix
79 *
80 * \tparam M The matrix.
81 */
82 template<class M>
83 constexpr std::size_t preconditionerBlockLevel() noexcept
84 {
85 return isMultiTypeBlockMatrix<M>::value ? 2 : 1;
86 }
87
88 /*!
89 * \ingroup Linear
90 * \brief Solver for simple block-diagonal matrices (e.g. from explicit time stepping schemes)
91 *
92 * Solver: Single Jacobi iteration
93 * Preconditioner: Unity
94 */
95
1/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
2 class ExplicitDiagonalSolver : public LinearSolver
96 {
97 public:
98 using LinearSolver::LinearSolver;
99
100 template<class Matrix, class Vector>
101 2000 bool solve(const Matrix& A, Vector& x, const Vector& b)
102 {
103
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
2000 Vector rhs(b);
104 2000 constexpr auto precondBlockLevel = preconditionerBlockLevel<Matrix>();
105
1/2
✓ Branch 0 taken 2000 times.
✗ Branch 1 not taken.
4000 Dune::SeqJac<Matrix, Vector, Vector, precondBlockLevel> jac(A, 1, 1.0);
106 jac.pre(x, rhs);
107 2000 jac.apply(x, rhs);
108 2000 jac.post(x);
109
1/2
✓ Branch 0 taken 2000 times.
✗ Branch 1 not taken.
4000 return true;
110 }
111
112 std::string name() const
113 {
114 return "Explicit diagonal matrix solver";
115 }
116 };
117
118 /*!
119 * \name Solver for MultiTypeBlockMatrix's
120 */
121 // \{
122
123 /*!
124 * \ingroup Linear
125 * \brief A Uzawa preconditioned BiCGSTAB solver for saddle-point problems
126 */
127 template <class LinearSolverTraits>
128 class UzawaBiCGSTABBackend : public LinearSolver
129 {
130 public:
131 using LinearSolver::LinearSolver;
132
133 template<class Matrix, class Vector>
134 bool solve(const Matrix& A, Vector& x, const Vector& b)
135 {
136 using Preconditioner = SeqUzawa<Matrix, Vector, Vector>;
137 using Solver = Dune::BiCGSTABSolver<Vector>;
138 static const auto solverParams = LinearSolverParameters<LinearSolverTraits>::createParameterTree(this->paramGroup());
139 return IterativePreconditionedSolverImpl::template solveWithParamTree<Preconditioner, Solver>(A, x, b, solverParams);
140 }
141
142 std::string name() const
143 {
144 return "Uzawa preconditioned BiCGSTAB solver";
145 }
146 };
147
148 /*!
149 * \ingroup Linear
150 * \brief A simple ilu0 block diagonal preconditioner
151 */
152 template<class M, class X, class Y, int blockLevel = 2>
153 1498 class BlockDiagILU0Preconditioner : public Dune::Preconditioner<X, Y>
154 {
155 template<std::size_t i>
156 using DiagBlockType = std::decay_t<decltype(std::declval<M>()[Dune::index_constant<i>{}][Dune::index_constant<i>{}])>;
157
158 template<std::size_t i>
159 using VecBlockType = std::decay_t<decltype(std::declval<X>()[Dune::index_constant<i>{}])>;
160
161 template<std::size_t i>
162 using BlockILU = Dune::SeqILU<DiagBlockType<i>, VecBlockType<i>, VecBlockType<i>, blockLevel-1>;
163
164 using ILUTuple = typename makeFromIndexedType<std::tuple, BlockILU, std::make_index_sequence<M::N()> >::type;
165
166 public:
167 //! \brief The matrix type the preconditioner is for.
168 using matrix_type = typename std::decay_t<M>;
169 //! \brief The domain type of the preconditioner.
170 using domain_type = X;
171 //! \brief The range type of the preconditioner.
172 using range_type = Y;
173 //! \brief The field type of the preconditioner.
174 using field_type = typename X::field_type;
175
176 /*! \brief Constructor.
177
178 Constructor gets all parameters to operate the prec.
179 \param m The (multi type block) matrix to operate on
180 \param w The relaxation factor
181 */
182 749 BlockDiagILU0Preconditioner(const M& m, double w = 1.0)
183 749 : BlockDiagILU0Preconditioner(m, w, std::make_index_sequence<M::N()>{})
184 {
185 static_assert(blockLevel >= 2, "Only makes sense for MultiTypeBlockMatrix!");
186 }
187
188 749 void pre (X& v, Y& d) final {}
189
190 68746 void apply (X& v, const Y& d) final
191 {
192 using namespace Dune::Hybrid;
193 68746 forEach(integralRange(Dune::Hybrid::size(ilu_)), [&](const auto i)
194 {
195 std::get<decltype(i)::value>(ilu_).apply(v[i], d[i]);
196 });
197 68746 }
198
199 749 void post (X&) final {}
200
201 //! Category of the preconditioner (see SolverCategory::Category)
202 749 Dune::SolverCategory::Category category() const final
203 {
204 749 return Dune::SolverCategory::sequential;
205 }
206
207 private:
208 template<std::size_t... Is>
209 749 BlockDiagILU0Preconditioner (const M& m, double w, std::index_sequence<Is...> is)
210
3/6
✓ Branch 4 taken 749 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 749 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 749 times.
✗ Branch 11 not taken.
2996 : ilu_(std::make_tuple(BlockILU<Is>(m[Dune::index_constant<Is>{}][Dune::index_constant<Is>{}], w)...))
211 749 {}
212
213 ILUTuple ilu_;
214 };
215
216
217 /*!
218 * \ingroup Linear
219 * \brief A simple ilu0 block diagonal preconditioned BiCGSTABSolver
220 * \note expects a system as a multi-type block-matrix
221 * | A B |
222 * | C D |
223 */
224
1/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 26 times.
26 class BlockDiagILU0BiCGSTABSolver : public LinearSolver
225 {
226
227 public:
228 using LinearSolver::LinearSolver;
229
230 template<class Matrix, class Vector>
231 749 bool solve(const Matrix& M, Vector& x, const Vector& b)
232 {
233 749 BlockDiagILU0Preconditioner<Matrix, Vector, Vector> preconditioner(M);
234
1/4
✓ Branch 1 taken 749 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1498 Dumux::ParallelMultiTypeMatrixAdapter<Matrix, Vector, Vector> op(M);
235
5/10
✓ Branch 1 taken 749 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 749 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 749 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 749 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 749 times.
✗ Branch 13 not taken.
3745 Dune::BiCGSTABSolver<Vector> solver(op, preconditioner, this->residReduction(),
236 this->maxIter(), this->verbosity());
237
1/2
✓ Branch 1 taken 749 times.
✗ Branch 2 not taken.
1498 auto bTmp(b);
238
1/2
✓ Branch 1 taken 749 times.
✗ Branch 2 not taken.
749 solver.apply(x, bTmp, result_);
239
240 1498 return result_.converged;
241 }
242
243 const Dune::InverseOperatorResult& result() const
244 {
245 return result_;
246 }
247
248 std::string name() const
249
6/16
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 19 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 19 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 19 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
40 { return "block-diagonal ILU0-preconditioned BiCGSTAB solver"; }
250
251 private:
252 Dune::InverseOperatorResult result_;
253 };
254
255 /*!
256 * \ingroup Linear
257 * \brief A simple ilu0 block diagonal preconditioned RestartedGMResSolver
258 * \note expects a system as a multi-type block-matrix
259 * | A B |
260 * | C D |
261 */
262 class BlockDiagILU0RestartedGMResSolver : public LinearSolver
263 {
264
265 public:
266 using LinearSolver::LinearSolver;
267
268 template<int precondBlockLevel = 2, class Matrix, class Vector>
269 bool solve(const Matrix& M, Vector& x, const Vector& b)
270 {
271 BlockDiagILU0Preconditioner<Matrix, Vector, Vector> preconditioner(M);
272 Dumux::ParallelMultiTypeMatrixAdapter<Matrix, Vector, Vector> op(M);
273 static const int restartGMRes = getParamFromGroup<int>(this->paramGroup(), "LinearSolver.GMResRestart");
274 Dune::RestartedGMResSolver<Vector> solver(op, preconditioner, this->residReduction(), restartGMRes,
275 this->maxIter(), this->verbosity());
276 auto bTmp(b);
277 solver.apply(x, bTmp, result_);
278
279 return result_.converged;
280 }
281
282 const Dune::InverseOperatorResult& result() const
283 {
284 return result_;
285 }
286
287 std::string name() const
288 { return "block-diagonal ILU0-preconditioned restarted GMRes solver"; }
289
290 private:
291 Dune::InverseOperatorResult result_;
292 };
293
294 /*!
295 * \ingroup Linear
296 * \brief A simple ilu0 block diagonal preconditioner
297 */
298 template<class M, class X, class Y, int blockLevel = 2>
299 3080 class BlockDiagAMGPreconditioner : public Dune::Preconditioner<X, Y>
300 {
301 template<std::size_t i>
302 using DiagBlockType = std::decay_t<decltype(std::declval<M>()[Dune::index_constant<i>{}][Dune::index_constant<i>{}])>;
303
304 template<std::size_t i>
305 using VecBlockType = std::decay_t<decltype(std::declval<X>()[Dune::index_constant<i>{}])>;
306
307 template<std::size_t i>
308 using Smoother = Dune::SeqSSOR<DiagBlockType<i>, VecBlockType<i>, VecBlockType<i>>;
309
310 template<std::size_t i>
311 using LinearOperator = Dune::MatrixAdapter<DiagBlockType<i>, VecBlockType<i>, VecBlockType<i>>;
312
313 template<std::size_t i>
314 using ScalarProduct = Dune::SeqScalarProduct<VecBlockType<i>>;
315
316 template<std::size_t i>
317 using BlockAMG = Dune::Amg::AMG<LinearOperator<i>, VecBlockType<i>, Smoother<i>>;
318
319 using AMGTuple = typename makeFromIndexedType<std::tuple, BlockAMG, std::make_index_sequence<M::N()> >::type;
320
321 public:
322 //! \brief The matrix type the preconditioner is for.
323 using matrix_type = typename std::decay_t<M>;
324 //! \brief The domain type of the preconditioner.
325 using domain_type = X;
326 //! \brief The range type of the preconditioner.
327 using range_type = Y;
328 //! \brief The field type of the preconditioner.
329 using field_type = typename X::field_type;
330
331 /*! \brief Constructor.
332
333 Constructor gets all parameters to operate the prec.
334 \param lop The linear operator
335 \param c The criterion
336 \param sa The smoother arguments
337 */
338 template<class LOP, class Criterion, class SmootherArgs>
339 1540 BlockDiagAMGPreconditioner(const LOP& lop, const Criterion& c, const SmootherArgs& sa)
340 1540 : BlockDiagAMGPreconditioner(lop, c, sa, std::make_index_sequence<M::N()>{})
341 {
342 static_assert(blockLevel >= 2, "Only makes sense for MultiTypeBlockMatrix!");
343 }
344
345 /*!
346 * \brief Prepare the preconditioner.
347 *
348 * A solver solves a linear operator equation A(v)=d by applying
349 * one or several steps of the preconditioner. The method pre()
350 * is called before the first apply operation.
351 * d and v are right hand side and solution vector of the linear
352 * system respectively. It may. e.g., scale the system, allocate memory or
353 * compute a (I)LU decomposition.
354 * Note: The ILU decomposition could also be computed in the constructor
355 * or with a separate method of the derived method if several
356 * linear systems with the same matrix are to be solved.
357 *
358 * \param v The left hand side of the equation.
359 * \param d The right hand side of the equation.
360 */
361 1540 void pre (X& v, Y& d) final
362 {
363 using namespace Dune::Hybrid;
364 1540 forEach(integralRange(Dune::Hybrid::size(amg_)), [&](const auto i)
365 {
366 std::get<decltype(i)::value>(amg_).pre(v[i], d[i]);
367 });
368 1540 }
369
370 /*!
371 * \brief Apply one step of the preconditioner to the system A(v)=d.
372 *
373 * On entry v=0 and d=b-A(x) (although this might not be
374 * computed in that way. On exit v contains the update, i.e
375 * one step computes \f$ v = M^{-1} d \f$ where \f$ M \f$ is the
376 * approximate inverse of the operator \f$ A \f$ characterizing
377 * the preconditioner.
378 * \param v The update to be computed
379 * \param d The current defect.
380 */
381 2509 void apply (X& v, const Y& d) final
382 {
383 using namespace Dune::Hybrid;
384 2509 forEach(integralRange(Dune::Hybrid::size(amg_)), [&](const auto i)
385 {
386 std::get<decltype(i)::value>(amg_).apply(v[i], d[i]);
387 });
388 2509 }
389
390 /*!
391 * \brief Clean up.
392 *
393 * This method is called after the last apply call for the
394 * linear system to be solved. Memory may be deallocated safely
395 * here. v is the solution of the linear equation.
396 *
397 * \param v The right hand side of the equation.
398 */
399 1540 void post (X& v) final
400 {
401 using namespace Dune::Hybrid;
402
1/2
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
1540 forEach(integralRange(Dune::Hybrid::size(amg_)), [&](const auto i)
403 {
404
6/36
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 49 taken 1540 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 1540 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 1540 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 1540 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 1540 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 1540 times.
✗ Branch 65 not taken.
4620 std::get<decltype(i)::value>(amg_).post(v[i]);
405 });
406 1540 }
407
408 //! Category of the preconditioner (see SolverCategory::Category)
409 1540 Dune::SolverCategory::Category category() const final
410 {
411 1540 return Dune::SolverCategory::sequential;
412 }
413
414 private:
415 template<class LOP, class Criterion, class SmootherArgs, std::size_t... Is>
416 1540 BlockDiagAMGPreconditioner (const LOP& lop, const Criterion& c, const SmootherArgs& sa, std::index_sequence<Is...> is)
417
8/16
✓ Branch 9 taken 1540 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 1540 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 1540 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1540 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1540 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1540 times.
✗ Branch 25 not taken.
✓ Branch 27 taken 1540 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 1540 times.
✗ Branch 31 not taken.
13860 : amg_(std::make_tuple(BlockAMG<Is>(*std::get<Is>(lop), *std::get<Is>(c), *std::get<Is>(sa))...))
418 1540 {}
419
420 AMGTuple amg_;
421 };
422
423 /*!
424 * \ingroup Linear
425 * \brief A simple ilu0 block diagonal preconditioned BiCGSTABSolver
426 * \note expects a system as a multi-type block-matrix
427 * | A B |
428 * | C D |
429 */
430
1/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23 times.
23 class BlockDiagAMGBiCGSTABSolver : public LinearSolver
431 {
432 template<class M, std::size_t i>
433 using DiagBlockType = std::decay_t<decltype(std::declval<M>()[Dune::index_constant<i>{}][Dune::index_constant<i>{}])>;
434
435 template<class X, std::size_t i>
436 using VecBlockType = std::decay_t<decltype(std::declval<X>()[Dune::index_constant<i>{}])>;
437
438 template<class M, class X, std::size_t i>
439 using Smoother = Dune::SeqSSOR<DiagBlockType<M, i>, VecBlockType<X, i>, VecBlockType<X, i>>;
440
441 template<class M, class X, std::size_t i>
442 using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother<M, X, i>>::Arguments;
443
444 template<class M, std::size_t i>
445 using Criterion = Dune::Amg::CoarsenCriterion<Dune::Amg::SymmetricCriterion<DiagBlockType<M, i>, Dune::Amg::FirstDiagonal>>;
446
447 template<class M, class X, std::size_t i>
448 using LinearOperator = Dune::MatrixAdapter<DiagBlockType<M, i>, VecBlockType<X, i>, VecBlockType<X, i>>;
449
450 public:
451 using LinearSolver::LinearSolver;
452
453 // Solve saddle-point problem using a Schur complement based preconditioner
454 template<class Matrix, class Vector>
455 1540 bool solve(const Matrix& m, Vector& x, const Vector& b)
456 {
457 //! \todo Check whether the default accumulation mode atOnceAccu is needed.
458 //! \todo make parameters changeable at runtime from input file / parameter tree
459 1540 Dune::Amg::Parameters params(15, 2000, 1.2, 1.6, Dune::Amg::atOnceAccu);
460 1540 params.setDefaultValuesIsotropic(3);
461 3080 params.setDebugLevel(this->verbosity());
462
463 1540 auto criterion = makeCriterion_<Criterion, Matrix>(params, std::make_index_sequence<Matrix::N()>{});
464
1/2
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
3080 auto smootherArgs = makeSmootherArgs_<SmootherArgs, Matrix, Vector>(std::make_index_sequence<Matrix::N()>{});
465
466 using namespace Dune::Hybrid;
467
1/2
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
1540 forEach(std::make_index_sequence<Matrix::N()>{}, [&](const auto i)
468 {
469
2/4
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1540 times.
✗ Branch 5 not taken.
3080 auto& args = std::get<decltype(i)::value>(smootherArgs);
470
2/4
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1540 times.
✗ Branch 5 not taken.
3080 args->iterations = 1;
471
4/8
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1540 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1540 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1540 times.
✗ Branch 11 not taken.
6160 args->relaxationFactor = 1;
472 });
473
474
1/2
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
3080 auto linearOperator = makeLinearOperator_<LinearOperator, Matrix, Vector>(m, std::make_index_sequence<Matrix::N()>{});
475
476
1/2
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
3080 BlockDiagAMGPreconditioner<Matrix, Vector, Vector> preconditioner(linearOperator, criterion, smootherArgs);
477
478
1/4
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
3080 Dumux::ParallelMultiTypeMatrixAdapter<Matrix, Vector, Vector> op(m);
479
5/10
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1540 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1540 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1540 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 1540 times.
✗ Branch 13 not taken.
7700 Dune::BiCGSTABSolver<Vector> solver(op, preconditioner, this->residReduction(),
480 this->maxIter(), this->verbosity());
481
1/2
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
3080 auto bTmp(b);
482
1/2
✓ Branch 1 taken 1540 times.
✗ Branch 2 not taken.
1540 solver.apply(x, bTmp, result_);
483
484 3080 return result_.converged;
485 }
486
487 const Dune::InverseOperatorResult& result() const
488 {
489 return result_;
490 }
491
492 std::string name() const
493 { return "block-diagonal AMG-preconditioned BiCGSTAB solver"; }
494
495 private:
496 template<template<class M, std::size_t i> class Criterion, class Matrix, class Params, std::size_t... Is>
497 1540 auto makeCriterion_(const Params& p, std::index_sequence<Is...>)
498 {
499
1/4
✓ Branch 2 taken 1540 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1540 return std::make_tuple(std::make_shared<Criterion<Matrix, Is>>(p)...);
500 }
501
502 template<template<class M, class X, std::size_t i> class SmootherArgs, class Matrix, class Vector, std::size_t... Is>
503 1540 auto makeSmootherArgs_(std::index_sequence<Is...>)
504 {
505
1/4
✓ Branch 2 taken 1540 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1540 return std::make_tuple(std::make_shared<SmootherArgs<Matrix, Vector, Is>>()...);
506 }
507
508 template<template<class M, class X, std::size_t i> class LinearOperator, class Matrix, class Vector, std::size_t... Is>
509 1540 auto makeLinearOperator_(const Matrix& m, std::index_sequence<Is...>)
510 {
511
3/8
✓ Branch 4 taken 1540 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1540 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1540 times.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
4620 return std::make_tuple(std::make_shared<LinearOperator<Matrix, Vector, Is>>(m[Dune::index_constant<Is>{}][Dune::index_constant<Is>{}])...);
512 }
513
514 Dune::InverseOperatorResult result_;
515 };
516
517 // \}
518
519 } // end namespace Dumux
520
521 #endif
522