GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/common/variablelengthspline_.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 108 108 100.0%
Functions: 13 13 100.0%
Branches: 109 200 54.5%

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 Core
10 * \brief Implements a spline with a variable number of sampling points
11 */
12 #ifndef DUMUX_VARIABLE_LENGTH_SPLINE_HH
13 #define DUMUX_VARIABLE_LENGTH_SPLINE_HH
14
15 #include <dune/common/fvector.hh>
16 #include <dune/common/fmatrix.hh>
17 #include <dune/istl/bvector.hh>
18 #include <dune/istl/btdmatrix.hh>
19
20 #include "splinecommon_.hh"
21
22 namespace Dumux {
23
24 /*!
25 * \ingroup Core
26 * \brief The common code for all 3rd order polynomial splines with
27 * where the number of sampling points only known at run-time.
28 */
29 template<class ScalarT>
30
40/80
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
✓ Branch 34 taken 1 times.
✗ Branch 35 not taken.
✓ Branch 37 taken 2 times.
✗ Branch 38 not taken.
✓ Branch 40 taken 2 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 2 times.
✗ Branch 44 not taken.
✓ Branch 46 taken 2 times.
✗ Branch 47 not taken.
✓ Branch 49 taken 1 times.
✗ Branch 50 not taken.
✓ Branch 52 taken 1 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 1 times.
✗ Branch 56 not taken.
✓ Branch 58 taken 1 times.
✗ Branch 59 not taken.
✓ Branch 61 taken 1 times.
✗ Branch 62 not taken.
✓ Branch 64 taken 1 times.
✗ Branch 65 not taken.
✓ Branch 67 taken 1 times.
✗ Branch 68 not taken.
✓ Branch 70 taken 1 times.
✗ Branch 71 not taken.
✓ Branch 73 taken 1 times.
✗ Branch 74 not taken.
✓ Branch 76 taken 1 times.
✗ Branch 77 not taken.
✓ Branch 79 taken 1 times.
✗ Branch 80 not taken.
✓ Branch 82 taken 1 times.
✗ Branch 83 not taken.
✓ Branch 85 taken 1 times.
✗ Branch 86 not taken.
✓ Branch 88 taken 1 times.
✗ Branch 89 not taken.
✓ Branch 91 taken 1 times.
✗ Branch 92 not taken.
✓ Branch 94 taken 1 times.
✗ Branch 95 not taken.
✓ Branch 97 taken 1 times.
✗ Branch 98 not taken.
✓ Branch 100 taken 1 times.
✗ Branch 101 not taken.
✓ Branch 103 taken 1 times.
✗ Branch 104 not taken.
✓ Branch 106 taken 1 times.
✗ Branch 107 not taken.
✓ Branch 109 taken 1 times.
✗ Branch 110 not taken.
✓ Branch 112 taken 1 times.
✗ Branch 113 not taken.
✓ Branch 115 taken 1 times.
✗ Branch 116 not taken.
✓ Branch 118 taken 1 times.
✗ Branch 119 not taken.
44 class VariableLengthSpline_
31 : public SplineCommon_<ScalarT,
32 VariableLengthSpline_<ScalarT> >
33 {
34 friend class SplineCommon_<ScalarT, VariableLengthSpline_<ScalarT> >;
35
36 using Scalar = ScalarT;
37 using Vector = Dune::BlockVector<Dune::FieldVector<Scalar, 1> >;
38 using BTDMatrix = Dune::BTDMatrix<Dune::FieldMatrix<Scalar, 1, 1> >;
39
40 public:
41 /*!
42 * \brief Returns the number of sampling points.
43 */
44 int numSamples() const
45
3/8
✗ Branch 1 not taken.
✓ Branch 2 taken 160 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 131 times.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
625 { return xPos_.size(); }
46
47
48 ///////////////////////////////////////
49 ///////////////////////////////////////
50 ///////////////////////////////////////
51 // Full splines //
52 ///////////////////////////////////////
53 ///////////////////////////////////////
54 ///////////////////////////////////////
55
56 /*!
57 * \brief Set the sampling points and the boundary slopes of a
58 * full spline using C-style arrays.
59 *
60 * This method uses separate array-like objects for the values of
61 * the X and Y coordinates. In this context 'array-like' means
62 * that an access to the members is provided via the []
63 * operator. (e.g. C arrays, std::vector, std::array, etc.) Each
64 * array must be of size 'nSamples' at least. Also, the number of
65 * sampling points must be larger than 1.
66 */
67 template <class ScalarArrayX, class ScalarArrayY>
68 2 void setXYArrays(int nSamples,
69 const ScalarArrayX &x,
70 const ScalarArrayY &y,
71 Scalar m0, Scalar m1)
72 {
73
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(nSamples > 1);
74
75 2 setNumSamples_(nSamples);
76
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 2 times.
12 for (int i = 0; i < nSamples; ++i) {
77 20 xPos_[i] = x[i];
78 30 yPos_[i] = y[i];
79 }
80 2 makeFullSpline_(m0, m1);
81 2 }
82
83 /*!
84 * \brief Set the sampling points and the boundary slopes of a
85 * full spline using STL-compatible containers.
86 *
87 * This method uses separate STL-compatible containers for the
88 * values of the sampling points' X and Y
89 * coordinates. "STL-compatible" means that the container provides
90 * access to iterators using the begin(), end() methods and also
91 * provides a size() method. Also, the number of entries in the X
92 * and the Y containers must be equal and larger than 1.
93 */
94 template <class ScalarContainerX, class ScalarContainerY>
95 2 void setXYContainers(const ScalarContainerX &x,
96 const ScalarContainerY &y,
97 Scalar m0, Scalar m1)
98 {
99
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
6 assert(x.size() == y.size());
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(x.size() > 1);
101
102 2 setNumSamples_(x.size());
103 8 std::copy(x.begin(), x.end(), xPos_.begin());
104 8 std::copy(y.begin(), y.end(), yPos_.begin());
105 2 makeFullSpline_(m0, m1);
106 2 }
107
108 /*!
109 * \brief Set the sampling points and the boundary slopes of a
110 * full spline using a C-style array.
111 *
112 * This method uses a single array of sampling points, which are
113 * seen as an array-like object which provides access to the X and
114 * Y coordinates. In this context 'array-like' means that an
115 * access to the members is provided via the [] operator. (e.g. C
116 * arrays, std::vector, std::array, etc.) The array containing
117 * the sampling points must be of size 'nSamples' at least. Also,
118 * the number of sampling points must be larger than 1.
119 */
120 template <class PointArray>
121 1 void setArrayOfPoints(int nSamples,
122 const PointArray &points,
123 Scalar m0,
124 Scalar m1)
125 {
126 // a spline with no or just one sampling points? what an
127 // incredible bad idea!
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 assert(nSamples > 1);
129
130 1 setNumSamples_(nSamples);
131
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
6 for (int i = 0; i < nSamples; ++i) {
132 10 xPos_[i] = points[i][0];
133 15 yPos_[i] = points[i][1];
134 }
135 1 makeFullSpline_(m0, m1);
136 1 }
137
138 /*!
139 * \brief Set the sampling points and the boundary slopes of a
140 * full spline using a STL-compatible container of
141 * array-like objects.
142 *
143 * This method uses a single STL-compatible container of sampling
144 * points, which are assumed to be array-like objects storing the
145 * X and Y coordinates. "STL-compatible" means that the container
146 * provides access to iterators using the begin(), end() methods
147 * and also provides a size() method. Also, the number of entries
148 * in the X and the Y containers must be equal and larger than 1.
149 */
150 template <class XYContainer>
151 1 void setContainerOfPoints(const XYContainer &points,
152 Scalar m0,
153 Scalar m1)
154 {
155 // a spline with no or just one sampling points? what an
156 // incredible bad idea!
157
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
2 assert(points.size() > 1);
158
159 1 setNumSamples_(points.size());
160 1 typename XYContainer::const_iterator it = points.begin();
161 1 typename XYContainer::const_iterator endIt = points.end();
162
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1 times.
11 for (int i = 0; it != endIt; ++i, ++it) {
163 10 xPos_[i] = (*it)[0];
164 15 yPos_[i] = (*it)[1];
165 }
166
167 // make a full spline
168 1 makeFullSpline_(m0, m1);
169 1 }
170
171 /*!
172 * \brief Set the sampling points and the boundary slopes of a
173 * full spline using a STL-compatible container of
174 * tuple-like objects.
175 *
176 * This method uses a single STL-compatible container of sampling
177 * points, which are assumed to be tuple-like objects storing the
178 * X and Y coordinates. "tuple-like" means that the objects
179 * provide access to the x values via std::get<0>(obj) and to the
180 * y value via std::get<1>(obj) (e.g. std::tuple or
181 * std::pair). "STL-compatible" means that the container provides
182 * access to iterators using the begin(), end() methods and also
183 * provides a size() method. Also, the number of entries in the X
184 * and the Y containers must be equal and larger than 1.
185 */
186 template <class XYContainer>
187 1 void setContainerOfTuples(const XYContainer &points,
188 Scalar m0,
189 Scalar m1)
190 {
191 // resize internal arrays
192 1 setNumSamples_(points.size());
193 1 typename XYContainer::const_iterator it = points.begin();
194 1 typename XYContainer::const_iterator endIt = points.end();
195
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 for (int i = 0; it != endIt; ++i, ++it) {
196 15 xPos_[i] = std::get<0>(*it);
197 20 yPos_[i] = std::get<1>(*it);
198 }
199
200 // make a full spline
201 1 makeFullSpline_(m0, m1);
202 1 }
203
204 ///////////////////////////////////////
205 ///////////////////////////////////////
206 ///////////////////////////////////////
207 // Natural splines //
208 ///////////////////////////////////////
209 ///////////////////////////////////////
210 ///////////////////////////////////////
211 /*!
212 * \brief Set the sampling points natural spline using C-style arrays.
213 *
214 * This method uses separate array-like objects for the values of
215 * the X and Y coordinates. In this context 'array-like' means
216 * that an access to the members is provided via the []
217 * operator. (e.g. C arrays, std::vector, std::array, etc.) Each
218 * array must be of size 'nSamples' at least. Also, the number of
219 * sampling points must be larger than 1.
220 */
221 template <class ScalarArrayX, class ScalarArrayY>
222 2 void setXYArrays(int nSamples,
223 const ScalarArrayX &x,
224 const ScalarArrayY &y)
225 {
226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(nSamples > 1);
227
228 2 setNumSamples_(nSamples);
229
2/2
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 2 times.
12 for (int i = 0; i < nSamples; ++i) {
230 20 xPos_[i] = x[i];
231 30 yPos_[i] = y[i];
232 }
233
234 2 makeNaturalSpline_();
235 2 }
236
237 /*!
238 * \brief Set the sampling points of a natural spline using
239 * STL-compatible containers.
240 *
241 * This method uses separate STL-compatible containers for the
242 * values of the sampling points' X and Y
243 * coordinates. "STL-compatible" means that the container provides
244 * access to iterators using the begin(), end() methods and also
245 * provides a size() method. Also, the number of entries in the X
246 * and the Y containers must be equal and larger than 1.
247 */
248 template <class ScalarContainerX, class ScalarContainerY>
249 3 void setXYContainers(const ScalarContainerX &x,
250 const ScalarContainerY &y)
251 {
252
3/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
9 assert(x.size() == y.size());
253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 assert(x.size() > 1);
254
255 3 setNumSamples_(x.size());
256 12 std::copy(x.begin(), x.end(), xPos_.begin());
257 12 std::copy(y.begin(), y.end(), yPos_.begin());
258 3 makeNaturalSpline_();
259 3 }
260
261 /*!
262 * \brief Set the sampling points of a natural spline using a
263 * C-style array.
264 *
265 * This method uses a single array of sampling points, which are
266 * seen as an array-like object which provides access to the X and
267 * Y coordinates. In this context 'array-like' means that an
268 * access to the members is provided via the [] operator. (e.g. C
269 * arrays, std::vector, std::array, etc.) The array containing
270 * the sampling points must be of size 'nSamples' at least. Also,
271 * the number of sampling points must be larger than 1.
272 */
273 template <class PointArray>
274 1 void setArrayOfPoints(int nSamples,
275 const PointArray &points)
276 {
277 // a spline with no or just one sampling points? what an
278 // incredible bad idea!
279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 assert(nSamples > 1);
280
281 1 setNumSamples_(nSamples);
282
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 times.
6 for (int i = 0; i < nSamples; ++i) {
283 10 xPos_[i] = points[i][0];
284 15 yPos_[i] = points[i][1];
285 }
286 1 makeNaturalSpline_();
287 1 }
288
289 /*!
290 * \brief Set the sampling points of a natural spline using a
291 * STL-compatible container of array-like objects.
292 *
293 * This method uses a single STL-compatible container of sampling
294 * points, which are assumed to be array-like objects storing the
295 * X and Y coordinates. "STL-compatible" means that the container
296 * provides access to iterators using the begin(), end() methods
297 * and also provides a size() method. Also, the number of entries
298 * in the X and the Y containers must be equal and larger than 1.
299 */
300 template <class XYContainer>
301 1 void setContainerOfPoints(const XYContainer &points)
302 {
303 // a spline with no or just one sampling points? what an
304 // incredible bad idea!
305
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
2 assert(points.size() > 1);
306
307 1 setNumSamples_(points.size());
308 1 typename XYContainer::const_iterator it = points.begin();
309 1 typename XYContainer::const_iterator endIt = points.end();
310
4/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1 times.
11 for (int i = 0; it != endIt; ++ i, ++it) {
311 10 xPos_[i] = (*it)[0];
312 15 yPos_[i] = (*it)[1];
313 }
314
315 // make a natural spline
316 1 makeNaturalSpline_();
317 1 }
318
319 /*!
320 * \brief Set the sampling points of a natural spline using a
321 * STL-compatible container of tuple-like objects.
322 *
323 * This method uses a single STL-compatible container of sampling
324 * points, which are assumed to be tuple-like objects storing the
325 * X and Y coordinates. "tuple-like" means that the objects
326 * provide access to the x values via std::get<0>(obj) and to the
327 * y value via std::get<1>(obj) (e.g. std::tuple or
328 * std::pair). "STL-compatible" means that the container provides
329 * access to iterators using the begin(), end() methods and also
330 * provides a size() method. Also, the number of entries in the X
331 * and the Y containers must be equal and larger than 1.
332 */
333 template <class XYContainer>
334 1 void setContainerOfTuples(const XYContainer &points)
335 {
336 // resize internal arrays
337 1 setNumSamples_(points.size());
338 1 typename XYContainer::const_iterator it = points.begin();
339 1 typename XYContainer::const_iterator endIt = points.end();
340
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 for (int i = 0; it != endIt; ++i, ++it) {
341 15 xPos_[i] = std::get<0>(*it);
342 20 yPos_[i] = std::get<1>(*it);
343 }
344
345 // make a natural spline
346 1 makeNaturalSpline_();
347 1 }
348
349 protected:
350 /*!
351 * \brief Resizes the internal vectors to store the sample points.
352 */
353 15 void setNumSamples_(int nSamples)
354 {
355 15 xPos_.resize(nSamples);
356 15 yPos_.resize(nSamples);
357 15 m_.resize(nSamples);
358 15 }
359
360 /*!
361 * \brief Create a natural spline from the already set sampling points.
362 *
363 * Also creates temporary matrix and right hand side vector.
364 */
365 7 void makeFullSpline_(Scalar m0, Scalar m1)
366 {
367 7 BTDMatrix M(numSamples());
368
2/6
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
21 Vector d(numSamples());
369
370 // create linear system of equations
371
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 this->makeFullSystem_(M, d, m0, m1);
372
373 // solve for the moments
374
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
7 M.solve(m_, d);
375 7 }
376
377 /*!
378 * \brief Create a natural spline from the already set sampling points.
379 *
380 * Also creates temporary matrix and right hand side vector.
381 */
382 8 void makeNaturalSpline_()
383 {
384 8 BTDMatrix M(numSamples());
385
2/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
24 Vector d(numSamples());
386
387 // create linear system of equations
388
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 this->makeNaturalSystem_(M, d);
389
390 // solve for the moments
391
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 M.solve(m_, d);
392 8 }
393
394 /*!
395 * \brief Returns the x coordinate of the i-th sampling point.
396 */
397 Scalar x_(int i) const
398
22/40
✗ Branch 0 not taken.
✓ Branch 1 taken 397 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 397 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 397 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 397 times.
✓ Branch 8 taken 160 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 160 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 160 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 23 taken 170 times.
✓ Branch 24 taken 150 times.
✓ Branch 25 taken 170 times.
✓ Branch 26 taken 150 times.
✓ Branch 27 taken 131 times.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✓ Branch 30 taken 131 times.
✗ Branch 31 not taken.
✓ Branch 32 taken 131 times.
✓ Branch 33 taken 1 times.
✓ Branch 34 taken 1 times.
✓ Branch 36 taken 1 times.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 39 not taken.
✓ Branch 41 taken 141 times.
✓ Branch 42 taken 121 times.
✓ Branch 43 taken 141 times.
✓ Branch 44 taken 121 times.
3045 { return xPos_[i]; }
399
400 /*!
401 * \brief Returns the y coordinate of the i-th sampling point.
402 */
403 Scalar y_(int i) const
404 332 { return yPos_[i]; }
405
406 /*!
407 * \brief Returns the moment (i.e. second derivative) of the
408 * spline at the i-th sampling point.
409 */
410 Scalar moment_(int i) const
411 1889 { return m_[i]; }
412
413 Vector xPos_;
414 Vector yPos_;
415 Vector m_;
416 };
417
418 } // end namespace Dumux
419
420 #endif
421