BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSBeamPipeFactoryLHC.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 "BDSBeamPipeFactoryBase.hh"
20#include "BDSBeamPipeFactoryLHC.hh"
21#include "BDSBeamPipe.hh"
22#include "BDSExtent.hh"
23
24#include "globals.hh" // geant4 globals / types
25#include "G4Box.hh"
26#include "G4CutTubs.hh"
27#include "G4IntersectionSolid.hh"
28#include "G4LogicalVolume.hh"
29#include "G4SubtractionSolid.hh"
30#include "G4ThreeVector.hh"
31#include "G4Tubs.hh"
32#include "G4VSolid.hh"
33
34#include <cmath>
35#include <set>
36#include <utility> // for std::pair
37
38BDSBeamPipeFactoryLHC::BDSBeamPipeFactoryLHC()
39{;}
40
42 G4double lengthIn,
43 G4double aper1In,
44 G4double aper2In,
45 G4double aper3In,
46 G4double /*aper4In*/,
47 G4Material* vacuumMaterialIn,
48 G4double beamPipeThicknessIn,
49 G4Material* beamPipeMaterialIn,
50 const G4String& /*pointsFileIn*/,
51 const G4String& /*pointsUnitIn*/)
52{
53 // clean up after last usage
54 CleanUp();
55
56 // build the solids
57 //vacuum cylindrical solid (circular cross-section)
58 G4VSolid* vacCylSolid = new G4Tubs(nameIn + "_vacuum_cylinder", // name
59 0, // inner radius
60 aper3In, // outer radius
61 lengthIn*0.5-lengthSafety, // half length
62 0, // rotation start angle
63 CLHEP::twopi); // rotation finish angle
64 //vacuum box solid (rectangular cross-section)
65 G4VSolid* vacRectSolid = new G4Box(nameIn + "_vacuum_box", // name
66 aper1In, // x half width
67 aper2In, // y half width
68 lengthIn); // z full width (long for unambiguous intersection)
69 allSolids.insert(vacCylSolid);
70 allSolids.insert(vacRectSolid);
71 //intersection of both of these gives the desired shape
72 vacuumSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid", // name
73 vacCylSolid, // solid 1
74 vacRectSolid); // solid 2
75
76 //beampipe cylindrical solid (circular cross-section)
77 //beampipe inner edge for subtraction (actually just like vacuum + lengthSafety)x
78 G4VSolid* bpInnerCylSolid = new G4Tubs(nameIn + "_pipe_inner_cylinder", // name
79 0, // inner radius
80 aper3In + lengthSafetyLarge, // outer radius
81 1.5*lengthIn, // length big for unambiguous subtraction (but < outerlength)
82 0, // rotation start angle
83 CLHEP::twopi); // rotation finish angle
84 //beampipe inner edge box solid (rectangular cross-section)
85 G4VSolid* bpInnerRectSolid = new G4Box(nameIn + "_pipe_inner_box", // name
86 aper1In + lengthSafetyLarge,// x half width
87 aper2In + lengthSafetyLarge,// y half width
88 1.7*lengthIn); // z long for unambiguous intersection
89 //beampipe inner intersection - 1.5*length long which is > half length for unambiguous subtraction later
90 G4VSolid* bpInnerSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", // name
91 bpInnerCylSolid, // solid 1
92 bpInnerRectSolid); // solid 2
93
94 //beampipe outer edge for subtraction (actually just like vacuum + lengthSafety)
95 G4double extraWidth = lengthSafetyLarge + beamPipeThicknessIn;
96 G4VSolid* bpOuterCylSolid = new G4Tubs(nameIn + "_pipe_inner_cylinder", // name
97 0, // inner radius (0 for unambiguous subtraction)
98 aper3In + extraWidth, // outer radius
99 (lengthIn*0.5)-lengthSafety, // half length
100 0, // rotation start angle
101 CLHEP::twopi); // rotation finish angle
102 //beampipe outer edge box solid (rectangular cross-section)
103 G4VSolid* bpOuterRectSolid = new G4Box(nameIn + "_pipe_inner_box", // name
104 aper1In + extraWidth, // x half width
105 aper2In + extraWidth, // y half width
106 lengthIn); // z full width (long for unambiguous intersection)
107 G4VSolid* bpOuterSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", // name
108 bpOuterCylSolid, // solid 1
109 bpOuterRectSolid); // solid 2
110 allSolids.insert(bpInnerCylSolid);
111 allSolids.insert(bpInnerRectSolid);
112 allSolids.insert(bpInnerSolid);
113 allSolids.insert(bpOuterCylSolid);
114 allSolids.insert(bpOuterRectSolid);
115 allSolids.insert(bpOuterSolid);
116
117 beamPipeSolid = new G4SubtractionSolid(nameIn + "_pipe_solid", // name
118 bpOuterSolid, // this
119 bpInnerSolid); // minus this
120
121 //container cylindrical solid (circular cross-section)
122 G4VSolid* contCylSolid = new G4Tubs(nameIn + "_vacuum_cylinder", // name
123 0, // inner radius
124 aper3In + extraWidth + lengthSafetyLarge, // outer radius
125 lengthIn*0.5, // half length
126 0, // rotation start angle
127 CLHEP::twopi); // rotation finish angle
128 //vacuum box solid (rectangular cross-section)
129 G4VSolid* contRectSolid = new G4Box(nameIn + "_vacuum_box", // name
130 aper1In + extraWidth + lengthSafetyLarge, // x half width
131 aper2In + extraWidth + lengthSafetyLarge, // y half width
132 lengthIn); // z full width (long for unambiguous intersection)
133
134 allSolids.insert(contCylSolid);
135 allSolids.insert(contRectSolid);
136 //intersection of both of these gives the desired shape
137 containerSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid", // name
138 contCylSolid, // solid 1
139 contRectSolid); // solid 2
140
141 G4double width = aper3In + extraWidth + lengthSafetyLarge;
142 G4double height = aper2In + extraWidth + lengthSafetyLarge;
143
144 CreateContainerSubtractionSolid(nameIn, lengthIn, beamPipeThicknessIn, aper1In, aper2In, aper3In);
145
146 return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn, lengthIn, width, height);
147}
148
150 G4double lengthIn,
151 const G4ThreeVector& inputFaceNormalIn,
152 const G4ThreeVector& outputFaceNormalIn,
153 G4double aper1In,
154 G4double aper2In,
155 G4double aper3In,
156 G4double /*aper4In*/,
157 G4Material* vacuumMaterialIn,
158 G4double beamPipeThicknessIn,
159 G4Material* beamPipeMaterialIn,
160 const G4String& /*pointsFileIn*/,
161 const G4String& /*pointsUnitIn*/)
162{
163 // clean up after last usage
164 CleanUp();
165
166 inputFaceNormal = inputFaceNormalIn;
167 outputFaceNormal = outputFaceNormalIn;
168
169 G4double width = aper3In + beamPipeThicknessIn + 2*lengthSafetyLarge;
170 G4double height = aper2In + beamPipeThicknessIn + 2*lengthSafetyLarge;
171
172 CreateGeneralAngledSolids(nameIn, lengthIn, aper1In, aper2In, aper3In, beamPipeThicknessIn,
174 CreateContainerSubtractionSolid(nameIn, lengthIn, beamPipeThicknessIn,
175 aper1In, aper2In, aper3In);
176
177 return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn,
178 lengthIn, width, height);
179}
180
182 G4Material* vacuumMaterialIn,
183 G4Material* beamPipeMaterialIn,
184 G4double lengthIn,
185 G4double containerWidthIn,
186 G4double containerHeightIn)
187{
188 BDSBeamPipeFactoryBase::CommonConstruction(nameIn, vacuumMaterialIn,
189 beamPipeMaterialIn, lengthIn);
190
191 // record extents
192 BDSExtent ext = BDSExtent(containerWidthIn, containerHeightIn, lengthIn*0.5);
193
194 // build the BDSBeamPipe instance and return it
195 return BuildBeamPipeAndRegisterVolumes(ext, containerWidthIn);
196}
197
198
202 G4double lengthIn,
203 G4double aper1In,
204 G4double aper2In,
205 G4double aper3In,
206 G4double beamPipeThicknessIn,
207 const G4ThreeVector& inputfaceIn,
208 const G4ThreeVector& outputfaceIn)
209{
210 // build the solids
211 //vacuum cylindrical solid (circular cross-section)
212 G4VSolid* vacCylSolid = new G4CutTubs(nameIn + "_vacuum_cylinder", // name
213 0, // inner radius
214 aper3In, // outer radius
215 lengthIn*0.5-lengthSafety, // half length
216 0, // rotation start angle
217 CLHEP::twopi, // rotation finish angle
218 inputfaceIn, // input face normal
219 outputfaceIn); // output face normal
220 //vacuum box solid (rectangular cross-section)
221 G4VSolid* vacRectSolid = new G4Box(nameIn + "_vacuum_box", // name
222 aper1In, // x half width
223 aper2In, // y half width
224 lengthIn); // z full width (long for unambiguous intersection)
225 allSolids.insert(vacCylSolid);
226 allSolids.insert(vacRectSolid);
227 //intersection of both of these gives the desired shape
228 vacuumSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid", // name
229 vacCylSolid, // solid 1
230 vacRectSolid); // solid 2
231
232 //beampipe cylindrical solid (circular cross-section)
233 //beampipe inner edge for subtraction (actually just like vacuum + lengthSafety)x
234 G4VSolid* bpInnerCylSolid = new G4CutTubs(nameIn + "_pipe_inner_cylinder", // name
235 0, // inner radius
236 aper3In + lengthSafetyLarge, // outer radius
237 1.5*lengthIn, // length big for unambiguous subtraction (but < outerlength)
238 0, // rotation start angle
239 CLHEP::twopi, // rotation finish angle
240 inputfaceIn, // input face normal
241 outputfaceIn); // output face normal
242
243 //beampipe inner edge box solid (rectangular cross-section)
244 G4VSolid* bpInnerRectSolid = new G4Box(nameIn + "_pipe_inner_box", // name
245 aper1In + lengthSafetyLarge,// x half width
246 aper2In + lengthSafetyLarge,// y half width
247 1.7*lengthIn); // z long for unambiguous intersection
248 //beampipe inner intersection - 1.5*length long which is > half length for unambiguous subtraction later
249 G4VSolid* bpInnerSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", // name
250 bpInnerCylSolid, // solid 1
251 bpInnerRectSolid); // solid 2
252
253 //beampipe outer edge for subtraction (actually just like vacuum + lengthSafety)
254 G4double extraWidth = lengthSafetyLarge + beamPipeThicknessIn;
255 G4VSolid* bpOuterCylSolid = new G4CutTubs(nameIn + "_pipe_inner_cylinder", // name
256 0, // inner radius (0 for unambiguous subtraction)
257 aper3In + extraWidth, // outer radius
258 (lengthIn*0.5)-lengthSafety, // half length
259 0, // rotation start angle
260 CLHEP::twopi, // rotation finish angle
261 inputfaceIn, // input face normal
262 outputfaceIn); // output face normal
263
264 //beampipe outer edge box solid (rectangular cross-section)
265 G4VSolid* bpOuterRectSolid = new G4Box(nameIn + "_pipe_inner_box", // name
266 aper1In + beamPipeThicknessIn, // x half width
267 aper2In + beamPipeThicknessIn, // y half width
268 lengthIn); // z full width (long for unambiguous intersection)
269 G4VSolid* bpOuterSolid = new G4IntersectionSolid(nameIn + "_pipe_inner_solid", // name
270 bpOuterCylSolid, // solid 1
271 bpOuterRectSolid); // solid 2
272
273 allSolids.insert(bpInnerCylSolid);
274 allSolids.insert(bpInnerRectSolid);
275 allSolids.insert(bpInnerSolid);
276 allSolids.insert(bpOuterCylSolid);
277 allSolids.insert(bpOuterRectSolid);
278 allSolids.insert(bpOuterSolid);
279
280 beamPipeSolid = new G4SubtractionSolid(nameIn + "_pipe_solid", // name
281 bpOuterSolid, // this
282 bpInnerSolid); // minus this
283
284 //container cylindrical solid (circular cross-section)
285 G4VSolid* contCylSolid = new G4CutTubs(nameIn + "_vacuum_cylinder", // name
286 0, // inner radius
287 aper3In + extraWidth + lengthSafetyLarge, // outer radius
288 lengthIn*0.5, // half length
289 0, // rotation start angle
290 CLHEP::twopi, // rotation finish angle
291 inputfaceIn, // input face normal
292 outputfaceIn); // output face normal
293
294 //vacuum box solid (rectangular cross-section)
295 G4VSolid* contRectSolid = new G4Box(nameIn + "_vacuum_box", // name
296 aper1In + beamPipeThicknessIn + lengthSafety, // x half width
297 aper2In + beamPipeThicknessIn + lengthSafety, // y half width
298 lengthIn); // z full width (long for unambiguous intersection)
299
300 allSolids.insert(contCylSolid);
301 allSolids.insert(contRectSolid);
302 //intersection of both of these gives the desired shape
303 containerSolid = new G4IntersectionSolid(nameIn + "_vacuum_solid", // name
304 contCylSolid, // solid 1
305 contRectSolid); // solid 2
306}
307
309 G4double& lengthIn,
310 G4double& beamPipeThicknessIn,
311 G4double& aper1In,
312 G4double& aper2In,
313 G4double& aper3In)
314{
315 //container cylindrical solid (circular cross-section)
316 G4VSolid* contSubCylSolid = new G4Tubs(nameIn + "_subtraction_cylinder", // name
317 0, // inner radius
318 aper3In + beamPipeThicknessIn + 2*lengthSafetyLarge, // outer radius
319 2*lengthIn, // long length for unambiguous subtraction
320 0, // rotation start angle
321 CLHEP::twopi); // rotation finish angle
322 //vacuum box solid (rectangular cross-section)
323 G4VSolid* contSubRectSolid = new G4Box(nameIn + "_subtraction_box", // name
324 aper1In + beamPipeThicknessIn + 2*lengthSafetyLarge, // x half width
325 aper2In + beamPipeThicknessIn + 2*lengthSafetyLarge, // y half width
326 1.7*lengthIn); // z full width (long for unambiguous intersection)
327 allSolids.insert(contSubCylSolid);
328 allSolids.insert(contSubRectSolid);
329 //intersection of both of these gives the desired shape
330 containerSubtractionSolid = new G4IntersectionSolid(nameIn + "_subtraction_solid", // name
331 contSubCylSolid, // solid 1
332 contSubRectSolid); // solid 2
333}
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
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
BDSBeamPipe * CommonFinalConstruction(const G4String &nameIn, G4Material *vacuumMaterialIn, G4Material *beamPipeMaterialIn, G4double lengthIn, G4double widthIn, G4double heightIn)
void CreateContainerSubtractionSolid(const G4String &nameIn, G4double &lengthIn, G4double &beamPipeThicknessIn, G4double &aper1In, G4double &aper2In, G4double &aper3In)
function to create the container subtraction solid and avoid passing aper1,2,3 around further
void CreateGeneralAngledSolids(const G4String &nameIn, G4double lengthIn, G4double aper1In, G4double aper2In, G4double aper3In, G4double beamPipeThicknessIn, const G4ThreeVector &inputfaceIn, const G4ThreeVector &outputfaceIn)
A holder class for a piece of beam pipe geometry.
Definition: BDSBeamPipe.hh:45
Holder for +- extents in 3 dimensions.
Definition: BDSExtent.hh:39
G4double lengthSafety
Cache of global constants variable.
G4double lengthSafetyLarge
Cache of global constants variable.