BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSMagnetStrength.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 "BDSDebug.hh"
20#include "BDSException.hh"
21#include "BDSMagnetStrength.hh"
22
23#include "globals.hh" // geant4 globals / types
24
25#include "CLHEP/Units/SystemOfUnits.h"
26
27#include <algorithm>
28#include <iomanip>
29#include <map>
30#include <vector>
31
32const std::vector<G4String> BDSMagnetStrength::keys = {
33 "beta0", // relativistic beta for the primary particle - used in some integrators
34 "field", // constant field in G4units - magnitude of field only - use bx,by,bz to get direction
35 "efield", // electric field in G4units - magnitude of field only - use ex,ey,ez to get direction
36 "bx","by","bz", // (assumed) unit vector components for field direction
37 "ex","ey","ez", // (assumed) unit vector components for field direction
38 "e1", // entrance poleface rotation angle
39 "e2", // entrance poleface rotation angle
40 "h1", // poleface curvature for entrance face
41 "h2", // poleface curvature for exit face
42 "angle", "length", // (rad, mm)
43 "fint", // fringe field integral value for entrance face
44 "fintx", // fringe field integral value for exit face
45 "fintk2", // second fringe field integral value for entrance face
46 "fintxk2", // second fringe field integral value for exit face
47 "hgap", // fringe field vertical half-gap
48 "hkick", "vkick", // fractional horizontal and vertical dPx (w.r.t. rigidity)
49 "ks", // not in G4 units
50 "k1", "k1s",
51 "k2", "k2s",
52 "k3", "k3s",
53 "k4", "k4s",
54 "k5", "k5s",
55 "k6", "k6s",
56 "k7", "k7s",
57 "k8", "k8s",
58 "k9", "k9s",
59 "k10", "k10s",
60 "k11", "k11s",
61 "k12", "k12s",
62 "kg", // gabor lens focusing strength
63 "plasmaEfield", // magnitude of electric strength of confined Gabor lens plasma
64 "frequency", // frequency for time varying field (presumably em)
65 "phase", // phase for time varying field
66 "synchronousT0", // global T0 for the synchronous particle at the centre of the object
67 "equatorradius", // radius from axis at which field goes to 0
68 "nominalenergy", // nominal beam energy needed by some integrators
69 "scaling", // field scaling factor needed by dipolequadrupole integrator
70 "scalingOuter", // arbitrary scaling for yoke fields - kept as a separate scaling number
71 "isentrance", // bool to determine is integrator is for entrance (1) or exit (0) face
72 "kick1",
73 "kick2",
74 "kick3",
75 "kick4",
76 "rmat11",
77 "rmat12",
78 "rmat13",
79 "rmat14",
80 "rmat21",
81 "rmat22",
82 "rmat23",
83 "rmat24",
84 "rmat31",
85 "rmat32",
86 "rmat33",
87 "rmat34",
88 "rmat41",
89 "rmat42",
90 "rmat43",
91 "rmat44"
92};
93
94const std::map<G4String, BDSMagnetStrength::unitsFactors> BDSMagnetStrength::unitsFactorsMap = {
95 {"beta0" , {"", 1.0}},
96 {"field" , {"T", CLHEP::tesla}},
97 {"efield" , {"", CLHEP::megavolt}},
98 {"bx" , {"", 1.0}},
99 {"by" , {"", 1.0}},
100 {"bz" , {"", 1.0}},
101 {"ex" , {"", 1.0}},
102 {"ey" , {"", 1.0}},
103 {"ez" , {"", 1.0}},
104 {"e1" , {"rad", CLHEP::rad}},
105 {"e2" , {"rad", CLHEP::rad}},
106 {"h1" , {"rad", CLHEP::rad}},
107 {"h2" , {"rad", CLHEP::rad}},
108 {"angle" , {"rad", CLHEP::rad}},
109 {"length" , {"m", CLHEP::m}},
110 {"fint" , {"", 1.0}},
111 {"fintx" , {"", 1.0}},
112 {"fintk2" , {"", 1.0}},
113 {"fintxk2" , {"", 1.0}},
114 {"hgap" , {"m", CLHEP::m}},
115 {"hkick" , {"", 1.0}},
116 {"vkick" , {"", 1.0}},
117 {"ks" , {"", 1.0}},
118 {"k1" , {"", 1.0}},
119 {"k2" , {"", 1.0}},
120 {"k3" , {"", 1.0}},
121 {"k4" , {"", 1.0}},
122 {"k5" , {"", 1.0}},
123 {"k6" , {"", 1.0}},
124 {"k7" , {"", 1.0}},
125 {"k8" , {"", 1.0}},
126 {"k9" , {"", 1.0}},
127 {"k10" , {"", 1.0}},
128 {"k11" , {"", 1.0}},
129 {"k12" , {"", 1.0}},
130 {"k1s" , {"", 1.0}},
131 {"k2s" , {"", 1.0}},
132 {"k3s" , {"", 1.0}},
133 {"k4s" , {"", 1.0}},
134 {"k5s" , {"", 1.0}},
135 {"k6s" , {"", 1.0}},
136 {"k7s" , {"", 1.0}},
137 {"k8s" , {"", 1.0}},
138 {"k9s" , {"", 1.0}},
139 {"k10s" , {"", 1.0}},
140 {"k11s" , {"", 1.0}},
141 {"k12s" , {"", 1.0}},
142 {"frequency" , {"", CLHEP::megahertz}},
143 {"phase" , {"rad", CLHEP::rad}},
144 {"synchronousT0" , {"s", CLHEP::s}},
145 {"equatorradius" , {"m", CLHEP::m}},
146 {"kg" , {"", 1.0}},
147 {"plasmaEfield" , {"", 1.0}},
148 {"nominalenergy" , {"GeV", CLHEP::GeV}},
149 {"scaling" , {"", 1.0}},
150 {"scalingOuter" , {"", 1.0}},
151 {"isentrance" , {"", 1.0}},
152 {"kick1" , {"", 1.0}},
153 {"kick2" , {"", 1.0}},
154 {"kick3" , {"", 1.0}},
155 {"kick4" , {"", 1.0}},
156 {"rmat11" , {"", 1.0}},
157 {"rmat12" , {"", 1.0}},
158 {"rmat13" , {"", 1.0}},
159 {"rmat14" , {"", 1.0}},
160 {"rmat21" , {"", 1.0}},
161 {"rmat22" , {"", 1.0}},
162 {"rmat23" , {"", 1.0}},
163 {"rmat24" , {"", 1.0}},
164 {"rmat31" , {"", 1.0}},
165 {"rmat32" , {"", 1.0}},
166 {"rmat33" , {"", 1.0}},
167 {"rmat34" , {"", 1.0}},
168 {"rmat41" , {"", 1.0}},
169 {"rmat42" , {"", 1.0}},
170 {"rmat43" , {"", 1.0}},
171 {"rmat44" , {"", 1.0}},
172 {"coilRadialThickness", {"m", CLHEP::m}}
173};
174
175const std::vector<G4String> BDSMagnetStrength::normalComponentKeys = {
176 "k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8", "k9", "k10", "k11", "k12"};
177
178const std::vector<G4String> BDSMagnetStrength::skewComponentKeys = {
179 "k1s", "k2s", "k3s", "k4s", "k5s", "k6s", "k7s", "k8s", "k9s", "k10s", "k11s", "k12s"};
180
181const G4double BDSMagnetStrength::zero = 0.0;
182G4double BDSMagnetStrength::variable = 0.0;
183
184BDSMagnetStrength::BDSMagnetStrength(const std::map<G4String, G4double>& sts)
185{
186 for (const auto& keyValue : sts)
187 {
188 if (ValidKey(keyValue.first))
189 {(*this)[keyValue.first] = keyValue.second;}
190 }
191}
192
193std::ostream& operator<<(std::ostream& out, BDSMagnetStrength const &st)
194{
195 for (const auto& key : BDSMagnetStrength::keys)
196 {out << key << ": " << st.GetValue(key) << ", ";}
197 return out;
198}
199
201 const G4int precision) const
202{
203 for (auto& key : keys)
204 {out << " " << std::setw(precision) << GetValue(key) / unitsFactorsMap.at(key).factor;}
205 return out;
206}
207
208G4String BDSMagnetStrength::UnitName(const G4String& key)
209{
210 if (ValidKey(key))
211 {return unitsFactorsMap.at(key).unit;}
212 else
213 {throw BDSException(__METHOD_NAME__, "Invalid key \"" + key + "\"");}
214}
215
216G4double BDSMagnetStrength::Unit(const G4String& key)
217{
218 if (ValidKey(key))
219 {return unitsFactorsMap.at(key).factor;}
220 else
221 {throw BDSException(__METHOD_NAME__, "Invalid key \"" + key + "\"");}
222}
223
224G4double& BDSMagnetStrength::operator[](const G4String& key)
225{
226 if (ValidKey(key))
227 {
228 // check if this key is initialised (non const version of this operator)
229 // if it's not, initialise it so assignment will work
230 auto it = strengths.find(key);
231 if (it != strengths.end())
232 {return it->second;}
233 else
234 {
235 strengths[key] = 0.0;
236 return strengths[key];
237 }
238 }
239 else
240 {throw BDSException(__METHOD_NAME__, "Invalid key \"" + key + "\"");}
241}
242
243const G4double& BDSMagnetStrength::operator[](const G4String& key) const
244{
245 if (ValidKey(key))
246 {return GetValue(key);}
247 else
248 {throw BDSException(__METHOD_NAME__, "Invalid key \"" + key + "\"");}
249}
250
251std::vector<G4double> BDSMagnetStrength::NormalComponents() const
252{
253 std::vector<G4double> result;
254 result.reserve(normalComponentKeys.size());
255 for (const auto& key : normalComponentKeys)
256 {result.push_back(GetValue(key));}
257 return result;
258}
259
260std::vector<G4double> BDSMagnetStrength::SkewComponents() const
261{
262 std::vector<G4double> result;
263 result.reserve(skewComponentKeys.size());
264 for (const auto& key : skewComponentKeys)
265 {result.push_back(GetValue(key));}
266 return result;
267}
268
269G4bool BDSMagnetStrength::ValidKey(const G4String& key)
270{
271 if (std::find(keys.begin(), keys.end(), key) != keys.end())
272 {return true;}
273 else
274 {return false;}
275}
276
277const G4double& BDSMagnetStrength::GetValue(const G4String& key) const
278{
279 auto it = strengths.find(key);
280 if (it != strengths.end())
281 {return it->second;}
282 else
283 {return zero;}
284}
285
286G4bool BDSMagnetStrength::KeyHasBeenSet(const G4String& key) const
287{
288 return strengths.find(key) != strengths.end();
289}
General exception with possible name of object and message.
Efficient storage of magnet strengths.
std::vector< G4double > NormalComponents() const
Accessor for all normal components - k1 - k12.
std::vector< G4double > SkewComponents() const
Accessor for all skew components - k1 - k12.
G4bool KeyHasBeenSet(const G4String &key) const
Whether a key has been set.
std::ostream & WriteValuesInSIUnitsForSuvey(std::ostream &out, const G4int precision=14) const
static G4double variable
Dummy variable that can be overwritten.
static G4bool ValidKey(const G4String &key)
Whether or not the supplied key is a valid magnet strength parameter.
const G4double & GetValue(const G4String &key) const
G4double & operator[](const G4String &key)
Accessors with array / map [] operator.
static const std::vector< G4String > keys
Vector of the allowed strength parameters.
BDSMagnetStrength()
Default constructor does nothing as class will return 0 for uninitialised keys.
static const G4double zero
Keep a single copy of 0.0 as it needs to be returned as a reference not a value.
static const std::vector< G4String > skewComponentKeys
Vector of the normal component strength parameters.
static const std::map< G4String, unitsFactors > unitsFactorsMap
Map of each unit name and numerical factor to each key.
static G4String UnitName(const G4String &key)
Access a unit name for a given key.
static G4double Unit(const G4String &key)
Access a unit factor for a given key.
static const std::vector< G4String > normalComponentKeys
Vector of the normal component strength parameters.