BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSBunchHaloFlatSigma.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 "BDSBunchHaloFlatSigma.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 "CLHEP/Random/RandFlat.h"
28#include "CLHEP/Units/SystemOfUnits.h"
29#include "Randomize.hh"
30
31#include <algorithm>
32#include <cmath>
33#include <iterator>
34#include <utility>
35#include <vector>
36
37
38namespace BDS
39{
40 PhaseSpaceCoord PhaseSpaceCoordFromActionAngle(ActionAngleCoord aa, const TwissPair& tp)
41 {
42 G4double action = aa.action;
43 G4double angle = aa.angle;
44 G4double alpha = tp.alpha;
45 G4double beta = tp.beta;
46 G4double x = std::sqrt(2 * action * beta) * std::cos(angle);
47 G4double xp = (-std::sqrt(2 * action / beta) * (std::sin(angle) + alpha * std::cos(angle)));
48 PhaseSpaceCoord result = {x, xp};
49 return result;
50 }
51
52 EllipsePointGenerator::EllipsePointGenerator(G4double actionIn,
53 const TwissPair& tp):
54 action(actionIn),
55 twisspair(tp)
56 {
57 // Here: populate angles vector from 0 to 2pi and the corresponding arc
58 // lengths from angle=0 to each angle.
59 G4int npoints = 100;
60 std::vector<PhaseSpaceCoord> points;
61 points.reserve(npoints);
62 // Sample points on the ellipse equidistantly.
63 // leq (<=) so that can can interpolate up to 2pi.
64 for (G4int i = 0; i <= npoints; ++i)
65 {
66 G4double angle = i * CLHEP::twopi / npoints;
67 angles.push_back(angle);
68 ActionAngleCoord aa = {action, angle};
69 points.push_back(PhaseSpaceCoordFromActionAngle(aa, twisspair));
70 }
71 // Get the cumulative distances from angle=0 to each angle. The distance
72 // between the first and second point is of course non-zero. So we have to
73 // consider the case where we roll a pathLength between 0 and the first
74 // distance. To do this we insert 0 at the start.
75 std::vector<G4double> cumulativeDistances = CumulativeDistances(points);
76 cumulativeDistances.insert(std::begin(cumulativeDistances), 0);
77 pathLengths = std::move(cumulativeDistances);
78 }
79
80 PhaseSpaceCoord EllipsePointGenerator::GetRandomPointOnEllipse() const
81 {
82 // Select random point on the perimeter
83 G4double pathLength = EllipsePerimeter() * G4RandFlat::shoot();
84 // Invert to get the angle and then use that to get the (x, xp) pair.
85 G4double angle = PathLengthToAngle(pathLength);
86 ActionAngleCoord aa = {action, angle};
87 return PhaseSpaceCoordFromActionAngle(aa, twisspair);
88 }
89
90 G4double EllipsePointGenerator::PathLengthToAngle(G4double pathLength) const
91 {
92 // Find position of pathLength in pathLengths
93 auto it = std::lower_bound(std::begin(pathLengths), std::end(pathLengths), pathLength);
94 auto n = std::distance(std::begin(pathLengths), it);
95
96 // Get path lengths and angles either side of the point we are trying to
97 // evaluate.
98 G4double s1 = *it;
99 G4double s0 = *(--it);
100 G4double angle0 = *std::next(std::begin(angles), n - 1);
101 G4double angle1 = *std::next(std::begin(angles), n);
102
103 // Do the linear interpolation
104 G4double angle = angle0 + (pathLength - s0) * ((angle1 - angle0) / (s1 - s0));
105 return angle;
106 }
107}
108
109BDSBunchHaloFlatSigma::BDSBunchHaloFlatSigma():
110 BDSBunch("halosigma"),
111 alphaX(0.0), alphaY(0.0),
112 betaX(0.0), betaY(0.0),
113 emitX(0.0), emitY(0.0),
114 sigmaX(0.0), sigmaY(0.0),
115 haloNSigmaXInner(0.0), haloNSigmaXOuter(0.0),
116 haloNSigmaYInner(0.0), haloNSigmaYOuter(0.0)
117{;}
118
120 const GMAD::Beam& beam,
121 const BDSBunchType& distrType,
122 G4Transform3D beamlineTransformIn,
123 const G4double beamlineSIn)
124{
125 BDSBunch::SetOptions(beamParticle, beam, distrType, beamlineTransformIn, beamlineSIn);
126 alphaX = G4double(beam.alfx);
127 alphaY = G4double(beam.alfy);
128 betaX = G4double(beam.betx);
129 betaY = G4double(beam.bety);
130 haloNSigmaXInner = G4double(beam.haloNSigmaXInner);
131 haloNSigmaXOuter = G4double(beam.haloNSigmaXOuter);
132 haloNSigmaYInner = G4double(beam.haloNSigmaYInner);
133 haloNSigmaYOuter = G4double(beam.haloNSigmaYOuter);
134
135 G4double ex, ey; // dummy variables we don't need
136 SetEmittances(beamParticle, beam, emitX, emitY, ex, ey);
137
138 sigmaX = std::sqrt(emitX * betaX);
139 sigmaY = std::sqrt(emitY * betaY);
140
142}
143
145{
146 // Sampler flat in nsigma between lower and upper.
147 G4double xsigrange = (haloNSigmaXOuter - haloNSigmaXInner);
148 G4double ysigrange = (haloNSigmaYOuter - haloNSigmaYInner);
149 G4double xnsig = haloNSigmaXInner + G4RandFlat::shoot() * xsigrange;
150 G4double ynsig = haloNSigmaYInner + G4RandFlat::shoot() * ysigrange;
151
152 // Courant-snyder invariants for the particle, which are actually twice the
153 // particle actions...
154 G4double csix = std::pow(xnsig * sigmaX, 2) / betaX;
155 G4double csiy = std::pow(ynsig * sigmaY, 2) / betaY;
156 // The particle actions, which we use here.
157 G4double jx = csix / 2.0;
158 G4double jy = csiy / 2.0;
159
162
165 auto xps = epgx.GetRandomPointOnEllipse();
166 auto yps = epgy.GetRandomPointOnEllipse();
167
168 G4double x = (xps.position + X0) * CLHEP::m;
169 G4double xp = (xps.momentum + Xp0) * CLHEP::rad;
170 G4double y = (yps.position + Y0) * CLHEP::m;
171 G4double yp = (yps.momentum + Yp0) * CLHEP::rad;
172 G4double z = 0.;
173 G4double zp = CalculateZp(xp, yp, Zp0);
174 G4double weight = 1.0;
175 BDSParticleCoordsFull result(x, y, z, xp, yp, zp, T0, S0 + z, E0, weight);
176 return result;
177}
178
180{
182
183 if (emitX <= 0)
184 {throw BDSException(__METHOD_NAME__, "emitx must be > 0!");}
185 if (emitY <= 0)
186 {throw BDSException(__METHOD_NAME__, "emity must be > 0!");}
187
188 if (haloNSigmaXInner <= 0)
189 {throw BDSException(__METHOD_NAME__, "haloNSigmaXInner <= 0");}
190
191 if (haloNSigmaYInner <= 0)
192 {throw BDSException(__METHOD_NAME__, "haloNSigmaYInner <= 0");}
193
194 if (haloNSigmaXInner > haloNSigmaXOuter)
195 {throw BDSException(__METHOD_NAME__, "haloNSigmaXInner cannot be less than haloNSigmaXOuter");}
196
197 if (haloNSigmaYInner > haloNSigmaYOuter)
198 {throw BDSException(__METHOD_NAME__, "haloNSigmaYInner cannot be less than haloNSigmaYOuter");}
199}
G4double alphaX
Twiss parameter.
G4double sigmaY
Twiss parameter.
G4double betaY
Twiss parameter.
virtual void SetOptions(const BDSParticleDefinition *beamParticle, const GMAD::Beam &beam, const BDSBunchType &distrType, G4Transform3D beamlineTransformIn=G4Transform3D::Identity, const G4double beamlineS=0)
G4double sigmaX
Twiss parameter.
G4double emitX
Twiss parameter.
G4double betaX
Twiss parameter.
G4double emitY
Twiss parameter.
virtual BDSParticleCoordsFull GetNextParticleLocal()
G4double alphaY
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 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++.
Class for generating points uniformly on ellipse perimeters via interpolation. Part of implementation...
double alfy
initial twiss parameters
Definition beamBase.h:89
double haloNSigmaYInner
for the halo distribution
Definition beamBase.h:126
double betx
initial twiss parameters
Definition beamBase.h:89
double haloNSigmaXInner
for the halo distribution
Definition beamBase.h:124
double haloNSigmaYOuter
for the halo distribution
Definition beamBase.h:127
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
Beam class.
Definition beam.h:43
Return either G4Tubs or G4CutTubs depending on flat face.
Simple struct for storing action/angle pairs to aid readability. Implementation detail.
Simple struct for storing position/momentum pairs to aid readability. Implementation detail.
Simple struct for storing Twiss alpha/beta pairs to aid readability. Implementation detail.