1#include "gtest/gtest.h"
17#include "Utility/Inform.h"
46 class FieldSupportOnlyComponent final :
public Component {
48 FieldSupportOnlyComponent(
49 const std::string& name,
const double fieldBegin,
const double fieldEnd)
50 :
Component(name), fieldBegin_m(fieldBegin), fieldEnd_m(fieldEnd) {}
53 ElementBase*
clone()
const override {
return new FieldSupportOnlyComponent(*
this); }
58 bool apply(
const std::shared_ptr<ParticleContainer_t>&)
override {
return false; }
79 bool bends()
const override {
return false; }
82 zBegin = fieldBegin_m;
103 char** argv =
nullptr;
105 ippl::initialize(argc, argv);
106 gmsg =
new Inform(
nullptr, -1);
141 std::shared_ptr<PartBunch_t>
makeBunch(
const size_t numParticles) {
143 const auto fsCmd = std::make_shared<TestableFieldSolverCmd>();
145 fsCmd->setType(
"NONE");
149 fsCmd->setBCX(
"PERIODIC");
150 fsCmd->setBCY(
"PERIODIC");
151 fsCmd->setBCZ(
"PERIODIC");
153 auto beam = std::make_shared<Beam>();
155 EXPECT_NE(opBeam,
nullptr);
157 auto bunch = std::make_shared<PartBunch_t>(
158 std::vector{1.0}, std::vector{1.0}, std::vector<Beam*>{opBeam},
160 bunch->getParticleContainer()->createParticles(numParticles);
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);
172 quadrupole->fixPosition();
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);
182 component->fixPosition();
195 PartData reference(1.0, 9.382720813e8, 1.0e6);
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);
206 auto bunch = makeBunch(0);
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);
222 PartData reference(1.0, 9.382720813e8, 1.0e6);
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);
230 ASSERT_FALSE(tracedModel.
empty());
232 bool foundOverlap =
false;
233 for (
const auto& segment : tracedModel.
getSegments()) {
234 if (segment.getActiveElements().size() != 2u) {
238 std::set<std::string> activeNames;
239 for (
const auto& element : segment.getActiveElements()) {
240 activeNames.insert(element->getName());
243 if (activeNames == std::set<std::string>{
"Q_LONG",
"Q_SHORT"}) {
245 EXPECT_NEAR(segment.getBegin(), 0.45, 0.02);
246 EXPECT_NEAR(segment.getEnd(), 0.5, 0.02);
250 EXPECT_TRUE(foundOverlap);
253 ASSERT_EQ(registrationModel.
size(), 2u);
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());
261 EXPECT_EQ(registeredNames, (std::set<std::string>{
"Q_LONG",
"Q_SHORT"}));
265 auto bunch = makeBunch(0);
271 auto component = makePlacedFieldSupportOnlyComponent(
"TW_LIKE", 0.0, 0.1);
272 beamline.
visit(*component, visitor, *bunch);
279 PartData reference(1.0, 9.382720813e8, 1.0e6);
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);
284 EXPECT_NO_THROW(threader.
execute());
ippl::Vector< T, Dim > Vector_t
TEST_F(OrbitThreaderTest, ExposesEmptyReferencePathModelBeforeExecution)
Abstract base class for accelerator geometry classes.
static Beam * find(const std::string &name)
Find named BEAM.
virtual void visitBeamline(const Beamline &)=0
Apply the algorithm to a beam line.
An abstract sequence of beam line components.
virtual ElementType getType() const
Get element type std::string.
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.
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.
Abstract base class for electromagnetic fields.
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.
Geometry representing an identity transform.
std::vector< Attribute > itsAttr
The object attributes.
void visit(const T &, BeamlineVisitor &, PartBunch_t &)
void storeInputFn(const std::string &fn)
store opals input filename
static OpalData * getInstance()
void setOpenMode(OpenMode openMode)
void setBCZ(const std::string &bc)
void setType(const std::string &t)
void setBCX(const std::string &bc)
void setBCY(const std::string &bc)
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.
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.