GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/linear/symmetrize_constraints.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 37 37 100.0%
Functions: 21 21 100.0%
Branches: 22 30 73.3%

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-FileCopyrightText: 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 Helper function to symmetrize row-constraints in constrained linear systems
11 */
12 #ifndef DUMUX_LINEAR_SYMMETRIZE_CONSTRAINTS_HH
13 #define DUMUX_LINEAR_SYMMETRIZE_CONSTRAINTS_HH
14
15 #include <iostream>
16
17 #include <dune/common/hybridutilities.hh>
18 #include <dune/common/fmatrix.hh>
19 #include <dune/istl/bcrsmatrix.hh>
20 #include <dune/istl/multitypeblockmatrix.hh>
21
22 namespace Dumux::Detail {
23
24 // loop over dense matrix block: end of recursion (actually do some work)
25 template<class K, int rows, int cols, class VectorRow, class VectorCol>
26 3161866 void symmetrizeConstraintsImpl(Dune::FieldMatrix<K, rows, cols>& A,
27 VectorRow& bRow, const VectorCol& bCol,
28 const VectorCol& constrainedRows,
29 bool isDiagonal)
30 {
31
3/4
✓ Branch 0 taken 2981507 times.
✓ Branch 1 taken 973913 times.
✓ Branch 2 taken 276029 times.
✗ Branch 3 not taken.
7145292 for (int j = 0; j < A.M(); ++j)
32 {
33 // all rows in this column can be eliminated by a Dirichlet row
34
2/2
✓ Branch 0 taken 120780 times.
✓ Branch 1 taken 1831040 times.
5209356 const auto& constrainedRowsJ = constrainedRows[j];
35
3/4
✓ Branch 0 taken 166618 times.
✓ Branch 1 taken 2814889 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 276029 times.
5209356 if (constrainedRowsJ > 0.5)
36 {
37
2/4
✓ Branch 0 taken 304354 times.
✓ Branch 1 taken 144738 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
811414 for (int i = 0; i < A.N(); ++i)
38 {
39
2/2
✓ Branch 0 taken 224832 times.
✓ Branch 1 taken 33684 times.
562870 auto& Aij = A[i][j];
40
2/4
✓ Branch 0 taken 40932 times.
✓ Branch 1 taken 24310 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
562870 auto& bi = bRow[i];
41
2/2
✓ Branch 0 taken 224832 times.
✓ Branch 1 taken 33684 times.
562870 const auto& bj = bCol[j];
42
2/4
✓ Branch 0 taken 265764 times.
✓ Branch 1 taken 38590 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
562870 if (!((i == j) && isDiagonal))
43 {
44 529404 bi -= Aij*bj;
45 529404 Aij = 0.0;
46 }
47 }
48 }
49 }
50 1856150 }
51
52 // recursively loop over sub-blocks
53 template<class MBlock, class VectorRow, class VectorCol>
54 68 void symmetrizeConstraintsImpl(Dune::BCRSMatrix<MBlock>& A,
55 VectorRow& bRow, const VectorCol& bCol,
56 const VectorCol& constrainedRows,
57 bool isDiagonal)
58 {
59 68 const auto rowEnd = A.end();
60
2/2
✓ Branch 0 taken 438294 times.
✓ Branch 1 taken 48 times.
728198 for (auto row = A.begin(); row != rowEnd; ++row)
61 {
62 728130 const auto colEnd = row->end();
63
2/2
✓ Branch 0 taken 2233791 times.
✓ Branch 1 taken 438294 times.
4398653 for (auto col = row->begin(); col != colEnd; ++col)
64 {
65 3670523 const auto i = row.index();
66 3670523 const auto j = col.index();
67
68 3670523 auto& Aij = A[i][j];
69 3670523 auto& bi = bRow[i];
70 3670523 const auto& bj = bCol[j];
71 3670523 const auto& dj = constrainedRows[j];
72
73 5484896 symmetrizeConstraintsImpl(Aij, bi, bj, dj, ((i == j) && isDiagonal));
74 }
75 }
76 68 }
77
78 // recursively loop over sub-blocks
79 template<class... MBlock, class VectorRow, class VectorCol>
80 12 void symmetrizeConstraintsImpl(Dune::MultiTypeBlockMatrix<MBlock...>& A,
81 VectorRow& bRow, const VectorCol& bCol,
82 const VectorCol& constrainedRows,
83 bool isDiagonal)
84 {
85 using namespace Dune::Hybrid;
86 108 forEach(std::make_index_sequence<Dune::MultiTypeBlockMatrix<MBlock...>::N()>{}, [&](const auto i)
87 {
88 24 forEach(std::make_index_sequence<Dune::MultiTypeBlockMatrix<MBlock...>::M()>{}, [&](const auto j)
89 {
90 24 auto& Aij = A[i][j];
91 48 auto& bi = bRow[i];
92 24 const auto& bj = bCol[j];
93 48 const auto& dj = constrainedRows[j];
94
95 24 symmetrizeConstraintsImpl(Aij, bi, bj, dj, ((i == j) && isDiagonal));
96 });
97 });
98 12 }
99
100 } // end namespace Dumux::Detail
101
102 namespace Dumux {
103
104 /*!
105 * \ingroup Linear
106 * \brief Symmetrize the constrained system Ax=b
107 * \note The function addresses the case where some rows in the linear system have been replaced
108 * to fix a degree of freedom to a fixed value. A typical use case is strongly enforced Dirichlet constraints.
109 * To symmetrize the constraints in operator A, this function eliminates the corresponding column entries by
110 * bringing them to the right-hand side. Particularly, if matrix operator A was symmetric before incorporating
111 * constraints, calling this function restores the symmetry of operator A.
112 * \note the constrainedRows vector is the same shape and type as b and contains 1 for each row
113 * that corresponds to constraints (e.g. strongly enforced Dirichlet dofs) and 0 elsewhere
114 * \note this is a specialization for Dune::BCRSMatrix
115 */
116 template<class MBlock, class Vector>
117 void symmetrizeConstraints(Dune::BCRSMatrix<MBlock>& A, Vector& b, const Vector& constrainedRows)
118 {
119 Detail::symmetrizeConstraintsImpl(A, b, b, constrainedRows, true);
120 }
121
122 /*!
123 * \ingroup Linear
124 * \brief Symmetrize the constrained system Ax=b
125 * \note The function addresses the case where some rows in the linear system have been replaced
126 * to fix a degree of freedom to a fixed value. A typical use case is strongly enforced Dirichlet constraints.
127 * To symmetrize the constraints in operator A, this function eliminates the corresponding column entries by
128 * bringing them to the right-hand side. Particularly, if matrix operator A was symmetric before incorporating
129 * constraints, calling this function restores the symmetry of operator A.
130 * \note the constrainedRows vector is the same shape and type as b and contains 1 for each row
131 * that corresponds to constraints (e.g. strongly enforced Dirichlet dofs) and 0 elsewhere
132 * \note this is a specialization for Dune::MultiTypeBlockMatrix
133 */
134 template<class... MBlock, class Vector>
135 12 void symmetrizeConstraints(Dune::MultiTypeBlockMatrix<MBlock...>& A, Vector& b, const Vector& constrainedRows)
136 {
137 12 Detail::symmetrizeConstraintsImpl(A, b, b, constrainedRows, true);
138 12 }
139
140 } // end namespace Dumux
141
142 #endif
143