27 #ifndef OPM_SPLINE_HPP 28 #define OPM_SPLINE_HPP 90 template<
class Scalar>
94 typedef std::vector<Scalar> Vector;
128 Scalar y0, Scalar y1,
129 Scalar m0, Scalar m1)
130 {
set(x0, x1, y0, y1, m0, m1); }
141 template <
class ScalarArrayX,
class ScalarArrayY>
143 const ScalarArrayX& x,
144 const ScalarArrayY& y,
146 bool sortInputs =
true)
147 { this->
setXYArrays(nSamples, x, y, splineType, sortInputs); }
157 template <
class Po
intArray>
159 const PointArray& points,
161 bool sortInputs =
true)
172 template <
class ScalarContainer>
174 const ScalarContainer& y,
176 bool sortInputs =
true)
186 template <
class Po
intContainer>
187 explicit Spline(
const PointContainer& points,
189 bool sortInputs =
true)
202 template <
class ScalarArray>
204 const ScalarArray& x,
205 const ScalarArray& y,
208 bool sortInputs =
true)
209 { this->
setXYArrays(nSamples, x, y, m0, m1, sortInputs); }
220 template <
class Po
intArray>
222 const PointArray& points,
225 bool sortInputs =
true)
237 template <
class ScalarContainerX,
class ScalarContainerY>
239 const ScalarContainerY& y,
242 bool sortInputs =
true)
253 template <
class Po
intContainer>
257 bool sortInputs =
true)
271 void set(Scalar x0, Scalar x1,
272 Scalar y0, Scalar y1,
273 Scalar m0, Scalar m1)
325 template <
class ScalarArrayX,
class ScalarArrayY>
327 const ScalarArrayX& x,
328 const ScalarArrayY& y,
329 Scalar m0, Scalar m1,
330 bool sortInputs =
true)
332 assert(nSamples > 1);
335 for (std::size_t i = 0; i < nSamples; ++i) {
359 template <
class ScalarContainerX,
class ScalarContainerY>
361 const ScalarContainerY& y,
362 Scalar m0, Scalar m1,
363 bool sortInputs =
true)
365 assert(x.size() == y.size());
366 assert(x.size() > 1);
370 std::ranges::copy(x, xPos_.begin());
371 std::ranges::copy(y, yPos_.begin());
393 template <
class Po
intArray>
395 const PointArray& points,
398 bool sortInputs =
true)
402 assert(nSamples > 1);
405 for (std::size_t i = 0; i < nSamples; ++i) {
406 xPos_[i] = points[i][0];
407 yPos_[i] = points[i][1];
430 template <
class XYContainer>
434 bool sortInputs =
true)
438 assert(points.size() > 1);
441 typename XYContainer::const_iterator it = points.begin();
442 typename XYContainer::const_iterator endIt = points.end();
443 for (std::size_t i = 0; it != endIt; ++i, ++it) {
472 template <
class XYContainer>
476 bool sortInputs =
true)
480 typename XYContainer::const_iterator it = points.begin();
481 typename XYContainer::const_iterator endIt = points.end();
482 for (
unsigned i = 0; it != endIt; ++i, ++it) {
483 xPos_[i] = std::get<0>(*it);
484 yPos_[i] = std::get<1>(*it);
513 template <
class ScalarArrayX,
class ScalarArrayY>
515 const ScalarArrayX& x,
516 const ScalarArrayY& y,
518 bool sortInputs =
true)
520 assert(nSamples > 1);
523 for (std::size_t i = 0; i < nSamples; ++i) {
533 if (splineType == Periodic)
535 else if (splineType == Natural)
537 else if (splineType == Monotonic)
540 throw std::runtime_error(
"Spline type "+std::to_string(
int(splineType))+
" not supported at this place");
554 template <
class ScalarContainerX,
class ScalarContainerY>
556 const ScalarContainerY& y,
558 bool sortInputs =
true)
560 assert(x.size() == y.size());
561 assert(x.size() > 1);
564 std::ranges::copy(x, xPos_.begin());
565 std::ranges::copy(y, yPos_.begin());
572 if (splineType == Periodic)
574 else if (splineType == Natural)
576 else if (splineType == Monotonic)
579 throw std::runtime_error(
"Spline type "+std::to_string(
int(splineType))+
" not supported at this place");
594 template <
class Po
intArray>
596 const PointArray& points,
598 bool sortInputs =
true)
602 assert(nSamples > 1);
605 for (std::size_t i = 0; i < nSamples; ++i) {
606 xPos_[i] = points[i][0];
607 yPos_[i] = points[i][1];
615 if (splineType == Periodic)
617 else if (splineType == Natural)
619 else if (splineType == Monotonic)
622 throw std::runtime_error(
"Spline type "+std::to_string(
int(splineType))+
" not supported at this place");
636 template <
class XYContainer>
639 bool sortInputs =
true)
643 assert(points.size() > 1);
646 typename XYContainer::const_iterator it = points.begin();
647 typename XYContainer::const_iterator endIt = points.end();
648 for (std::size_t i = 0; it != endIt; ++ i, ++it) {
658 if (splineType == Periodic)
660 else if (splineType == Natural)
662 else if (splineType == Monotonic)
665 throw std::runtime_error(
"Spline type "+std::to_string(
int(splineType))+
" not supported at this place");
682 template <
class XYContainer>
685 bool sortInputs =
true)
689 typename XYContainer::const_iterator it = points.begin();
690 typename XYContainer::const_iterator endIt = points.end();
691 for (
unsigned i = 0; it != endIt; ++i, ++it) {
692 xPos_[i] = std::get<0>(*it);
693 yPos_[i] = std::get<1>(*it);
701 if (splineType == Periodic)
703 else if (splineType == Natural)
705 else if (splineType == Monotonic)
708 throw std::runtime_error(
"Spline type "+std::to_string(
int(splineType))+
" not supported at this place");
714 template <
class Evaluation>
722 {
return xPos_.size(); }
727 Scalar
xAt(std::size_t sampleIdx)
const 728 {
return x_(sampleIdx); }
734 {
return y_(sampleIdx); }
753 void printCSV(Scalar xi0, Scalar xi1, std::size_t k, std::ostream& os)
const;
766 template <
class Evaluation>
767 Evaluation
eval(
const Evaluation& x,
bool extrapolate =
false)
const 769 if (!extrapolate && !
applies(x))
775 Scalar m = evalDerivative_(
xAt(0), 0);
777 return y0 + m*(x -
xAt(0));
779 else if (x >
xAt(static_cast<std::size_t>(static_cast<long int>(
numSamples()) - 1))) {
780 Scalar m = evalDerivative_(
xAt(static_cast<std::size_t>(
numSamples() - 1)),
782 Scalar y0 =
y_(static_cast<std::size_t>(
numSamples() - 1));
783 return y0 + m*(x -
xAt(static_cast<std::size_t>(
numSamples() - 1)));
787 return eval_(x, segmentIdx_(scalarValue(x)));
802 template <
class Evaluation>
805 if (!extrapolate && !
applies(x))
806 throw NumericalProblem(
"Tried to evaluate the derivative of a spline outside of its range");
811 return evalDerivative_(
xAt(0), 0);
816 return evalDerivative_(x, segmentIdx_(scalarValue(x)));
831 template <
class Evaluation>
834 if (!extrapolate && !
applies(x))
835 throw NumericalProblem(
"Tried to evaluate the second derivative of a spline outside of its range");
836 else if (extrapolate)
839 return evalDerivative2_(x, segmentIdx_(scalarValue(x)));
854 template <
class Evaluation>
857 if (!extrapolate && !
applies(x))
858 throw NumericalProblem(
"Tried to evaluate the third derivative of a spline outside of its range");
859 else if (extrapolate)
862 return evalDerivative3_(x, segmentIdx_(scalarValue(x)));
871 template <
class Evaluation>
875 const Evaluation& d)
const 886 template <
class Evaluation>
891 const Evaluation& d)
const 895 Evaluation tmpSol[3], sol = 0;
896 std::size_t nSol = 0;
897 std::size_t iFirst = segmentIdx_(x0);
898 std::size_t iLast = segmentIdx_(x1);
899 for (std::size_t i = iFirst; i <= iLast; ++i)
907 throw std::runtime_error(
"Spline has more than one intersection");
912 throw std::runtime_error(
"Spline has no intersection");
926 [[maybe_unused]]
bool extrapolate =
false)
const 928 assert(std::abs(x0 - x1) > 1e-30);
939 Scalar m = evalDerivative_(
xAt(0), 0);
940 if (std::abs(m) < 1e-20)
945 std::size_t i = segmentIdx_(x0);
946 if (
x_(i + 1) >= x1) {
949 monotonic_(i, x0, x1, r);
955 monotonic_(i, x0,
x_(i+1), r);
960 std::size_t iEnd = segmentIdx_(x1);
961 for (; i < iEnd - 1; ++i) {
962 monotonic_(i,
x_(i),
x_(i + 1), r);
975 return (r < 0 || r==3) ? -1 : 0;
977 return r > 0 ? 1 : 0;
983 monotonic_(iEnd,
x_(iEnd), x1, r);
1005 bool operator ()(
unsigned idxA,
unsigned idxB)
const 1006 {
return x_.at(idxA) < x_.at(idxB); }
1008 const std::vector<Scalar>& x_;
1019 std::vector<unsigned> idxVector(n);
1020 for (
unsigned i = 0; i < n; ++i)
1026 std::ranges::sort(idxVector, cmp);
1029 std::vector<Scalar> tmpX(n), tmpY(n);
1030 for (std::size_t i = 0; i < idxVector.size(); ++ i) {
1031 tmpX[i] = xPos_[idxVector[i]];
1032 tmpY[i] = yPos_[idxVector[i]];
1046 for (
unsigned i = 0; i <= (n - 1)/2; ++i) {
1047 std::swap(xPos_[i], xPos_[n - i - 1]);
1048 std::swap(yPos_[i], yPos_[n - i - 1]);
1057 xPos_.resize(nSamples);
1058 yPos_.resize(nSamples);
1059 slopeVec_.resize(nSamples);
1077 M.solve(moments, d);
1098 M.solve(moments, d);
1122 M.solve(moments, d);
1125 for (
int i = static_cast<int>(
numSamples()) - 2; i >= 0; --i) {
1126 unsigned ui =
static_cast<unsigned>(i);
1127 moments[ui+1] = moments[ui];
1141 template <
class DestVector,
class SourceVector>
1144 const SourceVector& srcX,
1145 const SourceVector& srcY,
1148 assert(nSamples >= 2);
1152 for (
unsigned i = 0; i < nSamples; ++i) {
1154 if (srcX[0] > srcX[nSamples - 1])
1155 idx = nSamples - i - 1;
1156 destX[i] = srcX[idx];
1157 destY[i] = srcY[idx];
1161 template <
class DestVector,
class ListIterator>
1162 void assignFromArrayList_(DestVector& destX,
1164 const ListIterator& srcBegin,
1165 const ListIterator& srcEnd,
1168 assert(nSamples >= 2);
1171 ListIterator it = srcBegin;
1173 bool reverse =
false;
1174 if ((*srcBegin)[0] > (*it)[0])
1179 for (
unsigned i = 0; it != srcEnd; ++i, ++it) {
1182 idx = nSamples - i - 1;
1183 destX[idx] = (*it)[0];
1184 destY[idx] = (*it)[1];
1195 template <
class DestVector,
class ListIterator>
1198 ListIterator srcBegin,
1199 ListIterator srcEnd,
1202 assert(nSamples >= 2);
1208 ListIterator it = srcBegin;
1210 bool reverse =
false;
1211 if (std::get<0>(*srcBegin) > std::get<0>(*it))
1216 for (
unsigned i = 0; it != srcEnd; ++i, ++it) {
1219 idx = nSamples - i - 1;
1220 destX[idx] = std::get<0>(*it);
1221 destY[idx] = std::get<1>(*it);
1229 template <
class Vector,
class Matrix>
1237 d[0] = 6/
h_(1) * ( (
y_(1) -
y_(0))/
h_(1) - m0);
1246 (m1 - (
y_(n) -
y_(n - 1))/
h_(n));
1253 template <
class Vector,
class Matrix>
1263 for (std::size_t i = 1; i < n; ++i) {
1264 Scalar lambda_i =
h_(i + 1) / (
h_(i) +
h_(i + 1));
1265 Scalar mu_i = 1 - lambda_i;
1267 6 / (
h_(i) +
h_(i + 1))
1269 ( (
y_(i + 1) -
y_(i))/
h_(i + 1) - (
y_(i) -
y_(i - 1))/
h_(i));
1273 M[i][i + 1] = lambda_i;
1278 Scalar lambda_0 = 0;
1299 template <
class Matrix,
class Vector>
1308 assert(M.rows() == n);
1311 for (std::size_t i = 2; i < n; ++i) {
1312 Scalar lambda_i =
h_(i + 1) / (
h_(i) +
h_(i + 1));
1313 Scalar mu_i = 1 - lambda_i;
1315 6 / (
h_(i) +
h_(i + 1))
1317 ( (
y_(i + 1) -
y_(i))/
h_(i + 1) - (
y_(i) -
y_(i - 1))/
h_(i));
1321 M[i-1][i] = lambda_i;
1325 Scalar lambda_n =
h_(1) / (
h_(n) +
h_(1));
1326 Scalar lambda_1 =
h_(2) / (
h_(1) +
h_(2));;
1327 Scalar mu_1 = 1 - lambda_1;
1328 Scalar mu_n = 1 - lambda_n;
1346 M[n-1][0] = lambda_n;
1360 template <
class Vector>
1366 std::vector<Scalar> delta(n);
1367 for (std::size_t k = 0; k < n - 1; ++k)
1368 delta[k] = (
y_(k + 1) -
y_(k))/(
x_(k + 1) -
x_(k));
1371 for (std::size_t k = 1; k < n - 1; ++k)
1372 slopes[k] = (delta[k - 1] + delta[k])/2;
1373 slopes[0] = delta[0];
1374 slopes[n - 1] = delta[n - 2];
1377 for (std::size_t k = 0; k < n - 1; ++k) {
1378 if (std::abs(delta[k]) < 1e-50) {
1386 Scalar alpha = slopes[k] / delta[k];
1387 Scalar beta = slopes[k + 1] / delta[k];
1389 if (alpha < 0 || (k > 0 && slopes[k] / delta[k - 1] < 0)) {
1393 else if (alpha*alpha + beta*beta > 3*3) {
1394 Scalar tau = 3.0/std::sqrt(alpha*alpha + beta*beta);
1395 slopes[k] = tau*alpha*delta[k];
1396 slopes[k + 1] = tau*beta*delta[k];
1409 template <
class MomentsVector,
class SlopeVector>
1420 Scalar h = this->
h_(n - 1);
1425 (
y_(n - 1) -
y_(n - 2))/h
1427 h/6*(moments[n-1] - moments[n - 2]);
1432 moments[n - 1] * x*x / (2 * h)
1438 for (std::size_t i = 0; i < n - 1; ++ i) {
1441 Scalar h_i = this->
h_(i + 1);
1446 (
y_(i+1) -
y_(i))/h_i
1448 h_i/6*(moments[i+1] - moments[i]);
1451 - moments[i] * x_i1*x_i1 / (2 * h_i)
1458 slopes[n - 1] = mRight;
1463 template <
class Evaluation>
1464 Evaluation eval_(
const Evaluation& x, std::size_t i)
const 1467 Scalar delta =
h_(i + 1);
1468 Evaluation t = (x -
x_(i))/delta;
1472 + h10_(t) *
slope_(i)*delta
1473 + h01_(t) *
y_(i + 1)
1474 + h11_(t) *
slope_(i + 1)*delta;
1479 template <
class Evaluation>
1480 Evaluation evalDerivative_(
const Evaluation& x, std::size_t i)
const 1483 Scalar delta =
h_(i + 1);
1484 Evaluation t = (x -
x_(i))/delta;
1485 Evaluation alpha = 1 / delta;
1489 (h00_prime_(t) *
y_(i)
1490 + h10_prime_(t) *
slope_(i)*delta
1491 + h01_prime_(t) *
y_(i + 1)
1492 + h11_prime_(t) *
slope_(i + 1)*delta);
1497 template <
class Evaluation>
1498 Evaluation evalDerivative2_(
const Evaluation& x, std::size_t i)
const 1501 Scalar delta =
h_(i + 1);
1502 Evaluation t = (x -
x_(i))/delta;
1503 Evaluation alpha = 1 / delta;
1507 *(h00_prime2_(t) *
y_(i)
1508 + h10_prime2_(t) *
slope_(i)*delta
1509 + h01_prime2_(t) *
y_(i + 1)
1510 + h11_prime2_(t) *
slope_(i + 1)*delta);
1515 template <
class Evaluation>
1516 Evaluation evalDerivative3_(
const Evaluation& x, std::size_t i)
const 1519 Scalar delta =
h_(i + 1);
1520 Evaluation t = (x -
x_(i))/delta;
1521 Evaluation alpha = 1 / delta;
1525 *(h00_prime3_(t)*
y_(i)
1526 + h10_prime3_(t)*
slope_(i)*delta
1527 + h01_prime3_(t)*
y_(i + 1)
1528 + h11_prime3_(t)*
slope_(i + 1)*delta);
1532 template <
class Evaluation>
1533 Evaluation h00_(
const Evaluation& t)
const 1534 {
return (2*t - 3)*t*t + 1; }
1536 template <
class Evaluation>
1537 Evaluation h10_(
const Evaluation& t)
const 1538 {
return ((t - 2)*t + 1)*t; }
1540 template <
class Evaluation>
1541 Evaluation h01_(
const Evaluation& t)
const 1542 {
return (-2*t + 3)*t*t; }
1544 template <
class Evaluation>
1545 Evaluation h11_(
const Evaluation& t)
const 1546 {
return (t - 1)*t*t; }
1549 template <
class Evaluation>
1550 Evaluation h00_prime_(
const Evaluation& t)
const 1551 {
return (3*2*t - 2*3)*t; }
1553 template <
class Evaluation>
1554 Evaluation h10_prime_(
const Evaluation& t)
const 1555 {
return (3*t - 2*2)*t + 1; }
1557 template <
class Evaluation>
1558 Evaluation h01_prime_(
const Evaluation& t)
const 1559 {
return (-3*2*t + 2*3)*t; }
1561 template <
class Evaluation>
1562 Evaluation h11_prime_(
const Evaluation& t)
const 1563 {
return (3*t - 2)*t; }
1566 template <
class Evaluation>
1567 Evaluation h00_prime2_(
const Evaluation& t)
const 1568 {
return 2*3*2*t - 2*3; }
1570 template <
class Evaluation>
1571 Evaluation h10_prime2_(
const Evaluation& t)
const 1572 {
return 2*3*t - 2*2; }
1574 template <
class Evaluation>
1575 Evaluation h01_prime2_(
const Evaluation& t)
const 1576 {
return -2*3*2*t + 2*3; }
1578 template <
class Evaluation>
1579 Evaluation h11_prime2_(
const Evaluation& t)
const 1580 {
return 2*3*t - 2; }
1583 template <
class Evaluation>
1584 Scalar h00_prime3_(
const Evaluation&)
const 1587 template <
class Evaluation>
1588 Scalar h10_prime3_(
const Evaluation&)
const 1591 template <
class Evaluation>
1592 Scalar h01_prime3_(
const Evaluation&)
const 1595 template <
class Evaluation>
1596 Scalar h11_prime3_(
const Evaluation&)
const 1607 int monotonic_(std::size_t i, Scalar x0, Scalar x1,
int& r)
const 1614 if (std::abs(a) < 1e-20 && std::abs(b) < 1e-20 && std::abs(c) < 1e-20)
1617 Scalar disc = b*b - 4*a*c;
1621 if (x0*(x0*a + b) + c > 0) {
1622 r = (r==3 || r == 1)?1:0;
1626 r = (r==3 || r == -1)?-1:0;
1630 disc = std::sqrt(disc);
1631 Scalar xE1 = (-b + disc)/(2*a);
1632 Scalar xE2 = (-b - disc)/(2*a);
1634 if (std::abs(disc) < 1e-30) {
1636 if (std::abs(xE1 - x0) < 1e-30)
1641 if (x0*(x0*a + b) + c > 0) {
1642 r = (r==3 || r == 1)?1:0;
1646 r = (r==3 || r == -1)?-1:0;
1650 if ((x0 < xE1 && xE1 < x1) ||
1651 (x0 < xE2 && xE2 < x1))
1660 if (x0*(x0*a + b) + c > 0) {
1661 r = (r==3 || r == 1)?1:0;
1665 r = (r==3 || r == -1)?-1:0;
1674 template <
class Evaluation>
1677 const Evaluation& a,
1678 const Evaluation& b,
1679 const Evaluation& c,
1680 const Evaluation& d,
1681 Scalar x0 = -1e30, Scalar x1 = 1e30)
const 1689 x0 = std::max(
x_(segIdx), x0);
1690 x1 = std::min(
x_(segIdx+1), x1);
1694 for (
unsigned j = 0; j < n; ++j) {
1695 if (x0 <= sol[j] && sol[j] <= x1) {
1704 std::size_t segmentIdx_(Scalar x)
const 1707 std::size_t iLow = 0;
1710 while (iLow + 1 < iHigh) {
1711 std::size_t i = (iLow + iHigh) / 2;
1723 Scalar
h_(std::size_t i)
const 1725 assert(
x_(i) >
x_(i-1));
1727 return x_(i) -
x_(i - 1);
1733 Scalar
x_(std::size_t i)
const 1734 {
return xPos_[i]; }
1739 Scalar
y_(std::size_t i)
const 1740 {
return yPos_[i]; }
1747 {
return slopeVec_[i]; }
1751 Scalar a_(std::size_t i)
const 1752 {
return evalDerivative3_(Scalar(0.0), i)/6.0; }
1756 Scalar b_(std::size_t i)
const 1757 {
return evalDerivative2_(Scalar(0.0), i)/2.0; }
1761 Scalar c_(std::size_t i)
const 1762 {
return evalDerivative_(Scalar(0.0), i); }
1766 Scalar d_(std::size_t i)
const 1767 {
return eval_(Scalar(0.0), i); }
Scalar xAt(std::size_t sampleIdx) const
Return the x value of a given sampling point.
Definition: Spline.hpp:727
Definition: Exceptions.hpp:39
void assignSamplingPoints_(DestVector &destX, DestVector &destY, const SourceVector &srcX, const SourceVector &srcY, unsigned nSamples)
Set the sampling point vectors.
Definition: Spline.hpp:1142
Scalar y_(std::size_t i) const
Returns the y coordinate of the i-th sampling point.
Definition: Spline.hpp:1739
void setXYArrays(std::size_t nSamples, const ScalarArrayX &x, const ScalarArrayY &y, SplineType splineType=Natural, bool sortInputs=true)
Set the sampling points natural spline using C-style arrays.
Definition: Spline.hpp:514
Scalar h_(std::size_t i) const
Returns x[i] - x[i - 1].
Definition: Spline.hpp:1723
void makeMonotonicSpline_(Vector &slopes)
Create a monotonic spline from the already set sampling points.
Definition: Spline.hpp:1361
Evaluation evalDerivative(const Evaluation &x, bool extrapolate=false) const
Evaluate the spline's derivative at a given position.
Definition: Spline.hpp:803
void sortInput_()
Sort the sample points in ascending order of their x value.
Definition: Spline.hpp:1014
SplineType
The type of the spline to be created.
Definition: Spline.hpp:102
Helper class needed to sort the input sampling points.
Definition: Spline.hpp:999
void makeFullSpline_(Scalar m0, Scalar m1)
Create a natural spline from the already set sampling points.
Definition: Spline.hpp:1067
Scalar slope_(std::size_t i) const
Returns the slope (i.e.
Definition: Spline.hpp:1746
Spline()
Default constructor for a spline.
Definition: Spline.hpp:114
Evaluation evalThirdDerivative(const Evaluation &x, bool extrapolate=false) const
Evaluate the spline's third derivative at a given position.
Definition: Spline.hpp:855
Provides free functions to invert polynomials of degree 1, 2 and 3.
void setXYContainers(const ScalarContainerX &x, const ScalarContainerY &y, Scalar m0, Scalar m1, bool sortInputs=true)
Set the sampling points and the boundary slopes of a full spline using STL-compatible containers...
Definition: Spline.hpp:360
Provides the OPM specific exception classes.
void setArrayOfPoints(std::size_t nSamples, const PointArray &points, SplineType splineType=Natural, bool sortInputs=true)
Set the sampling points of a natural spline using a C-style array.
Definition: Spline.hpp:595
std::size_t numSamples() const
Return the number of (x, y) values.
Definition: Spline.hpp:721
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
Spline(std::size_t nSamples, const PointArray &points, SplineType splineType=Natural, bool sortInputs=true)
Convenience constructor for a natural or a periodic spline.
Definition: Spline.hpp:158
int monotonic() const
Same as monotonic(x0, x1), but with the entire range of the spline as interval.
Definition: Spline.hpp:992
int monotonic(Scalar x0, Scalar x1, [[maybe_unused]] bool extrapolate=false) const
Returns 1 if the spline is monotonically increasing, -1 if the spline is mononously decreasing and 0 ...
Definition: Spline.hpp:925
Spline(const PointContainer &points, SplineType splineType=Natural, bool sortInputs=true)
Convenience constructor for a natural or a periodic spline.
Definition: Spline.hpp:187
void setNumSamples_(std::size_t nSamples)
Resizes the internal vectors to store the sample points.
Definition: Spline.hpp:1055
bool applies(const Evaluation &x) const
Return true iff the given x is in range [x1, xn].
Definition: Spline.hpp:715
void reverseSamplingPoints_()
Reverse order of the elements in the arrays which contain the sampling points.
Definition: Spline.hpp:1042
Spline(const ScalarContainer &x, const ScalarContainer &y, SplineType splineType=Natural, bool sortInputs=true)
Convenience constructor for a natural or a periodic spline.
Definition: Spline.hpp:173
Scalar x_(std::size_t i) const
Returns the y coordinate of the i-th sampling point.
Definition: Spline.hpp:1733
Evaluation intersectInterval(Scalar x0, Scalar x1, const Evaluation &a, const Evaluation &b, const Evaluation &c, const Evaluation &d) const
Find the intersections of the spline with a cubic polynomial in a sub-interval of the spline...
Definition: Spline.hpp:887
void setArrayOfPoints(std::size_t nSamples, const PointArray &points, Scalar m0, Scalar m1, bool sortInputs=true)
Set the sampling points and the boundary slopes of a full spline using a C-style array.
Definition: Spline.hpp:394
Evaluation evalSecondDerivative(const Evaluation &x, bool extrapolate=false) const
Evaluate the spline's second derivative at a given position.
Definition: Spline.hpp:832
void setXYContainers(const ScalarContainerX &x, const ScalarContainerY &y, SplineType splineType=Natural, bool sortInputs=true)
Set the sampling points of a natural spline using STL-compatible containers.
Definition: Spline.hpp:555
Spline(std::size_t nSamples, const ScalarArray &x, const ScalarArray &y, Scalar m0, Scalar m1, bool sortInputs=true)
Convenience constructor for a full spline.
Definition: Spline.hpp:203
Provides a tridiagonal matrix that also supports non-zero entries in the upper right and lower left...
std::size_t intersectSegment_(Evaluation *sol, std::size_t segIdx, const Evaluation &a, const Evaluation &b, const Evaluation &c, const Evaluation &d, Scalar x0=-1e30, Scalar x1=1e30) const
Find all the intersections of a segment of the spline with a cubic polynomial within a specified inte...
Definition: Spline.hpp:1675
void setContainerOfPoints(const XYContainer &points, SplineType splineType=Natural, bool sortInputs=true)
Set the sampling points of a natural spline using a STL-compatible container of array-like objects...
Definition: Spline.hpp:637
void makePeriodicSpline_()
Create a periodic spline from the already set sampling points.
Definition: Spline.hpp:1109
Scalar valueAt(std::size_t sampleIdx) const
Return the x value of a given sampling point.
Definition: Spline.hpp:733
unsigned invertCubicPolynomial(SolContainer *sol, Scalar a, Scalar b, Scalar c, Scalar d)
Invert a cubic polynomial analytically.
Definition: PolynomialUtils.hpp:149
Evaluation eval(const Evaluation &x, bool extrapolate=false) const
Evaluate the spline at a given position.
Definition: Spline.hpp:767
Provides a tridiagonal matrix that also supports non-zero entries in the upper right and lower left...
Definition: TridiagonalMatrix.hpp:50
void setXYArrays(std::size_t nSamples, const ScalarArrayX &x, const ScalarArrayY &y, Scalar m0, Scalar m1, bool sortInputs=true)
Set the sampling points and the boundary slopes of a full spline using C-style arrays.
Definition: Spline.hpp:326
Spline(const PointContainer &points, Scalar m0, Scalar m1, bool sortInputs=true)
Convenience constructor for a full spline.
Definition: Spline.hpp:254
Spline(const ScalarContainerX &x, const ScalarContainerY &y, Scalar m0, Scalar m1, bool sortInputs=true)
Convenience constructor for a full spline.
Definition: Spline.hpp:238
Spline(Scalar x0, Scalar x1, Scalar y0, Scalar y1, Scalar m0, Scalar m1)
Convenience constructor for a full spline with just two sampling points.
Definition: Spline.hpp:127
void makeFullSystem_(Matrix &M, Vector &d, Scalar m0, Scalar m1)
Make the linear system of equations Mx = d which results in the moments of the full spline...
Definition: Spline.hpp:1230
Spline(std::size_t nSamples, const PointArray &points, Scalar m0, Scalar m1, bool sortInputs=true)
Convenience constructor for a full spline.
Definition: Spline.hpp:221
void printCSV(Scalar xi0, Scalar xi1, std::size_t k, std::ostream &os) const
Prints k tuples of the format (x, y, dx/dy, isMonotonic) to stdout.
Definition: Spline.cpp:35
void setContainerOfTuples(const XYContainer &points, Scalar m0, Scalar m1, bool sortInputs=true)
Set the sampling points and the boundary slopes of a full spline using a STL-compatible container of ...
Definition: Spline.hpp:473
void setContainerOfTuples(const XYContainer &points, SplineType splineType=Natural, bool sortInputs=true)
Set the sampling points of a natural spline using a STL-compatible container of tuple-like objects...
Definition: Spline.hpp:683
Evaluation intersect(const Evaluation &a, const Evaluation &b, const Evaluation &c, const Evaluation &d) const
Find the intersections of the spline with a cubic polynomial in the whole interval, throws Opm::MathError exception if there is more or less than one solution.
Definition: Spline.hpp:872
void assignFromTupleList_(DestVector &destX, DestVector &destY, ListIterator srcBegin, ListIterator srcEnd, unsigned nSamples)
Set the sampling points.
Definition: Spline.hpp:1196
void makePeriodicSystem_(Matrix &M, Vector &d)
Make the linear system of equations Mx = d which results in the moments of the periodic spline...
Definition: Spline.hpp:1300
void makeNaturalSpline_()
Create a natural spline from the already set sampling points.
Definition: Spline.hpp:1088
Class implementing cubic splines.
Definition: Spline.hpp:91
void setSlopesFromMoments_(SlopeVector &slopes, const MomentsVector &moments)
Convert the moments at the sample points to slopes.
Definition: Spline.hpp:1410
void setContainerOfPoints(const XYContainer &points, Scalar m0, Scalar m1, bool sortInputs=true)
Set the sampling points and the boundary slopes of a full spline using a STL-compatible container of ...
Definition: Spline.hpp:431
Spline(std::size_t nSamples, const ScalarArrayX &x, const ScalarArrayY &y, SplineType splineType=Natural, bool sortInputs=true)
Convenience constructor for a natural or a periodic spline.
Definition: Spline.hpp:142
void makeNaturalSystem_(Matrix &M, Vector &d)
Make the linear system of equations Mx = d which results in the moments of the natural spline...
Definition: Spline.hpp:1254