BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSTunnelFactoryRectangular.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 "BDSTunnelFactoryRectangular.hh"
21#include "BDSTunnelInfo.hh"
22
23#include "globals.hh" // geant4 globals / types
24#include "G4Box.hh"
25#include "G4CutTubs.hh"
26#include "G4IntersectionSolid.hh"
27#include "G4LogicalVolume.hh"
28#include "G4SubtractionSolid.hh"
29#include "G4ThreeVector.hh"
30#include "G4VSolid.hh"
31
32#include <cmath> // sin, cos, fabs
33#include <set>
34#include <utility> // for std::pair
35
36class G4Material;
37
38BDSTunnelFactoryRectangular::BDSTunnelFactoryRectangular()
39{;}
40
42 G4double length,
43 G4double tunnelThickness,
44 G4double tunnelSoilThickness,
45 G4Material* tunnelMaterial,
46 G4Material* tunnelSoilMaterial,
47 G4bool tunnelFloor,
48 G4double tunnelFloorOffset,
49 G4double tunnel1,
50 G4double tunnel2,
51 G4bool visible)
52{
53 // tidy up things from previous usage if any - base class method
54 CleanUp();
55
56 // test input parameters - set global options as default if not specified
57 TestInputParameters(length, tunnelThickness, tunnelSoilThickness, tunnelMaterial,
58 tunnelSoilMaterial, tunnelFloorOffset, tunnel1, tunnel2);
59
60 // build the solids
61 G4VSolid* tunnelOuterSolid = new G4Box(name + "_tunnel_outer_solid", // name
62 tunnel1 + tunnelThickness, // x radius
63 tunnel2 + tunnelThickness, // y radius
64 0.5*length - lengthSafety); // z half length (to fit in container)
65
66 G4VSolid* tunnelInnerSolid = new G4Box(name + "_tunnel_outer_solid", // name
67 tunnel1 + lengthSafety, // x radius
68 tunnel2 + lengthSafety, // y radius
69 length); // z half length - long for unambiguous subtraction
70
71 // register solids
72 allSolids.insert(tunnelOuterSolid);
73 allSolids.insert(tunnelInnerSolid);
74
75 tunnelSolid = new G4SubtractionSolid(name + "_tunnel_solid", // name
76 tunnelOuterSolid, // this
77 tunnelInnerSolid); // minus this
78
79
80 G4double soilInnerX = tunnel1 + tunnelThickness + lengthSafety;
81 G4double soilInnerY = tunnel2 + tunnelThickness + lengthSafety;
82
83 G4double soilOuterX = soilInnerX + tunnelSoilThickness;
84 G4double soilOuterY = soilInnerY + tunnelSoilThickness;
85
86 G4double containerX = soilOuterX + lengthSafety;
87 G4double containerY = soilOuterY + lengthSafety;
88
89 G4VSolid* soilOuterSolid = new G4Box(name + "_soild_outer_solid", // name
90 soilOuterX, // x half width
91 soilOuterY, // y half width
92 0.5*length); // z half width
93
94 G4VSolid* soilInnerSolid = new G4Box(name + "_soil_outer_solid", // name
95 soilInnerX, // x radius
96 soilInnerY, // y radius
97 length); // z half length - long for unambiguous subtraction
98
99 // register solids
100 allSolids.insert(soilOuterSolid);
101 allSolids.insert(soilInnerSolid);
102
103 soilSolid = new G4SubtractionSolid(name + "_soil_solid", // name
104 soilOuterSolid, // this
105 soilInnerSolid); // minus this
106
107 // container solid depends on whether the floor is there or not, but can prepare the outer part for subtraction
108 G4VSolid* containerSolidOuter = new G4Box(name + "_container_outer_solid", // name
109 containerX, // x half width
110 containerY, // y half width
111 length*0.5); // z half width
112 G4ThreeVector contInsideDisplacement;
113 G4VSolid* containerSolidInner = nullptr;
114
115 // build the floor if necessary
116 if (tunnelFloor)
117 {
118 G4double floorThickness = tunnel2 - tunnelFloorOffset - lengthSafety;
119
120 // placement vector for floor - assinging default 0,0,0 in base class
121 floorDisplacement = G4ThreeVector(0, -(tunnelFloorOffset + floorThickness*0.5), 0);
122 floorSolid = new G4Box(name + "_floor_solid", // name
123 tunnel1 - lengthSafety, // x half width
124 floorThickness*0.5 - lengthSafety, // y half width
125 0.5*length - lengthSafety); // z half width
126
127 G4double tunnelContInnerYRadius = tunnel2 - 0.5*floorThickness - lengthSafety;
128
129 containerSolidInner = new G4Box(name + "_tunnel_cont_solid_inner", // name
130 tunnel1, // x radius
131 tunnelContInnerYRadius, // y radius
132 length); // long z for unambiguous subtraction
133
134 // offset the centre cut out by the difference between the vertical half widths of tunnel2 and tunnel2+floor
135 contInsideDisplacement = G4ThreeVector(0, floorThickness*0.5, 0);
136 }
137 else
138 {
139 containerSolidInner = new G4Box(name + "_tunnel_cont_solid_inner", // name
140 tunnel1, // x radius
141 tunnel2, // y radius
142 length); // long z for unambiguous subtraction
143 contInsideDisplacement = G4ThreeVector(0,0,0);
144 }
145
146 containerSolid = new G4SubtractionSolid(name + "_tunnel_cont_solid", // name
147 containerSolidOuter, // this
148 containerSolidInner, // minus this
149 0, // rotate by this
150 contInsideDisplacement);
151
152 CommonConstruction(name, tunnelMaterial, tunnelSoilMaterial, length, containerX, containerY, visible);
153
154 return tunnelSection;
155}
156
157
159 G4double length,
160 G4ThreeVector inputFace,
161 G4ThreeVector outputFace,
162 G4double tunnelThickness,
163 G4double tunnelSoilThickness,
164 G4Material* tunnelMaterial,
165 G4Material* tunnelSoilMaterial,
166 G4bool tunnelFloor,
167 G4double tunnelFloorOffset,
168 G4double tunnel1,
169 G4double tunnel2,
170 G4bool visible)
171{
172 // tidy up things from previous usage if any - base class method
173 CleanUp();
174
175 // test input parameters - set global options as default if not specified
176 TestInputParameters(length, tunnelThickness, tunnelSoilThickness, tunnelMaterial,
177 tunnelSoilMaterial, tunnelFloorOffset, tunnel1, tunnel2);
178
179 // build the solids
180 // create an intersection cut tubs to get the faces - make it bigger than everything else
181 // then make elliptical solids longer than they need to be
182 G4double intersectionRadius = ( std::max(tunnel1,tunnel2) + tunnelThickness + tunnelSoilThickness ) * 3;
183 G4VSolid* faceSolid = new G4CutTubs(name + "_face_intersection_solid", // name
184 0, // inner radius
185 intersectionRadius, // 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
193 // tunnel
194 G4VSolid* tunnelOuterSolid = new G4Box(name + "_tunnel_outer_solid", // name
195 tunnel1 + tunnelThickness, // x radius
196 tunnel2 + tunnelThickness, // y radius
197 length); // z half length
198
199 G4VSolid* tunnelInnerSolid = new G4Box(name + "_tunnel_outer_solid", // name
200 tunnel1 + lengthSafety, // x radius
201 tunnel2 + lengthSafety, // y radius
202 length*1.5); // z half length - long for unambiguous subtraction
203
204 G4VSolid* tunnelSolidUnAngled = new G4SubtractionSolid(name + "_tunnel_square_solid", // name
205 tunnelOuterSolid, // this
206 tunnelInnerSolid); // minus this
207
208 // register solids
209 allSolids.insert(faceSolid);
210 allSolids.insert(tunnelOuterSolid);
211 allSolids.insert(tunnelInnerSolid);
212 allSolids.insert(tunnelSolidUnAngled);
213
214 // cut off the faces with the angled face solid
215 tunnelSolid = new G4IntersectionSolid(name + "_tunnel_solid", // name
216 tunnelSolidUnAngled,
217 faceSolid);
218
219 // soil solid
220 G4double soilInnerX = tunnel1 + tunnelThickness + lengthSafety;
221 G4double soilInnerY = tunnel2 + tunnelThickness + lengthSafety;
222
223 G4double soilOuterX = soilInnerX + tunnelSoilThickness;
224 G4double soilOuterY = soilInnerY + tunnelSoilThickness;
225
226 G4double containerX = soilOuterX + lengthSafety;
227 G4double containerY = soilOuterY + lengthSafety;
228
229 G4VSolid* soilOuterSolid = new G4Box(name + "_soil_outer_solid", // name
230 soilOuterX, // x half width
231 soilOuterY, // y half width
232 length); // z half length
233
234 G4VSolid* soilInnerSolid = new G4Box(name + "_soil_inner_solid", // name
235 soilInnerX, // x radius
236 soilInnerY, // y radius
237 1.5*length); // z half length - long for unambiguous subtraction
238
239 // cut out inside of big box of soil to get rectangular tube - purposively long for upcoming intersection
240 G4VSolid* soilSolidUnAngled = new G4SubtractionSolid(name + "_soil_square_solid", // name
241 soilOuterSolid, // this
242 soilInnerSolid); // minus this
243
244 // register solids
245 allSolids.insert(soilOuterSolid);
246 allSolids.insert(soilInnerSolid);
247 allSolids.insert(soilSolidUnAngled);
248
249 // make it angled
250 soilSolid = new G4IntersectionSolid(name + "_soil_soild", // name
251 soilSolidUnAngled,
252 faceSolid);
253
254
255 // container solid depends on whether the floor is there or not, but can prepare the outer part for subtraction
256 G4VSolid* containerSolidOuter = new G4Box(name + "_container_outer_solid", // name
257 containerX, // x half width
258 containerY, // y half width
259 length); // z long for unambiguous intersection later
260 G4ThreeVector contInsideDisplacement;
261 G4VSolid* containerSolidInner = nullptr;
262 G4VSolid* containerSolidSquare = nullptr;
263
264 allSolids.insert(containerSolidOuter);
265
266 // build the floor if necessary
267 if (tunnelFloor)
268 {
269 G4double floorThickness = tunnel2 - tunnelFloorOffset - lengthSafety;
270
271 // placement vector for floor - assinging default 0,0,0 in base class
272 floorDisplacement = G4ThreeVector(0, -(tunnelFloorOffset + floorThickness*0.5), 0);
273
274 G4VSolid* floorSolidSquare = new G4Box(name + "_floor_box_solid", // name
275 tunnel1, // x half width
276 floorThickness*0.5, // y half width
277 length); // z half width
278
279 floorSolid = new G4IntersectionSolid(name + "_floor_solid", // name
280 floorSolidSquare,
281 faceSolid);
282
283 allSolids.insert(floorSolidSquare);
284
285 // need to create a container for the tunnel + floor that only just contains it
286 G4double tunnelContInnerYRadius = ( tunnelFloorOffset + tunnel2 ) * 0.5;
287 containerSolidInner = new G4Box(name + "_tunnel_cont_solid_inner", // name
288 tunnel1, // x radius
289 tunnelContInnerYRadius, // y radius
290 2*length); // z long for unambiguous subtraction
291
292 // offset the centre cut out by the difference between the vertical half widths of tunnel2 and tunnel2+floor
293 contInsideDisplacement = G4ThreeVector(0, -(tunnelContInnerYRadius - tunnel2), 0);
294 }
295 else
296 {
297 containerSolidInner = new G4Box(name + "_tunnel_cont_solid_inner", // name
298 tunnel1, // x radius
299 tunnel2, // y radius
300 2*length); // z half length - long for unambiguous subtraction
301 contInsideDisplacement = G4ThreeVector(0,0,0);
302 }
303
304 containerSolidSquare = new G4SubtractionSolid(name + "_container_square_solid", // name
305 containerSolidOuter, // this
306 containerSolidInner, // minus this
307 0, // rotate by this
308 contInsideDisplacement); // with this displacment
309
310 containerSolid = new G4IntersectionSolid(name + "_container_solid", // name
311 containerSolidSquare,
312 faceSolid);
313
314 CommonConstruction(name, tunnelMaterial, tunnelSoilMaterial, length, containerX,
315 containerY, visible);
316
317 return tunnelSection;
318}
319
322 G4double& tunnelThickness,
323 G4double& tunnelSoilThickness,
324 G4Material*& tunnelMaterial,
325 G4Material*& tunnelSoilMaterial,
326 G4double& tunnelFloorOffset,
327 G4double& tunnel1,
328 G4double& tunnel2)
329{
330 CommontTestInputParameters(length, tunnelThickness, tunnelSoilThickness, tunnelMaterial, tunnelSoilMaterial);
331
332 if (tunnelFloorOffset < 1e-10)
333 {tunnelFloorOffset = defaultModel->floorOffset;}
334
335 if (tunnel1 < 1e-10)
336 {tunnel1 = defaultModel->aper1;}
337
338 if (tunnel2 < 1e-10)
339 {tunnel2 = defaultModel->aper2;}
340}
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, G4double &tunnel2)
functions below here are private to this particular factory
G4double aper2
Tunnel aperture / shape parameter 2.
G4double aper1
Tunnel aperture / shape parameter 1.
Class that represents a section of tunnel.