20#include "BDSFieldMagSolenoidSheet.hh"
21#include "BDSMagnetStrength.hh"
22#include "BDSUtilities.hh"
24#include "G4ThreeVector.hh"
27#include "CLHEP/Units/PhysicalConstants.h"
28#include "CLHEP/Units/SystemOfUnits.h"
38BDSFieldMagSolenoidSheet::BDSFieldMagSolenoidSheet(G4double fullLength,
42 halfLength(0.5*fullLength),
44 spatialLimit(std::min(1e-5*sheetRadius, 1e-5*fullLength)),
52 G4double testBz =
OnAxisBz(halfLength, -halfLength);
53 normalisation = B0 / testBz;
57 const G4double )
const
59 G4double z = position.z();
60 G4double rho = position.perp();
61 G4double phi = position.phi();
65 if (std::abs(std::abs(z) - halfLength) < spatialLimit && (rho < a+2*spatialLimit))
66 {
return G4ThreeVector();}
67 else if (std::abs(rho - a) < spatialLimit && (std::abs(z) < halfLength+2*spatialLimit))
68 {
return G4ThreeVector();}
70 G4double zp = z + halfLength;
71 G4double zm = z - halfLength;
77 if (std::abs(rho) < spatialLimit)
81 G4double zpSq = zp*zp;
82 G4double zmSq = zm*zm;
84 G4double rhoPlusA = rho + a;
85 G4double rhoPlusASq = rhoPlusA * rhoPlusA;
86 G4double aMinusRho = a - rho;
87 G4double aMinusRhoSq = aMinusRho*aMinusRho;
89 G4double denominatorP = std::sqrt(zpSq + rhoPlusASq);
90 G4double denominatorM = std::sqrt(zmSq + rhoPlusASq);
92 G4double alphap = a / denominatorP;
93 G4double alpham = a / denominatorM;
95 G4double betap = zp / denominatorP;
96 G4double betam = zm / denominatorM;
98 G4double gamma = (a - rho) / (rhoPlusA);
99 G4double gammaSq = gamma * gamma;
101 G4double kp = std::sqrt(zpSq + aMinusRhoSq) / denominatorP;
102 G4double km = std::sqrt(zmSq + aMinusRhoSq) / denominatorM;
104 Brho = B0 * (alphap *
CEL(kp, 1, 1, -1) - alpham *
CEL(km, 1, 1, -1)) / CLHEP::pi;
105 Bz = ((B0 * a) / (rhoPlusA)) * (betap *
CEL(kp, gammaSq, 1, gamma) - betam *
CEL(km, gammaSq, 1, gamma)) / CLHEP::pi;
107 if (std::isnan(Brho))
114 G4ThreeVector result = G4ThreeVector(Brho,0,Bz) * normalisation;
115 result = result.rotateZ(phi);
123 G4int nIterationLimit)
128 G4double errtol = 0.000001;
129 G4double k = std::abs(kc);
141 G4double f = kc * kc;
142 G4double q = 1.0 - f;
143 G4double g = 1.0 - pp;
145 q = q * (ss - c * pp);
146 pp = std::sqrt(f / g);
148 ss = -q / (g * g * pp) + cc * pp;
160 while ( (std::abs(g-k) > g*errtol) && nLoop < nIterationLimit)
173 G4double result = CLHEP::halfpi*(ss + cc*em)/( em*(em + pp) );
180 G4double f1 = zp / std::sqrt( zp*zp + a*a );
181 G4double f2 = zm / std::sqrt( zm*zm + a*a );
182 G4double Bz = 0.5*B0 * (f1 - f2);
Class that provides the magnetic field due to a cylinder of current.
G4double OnAxisBz(G4double zp, G4double zm) const
static G4double CEL(G4double kc, G4double p, G4double c, G4double s, G4int nIterationLimit=1000)
Generalised Complete Elliptical Integral.
virtual G4ThreeVector GetField(const G4ThreeVector &position, const G4double t=0) const
Calculate the field value.
G4bool finiteStrength
Flag to cache whether finite nor not.
Efficient storage of magnet strengths.
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())