BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSTunnelFactoryCircular.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 "BDSTunnelFactoryBase.hh"
20#include "BDSTunnelFactoryCircular.hh"
21#include "BDSTunnelInfo.hh"
22#include "BDSTunnelSection.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 "G4UnionSolid.hh"
33#include "G4VSolid.hh"
34
35#include <cmath> // sin, cos, fabs
36#include <set>
37#include <utility> // for std::pair
38
39BDSTunnelFactoryCircular::BDSTunnelFactoryCircular()
40{;}
41
43 G4double length,
44 G4double tunnelThickness,
45 G4double tunnelSoilThickness,
46 G4Material* tunnelMaterial,
47 G4Material* tunnelSoilMaterial,
48 G4bool tunnelFloor,
49 G4double tunnelFloorOffset,
50 G4double tunnel1,
51 G4double /*tunnel2*/,
52 G4bool visible)
53{
54 // tidy up things from previous usage if any - base class method
55 CleanUp();
56
57 // test input parameters - set global options as default if not specified
58 TestInputParameters(length, tunnelThickness, tunnelSoilThickness, tunnelMaterial,
59 tunnelSoilMaterial, tunnelFloorOffset, tunnel1);
60
61 // build the solids
62 tunnelSolid = new G4Tubs(name + "_tunnel_solid", // name
63 tunnel1 + lengthSafety, // inner radius
64 tunnel1 + tunnelThickness, // outer radius
65 length*0.5 - lengthSafety, // z half length
66 0, // start angle
67 CLHEP::twopi); // sweep angle
68
69 G4double soilInnerR = tunnel1 + tunnelThickness + lengthSafety;
70 G4double soilOuterR = soilInnerR + tunnelSoilThickness;
71 soilSolid = new G4Tubs(name + "_soil_solid", // name
72 soilInnerR, // inner radius
73 soilOuterR, // outer radius
74 length*0.5 - lengthSafety, // z half length
75 0, // start angle
76 CLHEP::twopi); // sweep angle
77
78 G4double containerRadius = soilOuterR + lengthSafety;
79
80 // build the floor if necessary
81 if (tunnelFloor)
82 {
83 G4double floorBoxRadius = 1.5*tunnel1; // will definitely encompass the tunnel
84 G4double floorCylinderRadius = tunnel1 - lengthSafety; // so it fits within the tunnel
85 G4double floorBoxDisplacement = tunnelFloorOffset + floorBoxRadius + lengthSafety;
86
87 G4VSolid* floorCylinder = new G4Tubs(name + "_floor_cylinder_solid", // name
88 0, // inner radius
89 floorCylinderRadius, // outer radius
90 length*0.5 - lengthSafety, // z half length
91 0, // start angle
92 CLHEP::twopi); // sweep angle
93
94 G4VSolid* floorBox = new G4Box(name + "_floor_box_solid", // name
95 floorBoxRadius, // x half width
96 floorBoxRadius, // y half width
97 length); // z half length
98 // box z length extra long for unambiguous subtraction
99
100 floorSolid = new G4IntersectionSolid(name + "_floor_solid", // name
101 floorCylinder, // this
102 floorBox, // minus this,
103 0, // rotation matrix
104 G4ThreeVector(0,-floorBoxDisplacement,0)); // translation
105
106 // need to create a container for the tunnel + floor that only just contains it
107 // need to do the same trick again - prepare small floor container segment and union
108 // it with tunnel container. Container has to be a wee bit bigger so can't use the same
109 // solids sadly.
110
111 // floor container cylinder has to definitely overlaps with outside cylinder -> tunnel1*1.1
112 G4VSolid* floorContainerCylinder = new G4Tubs(name + "_floor_cont_cyl_solid", // name
113 0, // inner radius
114 tunnel1*1.1, // outer radius
115 length*0.5, // z half length
116 0, // start angle
117 CLHEP::twopi); // sweep angle
118
119 G4VSolid* floorContainerBox = new G4Box(name + "_floor_cont_box_solid", // name
120 floorBoxRadius, // x half width
121 floorBoxRadius, // y half width
122 length); // z half length
123 // z long for unambiguous intersection
124
125 // calculate box container offset - should be just above floor by lengthsafety (floor actually lowered
126 // by length safety a la rest of geometry to fit within its dimensions)
127 G4double floorBoxContDisp = floorBoxDisplacement - lengthSafety;
128 G4VSolid* floorContainerSolid = new G4IntersectionSolid(name + "_floor_cont_solid", // name
129 floorContainerCylinder, // this
130 floorContainerBox, // minus this,
131 0, // rotation matrix
132 G4ThreeVector(0,-floorBoxContDisp,0));// translation
133
134 G4VSolid* tunnelContainerSolid = new G4Tubs(name + "_tunnel_solid", // name
135 tunnel1, // inner radius
136 containerRadius, // outer radius
137 length*0.5, // z half length
138 0, // start angle
139 CLHEP::twopi); // sweep angle
140
141 containerSolid = new G4UnionSolid(name + "_container_solid", // name
142 tunnelContainerSolid, // this
143 floorContainerSolid); // plus this
144 }
145 else
146 {
147 containerSolid = new G4Tubs(name + "_tunnel_container_solid", // name
148 tunnel1, // inner radius
149 containerRadius, // outer radius,
150 0.5*length, // z half length
151 0, // start angle
152 CLHEP::twopi); // sweep angle
153 }
154
155 CommonConstruction(name, tunnelMaterial, tunnelSoilMaterial, length, containerRadius, containerRadius, visible);
156
157 return tunnelSection;
158}
159
160
162 G4double length,
163 G4ThreeVector inputFace,
164 G4ThreeVector outputFace,
165 G4double tunnelThickness,
166 G4double tunnelSoilThickness,
167 G4Material* tunnelMaterial,
168 G4Material* tunnelSoilMaterial,
169 G4bool tunnelFloor,
170 G4double tunnelFloorOffset,
171 G4double tunnel1,
172 G4double /*tunnel2*/,
173 G4bool visible)
174{
175 // tidy up things from previous usage if any - base class method
176 CleanUp();
177
178 // test input parameters - set global options as default if not specified
179 TestInputParameters(length, tunnelThickness, tunnelSoilThickness, tunnelMaterial,
180 tunnelSoilMaterial, tunnelFloorOffset, tunnel1);
181
182 // build the solids
183 tunnelSolid = new G4CutTubs(name + "_tunnel_solid", // name
184 tunnel1, // inner radius
185 tunnel1 + tunnelThickness, // outer radius
186 length*0.5 - lengthSafety, // z half length
187 0, // start angle
188 CLHEP::twopi, // sweep angle
189 inputFace, // input face normal vector
190 outputFace); // output face normal vector
191
192 G4double soilInnerR = tunnel1 + tunnelThickness + lengthSafety;
193 G4double soilOuterR = soilInnerR + tunnelSoilThickness;
194 soilSolid = new G4CutTubs(name + "_soil_solid", // name
195 soilInnerR, // inner radius
196 soilOuterR, // outer radius
197 length*0.5 - lengthSafety, // z half length
198 0, // start angle
199 CLHEP::twopi, // sweep angle
200 inputFace, // input face normal vector
201 outputFace); // output face normal vector
202
203 G4double containerRadius = soilOuterR + lengthSafety;
204
205 // build the floor if necessary
206 if (tunnelFloor)
207 {
208 // these three lines are a repeat of the same part in the first function (~L211)
209 G4double floorBoxRadius = 1.5*tunnel1; // will definitely encompass the tunnel
210 G4double floorCylinderRadius = tunnel1 - lengthSafety; // so it fits within the tunnel
211 G4double floorBoxDisplacement = tunnelFloorOffset + floorBoxRadius + lengthSafety;
212
213 G4VSolid* floorCylinder = new G4CutTubs(name + "_floor_cylinder_solid", // name
214 0, // inner radius
215 floorCylinderRadius, // outer radius
216 length*0.5 - lengthSafety, // z half length
217 0, // start angle
218 CLHEP::twopi, // sweep angle
219 inputFace, // input face normal vector
220 outputFace); // output face normal vector
221
222 G4VSolid* floorBox = new G4Box(name + "_floor_box_solid", // name
223 floorBoxRadius, // x half width
224 floorBoxRadius, // y half width
225 length); // z half length
226 // z long for unambiguous intersection
227
228 // register solids
229 allSolids.insert(floorCylinder);
230 allSolids.insert(floorBox);
231
232 floorSolid = new G4IntersectionSolid(name + "_floor_solid", // name
233 floorCylinder, // this
234 floorBox, // minus this,
235 0, // rotation matrix
236 G4ThreeVector(0,-floorBoxDisplacement,0)); // translation
237
238 // floor container cylinder has to definitely overlaps with outside cylinder -> tunnel1*1.1
239 G4VSolid* floorContainerCylinder = new G4CutTubs(name + "_floor_cont_cyl_solid", // name
240 0, // inner radius
241 tunnel1*1.1, // outer radius
242 length*0.5, // z half length
243 0, // start angle
244 CLHEP::twopi, // sweep angle
245 inputFace, // input face normal
246 outputFace); // output face normal
247
248 G4VSolid* floorContainerBox = new G4Box(name + "_floor_cont_box_solid", // name
249 1.5*tunnel1, // x half width
250 1.5*tunnel1, // y half width
251 length); // z half length
252 // floor container box z long for unambiguous intersection
253
254 // register solids
255 allSolids.insert(floorContainerCylinder);
256 allSolids.insert(floorContainerBox);
257
258 // calculate box container offset - should be just above floor by lengthsafety (floor actually lowered
259 // by length safety a la rest of geometry to fit within its dimensions)
260 G4double floorBoxContDisp = floorBoxDisplacement - lengthSafety;
261 G4VSolid* floorContainerSolid = new G4IntersectionSolid(name + "_floor_cont_solid", // name
262 floorContainerCylinder, // this
263 floorContainerBox, // minus this,
264 0, // rotation matrix
265 G4ThreeVector(0,-floorBoxContDisp,0));// translation
266
267 G4VSolid* tunnelContainerSolid = new G4CutTubs(name + "_tunnel_solid", // name
268 tunnel1 - lengthSafety, // inner radius
269 containerRadius, // outer radius
270 length*0.5, // z half length
271 0, // start angle
272 CLHEP::twopi, // sweep angle
273 inputFace, // input face normal vector
274 outputFace); // output face normal vector
275
276 // register solids
277 allSolids.insert(floorContainerSolid);
278 allSolids.insert(tunnelContainerSolid);
279
280 containerSolid = new G4UnionSolid(name + "_container_solid", // name
281 tunnelContainerSolid, // this
282 floorContainerSolid); // plus this
283
284 G4VSolid* intersectionSolidCylinder = new G4CutTubs(name + "_int_cyl_solid", // name
285 0, // inner radius
286 tunnel1 - 2*lengthSafety, // outer radius
287 length*0.5, // z half length
288 0, // start angle
289 CLHEP::twopi, // sweep angle
290 inputFace, // input face normal vector
291 outputFace); // output face normal vector
292 allSolids.insert(intersectionSolidCylinder);
293
294 intersectionSolid = new G4SubtractionSolid(name + "_intersection_solid", // name
295 intersectionSolidCylinder, // this
296 floorContainerSolid, // minus this,
297 0, // rotation
298 G4ThreeVector(0,-floorBoxContDisp+lengthSafety,0)); // translation
299 }
300 else
301 {
302 containerSolid = new G4CutTubs(name + "_tunnel_container_solid", // name
303 tunnel1, // inner radius
304 containerRadius, // outer radius,
305 length*0.5, // z half length
306 0, // start angle
307 CLHEP::twopi, // sweep angle
308 inputFace, // input face normal vector
309 outputFace); // output face normal vector
310
311 intersectionSolid = new G4CutTubs(name + "_tunnel_intersection_solid", // name
312 0, // inner radius
313 tunnel1 - 2*lengthSafety, // outer radius
314 length*0.5, // z half length
315 0, // start angle
316 CLHEP::twopi, // sweep angle
317 inputFace, // input face normal vector
318 outputFace); // output face normal vector
319 }
320
321 CommonConstruction(name, tunnelMaterial, tunnelSoilMaterial, length, containerRadius,
322 containerRadius, visible);
323
324 return tunnelSection;
325}
326
329 G4double& tunnelThickness,
330 G4double& tunnelSoilThickness,
331 G4Material*& tunnelMaterial,
332 G4Material*& tunnelSoilMaterial,
333 G4double& tunnelFloorOffset,
334 G4double& tunnel1)
335{
336 CommontTestInputParameters(length, tunnelThickness, tunnelSoilThickness, tunnelMaterial, tunnelSoilMaterial);
337
338 if (tunnelFloorOffset < 1e-10)
339 {tunnelFloorOffset = defaultModel->floorOffset;}
340
341 if (tunnel1 < 1e-10)
342 {tunnel1 = defaultModel->aper1;}
343}
G4double lengthSafety
Cache of global constants variable.
void CommontTestInputParameters(G4double &length, G4double &tunnelThickness, G4double &tunnelSoilThickness, G4Material *&tunnelMaterial, G4Material *&tunnelSoilMaterial)
virtual BDSTunnelSection * CreateTunnelSection(G4String name, G4double length, G4double tunnelThickness, G4double tunnelSoilThickness, G4Material *tunnelMaterial, G4Material *tunnelSoilMaterial, G4bool tunnelFloor, G4double tunnelFloorOffset, G4double tunnel1, G4double tunnel2, G4bool visible)
Create a tunnel section with flat input and output faces.
virtual BDSTunnelSection * CreateTunnelSectionAngled(G4String name, G4double length, G4ThreeVector inputFace, G4ThreeVector outputFace, G4double tunnelThickness, G4double tunnelSoilThickness, G4Material *tunnelMaterial, G4Material *tunnelSoilMaterial, G4bool tunnelFloor, G4double tunnelFloorOffset, G4double tunnel1, G4double tunnel2, G4bool visible)
Create a tunnel section with an angled input and output face.
void TestInputParameters(G4double &length, G4double &tunnelThickness, G4double &tunnelSoilThickness, G4Material *&tunnelMaterial, G4Material *&tunnelSoildMaterial, G4double &tunnelFloorOffset, G4double &tunnel1)
functions below here are private to this particular factory
G4double aper1
Tunnel aperture / shape parameter 1.
Class that represents a section of tunnel.