OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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"
25#include "Physics/Units.h"
28#include "Utilities/Options.h"
29#include "Utilities/Util.h"
30
31#include <cstddef>
32#include <memory>
33
34extern Inform *gmsg;
35
39
40
42 Component(right),
43 description_m(right.description_m),
44 bb_m(right.bb_m),
45 tree_m(/*right.tree_m*/),
46 informed_m(right.informed_m),
47 losses_m(0),
48 lossDs_m(nullptr),
49 parmatint_m(nullptr)
50{
51 for (const std::shared_ptr<mslang::Base>& obj: right.holes_m) {
52 holes_m.emplace_back(obj->clone());
53 }
54
56 tree_m.objects_m.insert(tree_m.objects_m.end(), holes_m.begin(), holes_m.end());
58}
59
60
63 description_m(""),
64 informed_m(false),
65 losses_m(0),
66 lossDs_m(nullptr),
67 parmatint_m(nullptr)
68{}
69
70
72 if (online_m)
73 goOffline();
74 // for (mslang::Base *obj: holes_m) {
75 // delete obj;
76 // }
77}
78
79
81 visitor.visitFlexibleCollimator(*this);
82}
83
85 const double z = R(2);
86
87 if ((z < 0.0) ||
88 (z > getElementLength()) ||
89 (!isInsideTransverse(R))) {
90 return false;
91 }
92
93 if (!bb_m.isInside(R)) {
95 }
96
97 if (!tree_m.isInside(R)) {
98 return true;
99 }
100
101 return false;
102}
103
104bool FlexibleCollimator::apply(const std::size_t& i, const double& t,
105 Vector_t& /*E*/, Vector_t& /*B*/) {
106 const Vector_t& R = RefPartBunch_m->R[i];
107 bool pdead = isStopped(R);
108
109 if (pdead) {
110 if (lossDs_m) {
111 const Vector_t& P = RefPartBunch_m->P[i];
112 const double& dt = RefPartBunch_m->dt[i];
113 const Vector_t singleStep = Physics::c * dt * Util::getBeta(P);
114 double frac = -R(2) / singleStep(2);
115 lossDs_m->addParticle(OpalParticle(RefPartBunch_m->ID[i],
116 R + frac * singleStep, P,
117 t + frac * dt,
118 RefPartBunch_m->Q[i], RefPartBunch_m->M[i]));
119 }
120 ++losses_m;
121 }
122 return pdead;
123}
124
126 const Vector_t& /*P*/,
127 const double& /*t*/,
128 Vector_t& /*E*/,
129 Vector_t& /*B*/) {
130 return false;
131}
132
133// rectangle collimators in cyclotron cyclindral coordinates
134// without particlematterinteraction, the particle hitting collimator is deleted directly
136 const int /*turnnumber*/,
137 const double /*t*/,
138 const double /*tstep*/) {
139 return false;
140}
141
142void FlexibleCollimator::initialise(PartBunchBase<double, 3>* bunch, double& startField, double& endField) {
143 RefPartBunch_m = bunch;
144 endField = startField + getElementLength();
145
147
148 lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(getOutputFN(), !Options::asciidump));
149
150 goOnline(-1e6);
151}
152
154 RefPartBunch_m = bunch;
155
157
158 lossDs_m = std::unique_ptr<LossDataSink>(new LossDataSink(getOutputFN(), !Options::asciidump));
159
160 goOnline(-1e6);
161}
162
164 if (online_m)
165 goOffline();
166 *gmsg << "* Finalize flexible collimator " << getName() << endl;
167}
168
169void FlexibleCollimator::goOnline(const double&) {
170 print();
171 online_m = true;
172}
173
175 if (RefPartBunch_m == nullptr) {
176 if (!informed_m) {
177 std::string errormsg = _Fieldmap::typeset_msg("BUNCH SIZE NOT SET", "warning");
178 ERRORMSG(errormsg << endl);
179 if (Ippl::myNode() == 0) {
180 std::ofstream omsg("errormsg.txt", std::ios_base::app);
181 omsg << errormsg << std::endl;
182 omsg.close();
183 }
184 informed_m = true;
185 }
186 return;
187 }
188 *gmsg << level3;
189}
190
192 if (online_m && lossDs_m)
193 lossDs_m->save();
194 lossDs_m.reset(0);
195 online_m = false;
196}
197
198void FlexibleCollimator::getDimensions(double& zBegin, double& zEnd) const {
199 zBegin = 0.0;
200 zEnd = getElementLength();
201}
202
206
207void FlexibleCollimator::setDescription(const std::string& desc) {
208 tree_m.reset();
209 holes_m.clear();
210
211 mslang::Function* fun;
212
213 if (!mslang::parse(desc, fun))
214 throw GeneralClassicException("FlexibleCollimator::setDescription",
215 "Couldn't parse input file");
216
217 fun->apply(holes_m);
218
219 if (holes_m.size() == 0) return;
220
221 for (std::shared_ptr<mslang::Base>& it: holes_m) {
222 it->computeBoundingBox();
223 }
224
225 std::shared_ptr<mslang::Base>& first = holes_m.front();
226 const mslang::BoundingBox2D& bb = first->bb_m;
227
228 Vector_t llc({bb.center_m[0] - 0.5 * bb.width_m,
229 bb.center_m[1] - 0.5 * bb.height_m,
230 0.0});
231 Vector_t urc({bb.center_m[0] + 0.5 * bb.width_m,
232 bb.center_m[1] + 0.5 * bb.height_m,
233 0.0});
234
235 for (const std::shared_ptr<mslang::Base>& it: holes_m) {
236 const mslang::BoundingBox2D& bb = it->bb_m;
237 llc[0] = std::min(llc[0], bb.center_m[0] - 0.5 * bb.width_m);
238 llc[1] = std::min(llc[1], bb.center_m[1] - 0.5 * bb.height_m);
239 urc[0] = std::max(urc[0], bb.center_m[0] + 0.5 * bb.width_m);
240 urc[1] = std::max(urc[1], bb.center_m[1] + 0.5 * bb.height_m);
241 }
242
243 double width = urc[0] - llc[0];
244 double height = urc[1] - llc[1];
245
246 llc[0] -= Units::mm2m * width;
247 urc[0] += Units::mm2m * width;
248 llc[1] -= Units::mm2m * height;
249 urc[1] += Units::mm2m * height;
250
251 bb_m = mslang::BoundingBox2D(llc, urc);
252
253 tree_m.bb_m = bb_m;
254 tree_m.objects_m.insert(tree_m.objects_m.end(), holes_m.begin(), holes_m.end());
255 tree_m.buildUp();
256
257 delete fun;
258}
259
260void FlexibleCollimator::writeHolesAndQuadtree(const std::string& baseFilename) const {
261 if (Ippl::myNode() == 0) {
262 std::string fname = Util::combineFilePath({
264 baseFilename
265 });
266
267 std::ofstream out(fname + "_quadtree.gpl");
268 tree_m.writeGnuplot(out);
269 out.close();
270
271 out.open(fname + "_holes.gpl");
272 for (const std::shared_ptr<mslang::Base> &obj: holes_m) {
273 obj->writeGnuplot(out);
274 }
275 out.close();
276 }
277}
Inform * gmsg
Definition Main.cpp:69
ElementType
Definition ElementBase.h:89
Inform * gmsg
Definition Main.cpp:69
#define ERRORMSG(msg)
Definition IpplInfo.h:350
Inform & endl(Inform &inf)
Definition Inform.cpp:42
Inform & level3(Inform &inf)
Definition Inform.cpp:47
const std::string name
constexpr double c
The velocity of light in m/s.
Definition Physics.h:45
constexpr double mm2m
Definition Units.h:29
bool parse(std::string str, Function *&fun)
Definition MSLang.cpp:35
bool asciidump
Definition Options.cpp:83
std::string combineFilePath(std::initializer_list< std::string > ilist)
Definition Util.cpp:204
Vector_t getBeta(Vector_t p)
Definition Util.h:54
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:666
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
bool getFlagDeleteOnTransverseExit() const
virtual double getElementLength() const
Get design length.
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:649
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:96
bool isInside(const Vector_t &R) const
Definition QuadTree.cpp:109
BoundingBox2D bb_m
Definition QuadTree.h:15
std::list< std::shared_ptr< Base > > objects_m
Definition QuadTree.h:14
static int myNode()
Definition IpplInfo.cpp:691