From 6ee9f7452468a8520a6671345279f95115b73b16 Mon Sep 17 00:00:00 2001 From: Ben Dudson Date: Sat, 3 Feb 2024 11:14:39 -0800 Subject: [PATCH 1/2] Simplify XZInterpolation class Reduce duplication by moving some overloads to the base class. --- include/bout/interpolation_xz.hxx | 77 ++++++++------------ src/mesh/interpolation/bilinear_xz.cxx | 19 ----- src/mesh/interpolation/hermite_spline_xz.cxx | 19 ----- src/mesh/interpolation/lagrange_4pt_xz.cxx | 19 ----- src/mesh/interpolation_xz.cxx | 6 +- 5 files changed, 35 insertions(+), 105 deletions(-) diff --git a/include/bout/interpolation_xz.hxx b/include/bout/interpolation_xz.hxx index 3f8e37d3fd..8a815dfb6b 100644 --- a/include/bout/interpolation_xz.hxx +++ b/include/bout/interpolation_xz.hxx @@ -1,8 +1,7 @@ /************************************************************************** - * Copyright 2010-2020 B.D.Dudson, S.Farley, P. Hill, J.T. Omotani, J.T. Parker, - * M.V.Umansky, X.Q.Xu + * Copyright 2010-2024 BOUT++ contributors * - * Contact: Ben Dudson, bd512@york.ac.uk + * Contact: Ben Dudson, dudson2@llnl.gov * * This file is part of BOUT++. * @@ -21,8 +20,8 @@ * **************************************************************************/ -#ifndef __INTERP_XZ_H__ -#define __INTERP_XZ_H__ +#ifndef INTERP_XZ_H +#define INTERP_XZ_H #include "bout/mask.hxx" @@ -95,20 +94,30 @@ public: ASSERT1(has_region); return getRegion(); } + /// Calculate weights using given offsets in X and Z virtual void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const std::string& region = "RGN_NOBNDRY") = 0; - virtual void calcWeights(const Field3D& delta_x, const Field3D& delta_z, - const BoutMask& mask, - const std::string& region = "RGN_NOBNDRY") = 0; + void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, + const std::string& region = "RGN_NOBNDRY") { + setMask(mask); + calcWeights(delta_x, delta_z, region); + } + /// Use pre-calculated weights virtual Field3D interpolate(const Field3D& f, const std::string& region = "RGN_NOBNDRY") const = 0; - virtual Field3D interpolate(const Field3D& f, const Field3D& delta_x, - const Field3D& delta_z, - const std::string& region = "RGN_NOBNDRY") = 0; - virtual Field3D interpolate(const Field3D& f, const Field3D& delta_x, - const Field3D& delta_z, const BoutMask& mask, - const std::string& region = "RGN_NOBNDRY") = 0; + + /// Calculate weights then interpolate + Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, + const std::string& region = "RGN_NOBNDRY") { + calcWeights(delta_x, delta_z, region); + return interpolate(f, region); + } + Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, + const BoutMask& mask, const std::string& region = "RGN_NOBNDRY") { + calcWeights(delta_x, delta_z, mask, region); + return interpolate(f, region); + } // Interpolate using the field at (x,y+y_offset,z), rather than (x,y,z) void setYOffset(int offset) { y_offset = offset; } @@ -162,18 +171,10 @@ public: void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const std::string& region = "RGN_NOBNDRY") override; - void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, - const std::string& region = "RGN_NOBNDRY") override; - // Use precalculated weights Field3D interpolate(const Field3D& f, const std::string& region = "RGN_NOBNDRY") const override; - // Calculate weights and interpolate - Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, - const std::string& region = "RGN_NOBNDRY") override; - Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, - const BoutMask& mask, - const std::string& region = "RGN_NOBNDRY") override; + std::vector getWeightsForYApproximation(int i, int j, int k, int yoffset) override; }; @@ -208,6 +209,10 @@ class XZLagrange4pt : public XZInterpolation { Field3D t_x, t_z; + BoutReal lagrange_4pt(BoutReal v2m, BoutReal vm, BoutReal vp, BoutReal v2p, + BoutReal offset) const; + BoutReal lagrange_4pt(const BoutReal v[], BoutReal offset) const; + public: XZLagrange4pt(Mesh* mesh = nullptr) : XZLagrange4pt(0, mesh) {} XZLagrange4pt(int y_offset = 0, Mesh* mesh = nullptr); @@ -218,21 +223,10 @@ public: void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const std::string& region = "RGN_NOBNDRY") override; - void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, - const std::string& region = "RGN_NOBNDRY") override; // Use precalculated weights Field3D interpolate(const Field3D& f, const std::string& region = "RGN_NOBNDRY") const override; - // Calculate weights and interpolate - Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, - const std::string& region = "RGN_NOBNDRY") override; - Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, - const BoutMask& mask, - const std::string& region = "RGN_NOBNDRY") override; - BoutReal lagrange_4pt(BoutReal v2m, BoutReal vm, BoutReal vp, BoutReal v2p, - BoutReal offset) const; - BoutReal lagrange_4pt(const BoutReal v[], BoutReal offset) const; }; class XZBilinear : public XZInterpolation { @@ -251,18 +245,10 @@ public: void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const std::string& region = "RGN_NOBNDRY") override; - void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, - const std::string& region = "RGN_NOBNDRY") override; // Use precalculated weights Field3D interpolate(const Field3D& f, const std::string& region = "RGN_NOBNDRY") const override; - // Calculate weights and interpolate - Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, - const std::string& region = "RGN_NOBNDRY") override; - Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z, - const BoutMask& mask, - const std::string& region = "RGN_NOBNDRY") override; }; class XZInterpolationFactory @@ -279,11 +265,12 @@ public: ReturnType create(const std::string& type, [[maybe_unused]] Options* options) const { return Factory::create(type, nullptr); } - - static void ensureRegistered(); }; template using RegisterXZInterpolation = XZInterpolationFactory::RegisterInFactory; -#endif // __INTERP_XZ_H__ +using RegisterUnavailableXZInterpolation = + XZInterpolationFactory::RegisterUnavailableInFactory; + +#endif // INTERP_XZ_H diff --git a/src/mesh/interpolation/bilinear_xz.cxx b/src/mesh/interpolation/bilinear_xz.cxx index 8445764a8f..4c0603f983 100644 --- a/src/mesh/interpolation/bilinear_xz.cxx +++ b/src/mesh/interpolation/bilinear_xz.cxx @@ -83,12 +83,6 @@ void XZBilinear::calcWeights(const Field3D& delta_x, const Field3D& delta_z, } } -void XZBilinear::calcWeights(const Field3D& delta_x, const Field3D& delta_z, - const BoutMask& mask, const std::string& region) { - setMask(mask); - calcWeights(delta_x, delta_z, region); -} - Field3D XZBilinear::interpolate(const Field3D& f, const std::string& region) const { ASSERT1(f.getMesh() == localmesh); Field3D f_interp{emptyFrom(f)}; @@ -113,16 +107,3 @@ Field3D XZBilinear::interpolate(const Field3D& f, const std::string& region) con } return f_interp; } - -Field3D XZBilinear::interpolate(const Field3D& f, const Field3D& delta_x, - const Field3D& delta_z, const std::string& region) { - calcWeights(delta_x, delta_z, region); - return interpolate(f, region); -} - -Field3D XZBilinear::interpolate(const Field3D& f, const Field3D& delta_x, - const Field3D& delta_z, const BoutMask& mask, - const std::string& region) { - calcWeights(delta_x, delta_z, mask, region); - return interpolate(f, region); -} diff --git a/src/mesh/interpolation/hermite_spline_xz.cxx b/src/mesh/interpolation/hermite_spline_xz.cxx index a8e5df7cdf..e2ea540a1f 100644 --- a/src/mesh/interpolation/hermite_spline_xz.cxx +++ b/src/mesh/interpolation/hermite_spline_xz.cxx @@ -111,12 +111,6 @@ void XZHermiteSpline::calcWeights(const Field3D& delta_x, const Field3D& delta_z } } -void XZHermiteSpline::calcWeights(const Field3D& delta_x, const Field3D& delta_z, - const BoutMask& mask, const std::string& region) { - setMask(mask); - calcWeights(delta_x, delta_z, region); -} - /*! * Return position and weight of points needed to approximate the function value at the * point that the field line through (i,j,k) meets the (j+1)-plane. For the case where @@ -223,16 +217,3 @@ Field3D XZHermiteSpline::interpolate(const Field3D& f, const std::string& region } return f_interp; } - -Field3D XZHermiteSpline::interpolate(const Field3D& f, const Field3D& delta_x, - const Field3D& delta_z, const std::string& region) { - calcWeights(delta_x, delta_z, region); - return interpolate(f, region); -} - -Field3D XZHermiteSpline::interpolate(const Field3D& f, const Field3D& delta_x, - const Field3D& delta_z, const BoutMask& mask, - const std::string& region) { - calcWeights(delta_x, delta_z, mask, region); - return interpolate(f, region); -} diff --git a/src/mesh/interpolation/lagrange_4pt_xz.cxx b/src/mesh/interpolation/lagrange_4pt_xz.cxx index 92c14ecfd5..903e64767b 100644 --- a/src/mesh/interpolation/lagrange_4pt_xz.cxx +++ b/src/mesh/interpolation/lagrange_4pt_xz.cxx @@ -75,12 +75,6 @@ void XZLagrange4pt::calcWeights(const Field3D& delta_x, const Field3D& delta_z, } } -void XZLagrange4pt::calcWeights(const Field3D& delta_x, const Field3D& delta_z, - const BoutMask& mask, const std::string& region) { - setMask(mask); - calcWeights(delta_x, delta_z, region); -} - Field3D XZLagrange4pt::interpolate(const Field3D& f, const std::string& region) const { ASSERT1(f.getMesh() == localmesh); @@ -132,19 +126,6 @@ Field3D XZLagrange4pt::interpolate(const Field3D& f, const std::string& region) return f_interp; } -Field3D XZLagrange4pt::interpolate(const Field3D& f, const Field3D& delta_x, - const Field3D& delta_z, const std::string& region) { - calcWeights(delta_x, delta_z, region); - return interpolate(f, region); -} - -Field3D XZLagrange4pt::interpolate(const Field3D& f, const Field3D& delta_x, - const Field3D& delta_z, const BoutMask& mask, - const std::string& region) { - calcWeights(delta_x, delta_z, mask, region); - return interpolate(f, region); -} - // 4-point Lagrangian interpolation // offset must be between 0 and 1 BoutReal XZLagrange4pt::lagrange_4pt(const BoutReal v2m, const BoutReal vm, diff --git a/src/mesh/interpolation_xz.cxx b/src/mesh/interpolation_xz.cxx index f7f0b457f2..7dc48eca90 100644 --- a/src/mesh/interpolation_xz.cxx +++ b/src/mesh/interpolation_xz.cxx @@ -38,7 +38,9 @@ const Field3D interpolate(const Field3D& f, const Field3D& delta_x, const Field3D& delta_z) { TRACE("Interpolating 3D field"); XZLagrange4pt interpolateMethod{f.getMesh()}; - return interpolateMethod.interpolate(f, delta_x, delta_z); + // Cast to base pointer so virtual function overload is resolved + return static_cast(&interpolateMethod) + ->interpolate(f, delta_x, delta_z); } const Field3D interpolate(const Field2D& f, const Field3D& delta_x, @@ -84,8 +86,6 @@ const Field3D interpolate(const Field2D& f, const Field3D& delta_x) { return result; } -void XZInterpolationFactory::ensureRegistered() {} - namespace { RegisterXZInterpolation registerinterphermitespline{"hermitespline"}; RegisterXZInterpolation registerinterpmonotonichermitespline{ From 936cd55ad7468b8a971a1b1e53ca60092b7e297a Mon Sep 17 00:00:00 2001 From: Ben Dudson Date: Sun, 4 Feb 2024 10:25:04 -0800 Subject: [PATCH 2/2] Moving registration to header Optimised build was omitting XZInterpolation factory registrations. --- include/bout/interpolation_xz.hxx | 8 ++++++++ src/mesh/interpolation_xz.cxx | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/bout/interpolation_xz.hxx b/include/bout/interpolation_xz.hxx index 8a815dfb6b..d8dbeebc7d 100644 --- a/include/bout/interpolation_xz.hxx +++ b/include/bout/interpolation_xz.hxx @@ -273,4 +273,12 @@ using RegisterXZInterpolation = XZInterpolationFactory::RegisterInFactory registerinterphermitespline{"hermitespline"}; +RegisterXZInterpolation registerinterpmonotonichermitespline{ + "monotonichermitespline"}; +RegisterXZInterpolation registerinterplagrange4pt{"lagrange4pt"}; +RegisterXZInterpolation registerinterpbilinear{"bilinear"}; +} // namespace + #endif // INTERP_XZ_H diff --git a/src/mesh/interpolation_xz.cxx b/src/mesh/interpolation_xz.cxx index 7dc48eca90..d151c35613 100644 --- a/src/mesh/interpolation_xz.cxx +++ b/src/mesh/interpolation_xz.cxx @@ -85,11 +85,3 @@ const Field3D interpolate(const Field2D& f, const Field3D& delta_x) { } return result; } - -namespace { -RegisterXZInterpolation registerinterphermitespline{"hermitespline"}; -RegisterXZInterpolation registerinterpmonotonichermitespline{ - "monotonichermitespline"}; -RegisterXZInterpolation registerinterplagrange4pt{"lagrange4pt"}; -RegisterXZInterpolation registerinterpbilinear{"bilinear"}; -} // namespace