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