28 #ifndef OPM_INTERVAL_TABULATED_2D_FUNCTION_HPP 29 #define OPM_INTERVAL_TABULATED_2D_FUNCTION_HPP 41 #include <type_traits> 52 template <
class Scalar>
59 template <
class DataContainer>
61 const std::vector<Scalar>& yPos,
62 const DataContainer& data,
63 const bool xExtrapolate =
false,
64 const bool yExtrapolate =
false)
68 , xExtrapolate_(xExtrapolate)
69 , yExtrapolate_(yExtrapolate)
74 for (
unsigned i = 0; i < xPos.size() - 1; ++ i) {
75 if (xPos[i + 1] <= xPos[i])
76 throw std::runtime_error(
"The array for the x-positions is not strictly increasing!");
79 for (
unsigned i = 0; i < yPos.size() - 1; ++ i) {
80 if (yPos[i + 1] <= yPos[i])
81 throw std::runtime_error(
"The array for the y-positions is not strictly increasing!");
86 if (
numX() != samples_.size())
87 throw std::runtime_error(
"numX() is not equal to the number of rows of the sampling points");
89 for (
unsigned xIdx = 0; xIdx <
numX(); ++xIdx) {
90 if (samples_[xIdx].size() !=
numY()) {
91 throw std::runtime_error(
"The " + std::to_string(xIdx) +
92 "-th row of the sampling points has " 93 "different size than numY() ");
102 {
return xPos_.size(); }
108 {
return yPos_.size(); }
114 {
return xPos_.front(); }
120 {
return xPos_.back(); }
126 {
return yPos_.front(); }
132 {
return yPos_.back(); }
134 const std::vector<Scalar>& xPos()
const 137 const std::vector<Scalar>& yPos()
const 140 const std::vector<std::vector<Scalar>>& samples()
const 143 bool xExtrapolate()
const 144 {
return xExtrapolate_; }
146 bool yExtrapolate()
const 147 {
return yExtrapolate_; }
149 bool operator==(
const IntervalTabulated2DFunction<Scalar>& data)
const {
150 return this->xPos() == data.xPos() &&
151 this->yPos() == data.yPos() &&
152 this->samples() == data.samples() &&
153 this->xExtrapolate() == data.xExtrapolate() &&
154 this->yExtrapolate() == data.yExtrapolate();
160 Scalar
valueAt(std::size_t i, std::size_t j)
const 161 {
return samples_[i][j]; }
166 template <
class Evaluation>
167 bool applies(
const Evaluation& x,
const Evaluation& y)
const 173 template <
class Evaluation>
175 {
return xMin() <= x && x <=
xMax(); }
180 template <
class Evaluation>
182 {
return yMin() <= y && y <=
yMax(); }
192 template <
typename Evaluation>
193 Evaluation
eval(
const Evaluation& x,
const Evaluation& y)
const 196 if constexpr (std::is_floating_point_v<Evaluation>) {
198 std::to_string(x) +
", " +
199 std::to_string(y) +
")");
202 std::to_string(x.value()) +
", " +
203 std::to_string(y.value()) +
")");
209 const unsigned i = xSegmentIndex_(x);
210 const unsigned j = ySegmentIndex_(y);
213 const Evaluation alpha = xToAlpha(x, i);
214 const Evaluation beta = yToBeta(y, j);
216 const Evaluation s1 =
valueAt(i, j) * (1.0 - beta) +
valueAt(i, j + 1) * beta;
217 const Evaluation s2 =
valueAt(i + 1, j) * (1.0 - beta) +
valueAt(i + 1, j + 1) * beta;
219 Valgrind::CheckDefined(s1);
220 Valgrind::CheckDefined(s2);
223 return s1*(1.0 - alpha) + s2*alpha;
228 std::vector<Scalar> xPos_;
230 std::vector<Scalar> yPos_;
232 std::vector<std::vector<Scalar> > samples_;
234 bool xExtrapolate_ =
false;
235 bool yExtrapolate_ =
false;
240 template <
class Evaluation>
241 unsigned xSegmentIndex_(
const Evaluation& x)
const 243 assert(xExtrapolate_ ||
appliesX(x) );
245 return segmentIndex_(x, xPos_);
251 template <
class Evaluation>
252 unsigned ySegmentIndex_(
const Evaluation& y)
const 254 assert(yExtrapolate_ ||
appliesY(y) );
256 return segmentIndex_(y, yPos_);
260 template <
class Evaluation>
261 static unsigned segmentIndex_(
const Evaluation& v,
const std::vector<Scalar>& vPos)
263 const unsigned n = vPos.size();
266 if (v <= vPos.front() || n == 2)
268 else if (v >= vPos.back())
271 assert(n > 2 && v > vPos.front() && v < vPos.back());
275 std::size_t lowerIdx = 0;
276 std::size_t upperIdx = vPos.size() - 1;
277 while (lowerIdx + 1 < upperIdx) {
278 std::size_t pivotIdx = (lowerIdx + upperIdx) / 2;
279 if (v < vPos[pivotIdx])
285 assert(vPos[lowerIdx] <= v);
286 assert(v <= vPos[lowerIdx + 1]);
296 template <
class Evaluation>
297 Evaluation xToAlpha(
const Evaluation& x,
unsigned xSegmentIdx)
const 299 Scalar x1 = xPos_[xSegmentIdx];
300 Scalar x2 = xPos_[xSegmentIdx + 1];
301 return (x - x1)/(x2 - x1);
310 template <
class Evaluation>
311 Evaluation yToBeta(
const Evaluation& y,
unsigned ySegmentIdx)
const 313 Scalar y1 = yPos_[ySegmentIdx];
314 Scalar y2 = yPos_[ySegmentIdx + 1];
315 return (y - y1)/(y2 - y1);
bool applies(const Evaluation &x, const Evaluation &y) const
Returns true if a coordinate lies in the tabulated range.
Definition: IntervalTabulated2DFunction.hpp:167
Scalar valueAt(std::size_t i, std::size_t j) const
Returns the value of a sampling point.
Definition: IntervalTabulated2DFunction.hpp:160
Definition: Exceptions.hpp:39
Provides the OPM specific exception classes.
std::size_t numX() const
Returns the number of sampling points in X direction.
Definition: IntervalTabulated2DFunction.hpp:101
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
bool appliesX(const Evaluation &x) const
Returns true if a coordinate lies in the tabulated range on the x direction.
Definition: IntervalTabulated2DFunction.hpp:174
Scalar xMin() const
Returns the minimum of the X coordinate of the sampling points.
Definition: IntervalTabulated2DFunction.hpp:113
std::size_t numY() const
Returns the number of sampling points in Y direction.
Definition: IntervalTabulated2DFunction.hpp:107
Evaluation eval(const Evaluation &x, const Evaluation &y) const
Evaluate the function at a given (x,y) position.
Definition: IntervalTabulated2DFunction.hpp:193
Scalar yMin() const
Returns the minimum of the Y coordinate of the sampling points.
Definition: IntervalTabulated2DFunction.hpp:125
Scalar xMax() const
Returns the maximum of the X coordinate of the sampling points.
Definition: IntervalTabulated2DFunction.hpp:119
Some templates to wrap the valgrind client request macros.
Implements a function that depends on two variables.
Definition: IntervalTabulated2DFunction.hpp:53
Scalar yMax() const
Returns the maximum of the Y coordinate of the sampling points.
Definition: IntervalTabulated2DFunction.hpp:131
bool appliesY(const Evaluation &y) const
Returns true if a coordinate lies in the tabulated range on the y direction.
Definition: IntervalTabulated2DFunction.hpp:181