diff --git a/src/Classic/Algorithms/CMakeLists.txt b/src/Classic/Algorithms/CMakeLists.txt index 5c78d2e65035d761705f79e426c11fa2f68aedcd..57143a95f0f7dfb2e8c69d718bbbb2625bf9b724 100644 --- a/src/Classic/Algorithms/CMakeLists.txt +++ b/src/Classic/Algorithms/CMakeLists.txt @@ -16,6 +16,7 @@ set (_SRCS PartData.cpp OpalParticle.cpp PolynomialTimeDependence.cpp + SplineTimeDependence.cpp Surveyor.cpp ThinMapper.cpp ThinTracker.cpp @@ -57,6 +58,7 @@ set (HDRS PolynomialTimeDependence.h Quaternion.h rbendmap.h + SplineTimeDependence.h Surveyor.h ThinMapper.h ThinTracker.h diff --git a/src/Classic/Algorithms/SplineTimeDependence.h b/src/Classic/Algorithms/SplineTimeDependence.h index a35a9540f20771f5688454560f8f2591b29281ab..ede981913b18e7a72dda0b114cfc823f8b4fff1a 100644 --- a/src/Classic/Algorithms/SplineTimeDependence.h +++ b/src/Classic/Algorithms/SplineTimeDependence.h @@ -33,13 +33,9 @@ #include <gsl/gsl_spline.h> #include "Ippl.h" +#include "Utilities/GeneralClassicException.h" #include "Algorithms/AbstractTimeDependence.h" - -namespace interpolation { - class PolynomialPatch; -} - /** @class SplineTimeDependence * * Time dependence that follows a spline. Interpolation is supported at @@ -59,6 +55,10 @@ class SplineTimeDependence : public AbstractTimeDependence { * with quadratic smoothing) * @param times the times of successive elements in the time dependence * @param values the values at each time step. + * + * It is an error if times and values are not of equal length, times and + * values length < splineOrder + 1, or times do not increase strictly + * monotonically. */ SplineTimeDependence(size_t splineOrder, std::vector<double> times, diff --git a/src/Elements/CMakeLists.txt b/src/Elements/CMakeLists.txt index 2b494e1e0ea68fc5b3b2bd859b5b31a67f53b6ea..4bf1fadf1aa5ff95d7b78d51983b42347e174728 100644 --- a/src/Elements/CMakeLists.txt +++ b/src/Elements/CMakeLists.txt @@ -46,6 +46,7 @@ set (_SRCS OpalSlit.cpp OpalSolenoid.cpp OpalSource.cpp + OpalSplineTimeDependence.cpp OpalSRot.cpp OpalVariableRFCavity.cpp OpalVariableRFCavityFringeField.cpp @@ -108,6 +109,7 @@ set (HDRS OpalSlit.h OpalSolenoid.h OpalSource.h + OpalSplineTimeDependence.h OpalSRot.h OpalStripper.h OpalTravelingWave.h diff --git a/src/Elements/OpalPolynomialTimeDependence.h b/src/Elements/OpalPolynomialTimeDependence.h index bf0d6910cd54396100a90195a129c6fa355f1cfc..f6df689618aa44cbe9c257ed0bc39d1dc27dcfc2 100644 --- a/src/Elements/OpalPolynomialTimeDependence.h +++ b/src/Elements/OpalPolynomialTimeDependence.h @@ -28,11 +28,8 @@ #ifndef OPAL_OpalPolynomialTimeDependence_HH #define OPAL_OpalPolynomialTimeDependence_HH -#include "Algorithms/PolynomialTimeDependence.h" #include "Elements/OpalElement.h" -class PolynomialTimeDependence; - /** OpalPolynomialTimeDependence provides UI wrapper for the * PolynomialTimeDependence */ diff --git a/src/Elements/OpalSplineTimeDependence.cpp b/src/Elements/OpalSplineTimeDependence.cpp new file mode 100644 index 0000000000000000000000000000000000000000..80a0b30adc601a5b7c64c7f4ffbc9586e3cc41b0 --- /dev/null +++ b/src/Elements/OpalSplineTimeDependence.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018, Chris Rogers + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STFC nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <string> +#include "Attributes/Attributes.h" +#include "Utilities/OpalException.h" +#include "Elements/OpalSplineTimeDependence.h" + +const std::string OpalSplineTimeDependence::doc_string = + std::string("The \"SPLINE_TIME_DEPENDENCE\" element defines ")+\ + std::string("an array of times and corresponding values for time lookup, ")+\ + std::string("for use in time-dependent elements. Lookup is supported at ")+\ + std::string("first order or third order with quadratic smoothing."); + +// I investigated using a StringArray or RealArray here; +// Don't seem to have capacity to handle variables, so for now not implemented +OpalSplineTimeDependence::OpalSplineTimeDependence() + : OpalElement(int(SIZE), + "SPLINE_TIME_DEPENDENCE", + doc_string.c_str()) { + itsAttr[ORDER] = Attributes::makeReal("ORDER", + std::string("Order of the lookup - either 1 for linear interpolation, ")+ + std::string("or 3 for cubic interpolation with quadratic smoothing. ")+ + std::string("Other values make an error.")); + + itsAttr[TIMES] = Attributes::makeRealArray("TIMES", + std::string("Array of real times in ns. There must be at least \"ORDER\"+1 ")+ + std::string("elements in the array and they must be strictly monotically ")+ + std::string("increasing")); + + itsAttr[VALUES] = Attributes::makeRealArray("VALUES", + std::string("Array of real values. The length of \"VALUES\" must be the ")+ + std::string("same as the length of \"TIMES\".")); + + registerRealAttribute("ORDER"); + registerRealAttribute("TIMES"); + registerRealAttribute("VALUES"); + + registerOwnership(); +} + +OpalSplineTimeDependence* OpalSplineTimeDependence::clone(const std::string &name) { + return new OpalSplineTimeDependence(name, this); +} + +void OpalSplineTimeDependence::print(std::ostream& out) const { + OpalElement::print(out); +} + +OpalSplineTimeDependence::OpalSplineTimeDependence(const std::string &name, + OpalSplineTimeDependence *parent): + OpalElement(name, parent) { +} + +OpalSplineTimeDependence::~OpalSplineTimeDependence() {} + +void OpalSplineTimeDependence::fillRegisteredAttributes + (const ElementBase &base, ValueFlag flag) { + OpalElement::fillRegisteredAttributes(base, flag); +} + +void OpalSplineTimeDependence::update() { + + double orderReal = Attributes::getReal(itsAttr[ORDER])+1e-10; + if ((orderReal - 1.) > 1e-9 && (orderReal - 3.) > 1e-9) { + throw OpalException("OpalSplineTimeDependence::update", + "SPLINE_TIME_DEPENDENCE \"ORDER\" should be 1 or 3."); + } + size_t order(floor(orderReal)); + std::vector<double> times = Attributes::getRealArray(itsAttr[TIMES]); + std::vector<double> values = Attributes::getRealArray(itsAttr[VALUES]); + std::shared_ptr<SplineTimeDependence> spline = + std::make_shared<SplineTimeDependence>(order, + times, + values); + AbstractTimeDependence::setTimeDependence(getOpalName(), spline); +} diff --git a/src/Elements/OpalSplineTimeDependence.h b/src/Elements/OpalSplineTimeDependence.h new file mode 100644 index 0000000000000000000000000000000000000000..9b24ff1e86955804cc7114b3f55ae6933ad03e28 --- /dev/null +++ b/src/Elements/OpalSplineTimeDependence.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, Chris Rogers + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STFC nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef OPAL_OpalSplineTimeDependence_HH +#define OPAL_OpalSplineTimeDependence_HH + +#include "Algorithms/SplineTimeDependence.h" +#include "Elements/OpalElement.h" + +/** OpalSplineTimeDependence provides UI wrapper for the + * SplineTimeDependence + */ + +class OpalSplineTimeDependence : public OpalElement { + public: + /** Enumeration maps to UI parameters */ + enum { + ORDER = COMMON, + TIMES, + VALUES, + SIZE // size of the enum + }; + + /** Define mapping from enum variables to string UI parameter names */ + OpalSplineTimeDependence(); + + /** No memory allocated so does nothing */ + virtual ~OpalSplineTimeDependence(); + + /** Inherited copy constructor */ + virtual OpalSplineTimeDependence *clone(const std::string &name); + + /** Calls fillRegisteredAttributes on the OpalElement */ + void fillRegisteredAttributes(const ElementBase &base, ValueFlag flag); + + /** Receive parameters from the parser and hand them off to the + * SplineTimeDependence + */ + void update(); + + /** Calls print on the OpalElement */ + virtual void print(std::ostream &) const; + private: + // Not implemented. + OpalSplineTimeDependence(const OpalSplineTimeDependence &); + void operator=(const OpalSplineTimeDependence &); + + // Clone constructor. + OpalSplineTimeDependence(const std::string &name, + OpalSplineTimeDependence *parent); + + static const std::string doc_string; +}; + +#endif // OPAL_OpalSplineTimeDependence_HH diff --git a/tests/classic_src/Algorithms/CMakeLists.txt b/tests/classic_src/Algorithms/CMakeLists.txt index d20e926d4402ba40575ac94eaf171c5ec0f8c8b2..027e46ee363c80544e4d53e6d71066fc21f42038 100644 --- a/tests/classic_src/Algorithms/CMakeLists.txt +++ b/tests/classic_src/Algorithms/CMakeLists.txt @@ -1,5 +1,6 @@ set (_SRCS PolynomialTimeDependenceTest.cpp + SplineTimeDependenceTest.cpp ) include_directories ( diff --git a/tests/classic_src/Algorithms/PolynomialTimeDependenceTest.cpp b/tests/classic_src/Algorithms/PolynomialTimeDependenceTest.cpp index 41241845a3035e6f2b3fba3c743107994236cc2c..66c5767cabdc139442140ba7d6488866302183b6 100644 --- a/tests/classic_src/Algorithms/PolynomialTimeDependenceTest.cpp +++ b/tests/classic_src/Algorithms/PolynomialTimeDependenceTest.cpp @@ -1,3 +1,30 @@ +/* + * Copyright (c) 2014, Chris Rogers + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STFC nor the names of its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + #include "gtest/gtest.h" #include "Utilities/GeneralClassicException.h" #include "Algorithms/AbstractTimeDependence.h" diff --git a/tests/classic_src/Algorithms/SplineTimeDependenceTest.cpp b/tests/classic_src/Algorithms/SplineTimeDependenceTest.cpp index 437fb88245a4e778788a2c74fa3d084ebb93d833..494f9a42112b28c12ba079f33b41ae6e237f79a8 100644 --- a/tests/classic_src/Algorithms/SplineTimeDependenceTest.cpp +++ b/tests/classic_src/Algorithms/SplineTimeDependenceTest.cpp @@ -30,8 +30,6 @@ #include "Utilities/GeneralClassicException.h" #include "Algorithms/SplineTimeDependence.h" -using interpolation::PolynomialPatch; - class SplineTimeDependenceTest : public ::testing::Test { public: SplineTimeDependenceTest() : times_m(10), values_m(10) { diff --git a/tests/opal_src/Elements/CMakeLists.txt b/tests/opal_src/Elements/CMakeLists.txt index 33f0be8f4aaaa6bf79233619703f757ae250bdbd..52b36a42ee523730a0bdb0404eb71e04170f436d 100644 --- a/tests/opal_src/Elements/CMakeLists.txt +++ b/tests/opal_src/Elements/CMakeLists.txt @@ -1,6 +1,7 @@ set (_SRCS OpalOffsetTest.cpp OpalPolynomialTimeDependenceTest.cpp + OpalSplineTimeDependenceTest.cpp OpalVariableRFCavityTest.cpp OpalVariableRFCavityFringeFieldTest.cpp ) diff --git a/tests/opal_src/Elements/OpalSplineTimeDependenceTest.cpp b/tests/opal_src/Elements/OpalSplineTimeDependenceTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fab671c167c6ffb6c25ce794bf6ec1f69318366c --- /dev/null +++ b/tests/opal_src/Elements/OpalSplineTimeDependenceTest.cpp @@ -0,0 +1,23 @@ +#include <sstream> + +#include "gtest/gtest.h" +#include "Elements/OpalSplineTimeDependence.h" + +#include "opal_test_utilities/SilenceTest.h" + +TEST(OpalSplineTimeDependenceTest, ConstructorTest) { + OpalTestUtilities::SilenceTest silencer; + + OpalSplineTimeDependence dep; + OpalSplineTimeDependence* dep_clone = dep.clone("new name"); + EXPECT_EQ(dep_clone->getOpalName(), "new name"); +} + +TEST(OpalSplineSplineDependenceTest, PrintTest) { + OpalTestUtilities::SilenceTest silencer; + + OpalSplineTimeDependence dep; + std::stringstream _string; + dep.print(_string); + EXPECT_EQ(_string.str(), "SPLINE_TIME_DEPENDENCE;\n"); +}