BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSBeamPipeFactoryCircular.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 "BDSBeamPipeFactoryCircular.hh"
19#include "BDSBeamPipe.hh"
20#include "BDSExtent.hh"
21#include "BDSUtilities.hh"
22
23#include "globals.hh" // geant4 globals / types
24#include "G4CutTubs.hh"
25#include "G4LogicalVolume.hh"
26#include "G4SubtractionSolid.hh"
27#include "G4ThreeVector.hh"
28#include "G4Tubs.hh"
29#include "G4VSolid.hh"
30
31#include <cmath>
32#include <set>
33#include <utility> // for std::pair
34
35BDSBeamPipeFactoryCircular::BDSBeamPipeFactoryCircular()
36{;}
37
39 G4double lengthIn,
40 G4double aper1In,
41 G4double /*aper2In*/,
42 G4double /*aper3In*/,
43 G4double /*aper4In*/,
44 G4Material* vacuumMaterialIn,
45 G4double beamPipeThicknessIn,
46 G4Material* beamPipeMaterialIn,
47 const G4String& /*pointsFileIn*/,
48 const G4String& /*pointsUnitIn*/)
49{
50 // clean up after last usage
51 CleanUp();
52
53 // build the solids
54 vacuumSolid = new G4Tubs(nameIn + "_vacuum_solid", // name
55 0, // inner radius
56 aper1In, // outer radius
57 lengthIn*0.5 - lengthSafety, // half length
58 0, // rotation start angle
59 CLHEP::twopi); // rotation finish angle
60
61 beamPipeSolid = new G4Tubs(nameIn + "_pipe_solid", // name
62 aper1In + lengthSafetyLarge, // inner radius + length safety to avoid overlaps
63 aper1In + lengthSafetyLarge + beamPipeThicknessIn, // outer radius
64 lengthIn*0.5 - lengthSafety, // half length
65 0, // rotation start angle
66 CLHEP::twopi); // rotation finish angle
67
68 G4double containerRadius = aper1In + beamPipeThicknessIn + 2*lengthSafetyLarge;
69 containerSolid = new G4Tubs(nameIn + "_container_solid", // name
70 0, // inner radius
71 containerRadius, // outer radius
72 lengthIn*0.5, // half length
73 0, // rotation start angle
74 CLHEP::twopi); // rotation finish angle
75
76 return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn,
77 lengthIn, containerRadius);
78}
79
81 G4double lengthIn,
82 const G4ThreeVector& inputFaceNormalIn,
83 const G4ThreeVector& outputFaceNormalIn,
84 G4double aper1In,
85 G4double /*aper2In*/,
86 G4double /*aper3In*/,
87 G4double /*aper4In */,
88 G4Material* vacuumMaterialIn,
89 G4double beamPipeThicknessIn,
90 G4Material* beamPipeMaterialIn,
91 const G4String& /*pointsFileIn*/,
92 const G4String& /*pointsUnitIn*/)
93{
94 // clean up after last usage
95 CleanUp();
96 inputFaceNormal = inputFaceNormalIn;
97 outputFaceNormal = outputFaceNormalIn;
98
99 G4double containerRadius = 0;
100 CreateGeneralAngledSolids(nameIn, lengthIn, aper1In, beamPipeThicknessIn,
101 inputFaceNormal, outputFaceNormal, containerRadius);
102
103 return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn,
104 lengthIn, containerRadius);
105}
106
110 G4Material* vacuumMaterialIn,
111 G4Material* beamPipeMaterialIn,
112 G4double lengthIn,
113 G4double containerRadiusIn)
114{
115 // prepare a longer container subtraction solid
116 // doesn't have to be angled as it's only used for transverse subtraction
117 containerSubtractionSolid = new G4Tubs(nameIn + "_container_sub_solid",// name
118 0, // inner radius
119 containerRadiusIn, // outer radius
120 lengthIn*4, // full length for unambiguous subtraction
121 0, // rotation start angle
122 CLHEP::twopi); // rotation finish angle
123
124 BDSBeamPipeFactoryBase::CommonConstruction(nameIn, vacuumMaterialIn,
125 beamPipeMaterialIn, lengthIn);
126
127 // record extents
128 BDSExtent ext = BDSExtent(containerRadiusIn, containerRadiusIn, lengthIn*0.5);
129
130 // true for containerIsCircular - true for this factory
131 return BDSBeamPipeFactoryBase::BuildBeamPipeAndRegisterVolumes(ext, containerRadiusIn, true);
132}
133
137 G4double lengthIn,
138 G4double aper1In,
139 G4double beamPipeThicknessIn,
140 const G4ThreeVector& inputfaceIn,
141 const G4ThreeVector& outputfaceIn,
142 G4double& containerRadius)
143{
144 // long length for unambiguous boolean - ensure no gaps in beam pipe geometry
145 G4double angledVolumeLength = BDS::CalculateSafeAngledVolumeLength(inputfaceIn, outputfaceIn, lengthIn, aper1In);
146
147 G4double extraWidth = lengthSafetyLarge + beamPipeThicknessIn;
148 containerRadius = aper1In + extraWidth + lengthSafetyLarge;
149
150 // check faces of angled container volume don't intersect - if it can be built, remaining angled volumes can be built
151 CheckAngledVolumeCanBeBuilt(lengthIn, inputfaceIn, outputfaceIn, containerRadius, nameIn);
152
153 containerSolid = new G4CutTubs(nameIn + "_container_solid", // name
154 0, // inner radius
155 containerRadius, // outer radius
156 lengthIn*0.5, // half length - no -length safety!
157 0, // rotation start angle
158 CLHEP::twopi, // rotation finish angle
159 inputfaceIn, // input face normal
160 outputfaceIn); // rotation finish angle
161
162 // build the solids
163 vacuumSolid = new G4CutTubs(nameIn + "_vacuum_solid", // name
164 0, // inner radius
165 aper1In, // outer radius
166 lengthIn*0.5 - lengthSafety, // half length
167 0, // rotation start angle
168 CLHEP::twopi, // rotation finish angle
169 inputfaceIn, // input face normal
170 outputfaceIn ); // output face normal
171
172 // beampipesolid created as subtraction since direct G4CutTubs creation
173 // created scattering in sector bends. not really understood but likely
174 // fault in G4CutTubs
175 G4VSolid* inner = new G4CutTubs(nameIn + "_pipe_inner_solid", // name
176 0, // inner radius
177 aper1In + lengthSafetyLarge, // outer radius
178 angledVolumeLength, // long length!
179 0, // rotation start angle
180 CLHEP::twopi, // rotation finish angle
181 inputfaceIn, // input face normal
182 outputfaceIn); // output face normal
183
184 G4VSolid* outer = new G4CutTubs(nameIn + "_pipe_outer_solid", // name
185 0, // inner radius + length safety to avoid overlaps
186 aper1In + extraWidth, // outer radius
187 lengthIn*0.5 - lengthSafety, // half length
188 0, // rotation start angle
189 CLHEP::twopi, // rotation finish angle
190 inputfaceIn, // input face normal
191 outputfaceIn); // output face normal
192 allSolids.insert(inner);
193 allSolids.insert(outer);
194
195 beamPipeSolid = new G4SubtractionSolid(nameIn + "_pipe_solid",
196 outer,
197 inner);
198}
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.
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 beamPipeThicknessIn, const G4ThreeVector &inputfaceIn, const G4ThreeVector &outputfaceIn, G4double &containerRadius)
Pass containerRadius by reference to update.
BDSBeamPipe * CommonFinalConstruction(const G4String &nameIn, G4Material *vacuumMaterialIn, G4Material *beamPipeMaterialIn, G4double lengthIn, G4double containerRadiusIn)
A holder class for a piece of beam pipe geometry.
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:38
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.