GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/common/tabulated2dfunction.hh
Date: 2024-09-21 20:52:54
Exec Total Coverage
Lines: 35 35 100.0%
Functions: 5 5 100.0%
Branches: 14 28 50.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-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 tabulation for a two-dimensional function.
11 */
12 #ifndef DUMUX_TABULATED_2D_FUNCTION_HH
13 #define DUMUX_TABULATED_2D_FUNCTION_HH
14
15 #include <vector>
16 #include <cassert>
17 #include <algorithm>
18
19 namespace Dumux {
20
21 /*!
22 * \ingroup Core
23 * \brief Implements tabulation for a two-dimensional function.
24 *
25 * This class can be used to tabulate a two dimensional function
26 * \f$f(x, y)\f$ over the range \f$[x_{min}, x_{max}] \times [y_{min},
27 * y_{max}]\f$. For this, the ranges of the \f$x\f$ and \f$y\f$ axes are
28 * divided into \f$m\f$ and \f$n\f$ sub-intervals and the values of
29 * \f$f(x_i, y_j)\f$ need to be provided. Here, \f$x_i\f$ and
30 * \f$y_j\f$ are the largest positions of the \f$i\f$-th and
31 * \f$j\f$-th interval. Between these sampling points this tabulation
32 * class uses linear interpolation.
33 */
34 template<class Scalar>
35 class Tabulated2DFunction
36 {
37 public:
38 /*!
39 * \brief Default constructor.
40 */
41 Tabulated2DFunction()
42 { };
43
44 /*!
45 * \brief Constructor where the tabulation parameters are already
46 * provided.
47 */
48 Tabulated2DFunction(Scalar xMin, Scalar xMax, int m,
49 Scalar yMin, Scalar yMax, int n)
50 {
51 resize(xMin, xMax, m, yMin, yMax, n);
52 };
53
54 /*!
55 * \brief Resize the tabulation to a new range.
56 *
57 * \note _All_ previously specified sampling points become invalid
58 * after calling this method. You have to supply new ones.
59 */
60 void resize(Scalar xMin, Scalar xMax, int m,
61 Scalar yMin, Scalar yMax, int n)
62 {
63 2 samples_.resize(m*n);
64
65 6 m_ = m;
66 6 n_ = n;
67
68 6 xMin_ = xMin;
69 6 xMax_ = xMax;
70
71 6 yMin_ = yMin;
72 2 yMax_ = yMax;
73 }
74
75 /*!
76 * \brief Return the position on the x-axis of the i-th interval.
77 */
78 200 Scalar iToX(int i) const
79 {
80
2/4
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 200 times.
200 assert(0 <= i && i < m_);
81
82 200 return xMin_ + i*(xMax_ - xMin_)/(m_ - 1);
83 }
84
85 /*!
86 * \brief Return the position on the y-axis of the j-th interval.
87 */
88 40000 Scalar jToY(int j) const
89 {
90
2/4
✓ Branch 0 taken 40000 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40000 times.
40000 assert(0 <= j && j < n_);
91
92 40000 return yMin_ + j*(yMax_ - yMin_)/(n_ - 1);
93 }
94
95 /*!
96 * \brief Return the interval index of a given position on the x-axis.
97 *
98 * This method returns a *floating point* number. The integer part
99 * should be interpreted as interval, the decimal places are the
100 * position of the x value between the i-th and the (i+1)-th
101 * sample point.
102 */
103 Scalar xToI(Scalar x) const
104 {
105 44292 return (x - xMin_)/(xMax_ - xMin_)*(m_ - 1);
106 }
107
108
109 /*!
110 * \brief Return the interval index of a given position on the y-axis.
111 *
112 * This method returns a *floating point* number. The integer part
113 * should be interpreted as interval, the decimal places are the
114 * position of the y value between the j-th and the (j+1)-th
115 * sample point.
116 */
117 Scalar yToJ(Scalar y) const
118 {
119 44292 return (y - yMin_)/(yMax_ - yMin_)*(n_ - 1);
120 }
121
122
123 /*!
124 * \brief Get the value of the sample point which is at the
125 * intersection of the \f$i\f$-th interval of the x-Axis
126 * and the \f$j\f$-th of the y-Axis.
127 */
128 177168 Scalar getSamplePoint(int i, int j) const
129 {
130
2/4
✓ Branch 0 taken 177168 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 177168 times.
177168 assert(0 <= i && i < m_);
131
2/4
✓ Branch 0 taken 177168 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 177168 times.
177168 assert(0 <= j && j < n_);
132
133 354336 return samples_[j*m_ + i];
134 }
135
136 /*!
137 * \brief Set the value of the sample point which is at the
138 * intersection of the \f$i\f$-th interval of the x-Axis
139 * and the \f$j\f$-th of the y-Axis.
140 */
141 120000 void setSamplePoint(int i, int j, Scalar value)
142 {
143
2/4
✓ Branch 0 taken 120000 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 120000 times.
120000 assert(0 <= i && i < m_);
144
2/4
✓ Branch 0 taken 120000 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 120000 times.
120000 assert(0 <= j && j < n_);
145
146 240000 samples_[j*m_ + i] = value;
147 120000 }
148
149 /*!
150 * \brief Return an interpolated value.
151 */
152 44292 Scalar get(Scalar x, Scalar y) const
153 {
154 88584 Scalar alpha = xToI(x);
155 88584 Scalar beta = yToJ(y);
156
157 using std::clamp;
158
1/2
✓ Branch 0 taken 44292 times.
✗ Branch 1 not taken.
44292 int i = clamp(static_cast<int>(alpha), 0, m_ - 2);
159
1/2
✓ Branch 0 taken 44292 times.
✗ Branch 1 not taken.
44292 int j = clamp(static_cast<int>(beta), 0, n_ - 2);
160
161 44292 alpha -= i;
162 44292 beta -= j;
163
164 // bi-linear interpolation
165 44292 Scalar s1 = getSamplePoint(i, j)*(1.0 - alpha) + getSamplePoint(i + 1, j)*alpha;
166 44292 Scalar s2 = getSamplePoint(i, j + 1)*(1.0 - alpha) + getSamplePoint(i + 1, j + 1)*alpha;
167 44292 return s1*(1.0 - beta) + s2*beta;
168 }
169
170 /*!
171 * \brief The () operator
172 *
173 * This is just a convenience alias for get(x,y);
174 */
175 Scalar operator()(Scalar x, Scalar y) const
176 44292 { return get(x, y); }
177
178 private:
179 // the vector which contains the values of the sample points
180 // f(x_i, y_j). don't use this directly, use getSamplePoint(i,j)
181 // instead!
182 std::vector<Scalar> samples_;
183
184 // the number of sample points in x direction
185 int m_;
186
187 // the number of sample points in y direction
188 int n_;
189
190 // the range of the tabulation on the x axis
191 Scalar xMin_;
192 Scalar xMax_;
193
194 // the range of the tabulation on the y axis
195 Scalar yMin_;
196 Scalar yMax_;
197
198 };
199
200 } // end namespace Dumux
201
202 #endif
203