OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
TestOrbitThreader.cpp
Go to the documentation of this file.
1#include "gtest/gtest.h"
2
10#include "Beamlines/Beamline.h"
12#include "Fields/NullField.h"
13#include "Structure/Beam.h"
14#include "Structure/DataSink.h"
16#include "Utilities/Options.h"
17#include "Utility/Inform.h"
18
19#include <filesystem>
20#include <set>
21
22extern Inform* gmsg;
23
24namespace {
25 class DummyBeamline final : public Beamline {
26 public:
27 DummyBeamline() : Beamline("dummy") {}
28
29 ElementType getType() const override { return ElementType::BEAMLINE; }
30 BGeometryBase& getGeometry() override { return geometry_; }
31 const BGeometryBase& getGeometry() const override { return geometry_; }
32 void accept(BeamlineVisitor& visitor) const override { visitor.visitBeamline(*this); }
33 ElementBase* clone() const override { return new DummyBeamline(*this); }
34 void iterate(BeamlineVisitor&, bool) const override {}
35
36 private:
38 };
39
46 class FieldSupportOnlyComponent final : public Component {
47 public:
48 FieldSupportOnlyComponent(
49 const std::string& name, const double fieldBegin, const double fieldEnd)
50 : Component(name), fieldBegin_m(fieldBegin), fieldEnd_m(fieldEnd) {}
51
52 void accept(BeamlineVisitor&) const override {}
53 ElementBase* clone() const override { return new FieldSupportOnlyComponent(*this); }
54
55 EMField& getField() override { return field_m; }
56 const EMField& getField() const override { return field_m; }
57
58 bool apply(const std::shared_ptr<ParticleContainer_t>&) override { return false; }
59
60 bool apply(
61 const size_t&, const double&, Vector_t<double, 3>&, Vector_t<double, 3>&) override {
62 return false;
63 }
64
65 bool apply(
66 const Vector_t<double, 3>&, const Vector_t<double, 3>&, const double&,
68 return false;
69 }
70
72 const Vector_t<double, 3>&, const Vector_t<double, 3>&, const double&,
74 return false;
75 }
76
77 void initialise(PartBunch_t*, double&, double&) override {}
78 void finalise() override {}
79 bool bends() const override { return false; }
80
81 void getFieldExtend(double& zBegin, double& zEnd) const override {
82 zBegin = fieldBegin_m;
83 zEnd = fieldEnd_m;
84 }
85
86 ElementType getType() const override { return ElementType::ANY; }
87
88 BGeometryBase& getGeometry() override { return geometry_m; }
89 const BGeometryBase& getGeometry() const override { return geometry_m; }
90
91 private:
92 double fieldBegin_m;
93 double fieldEnd_m;
94 NullGeometry geometry_m;
95 NullField field_m;
96 };
97} // namespace
98
99class OrbitThreaderTest : public ::testing::Test {
100protected:
101 static void SetUpTestSuite() {
102 int argc = 0;
103 char** argv = nullptr;
104
105 ippl::initialize(argc, argv);
106 gmsg = new Inform(nullptr, -1);
107 Options::enableHDF5 = false;
108 }
109
110 static void TearDownTestSuite() {
111 delete gmsg;
112 gmsg = nullptr;
113 ippl::finalize();
114 }
115
116 void SetUp() override {
117 OpalData::getInstance()->storeInputFn("TestOrbitThreader.opal");
119 std::filesystem::create_directories(OpalData::getInstance()->getAuxiliaryOutputDirectory());
120 }
121
123 public:
124 void setType(const std::string& t) {
126 }
127
128 void setBCX(const std::string& bc) {
130 }
131
132 void setBCY(const std::string& bc) {
134 }
135
136 void setBCZ(const std::string& bc) {
138 }
139 };
140
141 std::shared_ptr<PartBunch_t> makeBunch(const size_t numParticles) {
142 dataSink_m = std::make_shared<DataSink>();
143 const auto fsCmd = std::make_shared<TestableFieldSolverCmd>();
144 fsCmdBase_m = fsCmd;
145 fsCmd->setType("NONE");
146 fsCmd->setNX(8);
147 fsCmd->setNY(8);
148 fsCmd->setNZ(8);
149 fsCmd->setBCX("PERIODIC");
150 fsCmd->setBCY("PERIODIC");
151 fsCmd->setBCZ("PERIODIC");
152
153 auto beam = std::make_shared<Beam>();
154 Beam* opBeam = Beam::find("UNNAMED_BEAM");
155 EXPECT_NE(opBeam, nullptr);
156
157 auto bunch = std::make_shared<PartBunch_t>(
158 std::vector{1.0}, std::vector{1.0}, std::vector<Beam*>{opBeam},
159 std::vector<size_t>{numParticles}, 1.0, "LF2", fsCmdBase_m.get(), dataSink_m.get());
160 bunch->getParticleContainer()->createParticles(numParticles);
161 return bunch;
162 }
163
164 std::shared_ptr<MultipoleRep> makePlacedQuadrupole(
165 const std::string& name, const double length, const double entryPosition,
166 const double normalComponent) {
167 auto quadrupole = std::make_shared<MultipoleRep>(name);
168 quadrupole->setElementLength(length);
169 quadrupole->setNormalComponent(1, normalComponent);
170 quadrupole->setPlacementPose(PlacementPose(
171 CoordinateSystemTrafo(Vector_t<double, 3>(0.0, 0.0, entryPosition), Quaternion())));
172 quadrupole->fixPosition();
173 return quadrupole;
174 }
175
176 std::shared_ptr<FieldSupportOnlyComponent> makePlacedFieldSupportOnlyComponent(
177 const std::string& name, const double entryPosition, const double fieldLength) {
178 auto component = std::make_shared<FieldSupportOnlyComponent>(name, 0.0, fieldLength);
179 component->setElementLength(0.0);
180 component->setPlacementPose(PlacementPose(
181 CoordinateSystemTrafo(Vector_t<double, 3>(0.0, 0.0, entryPosition), Quaternion())));
182 component->fixPosition();
183 return component;
184 }
185
186 std::shared_ptr<FieldSolverCmd> fsCmdBase_m;
187 std::shared_ptr<DataSink> dataSink_m;
188};
189
190TEST_F(OrbitThreaderTest, ExposesEmptyReferencePathModelBeforeExecution) {
191 StepSizeConfig stepSizes;
192 stepSizes.push_back(1.0e-12, 1.0, 8);
193 stepSizes.resetIterator();
194
195 PartData reference(1.0, 9.382720813e8, 1.0e6);
196 OpalBeamline beamline;
197 OrbitThreader threader(
198 reference, Vector_t<double, 3>(0.0), Vector_t<double, 3>(0.0, 0.0, 1.0), 0.0, 0.0, 0.0,
199 1.0e-12, stepSizes, beamline);
200
201 EXPECT_TRUE(threader.getReferencePathModel().empty());
202 EXPECT_TRUE(threader.getActionRangeRegistrationModel().empty());
203}
204
205TEST_F(OrbitThreaderTest, ExecutesOverlapAndBuildsTracedAndRegistrationModels) {
206 auto bunch = makeBunch(0);
207
208 DummyBeamline beamlineForVisitor;
209 DefaultVisitor visitor(beamlineForVisitor, false, false);
210
211 OpalBeamline beamline;
212 auto longQuadrupole = makePlacedQuadrupole("Q_LONG", 0.5, 0.0, 0.5);
213 auto shortQuadrupole = makePlacedQuadrupole("Q_SHORT", 0.1, 0.45, 0.8);
214 beamline.visit(*longQuadrupole, visitor, *bunch);
215 beamline.visit(*shortQuadrupole, visitor, *bunch);
216 beamline.prepareSections();
217
218 StepSizeConfig stepSizes;
219 stepSizes.push_back(1.0e-11, 0.7, 512);
220 stepSizes.resetIterator();
221
222 PartData reference(1.0, 9.382720813e8, 1.0e6);
223 OrbitThreader threader(
224 reference, Vector_t<double, 3>(0.0), Vector_t<double, 3>(0.0, 0.0, 1.0), 0.0, 0.0, 0.0,
225 1.0e-11, stepSizes, beamline);
226
227 threader.execute();
228
229 const ReferencePathModel& tracedModel = threader.getReferencePathModel();
230 ASSERT_FALSE(tracedModel.empty());
231
232 bool foundOverlap = false;
233 for (const auto& segment : tracedModel.getSegments()) {
234 if (segment.getActiveElements().size() != 2u) {
235 continue;
236 }
237
238 std::set<std::string> activeNames;
239 for (const auto& element : segment.getActiveElements()) {
240 activeNames.insert(element->getName());
241 }
242
243 if (activeNames == std::set<std::string>{"Q_LONG", "Q_SHORT"}) {
244 foundOverlap = true;
245 EXPECT_NEAR(segment.getBegin(), 0.45, 0.02);
246 EXPECT_NEAR(segment.getEnd(), 0.5, 0.02);
247 break;
248 }
249 }
250 EXPECT_TRUE(foundOverlap);
251
252 const ReferencePathModel& registrationModel = threader.getActionRangeRegistrationModel();
253 ASSERT_EQ(registrationModel.size(), 2u);
254
255 std::set<std::string> registeredNames;
256 for (const auto& segment : registrationModel.getSegments()) {
257 ASSERT_EQ(segment.getActiveElements().size(), 1u);
258 EXPECT_TRUE(segment.hasLegacyElementEdge());
259 registeredNames.insert((*segment.getActiveElements().begin())->getName());
260 }
261 EXPECT_EQ(registeredNames, (std::set<std::string>{"Q_LONG", "Q_SHORT"}));
262}
263
264TEST_F(OrbitThreaderTest, UsesFieldSupportExtentForLengthCheck) {
265 auto bunch = makeBunch(0);
266
267 DummyBeamline beamlineForVisitor;
268 DefaultVisitor visitor(beamlineForVisitor, false, false);
269
270 OpalBeamline beamline;
271 auto component = makePlacedFieldSupportOnlyComponent("TW_LIKE", 0.0, 0.1);
272 beamline.visit(*component, visitor, *bunch);
273 beamline.prepareSections();
274
275 StepSizeConfig stepSizes;
276 stepSizes.push_back(1.0e-12, 0.2, 64);
277 stepSizes.resetIterator();
278
279 PartData reference(1.0, 9.382720813e8, 1.0e6);
280 OrbitThreader threader(
281 reference, Vector_t<double, 3>(0.0), Vector_t<double, 3>(0.0, 0.0, 1.0), 0.0, 0.0, 0.0,
282 1.0e-12, stepSizes, beamline);
283
284 EXPECT_NO_THROW(threader.execute());
285}
ippl::Vector< T, Dim > Vector_t
ElementType
Definition ElementBase.h:94
TEST_F(OrbitThreaderTest, ExposesEmptyReferencePathModelBeforeExecution)
Inform * gmsg
Definition changes.cpp:7
Abstract base class for accelerator geometry classes.
Definition Geometry.h:42
Definition Beam.h:32
static Beam * find(const std::string &name)
Find named BEAM.
Definition Beam.cpp:290
virtual void visitBeamline(const Beamline &)=0
Apply the algorithm to a beam line.
An abstract sequence of beam line components.
Definition Beamline.h:34
virtual ElementType getType() const
Get element type std::string.
Definition Component.cpp:49
virtual bool applyToReferenceParticle(const Vector_t< double, 3 > &R, const Vector_t< double, 3 > &P, const double &t, Vector_t< double, 3 > &E, Vector_t< double, 3 > &B)
Apply to reference particle with position R and momemtum P.
virtual void finalise()=0
virtual void initialise(PartBunch_t *bunch, double &startField, double &endField)=0
virtual EMField & getField()=0
Return field.
virtual void getFieldExtend(double &zBegin, double &zEnd) const =0
Return the field-support extent of the component.
virtual bool bends() const =0
virtual bool apply(const std::shared_ptr< ParticleContainer_t > &pc)
Apply to all particles. Kernel launch moved inside the function.
Definition Component.cpp:57
Rigid spatial transform between a parent frame and a local frame.
ElementType getType() const override
Get element type std::string.
ElementBase * clone() const override
Return clone.
BGeometryBase & getGeometry() override
Get geometry.
void accept(BeamlineVisitor &visitor) const override
Apply visitor.
void iterate(BeamlineVisitor &, bool) const override
Apply visitor to all elements of the line.
NullGeometry geometry_
Abstract base class for electromagnetic fields.
Definition EMField.h:171
virtual void accept(BeamlineVisitor &visitor) const =0
Apply visitor.
virtual ElementBase * clone() const =0
Return clone.
virtual BGeometryBase & getGeometry()=0
Get geometry.
A zero electromagnetic field.
Definition NullField.h:29
Geometry representing an identity transform.
std::vector< Attribute > itsAttr
The object attributes.
Definition Object.h:210
void prepareSections()
void visit(const T &, BeamlineVisitor &, PartBunch_t &)
void storeInputFn(const std::string &fn)
store opals input filename
Definition OpalData.cpp:561
static OpalData * getInstance()
Definition OpalData.cpp:193
void setOpenMode(OpenMode openMode)
Definition OpalData.cpp:298
std::shared_ptr< FieldSupportOnlyComponent > makePlacedFieldSupportOnlyComponent(const std::string &name, const double entryPosition, const double fieldLength)
static void SetUpTestSuite()
static void TearDownTestSuite()
std::shared_ptr< FieldSolverCmd > fsCmdBase_m
std::shared_ptr< MultipoleRep > makePlacedQuadrupole(const std::string &name, const double length, const double entryPosition, const double normalComponent)
std::shared_ptr< PartBunch_t > makeBunch(const size_t numParticles)
std::shared_ptr< DataSink > dataSink_m
const ReferencePathModel & getReferencePathModel() const
Return the threader-owned reference-path model.
const ReferencePathModel & getActionRangeRegistrationModel() const
Return the action-range registration model.
Particle reference data.
Definition PartData.h:37
Nominal rigid placement transform.
Quaternion storage and rotation algebra used by OPALX geometry code.
Ordered collection of reference-path segments.
const container_type & getSegments() const
void push_back(double dt, double zstop, unsigned long numSteps)
void setPredefinedString(Attribute &attr, const std::string &val)
Set predefined string value.
bool enableHDF5
If true HDF5 files are written.
Definition Options.cpp:83