BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSFieldEMRFCavity.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2024.
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 "BDSCavityInfo.hh"
20#include "BDSDebug.hh"
21#include "BDSException.hh"
22#include "BDSFieldEMRFCavity.hh"
23#include "BDSMagnetStrength.hh"
24#include "BDSUtilities.hh"
25
26#include "CLHEP/Units/PhysicalConstants.h"
27#include "globals.hh"
28#include "G4ThreeVector.hh"
29
30#include "TMath.h"
31
32#include <cmath>
33#include <utility>
34
35const G4double BDSFieldEMRFCavity::j0FirstZero = 2.404825557695772768622;
36
37const G4double BDSFieldEMRFCavity::Z0 = CLHEP::mu0 * CLHEP::c_light;
38
39BDSFieldEMRFCavity::BDSFieldEMRFCavity(BDSMagnetStrength const* strength):
40 BDSFieldEMRFCavity((*strength)["efield"],
41 (*strength)["frequency"],
42 (*strength)["phase"],
43 (*strength)["equatorradius"],
44 (*strength)["synchronousT0"])
45{;}
46
47BDSFieldEMRFCavity::BDSFieldEMRFCavity(G4double eFieldAmplitude,
48 G4double frequencyIn,
49 G4double phaseOffset,
50 G4double cavityRadiusIn,
51 G4double synchronousTIn):
52 eFieldMax(eFieldAmplitude),
53 phase(phaseOffset),
54 cavityRadius(cavityRadiusIn),
55 synchronousT(synchronousTIn),
56 normalisedCavityRadius(j0FirstZero/cavityRadius),
57 angularFrequency(CLHEP::twopi * frequencyIn)
58{
59 // this would cause NANs to be propagated into tracking which is really bad
60 if (!BDS::IsFinite(cavityRadiusIn) || std::isnan(normalisedCavityRadius) || std::isinf(normalisedCavityRadius))
61 {throw BDSException(__METHOD_NAME__, "no cavity radius supplied - required for pill box model");}
62}
63
64std::pair<G4ThreeVector, G4ThreeVector> BDSFieldEMRFCavity::GetField(const G4ThreeVector& position,
65 const G4double t) const
66{
67 // Converting from Local Cartesian to Local Cylindrical
68 G4double phi = std::atan2(position.y(),position.x());
69 G4double r = std::hypot(position.x(),position.y());
70
71 G4double rNormalised = normalisedCavityRadius * r;
72
73 // In case a point outside the cavity is queried, ensure the bessel will return 0
74 if (rNormalised > j0FirstZero)
75 {rNormalised = j0FirstZero - 1e-6;}
76
77 G4double J0r = TMath::BesselJ0(rNormalised);
78 G4double J1r = TMath::BesselJ1(rNormalised);
79
80 // Calculating free-space impedance and scale factor for Bphi:
81 G4double hMax = -eFieldMax/Z0;
82 G4double Bmax = hMax * CLHEP::mu0;
83
84 // Calculating field components.
85 G4double arg = angularFrequency*(t - synchronousT) + phase;
86 G4double Ez = eFieldMax * J0r * std::cos(arg);
87 G4double Bphi = Bmax * J1r * std::sin(arg);
88
89 // Converting Bphi into cartesian coordinates:
90 G4TwoVector bxby(0,Bphi); // this is equivalent to a pi/2 rotation of (1,0)
91 bxby.rotate(phi);
92 G4double Bx = bxby.x();
93 G4double By = bxby.y();
94
95 // Local B and E fields:
96 G4ThreeVector LocalB = G4ThreeVector(Bx, By, 0);
97 G4ThreeVector LocalE = G4ThreeVector(0, 0, Ez);
98
99 auto result = std::make_pair(LocalB, LocalE);
100 return result;
101}
102
103G4double BDSFieldEMRFCavity::TransitTimeFactor(G4double frequency,
104 G4double phase,
105 G4double zLength,
106 G4double beta)
107{
108 G4double rfWavelength = CLHEP::c_light / frequency;
109 G4double piGOverBetaLambda = (CLHEP::pi * zLength) / (beta * rfWavelength);
110 G4double transitTimeFactor = std::sin(piGOverBetaLambda + phase) / piGOverBetaLambda;
111 return transitTimeFactor;
112}
General exception with possible name of object and message.
Pill box cavity electromagnetic field.
virtual std::pair< G4ThreeVector, G4ThreeVector > GetField(const G4ThreeVector &position, const G4double t) const
Accessor to get B and E field.
const G4double angularFrequency
Angular frequency calculated from frequency - cached to avoid repeated calculation.
G4double phase
Phase offset of the oscillator.
static const G4double j0FirstZero
X coordinate of first 0 point for bessel J0.
static const G4double Z0
Impedance of free space.
G4double eFieldMax
Maximum field in V/m.
const G4double normalisedCavityRadius
Pre-calculated normalised calculated radius w.r.t. bessel first 0.
static G4double TransitTimeFactor(G4double frequency, G4double phase, G4double zLength, G4double beta)
General function put here as it represents the equations in this class.
Efficient storage of magnet strengths.
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())