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) 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 "BDSCavityInfo.hh"
19#include "BDSDebug.hh"
20#include "BDSException.hh"
21#include "BDSFieldEMRFCavity.hh"
22#include "BDSMagnetStrength.hh"
23#include "BDSUtilities.hh"
24
25#include "CLHEP/Units/PhysicalConstants.h"
26#include "globals.hh"
27#include "G4ThreeVector.hh"
28
29#include "TMath.h"
30
31#include <cmath>
32#include <utility>
33
34const G4double BDSFieldEMRFCavity::j0FirstZero = 2.404825557695772768622;
35
36const G4double BDSFieldEMRFCavity::Z0 = CLHEP::mu0 * CLHEP::c_light;
37
38BDSFieldEMRFCavity::BDSFieldEMRFCavity(BDSMagnetStrength const* strength):
39 BDSFieldEMRFCavity((*strength)["efield"],
40 (*strength)["frequency"],
41 (*strength)["phase"],
42 (*strength)["equatorradius"],
43 (*strength)["synchronousT0"])
44{;}
45
46BDSFieldEMRFCavity::BDSFieldEMRFCavity(G4double eFieldAmplitude,
47 G4double frequencyIn,
48 G4double phaseOffset,
49 G4double cavityRadiusIn,
50 G4double synchronousTIn):
51 eFieldMax(eFieldAmplitude),
52 phase(phaseOffset),
53 cavityRadius(cavityRadiusIn),
54 synchronousT(synchronousTIn),
55 normalisedCavityRadius(j0FirstZero/cavityRadius),
56 angularFrequency(CLHEP::twopi * frequencyIn)
57{
58 // this would cause NANs to be propagated into tracking which is really bad
59 if (!BDS::IsFinite(cavityRadiusIn) || std::isnan(normalisedCavityRadius) || std::isinf(normalisedCavityRadius))
60 {throw BDSException(__METHOD_NAME__, "no cavity radius supplied - required for pill box model");}
61}
62
63std::pair<G4ThreeVector, G4ThreeVector> BDSFieldEMRFCavity::GetField(const G4ThreeVector& position,
64 const G4double t) const
65{
66 // Converting from Local Cartesian to Local Cylindrical
67 G4double phi = std::atan2(position.y(),position.x());
68 G4double r = std::hypot(position.x(),position.y());
69
70 G4double rNormalised = normalisedCavityRadius * r;
71
72 // In case a point outside the cavity is queried, ensure the bessel will return 0
73 if (rNormalised > j0FirstZero)
74 {rNormalised = j0FirstZero - 1e-6;}
75
76 G4double J0r = TMath::BesselJ0(rNormalised);
77 G4double J1r = TMath::BesselJ1(rNormalised);
78
79 // Calculating free-space impedance and scale factor for Bphi:
80 G4double hMax = -eFieldMax/Z0;
81 G4double Bmax = hMax * CLHEP::mu0;
82
83 // Calculating field components.
84 G4double arg = angularFrequency*(t - synchronousT) + phase;
85 G4double Ez = eFieldMax * J0r * std::cos(arg);
86 G4double Bphi = Bmax * J1r * std::sin(arg);
87
88 // Converting Bphi into cartesian coordinates:
89 G4TwoVector bxby(0,Bphi); // this is equivalent to a pi/2 rotation of (1,0)
90 bxby.rotate(phi);
91 G4double Bx = bxby.x();
92 G4double By = bxby.y();
93
94 // Local B and E fields:
95 G4ThreeVector LocalB = G4ThreeVector(Bx, By, 0);
96 G4ThreeVector LocalE = G4ThreeVector(0, 0, Ez);
97
98 auto result = std::make_pair(LocalB, LocalE);
99 return result;
100}
101
102G4double BDSFieldEMRFCavity::TransitTimeFactor(G4double frequency,
103 G4double phase,
104 G4double zLength,
105 G4double beta)
106{
107 G4double rfWavelength = CLHEP::c_light / frequency;
108 G4double piGOverBetaLambda = (CLHEP::pi * zLength) / (beta * rfWavelength);
109 G4double transitTimeFactor = std::sin(piGOverBetaLambda + phase) / piGOverBetaLambda;
110 return transitTimeFactor;
111}
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())