GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: dumux/dumux/common/variablesbackend.hh
Date: 2025-04-12 19:19:20
Exec Total Coverage
Lines: 31 33 93.9%
Functions: 32 34 94.1%
Branches: 64 139 46.0%

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 Core
10 * \brief Backends for operations on different solution vector types
11 * or more generic variable classes to be used in places where
12 * several different types/layouts should be supported.
13 */
14 #ifndef DUMUX_COMMON_VARIABLES_BACKEND_HH
15 #define DUMUX_COMMON_VARIABLES_BACKEND_HH
16
17 #include <array>
18 #include <utility>
19 #include <type_traits>
20
21 #include <dune/common/indices.hh>
22 #include <dune/common/typetraits.hh>
23 #include <dune/common/hybridutilities.hh>
24 #include <dune/common/std/type_traits.hh>
25 #include <dune/common/typetraits.hh>
26 #include <dune/istl/bvector.hh>
27
28 #include <dumux/common/typetraits/isvalid.hh>
29
30 // forward declaration
31 namespace Dune {
32
33 template<class... Args>
34 class MultiTypeBlockVector;
35
36 } // end namespace Dune
37
38 namespace Dumux::Detail::DofBackend {
39
40 struct HasResize
41 {
42 template<class V>
43 auto operator()(const V& v) -> decltype(std::declval<V>().resize(0))
44 {}
45 };
46
47 template<class Vector>
48 static constexpr auto hasResize()
49 { return decltype( isValid(HasResize())(std::declval<Vector>()) )::value; }
50
51 } // end namespace Dumux::Detail::VariablesBackend
52
53 namespace Dumux {
54
55 /*!
56 * \ingroup Core
57 * \brief Class providing operations with primary variable vectors
58 */
59 template<class DofVector, bool isScalar = Dune::IsNumber<DofVector>::value>
60 class DofBackend;
61
62 /*!
63 * \ingroup Core
64 * \brief Specialization providing operations for scalar/number types
65 */
66 template<class Scalar>
67 class DofBackend<Scalar, true>
68 {
69 public:
70 using DofVector = Scalar; //!< the type of the dofs parametrizing the variables object
71 using SizeType = std::size_t;
72
73 //! Return the number of entries in the dof vector
74 static SizeType size(const DofVector& d)
75 { return 1; }
76
77 //! Make a zero-initialized dof vector instance
78 static DofVector zeros(SizeType size)
79 { return 0.0; }
80
81 //! Perform axpy operation (y += a * x)
82 template<class OtherDofVector>
83 54 static void axpy(Scalar a, const OtherDofVector& x, DofVector& y)
84 54 { y += a*x; }
85 };
86
87 /*!
88 * \ingroup Core
89 * \brief Specialization providing operations for block vectors
90 * \tparam Vector a type that is
91 * - default-constructible
92 * - has size() member
93 * - has resize(0) member
94 * - has axpy(a, x) member
95 */
96 template<class Vector>
97 class DofBackend<Vector, false>
98 {
99 public:
100 using DofVector = Vector; //!< the type of the dofs parametrizing the variables object
101 using SizeType = std::size_t;
102
103 //! Return the number of entries in the dof vector
104 17404 static SizeType size(const DofVector& d)
105
9/13
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 52 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 10 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 10 times.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 3 taken 13020 times.
17404 { return d.size(); }
106
107 //! Make a zero-initialized dof vector instance
108
1/2
✓ Branch 1 taken 16111 times.
✗ Branch 2 not taken.
16111 static DofVector zeros(SizeType size)
109 {
110 16111 DofVector d;
111 if constexpr (Detail::DofBackend::hasResize<Vector>())
112
1/2
✓ Branch 1 taken 16111 times.
✗ Branch 2 not taken.
16111 d.resize(size);
113 16111 return d;
114 }
115
116 //! Perform axpy operation (y += a * x)
117 template<class OtherDofVector>
118 51993 static void axpy(typename DofVector::field_type a, const OtherDofVector& x, DofVector& y)
119 {
120
22/40
✓ Branch 0 taken 47812835 times.
✓ Branch 1 taken 45632 times.
✓ Branch 2 taken 7119042 times.
✓ Branch 3 taken 6587 times.
✓ Branch 4 taken 1361427 times.
✓ Branch 5 taken 1136 times.
✓ Branch 6 taken 9569684 times.
✓ Branch 7 taken 21813 times.
✓ Branch 8 taken 376839 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 147780 times.
✓ Branch 11 taken 20 times.
✓ Branch 12 taken 15 times.
✓ Branch 13 taken 5 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 15 times.
✓ Branch 19 taken 5 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 12 times.
✓ Branch 25 taken 3 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✓ Branch 30 taken 12 times.
✓ Branch 31 taken 4 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
✓ Branch 36 taken 20 times.
✓ Branch 37 taken 4 times.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
66530276 for (typename DofVector::size_type i = 0; i < y.size(); ++i)
121 {
122 if constexpr (Dune::IsNumber<std::decay_t<decltype(y[0])>>::value)
123 74 y[i] += a*x[i];
124 else
125 100002787 y[i].axpy(a, x[i]);
126 }
127 42931 }
128 };
129
130 /*!
131 * \ingroup Core
132 * \brief Specialization providing operations for multitype block vectors
133 */
134 template<class... Blocks>
135 class DofBackend<Dune::MultiTypeBlockVector<Blocks...>, false>
136 {
137 using DV = Dune::MultiTypeBlockVector<Blocks...>;
138 static constexpr auto numBlocks = DV::size();
139
140 using VectorSizeInfo = std::array<std::size_t, numBlocks>;
141
142 public:
143 using DofVector = DV; //!< the type of the dofs parametrizing the variables object
144 using SizeType = VectorSizeInfo;
145
146 //! Return the number of entries in the sub-dof-vectors
147
4/6
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 2 taken 2404 times.
✓ Branch 1 taken 20 times.
2445 static SizeType size(const DofVector& d)
148 {
149 VectorSizeInfo result;
150 using namespace Dune::Hybrid;
151
4/6
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 2 taken 2404 times.
✓ Branch 1 taken 20 times.
2445 forEach(std::make_index_sequence<numBlocks>{}, [&](auto i) {
152
4/6
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 2 taken 2404 times.
✓ Branch 1 taken 20 times.
2445 result[i] = d[Dune::index_constant<i>{}].size();
153 });
154 return result;
155 }
156
157 //! Make a zero-initialized dof vector instance
158
1/2
✓ Branch 1 taken 2445 times.
✗ Branch 2 not taken.
2445 static DofVector zeros(const SizeType& size)
159 {
160 2445 DofVector result;
161 using namespace Dune::Hybrid;
162
1/2
✓ Branch 1 taken 2445 times.
✗ Branch 2 not taken.
2445 forEach(std::make_index_sequence<numBlocks>{}, [&](auto i) {
163 2445 result[Dune::index_constant<i>{}].resize(size[i]);
164 });
165 2445 return result;
166 }
167
168 //! Perform axpy operation (y += a * x)
169 template<class Scalar, class OtherDofVector, std::enable_if_t< Dune::IsNumber<Scalar>::value, int> = 0>
170 7689 static void axpy(Scalar a, const OtherDofVector& x, DofVector& y)
171 {
172 using namespace Dune::Hybrid;
173
4/12
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 6 taken 1240 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 6395 times.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✓ Branch 18 taken 42 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 12 times.
✗ Branch 23 not taken.
9866 forEach(std::make_index_sequence<numBlocks>{}, [&](auto i) {
174 14746 DofBackend<std::decay_t<decltype(y[Dune::index_constant<i>{}])>>::axpy(
175 12597 a, x[Dune::index_constant<i>{}], y[Dune::index_constant<i>{}]
176 );
177 });
178 }
179 };
180
181 namespace Detail {
182
183 template<class Vars>
184 using SolutionVectorType = typename Vars::SolutionVector;
185
186 template<class Vars, bool varsExportSolution>
187 class VariablesBackend;
188
189 /*!
190 * \ingroup Core
191 * \brief Class providing operations for primary variable vector/scalar types
192 * \note We assume the variables being simply a dof vector if we
193 * do not find the variables class to export `SolutionVector`.
194 */
195 template<class Vars>
196 class VariablesBackend<Vars, false>
197 : public Dumux::DofBackend<Vars>
198 {
199 using ParentType = Dumux::DofBackend<Vars>;
200
201 public:
202 using Variables = Vars;
203 using typename ParentType::DofVector;
204
205 //! update to new solution vector
206 66902 static void update(Variables& v, const DofVector& dofs)
207
7/31
✓ Branch 1 taken 2985 times.
✗ 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 taken 5 times.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 27 taken 5 times.
✗ Branch 28 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✓ Branch 35 taken 3 times.
✗ Branch 36 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
✓ Branch 43 taken 4 times.
✗ Branch 44 not taken.
✗ Branch 48 not taken.
✗ Branch 49 not taken.
✓ Branch 51 taken 4 times.
✗ Branch 52 not taken.
✓ Branch 0 taken 2 times.
65895 { v = dofs; }
208
209 //! return const reference to dof vector
210 static const DofVector& dofs(const Variables& v)
211 { return v; }
212
213 //! return reference to dof vector
214 static DofVector& dofs(Variables& v)
215 { return v; }
216 };
217
218 /*!
219 * \ingroup Core
220 * \brief Class providing operations for generic variable classes,
221 * containing primary and possibly also secondary variables.
222 */
223 template<class Vars>
224 class VariablesBackend<Vars, true>
225 : public Dumux::DofBackend<typename Vars::SolutionVector>
226 {
227 public:
228 using DofVector = typename Vars::SolutionVector;
229 using Variables = Vars; //!< the type of the variables object
230
231 //! update to new solution vector
232 73 static void update(Variables& v, const DofVector& dofs)
233 73 { v.update(dofs); }
234
235 //! return const reference to dof vector
236 static const DofVector& dofs(const Variables& v)
237 { return v.dofs(); }
238
239 //! return reference to dof vector
240
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
113 static DofVector& dofs(Variables& v)
241
5/13
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 4 taken 25 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 15 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 15 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 38 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 3 not taken.
171 { return v.dofs(); }
242 };
243 } // end namespace Detail
244
245 /*!
246 * \ingroup Core
247 * \brief Class providing operations for generic variable classes
248 * that represent the state of a numerical solution, possibly
249 * consisting of primary/secondary variables and information on
250 * the time level.
251 */
252 template<class Vars>
253 using VariablesBackend = Detail::VariablesBackend<Vars, Dune::Std::is_detected_v<Detail::SolutionVectorType, Vars>>;
254
255 } // end namespace Dumux
256
257 #endif
258