BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSFieldMagSolenoidBlock.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
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 "BDSFieldMagSolenoidBlock.hh"
20#include "BDSMagnetStrength.hh"
21#include "BDSSpecialFunctions.hh"
22#include "BDSUtilities.hh"
23#include "BDSFieldMagSolenoidSheet.hh"
24#include "BDSFieldMagVectorSum.hh"
25
26
27#include "G4ThreeVector.hh"
28#include "G4Types.hh"
29
30#include "CLHEP/Units/PhysicalConstants.h"
31#include "CLHEP/Units/SystemOfUnits.h"
32
33#include <cmath>
34#include <memory>
35
36BDSFieldMagSolenoidBlock::BDSFieldMagSolenoidBlock(BDSMagnetStrength const* strength,
37 G4double innerRadiusIn):
38 BDSFieldMagSolenoidBlock((*strength)["field"], false, innerRadiusIn, (*strength)["coilRadialThickness"], (*strength)["length"], 0, 1)
39{;}
40
41
42BDSFieldMagSolenoidBlock::BDSFieldMagSolenoidBlock(G4double strength,
43 G4bool strengthIsCurrent,
44 G4double innerRadiusIn,
45 G4double radialThicknessIn,
46 G4double fullLengthZIn,
47 G4double toleranceIn,
48 G4int nSheetsIn):
49 a(innerRadiusIn),
50 radialThickness(radialThicknessIn),
51 fullLengthZ(fullLengthZIn),
52 B0(0),
53 I(0),
54 coilTolerance(toleranceIn/(nSheetsIn*2)), //double the tolerance for each sheet
55 nSheetsBlock(nSheetsIn)
56{
57 // 'strength' can be current or B field
58 finiteStrength = BDS::IsFinite(std::abs(strength));
59
60 // apply relationship B0 = mu_0 I / 2 a for on-axis rho=0,z=0
61 if (strengthIsCurrent)
62 {
63 I = strength;
64 }
65 else
66 {// strength is B0 -> calculate current
67 B0 = strength;
68 I = B0 * 2 * a / CLHEP::mu0;
69 }
70 currentDensity = I*radialThickness*fullLengthZ/nSheetsBlock; // Current density in A/m^2 (TODO:Check)
71}
72
73G4ThreeVector BDSFieldMagSolenoidBlock::GetField(const G4ThreeVector& position,
74 const G4double /*t*/) const
75{
76 //G4double z = position.z();
77 //G4double rho = position.perp();
78 //G4double phi = position.phi(); // angle about z axis
79 std::unique_ptr<BDSFieldMag> field;
80 G4ThreeVector blockField = G4ThreeVector(0,0,0);
81 G4ThreeVector sheetField;
82 double dr = radialThickness/nSheetsBlock;
83 for (int sheet = 0; sheet < nSheetsBlock; sheet++)
84 {
85 field = std::make_unique<BDSFieldMagSolenoidSheet>(currentDensity,
86 true,
87 a + (sheet * dr) + dr / 2,
88 fullLengthZ,
89 coilTolerance);
90 sheetField = field->GetField(position);
91 if (sheetField == G4ThreeVector(0, 0, 0))
92 {break;}
93 else
94 {blockField += sheetField;}
95 }
96 return blockField;
97}
Class that provides the magnetic field due to a square annulus of current.
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())