OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
FlexibleCollimator.cpp
Go to the documentation of this file.
1//
2// Class FlexibleCollimator
3// Defines the abstract interface for a collimator.
4//
5// Copyright (c) 200x - 2021, Paul Scherrer Institut, Villigen PSI, Switzerland
6// All rights reserved.
7//
8// This file is part of OPAL.
9//
10// OPAL is free software: you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// You should have received a copy of the GNU General Public License
16// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17//
19
23#include "Fields/Fieldmap.h"
24#include "Physics/Physics.h"
27#include "Utilities/Options.h"
28#include "Utilities/Util.h"
29
30#include <memory>
31
32extern Inform *gmsg;
33
36{}
37
38
40 Component(right),
41 description_m(right.description_m),
42 bb_m(right.bb_m),
43 tree_m(/*right.tree_m*/),
44 informed_m(right.informed_m),
45 losses_m(0),
46 lossDs_m(nullptr),
47 parmatint_m(nullptr)
48{
49 for (const std::shared_ptr<mslang::Base>& obj: right.holes_m) {
50 holes_m.emplace_back(obj->clone());
51 }
52
54 tree_m.objects_m.insert(tree_m.objects_m.end(), holes_m.begin(), holes_m.end());
56}
57
58
61 description_m(""),
62 informed_m(false),
63 losses_m(0),
64 lossDs_m(nullptr),
65 parmatint_m(nullptr)
66{}
67
68
70 if (online_m)
71 goOffline();
72 // for (mslang::Base *obj: holes_m) {
73 // delete obj;
74 // }
75}
76
77
79 visitor.visitFlexibleCollimator(*this);
80}
81
83 const double z = R(2);
84
85 if ((z < 0.0) ||
86 (z > getElementLength()) ||
88 return false;
89 }
90
91 if (!bb_m.isInside(R)) {
93 }
94
95 if (!tree_m.isInside(R)) {
96 return true;
97 }
98
99 return false;
100}
101
102bool FlexibleCollimator::apply(const size_t& i, const double& t,
103 Vector_t& /*E*/, Vector_t& /*B*/) {
104 const Vector_t& R = RefPartBunch_m->R[i];
105 bool pdead = isStopped(R);
106
107 if (pdead) {
108 if (lossDs_m) {
109 const Vector_t& P = RefPartBunch_m->P[i];
110 const double& dt = RefPartBunch_m->dt[i];
111 const Vector_t singleStep = Physics::c * dt * Util::getBeta(P);
112 double frac = -R(2) / singleStep(2);
113 lossDs_m->addParticle(OpalParticle(RefPartBunch_m->ID[i],
114 R + frac * singleStep, P,
115 t + frac * dt,
116 RefPartBunch_m->Q[i], RefPartBunch_m->M[i]));
117 }
118 ++losses_m;
119 }
120 return pdead;
121}
122
124 const Vector_t& /*P*/,
125 const double& /*t*/,
126 Vector_t& /*E*/,
127 Vector_t& /*B*/) {
128 return false;
129}
130
131// rectangle collimators in cyclotron cyclindral coordinates
132// without particlematterinteraction, the particle hitting collimator is deleted directly
134 const int /*turnnumber*/,
135 const double /*t*/,
136 const double /*tstep*/) {
137 return false;
138}
139
140void FlexibleCollimator::initialise(PartBunchBase<double, 3>* bunch, double& startField, double& endField) {
141 RefPartBunch_m = bunch;
142 endField = startField + getElementLength();
143
145
146 lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(getOutputFN(), !Options::asciidump));
147
148 goOnline(-1e6);
149}
150
152 RefPartBunch_m = bunch;
153
155
156 lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(getOutputFN(), !Options::asciidump));
157
158 goOnline(-1e6);
159}
160
162 if (online_m)
163 goOffline();
164 *gmsg << "* Finalize flexible collimator " << getName() << endl;
165}
166
167void FlexibleCollimator::goOnline(const double&) {
168 print();
169 online_m = true;
170}
171
173 if (RefPartBunch_m == nullptr) {
174 if (!informed_m) {
175 std::string errormsg = Fieldmap::typeset_msg("BUNCH SIZE NOT SET", "warning");
176 ERRORMSG(errormsg << endl);
177 if (Ippl::myNode() == 0) {
178 std::ofstream omsg("errormsg.txt", std::ios_base::app);
179 omsg << errormsg << std::endl;
180 omsg.close();
181 }
182 informed_m = true;
183 }
184 return;
185 }
186
187 *gmsg << level3;
188}
189
191 if (online_m && lossDs_m)
192 lossDs_m->save();
193 lossDs_m.reset(0);
194 online_m = false;
195}
196
197void FlexibleCollimator::getDimensions(double& zBegin, double& zEnd) const {
198 zBegin = 0.0;
199 zEnd = getElementLength();
200}
201
204}
205
206void FlexibleCollimator::setDescription(const std::string& desc) {
207 tree_m.reset();
208 holes_m.clear();
209
210 mslang::Function* fun;
211
212 if (!mslang::parse(desc, fun))
213 throw GeneralClassicException("FlexibleCollimator::setDescription",
214 "Couldn't parse input file");
215
216 fun->apply(holes_m);
217
218 if (holes_m.size() == 0) return;
219
220 for (std::shared_ptr<mslang::Base>& it: holes_m) {
221 it->computeBoundingBox();
222 }
223
224 std::shared_ptr<mslang::Base>& first = holes_m.front();
225 const mslang::BoundingBox2D& bb = first->bb_m;
226
227 Vector_t llc(bb.center_m[0] - 0.5 * bb.width_m,
228 bb.center_m[1] - 0.5 * bb.height_m,
229 0.0);
230 Vector_t urc(bb.center_m[0] + 0.5 * bb.width_m,
231 bb.center_m[1] + 0.5 * bb.height_m,
232 0.0);
233
234 for (const std::shared_ptr<mslang::Base>& it: holes_m) {
235 const mslang::BoundingBox2D& bb = it->bb_m;
236 llc[0] = std::min(llc[0], bb.center_m[0] - 0.5 * bb.width_m);
237 llc[1] = std::min(llc[1], bb.center_m[1] - 0.5 * bb.height_m);
238 urc[0] = std::max(urc[0], bb.center_m[0] + 0.5 * bb.width_m);
239 urc[1] = std::max(urc[1], bb.center_m[1] + 0.5 * bb.height_m);
240 }
241
242 double width = urc[0] - llc[0];
243 double height = urc[1] - llc[1];
244
245 llc[0] -= 1e-3 * width;
246 urc[0] += 1e-3 * width;
247 llc[1] -= 1e-3 * height;
248 urc[1] += 1e-3 * height;
249
250 bb_m = mslang::BoundingBox2D(llc, urc);
251
252 tree_m.bb_m = bb_m;
253 tree_m.objects_m.insert(tree_m.objects_m.end(), holes_m.begin(), holes_m.end());
254 tree_m.buildUp();
255
256 delete fun;
257}
258
259void FlexibleCollimator::writeHolesAndQuadtree(const std::string& baseFilename) const {
260 if (Ippl::myNode() == 0) {
261 std::string fname = Util::combineFilePath({
263 baseFilename
264 });
265
266 std::ofstream out(fname + "_quadtree.gpl");
267 tree_m.writeGnuplot(out);
268 out.close();
269
270 out.open(fname + "_holes.gpl");
271 for (const std::shared_ptr<mslang::Base> &obj: holes_m) {
272 obj->writeGnuplot(out);
273 }
274 out.close();
275 }
276}
Inform * gmsg
Definition: Main.cpp:61
ElementType
Definition: ElementBase.h:88
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Inform & level3(Inform &inf)
Definition: Inform.cpp:47
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
const std::string name
constexpr double e
The value of.
Definition: Physics.h:39
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
bool parse(std::string str, Function *&fun)
Definition: MSLang.cpp:37
bool asciidump
Definition: Options.cpp:85
std::string combineFilePath(std::initializer_list< std::string > ilist)
Definition: Util.cpp:196
Vector_t getBeta(Vector_t p)
Definition: Util.h:50
ParticlePos_t & R
ParticleAttrib< double > M
ParticleAttrib< Vector_t > P
ParticleAttrib< double > Q
ParticleAttrib< double > dt
ParticleIndex_t & ID
static OpalData * getInstance()
Definition: OpalData.cpp:196
std::string getAuxiliaryOutputDirectory() const
get the name of the the additional data directory
Definition: OpalData.cpp:661
virtual void visitFlexibleCollimator(const FlexibleCollimator &)=0
Apply the algorithm to a flexible collimator.
Interface for a single beam element.
Definition: Component.h:50
bool online_m
Definition: Component.h:192
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:191
virtual const std::string & getName() const
Get element name.
virtual ParticleMatterInteractionHandler * getParticleMatterInteraction() const
Definition: ElementBase.h:482
bool getFlagDeleteOnTransverseExit() const
Definition: ElementBase.h:613
virtual double getElementLength() const
Get design length.
Definition: ElementBase.h:414
bool isInsideTransverse(const Vector_t &r) const
std::string getOutputFN() const
Get output filename.
std::unique_ptr< LossDataSink > lossDs_m
bool isStopped(const Vector_t &R)
std::vector< std::shared_ptr< mslang::Base > > holes_m
ParticleMatterInteractionHandler * parmatint_m
virtual void initialise(PartBunchBase< double, 3 > *bunch, double &startField, double &endField) override
virtual bool apply(const size_t &i, const double &t, Vector_t &E, Vector_t &B) override
virtual bool checkCollimator(PartBunchBase< double, 3 > *bunch, const int turnnumber, const double t, const double tstep)
virtual void finalise() override
mslang::BoundingBox2D bb_m
virtual bool applyToReferenceParticle(const Vector_t &R, const Vector_t &P, const double &t, Vector_t &E, Vector_t &B) override
void setDescription(const std::string &desc)
virtual void goOffline() override
virtual ElementType getType() const override
Get element type std::string.
virtual void goOnline(const double &kineticEnergy) override
virtual void accept(BeamlineVisitor &) const override
Apply visitor to FlexibleCollimator.
void writeHolesAndQuadtree(const std::string &baseFilename) const
mslang::QuadTree tree_m
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:652
virtual void apply(std::vector< std::shared_ptr< Base > > &bfuncs)=0
bool isInside(const Vector_t &X) const
void writeGnuplot(std::ostream &out) const
Definition: QuadTree.cpp:91
bool isInside(const Vector_t &R) const
Definition: QuadTree.cpp:104
BoundingBox2D bb_m
Definition: QuadTree.h:12
std::list< std::shared_ptr< Base > > objects_m
Definition: QuadTree.h:11
Definition: Inform.h:42
static int myNode()
Definition: IpplInfo.cpp:691