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