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