OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
TestLaser.cpp
Go to the documentation of this file.
10#include "Physics/Physics.h"
13
14#include "gtest/gtest.h"
15
16#include <cmath>
17
18namespace {
19 void setValidLaserAttributes(OpalLaser& laser) {
25 Attributes::setRealArray(laser.itsAttr[OpalLaser::DIR], {0.0, 0.0, -2.0});
26 }
27
28 class DispatchRecordingVisitor : public DefaultVisitor {
29 public:
30 explicit DispatchRecordingVisitor(const Beamline& beamline)
31 : DefaultVisitor(beamline, false, false) {}
32
33 void visitComponent(const Component&) override { sawComponent = true; }
34 void visitLaser(const Laser&) override { sawLaser = true; }
35 void visitSBend(const SBend&) override { sawSBend = true; }
36 void visitRBend(const RBend&) override { sawRBend = true; }
37
38 bool sawComponent = false;
39 bool sawLaser = false;
40 bool sawSBend = false;
41 bool sawRBend = false;
42 };
43} // namespace
44
45TEST(TestLaser, UpdateStoresValidatedParameters) {
46 OpalLaser laser;
47 setValidLaserAttributes(laser);
49 Attributes::setRealArray(laser.itsAttr[OpalLaser::STOKES], {0.0, 0.0, 1.0});
50
51 EXPECT_NO_THROW(laser.update());
52
53 auto* rep = dynamic_cast<LaserRep*>(laser.getElement());
54 ASSERT_NE(rep, nullptr);
55 EXPECT_DOUBLE_EQ(rep->getElementLength(), 0.01);
56 EXPECT_DOUBLE_EQ(rep->getWavelength(), 1.03e-6);
57 EXPECT_DOUBLE_EQ(rep->getPulseEnergy(), 1.0);
58 EXPECT_DOUBLE_EQ(rep->getPulseLength(), 2.0e-12);
59 EXPECT_DOUBLE_EQ(rep->getWaistX(), 5.0e-6);
60 EXPECT_DOUBLE_EQ(rep->getWaistY(), 6.0e-6);
61 EXPECT_NEAR(rep->getDirection()(0), 0.0, 1.0e-15);
62 EXPECT_NEAR(rep->getDirection()(1), 0.0, 1.0e-15);
63 EXPECT_NEAR(rep->getDirection()(2), -1.0, 1.0e-15);
64 EXPECT_DOUBLE_EQ(rep->getStokes()(2), 1.0);
65}
66
67TEST(TestLaser, UpdateDefaultsStokesToZero) {
68 OpalLaser laser;
69 setValidLaserAttributes(laser);
70
71 EXPECT_NO_THROW(laser.update());
72
73 auto* rep = dynamic_cast<LaserRep*>(laser.getElement());
74 ASSERT_NE(rep, nullptr);
75 EXPECT_DOUBLE_EQ(rep->getStokes()(0), 0.0);
76 EXPECT_DOUBLE_EQ(rep->getStokes()(1), 0.0);
77 EXPECT_DOUBLE_EQ(rep->getStokes()(2), 0.0);
78}
79
80TEST(TestLaser, UpdateRequiresWavelength) {
81 OpalLaser laser;
86 Attributes::setRealArray(laser.itsAttr[OpalLaser::DIR], {0.0, 0.0, -2.0});
87
88 EXPECT_THROW(laser.update(), OpalException);
89}
90
91TEST(TestLaser, UpdateRejectsNonPositivePulseEnergy) {
92 OpalLaser laser;
93 setValidLaserAttributes(laser);
95
96 EXPECT_THROW(laser.update(), OpalException);
97}
98
99TEST(TestLaser, UpdateRejectsBadDirectionSize) {
100 OpalLaser laser;
101 setValidLaserAttributes(laser);
103
104 EXPECT_THROW(laser.update(), OpalException);
105}
106
107TEST(TestLaser, UpdateRejectsZeroDirection) {
108 OpalLaser laser;
109 setValidLaserAttributes(laser);
110 Attributes::setRealArray(laser.itsAttr[OpalLaser::DIR], {0.0, 0.0, 0.0});
111
112 EXPECT_THROW(laser.update(), OpalException);
113}
114
115TEST(TestLaser, UpdateRejectsBadStokesSize) {
116 OpalLaser laser;
117 setValidLaserAttributes(laser);
119
120 EXPECT_THROW(laser.update(), OpalException);
121}
122
123TEST(TestLaser, UpdateRejectsStokesNormAboveOne) {
124 OpalLaser laser;
125 setValidLaserAttributes(laser);
126 Attributes::setRealArray(laser.itsAttr[OpalLaser::STOKES], {1.0, 1.0, 0.0});
127
128 EXPECT_THROW(laser.update(), OpalException);
129}
130
131TEST(TestLaser, UpdateRejectsNegativeLength) {
132 OpalLaser laser;
133 setValidLaserAttributes(laser);
135
136 EXPECT_THROW(laser.update(), OpalException);
137}
138
167TEST(TestLaser, LinearComptonForwardPhotonEnergyMatchesExactNinetyDegreeKinematics) {
168 OpalLaser laser;
169 setValidLaserAttributes(laser);
170 Attributes::setRealArray(laser.itsAttr[OpalLaser::DIR], {1.0, 0.0, 0.0});
171
172 ASSERT_NO_THROW(laser.update());
173
174 auto* rep = dynamic_cast<LaserRep*>(laser.getElement());
175 ASSERT_NE(rep, nullptr);
176
177 Vector_t<double, 3> beamDirection(0.0);
178 beamDirection(2) = 1.0;
179
180 const double electronTotalEnergyGeV = 1.0;
181 const double laserPhotonEnergyGeV = rep->getPhotonEnergyGeV();
182 const double electronMomentumGeV = std::sqrt(
183 electronTotalEnergyGeV * electronTotalEnergyGeV - Physics::m_e * Physics::m_e);
184 const double expectedInvariantX =
185 2.0 * laserPhotonEnergyGeV * electronTotalEnergyGeV / (Physics::m_e * Physics::m_e);
186 const double stableEnergyMinusMomentum =
187 Physics::m_e * Physics::m_e / (electronTotalEnergyGeV + electronMomentumGeV);
188 const double expectedForwardPhotonEnergyGeV =
189 laserPhotonEnergyGeV * electronTotalEnergyGeV
190 / (stableEnergyMinusMomentum + laserPhotonEnergyGeV);
191
192 EXPECT_NEAR(
193 rep->getLinearComptonInvariantX(electronTotalEnergyGeV, beamDirection),
194 expectedInvariantX, expectedInvariantX * 1.0e-12);
195 EXPECT_NEAR(
196 rep->getLinearComptonForwardPhotonEnergyGeV(electronTotalEnergyGeV, beamDirection),
197 expectedForwardPhotonEnergyGeV, expectedForwardPhotonEnergyGeV * 1.0e-12);
198}
199
200TEST(TestLaser, BeamlineVisitorDispatchesLaserAndBendsToSpecificHooks) {
201 TBeamline<FlaggedElmPtr> beamline("LINE");
202
203 {
204 DispatchRecordingVisitor visitor(beamline);
205 LaserRep laser("LASER");
206 laser.accept(visitor);
207 EXPECT_TRUE(visitor.sawLaser);
208 EXPECT_FALSE(visitor.sawSBend);
209 EXPECT_FALSE(visitor.sawRBend);
210 EXPECT_FALSE(visitor.sawComponent);
211 }
212
213 {
214 DispatchRecordingVisitor visitor(beamline);
215 SBendRep sbend("SBEND");
216 sbend.accept(visitor);
217 EXPECT_FALSE(visitor.sawLaser);
218 EXPECT_TRUE(visitor.sawSBend);
219 EXPECT_FALSE(visitor.sawRBend);
220 EXPECT_FALSE(visitor.sawComponent);
221 }
222
223 {
224 DispatchRecordingVisitor visitor(beamline);
225 RBendRep rbend("RBEND");
226 rbend.accept(visitor);
227 EXPECT_FALSE(visitor.sawLaser);
228 EXPECT_FALSE(visitor.sawSBend);
229 EXPECT_TRUE(visitor.sawRBend);
230 EXPECT_FALSE(visitor.sawComponent);
231 }
232}
ippl::Vector< T, Dim > Vector_t
Visitor-based parallel tracker with time as the independent variable.
TEST(TestLaser, UpdateStoresValidatedParameters)
Definition TestLaser.cpp:45
An abstract sequence of beam line components.
Definition Beamline.h:34
void visitComponent(const Component &) override
Apply the algorithm to an arbitrary component.
void visitRBend(const RBend &) override
Apply the algorithm to a rectangular bend.
void visitSBend(const SBend &) override
Apply the algorithm to a sector bend.
void visitLaser(const Laser &) override
Apply the algorithm to a laser.
ElementBase * getElement() const
Return the embedded OPALX element.
Definition Element.h:119
Passive OPALX laser element.
Definition Laser.h:25
void accept(BeamlineVisitor &) const override
Accept a beamline visitor through the laser-specific interface.
Definition Laser.cpp:32
std::vector< Attribute > itsAttr
The object attributes.
Definition Object.h:210
@ PULSELENGTH
Definition OpalLaser.h:8
@ WAVELENGTH
Definition OpalLaser.h:8
@ PULSEENERGY
Definition OpalLaser.h:8
void update() override
Update the embedded OPALX element.
Definition OpalLaser.cpp:71
Concrete OPALX representation of an analytic rectangular bend.
Definition RBendRep.h:13
Abstract rectangular bend with straight body and curved reference path.
Definition RBend.h:16
void accept(BeamlineVisitor &visitor) const override
Apply visitor.
Definition RBend.cpp:13
Concrete OPALX representation of an analytic sector bend.
Definition SBendRep.h:13
Abstract sector bend with planar-arc body geometry.
Definition SBend.h:15
void accept(BeamlineVisitor &visitor) const override
Apply visitor.
Definition SBend.cpp:13
void setRealArray(Attribute &attr, const std::vector< double > &value)
Set array value.
void setReal(Attribute &attr, double val)
Set real value.
constexpr double m_e
The electron rest mass in GeV.
Definition Physics.h:93