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 - 2023.
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 "frequency", // frequency for time varying field (presumably em)
63 "tOffset", // tOffset resulting in a phase for time varying field
64 "phase", // phase for time varying field
65 "synchronousT0", // global T0 for the synchronous particle at the centre of the object
66 "equatorradius", // radius from axis at which field goes to 0
67 "nominalenergy", // nominal beam energy needed by some integrators
68 "scaling", // field scaling factor needed by dipolequadrupole integrator
69 "scalingOuter", // arbitrary scaling for yoke fields - kept as a separate scaling number
70 "isentrance", // bool to determine is integrator is for entrance (1) or exit (0) face
71 "kick1",
72 "kick2",
73 "kick3",
74 "kick4",
75 "rmat11",
76 "rmat12",
77 "rmat13",
78 "rmat14",
79 "rmat21",
80 "rmat22",
81 "rmat23",
82 "rmat24",
83 "rmat31",
84 "rmat32",
85 "rmat33",
86 "rmat34",
87 "rmat41",
88 "rmat42",
89 "rmat43",
90 "rmat44"
91};
92
93const std::map<G4String, BDSMagnetStrength::unitsFactors> BDSMagnetStrength::unitsFactorsMap = {
94 {"beta0" , {"", 1.0}},
95 {"field" , {"T", CLHEP::tesla}},
96 {"efield" , {"", CLHEP::megavolt}},
97 {"bx" , {"", 1.0}},
98 {"by" , {"", 1.0}},
99 {"bz" , {"", 1.0}},
100 {"ex" , {"", 1.0}},
101 {"ey" , {"", 1.0}},
102 {"ez" , {"", 1.0}},
103 {"e1" , {"rad", CLHEP::rad}},
104 {"e2" , {"rad", CLHEP::rad}},
105 {"h1" , {"rad", CLHEP::rad}},
106 {"h2" , {"rad", CLHEP::rad}},
107 {"angle" , {"rad", CLHEP::rad}},
108 {"length" , {"m", CLHEP::m}},
109 {"fint" , {"", 1.0}},
110 {"fintx" , {"", 1.0}},
111 {"fintk2" , {"", 1.0}},
112 {"fintxk2" , {"", 1.0}},
113 {"hgap" , {"m", CLHEP::m}},
114 {"hkick" , {"", 1.0}},
115 {"vkick" , {"", 1.0}},
116 {"ks" , {"", 1.0}},
117 {"k1" , {"", 1.0}},
118 {"k2" , {"", 1.0}},
119 {"k3" , {"", 1.0}},
120 {"k4" , {"", 1.0}},
121 {"k5" , {"", 1.0}},
122 {"k6" , {"", 1.0}},
123 {"k7" , {"", 1.0}},
124 {"k8" , {"", 1.0}},
125 {"k9" , {"", 1.0}},
126 {"k10" , {"", 1.0}},
127 {"k11" , {"", 1.0}},
128 {"k12" , {"", 1.0}},
129 {"k1s" , {"", 1.0}},
130 {"k2s" , {"", 1.0}},
131 {"k3s" , {"", 1.0}},
132 {"k4s" , {"", 1.0}},
133 {"k5s" , {"", 1.0}},
134 {"k6s" , {"", 1.0}},
135 {"k7s" , {"", 1.0}},
136 {"k8s" , {"", 1.0}},
137 {"k9s" , {"", 1.0}},
138 {"k10s" , {"", 1.0}},
139 {"k11s" , {"", 1.0}},
140 {"k12s" , {"", 1.0}},
141 {"frequency" , {"", CLHEP::megahertz}},
142 {"tOffset" , {"s", CLHEP::s}},
143 {"phase" , {"rad", CLHEP::rad}},
144 {"synchronousT0" , {"s", CLHEP::s}},
145 {"equatorradius" , {"m", CLHEP::m}},
146 {"nominalenergy" , {"GeV", CLHEP::GeV}},
147 {"scaling" , {"", 1.0}},
148 {"scalingOuter" , {"", 1.0}},
149 {"isentrance" , {"", 1.0}},
150 {"kick1" , {"", 1.0}},
151 {"kick2" , {"", 1.0}},
152 {"kick3" , {"", 1.0}},
153 {"kick4" , {"", 1.0}},
154 {"rmat11" , {"", 1.0}},
155 {"rmat12" , {"", 1.0}},
156 {"rmat13" , {"", 1.0}},
157 {"rmat14" , {"", 1.0}},
158 {"rmat21" , {"", 1.0}},
159 {"rmat22" , {"", 1.0}},
160 {"rmat23" , {"", 1.0}},
161 {"rmat24" , {"", 1.0}},
162 {"rmat31" , {"", 1.0}},
163 {"rmat32" , {"", 1.0}},
164 {"rmat33" , {"", 1.0}},
165 {"rmat34" , {"", 1.0}},
166 {"rmat41" , {"", 1.0}},
167 {"rmat42" , {"", 1.0}},
168 {"rmat43" , {"", 1.0}},
169 {"rmat44" , {"", 1.0}}
170};
171
172const std::vector<G4String> BDSMagnetStrength::normalComponentKeys = {
173 "k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8", "k9", "k10", "k11", "k12"};
174
175const std::vector<G4String> BDSMagnetStrength::skewComponentKeys = {
176 "k1s", "k2s", "k3s", "k4s", "k5s", "k6s", "k7s", "k8s", "k9s", "k10s", "k11s", "k12s"};
177
178const G4double BDSMagnetStrength::zero = 0.0;
179G4double BDSMagnetStrength::variable = 0.0;
180
181BDSMagnetStrength::BDSMagnetStrength(const std::map<G4String, G4double>& sts)
182{
183 for (const auto& keyValue : sts)
184 {
185 if (ValidKey(keyValue.first))
186 {(*this)[keyValue.first] = keyValue.second;}
187 }
188}
189
190std::ostream& operator<<(std::ostream& out, BDSMagnetStrength const &st)
191{
192 for (const auto& key : BDSMagnetStrength::keys)
193 {out << key << ": " << st.GetValue(key) << ", ";}
194 return out;
195}
196
198 const G4int precision) const
199{
200 for (auto& key : keys)
201 {out << " " << std::setw(precision) << GetValue(key) / unitsFactorsMap.at(key).factor;}
202 return out;
203}
204
205G4String BDSMagnetStrength::UnitName(const G4String& key)
206{
207 if (ValidKey(key))
208 {return unitsFactorsMap.at(key).unit;}
209 else
210 {throw BDSException(__METHOD_NAME__, "Invalid key \"" + key + "\"");}
211}
212
213G4double BDSMagnetStrength::Unit(const G4String& key)
214{
215 if (ValidKey(key))
216 {return unitsFactorsMap.at(key).factor;}
217 else
218 {throw BDSException(__METHOD_NAME__, "Invalid key \"" + key + "\"");}
219}
220
221G4double& BDSMagnetStrength::operator[](const G4String& key)
222{
223 if (ValidKey(key))
224 {
225 // check if this key is initialised (non const version of this operator)
226 // if it's not, initialise it so assignment will work
227 auto it = strengths.find(key);
228 if (it != strengths.end())
229 {return it->second;}
230 else
231 {
232 strengths[key] = 0.0;
233 return strengths[key];
234 }
235 }
236 else
237 {throw BDSException(__METHOD_NAME__, "Invalid key \"" + key + "\"");}
238}
239
240const G4double& BDSMagnetStrength::operator[](const G4String& key) const
241{
242 if (ValidKey(key))
243 {return GetValue(key);}
244 else
245 {throw BDSException(__METHOD_NAME__, "Invalid key \"" + key + "\"");}
246}
247
248std::vector<G4double> BDSMagnetStrength::NormalComponents() const
249{
250 std::vector<G4double> result;
251 result.reserve(normalComponentKeys.size());
252 for (const auto& key : normalComponentKeys)
253 {result.push_back(GetValue(key));}
254 return result;
255}
256
257std::vector<G4double> BDSMagnetStrength::SkewComponents() const
258{
259 std::vector<G4double> result;
260 result.reserve(skewComponentKeys.size());
261 for (const auto& key : skewComponentKeys)
262 {result.push_back(GetValue(key));}
263 return result;
264}
265
266G4bool BDSMagnetStrength::ValidKey(const G4String& key)
267{
268 if (std::find(keys.begin(), keys.end(), key) != keys.end())
269 {return true;}
270 else
271 {return false;}
272}
273
274const G4double& BDSMagnetStrength::GetValue(const G4String& key) const
275{
276 auto it = strengths.find(key);
277 if (it != strengths.end())
278 {return it->second;}
279 else
280 {return zero;}
281}
282
283G4bool BDSMagnetStrength::KeyHasBeenSet(const G4String& key) const
284{
285 return strengths.find(key) != strengths.end();
286}
General exception with possible name of object and message.
Definition: BDSException.hh:35
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.