19#include "BDSBeamPipe.hh"
20#include "BDSColours.hh"
22#include "BDSException.hh"
23#include "BDSExtent.hh"
24#include "BDSGeometryComponent.hh"
25#include "BDSGeometryExternal.hh"
26#include "BDSGeometryFactory.hh"
27#include "BDSGlobalConstants.hh"
28#include "BDSMagnetOuter.hh"
29#include "BDSMagnetOuterFactory.hh"
30#include "BDSMagnetOuterFactoryBase.hh"
31#include "BDSMagnetOuterFactoryCylindrical.hh"
32#include "BDSMagnetOuterFactoryPolesCircular.hh"
33#include "BDSMagnetOuterFactoryPolesFacet.hh"
34#include "BDSMagnetOuterFactoryPolesFacetCrop.hh"
35#include "BDSMagnetOuterFactoryPolesSquare.hh"
36#include "BDSMagnetOuterFactoryLHCLeft.hh"
37#include "BDSMagnetOuterFactoryLHCRight.hh"
38#include "BDSMagnetOuterFactoryNone.hh"
39#include "BDSMagnetOuterInfo.hh"
40#include "BDSMagnetGeometryType.hh"
41#include "BDSMaterials.hh"
42#include "BDSWarning.hh"
46#include "G4CutTubs.hh"
47#include "G4LogicalVolume.hh"
48#include "G4ThreeVector.hh"
64BDSMagnetOuterFactory::BDSMagnetOuterFactory()
78BDSMagnetOuterFactory::~BDSMagnetOuterFactory()
95 case BDSMagnetGeometryType::none:
97 case BDSMagnetGeometryType::cylindrical:
99 case BDSMagnetGeometryType::polescircular:
101 case BDSMagnetGeometryType::polessquare:
103 case BDSMagnetGeometryType::polesfacet:
105 case BDSMagnetGeometryType::polesfacetcrop:
107 case BDSMagnetGeometryType::lhcleft:
109 case BDSMagnetGeometryType::lhcright:
111 case BDSMagnetGeometryType::external:
112 {
return nullptr;
break;}
115 throw BDSException(__METHOD_NAME__,
"unknown type \"" + magnetTypeIn.ToString() +
"\"");
123 G4double outerLength,
124 G4double containerLength,
129 G4String name = outerInfo->name;
132 if (geometryType == BDSMagnetGeometryType::external)
134 outer =
CreateExternal(name, outerInfo, outerLength, containerLength, beamPipe);
136 if (loadedLength > outerLength)
138 BDS::Warning(__METHOD_NAME__,
"External geometry of length " + std::to_string(loadedLength/CLHEP::m)
139 +
"m\nappears to be too long for magnet of length " + std::to_string(outerLength/CLHEP::m) +
"m. ");
145 if (geometryType != BDSMagnetGeometryType::none)
146 {CheckOuterBiggerThanBeamPipe(name, outerInfo, beamPipe);}
152 case BDSMagnetType::decapole:
154 outer = factory->
CreateDecapole(name, outerLength, beamPipe, containerLength, outerInfo);
157 case BDSMagnetType::vkicker:
159 outer = factory->
CreateKicker(name, outerLength, beamPipe, containerLength, outerInfo,
true);
162 case BDSMagnetType::hkicker:
164 outer = factory->
CreateKicker(name, outerLength, beamPipe, containerLength, outerInfo,
false);
167 case BDSMagnetType::muonspoiler:
169 outer = factory->
CreateMuonSpoiler(name, outerLength, beamPipe, containerLength, outerInfo);
172 case BDSMagnetType::octupole:
174 outer = factory->
CreateOctupole(name, outerLength, beamPipe, containerLength, outerInfo);
177 case BDSMagnetType::quadrupole:
179 outer = factory->
CreateQuadrupole(name, outerLength, beamPipe, containerLength, outerInfo);
182 case BDSMagnetType::rfcavity:
184 outer = factory->
CreateRfCavity(name, outerLength, beamPipe, containerLength, outerInfo);
187 case BDSMagnetType::sectorbend:
190 containerLength, outerInfo);
193 case BDSMagnetType::rectangularbend:
196 containerLength, outerInfo);
199 case BDSMagnetType::sextupole:
201 outer = factory->
CreateSextupole(name, outerLength, beamPipe, containerLength, outerInfo);
204 case BDSMagnetType::solenoid:
206 outer = factory->
CreateSolenoid(name, outerLength, beamPipe, containerLength, outerInfo);
209 case BDSMagnetType::multipole:
211 outer = factory->
CreateMultipole(name, outerLength, beamPipe, containerLength, outerInfo);
214 case BDSMagnetType::thinmultipole:
215 case BDSMagnetType::dipolefringe:
216 case BDSMagnetType::undulator:
217 case BDSMagnetType::rmatrix:
218 case BDSMagnetType::paralleltransporter:
221 G4cout << __METHOD_NAME__ <<
"unknown magnet type " << magnetType <<
" - no outer volume built" << G4endl;
230 G4double magnetContainerLength,
233 std::map<G4String, G4Colour*> defaultMap = {
243 info->geometryTypeAndPath,
255 std::stringstream ss, ss2, ss3;
256 ss << info->geometryTypeAndPath;
259 std::string sss = ss.str();
260 sss +=
" will not fit around beam pipe\nin element \"" + name +
"\" and could potentially overlap with it\n";
261 sss +=
"Determined extents to be:\n";
262 sss +=
"External geometry inner: " + ss2.str() +
"\n";
263 sss +=
"Beam pipe outer : " + ss3.str() +
"\n";
264 sss +=
"Check for overlaps with /geometry/test/run";
265 BDS::Warning(__METHOD_NAME__, sss);
283 G4VSolid* containerSolid;
285 if ((inputFace.z() > -1) || (outputFace.z() < 1))
287 G4double posR = std::hypot(outer.
XPos(),outer.
YPos());
288 G4double negR = std::hypot(outer.
XNeg(),outer.
YNeg());
289 G4double magnetContainerRadius = std::max(posR, negR) + 1*CLHEP::mm;
290 containerSolid =
new G4CutTubs(name +
"_container_solid",
292 magnetContainerRadius,
298 containerExt =
BDSExtent(magnetContainerRadius, magnetContainerRadius, 0.5*length);
303 containerSolid =
new G4Box(name +
"_container_solid",
307 containerExt =
BDSExtent(radius, radius, length*0.5);
311 G4LogicalVolume* containerLV =
new G4LogicalVolume(containerSolid,
313 name +
"_container_lv");
324void BDSMagnetOuterFactory::CheckOuterBiggerThanBeamPipe(
const G4String& name,
328 G4double outerHorizontal = outerInfo->horizontalWidth;
329 G4double outerVertical = outerInfo->horizontalWidth * outerInfo->vhRatio;
335 if (outerHorizontal < bpExtent.
DX()+margin || outerVertical < bpExtent.
DY()+margin)
337 std::string msg =
"Magnet outer dimensions too small to encompass beam pipe for element " + name +
"\n";
338 msg +=
"magnet horizontal full width -> " + std::to_string(outerHorizontal) +
"mm\n";
339 msg +=
"magnet vertical full width -> " + std::to_string(outerVertical) +
"mm\n";
340 msg +=
"Beam pipe width (mm): " + std::to_string(bpExtent.
DX()) +
", height : ";
341 msg += std::to_string(bpExtent.
DY());
A holder class for a piece of beam pipe geometry.
G4ThreeVector InputFaceNormal() const
Accessor.
G4ThreeVector OutputFaceNormal() const
Accessor.
static BDSColours * Instance()
singleton pattern
G4Colour * GetColour(const G4String &type, G4bool normaliseTo255=true)
Get colour from name.
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
G4double XPos() const
Accessor.
G4double MaximumAbsTransverse() const
Return the maximum absolute value considering only x,y.
G4double XNeg() const
Accessor.
G4double DZ() const
The difference in a dimension.
G4double YNeg() const
Accessor.
G4double DX() const
The difference in a dimension.
G4double DY() const
The difference in a dimension.
G4bool TransverselyLessThan(const BDSExtent &r) const
Comparison operator for x,y only. Ignores z (length).
G4double YPos() const
Accessor.
A generic geometry component for a bdsim model.
BDSExtent GetExtent() const
Accessor - see member for more info.
BDSExtent GetInnerExtent() const
Accessor - see member for more info.
A loaded piece of externally provided geometry.
BDSGeometryExternal * BuildGeometry(G4String componentName, const G4String &formatAndFilePath, std::map< G4String, G4Colour * > *colourMapping=nullptr, G4bool autoColour=true, G4double suggestedLength=0, G4double suggestedHorizontalWidth=0, std::vector< G4String > *namedVacuumVolumes=nullptr, G4bool makeSensitive=true, BDSSDType sensitivityType=BDSSDType::energydep, BDSSDType vacuumSensitivityType=BDSSDType::energydepvacuum, G4bool stripOuterVolumeAndMakeAssembly=false, G4UserLimits *userLimitsToAttachToAllLVs=nullptr, G4bool dontReloadGeometry=false)
static BDSGeometryFactory * Instance()
Singleton accessor.
static BDSGlobalConstants * Instance()
Access method.
Abstract base class for magnet outer volume factories.
virtual BDSMagnetOuter * CreateQuadrupole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
quadrupole outer volume
virtual BDSMagnetOuter * CreateSolenoid(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
solenoid outer volume
virtual BDSMagnetOuter * CreateKicker(G4String name, G4double length, const BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe, G4bool vertical)=0
horizontal and vertical kicker outer volume
virtual BDSMagnetOuter * CreateRectangularBend(G4String name, G4double length, const BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
rectangular bend outer volume
virtual BDSMagnetOuter * CreateDecapole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
decapole outer volume
virtual BDSMagnetOuter * CreateSectorBend(G4String name, G4double length, const BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
sector bend outer volume
virtual BDSMagnetOuter * CreateMuonSpoiler(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
muon spoiler outer volume
virtual BDSMagnetOuter * CreateMultipole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
general multipole outer volume - could be any 2N order multipole
virtual BDSMagnetOuter * CreateOctupole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
octupole outer volume
virtual BDSMagnetOuter * CreateRfCavity(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
RF cavity outer volume.
virtual BDSMagnetOuter * CreateSextupole(G4String name, G4double length, BDSBeamPipe *beamPipe, G4double containerLength, const BDSMagnetOuterInfo *recipe)=0
sextupole outer volume
Factory that produces cylindrical magnet geometry.
LHC outer magnet geometry offset to the left.
LHC outer magnet geometry offset to the right.
Factory that produces null outer geometry.
Factory class for outer volume of magnets. Produces magnets with 2N-poles around the beampipe with a ...
Factory class for outer volume of magnets.
Factory class for outer volume of magnets.
Factory class for outer volume of magnets.
The main interface for using the magnet outer factories.
static BDSMagnetOuterFactory * Instance()
Singleton accessor.
BDSMagnetOuterFactoryBase * lhcleft
Factory instance.
BDSMagnetOuterFactoryBase * polesfacetcrop
Factory instance.
BDSMagnetOuterFactoryBase * lhcright
Factory instance.
static BDSMagnetOuterFactory * instance
Singleton instance.
BDSGeometryComponent * CreateContainerForExternal(const G4String &name, G4double length, BDSGeometryExternal *external, BDSBeamPipe *beampipe)
BDSMagnetOuter * CreateExternal(const G4String &name, BDSMagnetOuterInfo *info, G4double length, G4double magnetContainerLength, BDSBeamPipe *beampipe)
BDSMagnetOuterFactoryBase * cylindrical
Factory instance.
BDSMagnetOuterFactoryBase * polessquare
Factory instance.
BDSMagnetOuter * CreateMagnetOuter(BDSMagnetType magnetType, BDSMagnetOuterInfo *outerInfo, G4double outerLength, G4double chordLength, BDSBeamPipe *beampipe)
G4double lengthSafetyLarge
BDSMagnetOuterFactoryBase * polescircular
Factory instance.
BDSMagnetOuterFactoryBase * GetAppropriateFactory(BDSMagnetGeometryType magnetTypeIn)
Get the appropriate derived factory for the required magnet style.
G4bool sensitiveOuter
Cache of global option.
BDSMagnetOuterFactoryBase * none
Factory instance.
BDSMagnetOuterFactoryBase * polesfacet
Factory instance.
Holder struct of all information required to create the outer geometry of a magnet.
An object for both the returned magnet outer body but also a tight fitting container for the whole ma...
static BDSMaterials * Instance()
Singleton pattern access.
G4Material * GetMaterial(G4String material) const
Get material by name.
type underlying() const
return underlying value (can be used in switch statement)