19#include "BDSBeamPipeFactoryBase.hh"
20#include "BDSBeamPipeFactoryElliptical.hh"
21#include "BDSBeamPipeFactoryRectEllipse.hh"
22#include "BDSBeamPipe.hh"
24#include "BDSException.hh"
25#include "BDSExtent.hh"
26#include "BDSUtilities.hh"
30#include "G4CutTubs.hh"
31#include "G4EllipticalTube.hh"
32#include "G4IntersectionSolid.hh"
33#include "G4LogicalVolume.hh"
34#include "G4SubtractionSolid.hh"
35#include "G4ThreeVector.hh"
38#include "CLHEP/Units/SystemOfUnits.h"
45BDSBeamPipeFactoryRectEllipse::BDSBeamPipeFactoryRectEllipse()
54 G4Material* vacuumMaterialIn,
55 G4double beamPipeThicknessIn,
56 G4Material* beamPipeMaterialIn,
66 if (((aper1In == aper3In) && (aper2In == aper4In)) ||
67 ( (aper3In < aper1In) && (aper4In < aper2In) ) )
71 vacuumMaterialIn, beamPipeThicknessIn, beamPipeMaterialIn);
78 G4VSolid* vacCylSolid =
new G4EllipticalTube(nameIn +
"_vacuum_ellipsoid",
83 G4VSolid* vacRectSolid =
new G4Box(nameIn +
"_vacuum_box",
87 allSolids.insert(vacCylSolid);
88 allSolids.insert(vacRectSolid);
90 vacuumSolid =
new G4IntersectionSolid(nameIn +
"_vacuum_solid",
96 G4VSolid* bpInnerCylSolid =
new G4EllipticalTube(nameIn +
"_pipe_inner_ellipsoid",
101 G4VSolid* bpInnerRectSolid =
new G4Box(nameIn +
"_pipe_inner_box",
106 G4VSolid* bpInnerSolid =
new G4IntersectionSolid(nameIn +
"_pipe_inner_solid",
112 G4VSolid* bpOuterCylSolid =
new G4EllipticalTube(nameIn +
"_pipe_inner_ellipsoid",
113 aper3In + extraWidth,
114 aper4In + extraWidth,
117 G4VSolid* bpOuterRectSolid =
new G4Box(nameIn +
"_pipe_inner_box",
118 aper1In + extraWidth,
119 aper2In + extraWidth,
121 G4VSolid* bpOuterSolid =
new G4IntersectionSolid(nameIn +
"_pipe_inner_solid",
125 allSolids.insert(bpInnerCylSolid);
126 allSolids.insert(bpInnerRectSolid);
127 allSolids.insert(bpInnerSolid);
128 allSolids.insert(bpOuterCylSolid);
129 allSolids.insert(bpOuterRectSolid);
130 allSolids.insert(bpOuterSolid);
133 beamPipeSolid =
new G4SubtractionSolid(nameIn +
"_pipe_solid",
138 G4VSolid* contCylSolid =
new G4EllipticalTube(nameIn +
"_vacuum_ellipsoid",
143 G4VSolid* contRectSolid =
new G4Box(nameIn +
"_vacuum_box",
148 allSolids.insert(contCylSolid);
149 allSolids.insert(contRectSolid);
152 containerSolid =
new G4IntersectionSolid(nameIn +
"_vacuum_solid",
159 CreateContainerSubtractionSolid(nameIn, lengthIn, beamPipeThicknessIn, aper1In, aper2In, aper3In, aper4In);
166 const G4ThreeVector& inputFaceNormalIn,
167 const G4ThreeVector& outputFaceNormalIn,
172 G4Material* vacuumMaterialIn,
173 G4double beamPipeThicknessIn,
174 G4Material* beamPipeMaterialIn,
184 if (((aper1In == aper3In) && (aper2In == aper4In)) ||
185 ( (aper3In < aper1In) && (aper4In < aper2In) ) )
189 aper1In, aper2In, aper3In, aper4In,
190 vacuumMaterialIn, beamPipeThicknessIn, beamPipeMaterialIn);
198 G4double width = std::max(aper1In,aper3In) + beamPipeThicknessIn +
lengthSafetyLarge;
199 G4double height = std::max(aper2In,aper4In) + beamPipeThicknessIn +
lengthSafetyLarge;
203 CreateContainerSubtractionSolid(nameIn, lengthIn, beamPipeThicknessIn, aper1In,
204 aper2In, aper3In, aper4In);
207 lengthIn, width, height);
211 G4Material* vacuumMaterialIn,
212 G4Material* beamPipeMaterialIn,
214 G4double containerWidthIn,
215 G4double containerHeightIn)
218 beamPipeMaterialIn, lengthIn);
235 G4double beamPipeThicknessIn,
236 const G4ThreeVector& inputfaceIn,
237 const G4ThreeVector& outputfaceIn)
247 G4VSolid* vacCylSolid =
new G4EllipticalTube(nameIn +
"_vacuum_ellipsoid",
252 G4VSolid* vacRectSolid =
new G4Box(nameIn +
"_vacuum_box",
255 1.1*angledVolumeLength);
258 G4VSolid* longVacuumSolid =
new G4IntersectionSolid(nameIn +
"_vacuum_long_solid",
263 G4double angledFaceRadius = (std::max(std::max(aper1In,aper2In),std::max(aper3In,aper4In)) + beamPipeThicknessIn) * 1.1;
268 G4VSolid* vacuumAngledSolid =
new G4CutTubs(nameIn +
"_pipe_angled_faces",
277 allSolids.insert(vacCylSolid);
278 allSolids.insert(vacRectSolid);
279 allSolids.insert(longVacuumSolid);
280 allSolids.insert(vacuumAngledSolid);
282 vacuumSolid =
new G4IntersectionSolid(nameIn +
"_vacuum_solid",
290 G4String message =
"beam pipe thickness in element \"" + nameIn
291 +
"\" is thinner than minimum " + std::to_string(
lengthSafetyLarge / CLHEP::mm) +
"mm.";
294 G4VSolid* bpInnerCylSolid =
new G4EllipticalTube(nameIn +
"_pipe_inner_ellipsoid",
299 G4VSolid* bpInnerRectSolid =
new G4Box(nameIn +
"_pipe_inner_box",
302 1.1*angledVolumeLength);
304 G4VSolid* bpInnerSolid =
new G4IntersectionSolid(nameIn +
"_pipe_inner_solid",
311 G4VSolid* bpOuterCylSolid =
new G4EllipticalTube(nameIn +
"_pipe_inner_ellipsoid",
312 aper3In + extraWidth,
313 aper4In + extraWidth,
316 G4VSolid* bpOuterRectSolid =
new G4Box(nameIn +
"_pipe_inner_box",
317 aper1In + extraWidth,
318 aper2In + extraWidth,
319 1.1*angledVolumeLength);
320 G4VSolid* bpOuterSolid =
new G4IntersectionSolid(nameIn +
"_pipe_inner_solid",
324 G4VSolid* longBeamPipeSolid =
new G4SubtractionSolid(nameIn +
"_long_pipe_solid",
328 allSolids.insert(bpInnerCylSolid);
329 allSolids.insert(bpInnerRectSolid);
330 allSolids.insert(bpInnerSolid);
331 allSolids.insert(bpOuterCylSolid);
332 allSolids.insert(bpOuterRectSolid);
333 allSolids.insert(bpOuterSolid);
336 beamPipeSolid =
new G4IntersectionSolid(nameIn +
"_pipe_solid",
342 G4VSolid* contCylSolid =
new G4EllipticalTube(nameIn +
"_vacuum_ellipsoid",
349 G4VSolid* contRectSolid =
new G4Box(nameIn +
"_vacuum_box",
352 1.1*angledVolumeLength);
354 G4VSolid* longContainerSolid =
new G4IntersectionSolid(nameIn +
"_long_container_solid",
358 allSolids.insert(contCylSolid);
359 allSolids.insert(contRectSolid);
360 allSolids.insert(longContainerSolid);
362 containerSolid =
new G4IntersectionSolid(nameIn +
"_container_solid",
367void BDSBeamPipeFactoryRectEllipse::CreateContainerSubtractionSolid(
const G4String& nameIn,
369 G4double& beamPipeThicknessIn,
376 G4VSolid* contSubCylSolid =
new G4EllipticalTube(nameIn +
"_subtraction_ellipsoid",
381 G4VSolid* contSubRectSolid =
new G4Box(nameIn +
"_subtraction_box",
385 allSolids.insert(contSubCylSolid);
386 allSolids.insert(contSubRectSolid);
G4ThreeVector outputFaceNormal
For recording the face normals in the finished pipe component.
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
BDSBeamPipe * BuildBeamPipeAndRegisterVolumes(BDSExtent extent, G4double containerRadius, G4bool containerIsCircular=false)
build beampipe and register logical volumes
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.
Factory for elliptical beam pipes.
virtual BDSBeamPipe * CreateBeamPipe(const G4String &nameIn, G4double lengthIn, G4double aper1=0, G4double aper2=0, G4double aper3=0, G4double aper4=0, G4Material *vacuumMaterialIn=nullptr, G4double beamPipeThicknessIn=0, G4Material *beamPipeMaterialIn=nullptr, const G4String &pointsFileIn="", const G4String &pointsUnitIn="")
create a flat ended beampipe
BDSBeamPipe * CommonFinalConstruction(const G4String &nameIn, G4Material *vacuumMaterialIn, G4Material *beamPipeMaterialIn, G4double lengthIn, G4double widthIn, G4double heightIn)
virtual BDSBeamPipe * CreateBeamPipe(const G4String &nameIn, G4double lengthIn, G4double aper1=0, G4double aper2=0, G4double aper3=0, G4double aper4=0, G4Material *vacuumMaterialIn=nullptr, G4double beamPipeThicknessIn=0, G4Material *beamPipeMaterialIn=nullptr, const G4String &pointsFileIn="", const G4String &pointsUnitIn="")
create a flat ended beampipe
void CreateGeneralAngledSolids(const G4String &nameIn, G4double lengthIn, G4double aper1In, G4double aper2In, G4double aper3In, G4double aper4In, G4double beamPipeThicknessIn, const G4ThreeVector &inputfaceIn, const G4ThreeVector &outputfaceIn)
A holder class for a piece of beam pipe geometry.
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
G4double lengthSafety
Cache of global constants variable.
G4double lengthSafetyLarge
Cache of global constants variable.
G4double CalculateSafeAngledVolumeLength(G4double angleIn, G4double angleOut, G4double length, G4double containerWidth, G4double containerHeight=0)
Calculate safe length of an angled volume so it fills the length of its container.