BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSBunchHalo.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSBunchHalo.hh"
20#include "BDSDebug.hh"
21#include "BDSException.hh"
22#include "BDSParticleCoordsFull.hh"
23
24#include "parser/beam.h"
25
26#include "globals.hh" // geant4 types / globals
27
28#include "Randomize.hh"
29#include "CLHEP/Random/RandFlat.h"
30#include "CLHEP/Units/SystemOfUnits.h"
31
32#include <cmath>
33
34BDSBunchHalo::BDSBunchHalo():
35 BDSBunch("halo"),
36 alphaX(0.0), alphaY(0.0),
37 betaX(0.0), betaY(0.0),
38 emitX(0.0), emitY(0.0),
39 gammaX(0.0), gammaY(0.0),
40 sigmaX(0.0), sigmaY(0.0),
41 sigmaXp(0.0), sigmaYp(0.0),
42 haloNSigmaXInner(0.0), haloNSigmaXOuter(0.0),
43 haloNSigmaYInner(0.0), haloNSigmaYOuter(0.0),
44 haloXCutInner(0.0),
45 haloYCutInner(0.0),
46 haloXCutOuter(0.0),
47 haloYCutOuter(0.0),
48 haloXpCutInner(0.0),
49 haloYpCutInner(0.0),
50 haloXpCutOuter(0.0),
51 haloYpCutOuter(0.0),
52 haloPSWeightParameter(0.0),
53 weightFunction(""),
54 emitInnerX(0.0), emitInnerY(0.0),
55 emitOuterX(0.0), emitOuterY(0.0),
56 xMax(0.0), yMax(0.0),
57 xpMax(0.0), ypMax(0.0)
58{
59 flatGen = new CLHEP::RandFlat(*CLHEP::HepRandom::getTheEngine());
60}
61
62BDSBunchHalo::~BDSBunchHalo()
63{
64 delete flatGen;
65}
66
68 const GMAD::Beam& beam,
69 const BDSBunchType& distrType,
70 G4Transform3D beamlineTransformIn,
71 const G4double beamlineSIn)
72{
73 BDSBunch::SetOptions(beamParticle, beam, distrType, beamlineTransformIn, beamlineSIn);
74 alphaX = G4double(beam.alfx);
75 alphaY = G4double(beam.alfy);
76 betaX = G4double(beam.betx);
77 betaY = G4double(beam.bety);
78 gammaX = (1.0+alphaX*alphaX)/betaX;
79 gammaY = (1.0+alphaY*alphaY)/betaY;
80 haloNSigmaXInner = G4double(beam.haloNSigmaXInner);
81 haloNSigmaXOuter = G4double(beam.haloNSigmaXOuter);
82 haloNSigmaYInner = G4double(beam.haloNSigmaYInner);
83 haloNSigmaYOuter = G4double(beam.haloNSigmaYOuter);
84 haloXCutInner = G4double(beam.haloXCutInner);
85 haloYCutInner = G4double(beam.haloYCutInner);
86 haloXCutOuter = G4double(beam.haloXCutOuter);
87 haloYCutOuter = G4double(beam.haloYCutOuter);
88 haloXpCutInner = G4double(beam.haloXpCutInner);
89 haloYpCutInner = G4double(beam.haloYpCutInner);
90 haloXpCutOuter = G4double(beam.haloXpCutOuter);
91 haloYpCutOuter = G4double(beam.haloYpCutOuter);
92 haloPSWeightParameter = G4double(beam.haloPSWeightParameter);
93 weightFunction = G4String(beam.haloPSWeightFunction);
94
95 G4double ex,ey; // dummy variables we don't need
96 SetEmittances(beamParticle, beam, emitX, emitY, ex, ey);
97
98 sigmaX = std::sqrt(emitX * betaX);
99 sigmaY = std::sqrt(emitY * betaY);
100 sigmaXp = std::sqrt(gammaX * emitX);
101 sigmaYp = std::sqrt(gammaY * emitY);
102
103 emitInnerX = std::pow(haloNSigmaXInner, 2) * emitX;
104 emitInnerY = std::pow(haloNSigmaYInner, 2) * emitY;
105 emitOuterX = std::pow(haloNSigmaXOuter, 2) * emitX;
106 emitOuterY = std::pow(haloNSigmaYOuter, 2) * emitY;
107
108 xMax = haloNSigmaXOuter * sigmaX;
109 yMax = haloNSigmaYOuter * sigmaY;
110 xpMax = std::sqrt(std::pow(haloNSigmaXOuter, 2) * emitX * gammaX);
111 ypMax = std::sqrt(std::pow(haloNSigmaYOuter, 2) * emitY * gammaY);
112
114}
115
117{
118 // Central orbit
119 G4double x = X0;
120 G4double y = Y0;
121 G4double z = Z0;
122 G4double xp = Xp0;
123 G4double yp = Yp0;
124
125 // z += (T0 - envelopeT * (1.-2.*flatGen->shoot())) * CLHEP::c_light * CLHEP::s;
126 z = 0;
127
128 while (true)
129 {
130 G4double dx = xMax * (1 - 2 * flatGen->shoot());
131 G4double dy = yMax * (1 - 2 * flatGen->shoot());
132 G4double dxp = xpMax * (1 - 2 * flatGen->shoot());
133 G4double dyp = ypMax * (1 - 2 * flatGen->shoot());
134
135 // compute single particle emittance
136 double emitXSp = gammaX * std::pow(std::abs(dx), 2) + (2. * alphaX * dx * dxp) + betaX * std::pow(std::abs(dxp), 2);
137 double emitYSp = gammaY * std::pow(std::abs(dy), 2) + (2. * alphaY * dy * dyp) + betaY * std::pow(std::abs(dyp), 2);
138
139 // check if particle is within normal beam core, if so continue generation
140 // also check if particle is within the desired cut.
141 if ((std::abs(emitXSp) < emitInnerX || std::abs(emitYSp) < emitInnerY) ||
142 (std::abs(emitXSp) > emitOuterX || std::abs(emitYSp) > emitOuterY) ||
143 (std::abs(dx) < (haloXCutInner * sigmaX)) ||
144 (std::abs(dy) < (haloYCutInner * sigmaY)) ||
145 (std::abs(dx) > (haloXCutOuter * sigmaX)) ||
146 (std::abs(dy) > (haloYCutOuter * sigmaY)) ||
147 (std::abs(dxp) < (haloXpCutInner * sigmaXp)) ||
148 (std::abs(dyp) < (haloYpCutInner * sigmaYp)) ||
149 (std::abs(dxp) > (haloXpCutOuter * sigmaXp)) ||
150 (std::abs(dyp) > (haloYpCutOuter * sigmaYp)) )
151 {
152 continue;
153 }
154 else
155 {
156 // determine weight, initialise 1 so always passes
157 double wx = 1.0;
158 double wy = 1.0;
159 if (weightFunction == "flat" || weightFunction == "" || weightFunction == "one")
160 {
161 wx = 1.0;
162 wy = 1.0;
163 }
164 else if (weightFunction == "oneoverr")
165 {
166 //abs because power of double - must be positive
167 wx = std::pow(std::abs(emitInnerX / emitXSp), haloPSWeightParameter);
168 wy = std::pow(std::abs(emitInnerY / emitYSp), haloPSWeightParameter);
169 }
170 else if (weightFunction == "oneoverrsqrd")
171 {
172 //abs because power of double - must be positive
173 double eXsqrd = std::pow(std::abs(emitXSp), 2);
174 double eYsqrd = std::pow(std::abs(emitYSp), 2);
175 double eXInsq = std::pow(std::abs(emitInnerX), 2);
176 double eYInsq = std::pow(std::abs(emitInnerY), 2);
177 wx = std::pow(std::abs(eXInsq / eXsqrd), haloPSWeightParameter);
178 wy = std::pow(std::abs(eYInsq / eYsqrd), haloPSWeightParameter);
179 }
180 else if (weightFunction == "exp")
181 {
182 wx = std::exp(-(emitXSp * haloPSWeightParameter) / (emitInnerX));
183 wy = std::exp(-(emitYSp * haloPSWeightParameter) / (emitInnerY));
184 }
185
186#ifdef BDSDEBUG
187 G4cout << __METHOD_NAME__ << emitXSp/emitX << " " << emitYSp/emitY << " " << wx << " " << wy << G4endl;
188#endif
189 // reject
190 if (flatGen->shoot() > wx && flatGen->shoot() > wy)
191 {continue;}
192
193 // add to reference orbit
194 x += dx * CLHEP::m;
195 y += dy * CLHEP::m;
196 xp += dxp * CLHEP::rad;
197 yp += dyp * CLHEP::rad;
198
199 G4double zp = CalculateZp(xp, yp, Zp0);
200
201#ifdef BDSDEBUG
202 G4cout << __METHOD_NAME__ << "selected> " << dx << " " << dy << " " << dxp << " " << dyp << G4endl;
203#endif
204 // E0 and T0 from base class and already in G4 units
205 BDSParticleCoordsFull result(x,y,z,xp,yp,zp,T0,S0+z,E0,/*weight=*/1.0);
206 return result;
207 }
208 }
209}
210
212{
214
215 if (emitX <= 0)
216 {throw BDSException(__METHOD_NAME__, "emitx must be finite!");}
217 if (emitY <= 0)
218 {throw BDSException(__METHOD_NAME__, "emity must be finite!");}
219
220 if (betaX <= 0)
221 {throw BDSException(__METHOD_NAME__, "betx must be finite!");}
222 if (betaY <= 0)
223 {throw BDSException(__METHOD_NAME__, "bety must be finite!");}
224
225 std::vector<G4String> weightFunctions = {"", "one", "flat","oneoverr", "oneoverrsqrd", "exp"};
226 auto search = std::find(weightFunctions.begin(), weightFunctions.end(), weightFunction);
227 if (search == weightFunctions.end())
228 {
229 G4cerr << __METHOD_END__ << "invalid haloPSWeightFunction \"" << weightFunction << "\"" << G4endl;
230 G4cout << "Available weight functions are:" << G4endl;
231 for (const auto& w : weightFunctions)
232 {G4cout << w << G4endl;}
233 throw BDSException(__METHOD_END__, "");
234 }
235
236 if (haloNSigmaXInner <= 0)
237 {throw BDSException(__METHOD_NAME__, "haloNSigmaXInner <= 0");}
238
239 if (haloNSigmaYInner <= 0)
240 {throw BDSException(__METHOD_NAME__, "haloNSigmaYInner <= 0");}
241
242 if (haloNSigmaXInner > haloNSigmaXOuter)
243 {throw BDSException(__METHOD_NAME__, "haloNSigmaXInner cannot be less than haloNSigmaXOuter");}
244
245 if (haloNSigmaYInner > haloNSigmaYOuter)
246 {throw BDSException(__METHOD_NAME__, "haloNSigmaYInner cannot be less than haloNSigmaYOuter");}
247
248 if (haloXCutInner < 0)
249 {throw BDSException(__METHOD_NAME__, "haloXCutInner < 0");}
250
251 if (haloYCutInner < 0)
252 {throw BDSException(__METHOD_NAME__, "haloYCutInner < 0");}
253
254 if (haloXCutOuter <= haloXCutInner)
255 {throw BDSException(__METHOD_NAME__, "haloXCutOuter must be greater than haloXCutInner!");}
256
257 if (haloYCutOuter <= haloYCutInner)
258 {throw BDSException(__METHOD_NAME__, "haloYCutOuter must be greater than haloYCutInner!");}
259
260 if (haloXpCutInner < 0)
261 {throw BDSException(__METHOD_NAME__, "haloXpCutInner < 0");}
262
263 if (haloYpCutInner < 0)
264 {throw BDSException(__METHOD_NAME__, "haloYpCutInner < 0");}
265
266 if (haloXpCutOuter <= haloXpCutInner)
267 {throw BDSException(__METHOD_NAME__, "haloXpCutOuter must be greater than haloXpCutInner!");}
268
269 if (haloYpCutOuter <= haloYpCutInner)
270 {throw BDSException(__METHOD_NAME__, "haloYpCutOuter must be greater than haloYpCutInner!");}
271}
G4double sigmaX
Twiss parameter.
Definition: BDSBunchHalo.hh:61
G4double sigmaYp
Twiss parameter.
Definition: BDSBunchHalo.hh:64
G4double alphaY
Twiss parameter.
Definition: BDSBunchHalo.hh:54
G4double gammaY
Twiss parameter.
Definition: BDSBunchHalo.hh:60
G4double emitX
Twiss parameter.
Definition: BDSBunchHalo.hh:57
G4double gammaX
Twiss parameter.
Definition: BDSBunchHalo.hh:59
G4double sigmaXp
Twiss parameter.
Definition: BDSBunchHalo.hh:63
G4double emitY
Twiss parameter.
Definition: BDSBunchHalo.hh:58
G4double sigmaY
Twiss parameter.
Definition: BDSBunchHalo.hh:62
virtual void SetOptions(const BDSParticleDefinition *beamParticle, const GMAD::Beam &beam, const BDSBunchType &distrType, G4Transform3D beamlineTransformIn=G4Transform3D::Identity, const G4double beamlineS=0)
Definition: BDSBunchHalo.cc:67
virtual BDSParticleCoordsFull GetNextParticleLocal()
G4double betaY
Twiss parameter.
Definition: BDSBunchHalo.hh:56
virtual void CheckParameters()
G4double alphaX
Twiss parameter.
Definition: BDSBunchHalo.hh:53
G4double betaX
Twiss parameter.
Definition: BDSBunchHalo.hh:55
The base class for bunch distribution generators.
Definition: BDSBunch.hh:47
G4double Yp0
Centre of distributions.
Definition: BDSBunch.hh:166
G4double T0
Centre of distributions.
Definition: BDSBunch.hh:164
G4double S0
Centre of distributions.
Definition: BDSBunch.hh:163
G4double Z0
Centre of distributions.
Definition: BDSBunch.hh:162
G4double X0
Centre of distributions.
Definition: BDSBunch.hh:160
G4double Zp0
Centre of distributions.
Definition: BDSBunch.hh:167
G4double Xp0
Centre of distributions.
Definition: BDSBunch.hh:165
G4double E0
Centre of distributions.
Definition: BDSBunch.hh:168
static void SetEmittances(const BDSParticleDefinition *beamParticle, const GMAD::Beam &beam, G4double &emittGeometricX, G4double &emittGeometricY, G4double &emittNormalisedX, G4double &emittNormalisedY)
Definition: BDSBunch.cc:155
G4double Y0
Centre of distributions.
Definition: BDSBunch.hh:161
virtual void SetOptions(const BDSParticleDefinition *beamParticle, const GMAD::Beam &beam, const BDSBunchType &distrType, G4Transform3D beamlineTransformIn=G4Transform3D::Identity, const G4double beamlineS=0)
Definition: BDSBunch.cc:78
static G4double CalculateZp(G4double xp, G4double yp, G4double Zp0)
Calculate zp safely based on other components.
Definition: BDSBunch.cc:317
virtual void CheckParameters()
Definition: BDSBunch.cc:195
General exception with possible name of object and message.
Definition: BDSException.hh:35
A set of particle coordinates including energy and weight.
Wrapper for particle definition.
Improve type-safety of native enum data type in C++.
double alfy
initial twiss parameters
Definition: beamBase.h:82
double haloXCutOuter
for the halo distribution
Definition: beamBase.h:121
double haloNSigmaYInner
for the halo distribution
Definition: beamBase.h:117
double haloXpCutOuter
for the halo distribution
Definition: beamBase.h:125
double haloXCutInner
for the halo distribution
Definition: beamBase.h:119
double haloYpCutInner
for the halo distribution
Definition: beamBase.h:124
double betx
initial twiss parameters
Definition: beamBase.h:82
double haloYCutOuter
for the halo distribution
Definition: beamBase.h:122
double haloNSigmaXInner
for the halo distribution
Definition: beamBase.h:115
double haloNSigmaYOuter
for the halo distribution
Definition: beamBase.h:118
double haloYCutInner
for the halo distribution
Definition: beamBase.h:120
double haloNSigmaXOuter
for the halo distribution
Definition: beamBase.h:116
double alfx
initial twiss parameters
Definition: beamBase.h:82
double bety
initial twiss parameters
Definition: beamBase.h:82
double haloPSWeightParameter
for the halo distribution
Definition: beamBase.h:127
std::string haloPSWeightFunction
for the halo distribution
Definition: beamBase.h:128
double haloXpCutInner
for the halo distribution
Definition: beamBase.h:123
double haloYpCutOuter
for the halo distribution
Definition: beamBase.h:126
Beam class.
Definition: beam.h:44