19#include "BDSComponentFactory.hh"
23#include "BDSAwakeScintillatorScreen.hh"
24#include "BDSAwakeSpectrometer.hh"
26#include "BDSCavityElement.hh"
27#include "BDSCollimatorCrystal.hh"
28#include "BDSCollimatorElliptical.hh"
29#include "BDSCollimatorJaw.hh"
30#include "BDSCollimatorRectangular.hh"
31#include "BDSColours.hh"
32#include "BDSComponentFactoryUser.hh"
35#include "BDSDicomIntersectVolume.hh"
37#include "BDSDegrader.hh"
40#include "BDSElement.hh"
41#include "BDSLaserWire.hh"
43#include "BDSMagnet.hh"
44#include "BDSSamplerPlane.hh"
45#include "BDSScreen.hh"
46#include "BDSShield.hh"
47#include "BDSTarget.hh"
48#include "BDSTeleporter.hh"
49#include "BDSTerminator.hh"
50#include "BDSTiltOffset.hh"
51#include "BDSTransform3D.hh"
52#include "BDSWireScanner.hh"
53#include "BDSUndulator.hh"
54#include "BDSWarning.hh"
57#include "BDSAcceleratorComponentRegistry.hh"
58#include "BDSBeamPipeFactory.hh"
59#include "BDSBeamPipeInfo.hh"
60#include "BDSBeamPipeType.hh"
61#include "BDSBendBuilder.hh"
63#include "BDSCavityInfo.hh"
64#include "BDSCavityType.hh"
65#include "BDSCrystalInfo.hh"
66#include "BDSCrystalType.hh"
68#include "BDSException.hh"
69#include "BDSExecOptions.hh"
70#include "BDSFieldInfo.hh"
71#include "BDSFieldFactory.hh"
72#include "BDSFieldType.hh"
73#include "BDSGlobalConstants.hh"
75#include "BDSIntegratorSet.hh"
76#include "BDSIntegratorSetType.hh"
77#include "BDSIntegratorType.hh"
78#include "BDSIntegratorDipoleFringe.hh"
79#include "BDSMagnetOuterFactory.hh"
80#include "BDSMagnetOuterInfo.hh"
81#include "BDSMagnetGeometryType.hh"
82#include "BDSMagnetStrength.hh"
83#include "BDSMagnetType.hh"
84#include "BDSMaterials.hh"
85#include "BDSParser.hh"
86#include "BDSParticleDefinition.hh"
87#include "BDSUtilities.hh"
91#include "G4Transform3D.hh"
93#include "CLHEP/Units/SystemOfUnits.h"
94#include "CLHEP/Units/PhysicalConstants.h"
96#include "parser/element.h"
97#include "parser/elementtype.h"
98#include "parser/cavitymodel.h"
99#include "parser/newcolour.h"
100#include "parser/crystal.h"
113 G4bool usualPrintOut):
114 designParticle(designParticleIn),
115 userComponentFactory(userComponentFactoryIn),
120 defaultModulator(nullptr),
125 {
throw BDSException(__METHOD_NAME__,
"no valid design particle - required.");}
126 brho = designParticle->BRho();
127 beta0 = designParticle->Beta();
131 {G4cout << __METHOD_NAME__ <<
"using \"" << integratorSetType <<
"\" set of integrators" << G4endl;}
134 PrepareCavityModels();
141BDSComponentFactory::~BDSComponentFactory()
144 {
delete info.second;}
146 {
delete info.second;}
162 G4double currentArcLengthIn)
168 G4double angleIn = 0.0;
169 G4double angleOut = 0.0;
170 G4bool registered =
false;
173 G4bool differentFromDefinition =
false;
176 G4cout << __METHOD_NAME__ <<
"named: \"" <<
element->name <<
"\"" << G4endl;
191 {differentFromDefinition =
true;}
199 {differentFromDefinition =
true;}
205 {differentFromDefinition =
true;}
213 {differentFromDefinition =
true;}
218 {differentFromDefinition =
true;}
228 if (prevType == ElementType::_DRIFT && nextType != ElementType::_DRIFT)
230 else if (prevType != ElementType::_DRIFT && nextType == ElementType::_DRIFT)
240 {differentFromDefinition =
true;}
247 {differentFromDefinition =
true;}
252 {differentFromDefinition =
true;}
258 if (registered && !differentFromDefinition)
261 G4cout << __METHOD_NAME__ <<
"using already manufactured component" << G4endl;
269 if (differentFromDefinition)
290 case ElementType::_DRIFT:
291 {component = CreateDrift(angleIn, angleOut);
break;}
292 case ElementType::_RF:
294 component = CreateRF(RFFieldDirection::z);
295 differentFromDefinition =
true;
298 case ElementType::_RFX:
300 component = CreateRF(RFFieldDirection::x);
301 differentFromDefinition =
true;
304 case ElementType::_RFY:
306 component = CreateRF(RFFieldDirection::y);
307 differentFromDefinition =
true;
310 case ElementType::_SBEND:
311 {component = CreateSBend();
break;}
312 case ElementType::_RBEND:
313 {component = CreateRBend();
break;}
314 case ElementType::_HKICKER:
315 {component = CreateKicker(KickerType::horizontal);
break;}
316 case ElementType::_VKICKER:
317 {component = CreateKicker(KickerType::vertical);
break;}
318 case ElementType::_KICKER:
319 case ElementType::_TKICKER:
320 {component = CreateKicker(KickerType::general);
break;}
321 case ElementType::_QUAD:
322 {component = CreateQuad();
break;}
323 case ElementType::_SEXTUPOLE:
324 {component = CreateSextupole();
break;}
325 case ElementType::_OCTUPOLE:
326 {component = CreateOctupole();
break;}
327 case ElementType::_DECAPOLE:
328 {component = CreateDecapole();
break;}
329 case ElementType::_MULT:
333 component = CreateThinMultipole(angleIn);
336 component = CreateMultipole();
339 case ElementType::_THINMULT:
340 {component = CreateThinMultipole(angleIn);
break;}
341 case ElementType::_ELEMENT:
342 {component = CreateElement();
break;}
343 case ElementType::_SOLENOID:
344 {component = CreateSolenoid();
break;}
345 case ElementType::_ECOL:
346 {component = CreateEllipticalCollimator();
break;}
347 case ElementType::_RCOL:
348 {component = CreateRectangularCollimator();
break;}
349 case ElementType::_TARGET:
350 {component = CreateTarget();
break;}
351 case ElementType::_JCOL:
352 {component = CreateJawCollimator();
break;}
353 case ElementType::_MUONSPOILER:
354 {component = CreateMuonSpoiler();
break;}
355 case ElementType::_SHIELD:
356 {component = CreateShield();
break;}
357 case ElementType::_DEGRADER:
358 {component = CreateDegrader();
break;}
359 case ElementType::_WIRESCANNER:
360 {component = CreateWireScanner();
break;}
361 case ElementType::_GAP:
362 {component = CreateGap();
break;}
363 case ElementType::_CRYSTALCOL:
364 {component = CreateCrystalCollimator();
break;}
365 case ElementType::_LASER:
366 {component = CreateLaser();
break;}
367 case ElementType::_SCREEN:
368 {component = CreateScreen();
break;}
369 case ElementType::_TRANSFORM3D:
370 {component = CreateTransform3D();
break;}
371 case ElementType::_THINRMATRIX:
372 {component = CreateThinRMatrix(angleIn,
elementName);
break;}
373 case ElementType::_PARALLELTRANSPORTER:
374 {component = CreateParallelTransporter();
break;}
375 case ElementType::_RMATRIX:
376 {component = CreateRMatrix();
break;}
377 case ElementType::_UNDULATOR:
378 {component = CreateUndulator();
break;}
379 case ElementType::_USERCOMPONENT:
382 {
throw BDSException(__METHOD_NAME__,
"no user component factory registered");}
396 case ElementType::_DUMP:
397 {component = CreateDump();
break;}
398 case ElementType::_CT:
400 {component = CreateCT();
break;}
402 {
throw BDSException(__METHOD_NAME__,
"ct element can't be used - not compiled with dicom module!");}
404 case ElementType::_AWAKESCREEN:
406 {component = CreateAwakeScreen();
break;}
408 throw BDSException(__METHOD_NAME__,
"Awake Screen can't be used - not compiled with AWAKE module!");
410 case ElementType::_AWAKESPECTROMETER:
412 {component = CreateAwakeSpectrometer();
break;}
414 {
throw BDSException(__METHOD_NAME__,
"Awake Spectrometer can't be used - not compiled with AWAKE module!");}
417 case ElementType::_MARKER:
418 case ElementType::_LINE:
419 case ElementType::_REV_LINE:
420 {component =
nullptr;
break;}
423 G4cerr << __METHOD_NAME__ <<
"unknown type " <<
element->
type << G4endl;
431 e.AppendToMessage(
"\nError in creating component \"" +
elementName +
"\"");
449 case ElementType::_ECOL:
450 case ElementType::_RCOL:
451 case ElementType::_JCOL:
471 const G4double teleporterHorizontalWidth,
472 const G4Transform3D& transformIn)
475 (*st)[
"length"] = teleporterLength;
478 BDSIntegratorType::teleporter,
483 G4cout <<
"---->creating Teleporter, " <<
"l = " << teleporterLength/CLHEP::m <<
"m" << G4endl;
485 return(
new BDSTeleporter(teleporterLength, teleporterHorizontalWidth, vacuumFieldInfo));
498 G4double prevTilt = 0;
499 G4double nextTilt = 0;
504 G4ThreeVector inputFaceNormal = faces.first.rotateZ(prevTilt - currentTilt);
505 G4ThreeVector outputFaceNormal = faces.second.rotateZ(nextTilt - currentTilt);
507 const G4double length =
element->
l*CLHEP::m;
513 length, extent, extent);
515 if (facesWillIntersect)
517 G4cerr << __METHOD_NAME__ <<
"Drift \"" <<
elementName
523 G4cerr <<
"\" and \"";
528 G4cerr <<
"\" is too short given its width and the angle of its faces." << G4endl;
545 case RFFieldDirection::x:
546 {fieldType = BDSFieldType::rfconstantinx;
break;}
547 case RFFieldDirection::y:
548 {fieldType = BDSFieldType::rfconstantiny;
break;}
549 case RFFieldDirection::z:
550 {fieldType = BDSFieldType::rfconstantinz;
break;}
562 G4double cavityLength =
element->
l * CLHEP::m;
567 if (fieldType == BDSFieldType::rfconstantinx || fieldType == BDSFieldType::rfconstantiny)
568 {buildCavityFringes =
false;}
570 G4bool buildIncomingFringe = buildCavityFringes;
577 G4bool buildOutgoingFringe = buildCavityFringes;
584 if (buildIncomingFringe)
586 if (buildOutgoingFringe)
603 vacuumField->SetModulatorInfo(modulator);
612 G4double stepFraction = 0.025;
616 G4double limit = std::min((*st)[
"length"], CLHEP::c_light*period) * stepFraction;
631 G4double cavityApertureRadius = cavityInfo->
irisRadius;
646 if (buildIncomingFringe)
650 (*stIn)[
"rmat11"] = 1;
651 (*stIn)[
"rmat21"] = 0;
652 (*stIn)[
"rmat22"] = 1;
653 (*stIn)[
"rmat33"] = 1;
654 (*stIn)[
"rmat43"] = 0;
655 (*stIn)[
"rmat44"] = 1;
657 (*stIn)[
"isentrance"] =
true;
658 auto cavityFringeIn = CreateCavityFringe(0, stIn,
elementName +
"_fringe_in", cavityApertureRadius, modulator);
672 if (buildOutgoingFringe)
676 (*stOut)[
"rmat11"] = 1;
677 (*stOut)[
"rmat21"] = 0;
678 (*stOut)[
"rmat22"] = 1;
679 (*stOut)[
"rmat33"] = 1;
680 (*stOut)[
"rmat43"] = 0;
681 (*stOut)[
"rmat44"] = 1;
683 (*stOut)[
"isentrance"] =
false;
684 auto cavityFringeIn = CreateCavityFringe(0, stOut,
elementName +
"_fringe_out", cavityApertureRadius, modulator);
707 (*st)[
"angle"] = angle;
710 (*st)[
"length"] =
element->
l * CLHEP::m;
720 G4cout <<
"Angle (rad) " << (*st)[
"angle"] / CLHEP::rad << G4endl;
721 G4cout <<
"Field (T) " << (*st)[
"field"] / CLHEP::tesla << G4endl;
728 incomingFaceAngle, outgoingFaceAngle,
746 G4double arcLength = 0, chordLength = 0, field = 0, angle = 0;
749 (*st)[
"angle"] = angle;
752 (*st)[
"length"] = arcLength;
766 -incomingFaceAngle, -outgoingFaceAngle,
775 incomingFaceAngle -= 0.5*angle;
776 outgoingFaceAngle -= 0.5*angle;
780 incomingFaceAngle, outgoingFaceAngle,
793 case KickerType::horizontal:
803 case KickerType::vertical:
813 case KickerType::general:
819 {BDS::Warning(__METHOD_NAME__,
"'kick' parameter defined in element \"" +
elementName +
"\" but will be ignored as general kicker.");}
833 G4double chordLength;
838 (*st)[
"scaling"] = scaling;
839 (*st)[
"hkick"] = scaling * hkick;
840 (*st)[
"vkick"] = scaling * vkick;
853 (*fringeStOut)[
"isentrance"] =
false;
857 G4bool finiteEntrFringe =
false;
858 G4bool finiteExitFringe =
false;
861 {finiteEntrFringe =
true;}
864 {finiteExitFringe =
true;}
867 G4bool buildEntranceFringe =
false;
868 G4bool buildExitFringe =
false;
870 {buildEntranceFringe =
true;}
872 {buildExitFringe =
true;}
875 buildEntranceFringe =
false;
876 buildExitFringe =
false;
881 fieldType = BDSFieldType::bfieldzero;
882 intType = BDSIntegratorType::kickerthin;
893 if (buildEntranceFringe || buildExitFringe)
895 G4cout << __METHOD_NAME__ <<
"WARNING - finite B field required for kicker pole face and fringe fields,"
896 " effects are unavailable for element ""\"" <<
elementName <<
"\"." << G4endl;
898 buildEntranceFringe =
false;
899 buildExitFringe =
false;
904 else if (type == KickerType::general)
907 if (buildEntranceFringe || buildExitFringe)
909 G4cerr << __METHOD_NAME__ <<
" Poleface and fringe field effects are unavailable "
910 <<
"for the thin (t)kicker element ""\"" <<
elementName <<
"\"." << G4endl;
912 buildEntranceFringe =
false;
913 buildExitFringe =
false;
924 (*st)[
"field"] =
element->
B * CLHEP::tesla * scaling;
925 (*fringeStIn) [
"field"] = (*st)[
"field"];
926 (*fringeStOut) [
"field"] = (*st)[
"field"];
930 if (type == KickerType::vertical)
940 G4double angleX = std::asin(hkick * scaling);
941 G4double angleY = std::asin(vkick * scaling);
944 if (std::isnan(angleX))
945 {
throw BDSException(__METHOD_NAME__,
"hkick too strong for element \"" +
element->name +
"\" ");}
946 if (std::isnan(angleY))
947 {
throw BDSException(__METHOD_NAME__,
"vkick too strong for element \"" +
element->name +
"\" ");}
961 case KickerType::horizontal:
962 case KickerType::general:
963 {fieldX =
element->
B * CLHEP::tesla * scaling;
break;}
964 case KickerType::vertical:
965 {fieldY =
element->
B * CLHEP::tesla * scaling;
break;}
976 G4double fieldChordLengthX = chordLength / std::cos(0.5*angleX);
979 G4double bendingRadiusX = fieldChordLengthX * 0.5 / sin(std::abs(angleX) * 0.5);
982 G4double arcLengthX = std::abs(bendingRadiusX * angleX);
990 G4double fieldChordLengthY = chordLength / std::cos(0.5*angleY);
991 G4double bendingRadiusY = fieldChordLengthY * 0.5 / sin(std::abs(angleY) * 0.5);
992 G4double arcLengthY = std::abs(bendingRadiusY * angleY);
999 G4ThreeVector field = G4ThreeVector(fieldY, fieldX, 0);
1000 G4double fieldMag = field.mag();
1001 G4ThreeVector unitField = field.unit();
1003 (*st)[
"field"] = fieldMag;
1004 (*st)[
"bx"] = unitField.x();
1005 (*st)[
"by"] = unitField.y();
1009 (*fringeStIn)[
"field"] = (*st)[
"field"];
1010 (*fringeStOut)[
"field"] = (*st)[
"field"];
1011 if (fieldX < 0 || fieldY < 0)
1013 (*fringeStIn)[
"field"] *= -1;
1014 (*fringeStOut)[
"field"] *= -1;
1018 (*fringeStIn) [
"bx"] = (*st)[
"bx"];
1019 (*fringeStIn) [
"by"] = (*st)[
"by"];
1020 (*fringeStOut)[
"bx"] = (*st)[
"bx"];
1021 (*fringeStOut)[
"by"] = (*st)[
"by"];
1024 G4double defaultVHRatio = 1.5;
1027 case KickerType::horizontal:
1028 case KickerType::general:
1029 {t = BDSMagnetType::hkicker;
break;}
1030 case KickerType::vertical:
1032 t = BDSMagnetType::vkicker;
1033 defaultVHRatio = 1./defaultVHRatio;
1037 {t = BDSMagnetType::hkicker;
break;}
1056 G4double defaultHorizontalWidth = 0.3 * globalDefaultHW;
1058 G4double bpDX = bpExt.
DX();
1059 G4double bpDY = bpExt.
DY();
1060 if (bpDX > defaultHorizontalWidth && bpDX < globalDefaultHW)
1061 {defaultHorizontalWidth = globalDefaultHW;}
1062 else if (bpDY > defaultHorizontalWidth && bpDY > globalDefaultHW)
1063 {defaultHorizontalWidth = globalDefaultHW;}
1066 defaultHorizontalWidth, defaultVHRatio, 0.9);
1102 G4double kickerChordLength = chordLength;
1103 if (buildEntranceFringe)
1105 if (buildExitFringe)
1108 if (buildEntranceFringe)
1110 G4String entrFringeName = baseName +
"_e1_fringe";
1120 G4String kickerName = baseName;
1131 if (buildEntranceFringe)
1133 G4String exitFringeName = baseName +
"_e2_fringe";
1207 beamPipeInfo->
beamPipeType = BDSBeamPipeType::circularvacuum;
1209 -angleIn, angleIn, beamPipeInfo);
1210 magnetOuterInfo->geometryType = BDSMagnetGeometryType::none;
1232 beamPipeInfo->
aper1,
1235 return thinMultipole;
1241 {
throw BDSException(__METHOD_NAME__,
"insufficient length for element \"" +
element->name +
"\" - must specify a suitable length");}
1248 G4double l =
element->
l * CLHEP::m;
1259 &vacuumBiasVolumeNames,
1273 G4double chordLength =
element->
l * CLHEP::m;
1275 (*st)[
"length"] = chordLength * 0.8;
1280 (*st)[
"field"] = scaling *
element->
B * CLHEP::tesla;
1281 (*st)[
"ks"] = (*st)[
"field"] /
brho;
1295 auto strength = [](G4double phi){
1301 (*s)[
"rmat41"] = -phi;
1302 (*s)[
"rmat23"] = phi;
1306 G4bool buildIncomingFringe =
true;
1311 G4bool buildOutgoingFringe =
true;
1317 G4double solenoidBodyLength =
element->
l * CLHEP::m;
1319 if (buildIncomingFringe)
1321 if (buildOutgoingFringe)
1325 G4double lengthScaling = solenoidBodyLength / (
element->
l * CLHEP::m);
1326 G4double s = 0.5*(*st)[
"ks"] * lengthScaling;
1331 if (buildIncomingFringe)
1333 auto stIn = strength(s);
1335 auto solenoidIn = CreateThinRMatrix(0, stIn,
elementName +
"_fringe_in",
1336 BDSIntegratorType::rmatrixthin, BDSFieldType::rmatrix, 0, modulator);
1352 vacuumField->SetModulatorInfo(modulator);
1355 vacuumField->SetScalingRadius(outerInfo->innerRadius);
1364 BDSFieldType::solenoid,
1377 G4double outerRadius = outerInfo->horizontalWidth * 0.5;
1378 G4double coilRadius = beamPipeRadius + 0.25*(outerRadius - beamPipeRadius);
1379 outerField->SetScalingRadius(coilRadius);
1382 auto solenoid =
new BDSMagnet(BDSMagnetType::solenoid,
1393 if (buildOutgoingFringe)
1395 auto stOut = strength(-s);
1397 auto solenoidOut = CreateThinRMatrix(0, stOut,
elementName +
"_fringe_out",
1398 BDSIntegratorType::rmatrixthin, BDSFieldType::rmatrix, 0, modulator);
1408 return CreateMagnet(
element, st, BDSFieldType::paralleltransporter, BDSMagnetType::paralleltransporter);
1415 G4bool circularOuter =
false;
1417 if (apertureType ==
"circular")
1418 {circularOuter =
true;}
1436 G4bool circularOuter =
false;
1438 if (apertureType ==
"circular")
1439 {circularOuter =
true;}
1453 G4bool circularOuter =
false;
1455 if (apertureType ==
"circular")
1456 {circularOuter =
true;}
1482 element->jawTiltLeft*CLHEP::rad,
1496 G4double elLength =
element->
l*CLHEP::m;
1504 outerField =
new BDSFieldInfo(BDSFieldType::muonspoiler,
1511 G4double limit = elLength / 20.0;
1513 if (ul != defaultUL)
1518 return new BDSMagnet(BDSMagnetType::muonspoiler,
1554 G4double degraderOffset;
1556 {
throw BDSException(__METHOD_NAME__,
"both \"materialThickness\" and \"degraderOffset\" are either undefined or < 0");}
1558 {
throw BDSException(__METHOD_NAME__,
"\"degraderOffset\" cannot be < 0");}
1560 {
throw BDSException(__METHOD_NAME__,
"\"materialThickness\" cannot be greater than the element length");}
1574 degraderOffset = (0.5*thicknessPerWedge) * (std::sin(CLHEP::halfpi - theta) / std::sin(theta));
1580 G4double baseWidth = bpi->aper1;
1602 {
throw BDSException(__METHOD_NAME__,
"\"angle\" parameter set for wirescanner \"" +
elementName +
"\" but this should not be set. Please unset and use \"wireAngle\".");}
1646 G4double limit = (*st)[
"length"] * 0.075;
1648 if (ul != defaultUL)
1665 G4double chordLength =
element->
l*CLHEP::m;
1668 G4cout << __METHOD_NAME__ <<
"using default length of 1 mm for dump" << G4endl;
1669 chordLength = 1*CLHEP::mm;
1672 G4bool circular =
false;
1674 if (apertureType ==
"circular")
1676 else if (apertureType !=
"rectangular" && !apertureType.empty())
1677 {
throw BDSException(__METHOD_NAME__,
"unknown shape for dump: \"" + apertureType +
"\"");}
1695 new BDSDicomIntersectVolume();
1718 if (!
element->crystalBoth.empty())
1723 else if (
element->crystalBoth.empty() && !
element->crystalRight.empty() && !
element->crystalLeft.empty())
1728 else if (
element->crystalRight.empty())
1735 G4cout << G4endl << G4endl << __METHOD_NAME__
1736 <<
"Left crystal being used but right angle set - perhaps check input for element "
1741 G4cout << G4endl << G4endl << __METHOD_NAME__
1742 <<
"Right crystal being used but left angle set - perhaps check input for element "
1753 element->crystalAngleYAxisLeft*CLHEP::rad,
1754 element->crystalAngleYAxisRight*CLHEP::rad));
1762 G4double length =
element->
l*CLHEP::m;
1766 G4ThreeVector position = G4ThreeVector(0,0,0);
1777 size.setX(
element->screenXSize*CLHEP::m);
1779 G4cout << __METHOD_NAME__ <<
" - size = " << size << G4endl;
1789 "same number of materials as layers - check 'layerMaterials'");
1795 std::list<std::string>::const_iterator itm;
1796 std::list<double>::const_iterator itt;
1797 std::list<int>::const_iterator itIsSampler;
1805 G4cout << __METHOD_NAME__ <<
" - screen layer: thickness: "
1806 << *(itt) <<
", material " << (*itm)
1807 <<
", isSampler: " << (*itIsSampler) << G4endl;
1823 return (
new BDSAwakeScintillatorScreen(
elementName,
1840 (*awakeStrength)[
"by"] = 1;
1845 BDSIntegratorType::g4classicalrk4,
1901 G4cout <<
"---->creating Terminator" << G4endl;
1915 BDSFieldType::paralleltransporter,
1916 BDSMagnetType::paralleltransporter);
1921 BDSFieldType::paralleltransporter,
1922 BDSMagnetType::paralleltransporter);
1936 const G4String& name)
1940 return CreateThinRMatrix(angleIn, st, name, BDSIntegratorType::rmatrixthin, BDSFieldType::rmatrix, 0, modulator);
1945 const G4String& name,
1948 G4double beamPipeRadius,
1952 beamPipeInfo->
beamPipeType = BDSBeamPipeType::circularvacuum;
1956 {beamPipeInfo->
aper1 = beamPipeRadius;}
1959 magnetOuterInfo->geometryType = BDSMagnetGeometryType::none;
1968 vacuumField->SetBeamPipeRadius(beamPipeInfo->
aper1);
1969 vacuumField->SetModulatorInfo(fieldModulator);
1981 beamPipeInfo->
aper1,
1989 const G4String& name,
1990 G4double irisRadius,
1995 BDSAcceleratorComponent* cavityFringe = CreateThinRMatrix(angleIn, st, name, intType, fieldType, irisRadius, fieldModulator);
1996 return cavityFringe;
2004 const G4String& nameSuffix)
const
2019 vacuumField->SetScalingRadius(outerInfo->innerRadius);
2024 G4bool externalOuterField = !(el->
fieldOuter.empty());
2049 G4bool printWarning)
2054 {BDS::Warning(
"---> NOT creating element \"" + el->name +
"\" -> l < 1e-7 m: l = " + std::to_string(el->
l) +
" m");}
2066 " is greater than " + std::to_string(maxAngle));}
2069 " is greater than " + std::to_string(maxAngle));}
2077 if (mgt == BDSMagnetGeometryType::lhcleft)
2079 if (mgt == BDSMagnetGeometryType::lhcright)
2082 G4double angle = (*st)[
"angle"];
2083 G4double hkickAng = -(*st)[
"hkick"];
2084 G4double vkickAng = -(*st)[
"vkick"];
2090 if ((angle < 0) && (
element->yokeOnInside))
2091 {yokeOnLeft =
true;}
2092 else if ((angle > 0) && (!(
element->yokeOnInside)))
2093 {yokeOnLeft =
true;}
2095 {yokeOnLeft =
false;}
2108 const G4Transform3D& fieldTransform,
2111 G4double outerFieldScaling,
2117 case BDSFieldType::dipole:
2118 {outerType = BDSFieldType::multipoleouterdipole;
break;}
2119 case BDSFieldType::quadrupole:
2120 {outerType = BDSFieldType::multipoleouterquadrupole;
break;}
2121 case BDSFieldType::sextupole:
2122 {outerType = BDSFieldType::multipoleoutersextupole;
break;}
2123 case BDSFieldType::octupole:
2124 {outerType = BDSFieldType::multipoleouteroctupole;
break;}
2125 case BDSFieldType::decapole:
2126 {outerType = BDSFieldType::multipoleouterdecapole;
break;}
2127 case BDSFieldType::skewquadrupole:
2128 {outerType = BDSFieldType::skewmultipoleouterquadrupole;
break;}
2129 case BDSFieldType::skewsextupole:
2130 {outerType = BDSFieldType::skewmultipoleoutersextupole;
break;}
2131 case BDSFieldType::skewoctupole:
2132 {outerType = BDSFieldType::skewmultipoleouteroctupole;
break;}
2133 case BDSFieldType::skewdecapole:
2134 {outerType = BDSFieldType::skewmultipoleouterdecapole;
break;}
2135 case BDSFieldType::dipole3d:
2136 case BDSFieldType::solenoid:
2137 {outerType = BDSFieldType::solenoidsheet;
break;}
2139 {
return nullptr;
break;}
2143 (*stCopy)[
"scalingOuter"] = outerFieldScaling;
2151 outerField->SetModulatorInfo(modulatorInfo);
2155 outerField->SetScalingRadius(outerInfo->innerRadius);
2156 outerField->SetSecondFieldOnLeft(outerInfo->yokeOnLeft);
2157 auto gt = outerInfo->geometryType;
2159 if ((gt == BDSMagnetGeometryType::lhcleft || gt == BDSMagnetGeometryType::lhcright) && yfmLHC)
2161 if (fieldType == BDSFieldType::dipole)
2162 {outerField->
SetFieldType(BDSFieldType::multipoleouterdipolelhc);}
2163 else if (fieldType == BDSFieldType::quadrupole)
2164 {outerField->
SetFieldType(BDSFieldType::multipoleouterquadrupolelhc);}
2165 else if (fieldType == BDSFieldType::sextupole)
2166 {outerField->
SetFieldType(BDSFieldType::multipoleoutersextupolelhc);}
2179 G4double defaultHorizontalWidth,
2180 G4double defaultVHRatio,
2181 G4double defaultCoilWidthFraction,
2182 G4double defaultCoilHeightFraction)
2185 G4double angle = (*st)[
"angle"];
2188 defaultHorizontalWidth, defaultVHRatio, defaultCoilWidthFraction,
2189 defaultCoilHeightFraction);
2197 if (el->magnetGeometryType.empty() || globals->IgnoreLocalMagnetGeometry())
2198 {result = globals->MagnetGeometryType();}
2206 const G4double angleIn,
2207 const G4double angleOut,
2209 const G4bool yokeOnLeft,
2210 G4double defaultHorizontalWidth,
2211 G4double defaultVHRatio,
2212 G4double defaultCoilWidthFraction,
2213 G4double defaultCoilHeightFraction)
2218 info->name = elementNameIn;
2222 if (! (el->magnetGeometryType.empty() || globals->IgnoreLocalMagnetGeometry()) )
2224 info->geometryTypeAndPath = el->magnetGeometryType;
2226 {BDS::Warning(__METHOD_NAME__,
"stripOuterVolume for element \"" + el->name +
"\" will have no effect");}
2230 info->angleIn = angleIn;
2231 info->angleOut = angleOut;
2240 G4Material* outerMaterial;
2241 if (el->material.empty())
2243 G4String defaultMaterialName = globals->OuterMaterialName();
2248 info->outerMaterial = outerMaterial;
2251 info->yokeOnLeft = yokeOnLeft;
2254 {info->
hStyle = globals->HStyle();}
2259 {info->vhRatio = G4double(el->
vhRatio);}
2260 else if (globals->VHRatio() > 0)
2261 {info->vhRatio = globals->VHRatio();}
2262 else if (defaultVHRatio > 0)
2263 {info->vhRatio = defaultVHRatio;}
2265 {info->vhRatio = info->
hStyle ? 0.8 : 1.0;}
2269 else if (globals->CoilWidthFraction() > 0)
2270 {info->coilWidthFraction = globals->CoilWidthFraction();}
2271 else if (defaultCoilHeightFraction > 0)
2272 {info->coilWidthFraction = defaultCoilWidthFraction;}
2274 {info->coilWidthFraction = info->
hStyle ? 0.8 : 0.65;}
2278 else if (globals->CoilHeightFraction() > 0)
2279 {info->coilHeightFraction = globals->CoilHeightFraction();}
2280 else if (defaultCoilHeightFraction > 0)
2281 {info->coilHeightFraction = defaultCoilHeightFraction;}
2283 {info->coilHeightFraction = 0.8;}
2292 G4double defaultHorizontalWidth)
2294 G4double horizontalWidth = el->horizontalWidth*CLHEP::m;
2295 if (horizontalWidth < 1e-6)
2297 if (defaultHorizontalWidth > 0)
2298 {horizontalWidth = defaultHorizontalWidth;}
2302 return horizontalWidth;
2307 G4Material* result =
nullptr;
2316 const G4ThreeVector& inputFaceNormalIn,
2317 const G4ThreeVector& outputFaceNormalIn)
2327 el->
aper1 * CLHEP::m,
2328 el->
aper2 * CLHEP::m,
2329 el->
aper3 * CLHEP::m,
2330 el->
aper4 * CLHEP::m,
2335 outputFaceNormalIn);
2339 G4String msg =
"\nProblem in element: \"" + el->name +
"\"";
2340 e.AppendToMessage(msg);
2354 const G4double angleIn,
2355 const G4double angleOut)
2365 G4cout << __METHOD_NAME__ <<
"offsetX,Y: " << el->
offsetX <<
" " << el->
offsetY <<
" tilt: " << el->
tilt << G4endl;
2367 G4double xOffset = el->
offsetX * CLHEP::m;
2368 G4double yOffset = el->
offsetY * CLHEP::m;
2369 G4double tilt = el->
tilt * CLHEP::rad;
2379 return tiltOffset ? tiltOffset->
Transform3D() : G4Transform3D();
2392 G4double horizontalWidth,
2393 const G4String& name)
2395 G4double radiusFromAngleLength = std::abs(arcLength / angle);
2396 if (horizontalWidth > 2*radiusFromAngleLength)
2398 G4cerr <<
"Error: the combination of length, angle and horizontalWidth in element named \"" << name
2399 <<
"\" will result in overlapping faces!" << G4endl <<
"Please reduce the horizontalWidth" << G4endl;
2409 G4Material* material =
nullptr;
2410 if (!model.material.empty())
2415 model.irisRadius*CLHEP::m,
2416 model.thickness*CLHEP::m,
2417 model.equatorRadius*CLHEP::m,
2418 model.halfCellLength*CLHEP::m,
2419 model.numberOfPoints,
2420 model.numberOfCells,
2421 model.equatorHorizontalAxis*CLHEP::m,
2422 model.equatorVerticalAxis*CLHEP::m,
2423 model.irisHorizontalAxis*CLHEP::m,
2424 model.irisVerticalAxis*CLHEP::m,
2425 model.tangentLineAngle);
2439 (G4double) colour.red,
2440 (G4double) colour.green,
2441 (G4double) colour.blue,
2442 (G4double) colour.alpha);
2455 G4String(model.data),
2457 G4double(model.lengthX)*CLHEP::m,
2458 G4double(model.lengthY)*CLHEP::m,
2459 G4double(model.lengthZ)*CLHEP::m,
2460 G4double(model.sizeA)*CLHEP::m,
2461 G4double(model.sizeB)*CLHEP::m,
2462 G4double(model.sizeC)*CLHEP::m,
2463 G4double(model.alpha)*CLHEP::halfpi,
2464 G4double(model.beta)*CLHEP::halfpi,
2465 G4double(model.gamma)*CLHEP::halfpi,
2466 G4int (model.spaceGroup),
2467 G4double(model.bendingAngleYAxis)*CLHEP::rad,
2468 G4double(model.bendingAngleZAxis)*CLHEP::rad,
2469 G4double(model.miscutAngleY)*CLHEP::rad);
2480 G4cout <<
"Defined crystals are:" << G4endl;
2482 {G4cout << kv.first << G4endl;}
2483 throw BDSException(__METHOD_NAME__,
"unknown crystal \"" + crystalName +
"\" - please define it");
2492 G4double frequency)
const
2499 if (modelName.empty())
2505 {
throw BDSException(__METHOD_NAME__,
"unknown cavity model identifier \"" + el->
cavityModel +
"\" - please define it");}
2513 if (cavityRadius > horizontalWidth)
2515 G4String msg =
"Cavity horizontalWidth for element \"" +
elementName +
"\" is smaller " +
"than the cavity model radius.";
2523 if (el->material.empty())
2525 G4String msg =
"cavity material is not defined for cavity \"" +
elementName +
"\"";
2526 msg +=
" or for cavity model \"" + el->
cavityModel +
"\" - please define it";
2537 G4double frequency)
const
2542 G4double aper1 = aperture->
aper1;
2545 G4double defaultHorizontalWidth = 20*CLHEP::cm;
2546 if (aper1 < defaultHorizontalWidth)
2547 {horizontalWidth = std::min(defaultHorizontalWidth, horizontalWidth);}
2549 G4double equatorRadius = horizontalWidth - thickness;
2550 if (equatorRadius <= 0)
2552 G4String msg =
"horizontalWidth - beampipeThickness <= 0 for element \"" + el->name +
"\" -> this quantity must be positive";
2557 G4double length = el->
l * CLHEP::m;
2558 G4double cellLength = length;
2565 cellLength = 2*CLHEP::c_light / frequency;
2566 G4double nCavities = length / cellLength;
2567 nCells = G4int(std::floor(nCavities));
2573 cellLength = length;
2588 G4double cavityLength)
2590 G4double eField = 0;
2591 G4double scaling = el->
scaling;
2593 {eField = scaling * el->
gradient * CLHEP::volt / CLHEP::m;}
2595 {eField = scaling * el->
E * CLHEP::volt / cavityLength;}
2601 G4double cavityLength,
2607 G4double chordLength = cavityLength;
2608 (*st)[
"equatorradius"] = 1*CLHEP::m;
2609 (*st)[
"length"] = chordLength;
2613 case BDSFieldType::rfconstantinz:
2614 {(*st)[
"ez"] = 1.0;
break;}
2615 case BDSFieldType::rfconstantinx:
2616 {(*st)[
"ex"] = 1.0;
break;}
2617 case BDSFieldType::rfconstantiny:
2618 {(*st)[
"ey"] = 1.0;
break;}
2620 {(*st)[
"ez"] = 1.0;
break;}
2624 G4double lengthScaling = cavityLength / (
element->
l * CLHEP::m);
2626 if ((fieldType == BDSFieldType::rfconstantinx || fieldType == BDSFieldType::rfconstantiny) &&
BDS::IsFinite(el->
E) )
2627 {
throw BDSException(__METHOD_NAME__,
"only \"gradient\" is accepted for rfconstantinx or rfconstantiny components and not \"E\"");}
2630 (*st)[
"efield"] = eField / lengthScaling;
2632 G4double frequency = std::abs(el->
frequency * CLHEP::hertz);
2633 (*st)[
"frequency"] = frequency;
2636 G4double phase = el->
phase * CLHEP::rad;
2637 (*st)[
"phase"] = phase;
2651 G4double tOffset = 0;
2653 {tOffset = el->
tOffset * CLHEP::s;}
2658 G4double phaseOffset = BDSFieldFactory::CalculateGlobalPhase(frequency, tOffset);
2659 (*st)[
"phase"] -= phaseOffset;
2660 (*st)[
"tOffset"] = tOffset;
2667 G4String colour = el->
colour;
2675 const G4String& defaultMaterialName)
2677 G4String materialName = el->material;
2678 if (materialName.empty())
2686 G4String materialName = el->material;
2687 if (materialName.empty())
2688 {
throw BDSException(__METHOD_NAME__,
"element \"" + el->name +
"\" has no material specified.");}
2700 for (
auto comp : *line)
2705 if (mag && el->
type != ElementType::_RF)
2710 <<
"\" is a magnet, but has fieldAll defined." << G4endl
2711 <<
"Can only have fieldOuter and or fieldVacuum specified." << G4endl;
2721 mag->SetOuterField(info);
2729 mag->SetVacuumField(info);
2741 {BDS::Warning(
"component \"" + el->name +
"\" has \"scalingFieldOuter\" != 1.0 -> this will have no effect for \"fieldAll\"");}
2750 if (!el->fieldModulator.empty())
2753 {
throw BDSException(__METHOD_NAME__,
"\""+
elementName+
"\" uses a field map with a modulator but also a modulator\ndouble modulation is not allowed");}
2757 info->SetModulatorInfo(modDef);
2766 G4double scaling = el->
scaling;
2767 G4double arcLength = el->
l * CLHEP::m;
2768 (*st)[
"length"] = arcLength;
2772 {(*st)[
"length"] = 1*CLHEP::m;}
2773 auto kn = el->
knl.begin();
2774 auto ks = el->
ksl.begin();
2777 auto nkey = normKeys.begin();
2778 auto skey = skewKeys.begin();
2780 for (; kn != el->
knl.end(); kn++, nkey++)
2781 {(*st)[*nkey] = scaling * (*kn);}
2782 for (; ks != el->
ksl.end(); ks++, skey++)
2783 {(*st)[*skey] = scaling * (*ks);}
2792 G4double scaling = el->
scaling;
2795 (*st)[
"kick1"] = scaling * el->
kick1;
2796 (*st)[
"kick2"] = scaling * el->
kick2;
2797 (*st)[
"kick3"] = scaling * el->
kick3;
2798 (*st)[
"kick4"] = scaling * el->
kick4;
2800 (*st)[
"rmat11"] = scaling * el->
rmat11;
2801 (*st)[
"rmat12"] = scaling * el->
rmat12;
2802 (*st)[
"rmat13"] = scaling * el->
rmat13;
2803 (*st)[
"rmat14"] = scaling * el->
rmat14;
2805 (*st)[
"rmat21"] = scaling * el->
rmat21;
2806 (*st)[
"rmat22"] = scaling * el->
rmat22;
2807 (*st)[
"rmat23"] = scaling * el->
rmat23;
2808 (*st)[
"rmat24"] = scaling * el->
rmat24;
2810 (*st)[
"rmat31"] = scaling * el->
rmat31;
2811 (*st)[
"rmat32"] = scaling * el->
rmat32;
2812 (*st)[
"rmat33"] = scaling * el->
rmat33;
2813 (*st)[
"rmat34"] = scaling * el->
rmat34;
2815 (*st)[
"rmat41"] = scaling * el->
rmat41;
2816 (*st)[
"rmat42"] = scaling * el->
rmat42;
2817 (*st)[
"rmat43"] = scaling * el->
rmat43;
2818 (*st)[
"rmat44"] = scaling * el->
rmat44;
2824 const G4double arcLength)
const
2829 {
return brho * angle / arcLength;}
2833 const G4double arcLength)
const
2838 {
return field * arcLength /
brho;}
2843 G4double& field)
const
2845 G4double arcLength = el->
l * CLHEP::m;
2848 field = el->
B * CLHEP::tesla;
2849 angle = el->
angle * CLHEP::rad;
2853 field = el->
B * CLHEP::tesla;
2858 angle = el->
angle * CLHEP::rad;
2864 {
throw BDSException(
"Error: the unsplit sbend "+ el->name +
" cannot be constucted as its bending angle is defined to be greater than pi/2.");}
2866 else if (std::abs(angle) > CLHEP::pi*2.0)
2867 {
throw BDSException(
"Error: the sbend "+ el->name +
" cannot be constucted as its bending angle is defined to be greater than 2 pi.");}
2871 G4double& arcLength,
2872 G4double& chordLength,
2874 G4double& angle)
const
2878 chordLength = el->
l * CLHEP::m;
2879 G4double arcLengthLocal = chordLength;
2884 field = el->
B * CLHEP::tesla;
2885 angle = el->
angle * CLHEP::rad;
2889 G4double radiusOfCurvatureOfDipole = 0.5 * chordLength / std::sin(0.5 * angle);
2890 arcLengthLocal = radiusOfCurvatureOfDipole * angle;
2893 {arcLengthLocal = chordLength;}
2897 field = el->
B * CLHEP::tesla;
2898 G4double bendingRadius =
brho / field;
2899 angle = 2.0*std::asin(chordLength*0.5 / bendingRadius);
2900 if (std::isnan(angle))
2901 {
throw BDSException(
"Field too strong for element " + el->name +
", magnet bending angle will be greater than pi.");}
2903 arcLengthLocal = bendingRadius * angle;
2907 angle = el->
angle * CLHEP::rad;
2913 G4double bendingRadius = chordLength * 0.5 / std::sin(std::abs(angle) * 0.5);
2914 arcLengthLocal = bendingRadius * angle;
2915 field =
brho * angle / std::abs(arcLengthLocal);
2922 arcLength = std::abs(arcLengthLocal);
2924 if (std::abs(angle) > CLHEP::pi/2.0)
2925 {
throw BDSException(
"Error: the rbend " + el->name +
" cannot be constucted as its bending angle is defined to be greater than pi/2.");}
2930 G4double bendAngle = 0;
2931 if (el->
type == ElementType::_RBEND)
2933 G4double arcLength = 0, chordLength = 0, field = 0;
2936 else if (el->
type == ElementType::_SBEND)
2941 else if (el->
type == ElementType::_ELEMENT)
2942 {bendAngle = -1*el->
angle*CLHEP::rad;}
2955 G4double outgoingFaceAngle = 0;
2959 G4double e2 = el->
e2*CLHEP::rad;
2960 if (el->
type == ElementType::_ELEMENT)
2962 G4double factor = bendAngle < 0 ? -1 : 1;
2963 outgoingFaceAngle += factor * e2;
2964 return outgoingFaceAngle;
2966 else if (el->
type == ElementType::_RBEND)
2969 {
return outgoingFaceAngle;}
2972 outgoingFaceAngle += 0.5 * bendAngle;
2978 {
return outgoingFaceAngle;}
2987 G4double factor = bendAngle < 0 ? -1 : 1;
2988 outgoingFaceAngle += factor * e2;
2991 return outgoingFaceAngle;
3002 G4double incomingFaceAngle = 0;
3006 G4double e1 = el->
e1*CLHEP::rad;
3007 if (el->
type == ElementType::_ELEMENT)
3009 G4double factor = bendAngle < 0 ? -1 : 1;
3010 incomingFaceAngle += factor * e1;
3011 return incomingFaceAngle;
3013 else if (el->
type == ElementType::_RBEND)
3016 {
return incomingFaceAngle;}
3019 incomingFaceAngle += 0.5 * bendAngle;
3025 {
return incomingFaceAngle;}
3034 G4double factor = bendAngle < 0 ? -1 : 1;
3035 incomingFaceAngle += factor * e1;
3038 return incomingFaceAngle;
3042 G4double elementArcLength)
const
3044 (*st)[
"synchronousT0"] = (
currentArcLength + 0.5 * elementArcLength) / CLHEP::c_light;
3048 G4bool inDevelopment)
const
3057 if (!
element->fieldModulator.empty())
3058 {
throw BDSException(__METHOD_NAME__,
"fieldModulator is currently in development for element \"" +
elementName +
"\"");}
static BDSAcceleratorComponentRegistry * Instance()
Singleton accessor.
void RegisterComponent(BDSAcceleratorComponent *component, bool isModified=false)
BDSAcceleratorComponent * GetComponent(const G4String &name)
Abstract class that represents a component of an accelerator.
virtual void Initialise()
virtual void SetMinimumKineticEnergy(G4double)
virtual void SetBiasVacuumList(const std::list< std::string > &biasVacuumListIn)
Copy the bias list to this element.
void SetField(BDSFieldInfo *fieldInfoIn)
Set the field definition for the whole component.
virtual void SetBiasMaterialList(const std::list< std::string > &biasMaterialListIn)
Copy the bias list to this element.
virtual void SetRegion(const G4String ®ionIn)
Set the region name for this component.
static BDSBeamPipeFactory * Instance()
Singleton accessor.
Holder class for all information required to describe a beam pipe model.
G4double aper1
Public member for direct access.
G4ThreeVector outputFaceNormal
Public member for direct access.
G4double beamPipeThickness
Public member for direct access.
G4double IndicativeRadius() const
Return an indicative extent of the beam pipe - typically the maximum of x or y extent.
BDSBeamPipeType beamPipeType
Public member for direct access.
G4ThreeVector inputFaceNormal
Public member for direct access.
RF Cavity. Uses factories to construct appropriate geometry.
Holder for all Geometrical information required to create an RF cavity.
G4double equatorRadius
Equator radius - half width of widest part.
G4double irisRadius
Iris radius - half width of narrowest part.
G4Material * material
Material.
G4double thickness
Thickness of wall material.
A piece of vacuum beam pipe with a crystal for channelling.
A class for an elliptical collimator.
Collimator with only two jaw and no top bit.
A class for a rectangular collimator.
Colour class that holds all colours used in BDSIM.
static BDSColours * Instance()
singleton pattern
G4Colour * GetColour(const G4String &type, G4bool normaliseTo255=true)
Get colour from name.
void DefineColour(const G4String &name, G4double red, G4double green, G4double blue, G4double alpha=1, G4bool normaliseTo255=true)
Define a new colour.
Factory for user specified accelerator components.
G4bool CanConstructComponentByName(const G4String &componentTypeName) const
Check whether a component can be constructed - ie if the name exists.
BDSAcceleratorComponent * ConstructComponent(const G4String &componentTypeName, GMAD::Element const *elementIn, GMAD::Element const *prevElementIn, GMAD::Element const *nextElementIn, G4double currentArcLength=0)
static G4bool YokeOnLeft(const GMAD::Element *el, const BDSMagnetStrength *st)
std::map< G4String, BDSCrystalInfo * > crystalInfos
Maps of crystal info instances by name.
G4double OutgoingFaceAngle(const GMAD::Element *el) const
G4double AngleFromField(const G4double field, const G4double arcLength) const
void INDEVELOPMENTERROR() const
TBC - remove when modulators are implemented fully.
BDSComponentFactoryUser * userComponentFactory
User component factory if any.
KickerType
Private enum for kicker types.
G4double FieldFromAngle(const G4double angle, const G4double arcLength) const
static G4double PrepareHorizontalWidth(GMAD::Element const *el, G4double defaultHorizontalWidth=-1)
Prepare the element horizontal width in Geant4 units - if not set, use the global default.
BDSComponentFactory()=delete
No default constructor.
BDSAcceleratorComponent * CreateTeleporter(const G4double teleporterLength, const G4double teleporterWidth, const G4Transform3D &transformIn)
BDSModulatorInfo * defaultModulator
Default modulator for all components.
G4Material * PrepareVacuumMaterial(GMAD::Element const *el) const
Prepare the vacuum material from the element or resort to default in options.
void CalculateAngleAndFieldRBend(const GMAD::Element *el, G4double &arcLength, G4double &chordLength, G4double &field, G4double &angle) const
static G4Transform3D CreateFieldTransform(const BDSTiltOffset *tiltOffset)
Create a transform from a tilt offset. If nullptr, returns identity transform.
BDSMagnet * CreateMagnet(const GMAD::Element *el, BDSMagnetStrength *st, BDSFieldType fieldType, BDSMagnetType magnetType, G4double angle=0.0, const G4String &nameSuffix="") const
Helper method for common magnet construction.
BDSMagnetStrength * PrepareMagnetStrengthForMultipoles(GMAD::Element const *el) const
Prepare magnet strength for multipoles.
GMAD::Element const * element
element for storing instead of passing around
static void PoleFaceRotationsNotTooLarge(const GMAD::Element *el, G4double maxAngle=0.5 *CLHEP::halfpi)
Check whether the pole face rotation angles are too big for practical construction.
G4double thinElementLength
Length of a thin element.
BDSCavityInfo * PrepareCavityModelInfoForElement(GMAD::Element const *el, G4double frequency) const
GMAD::Element const * nextElement
element access to previous element (can be nullptr)
BDSCavityInfo * PrepareCavityModelInfo(GMAD::Element const *el, G4double frequency) const
G4bool yokeFields
Cache of whether to include yoke magnetic fields.
static G4bool coloursInitialised
static BDSFieldInfo * PrepareMagnetOuterFieldInfo(const BDSMagnetStrength *vacuumSt, const BDSFieldType &fieldType, const BDSBeamPipeInfo *bpInfo, const BDSMagnetOuterInfo *outerInfo, const G4Transform3D &fieldTransform, const BDSIntegratorSet *integratorSetIn, G4double brhoIn, G4double outerFieldScaling=1.0, BDSModulatorInfo *modulatorInfo=nullptr)
Prepare the field definition for the yoke of a magnet.
void PrepareColours()
Prepare all colours defined in the parser.
static BDSMagnetOuterInfo * PrepareMagnetOuterInfo(const G4String &elementNameIn, const GMAD::Element *el, const BDSMagnetStrength *st, const BDSBeamPipeInfo *beamPipe, G4double defaultHorizontalWidth=-1, G4double defaultVHRatio=1.0, G4double defaultCoilWidthFraction=-1, G4double defaultCoilHeightFraction=-1)
BDSAcceleratorComponent * CreateTerminator(G4double witdth)
static G4Colour * PrepareColour(GMAD::Element const *element)
Checks if colour is specified for element, else uses the default for that element type.
BDSMagnetStrength * PrepareMagnetStrengthForRMatrix(GMAD::Element const *el) const
Prepare magnet strength for rmatrix.
G4double currentArcLength
Updated each time CreateComponent is called - supplied from outside. Only here to pass around all fun...
G4bool includeFringeFields
Cache of whether to include fringe fields.
void SetFieldDefinitions(GMAD::Element const *el, BDSAcceleratorComponent *component) const
static void CheckBendLengthAngleWidthCombo(G4double arcLength, G4double angle, G4double horizontalWidth, const G4String &name="not given")
void PrepareCrystals()
Prepare all crystals in defined the parser.
G4double lengthSafety
Length safety from global constants.
BDSMagnetStrength * PrepareCavityStrength(GMAD::Element const *el, BDSFieldType fieldType, G4double cavityLength, BDSMagnetStrength *&fringeIn, BDSMagnetStrength *&fringeOut) const
G4String elementName
Variable used to pass around the possibly modified name of an element.
void AddSynchronousTimeInformation(BDSMagnetStrength *st, G4double elementArcLength) const
Update the BDSMagnetStrength key synchronousT0 with the time at the centre of the element.
BDSAcceleratorComponent * CreateComponent(GMAD::Element const *elementIn, GMAD::Element const *prevElementIn, GMAD::Element const *nextElementIn, G4double currentArcLengthIn=0)
std::map< G4String, G4int > modifiedElements
void GetKickValue(G4double &hkick, G4double &vkick, const KickerType type) const
G4double BendAngle(const GMAD::Element *el) const
Calculate the angle of a bend whether it's an rbend or an sbend.
G4double IncomingFaceAngle(const GMAD::Element *el) const
void CalculateAngleAndFieldSBend(GMAD::Element const *el, G4double &angle, G4double &field) const
static G4Material * PrepareMaterial(GMAD::Element const *element, const G4String &defaultMaterialName)
Checks if a material is named in Element::material, else uses the supplied default.
static BDSTiltOffset * CreateTiltOffset(GMAD::Element const *el)
Create the tilt and offset information object by inspecting the parser element.
void SetModulatorDefinition(GMAD::Element const *el, BDSFieldInfo *info) const
void PrepareCavityModels()
const BDSIntegratorSet * integratorSet
Local copy of reference to integrator set to use.
BDSModulatorInfo * ModulatorDefinition(const GMAD::Element *el, G4bool inDevelopment=false) const
G4double brho
Rigidity in T*m (G4units) for beam particles.
void SetBeta0(BDSMagnetStrength *stIn) const
Simple setter used to add Beta0 to a strength instance.
BDSCrystalInfo * PrepareCrystalInfo(const G4String &crystalName) const
static BDSBeamPipeInfo * PrepareBeamPipeInfo(GMAD::Element const *el, const G4ThreeVector &inputFaceNormal=G4ThreeVector(0, 0,-1), const G4ThreeVector &outputFaceNormal=G4ThreeVector(0, 0, 1))
static BDSMagnetGeometryType MagnetGeometryType(const GMAD::Element *el)
static G4double EFieldFromElement(GMAD::Element const *el, G4double cavityLength)
std::map< G4String, BDSCavityInfo * > cavityInfos
Map of cavity model info instances by name.
G4bool HasSufficientMinimumLength(GMAD::Element const *el, G4bool printWarning=true)
Test the component length is sufficient for practical construction.
static G4double ScalingFieldOuter(const GMAD::Element *ele)
Get the scaling factor for a particular outer field depending on the global and individual setting.
GMAD::Element const * prevElement
element access to previous element (can be nullptr)
Holder for all information required to create a crystal.
Degrader based on wedge design used in the PSI medical accelerator.
A piece of vacuum beam pipe.
A class for a generic piece of external geometry.
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
G4double DX() const
The difference in a dimension.
G4double DY() const
The difference in a dimension.
static BDSFieldFactory * Instance()
Public accessor method for singleton pattern.
BDSFieldInfo * GetDefinition(const G4String &name) const
BDSModulatorInfo * GetModulatorDefinition(const G4String &modulatorName) const
All info required to build complete field of any type.
void SetTransformBeamline(const G4Transform3D &transformIn)
Set the beam line transform.
void CompoundBScaling(G4double extraBScalingIn)
*= for BScaling.
G4bool ProvideGlobal() const
Accessor.
void SetFieldType(BDSFieldType fieldTypeIn)
Set Transform - could be done afterwards once instance of this class is passed around.
BDSModulatorInfo * ModulatorInfo() const
Accessor.
BDSFieldType FieldType() const
Accessor.
void SetUserLimits(G4UserLimits *userLimitsIn)
Delete and replace the user limits which this class owns (only if not default ul).
Gap in accelerator beamline.
void SetExtent(const BDSExtent &extIn)
Set extent.
A class that holds global options and constants.
static BDSGlobalConstants * Instance()
Access method.
Which integrator to use for each type of magnet / field object.
G4bool IsMatrixIntegratorSet() const
Accessor for bool of is the integrator set matrix style.
BDSIntegratorType Integrator(const BDSFieldType field) const
Get appropriate integrator based on the field type.
A class that hold multiple accelerator components.
void AddComponent(BDSAcceleratorComponent *component)
Add a component to the line.
static BDSMagnetOuterFactory * Instance()
Singleton accessor.
Holder struct of all information required to create the outer geometry of a magnet.
G4bool hStyle
H Style for dipoles. If not, it's assumed C style.
Efficient storage of magnet strengths.
static std::vector< G4String > SkewComponentKeys()
Accessor for skew component keys - k1 - k12.
static std::vector< G4String > NormalComponentKeys()
Accessor for normal component keys - k1 - k12.
Abstract base class that implements features common to all magnets.
static BDSMaterials * Instance()
Singleton pattern access.
G4Material * GetMaterial(G4String material) const
Get material by name.
Holder class for all information required to describe a modulator.
static BDSParser * Instance()
Access method.
Wrapper for particle definition.
A multilayer screen in a beam pipe.
void AddScreenLayer(G4double thickness, G4String material, G4int isSampler=0)
Add a screen layer.
A square mask of solid material with a square aperture.
A class for a box or cylinder piece of 1 material.
An element that unnaturally shifts the beam across its length - a fudge volume.
Class for small control volume for circular macines.
A holder for any placement offsets and rotations for a BDSAcceleratorComponent.
G4Transform3D Transform3D() const
Get a transform to represent this tilt offset.
type underlying() const
return underlying value (can be used in switch statement)
Single cylindrical wire inside beam pipe.
const BDSIntegratorSet * IntegratorSet(G4String set)
Return the appropriate set of integrators to use for each magnet type.
BDSMagnetGeometryType DetermineMagnetGeometryType(G4String geometryType)
function to determine the enum type of the magnet geometry (case-insensitive)
G4bool WillIntersect(const G4ThreeVector &incomingNormal, const G4ThreeVector &outgoingNormal, const G4double &zSeparation, const BDSExtent &incomingExtent, const BDSExtent &outgoingExtent)
BDSCrystalType DetermineCrystalType(G4String crystalType)
function to determine the enum type of the cavity geometry (case-insensitive)
G4double SecondFringeFieldCorrection(BDSMagnetStrength const *strength, G4bool entranceOrExit)
Function to calculate the value of the second fringe field correction term.
G4UserLimits * CreateUserLimits(G4UserLimits *defaultUL, G4double length, G4double fraction=1.6)
BDSMagnet * BuildDipoleFringe(const GMAD::Element *element, G4double angleIn, G4double angleOut, const G4String &name, BDSMagnetStrength *st, G4double brho, const BDSIntegratorSet *integratorSet, BDSFieldType dipoleFieldType, BDSModulatorInfo *fieldModulator=nullptr)
BDSLine * BuildRBendLine(const G4String &elementName, const GMAD::Element *element, const GMAD::Element *prevElement, const GMAD::Element *nextElement, G4double brho, BDSMagnetStrength *st, const BDSIntegratorSet *integratorSet, G4double incomingFaceAngle, G4double outgoingFaceAngle, G4bool buildFringeFields, BDSModulatorInfo *fieldModulator=nullptr)
std::vector< G4String > SplitOnWhiteSpace(const G4String &input)
Split a string on whitespace and return a vector of these 'words'.
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())
G4double ArcLengthFromChordLength(G4double chordLength, G4double angle)
Calculate the arc length from the chord length for a given angle.
BDSCavityType DetermineCavityType(G4String cavityType)
function to determine the enum type of the cavity geometry (case-insensitive)
BDSAcceleratorComponent * BuildSBendLine(const G4String &elementName, const GMAD::Element *element, BDSMagnetStrength *st, G4double brho, const BDSIntegratorSet *integratorSet, G4double incomingFaceAngle, G4double outgoingFaceAngle, G4bool buildFringeFields, const GMAD::Element *prevElement, const GMAD::Element *nextElement, BDSModulatorInfo *fieldModulator=nullptr)
std::pair< G4ThreeVector, G4ThreeVector > CalculateFaces(G4double angleInIn, G4double angleOutIn)
Calculate input and output normal vector.
G4double FringeFieldCorrection(BDSMagnetStrength const *strength, G4bool entranceOrExit)
Function to calculate the value of the fringe field correction term.
Parser namespace for GMAD language. Combination of Geant4 and MAD.
ElementType
types of elements
std::string typestr(ElementType type)
conversion from enum to string
double hkick
fractional delta px for hkicker
std::string dicomDataFile
for CT, file for DICOM construction data
std::string spec
Arbitrary specification to pass to beamline builder.
double twindow
thickness of window
double aper4
beampipe information, new aperture model
std::string beampipeMaterial
beampipe information, new aperture model
double rmat33
rmatrix elements, only 4x4
double rmat11
rmatrix elements, only 4x4
double rmat43
rmatrix elements, only 4x4
std::list< std::string > layerMaterials
for screen
double scaling
Overall scaling of field strength.
double windowScreenGap
air gap between window and screen
double gradient
for rf cavities in V / m
double degraderOffset
for degrader
double wireAngle
for wirescanner
double aper2
beampipe information, new aperture model
double fintx
fringe field integral at the dipole exit
double kick4
rmatrix elements, only 4x4
double rmat42
rmatrix elements, only 4x4
double aper1
beampipe information, new aperture model
double rmat41
rmatrix elements, only 4x4
double awakeMagnetOffsetX
for AWAKE spectrometer
double zdir
for 3d transform and laser
std::string namedVacuumVolumes
For imported geometry - identify vacuum volumes.
bool stripOuterVolume
For Element. Make it an assembly.
double screenPSize
for AWAKE spectrometer
double xdir
for 3d transform and laser
double rmat34
rmatrix elements, only 4x4
double psi
for 3d transforms
double wireOffsetX
for wirescanner
double rmat31
rmatrix elements, only 4x4
double wedgeLength
for degrader
double vhRatio
ratio of vertial to horizontal for some magnets
double waveLength
for laser wire and 3d transforms
double rmat22
rmatrix elements, only 4x4
std::string userTypeName
User component element type name.
double wireOffsetY
for wirescanner
double kick3
rmatrix elements, only 4x4
double rmat24
rmatrix elements, only 4x4
double tOffset
time offset used for phase calculation (ns)
std::list< std::string > biasMaterialList
double xsizeRight
individual collimator jaw half widths
double coilWidthFraction
Fraction of available h space the coil will take up.
double rmat44
rmatrix elements, only 4x4
std::string fieldAll
Field for everything.
double jawTiltRight
jaw collimator jaw tilts (angle in x-z plane)
std::string region
region with range cuts
double wireDiameter
for wirescanner
double tmount
thickness of the screen mount
double wireOffsetZ
for wirescanner
std::list< double > ksl
skew multipole expansion
int numberWedges
for degrader
double kick1
rmatrix elements, only 4x4
std::list< double > knl
multipole expansion coefficients
std::string windowmaterial
for AWAKE spectrometer
double e2
output pole face rotation for bends
double phase
phase of rf cavity (rad)
double ysizeOut
collimator aperture or laser spotsize for laser
std::string fieldVacuum
Vacuum field.
bool autoColour
Automagically colour the external geometry.
double angle
bending angle
int hStyle
-1 = unset; 0 = false (ie c style); 1 = true, use hstyle
std::string geometryFile
For Element. File for external geometry.
std::string vacuumMaterial
beampipe information, new aperture model
double vkick
fractional delta py for vkicker
double E
voltage for rf cavities in V that will be assumed over length l
double coilHeightFraction
Fraction of availalbe v space the coil will take up.
std::list< int > layerIsSampler
for screen
bool elementLengthIsArcLength
For Element. Treat the length as arc length, if not chord.
double screenEndZ
for AWAKE spectrometer
double ysize
collimator aperture or laser spotsize for laser
double rmat23
rmatrix elements, only 4x4
std::string colour
Override colour for certain items.
double rmat13
rmatrix elements, only 4x4
double materialThickness
for degrader
double kick
fractional delta p for either h or v kicker
double rmat14
rmatrix elements, only 4x4
double beampipeThickness
beampipe information, new aperture model
std::string dicomDataPath
for CT, file for DICOM construction data
double minimumKineticEnergy
minimum kinetic energy for user limits - respected on element by element basis
std::string scintmaterial
for AWAKE spectrometer
double ydir
for 3d transform and laser
double undulatorMagnetHeight
for undulator
std::string cavityModel
Name of geometry model object for rfconstantinz cavities.
double e1
input pole face rotation for bends
std::string fieldOuter
Outer field.
double undulatorPeriod
for undulator
double wireLength
for wirescanner
double undulatorGap
for undulator
double poleStartZ
for AWAKE spectrometer
std::string mountmaterial
for AWAKE spectrometer
double aper3
beampipe information, new aperture model
ElementType type
element enum
std::list< std::string > biasVacuumList
physics biasing list for the vacuum
std::list< double > layerThicknesses
for screen
double scalingFieldOuter
Extra arbitrary scaling for outer field - compounded with 'scaling'.
double degraderHeight
for degrader
double tscint
thickness of scintillating part of screen
double screenWidth
for AWAKE spectrometer
double frequency
frequency for rf cavity in Hz
double kick2
rmatrix elements, only 4x4
double rmat12
rmatrix elements, only 4x4
std::string apertureType
beampipe information, new aperture model
double rmat21
rmatrix elements, only 4x4
double rmat32
rmatrix elements, only 4x4