spline: some fixes to make Spline::intersect() work correctly
most of these issues are fallout from the conversion of the spline class from a moments (second derivative) based approach to hermite base functions: - the second and third derivatives where incorrect, and the third derivative was not available in the public interface. - The unit test did not check the derivatives - The coefficients for the monomial basis were off by the factors stemming from the derivatives - The intersectIntervall_() method used std::max() instead of std::min() at one place and still added the base offset for the x values as indicated by Stoer
This commit is contained in:
1 parent
86ca995629
commit
c9067c4bda
2 files changed
+80
-15
No files matched your search
+44
-1
@@ -50,6 +50,7 @@ void testCommon(const Spline &sp,
|
||||
const double *y)
|
||||
{
|
||||
static double eps = 1e-10;
|
||||
static double epsFD = 1e-7;
|
||||
|
||||
int n = sp.numSamples();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
@@ -73,7 +74,49 @@ void testCommon(const Spline &sp,
|
||||
|
||||
if (std::abs(d1 - d0) > 1000*eps || std::abs(d2 - d0) > 1000*eps)
|
||||
OPM_THROW(std::runtime_error,
|
||||
"Spline seems to exhibit a discontinuous derivative at sampling point " << i << "!");
|
||||
"Spline seems to exhibit a discontinuous derivative at sampling point " << i << "!");
|
||||
}
|
||||
|
||||
// make sure the derivatives are consistent with the curve
|
||||
int np = 3*n;
|
||||
for (int i = 0; i < np; ++i) {
|
||||
double x = sp.xMin() + (sp.xMax() - sp.xMin())*i/np;
|
||||
|
||||
// first derivative
|
||||
double y1 = sp.eval(x+epsFD);
|
||||
double y0 = sp.eval(x);
|
||||
|
||||
double mFD = (y1 - y0)/epsFD;
|
||||
double m = sp.evalDerivative(x);
|
||||
|
||||
if (std::abs( mFD - m ) > 1000*epsFD)
|
||||
OPM_THROW(std::runtime_error,
|
||||
"Derivative of spline seems to be inconsistent with cuve"
|
||||
" (" << mFD << " - " << m << " = " << mFD - m << ")!");
|
||||
|
||||
// second derivative
|
||||
y1 = sp.evalDerivative(x+epsFD);
|
||||
y0 = sp.evalDerivative(x);
|
||||
|
||||
mFD = (y1 - y0)/epsFD;
|
||||
m = sp.evalSecondDerivative(x);
|
||||
|
||||
if (std::abs( mFD - m ) > 1000*epsFD)
|
||||
OPM_THROW(std::runtime_error,
|
||||
"Second derivative of spline seems to be inconsistent with cuve"
|
||||
" (" << mFD << " - " << m << " = " << mFD - m << ")!");
|
||||
|
||||
// Third derivative
|
||||
y1 = sp.evalSecondDerivative(x+epsFD);
|
||||
y0 = sp.evalSecondDerivative(x);
|
||||
|
||||
mFD = (y1 - y0)/epsFD;
|
||||
m = sp.evalThirdDerivative(x);
|
||||
|
||||
if (std::abs( mFD - m ) > 1000*epsFD)
|
||||
OPM_THROW(std::runtime_error,
|
||||
"Third derivative of spline seems to be inconsistent with cuve"
|
||||
" (" << mFD << " - " << m << " = " << mFD - m << ")!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user