OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
FlexibleCollimator.cpp
Go to the documentation of this file.
2 #include "Physics/Physics.h"
5 #include "Fields/Fieldmap.h"
7 #include "Utilities/Options.h"
9 #include "Utilities/Util.h"
10 
11 #include <memory>
12 
13 extern Inform *gmsg;
14 
15 // Class FlexibleCollimator
16 // ------------------------------------------------------------------------
17 
20 {}
21 
22 
24  Component(right),
25  description_m(right.description_m),
26  bb_m(right.bb_m),
27  tree_m(/*right.tree_m*/),
28  filename_m(right.filename_m),
29  informed_m(right.informed_m),
30  losses_m(0),
31  lossDs_m(nullptr),
32  parmatint_m(NULL)
33 {
34  for (const std::shared_ptr<mslang::Base> obj: right.holes_m) {
35  holes_m.emplace_back(obj->clone());
36  }
37 
38  tree_m.bb_m = bb_m;
39  tree_m.objects_m.insert(tree_m.objects_m.end(), holes_m.begin(), holes_m.end());
40  tree_m.buildUp();
41 }
42 
43 
45  Component(name),
46  description_m(""),
47  filename_m(""),
48  informed_m(false),
49  losses_m(0),
50  lossDs_m(nullptr),
51  parmatint_m(NULL)
52 {}
53 
54 
56  if (online_m)
57  goOffline();
58 
59  // for (mslang::Base *obj: holes_m) {
60  // delete obj;
61  // }
62 }
63 
64 
66  visitor.visitFlexibleCollimator(*this);
67 }
68 
69 
70 bool FlexibleCollimator::isStopped(const Vector_t &R, const Vector_t &P, double recpgamma) {
71  const double z = R(2);// + P(2) * recpgamma;
72 
73  if ((z < 0.0) ||
74  (z > getElementLength()) ||
75  (!isInsideTransverse(R))) return false;
76 
77  if (!bb_m.isInside(R)) {
78  return true;
79  }
80 
81  if (!tree_m.isInside(R)) {
82  return true;
83  }
84 
85  return false;
86 }
87 
88 bool FlexibleCollimator::apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) {
89  const Vector_t &R = RefPartBunch_m->R[i];
90  const Vector_t &P = RefPartBunch_m->P[i];
91  const double &dt = RefPartBunch_m->dt[i];
92  const double recpgamma = Physics::c * dt / sqrt(1.0 + dot(P, P));
93  bool pdead = isStopped(R, P, recpgamma);
94 
95  if (pdead) {
96  if (lossDs_m) {
97  double frac = -R(2) / P(2) * recpgamma;
98  lossDs_m->addParticle(R, P,
99  RefPartBunch_m->ID[i],
100  t + frac * dt, 0);
101  }
102  ++ losses_m;
103  }
104 
105  return pdead;
106 }
107 
108 bool FlexibleCollimator::applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) {
109  return false;
110 }
111 
112 // rectangle collimators in cyclotron cyclindral coordinates
113 // without particlematterinteraction, the particle hitting collimator is deleted directly
114 bool FlexibleCollimator::checkCollimator(PartBunchBase<double, 3> *bunch, const int turnnumber, const double t, const double tstep) {
115 
116  return false;
117 }
118 
119 void FlexibleCollimator::initialise(PartBunchBase<double, 3> *bunch, double &startField, double &endField) {
120  RefPartBunch_m = bunch;
121  endField = startField + getElementLength();
122 
124 
125  // if (!parmatint_m) {
126  if (filename_m == std::string(""))
127  lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(getName(), !Options::asciidump));
128  else
129  lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(filename_m.substr(0, filename_m.rfind(".")), !Options::asciidump));
130  // }
131 
132  goOnline(-1e6);
133 }
134 
136  RefPartBunch_m = bunch;
137 
139 
140  // if (!parmatint_m) {
141  if (filename_m == std::string(""))
142  lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(getName(), !Options::asciidump));
143  else
144  lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(filename_m.substr(0, filename_m.rfind(".")), !Options::asciidump));
145  // }
146 
147  goOnline(-1e6);
148 }
149 
151 {
152  if (online_m)
153  goOffline();
154  *gmsg << "* Finalize flexible collimator " << getName() << endl;
155 }
156 
157 void FlexibleCollimator::goOnline(const double &) {
158  print();
159 
160  online_m = true;
161 }
162 
164  if (RefPartBunch_m == NULL) {
165  if (!informed_m) {
166  std::string errormsg = Fieldmap::typeset_msg("BUNCH SIZE NOT SET", "warning");
167  ERRORMSG(errormsg << endl);
168  if (Ippl::myNode() == 0) {
169  std::ofstream omsg("errormsg.txt", std::ios_base::app);
170  omsg << errormsg << std::endl;
171  omsg.close();
172  }
173  informed_m = true;
174  }
175  return;
176  }
177 
178  *gmsg << level3;
179 }
180 
182  if (online_m && lossDs_m)
183  lossDs_m->save();
184  lossDs_m.reset(0);
185  online_m = false;
186 }
187 
188 void FlexibleCollimator::getDimensions(double &zBegin, double &zEnd) const {
189  zBegin = 0.0;
190  zEnd = getElementLength();
191 }
192 
194  return FLEXIBLECOLLIMATOR;
195 }
196 
197 void FlexibleCollimator::setDescription(const std::string &desc) {
198  tree_m.reset();
199  holes_m.clear();
200 
201  mslang::Function *fun;
202 
203  if (!mslang::parse(desc, fun))
204  throw GeneralClassicException("FlexibleCollimator::setDescription",
205  "Couldn't parse input file");
206 
207  fun->apply(holes_m);
208 
209  if (holes_m.size() == 0) return;
210 
211  for (std::shared_ptr<mslang::Base> & it: holes_m) {
212  it->computeBoundingBox();
213  }
214 
215  std::shared_ptr<mslang::Base> &first = holes_m.front();
216  const mslang::BoundingBox &bb = first->bb_m;
217 
218  Vector_t llc(bb.center_m[0] - 0.5 * bb.width_m,
219  bb.center_m[1] - 0.5 * bb.height_m,
220  0.0);
221  Vector_t urc(bb.center_m[0] + 0.5 * bb.width_m,
222  bb.center_m[1] + 0.5 * bb.height_m,
223  0.0);
224 
225  for (const std::shared_ptr<mslang::Base> & it: holes_m) {
226  const mslang::BoundingBox &bb = it->bb_m;
227  llc[0] = std::min(llc[0], bb.center_m[0] - 0.5 * bb.width_m);
228  llc[1] = std::min(llc[1], bb.center_m[1] - 0.5 * bb.height_m);
229  urc[0] = std::max(urc[0], bb.center_m[0] + 0.5 * bb.width_m);
230  urc[1] = std::max(urc[1], bb.center_m[1] + 0.5 * bb.height_m);
231  }
232 
233  double width = urc[0] - llc[0];
234  double height = urc[1] - llc[1];
235 
236  llc[0] -= 1e-3 * width;
237  urc[0] += 1e-3 * width;
238  llc[1] -= 1e-3 * height;
239  urc[1] += 1e-3 * height;
240 
241  bb_m = mslang::BoundingBox(llc, urc);
242 
243  tree_m.bb_m = bb_m;
244  tree_m.objects_m.insert(tree_m.objects_m.end(), holes_m.begin(), holes_m.end());
245  tree_m.buildUp();
246 
247  delete fun;
248 }
249 
250 void FlexibleCollimator::writeHolesAndQuadtree(const std::string &baseFilename) const {
251  if (Ippl::myNode() == 0) {
252  std::ofstream out("data/" + baseFilename + "_quadtree.gpl");
253  tree_m.writeGnuplot(out);
254  out.close();
255 
256  out.open("data/" + baseFilename + "_holes.gpl");
257  for (const std::shared_ptr<mslang::Base> &obj: holes_m) {
258  obj->writeGnuplot(out);
259  }
260  out.close();
261  }
262 
263 
264 }
virtual ParticleMatterInteractionHandler * getParticleMatterInteraction() const
Definition: ElementBase.h:579
ParticleAttrib< Vector_t > P
constexpr double e
The value of .
Definition: Physics.h:40
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:123
#define ERRORMSG(msg)
Definition: IpplInfo.h:399
Inform * gmsg
Definition: Main.cpp:21
bool online_m
Definition: Component.h:201
Abstract collimator.
bool isInside(const Vector_t &X) const
Definition: BoundingBox.cpp:11
static int myNode()
Definition: IpplInfo.cpp:794
virtual const std::string & getName() const
Get element name.
Definition: ElementBase.cpp:95
virtual void getDimensions(double &zBegin, double &zEnd) const override
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:647
virtual void accept(BeamlineVisitor &) const override
Apply visitor to FlexibleCollimator.
std::vector< std::shared_ptr< mslang::Base > > holes_m
bool isStopped(const Vector_t &R, const Vector_t &P, double recpgamma)
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
ParticleMatterInteractionHandler * parmatint_m
virtual ElementBase::ElementType getType() const override
Get element type std::string.
virtual void finalise() override
void setDescription(const std::string &desc)
ParticleIndex_t & ID
std::unique_ptr< LossDataSink > lossDs_m
void writeHolesAndQuadtree(const std::string &baseFilename) const
virtual double getElementLength() const
Get design length.
Definition: ElementBase.h:511
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:200
virtual void goOnline(const double &kineticEnergy) override
std::list< std::shared_ptr< Base > > objects_m
Definition: QuadTree.h:11
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
BoundingBox bb_m
Definition: QuadTree.h:12
ParticleAttrib< double > dt
virtual void apply(std::vector< std::shared_ptr< Base >> &bfuncs)=0
bool asciidump
Definition: Options.cpp:18
void writeGnuplot(std::ostream &out) const
Definition: QuadTree.cpp:91
mslang::QuadTree tree_m
const std::string name
virtual void visitFlexibleCollimator(const FlexibleCollimator &)=0
Apply the algorithm to a flexible collimator.
virtual bool checkCollimator(PartBunchBase< double, 3 > *bunch, const int turnnumber, const double t, const double tstep)
ParticlePos_t & R
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
bool isInsideTransverse(const Vector_t &r, double f=1) const
Definition: ElementBase.h:645
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
bool isInside(const Vector_t &R) const
Definition: QuadTree.cpp:104
Interface for a single beam element.
Definition: Component.h:51
mslang::BoundingBox bb_m
Abstract algorithm.
Definition: Inform.h:41
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
bool parse(std::string str, Function *&fun)
Definition: MSLang.cpp:37
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95
virtual void goOffline() override
Inform & endl(Inform &inf)
Definition: Inform.cpp:42