OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
CCollimator.cpp
Go to the documentation of this file.
1 //
2 // Class CCollimator
3 // Interface for cyclotron collimator
4 //
5 // Copyright (c) 2018-2022, 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 
22 #include "Fields/Fieldmap.h"
24 #include "Structure/LossDataSink.h"
25 
26 #include <cmath>
27 #include <fstream>
28 
29 extern Inform *gmsg;
30 
32 {}
33 
34 CCollimator::CCollimator(const std::string& name):
35  PluginElement(name) {
36  setDimensions(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
37  setGeom(0.0);
38 }
39 
41  PluginElement(right),
42  informed_m(right.informed_m) {
43  setDimensions(right.xstart_m, right.xend_m,
44  right.ystart_m, right.yend_m,
45  right.zstart_m, right.zend_m,
46  right.width_m);
48 }
49 
51 
52 void CCollimator::accept(BeamlineVisitor &visitor) const {
53  visitor.visitCCollimator(*this);
54 }
55 
57  Vector_t rmin, rmax;
58  bunch->get_bounds(rmin, rmax);
59 
60  if (rmax(2) >= zstart_m && rmin(2) <= zend_m) {
61  // interested in absolute minimum and maximum
62  double xmin = std::min(std::abs(rmin(0)), std::abs(rmax(0)));
63  double xmax = std::max(std::abs(rmin(0)), std::abs(rmax(0)));
64  double ymin = std::min(std::abs(rmin(1)), std::abs(rmax(1)));
65  double ymax = std::max(std::abs(rmin(1)), std::abs(rmax(1)));
66  double rbunch_min = std::hypot(xmin, ymin);
67  double rbunch_max = std::hypot(xmax, ymax);
68 
69  if ( rbunch_max > rmin_m && rbunch_min < rmax_m ){ // check similar to z
70  return true;
71  }
72  }
73  return false;
74 }
75 
76 // rectangle collimators in cyclotron cylindrical coordinates
77 // when there is no particlematterinteraction, the particle hitting collimator is deleted directly
78 bool CCollimator::doCheck(PartBunchBase<double, 3>* bunch, const int turnnumber,
79  const double t, const double /*tstep*/) {
80 
81  bool flagNeedUpdate = false;
82  size_t tempnum = bunch->getLocalNum();
83  int pflag = 0;
84  // now check each particle in bunch
85  for (unsigned int i = 0; i < tempnum; ++i) {
86  if (bunch->R[i](2) < zend_m && bunch->R[i](2) > zstart_m ) {
87  // only now careful check in r
88  pflag = checkPoint(bunch->R[i](0), bunch->R[i](1));
90  if ((pflag != 0) && (bunch->Bin[i] != -1)) {
91  lossDs_m->addParticle(OpalParticle(bunch->ID[i],
92  bunch->R[i], bunch->P[i],
93  t, bunch->Q[i], bunch->M[i]),
94  std::make_pair(turnnumber, bunch->bunchNum[i]));
95 
96  bunch->Bin[i] = -1;
97  flagNeedUpdate = true;
98  }
99  }
100  }
101  return flagNeedUpdate;
102 }
103 
104 bool CCollimator::doFinaliseCheck(PartBunchBase<double, 3>* bunch, bool flagNeedUpdate) {
105 
106  reduce(&flagNeedUpdate, &flagNeedUpdate + 1, &flagNeedUpdate, OpBitwiseOrAssign());
107 
108  if (flagNeedUpdate && parmatint_m) {
109  *gmsg << level2 << "============== START PARTICLE MATTER INTERACTION CALCULATION =============" << endl;
110  do {
112 
113  bool collWithParticles = (parmatint_m->getParticlesInMat() > 0);
114 
115  unsigned int localNum = bunch->getLocalNum();
116  unsigned int totalNum = 0;
117  reduce(localNum, totalNum, OpAddAssign());
118 
119  bool allParticlesInMat = (totalNum == 0 && collWithParticles);
120  if (allParticlesInMat) {
122  }
123 
124  Vector_t rmin, rmax;
125  bunch->get_bounds(rmin, rmax);
126  std::pair<Vector_t, double> boundingSphere;
127  boundingSphere.first = 0.5 * (rmax + rmin);
128  boundingSphere.second = euclidean_norm(rmax - boundingSphere.first);
129 
130  parmatint_m->apply(bunch, boundingSphere);
131  parmatint_m->print(*gmsg);
132 
133  } while (parmatint_m->stillActive());
134 
135  *gmsg << level2 << "============== END PARTICLE MATTER INTERACTION CALCULATION =============" << endl;
136  }
137  return flagNeedUpdate;
138 }
139 
142 }
143 
144 void CCollimator::goOnline(const double&) {
145  print();
146  online_m = true;
147 }
148 
150  *gmsg << "* Finalize cyclotron collimator " << getName() << endl;
151 }
152 
154  if (RefPartBunch_m == nullptr) {
155  if (!informed_m) {
156  std::string errormsg = _Fieldmap::typeset_msg("BUNCH SIZE NOT SET", "warning");
157  ERRORMSG(errormsg << endl);
158  if (Ippl::myNode() == 0) {
159  std::ofstream omsg("errormsg.txt", std::ios_base::app);
160  omsg << errormsg << std::endl;
161  omsg.close();
162  }
163  informed_m = true;
164  }
165  return;
166  }
167 }
168 
169 void CCollimator::setDimensions(double xstart, double xend,
170  double ystart, double yend,
171  double zstart, double zend,
172  double width) {
173  setDimensions(xstart, xend, ystart, yend);
174  zstart_m = zstart;
175  zend_m = zend;
176  width_m = width;
177  // zstart and zend are independent from x, y
178  if (zstart_m > zend_m) {
179  std::swap(zstart_m, zend_m);
180  }
181  setGeom(width_m);
182 }
183 
184 void CCollimator::getDimensions(double& zBegin, double& zEnd) const {
185  zBegin = 0.0;
186  zEnd = getElementLength();
187 }
188 
191 }
192 
194  // calculate maximum r from these
196  for (int i=0; i<4; i++) {
197  double r = std::hypot(geom_m[i].x, geom_m[i].y);
198  rmax_m = std::max(rmax_m, r);
199  }
200  // some debug printout
201  // for (int i=0; i<4; i++) {
202  // *gmsg << "point " << i << " ( " << geom_m[i].x << ", " << geom_m[i].y << ")" << endl;
203  // }
204  // *gmsg << "rmin " << rmin_m << " rmax " << rmax_m << endl;
205 }
void setDimensions(double xstart, double xend, double ystart, double yend, double zstart, double zend, double width)
Set dimensions and consistency checks.
virtual void getDimensions(double &zBegin, double &zEnd) const override
virtual bool doPreCheck(PartBunchBase< double, 3 > *) override
Virtual hook for preCheck.
Definition: CCollimator.cpp:56
virtual void goOnline(const double &kineticEnergy) override
Override implementation of PluginElement.
virtual void doFinalise() override
Virtual hook for finalise.
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
virtual void print(Inform &os)=0
ParticleAttrib< Vector_t > P
static int myNode()
Definition: IpplInfo.cpp:691
double xstart_m
input geometry positions
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
ParticleAttrib< short > bunchNum
void get_bounds(Vector_t &rmin, Vector_t &rmax) const
ParticleAttrib< double > M
PartBunchBase< double, 3 > * RefPartBunch_m
Definition: Component.h:191
virtual ~CCollimator()
Definition: CCollimator.cpp:50
static std::string typeset_msg(const std::string &msg, const std::string &title)
Definition: Fieldmap.cpp:649
virtual void accept(BeamlineVisitor &) const override
Apply visitor to CCollimator.
Definition: CCollimator.cpp:52
virtual const std::string & getName() const
Get element name.
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
std::unique_ptr< LossDataSink > lossDs_m
Pointer to Loss instance.
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
double rmin_m
radius closest to the origin
virtual bool doCheck(PartBunchBase< double, 3 > *bunch, const int turnnumber, const double t, const double tstep) override
Record hits when bunch particles pass.
Definition: CCollimator.cpp:78
double rmax_m
maximum extend in r
Definition: CCollimator.h:84
virtual size_t getParticlesInMat()=0
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition: Vector.h:243
virtual ElementType getType() const override
Get element type std::string.
double zstart_m
input geometry positions
Definition: CCollimator.h:80
ParticleMatterInteractionHandler * parmatint_m
Definition: CCollimator.h:86
void print()
unused check method
int checkPoint(const double &x, const double &y) const
Checks if coordinate is within element.
bool online_m
Definition: Component.h:192
size_t getLocalNum() const
Definition: Inform.h:42
ElementType
Definition: ElementBase.h:88
ParticleAttrib< double > Q
Point geom_m[5]
actual geometry positions with adaptive width such that each particle hits element once per turn ...
virtual double getElementLength() const
Get design length.
Definition: ElementBase.h:415
virtual void apply(PartBunchBase< double, 3 > *bunch, const std::pair< Vector_t, double > &boundingSphere)=0
double width_m
Definition: CCollimator.h:82
const std::string name
virtual bool doFinaliseCheck(PartBunchBase< double, 3 > *bunch, bool flagNeedUpdate) override
Virtual hook for finaliseCheck.
ParticlePos_t & R
virtual void doSetGeom() override
Calculate extend in r.
ParticleIndex_t & ID
virtual void visitCCollimator(const CCollimator &)=0
Apply the algorithm to a collimator.
virtual ParticleMatterInteractionHandler * getParticleMatterInteraction() const
Definition: ElementBase.h:483
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
ParticleAttrib< int > Bin
virtual void doInitialise(PartBunchBase< double, 3 > *bunch) override
Initialise particle matter interaction.
double zend_m
Definition: CCollimator.h:81
void setGeom(const double dist)
Sets geometry geom_m with element width dist.
Inform * gmsg
Definition: Main.cpp:70
bool informed_m
Flag if error information already printed.
Definition: CCollimator.h:77
bool reduce(Communicate &, InputIterator, InputIterator, OutputIterator, const ReduceOp &, bool *IncludeVal=0)
Definition: GlobalComm.hpp:55