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