19#include "BDSArrayReflectionType.hh"
20#include "BDSBeamPipeInfo.hh"
22#include "BDSException.hh"
23#include "BDSPTCOneTurnMap.hh"
24#include "BDSPrimaryGeneratorAction.hh"
25#include "BDSFieldClassType.hh"
26#include "BDSFieldE.hh"
27#include "BDSFieldEGlobal.hh"
28#include "BDSFieldEGlobalPlacement.hh"
29#include "BDSFieldEInterpolated.hh"
30#include "BDSFieldEInterpolated2Layer.hh"
31#include "BDSFieldESinusoid.hh"
32#include "BDSFieldEZero.hh"
33#include "BDSFieldEM.hh"
34#include "BDSFieldEMGlobal.hh"
35#include "BDSFieldEMGlobalPlacement.hh"
36#include "BDSFieldEMInterpolated.hh"
37#include "BDSFieldEMRFCavity.hh"
38#include "BDSFieldEMZero.hh"
39#include "BDSFieldFactory.hh"
40#include "BDSFieldInfo.hh"
41#include "BDSFieldLoader.hh"
42#include "BDSFieldMag.hh"
43#include "BDSFieldMagDecapole.hh"
44#include "BDSFieldMagDipole.hh"
45#include "BDSFieldMagDipoleOuter.hh"
46#include "BDSFieldMagDipoleOuterOld.hh"
47#include "BDSFieldMagDipoleQuadrupole.hh"
48#include "BDSFieldMagGlobal.hh"
49#include "BDSFieldMagGlobalPlacement.hh"
50#include "BDSFieldMagInterpolated.hh"
51#include "BDSFieldMagInterpolated2Layer.hh"
52#include "BDSFieldMagMultipole.hh"
53#include "BDSFieldMagMultipoleOuter.hh"
54#include "BDSFieldMagMultipoleOuterDual.hh"
55#include "BDSFieldMagMultipoleOuterDualOld.hh"
56#include "BDSFieldMagMultipoleOuterOld.hh"
57#include "BDSFieldMagMuonSpoiler.hh"
58#include "BDSFieldMagOctupole.hh"
59#include "BDSFieldMagQuadrupole.hh"
60#include "BDSFieldMagSextupole.hh"
61#include "BDSFieldMagSolenoidSheet.hh"
62#include "BDSFieldMagSkewOwn.hh"
63#include "BDSFieldMagZero.hh"
64#include "BDSFieldObjects.hh"
65#include "BDSFieldType.hh"
66#include "BDSGlobalConstants.hh"
67#include "BDSIntegratorCavityFringe.hh"
68#include "BDSIntegratorDecapole.hh"
69#include "BDSIntegratorDipoleRodrigues.hh"
70#include "BDSIntegratorDipoleRodrigues2.hh"
71#include "BDSIntegratorDipoleFringe.hh"
72#include "BDSIntegratorDipoleFringeScaling.hh"
73#include "BDSIntegratorDipoleQuadrupole.hh"
74#include "BDSIntegratorEuler.hh"
75#include "BDSIntegratorG4RK4MinStep.hh"
76#include "BDSIntegratorKickerThin.hh"
77#include "BDSIntegratorOctupole.hh"
78#include "BDSIntegratorQuadrupole.hh"
79#include "BDSIntegratorMultipoleThin.hh"
80#include "BDSIntegratorParallelTransport.hh"
81#include "BDSIntegratorSextupole.hh"
82#include "BDSIntegratorSolenoid.hh"
83#include "BDSIntegratorTeleporter.hh"
84#include "BDSIntegratorRMatrixThin.hh"
85#include "BDSIntegratorType.hh"
86#include "BDSMagnetOuterFactoryLHC.hh"
87#include "BDSMagnetStrength.hh"
88#include "BDSMagnetType.hh"
89#include "BDSParser.hh"
90#include "BDSParticleDefinition.hh"
91#include "BDSUtilities.hh"
92#include "BDSFieldMagUndulator.hh"
94#include "parser/field.h"
97#include "G4EquationOfMotion.hh"
98#include "G4EqMagElectricField.hh"
99#include "G4MagIntegratorStepper.hh"
100#include "G4Mag_UsualEqRhs.hh"
101#include "G4RotationMatrix.hh"
102#include "G4String.hh"
103#include "G4ThreeVector.hh"
104#include "G4Transform3D.hh"
105#include "G4Version.hh"
108#include "G4CashKarpRKF45.hh"
109#include "G4ClassicalRK4.hh"
110#include "G4ConstRK4.hh"
111#include "G4ExactHelixStepper.hh"
112#include "G4ExplicitEuler.hh"
113#include "G4HelixExplicitEuler.hh"
114#include "G4HelixHeum.hh"
115#include "G4HelixImplicitEuler.hh"
116#include "G4HelixMixedStepper.hh"
117#include "G4HelixSimpleRunge.hh"
118#include "G4ImplicitEuler.hh"
119#include "G4NystromRK4.hh"
120#include "G4RKG3_Stepper.hh"
121#include "G4SimpleHeum.hh"
122#include "G4SimpleRunge.hh"
123#if G4VERSION_NUMBER > 1029
124#include "G4BogackiShampine23.hh"
125#include "G4BogackiShampine45.hh"
126#include "G4DoLoMcPriRK34.hh"
127#include "G4DormandPrince745.hh"
128#include "G4DormandPrinceRK56.hh"
129#include "G4TsitourasRK45.hh"
131#if G4VERSION_NUMBER > 1039
132#include "G4DormandPrinceRK78.hh"
133#include "G4RK547FEq1.hh"
134#include "G4RK547FEq2.hh"
135#include "G4RK547FEq3.hh"
138#include "CLHEP/Units/SystemOfUnits.h"
139#include "CLHEP/Vector/EulerAngles.h"
159 useOldMultipoleOuterFields(false)
161 G4double defaultRigidity = std::numeric_limits<double>::max();
168BDSFieldFactory::~BDSFieldFactory()
171 {
delete info.second;}
175 G4double defaultBRho)
177 for (
const auto& definition : definitions)
179 if (definition.type.empty())
181 G4String msg =
"\"type\" not specified in field definition \"";
182 msg += definition.name +
"\", but required.";
188 G4ThreeVector offset = G4ThreeVector(definition.x*CLHEP::m,
189 definition.y*CLHEP::m,
190 definition.z*CLHEP::m);
193 if (definition.axisAngle)
195 G4ThreeVector axis = G4ThreeVector(definition.axisX,
198 rm = G4RotationMatrix(axis, definition.angle*CLHEP::rad);
206 CLHEP::HepEulerAngles ang = CLHEP::HepEulerAngles(definition.phi*CLHEP::rad,
207 definition.theta*CLHEP::rad,
208 definition.psi*CLHEP::rad);
209 rm = G4RotationMatrix(ang);
214 G4Transform3D transform = G4Transform3D(rm, offset);
217 G4String magFile =
"";
218 G4bool magFileSpecified = !definition.magneticFile.empty();
219 if (magFileSpecified)
221 std::pair<G4String, G4String> bf =
BDS::SplitOnColon(G4String(definition.magneticFile));
227 G4String eleFile =
"";
228 G4bool eleFileSpecified = !definition.electricFile.empty();
229 if (eleFileSpecified)
231 std::pair<G4String, G4String> ef =
BDS::SplitOnColon(G4String(definition.electricFile));
237 if (magFileSpecified)
240 if (!definition.magneticInterpolator.empty())
249 if (nDimFF != nDimInt)
251 G4String message =
"mismatch in number of dimensions between magnetic interpolator ";
252 message +=
"and field map format for field definition \"" + definition.name +
"\"";
262 if (eleFileSpecified)
265 if (!definition.electricInterpolator.empty())
274 if (nDimFF != nDimInt)
276 G4String message =
"mismatch in number of dimensions between electric interpolator ";
277 message +=
"and field map format for field definition \"" + definition.name +
"\"";
286 G4UserLimits* fieldLimit =
nullptr;
287 if (definition.maximumStepLength > 0)
291 G4double limit = G4double(definition.maximumStepLength) * CLHEP::m;
300 if (!definition.fieldParameters.empty())
307 G4bool(definition.globalTransform),
316 G4double(definition.eScaling),
317 G4double(definition.bScaling),
318 G4double(definition.t*CLHEP::s),
319 G4bool(definition.autoScale),
321 info->SetScalingRadius(poleTipRadius);
323 if (!definition.magneticSubField.empty())
325 if (definition.magneticSubField == definition.name)
326 {
throw BDSException(__METHOD_NAME__,
"error in \"" + definition.name +
"\": magneticSubField cannot be the field itself");}
327 info->SetMagneticSubField(G4String(definition.magneticSubField));
329 if (!definition.electricSubField.empty())
331 if (definition.electricSubField == definition.name)
332 {
throw BDSException(__METHOD_NAME__,
"error in \"" + definition.name +
"\": electricSubField cannot be the field itself");}
333 info->SetElectricSubField(G4String(definition.electricSubField));
335 if (!definition.magneticReflection.empty())
337 G4String magneticReflection = G4String(definition.magneticReflection);
339 info->SetMagneticArrayReflectionType(mar);
341 if (!definition.electricReflection.empty())
343 G4String electricReflection = G4String(definition.electricReflection);
345 info->SetElectricArrayReflectionType(ear);
348 info->SetNameOfParserDefinition(G4String(definition.name));
351 G4cout <<
"Definition: \"" << definition.name <<
"\"" << G4endl;
352 G4cout << *info << G4endl;
359 const G4String& parameterNameForError)
const
363 {result = std::stod(value);}
364 catch (std::exception& e)
366 G4String msg(e.what());
367 G4String baseMsg =
"Unable to interpret value (\"" + value +
"\" of parameter \"";
368 baseMsg += parameterNameForError +
"\" as a number: ";
375 const G4String& fieldParameters,
376 G4double& poleTipRadius)
const
382 for (
const auto& keyValue : map)
389 else if (keyValue.first ==
"poletipradius")
393 G4String msg =
"Invalid key \"" + keyValue.first +
"\" for field parameters. ";
394 msg +=
"Acceptable parameters are: \n";
396 for (G4int i = 0; i < (G4int)allKeys.size(); i++)
398 msg += allKeys[i] +
", ";
399 if ((i % 10 == 0) && (i > 0))
417 G4cerr << __METHOD_NAME__ <<
"\"" << name <<
"\" is not a valid field specifier" << G4endl;
418 G4cout <<
"Defined field specifiers are:" << G4endl;
420 {G4cout <<
"\"" << it.first <<
"\"" << G4endl;}
421 throw BDSException(__METHOD_NAME__,
"invalid field name");
423 return result->second;
428 const G4String& scalingKey)
431 G4cout << __METHOD_NAME__ << info << G4endl;
437 if (info.
FieldType() == BDSFieldType::none)
443 case BDSFieldClassType::magnetic:
444 {field =
CreateFieldMag(info, scalingStrength, scalingKey);
break;}
445 case BDSFieldClassType::electromagnetic:
447 case BDSFieldClassType::electric:
449 case BDSFieldClassType::irregular:
460 switch (numberOfDimensions)
463 {result = BDSInterpolatorType::cubic1d;
break;}
465 {result = BDSInterpolatorType::cubic2d;
break;}
467 {result = BDSInterpolatorType::cubic3d;
break;}
469 {result = BDSInterpolatorType::cubic4d;
break;}
471 {
throw BDSException(__METHOD_NAME__,
"unsupported number of dimensions " + std::to_string(numberOfDimensions));}
478 const G4String& scalingKey)
499 return completeField;
504 const G4String& scalingKey)
508 G4double brho = info.
BRho();
513 case BDSFieldType::bmap1d:
514 case BDSFieldType::bmap2d:
515 case BDSFieldType::bmap3d:
516 case BDSFieldType::bmap4d:
517 case BDSFieldType::mokka:
527 case BDSFieldType::bfieldzero:
529 case BDSFieldType::solenoid:
530 case BDSFieldType::dipole:
531 case BDSFieldType::dipole3d:
533 case BDSFieldType::solenoidsheet:
535 case BDSFieldType::quadrupole:
537 case BDSFieldType::undulator:
539 case BDSFieldType::dipolequadrupole:
541 case BDSFieldType::sextupole:
543 case BDSFieldType::octupole:
545 case BDSFieldType::decapole:
547 case BDSFieldType::multipole:
549 case BDSFieldType::muonspoiler:
551 case BDSFieldType::skewquadrupole:
553 case BDSFieldType::skewsextupole:
555 case BDSFieldType::skewoctupole:
557 case BDSFieldType::skewdecapole:
559 case BDSFieldType::multipoleouterdipole:
562 G4bool positiveField = (*strength)[
"field"] < 0;
563 if (useOldMultipoleOuterFields)
570 case BDSFieldType::multipoleouterquadrupole:
573 G4bool positiveField = (*strength)[
"k1"] > 0;
574 if (useOldMultipoleOuterFields)
581 case BDSFieldType::multipoleoutersextupole:
584 G4bool positiveField = (*strength)[
"k2"] > 0;
585 if (useOldMultipoleOuterFields)
592 case BDSFieldType::multipoleouteroctupole:
595 G4bool positiveField = (*strength)[
"k3"] > 0;
596 if (useOldMultipoleOuterFields)
603 case BDSFieldType::multipoleouterdecapole:
606 G4bool positiveField = (*strength)[
"k4"] > 0;
607 if (useOldMultipoleOuterFields)
614 case BDSFieldType::skewmultipoleouterquadrupole:
617 G4bool positiveField = (*strength)[
"k1"] > 0;
619 if (useOldMultipoleOuterFields)
627 case BDSFieldType::skewmultipoleoutersextupole:
630 G4bool positiveField = (*strength)[
"k2"] > 0;
632 if (useOldMultipoleOuterFields)
640 case BDSFieldType::skewmultipoleouteroctupole:
643 G4bool positiveField = (*strength)[
"k3"] > 0;
645 if (useOldMultipoleOuterFields)
653 case BDSFieldType::skewmultipoleouterdecapole:
656 G4bool positiveField = (*strength)[
"k4"] > 0;
658 if (useOldMultipoleOuterFields)
666 case BDSFieldType::multipoleouterdipole3d:
668 if (useOldMultipoleOuterFields)
674 case BDSFieldType::multipoleouterdipolelhc:
677 G4bool positiveField = (*strength)[
"field"] < 0;
678 G4bool positiveField2 = (*strength)[
"angle"] > 0;
680 if (useOldMultipoleOuterFields)
693 case BDSFieldType::multipoleouterquadrupolelhc:
696 G4bool positiveField = (*strength)[
"k1"] > 0;
698 if (useOldMultipoleOuterFields)
711 case BDSFieldType::multipoleoutersextupolelhc:
714 G4bool positiveField = (*strength)[
"k2"] > 0;
716 if (useOldMultipoleOuterFields)
729 case BDSFieldType::paralleltransporter:
749 {
throw BDSException(__METHOD_NAME__,
"subfield specified for non-field map type field - not supported");}
755 {
throw BDSException(__METHOD_NAME__,
"subfield type is not a field map type field - not supported");}
759 delete subFieldRecipe;
770 case BDSFieldType::rfcavity:
772 case BDSFieldType::ebmap1d:
773 case BDSFieldType::ebmap2d:
774 case BDSFieldType::ebmap3d:
775 case BDSFieldType::ebmap4d:
783 case BDSFieldType::ebfieldzero:
805 G4EqMagElectricField* eqOfM =
new G4EqMagElectricField(resultantField);
811 return completeField;
828 G4EqMagElectricField* eqOfM =
new G4EqMagElectricField(resultantField);
834 return completeField;
842 case BDSFieldType::rf:
844 case BDSFieldType::emap1d:
845 case BDSFieldType::emap2d:
846 case BDSFieldType::emap3d:
847 case BDSFieldType::emap4d:
855 case BDSFieldType::efieldzero:
873 {
throw BDSException(__METHOD_NAME__,
"subfield specified for non-field map type field - not supported");}
879 {
throw BDSException(__METHOD_NAME__,
"subfield type is not a field map type field - not supported");}
883 delete subFieldRecipe;
895 case BDSFieldType::teleporter:
897 case BDSFieldType::rmatrix:
899 case BDSFieldType::cavityfringe:
901 case BDSFieldType::paralleltransporter:
913 const G4double minimumRadiusOfCurvature = 10*CLHEP::cm;
914 G4double brho = info.
BRho();
915 G4MagIntegratorStepper* integrator =
nullptr;
919 case BDSIntegratorType::solenoid:
921 case BDSIntegratorType::dipolerodrigues:
923 case BDSIntegratorType::dipolerodrigues2:
925 case BDSIntegratorType::dipolematrix:
927 case BDSIntegratorType::quadrupole:
929 case BDSIntegratorType::sextupole:
931 case BDSIntegratorType::octupole:
933 case BDSIntegratorType::decapole:
935 case BDSIntegratorType::multipolethin:
937 case BDSIntegratorType::dipolefringe:
939 case BDSIntegratorType::dipolefringescaling:
941 case BDSIntegratorType::euler:
943 case BDSIntegratorType::kickerthin:
945 case BDSIntegratorType::g4rk4minimumstep:
947 case BDSIntegratorType::rmatrixthin:
949 case BDSIntegratorType::cavityfringe:
951 case BDSIntegratorType::g4constrk4:
952 integrator =
new G4ConstRK4(eqOfM);
break;
953 case BDSIntegratorType::g4exacthelixstepper:
954 integrator =
new G4ExactHelixStepper(eqOfM);
break;
955 case BDSIntegratorType::g4helixexpliciteuler:
956 integrator =
new G4HelixExplicitEuler(eqOfM);
break;
957 case BDSIntegratorType::g4helixheum:
958 integrator =
new G4HelixHeum(eqOfM);
break;
959 case BDSIntegratorType::g4heliximpliciteuler:
960 integrator =
new G4HelixImplicitEuler(eqOfM);
break;
961 case BDSIntegratorType::g4helixmixedstepper:
962 integrator =
new G4HelixMixedStepper(eqOfM);
break;
963 case BDSIntegratorType::g4helixsimplerunge:
964 integrator =
new G4HelixSimpleRunge(eqOfM);
break;
965 case BDSIntegratorType::g4nystromrk4:
966 integrator =
new G4NystromRK4(eqOfM);
break;
967 case BDSIntegratorType::g4rkg3stepper:
968 integrator =
new G4RKG3_Stepper(eqOfM);
break;
969 case BDSIntegratorType::g4cashkarprkf45:
970 case BDSIntegratorType::g4classicalrk4:
971 case BDSIntegratorType::g4expliciteuler:
972 case BDSIntegratorType::g4impliciteuler:
973 case BDSIntegratorType::g4simpleheum:
974 case BDSIntegratorType::g4simplerunge:
975#if G4VERSION_NUMBER > 1029
976 case BDSIntegratorType::g4bogackishampine23:
977 case BDSIntegratorType::g4bogackishampine45:
978 case BDSIntegratorType::g4dolomcprirk34:
979 case BDSIntegratorType::g4dormandprince745:
980 case BDSIntegratorType::g4dormandprincerk56:
981 case BDSIntegratorType::g4tsitourasrk45:
983#if G4VERSION_NUMBER > 1039
984 case BDSIntegratorType::g4dormandprincerk78:
985 case BDSIntegratorType::g4rk547feq1:
986 case BDSIntegratorType::g4rk547feq2:
987 case BDSIntegratorType::g4rk547feq3:
998 G4EquationOfMotion* eqOfM)
1000 G4MagIntegratorStepper* integrator =
nullptr;
1004 case BDSIntegratorType::g4cashkarprkf45:
1005 integrator =
new G4CashKarpRKF45(eqOfM, 8);
break;
1006 case BDSIntegratorType::g4classicalrk4:
1007 integrator =
new G4ClassicalRK4(eqOfM, 8);
break;
1008 case BDSIntegratorType::g4expliciteuler:
1009 integrator =
new G4ExplicitEuler(eqOfM, 8);
break;
1010 case BDSIntegratorType::g4impliciteuler:
1011 integrator =
new G4ImplicitEuler(eqOfM, 8);
break;
1012 case BDSIntegratorType::g4simpleheum:
1013 integrator =
new G4SimpleHeum(eqOfM, 8);
break;
1014 case BDSIntegratorType::g4simplerunge:
1015 integrator =
new G4SimpleRunge(eqOfM, 8);
break;
1016#if G4VERSION_NUMBER > 1029
1017 case BDSIntegratorType::g4bogackishampine23:
1018 {integrator =
new G4BogackiShampine45(eqOfM, 8);
break;}
1019 case BDSIntegratorType::g4bogackishampine45:
1020 {integrator =
new G4BogackiShampine45(eqOfM, 8);
break;}
1021 case BDSIntegratorType::g4dolomcprirk34:
1022 {integrator =
new G4DoLoMcPriRK34(eqOfM, 8);
break;}
1023 case BDSIntegratorType::g4dormandprince745:
1024 {integrator =
new G4DormandPrince745(eqOfM, 8);
break;}
1025 case BDSIntegratorType::g4dormandprincerk56:
1026 {integrator =
new G4DormandPrinceRK56(eqOfM, 8);
break;}
1027 case BDSIntegratorType::g4tsitourasrk45:
1028 {integrator =
new G4TsitourasRK45(eqOfM, 8);
break;}
1030#if G4VERSION_NUMBER > 1039
1031 case BDSIntegratorType::g4dormandprincerk78:
1032 {integrator =
new G4DormandPrinceRK78(eqOfM, 8);
break;}
1033 case BDSIntegratorType::g4rk547feq1:
1034 {integrator =
new G4RK547FEq1(eqOfM, 8);
break;}
1035 case BDSIntegratorType::g4rk547feq2:
1036 {integrator =
new G4RK547FEq2(eqOfM, 8);
break;}
1037 case BDSIntegratorType::g4rk547feq3:
1038 {integrator =
new G4RK547FEq3(eqOfM, 8);
break;}
1040 case BDSIntegratorType::solenoid:
1041 case BDSIntegratorType::dipolerodrigues:
1042 case BDSIntegratorType::quadrupole:
1043 case BDSIntegratorType::sextupole:
1044 case BDSIntegratorType::octupole:
1045 case BDSIntegratorType::decapole:
1046 case BDSIntegratorType::dipolefringe:
1047 case BDSIntegratorType::g4constrk4:
1048 case BDSIntegratorType::g4exacthelixstepper:
1049 case BDSIntegratorType::g4helixexpliciteuler:
1050 case BDSIntegratorType::g4helixheum:
1051 case BDSIntegratorType::g4heliximpliciteuler:
1052 case BDSIntegratorType::g4helixmixedstepper:
1053 case BDSIntegratorType::g4helixsimplerunge:
1054 case BDSIntegratorType::g4nystromrk4:
1055 case BDSIntegratorType::g4rkg3stepper:
1057 G4cerr <<
"Error: integrator \"" << info.
IntegratorType() <<
"\" is not suitable for an EM field." << G4endl;
1058 G4cout <<
"Suitable integrators are:" << G4endl;
1059 std::vector<BDSIntegratorType> types = {
1060 BDSIntegratorType::g4cashkarprkf45,
1061 BDSIntegratorType::g4classicalrk4,
1062 BDSIntegratorType::g4expliciteuler,
1063 BDSIntegratorType::g4impliciteuler,
1064 BDSIntegratorType::g4simpleheum,
1065 BDSIntegratorType::g4simplerunge
1066#if G4VERSION_NUMBER > 1029
1068 BDSIntegratorType::g4bogackishampine23,
1069 BDSIntegratorType::g4bogackishampine45,
1070 BDSIntegratorType::g4dolomcprirk34,
1071 BDSIntegratorType::g4dormandprince745,
1072 BDSIntegratorType::g4dormandprincerk56,
1073 BDSIntegratorType::g4tsitourasrk45
1075#if G4VERSION_NUMBER > 1039
1077 BDSIntegratorType::g4dormandprincerk78,
1078 BDSIntegratorType::g4rk547feq1,
1079 BDSIntegratorType::g4rk547feq2,
1080 BDSIntegratorType::g4rk547feq3
1083 for (
auto type : types)
1084 {G4cout << type << G4endl;}
1085 throw BDSException(__METHOD_NAME__,
"invalid integrator type");
1094 G4EquationOfMotion* eqOfM)
1102 G4Mag_EqRhs* bEqOfMotion =
new G4Mag_UsualEqRhs(bGlobalField);
1104 G4MagIntegratorStepper* integrator;
1108 if (!mapfile.empty())
1119 bEqOfMotion, integrator);
1120 return completeField;
1126 G4Mag_EqRhs* bEqOfMotion =
new G4Mag_UsualEqRhs(bGlobalField);
1129 bEqOfMotion, integrator);
1130 return completeField;
1139 bEqOfMotion, integrator);
1140 return completeField;
1146 G4Mag_EqRhs* bEqOfMotion =
new G4Mag_UsualEqRhs(bGlobalField);
1149 bEqOfMotion, integrator);
1150 return completeField;
1155 G4double result = 1.0;
1157 {result = (*st)[
"scalingOuter"];}
G4double aper1
Public member for direct access.
General exception with possible name of object and message.
Wrapper class to convert to global coordinates using a navigator for placements.
A base class for electric fields in local to be used in global coordinates.
Two interpolated fields in one. One takes precedence in a subregion.
Class to provide scaling and a base class pointer for interpolator fields.
A base class for electro-magnetic fields in local to be used in global coordinates.
A base class for electro-magnetic fields in local to be used in global coordinates.
Class to provide scaling and a base class pointer for interpolator fields.
Pill box cavity electro-magnetic field.
Null EM field - for special cases where we need a valid object.
Interface for BDSIM electro-magnetic fields that may or may not be local.
virtual void SetTransform(const G4Transform3D &transformIn)
A sinusoidal electric (only) field that doesn't vary with position. Uses cosine.
Null E field - for special cases where we need a valid object.
Interface for BDSIM electric fields that may or may not be local.
virtual void SetTransform(const G4Transform3D &transformIn)
Factory that produces fields and their associated objects.
G4double GetOuterScaling(const BDSMagnetStrength *st) const
Return the parameter "outerScaling" from strength st, but default to 1.
void PrepareFieldDefinitions(const std::vector< GMAD::Field > &definitions, G4double defaultBRho)
Prepare all required definitions that can be used dynamically.
BDSFieldObjects * CreateFieldE(const BDSFieldInfo &info)
Create an electric field.
BDSFieldObjects * CreateFieldIrregular(const BDSFieldInfo &info)
Create an irregular (special) field.
BDSFieldObjects * CreateRMatrix(const BDSFieldInfo &info)
Create special rmatrix 'field' that applies an rmatrix.
void PrepareFieldStrengthFromParameters(BDSMagnetStrength *st, const G4String &fieldParameters, G4double &poleTipRadius) const
static BDSPrimaryGeneratorAction * primaryGeneratorAction
Cache of primary generator action.
BDSFieldE * CreateFieldERaw(const BDSFieldInfo &info)
Creat just the electric field object.
G4double ConvertToDoubleWithException(const G4String &value, const G4String ¶meterNameForError) const
Convert the string 'value' to a double. Throw an exception including the parameterNameForError if it ...
static BDSFieldFactory * Instance()
Public accessor method for singleton pattern.
BDSFieldObjects * CreateField(const BDSFieldInfo &info, const BDSMagnetStrength *scalingStrength=nullptr, const G4String &scalingKey="none")
Main interface to field factory.
BDSFieldObjects * CreateParallelTransport(const BDSFieldInfo &info)
static BDSFieldFactory * instance
Instance - singleton pattern.
BDSFieldInfo * GetDefinition(const G4String &name) const
BDSFieldObjects * CreateCavityFringe(const BDSFieldInfo &info)
Create special rf cavity fringe 'field' that applies an rmatrix.
std::map< G4String, BDSFieldInfo * > parserDefinitions
BDSFieldInfo definitions prepare from parser vector of definitions.
G4MagIntegratorStepper * CreateIntegratorMag(const BDSFieldInfo &info, G4Mag_EqRhs *eqOfM, const BDSMagnetStrength *strength)
G4MagIntegratorStepper * CreateIntegratorE(const BDSFieldInfo &info, G4EquationOfMotion *eqOfM)
BDSFieldObjects * CreateFieldMag(const BDSFieldInfo &info, const BDSMagnetStrength *scalingStrength=nullptr, const G4String &scalingKey="none")
Create a purely magnetic field.
static BDSInterpolatorType DefaultInterpolatorType(G4int numberOfDimensions)
Suggest a default interpolator.
BDSFieldObjects * CreateFieldEM(const BDSFieldInfo &info)
Create a general EM field.
BDSFieldMag * CreateFieldMagRaw(const BDSFieldInfo &info, const BDSMagnetStrength *scalingStrength=nullptr, const G4String &scalingKey="none")
Creat just the magnetic field object.
BDSFieldFactory()
Private default constructor as singleton class.
BDSFieldObjects * CreateTeleporter(const BDSFieldInfo &info)
G4MagIntegratorStepper * CreateIntegratorEM(const BDSFieldInfo &info, G4EquationOfMotion *eqOfM)
static const BDSParticleDefinition * designParticle
Cache of design particle for fields.
All info required to build complete field of any type.
G4String MagneticSubFieldName() const
Accessor.
void UpdateUserLimitsLengthMaximumStepSize(G4double maximumStepSize, G4bool warn=false) const
G4Transform3D TransformComplete() const
Compound transform of field + beam line transform.
G4bool SecondFieldOnLeft() const
Accessor.
G4double PoleTipRadius() const
Accessor.
G4bool ProvideGlobal() const
Accessor.
BDSIntegratorType IntegratorType() const
Accessor.
G4double BeamPipeRadius() const
Accessor.
G4String ElectricSubFieldName() const
Accessor.
G4Transform3D Transform() const
Transform for the field definition only.
G4bool UsePlacementWorldTransform() const
Accessor.
G4double Tilt() const
Accessor.
BDSFieldType FieldType() const
Accessor.
BDSMagnetStrength * MagnetStrength() const
Accessor.
G4double BRho() const
Accessor.
G4Transform3D TransformBeamline() const
Transform from the curvilinear coordinates to the beam line component.
BDSFieldEMInterpolated * LoadEMField(const BDSFieldInfo &info)
Main interface to load an electro-magnetic field.
BDSFieldMagInterpolated * LoadMagField(const BDSFieldInfo &info, const BDSMagnetStrength *scalingStrength=nullptr, const G4String &scalingKey="none")
Main interface to load a magnetic field.
static BDSFieldLoader * Instance()
Singleton accessor.
BDSFieldEInterpolated * LoadEField(const BDSFieldInfo &info)
Main interface to load an electric field.
Class that provides the magnetic strength in a decapole.
A perfect magetic dipole in 3D, normal field inside 1/2 poleTipRadius.
A perfect magetic dipole in 3D, normal field inside 1/2 poleTipRadius.
Class that provides the magnetic strength in a mixed dipole / quadrupole.
A base class for magnetic fields in local to be used in global coordinates.
A base class for magnetic fields in local to be used in global coordinates.
Two interpolated fields in one. One takes precedence in a subregion.
Class to provide scaling and a base class pointer for interpolator fields.
Sum of two multipole fields spaced by a distance in x.
Sum of two multipole fields spaced by a distance in x.
A simple paramaterisation of N-Pole outer yoke magnetic field.
A simple parameterisation of N-Pole outer yoke magnetic field.
Class that provides the magnetic strength in a quadrupole.
Class that provides the magnetic strength in an octupole.
Class that provides the magnetic strength in a quadrupole.
Class that provides the magnetic strength in a sextupole.
A wrapper class for BDSFieldMagSkew where it owns the field.
Class that provides the magnetic field due to a cylinder of current.
Class that provides the magnetic strength in a quadrupole.
Null B field - for special cases where we need a valid object.
Interface for static magnetic fields that may or may not be local.
virtual void SetTransform(const G4Transform3D &transformIn)
A holder for all the Geant4 field related objects.
static BDSGlobalConstants * Instance()
Access method.
Integrator for RF cavity fringes. Only the transverse momentum kicks are applied, this integrator wil...
Integrator for Decapolar field.
Derived fringe field integrator that does normalise to momentum.
Integrator that ignores the field and uses the analytical solution for a dipole kick.
Integrator for combined dipole and quadrupolar field.
Exact helix through pure dipole field.
Stepper that calculates trajectory through uniform magnetic field.
BDSIM 2nd order Euler integration.
Integrator that wraps a G4ClassicalRK4 and below a minimum step size uses a drift.
Integrator for thin h or v kick.
Integrator that ignores the field and uses the analytical solution to a multipole.
Integrator for octupole field.
Integrator that just moves the particle parallel to the s axis.
Integrator that ignores the field and uses the analytical solution to a quadrupole.
Integrator that just moves the particle parallel to the s axis.
Integrator for sextupole field.
Integrator that ignores the field and uses the analytical solution to a solenoid.
Custom unphysical integrator to advance particle in teleporter.
Override G4Mag_UsualEqRhs, provides BDSIM integrators access to particle attributes.
static const G4double beamSeparation
Used in many places - make it a constant in the code and put here as most relevant.
Efficient storage of magnet strengths.
G4bool KeyHasBeenSet(const G4String &key) const
Whether a key has been set.
static G4bool ValidKey(const G4String &key)
Whether or not the supplied key is a valid magnet strength parameter.
static const std::vector< G4String > & AllKeys()
Accessor to all keys.
static G4double Unit(const G4String &key)
Access a unit factor for a given key.
Class to load and use PTC 1 turn map.
static BDSParser * Instance()
Access method.
Wrapper for particle definition.
G4double BRho() const
Accessor.
Generates primary particle vertices using BDSBunch.
void RegisterPTCOneTurnMap(BDSPTCOneTurnMap *otmIn)
type underlying() const
return underlying value (can be used in switch statement)
BDSArrayReflectionTypeSet DetermineArrayReflectionTypeSet(const G4String &arrayReflectionType)
Return a std::set of reflection types. Split string on white space.
BDSInterpolatorType InterpolatorTypeSpecificFromAuto(G4int nDimension, BDSInterpolatorType autoType)
G4bool InterpolatorTypeIsAuto(BDSInterpolatorType typeIn)
Return true if the type is one containing 'auto'.
BDSFieldFormat DetermineFieldFormat(G4String fieldformat)
Function that gives corresponding enum value for string (case-insensitive)
std::pair< G4String, G4String > SplitOnColon(const G4String &formatAndPath)
BDSFieldType DetermineFieldType(G4String fieldType)
Function that gives corresponding enum value for string (case-insensitive)
BDSInterpolatorType DetermineInterpolatorType(G4String interpolatorType)
Function that determines enum from string (case-insensitive).
BDSFieldClassType DetermineFieldClassType(BDSFieldType fieldType)
Function that gives the corresponding enum value for a field type enum.
G4String GetFullPath(G4String filename, bool excludeNameFromPath=false, bool useCWDForPrefix=false)
G4UserLimits * CreateUserLimits(G4UserLimits *defaultUL, G4double length, G4double fraction=1.6)
BDSIntegratorType DetermineIntegratorType(G4String integratorType)
Function that determines enum from string (case-insensitive).
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())
G4int NDimensionsOfInterpolatorType(const BDSInterpolatorType &it)
Report the number of dimensions for that interpolator type.
G4int NDimensionsOfFieldFormat(const BDSFieldFormat &ff)
Report the number of dimensions for that format.
std::map< G4String, G4String > GetUserParametersMap(const G4String &userParameters, char delimiter=':')
Take one long string and split on space and then on colon. "key1:value1 key2:value2" etc.