BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSBeamPipeFactoryBase.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "BDSBeamPipeFactoryBase.hh"
19#include "BDSColours.hh"
20#include "BDSColourFromMaterial.hh"
21#include "BDSDebug.hh"
22#include "BDSException.hh"
23#include "BDSGlobalConstants.hh"
24#include "BDSMaterials.hh"
25#include "BDSSDType.hh"
26#include "BDSUtilities.hh"
27
28#include "globals.hh" // geant4 globals / types
29#include "G4LogicalVolume.hh"
30#include "G4Material.hh"
31#include "G4PVPlacement.hh"
32#include "G4ThreeVector.hh"
33#include "G4UserLimits.hh"
34#include "G4VisAttributes.hh"
35
36#include <limits>
37#include <set>
38
40{
42 sensitiveBeamPipe = g->SensitiveBeamPipe();
43 sensitiveVacuum = g->StoreELossVacuum();
44 storeApertureImpacts = g->StoreApertureImpacts();
45 CleanUpBase(); // non-virtual call in constructor
46}
47
48void BDSBeamPipeFactoryBase::CleanUp()
49{
51}
52
54{
56 vacuumSolid = nullptr;
57 beamPipeSolid = nullptr;
58 containerSolid = nullptr;
60 vacuumLV = nullptr;
61 beamPipeLV = nullptr;
62 containerLV = nullptr;
63 vacuumPV = nullptr;
64 beamPipePV = nullptr;
65
66 inputFaceNormal = G4ThreeVector(0,0,-1);
67 outputFaceNormal = G4ThreeVector(0,0, 1);
68}
69
71 G4Material* vacuumMaterialIn,
72 G4Material* beamPipeMaterialIn,
73 G4double length)
74{
75 allSolids.insert(vacuumSolid);
76 allSolids.insert(beamPipeSolid);
78 BuildLogicalVolumes(nameIn, vacuumMaterialIn, beamPipeMaterialIn);
80 SetVisAttributes(beamPipeMaterialIn, vacuumMaterialIn);
82 SetUserLimits(length);
84 PlaceComponents(nameIn);
85}
86
88 G4Material* vacuumMaterialIn,
89 G4Material* beamPipeMaterialIn)
90{
91 // build the logical volumes
92 vacuumLV = new G4LogicalVolume(vacuumSolid,
93 vacuumMaterialIn,
94 nameIn + "_vacuum_lv");
95
96 beamPipeLV = new G4LogicalVolume(beamPipeSolid,
97 beamPipeMaterialIn,
98 nameIn + "_beampipe_lv");
99
100 G4Material* emptyMaterial = BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->EmptyMaterial());
101 containerLV = new G4LogicalVolume(containerSolid,
102 emptyMaterial,
103 nameIn + "_container_lv");
104 allLogicalVolumes.insert(vacuumLV);
105 allLogicalVolumes.insert(beamPipeLV);
106}
107
108void BDSBeamPipeFactoryBase::SetVisAttributes(G4Material* beamPipeMaterialIn,
109 G4Material* vacuumMaterialIn)
110{
112 G4Colour* c = cfm->GetColourWithDefault(beamPipeMaterialIn, BDSColours::Instance()->GetColour("beampipe"));
113 G4VisAttributes* pipeVisAttr = new G4VisAttributes(*c);
114 pipeVisAttr->SetVisibility(true);
115 pipeVisAttr->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
116 allVisAttributes.insert(pipeVisAttr);
117 beamPipeLV->SetVisAttributes(pipeVisAttr);
118
119 if (vacuumMaterialIn->GetDensity() > (1e-3*CLHEP::gram/CLHEP::cm3))
120 {
121 G4Colour* cv = cfm->GetColour(vacuumMaterialIn);
122 G4VisAttributes* vacVisAttr = new G4VisAttributes(*cv);
123 vacVisAttr->SetVisibility(true);
124 vacVisAttr->SetForceLineSegmentsPerCircle(nSegmentsPerCircle);
125 allVisAttributes.insert(vacVisAttr);
126 vacuumLV->SetVisAttributes(vacVisAttr);
127 }
128 else
129 {vacuumLV->SetVisAttributes(BDSGlobalConstants::Instance()->ContainerVisAttr());}
130
131 containerLV->SetVisAttributes(BDSGlobalConstants::Instance()->ContainerVisAttr());
132}
133
135{
136 auto defaultUL = BDSGlobalConstants::Instance()->DefaultUserLimits();
137 //copy the default and update with the length of the object rather than the default 1m
138 G4UserLimits* ul = BDS::CreateUserLimits(defaultUL, length);
139 if (ul != defaultUL) // if it's not the default register it
140 {allUserLimits.insert(ul);}
141 vacuumLV->SetUserLimits(ul);
142 containerLV->SetUserLimits(ul);
143
144 G4UserLimits* beamPipeUL = ul;
145 if (BDSGlobalConstants::Instance()->BeamPipeIsInfiniteAbsorber())
146 {// new beam pipe user limits, copy from updated default user limits above
147 beamPipeUL = new G4UserLimits(*ul);
148 beamPipeUL->SetUserMinEkine(std::numeric_limits<double>::max());
149 allUserLimits.insert(beamPipeUL);
150 }
151 beamPipeLV->SetUserLimits(beamPipeUL);
152}
153
154void BDSBeamPipeFactoryBase::PlaceComponents(const G4String& nameIn)
155{
156 // PLACEMENT
157 // place the components inside the container
158 // note we don't need the pointer for anything - it's registered upon construction with g4
159 vacuumPV = new G4PVPlacement(nullptr, // no rotation
160 G4ThreeVector(), // position
161 vacuumLV, // lv to be placed
162 nameIn + "_vacuum_pv", // name
163 containerLV, // mother lv to be placed in
164 false, // no boolean operation
165 0, // copy number
166 checkOverlaps); // whether to check overlaps
167
168 beamPipePV = new G4PVPlacement(nullptr, // no rotation
169 G4ThreeVector(), // position
170 beamPipeLV, // lv to be placed
171 nameIn + "_beampipe_pipe_pv", // name
172 containerLV, // mother lv to be placed in
173 false, // no boolean operation
174 0, // copy number
175 checkOverlaps); // whether to check overlaps
176 allPhysicalVolumes.insert(vacuumPV);
177 allPhysicalVolumes.insert(beamPipePV);
178}
179
181 G4double containerRadius,
182 G4bool containerIsCircular)
183{
184 // build the BDSBeamPipe instance and return it
185 BDSBeamPipe* aPipe = new BDSBeamPipe(containerSolid,containerLV,extent,
187 vacuumLV,containerIsCircular,containerRadius,
189
190 // register objects
191 aPipe->RegisterSolid(allSolids);
192 aPipe->RegisterLogicalVolume(allLogicalVolumes); //using geometry component base class method
193 aPipe->RegisterPhysicalVolume(allPhysicalVolumes);
194 if (sensitiveVacuum)
195 {aPipe->RegisterSensitiveVolume(vacuumLV, BDSSDType::energydepvacuum);}
196 if (beamPipeLV)
197 {
198 if (sensitiveBeamPipe && storeApertureImpacts)// in the case of the circular vacuum, there isn't a beampipeLV
199 {aPipe->RegisterSensitiveVolume(beamPipeLV, BDSSDType::aperturecomplete);}
200 else if (storeApertureImpacts)
201 {aPipe->RegisterSensitiveVolume(beamPipeLV, BDSSDType::apertureimpacts);}
202 else
203 {aPipe->RegisterSensitiveVolume(beamPipeLV, BDSSDType::energydep);}
204 }
205 aPipe->RegisterUserLimits(allUserLimits);
206 aPipe->RegisterVisAttributes(allVisAttributes);
207
208 return aPipe;
209}
210
212 const G4ThreeVector &inputface,
213 const G4ThreeVector &outputface,
214 G4double beampipeRadius,
215 const G4String& name)
216{
217 G4bool intersects = BDS::WillIntersect(inputface.angle(), outputface.angle(), beampipeRadius*2, length);
218
219 if (intersects)
220 {throw BDSException(__METHOD_NAME__, "a volume in the \"" + name + "\" beam pipe geometry cannot be constructed as it's angled faces intersect within it's extent");}
221}
G4ThreeVector outputFaceNormal
For recording the face normals in the finished pipe component.
G4bool storeApertureImpacts
Whether to store aperture impacts.
BDSBeamPipeFactoryBase()
base constructor
virtual void BuildLogicalVolumes(const G4String &nameIn, G4Material *vacuumMaterialIn, G4Material *beamPipeMaterialIn)
build logical volumes
virtual void SetVisAttributes(G4Material *beamPipeMaterialIn, G4Material *vacuumMaterialIn)
Set visual attributes.
G4ThreeVector inputFaceNormal
For recording the face normals in the finished pipe component.
void CommonConstruction(const G4String &nameIn, G4Material *vacuumMaterialIn, G4Material *beamPipeMaterialIn, G4double length)
finalise beampipe construction
G4bool sensitiveVacuum
Whether the vacuum will record any energy deposition.
BDSBeamPipe * BuildBeamPipeAndRegisterVolumes(BDSExtent extent, G4double containerRadius, G4bool containerIsCircular=false)
build beampipe and register logical volumes
virtual void PlaceComponents(const G4String &nameIn)
Place volumes.
G4bool sensitiveBeamPipe
Whether the beam pipe will record energy deposition.
static void CheckAngledVolumeCanBeBuilt(G4double length, const G4ThreeVector &inputfaceAngle, const G4ThreeVector &outputfaceAngle, G4double horizontalWidth, const G4String &name)
check if a beam pipe volume with angled faces can be constructed
G4VSolid * containerSubtractionSolid
Longer (in length) version of container solid for unambiguous subtraction.
virtual void SetUserLimits(G4double length)
Set user limits.
A holder class for a piece of beam pipe geometry.
static BDSColourFromMaterial * Instance()
Singleton pattern.
static BDSColours * Instance()
singleton pattern
Definition BDSColours.cc:32
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:38
G4bool checkOverlaps
Cache of global constants variable.
G4int nSegmentsPerCircle
Cache of global constants variable.
virtual void FactoryBaseCleanUp()
Empty containers for next use - factories are never deleted so can't rely on scope.
void RegisterLogicalVolume(G4LogicalVolume *logicalVolume)
void RegisterPhysicalVolume(G4VPhysicalVolume *physicalVolume)
void RegisterUserLimits(G4UserLimits *userLimit)
void RegisterVisAttributes(G4VisAttributes *visAttribute)
void RegisterSolid(G4VSolid *solid)
void RegisterSensitiveVolume(G4LogicalVolume *sensitiveVolume, BDSSDType sensitivityType)
A class that holds global options and constants.
static BDSGlobalConstants * Instance()
Access method.
static BDSMaterials * Instance()
Singleton pattern access.
G4Material * GetMaterial(G4String material) const
Get material by name.
G4bool WillIntersect(const G4ThreeVector &incomingNormal, const G4ThreeVector &outgoingNormal, const G4double &zSeparation, const BDSExtent &incomingExtent, const BDSExtent &outgoingExtent)
G4UserLimits * CreateUserLimits(G4UserLimits *defaultUL, G4double length, G4double fraction=1.6)