BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSMuonCoolerBuilder.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 "BDSComponentFactory.hh"
20#include "BDSDebug.hh"
21#include "BDSException.hh"
22#include "BDSFieldInfo.hh"
23#include "BDSFieldInfoExtra.hh"
24#include "BDSFieldType.hh"
25#include "BDSIntegratorType.hh"
26#include "BDSMaterials.hh"
27#include "BDSMuonCooler.hh"
28#include "BDSMuonCoolerBuilder.hh"
29#include "BDSMuonCoolerStructs.hh"
30#include "BDSParser.hh"
31
32#include "parser/coolingchannel.h"
33#include "parser/element.h"
34
35#include "G4String.hh"
36#include "G4ThreeVector.hh"
37#include "G4Types.hh"
38
39#include "CLHEP/Units/SystemOfUnits.h"
40
41#include <algorithm>
42#include <cmath>
43#include <iterator>
44#include <list>
45#include <set>
46#include <string>
47#include <vector>
48
49
50BDSMuonCooler* BDS::BuildMuonCooler(const G4String& elementName,
51 G4double chordLength,
52 G4double horizontalWidth,
53 const GMAD::CoolingChannel& definition,
54 BDSBeamPipeInfo* beamPipeInfo,
55 G4double designRigidity)
56{
57 G4double elementRadius = horizontalWidth * 0.5;
58
59 G4String definitionName = definition.name;
60
61 // build recipes for coils
62 std::vector<BDS::MuonCoolerCoilInfo> coilInfos = BDS::BuildMuonCoolerCoilInfos(definition);
63 // check potential overlaps
64 // boundary squares in 2D - keep them to reuse for various checks
65 std::vector<BDS::SquareCheck> coilSquares = BDS::MuonCoolerSquaresFromCoils(coilInfos);
67 elementName,
68 coilSquares,
69 chordLength,
70 elementRadius);
71
72 // build recipes for dipoles
73 std::vector<BDS::MuonCoolerDipoleInfo> dipoleInfos = BDS::BuildMuonCoolerDipoleInfos(definition);
74 // no overlap checks for dipoles as we don't physically build them yet
75
76 // build recipes for rf cavities
77 std::vector<BDS::MuonCoolerCavityInfo> cavityInfos = BDS::BuildMuonCoolerCavityInfos(definition);
78 // check potential overlaps
79 // boundary squares in 2D - keep them to reuse for various checks
80 std::vector<BDS::SquareCheck> cavitySquares = BDS::MuonCoolerSquaresFromCavities(cavityInfos);
81 BDS::CheckMuonCoolerCavityInfosForOverlaps(definitionName,
82 elementName,
83 cavitySquares,
84 coilSquares,
85 chordLength,
86 elementRadius);
87
88 // build recipes for absorbers
89 std::vector<BDS::MuonCoolerAbsorberInfo> absorberInfos = BDS::BuildMuonCoolerAbsorberInfo(definition);
90 // check potential overlaps
91 BDS::CheckMuonCoolerAbsorberInfoForOverlaps(definitionName,
92 elementName,
93 absorberInfos,
94 cavitySquares,
95 coilSquares,
96 chordLength,
97 elementRadius);
98
99 // build combined field recipe
100 BDSFieldInfo* outerFieldRecipe = BDS::BuildMuonCoolerFieldRecipe(definitionName,
101 designRigidity,
102 definition.integrator,
103 definition.magneticFieldModel,
104 definition.electricFieldModel,
105 definition.dipoleFieldModel,
106 coilInfos,
107 dipoleInfos,
108 cavityInfos);
109
110
111
112 // build final object for beam line
113 G4Material* surroundingMaterial = BDSMaterials::Instance()->GetMaterial(definition.surroundingMaterial);
114 auto result = new BDSMuonCooler(elementName,
115 chordLength,
116 elementRadius,
117 surroundingMaterial,
118 coilInfos,
119 dipoleInfos,
120 cavityInfos,
121 absorberInfos,
122 beamPipeInfo,
123 outerFieldRecipe);
124 return result;
125}
126
127std::vector<BDS::MuonCoolerCoilInfo> BDS::BuildMuonCoolerCoilInfos(const GMAD::CoolingChannel& definition)
128{
129 std::vector<BDS::MuonCoolerCoilInfo> result;
130
131 // Check we have matching coil parameter sizes or tolerate 1 variable for all
132 G4int nCoils = definition.nCoils;
133 std::vector<std::string> coilParamNames = {"coilInnerRadius",
134 "coilRadialThickness",
135 "coilLengthZ",
136 "coilCurrent",
137 "coilOffsetZ"};
138 std::vector<const std::list<double>*> coilVars = {&(definition.coilInnerRadius),
139 &(definition.coilRadialThickness),
140 &(definition.coilLengthZ),
141 &(definition.coilCurrent),
142 &(definition.coilOffsetZ)};
143 std::vector<std::vector<double> > coilVarsV;
144 BDS::MuonParamsToVector(definition.name,
145 coilVars,
146 coilParamNames,
147 nCoils,
148 coilVarsV);
149
150 std::vector<G4Material*> coilMaterials;
152 "coilMaterial",
153 definition.coilMaterial,
154 nCoils,
155 coilMaterials);
156
157 // build coil infos
158 for (G4int i = 0; i < nCoils; i++)
159 {
160 BDS::MuonCoolerCoilInfo info = {coilVarsV[0][i] * CLHEP::m, // innerRadius
161 coilVarsV[1][i] * CLHEP::m, // radialThickness
162 coilVarsV[2][i] * CLHEP::m, // lengthZ
163 coilVarsV[3][i] * CLHEP::ampere, // current
164 coilVarsV[4][i] * CLHEP::m, // offsetZ
165 coilMaterials[i], // no material for now
166 definition.onAxisTolerance * CLHEP::tesla, // onAxisTolerance
167 definition.nSheets
168
169 };
170 result.push_back(info);
171 }
172
173 if (definition.mirrorCoils)
174 {
175 result.reserve(2*result.size());
176 std::copy(result.rbegin(), result.rend(), std::back_inserter(result));
177 for (G4int j = (G4int)result.size() - 1; j > nCoils - 1; j--)
178 {result[j].offsetZ *= -1;}
179 }
180
181 return result;
182}
183
184void BDS::CheckMuonCoolerCoilInfosForOverlaps(const G4String& definitionName,
185 const G4String& elementName,
186 const std::vector<BDS::SquareCheck>& coilSquares,
187 G4double elementChordLength,
188 G4double elementRadius)
189{
190 // To check the overlaps, we will do it only in 2D in a cross-section considering the square
191 // polygons of the coil blocks. We will do a very simple point in square check - doesn't work
192 // if squares are rotated for example.
193
194 // check each against each other
195 for (G4int i = 0; i < (G4int)coilSquares.size(); i++)
196 {
197 for (G4int j = i+1; j < (G4int)coilSquares.size(); j++)
198 {
199 if (i == j)
200 {continue;}
201 if (coilSquares[i].Overlaps(coilSquares[j]))
202 {
203 G4String msg = "error in definition \"" + definitionName + "\": coil #" + std::to_string(i);
204 msg += " overlaps with coil #" + std::to_string(j) + "\n" + coilSquares[i].Str() + "\n" + coilSquares[j].Str();
205 throw BDSException(__METHOD_NAME__,msg);
206 }
207 }
208 }
209
210 // check all lie inside the container length and radius
211 G4double halfLength = 0.5*elementChordLength;
212 for (G4int i = 0; i < (G4int)coilSquares.size(); i++)
213 {
214 if (std::abs(coilSquares[i].z1) > halfLength || std::abs(coilSquares[i].z2) > halfLength)
215 {
216 G4String msg = "error in definition \"" + definitionName + "\": coil #" + std::to_string(i);
217 msg += " lies outside +- the half length (" + std::to_string(halfLength) + " mm) of the element \"" + elementName + "\"\n";
218 msg += coilSquares[i].Str();
219 throw BDSException(__METHOD_NAME__,msg);
220 }
221 if (coilSquares[i].r2 >= elementRadius)
222 {
223 G4String msg = "error in definition \"" + definitionName + "\": coil #" + std::to_string(i);
224 msg += " outer radius (" + std::to_string(coilSquares[i].r2) + " mm) is greater than 1/2 the horizontalWidth of the element \"" + elementName + "\"\n";
225 msg += elementName + ": horizontalWidth = " + std::to_string(elementRadius) + " mm\n";
226 msg += "Coil cross-section: " + coilSquares[i].Str();
227 throw BDSException(__METHOD_NAME__,msg);
228 }
229 }
230}
231
232std::vector<BDS::MuonCoolerDipoleInfo> BDS::BuildMuonCoolerDipoleInfos(const GMAD::CoolingChannel& definition)
233{
234 std::vector<BDS::MuonCoolerDipoleInfo> result;
235
236 // Check we have matching dipole parameter sizes or tolerate 1 variable for all
237 G4int nDipoles = definition.nDipoles;
238 std::vector<std::string> dipoleParamNames = {"dipoleAperture",
239 "dipoleLengthZ",
240 "dipoleFieldStrength",
241 "dipoleEngeCoefficient",
242 "dipoleOffsetZ"};
243 std::vector<const std::list<double>*> dipoleVars = {&(definition.dipoleAperture),
244 &(definition.dipoleLengthZ),
245 &(definition.dipoleFieldStrength),
246 &(definition.dipoleEngeCoefficient),
247 &(definition.dipoleOffsetZ)};
248 std::vector<std::vector<double> > dipoleVarsV;
249 BDS::MuonParamsToVector(definition.name,
250 dipoleVars,
251 dipoleParamNames,
252 nDipoles,
253 dipoleVarsV);
254
255 // build dipole infos
256
257 for (G4int i = 0; i < nDipoles; i++)
258 {
259 BDS::MuonCoolerDipoleInfo info = {dipoleVarsV[0][i] * CLHEP::m, // apertureRadius
260 dipoleVarsV[1][i] * CLHEP::m, // lengthZ
261 dipoleVarsV[2][i] * CLHEP::tesla, // fieldStrength
262 dipoleVarsV[3][i], // enge Coeff
263 dipoleVarsV[4][i] * CLHEP::m // offsetZ
264 };
265 result.push_back(info);
266 }
267
268 return result;
269}
270
271// no checks for overlaps for dipoles as we don't physically build them yet
272
273std::vector<BDS::MuonCoolerAbsorberInfo> BDS::BuildMuonCoolerAbsorberInfo(const GMAD::CoolingChannel& definition)
274{
275 std::vector<BDS::MuonCoolerAbsorberInfo> result;
276
277 G4int nAbsorbers = definition.nAbsorbers;
278 std::vector<std::string> absParamNames = {"absorberOffsetZ",
279 "absorberCylinderLength",
280 "absorberCylinderRadius",
281 "absorberWedgeOpeningAngle",
282 "absorberWedgeHeight",
283 "absorberWedgeRotationAngle",
284 "absorberWedgeOffsetX",
285 "absorberWedgeOffsetY",
286 "absorberWedgeApexToBase"};
287 std::vector<const std::list<double>*> absVars = {&(definition.absorberOffsetZ),
288 &(definition.absorberCylinderLength),
289 &(definition.absorberCylinderRadius),
290 &(definition.absorberWedgeOpeningAngle),
291 &(definition.absorberWedgeHeight),
292 &(definition.absorberWedgeRotationAngle),
293 &(definition.absorberWedgeOffsetX),
294 &(definition.absorberWedgeOffsetY),
295 &(definition.absorberWedgeApexToBase)};
296 std::vector<std::vector<double> > absVarsV;
297 BDS::MuonParamsToVector(definition.name,
298 absVars,
299 absParamNames,
300 nAbsorbers,
301 absVarsV);
302 absVarsV.reserve(absVars.size());
303
304 // check the absorber type list
305 const auto typeListSize = definition.absorberType.size();
306 if (definition.absorberType.empty() || (typeListSize != 1 && (G4int)typeListSize != nAbsorbers))
307 {
308 G4String msg = "error in coolingchannel definition \"" + definition.name + "\"\n";
309 msg += "number of \"absorberType\" doesn't match nAbsorbers (" + std::to_string(nAbsorbers) + ") or isn't 1";
310 throw BDSException(__METHOD_NAME__, msg);
311 }
312
313 // check contents of absorber type list
314 const std::set<std::string> absorberTypes = {"wedge", "cylinder"};
315 std::vector<std::string> absorberTypeV = {definition.absorberType.begin(), definition.absorberType.end()};
316 if (absorberTypeV.size() == 1)
317 {
318 for (G4int i = 1; i < nAbsorbers; i++)
319 {absorberTypeV.push_back(absorberTypeV[0]);}
320 }
321 for (G4int i = 0; i < (G4int)absorberTypeV.size(); i++)
322 {
323 auto search = absorberTypes.find(absorberTypeV[i]);
324 if (search == absorberTypes.end())
325 {
326 G4String msg = "unknown type of absorber: \"" + absorberTypeV[i] + "\" at index " + std::to_string(i);
327 msg += "\nin definition \"" + definition.name + "\"";
328 throw BDSException(__METHOD_NAME__, msg);
329 }
330 }
331
332 std::vector<G4Material*> absorberMaterials;
334 "absorberMaterial",
335 definition.absorberMaterial,
336 nAbsorbers,
337 absorberMaterials);
338
339 // build absorber infos
340 for (G4int i = 0; i < nAbsorbers; i++)
341 {
342 G4double dx = absVarsV[6][i] * CLHEP::m; // wedgeOffsetX
343 G4double dy = absVarsV[7][i] * CLHEP::m; // wedgeOffsetY
344 G4double dz = absVarsV[0][i] * CLHEP::m;
345 BDS::MuonCoolerAbsorberInfo info = {absorberTypeV[i], // absorberType
346 absVarsV[1][i] * CLHEP::m, // cylinderLength
347 absVarsV[2][i] * CLHEP::m, // cylinderRadius
348 absVarsV[3][i] * CLHEP::rad, // wedgeOpeningAngle
349 absVarsV[4][i] * CLHEP::m, // wedgeHeight
350 absVarsV[5][i] * CLHEP::rad, // wedgeRotationAngle
351 G4ThreeVector(dx,dy,dz), // wedgeOffset
352 absVarsV[8][i] * CLHEP::m, // wedgeApexToBase
353 absorberMaterials[i]
354 };
355 result.push_back(info);
356 }
357
358 return result;
359}
360
361void BDS::CheckMuonCoolerAbsorberInfoForOverlaps(const G4String& /*definitionName*/,
362 const G4String& /*elementName*/,
363 const std::vector<BDS::MuonCoolerAbsorberInfo>& /*absorberInfos*/,
364 const std::vector<BDS::SquareCheck>& /*coilInfos*/,
365 const std::vector<BDS::SquareCheck>& /*cavityInfos*/,
366 G4double /*elementChordLength*/,
367 G4double /*elementRadius*/)
368{;}
369
370std::vector<BDS::MuonCoolerCavityInfo> BDS::BuildMuonCoolerCavityInfos(const GMAD::CoolingChannel& definition)
371{
372 std::vector<BDS::MuonCoolerCavityInfo> result;
373
374 G4int nRFCavities = definition.nRFCavities;
375 std::vector<std::string> rfParamNames = {"rfOffsetZ",
376 "rfLength",
377 "rfVoltage",
378 "rfPhase",
379 "rfFrequency",
380 "rfWindowThickness",
381 "rfWindowRadius",
382 "rfCavityRadius",
383 "rfCavityThickness",
384 "rfTimeOffset"};
385 std::vector<const std::list<double>*> rfVars = {&(definition.rfOffsetZ),
386 &(definition.rfLength),
387 &(definition.rfVoltage),
388 &(definition.rfPhase),
389 &(definition.rfFrequency),
390 &(definition.rfWindowThickness),
391 &(definition.rfWindowRadius),
392 &(definition.rfCavityRadius),
393 &(definition.rfCavityThickness),
394 &(definition.rfTimeOffset)};
395 std::vector<std::vector<double> > rfVarsV;
396 BDS::MuonParamsToVector(definition.name,
397 rfVars,
398 rfParamNames,
399 nRFCavities,
400 rfVarsV);
401 std::vector<G4Material*> windowMaterials;
403 "rfWindowMaterial",
404 definition.rfWindowMaterial,
405 nRFCavities,
406 windowMaterials);
407 std::vector<G4Material*> cavityMaterials;
409 "rfCavityMaterial",
410 definition.rfCavityMaterial,
411 nRFCavities,
412 cavityMaterials);
413 std::vector<G4Material*> cavityVacuumMaterials;
415 "rfCavityVaccumMaterial",
416 definition.rfCavityVacuumMaterial,
417 nRFCavities,
418 cavityVacuumMaterials);
419
420 // build cavity infos
421 for (G4int i = 0; i < nRFCavities; i++)
422 { // BUG: CHECK system of units
423 BDS::MuonCoolerCavityInfo info = {rfVarsV[0][i] * CLHEP::m, // offsetZ
424 rfVarsV[1][i] * CLHEP::m, // lengthZ
425 rfVarsV[2][i] * CLHEP::megavolt / CLHEP::meter, // peakEfield
426 rfVarsV[3][i] * CLHEP::rad, // phaseOffset
427 rfVarsV[4][i] * CLHEP::hertz, // frequency
428 cavityVacuumMaterials[i], // cavity vacuum material
429 rfVarsV[5][i] * CLHEP::m, // windowThickness
430 windowMaterials[i], // window material
431 rfVarsV[6][i] * CLHEP::m, // windowRadius
432 cavityMaterials[i], // cavity material
433 rfVarsV[7][i] * CLHEP::m, // cavityRadius
434 rfVarsV[8][i] * CLHEP::m, // cavityThickness
435 rfVarsV[9][i] * CLHEP::ns // globalTimeOffset
436 };
437 result.push_back(info);
438 }
439
440 return result;
441}
442
443void BDS::CheckMuonCoolerCavityInfosForOverlaps(const G4String& /*definitionName*/,
444 const G4String& /*elementName*/,
445 const std::vector<BDS::SquareCheck>& /*cavitySquares*/,
446 const std::vector<BDS::SquareCheck>& /*coilSquares*/,
447 G4double /*elementChordLength*/,
448 G4double /*elementRadius*/)
449{;}
450
451std::vector<BDS::SquareCheck> BDS::MuonCoolerSquaresFromCoils(const std::vector<BDS::MuonCoolerCoilInfo>& coilInfos)
452{
453 std::vector<BDS::SquareCheck> squares;
454 squares.reserve(coilInfos.size());
455 for (auto& info : coilInfos)
456 {
457 squares.emplace_back(BDS::SquareCheck{info.offsetZ-0.5*info.fullLengthZ,
458 info.offsetZ+0.5*info.fullLengthZ,
459 info.innerRadius,
460 info.innerRadius+info.radialThickness});
461 }
462 return squares;
463}
464
465std::vector<BDS::SquareCheck> BDS::MuonCoolerSquaresFromCavities(const std::vector<BDS::MuonCoolerCavityInfo>& cavityInfos)
466{
467 std::vector<BDS::SquareCheck> squares;
468 squares.reserve(cavityInfos.size());
469 /*
470 for (auto& info : cavityInfos)
471 {
472 squares.emplace_back(BDS::SquareCheck{info.offsetZ-0.5*info.lengthZ,
473 info.offsetZ+0.5*info.lengthZ,
474 info.innerRadius,
475 info.innerRadius+info.radialThickness});
476 }
477 */
478 return squares;
479}
480
481void BDS::MuonParamsToVector(const G4String& definitionName,
482 const std::vector<const std::list<double>*>& params,
483 const std::vector<std::string>& paramNames,
484 G4int nExpectedParams,
485 std::vector<std::vector<double>>& paramsV)
486{
487 // convert to vectors from lists
488 paramsV.reserve(params.size());
489 for (auto l: params)
490 {paramsV.emplace_back(std::vector<double>{std::cbegin(*l), std::cend(*l)});}
491
492 // check lengths are either 1 or nCoils
493 for (G4int i = 0; i < (G4int) paramsV.size(); i++)
494 {
495 auto& v = paramsV[i];
496 if (((G4int) v.size() != nExpectedParams && v.size() != 1) || v.empty())
497 {
498 G4String msg = "error in coolingchannel definition \"" + definitionName + "\"\n";
499 msg += "number of " + paramNames[i] + " doesn't match expected number (" + std::to_string(nExpectedParams) + ") or isn't 1";
500 throw BDSException(__METHOD_NAME__, msg);
501 }
502 // if the vector is single-valued, then we copy the first value up to nExpected
503 // values so all are the same size
504 if (v.size() == 1)
505 {
506 for (G4int j = 1; j < nExpectedParams; j++)
507 {v.push_back(v[0]);}
508 }
509 }
510}
511
512void BDS::MuonParamsToMaterials(const G4String& definitionName,
513 const G4String& variableName,
514 const std::list<std::string>& materialNames,
515 G4int nExpectedParams,
516 std::vector<G4Material*>& materials)
517{
518 // check size
519 if (materialNames.empty() || (materialNames.size() != 1 && (G4int)materialNames.size() != nExpectedParams))
520 {
521 G4String msg = "error in coolingchannel definition \"" + definitionName + "\"\n";
522 msg += "number of \"" + variableName + "\" doesn't match expected number (" + std::to_string(nExpectedParams) + ") or isn't 1";
523 throw BDSException(__METHOD_NAME__, msg);
524 }
525
526 materials.reserve(nExpectedParams);
527
528 if (materialNames.size() == 1)
529 {
530 G4String materialName = G4String(materialNames.front());
531 G4Material* material = BDSMaterials::Instance()->GetMaterial(materialName);
532 for (G4int i = 0; i < nExpectedParams; i++)
533 {materials.push_back(material);}
534 }
535 else
536 {
537 std::vector<std::string> materialNamesV = {std::begin(materialNames), std::end(materialNames)};
538 for (G4int i = 0; i < (G4int)materialNamesV.size(); i++)
539 {
540 G4Material* material = BDSMaterials::Instance()->GetMaterial(materialNamesV[i]);
541 materials[i] = material;
542 }
543 }
544}
545
546BDSFieldInfo* BDS::BuildMuonCoolerFieldRecipe(const G4String& definitionName,
547 G4double designRigidity,
548 const G4String& integrator,
549 const G4String& magneticFieldModel,
550 const G4String& electricFieldModel,
551 const G4String& dipoleFieldModel,
552 const std::vector<BDS::MuonCoolerCoilInfo>& coilInfos,
553 const std::vector<BDS::MuonCoolerDipoleInfo>& dipoleInfos,
554 const std::vector<BDS::MuonCoolerCavityInfo>& cavityInfos)
555{
556 try
557 {
559 BDSFieldType mt = BDS::DetermineFieldType(magneticFieldModel);
560 BDSFieldType et = BDS::DetermineFieldType(electricFieldModel);
561 BDSFieldType dt = BDS::DetermineFieldType(dipoleFieldModel);
562 auto ei = new BDSFieldInfoExtraMuonCooler(mt, et, dt, coilInfos, dipoleInfos, cavityInfos);
563
564 auto result = new BDSFieldInfo(BDSFieldType::muoncooler, designRigidity, it);
565 result->SetNameOfParserDefinition(definitionName);
566 result->SetExtraInfo(ei);
567 return result;
568 }
569 catch (BDSException& e)
570 {
571 e.AppendToMessage("\nProblem with field in coolingchannel definition \"" + definitionName + "\"");
572 throw e;
573 }
574}
Holder class for all information required to describe a beam pipe model.
General exception with possible name of object and message.
necessary extra information for a muon cooler field.
All info required to build complete field of any type.
static BDSMaterials * Instance()
Singleton pattern access.
G4Material * GetMaterial(G4String material) const
Get material by name.
A muon cooling module.
Cooling channel parameters.
std::string name
Object name.
void MuonParamsToMaterials(const G4String &definitionName, const G4String &variableName, const std::list< std::string > &materialNames, G4int nExpectedParams, std::vector< G4Material * > &materials)
BDSFieldType DetermineFieldType(G4String fieldType)
Function that gives corresponding enum value for string (case-insensitive)
BDSMuonCooler * BuildMuonCooler(const G4String &elementName, G4double chordLength, G4double horizontalWidth, const GMAD::CoolingChannel &definition, BDSBeamPipeInfo *beamPipeInfo, G4double designRigidity)
void CheckMuonCoolerCoilInfosForOverlaps(const G4String &definitionName, const G4String &elementName, const std::vector< BDS::SquareCheck > &coilSquares, G4double elementChordLength, G4double elementRadius)
BDSIntegratorType DetermineIntegratorType(G4String integratorType)
Function that determines enum from string (case-insensitive).
std::vector< BDS::MuonCoolerCoilInfo > BuildMuonCoolerCoilInfos(const GMAD::CoolingChannel &definition)
void MuonParamsToVector(const G4String &definitionName, const std::vector< const std::list< double > * > &params, const std::vector< std::string > &paramNames, G4int nExpectedParams, std::vector< std::vector< double > > &paramsV)
std::vector< BDS::SquareCheck > MuonCoolerSquaresFromCoils(const std::vector< BDS::MuonCoolerCoilInfo > &coilInfos)
Utility function to make SquareCheck instances from coil info.
std::vector< BDS::MuonCoolerAbsorberInfo > BuildMuonCoolerAbsorberInfo(const GMAD::CoolingChannel &definition)
No checks for overlaps for dipoles as we don't physically build them yet.
std::vector< BDS::SquareCheck > MuonCoolerSquaresFromCavities(const std::vector< BDS::MuonCoolerCavityInfo > &cavityInfos)
Utility function to make SquareCheck instances from cavity info.
A very simple struct to permit checking un-rotated (i.e. axis-aligned) square overlaps.