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