OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
TestOpalBeamlinePlacement.cpp
Go to the documentation of this file.
2#include "gtest/gtest.h"
3
9#include "Structure/Beam.h"
10#include "Structure/DataSink.h"
12#include "Utilities/Options.h"
13#include "Utility/Inform.h"
14
15#include <cmath>
16
17extern Inform* gmsg;
18
19namespace {
20 constexpr double tol = 1e-12;
21
22 using Vector3 = ippl::Vector<double, 3>;
23
24 Quaternion rotationAroundY(double angle) {
25 return Quaternion(std::cos(0.5 * angle), 0.0, std::sin(0.5 * angle), 0.0);
26 }
27
28 void expectVectorNear(const Vector3& actual, const Vector3& expected) {
29 EXPECT_NEAR(actual(0), expected(0), tol);
30 EXPECT_NEAR(actual(1), expected(1), tol);
31 EXPECT_NEAR(actual(2), expected(2), tol);
32 }
33
34 class DummyBeamline final : public Beamline {
35 public:
36 DummyBeamline() : Beamline("dummy") {}
37
38 ElementType getType() const override { return ElementType::BEAMLINE; }
39 BGeometryBase& getGeometry() override { return geometry_; }
40 const BGeometryBase& getGeometry() const override { return geometry_; }
41 void accept(BeamlineVisitor& visitor) const override { visitor.visitBeamline(*this); }
42 ElementBase* clone() const override { return new DummyBeamline(*this); }
43 void iterate(BeamlineVisitor&, bool) const override {}
44
45 private:
47 };
48} // namespace
49
50class OpalBeamlinePlacementTest : public ::testing::Test {
51protected:
52 static void SetUpTestSuite() {
53 int argc = 0;
54 char** argv = nullptr;
55
56 ippl::initialize(argc, argv);
57 gmsg = new Inform(nullptr, -1);
58 Options::enableHDF5 = false;
59 }
60
61 static void TearDownTestSuite() {
62 delete gmsg;
63 gmsg = nullptr;
64 ippl::finalize();
65 }
66
67 void SetUp() override {
68 OpalData::getInstance()->storeInputFn("TestOpalBeamlinePlacement.opal");
70 }
71
73 public:
74 void setType(const std::string& t) {
76 }
77
78 void setBCX(const std::string& bc) {
80 }
81
82 void setBCY(const std::string& bc) {
84 }
85
86 void setBCZ(const std::string& bc) {
88 }
89 };
90
91 std::shared_ptr<PartBunch_t> makeBunch(const size_t numParticles) {
92 dataSink_m = std::make_shared<DataSink>();
93 const auto fsCmd = std::make_shared<TestableFieldSolverCmd>();
94 fsCmdBase_m = fsCmd;
95 fsCmd->setType("NONE");
96 fsCmd->setNX(8);
97 fsCmd->setNY(8);
98 fsCmd->setNZ(8);
99 fsCmd->setBCX("PERIODIC");
100 fsCmd->setBCY("PERIODIC");
101 fsCmd->setBCZ("PERIODIC");
102
103 auto beam = std::make_shared<Beam>();
104 Beam* opBeam = Beam::find("UNNAMED_BEAM");
105 EXPECT_NE(opBeam, nullptr);
106
107 auto bunch = std::make_shared<PartBunch_t>(
108 std::vector{1.0}, std::vector{1.0}, std::vector<Beam*>{opBeam},
109 std::vector<size_t>{numParticles}, 1.0, "LF2", fsCmdBase_m.get(), dataSink_m.get());
110 bunch->getParticleContainer()->createParticles(numParticles);
111 return bunch;
112 }
113
114 std::shared_ptr<FieldSolverCmd> fsCmdBase_m;
115 std::shared_ptr<DataSink> dataSink_m;
116};
117
118TEST_F(OpalBeamlinePlacementTest, BridgeReturnsPlacedElementViewAndPreservesNominalQueries) {
119 OpalBeamline beamline;
120 auto drift = std::make_shared<DriftRep>("D2");
121 drift->setElementLength(2.0);
122 drift->setCSTrafoGlobal2Local(
123 CoordinateSystemTrafo(Vector3(0.5, -1.0, 4.0), rotationAroundY(M_PI / 8.0)));
124 drift->setMisalignment(CoordinateSystemTrafo(Vector3(0.25, 0.0, 0.0), Quaternion()));
125
126 const PlacedElement placed = beamline.getPlacedElement(drift);
127 const Vector3 point(1.0, 2.0, 3.0);
128
129 expectVectorNear(
130 beamline.transformToLocalCS(drift, point),
131 placed.getNominalBodyTransform().transformTo(point));
132 expectVectorNear(
133 beamline.transformFromLocalCS(drift, point),
134 placed.getNominalBodyTransform().transformFrom(point));
135 expectVectorNear(
136 beamline.rotateToLocalCS(drift, point),
137 placed.getNominalBodyTransform().rotateTo(point));
138 expectVectorNear(
139 beamline.rotateFromLocalCS(drift, point),
140 placed.getNominalBodyTransform().rotateFrom(point));
141 expectVectorNear(
142 beamline.getCSTrafoLab2Local(drift).getOrigin(),
144 expectVectorNear(
145 beamline.getNominalEntryTransform(drift).getOrigin(),
147 expectVectorNear(
148 beamline.getNominalExitTransform(drift).getOrigin(),
150 expectVectorNear(
151 beamline.getMisalignment(drift).getOrigin(),
153}
154
155TEST_F(OpalBeamlinePlacementTest, PositionElementRelativeUsesPlacementPoseBridge) {
156 OpalBeamline beamline(Vector3(0.0, 0.0, 5.0), Quaternion());
157 auto drift = std::make_shared<DriftRep>("D3");
158 drift->setPlacementPose(PlacementPose(
159 CoordinateSystemTrafo(Vector3(1.0, 2.0, 3.0), rotationAroundY(M_PI / 10.0))));
160 drift->fixPosition();
161
162 CoordinateSystemTrafo expected = drift->getPlacementPose().getParentToNominal();
163 expected *= beamline.getCSTrafoLab2Local();
164
165 beamline.positionElementRelative(drift);
166
167 expectVectorNear(
169 expected.getOrigin());
170}
171
172TEST_F(OpalBeamlinePlacementTest, PrepareSectionsCompilesElementPositionIntoNominalPlacement) {
173 DriftRep drift("D4");
174 drift.setElementLength(0.4);
175 drift.setElementPosition(1.25);
176
177 auto bunch = makeBunch(0);
178 DummyBeamline beamlineForVisitor;
179 DefaultVisitor visitor(beamlineForVisitor, false, false);
180 OpalBeamline beamline;
181 beamline.visit(drift, visitor, *bunch);
182
183 beamline.prepareSections();
184
185 const auto elements = beamline.getElements();
186 ASSERT_EQ(elements.size(), 1u);
187 const auto placed = beamline.getPlacedElement(*elements.begin());
188
189 expectVectorNear(placed.getNominalBodyTransform().getOrigin(), Vector3(0.0, 0.0, 1.25));
190 expectVectorNear(placed.getNominalEntryTransform().getOrigin(), Vector3(0.0, 0.0, 1.25));
191 expectVectorNear(placed.getNominalExitTransform().getOrigin(), Vector3(0.0, 0.0, 1.65));
192}
193
194TEST_F(OpalBeamlinePlacementTest, BeamlineOwnsPlacedElementAssemblySnapshot) {
195 DriftRep drift("D5");
196 drift.setElementLength(0.3);
197 drift.setElementPosition(0.75);
198
199 auto bunch = makeBunch(0);
200 DummyBeamline beamlineForVisitor;
201 DefaultVisitor visitor(beamlineForVisitor, false, false);
202 OpalBeamline beamline;
203 beamline.visit(drift, visitor, *bunch);
204 beamline.prepareSections();
205
206 const auto elements = beamline.getElements();
207 ASSERT_EQ(elements.size(), 1u);
208 const auto component = *elements.begin();
209
210 const Vector3 assembledOrigin =
211 beamline.getPlacedElement(component).getNominalBodyTransform().getOrigin();
212 expectVectorNear(assembledOrigin, Vector3(0.0, 0.0, 0.75));
213
214 component->setPlacementPose(
215 PlacementPose(CoordinateSystemTrafo(Vector3(9.0, 8.0, 7.0), Quaternion())));
216
217 expectVectorNear(
218 beamline.getPlacedElement(component).getNominalBodyTransform().getOrigin(),
219 assembledOrigin);
220}
ElementType
Definition ElementBase.h:94
elements
Definition IndexMap.cpp:168
TEST_F(OpalBeamlinePlacementTest, BridgeReturnsPlacedElementViewAndPreservesNominalQueries)
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
Rigid spatial transform between a parent frame and a local frame.
ippl::Vector< double, 3 > getOrigin() const
ippl::Vector< double, 3 > transformFrom(const ippl::Vector< double, 3 > &r) const
Map a point from the local frame back to the parent frame.
ippl::Vector< double, 3 > rotateFrom(const ippl::Vector< double, 3 > &r) const
Rotate a vector from the local frame back into the parent frame.
ippl::Vector< double, 3 > rotateTo(const ippl::Vector< double, 3 > &r) const
Rotate a vector from the parent frame into the local frame.
ippl::Vector< double, 3 > transformTo(const ippl::Vector< double, 3 > &r) const
Map a point from the parent frame to the 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_
void setElementPosition(double elemedge)
Access to ELEMEDGE attribute.
virtual void setElementLength(double length)
Set design length.
const CoordinateSystemTrafo & getNominalToActual() const
Geometry representing an identity transform.
std::vector< Attribute > itsAttr
The object attributes.
Definition Object.h:210
std::shared_ptr< FieldSolverCmd > fsCmdBase_m
std::shared_ptr< DataSink > dataSink_m
std::shared_ptr< PartBunch_t > makeBunch(const size_t numParticles)
Vector_t< double, 3 > rotateToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
void positionElementRelative(std::shared_ptr< ElementBase >)
CoordinateSystemTrafo getMisalignment(const std::shared_ptr< Component > &comp) const
Vector_t< double, 3 > transformFromLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
CoordinateSystemTrafo getNominalExitTransform(const std::shared_ptr< Component > &comp) const
CoordinateSystemTrafo getNominalEntryTransform(const std::shared_ptr< Component > &comp) const
PlacedElement getPlacedElement(const std::shared_ptr< Component > &comp) const
Return the placed-element view used by the bridge stage.
void prepareSections()
CoordinateSystemTrafo getCSTrafoLab2Local(const std::shared_ptr< Component > &comp) const
Return the nominal rigid placement transform .
Vector_t< double, 3 > transformToLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
std::set< std::shared_ptr< Component > > getElements(const Vector_t< double, 3 > &x)
void visit(const T &, BeamlineVisitor &, PartBunch_t &)
Vector_t< double, 3 > rotateFromLocalCS(const std::shared_ptr< Component > &comp, const Vector_t< double, 3 > &r) const
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
Geometric placement record for an element instance.
const Misalignment & getMisalignment() const
CoordinateSystemTrafo getNominalEntryTransform() const
CoordinateSystemTrafo getNominalExitTransform() const
CoordinateSystemTrafo getNominalBodyTransform() const
Nominal rigid placement transform.
Quaternion storage and rotation algebra used by OPALX geometry code.
void setPredefinedString(Attribute &attr, const std::string &val)
Set predefined string value.
bool enableHDF5
If true HDF5 files are written.
Definition Options.cpp:83
constexpr double e
The value of.
Definition Physics.h:49