From 69c73bc3453848943847e816123c4e19f9c11ef3 Mon Sep 17 00:00:00 2001 From: Kilian Cooley Date: Fri, 21 Aug 2026 11:21:42 -0400 Subject: [PATCH 1/4] fix: Use low BC value for low extrapolation with linear splines Previously the high BC value was used, which would give incorrect results unless both BCs had the same value. See #80 --- src/magnet/magnet/math/spline.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/magnet/magnet/math/spline.hpp b/src/magnet/magnet/math/spline.hpp index 9550b8e65..fc99c5913 100644 --- a/src/magnet/magnet/math/spline.hpp +++ b/src/magnet/magnet/math/spline.hpp @@ -135,7 +135,7 @@ class Spline : private std::vector> { const double lx = xval - x(0); if (_type == LINEAR) - return lx * _BCHighVal + y(0); + return lx * _BCLowVal + y(0); const double firstDeriv = (y(1) - y(0)) / h(0) - 2 * h(0) * (_data[0].b + 2 * _data[1].b) / 6; From be4a9955333b80819ae13c2b93130655aa77ba8b Mon Sep 17 00:00:00 2001 From: Kilian Cooley Date: Fri, 21 Aug 2026 11:23:44 -0400 Subject: [PATCH 2/4] fix: First-derivative calculation for low extrapolation of splines The difference formula for the first derivative at the left endpoint was incorrect. Instead, use the linear coefficient of the spline polynomial over the first interval, since that is the first derivative at the low endpoint. See #80 --- src/magnet/magnet/math/spline.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/magnet/magnet/math/spline.hpp b/src/magnet/magnet/math/spline.hpp index fc99c5913..54e2d9a36 100644 --- a/src/magnet/magnet/math/spline.hpp +++ b/src/magnet/magnet/math/spline.hpp @@ -137,8 +137,7 @@ class Spline : private std::vector> { if (_type == LINEAR) return lx * _BCLowVal + y(0); - const double firstDeriv = - (y(1) - y(0)) / h(0) - 2 * h(0) * (_data[0].b + 2 * _data[1].b) / 6; + const double firstDeriv = _data[0].c; switch (_BCLow) { case FIXED_1ST_DERIV_BC: From 1fe0bb1b8eeb51c76a8e59c931672b9374ad23c1 Mon Sep 17 00:00:00 2001 From: Kilian Cooley Date: Fri, 21 Aug 2026 11:25:33 -0400 Subject: [PATCH 3/4] fix: First-derivative calculation for high extrapolation of splines The formula for the first derivative at the high endpoint was incorrect, having an erroneous factor of 2 on the first term. See #80 --- src/magnet/magnet/math/spline.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/magnet/magnet/math/spline.hpp b/src/magnet/magnet/math/spline.hpp index 54e2d9a36..9449fc4c4 100644 --- a/src/magnet/magnet/math/spline.hpp +++ b/src/magnet/magnet/math/spline.hpp @@ -157,7 +157,7 @@ class Spline : private std::vector> { return lx * _BCHighVal + y(size() - 1); const double firstDeriv = - 2 * h(size() - 2) * (_ddy[size() - 2] + 2 * _ddy[size() - 1]) / 6 + + h(size() - 2) * (_ddy[size() - 2] + 2 * _ddy[size() - 1]) / 6 + (y(size() - 1) - y(size() - 2)) / h(size() - 2); switch (_BCHigh) { From 4362b382182f5670bca14a1fa5ccf58b586d2e13 Mon Sep 17 00:00:00 2001 From: Kilian Cooley Date: Fri, 21 Aug 2026 11:26:42 -0400 Subject: [PATCH 4/4] fix: Quadratic terms for spline extrapolation Extrapolations using the second derivative were missing coefficients of 0.5, resulting in incorrect values. See #80 --- src/magnet/magnet/math/spline.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/magnet/magnet/math/spline.hpp b/src/magnet/magnet/math/spline.hpp index 9449fc4c4..6ba479c81 100644 --- a/src/magnet/magnet/math/spline.hpp +++ b/src/magnet/magnet/math/spline.hpp @@ -143,9 +143,9 @@ class Spline : private std::vector> { case FIXED_1ST_DERIV_BC: return lx * _BCLowVal + y(0); case FIXED_2ND_DERIV_BC: - return lx * lx * _BCLowVal + firstDeriv * lx + y(0); + return 0.5 * lx * lx * _BCLowVal + firstDeriv * lx + y(0); case PARABOLIC_RUNOUT_BC: - return lx * lx * _ddy[0] + lx * firstDeriv + y(0); + return 0.5 * lx * lx * _ddy[0] + lx * firstDeriv + y(0); } throw std::runtime_error("Unknown BC"); } @@ -164,9 +164,9 @@ class Spline : private std::vector> { case FIXED_1ST_DERIV_BC: return lx * _BCHighVal + y(size() - 1); case FIXED_2ND_DERIV_BC: - return lx * lx * _BCHighVal + firstDeriv * lx + y(size() - 1); + return 0.5 * lx * lx * _BCHighVal + firstDeriv * lx + y(size() - 1); case PARABOLIC_RUNOUT_BC: - return lx * lx * _ddy[size() - 1] + lx * firstDeriv + y(size() - 1); + return 0.5 * lx * lx * _ddy[size() - 1] + lx * firstDeriv + y(size() - 1); } throw std::runtime_error("Unknown BC"); }