BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSElement.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSAcceleratorModel.hh"
20#include "BDSDebug.hh"
21#include "BDSExtent.hh"
22#include "BDSElement.hh"
23#include "BDSException.hh"
24#include "BDSGeometryExternal.hh"
25#include "BDSGeometryFactory.hh"
26
27#include "G4String.hh"
28#include "G4Types.hh"
29
30#include <iomanip>
31#include <set>
32#include <vector>
33
34class G4LogicalVolume;
35
36BDSElement::BDSElement(const G4String& nameIn,
37 G4double arcLengthIn,
38 G4double horizontalWidthIn,
39 const G4String& geometryIn,
40 G4double angleIn,
41 std::vector<G4String>* namedVacuumVolumesIn,
42 G4bool autoColourGeometryIn,
43 G4bool markAsCollimatorIn,
44 G4bool stripOuterVolumeIn):
45 BDSAcceleratorComponent(nameIn, arcLengthIn, angleIn, markAsCollimatorIn ? "element-collimator" : "element"),
46 horizontalWidth(horizontalWidthIn),
47 geometryFileName(geometryIn),
48 autoColourGeometry(autoColourGeometryIn),
49 markAsCollimator(markAsCollimatorIn),
50 stripOuterVolume(stripOuterVolumeIn),
51 geometry(nullptr)
52{
53 if (namedVacuumVolumesIn)
54 {namedVacuumVolumes = *namedVacuumVolumesIn;}
55}
56
58{
60 BuildContainerLogicalVolume(); // pure virtual provided by derived class
62 // we purposively don't attach vis attributes to the container here as it would overwrite ones from geometry loading
63}
64
66{
67 // The horizontalWidth here is a suggested horizontalWidth for the factory. Each sub-factory may treat this
68 // differently.
69 BDSSDType sensitivityToAttach = markAsCollimator ? BDSSDType::collimatorcomplete : BDSSDType::energydep;
70 // The field isn't constructed here. It's registered through the base class SetField method in the component
71 // factory and built and attached in the Initialise() method of the base class. However, before Initialise()
72 // is called, the member fieldInfo will be set. We pass it in here to make sure we don't reuse the same
73 // geometry when a different field is required.
75 nullptr, autoColourGeometry,
76 chordLength, horizontalWidth,
77 &namedVacuumVolumes, true,
78 sensitivityToAttach, stripOuterVolume,
80
81 if (!geometry)
82 {throw BDSException(__METHOD_NAME__, "Error loading geometry in component \"" + name + "\"");}
83
84 // We don't register the geometry as a daughter as the geometry factory retains
85 // ownership of the geometry and will clean it up at the end.
86
87 // make the beam pipe container, this object's container
88 containerLogicalVolume = geometry->GetContainerLogicalVolume();
89 containerSolid = geometry->GetContainerSolid();
90 containerAssembly = geometry->GetContainerAssemblyVolume();
92
93 // register named vacuum volumes that have been identified
95
96 if (markAsCollimator)
97 {// label volumes as belonging to a collimator
98 auto collimatorVolumeSet = BDSAcceleratorModel::Instance()->VolumeSet("collimators");
100 {collimatorVolumeSet->insert(vol);}
101 }
102
103 // set placement offset from geom so it's placed correctly in the beam line
105
106 // update extents
108
109 const BDSExtent geomExtent = geometry->GetExtent();
110 BDSExtent nominalExt = BDSExtent(horizontalWidth*0.5, horizontalWidth*0.5, chordLength*0.5);
111 if (nominalExt.TransverselyGreaterThan(geomExtent))
112 {SetExtent(nominalExt);}
113
114 // check extent of geometry as compared to user input length of component in
115 // beam line. If longer (including some numerical tolerance), warn user
116 G4double extLength = GetExtent().DZ();
117 G4double tolerance = 1*CLHEP::micrometer;
118 if ((extLength - chordLength) > tolerance)
119 {
120 auto flagsCache(G4cerr.flags());
121 G4cerr << std::setprecision(15); // precise print out to aid user
122 G4cerr.setf( std::ios::fixed, std:: ios::floatfield );
123 G4cerr << "BDSElement> The loaded geometry is larger than the specified length"
124 << " of the element, which will cause overlaps!" << G4endl
125 << "Calculated extent along z of geometry: " << extLength << " mm" << G4endl;
126 G4cerr << "Arc length " << arcLength << " mm" << G4endl;
127 G4cerr << "Bending angle " << angle << " rad" << G4endl;
128 G4cerr << "Chord length " << chordLength << " mm" << G4endl;
129 G4cerr << "Chord length must be >= geometry length" << G4endl;
130 G4cerr << "Possible overlaps in element \"" << name << "\"" << G4endl << G4endl << G4endl;
131 // we don't force an exit here as our testing might not be exact for angled components
132 // for now, we leave it to the user to ensure this is acceptable
133 //throw BDSException(__METHOD_NAME__, "overlaps in element \"" + name + "\"");
134 G4cerr.flags(flagsCache);
135 }
136}
137
138std::set<G4VPhysicalVolume*> BDSElement::GetAllPhysicalVolumes() const
139{
140 return geometry ? geometry->GetAllPhysicalVolumes() : std::set<G4VPhysicalVolume*>();
141}
142
143std::set<G4RotationMatrix*> BDSElement::GetAllRotationMatrices() const
144{
145 return geometry ? geometry->GetAllRotationMatrices() : std::set<G4RotationMatrix*>();
146}
147
148std::set<G4VisAttributes*> BDSElement::GetAllVisAttributes() const
149{
150 return geometry ? geometry->GetAllVisAttributes() : std::set<G4VisAttributes*>();
151}
152
153std::set<G4UserLimits*> BDSElement::GetAllUserLimits() const
154{
155 return geometry ? geometry->GetAllUserLimits() : std::set<G4UserLimits*>();
156}
157
158std::set<BDSGeometryComponent*> BDSElement::GetAllDaughters() const
159{
160 return geometry ? geometry->GetAllDaughters() : std::set<BDSGeometryComponent*>();
161}
162
163std::set<G4VSolid*> BDSElement::GetAllSolids() const
164{
165 return geometry ? geometry->GetAllSolids() : std::set<G4VSolid*>();
166}
167
168std::set<G4LogicalVolume*> BDSElement::GetAllLogicalVolumes() const
169{
170 return geometry ? geometry->GetAllLogicalVolumes() : std::set<G4LogicalVolume*>();
171}
172
173std::set<G4LogicalVolume*> BDSElement::GetAllBiasingVolumes() const
174{
175 return geometry ? geometry->GetAllBiasingVolumes() : std::set<G4LogicalVolume*>();
176}
177
178std::map<G4LogicalVolume*, BDSSDType> BDSElement::GetAllSensitiveVolumes() const
179{
180 return geometry ? geometry->GetAllSensitiveVolumes() : std::map<G4LogicalVolume*, BDSSDType>();
181}
182
184{
185 if (geometry)
187}
188
190{
192 if (geometry)
194}
Abstract class that represents a component of an accelerator.
G4UserLimits * userLimits
Cache of user limits.
const G4double arcLength
Const protected member variable that may not be changed by derived classes.
void SetAcceleratorVacuumLogicalVolume(G4LogicalVolume *accVacLVIn)
const G4String name
Const protected member variable that may not be changed by derived classes.
G4double angle
Protected member variable that can be modified by derived classes.
virtual std::set< G4LogicalVolume * > GetAcceleratorMaterialLogicalVolumes() const
Return a set of logical volumes excluding the ones in the 'vacuum' set.
virtual void AttachUserLimits() const
Doesn't change member variables, but may change their contents.
G4double chordLength
Protected member variable that can be modified by derived classes.
std::set< G4LogicalVolume * > * VolumeSet(const G4String &name)
Returns pointer to a set of logical volumes. If no set by that name exits, create it.
virtual std::set< BDSGeometryComponent * > GetAllDaughters() const
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:158
virtual std::set< G4VSolid * > GetAllSolids() const
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:163
virtual void ExcludeLogicalVolumeFromBiasing(G4LogicalVolume *lv)
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:183
BDSGeometryExternal * geometry
Cache of the constructed geometry. Used to forward onto various BDSGeometryComponent functions.
Definition: BDSElement.hh:94
virtual std::set< G4LogicalVolume * > GetAllBiasingVolumes() const
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:173
virtual void Build()
Definition: BDSElement.cc:57
virtual void BuildContainerLogicalVolume()
This does the full construction. Loads the external geometry and field if there is one.
Definition: BDSElement.cc:65
virtual std::set< G4UserLimits * > GetAllUserLimits() const
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:153
virtual void AttachSensitiveDetectors()
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:189
virtual std::map< G4LogicalVolume *, BDSSDType > GetAllSensitiveVolumes() const
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:178
virtual std::set< G4LogicalVolume * > GetAllLogicalVolumes() const
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:168
virtual std::set< G4VisAttributes * > GetAllVisAttributes() const
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:148
virtual std::set< G4RotationMatrix * > GetAllRotationMatrices() const
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:143
virtual std::set< G4VPhysicalVolume * > GetAllPhysicalVolumes() const
Overloads of functions in BDSGeometryComponent.
Definition: BDSElement.cc:138
General exception with possible name of object and message.
Definition: BDSException.hh:35
Holder for +- extents in 3 dimensions.
Definition: BDSExtent.hh:39
G4bool TransverselyGreaterThan(const BDSExtent &r) const
Comparison operator for x,y only. Ignores z (length).
Definition: BDSExtent.hh:102
G4double DZ() const
The difference in a dimension.
Definition: BDSExtent.hh:85
virtual std::set< BDSGeometryComponent * > GetAllDaughters() const
Accessor - see member for more info.
G4LogicalVolume * GetContainerLogicalVolume() const
Accessor - see member for more info.
G4bool ContainerIsAssembly() const
Whether the container is an assembly. If not, it's a logical volume.
void InheritExtents(BDSGeometryComponent const *const anotherComponent)
Update the extents of this object with those of another object.
BDSExtent GetExtent() const
Accessor - see member for more info.
void SetPlacementOffset(const G4ThreeVector &offsetIn)
Set the offset from 0,0,0 that the object should ideally be placed in its parent.
G4AssemblyVolume * GetContainerAssemblyVolume() const
Accessor - see member for more info.
virtual std::set< G4RotationMatrix * > GetAllRotationMatrices() const
Accessor - see member for more info.
virtual void AttachSensitiveDetectors()
Attach a sensitive detector class to all registered sensitive volumes in this component.
virtual std::set< G4LogicalVolume * > GetAllBiasingVolumes() const
Return all logical volumes that should be used for biasing minus any that are in the excluded set.
virtual std::set< G4UserLimits * > GetAllUserLimits() const
Accessor - see member for more info.
virtual std::map< G4LogicalVolume *, BDSSDType > GetAllSensitiveVolumes() const
Access all sensitive volumes belonging to this component.
virtual std::set< G4LogicalVolume * > GetAllLogicalVolumes() const
Access all logical volumes belonging to this component.
virtual std::set< G4VisAttributes * > GetAllVisAttributes() const
Accessor - see member for more info.
virtual std::set< G4VSolid * > GetAllSolids() const
Accessor - see member for more info.
G4VSolid * GetContainerSolid() const
Accessor - see member for more info.
G4ThreeVector GetPlacementOffset() const
Accessor - see member for more info.
virtual void ExcludeLogicalVolumeFromBiasing(G4LogicalVolume *lv)
virtual std::set< G4VPhysicalVolume * > GetAllPhysicalVolumes() const
Accessor - see member for more info.
void SetExtent(const BDSExtent &extIn)
Set extent.
G4bool containerIsAssembly
True if the 'container' is really an assembly; false if an LV.
const std::set< G4LogicalVolume * > & VacuumVolumes() const
Access the vacuum volumes.
static BDSGeometryFactory * Instance()
Singleton accessor.
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, G4bool stripOuterVolumeAndMakeAssembly=false, G4UserLimits *userLimitsToAttachToAllLVs=nullptr, G4bool dontReloadGeometry=false)
Improve type-safety of native enum data type in C++.