BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSTunnelFactoryRectAboveGround.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 "BDSTunnelFactoryBase.hh"
19#include "BDSTunnelFactoryRectAboveGround.hh"
20#include "BDSTunnelInfo.hh"
21#include "BDSUtilities.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 "G4UnionSolid.hh"
31#include "G4VSolid.hh"
32
33#include <cmath> // sin, cos, fabs
34#include <set>
35#include <utility> // for std::pair
36
38
39BDSTunnelFactoryRectAboveGround::BDSTunnelFactoryRectAboveGround()
40{
41 slabSolid = nullptr;
42 slabXHalfWidth = 0;
43 slabYHalfWidth = 1*CLHEP::m;
44 containerXRadius = 0;
45 containerYRadius = 0;
46}
47
49{
51 containerXRadius = 0;
52 containerYRadius = 0;
53 slabXHalfWidth = 0;
54}
55
57 G4double length,
58 G4double tunnelThickness,
59 G4double tunnelSoilThickness,
60 G4Material* tunnelMaterial,
61 G4Material* tunnelSoilMaterial,
62 G4bool /*tunnelFloor*/,
63 G4double /*tunnelFloorOffset*/,
64 G4double tunnel1,
65 G4double tunnel2,
66 G4bool visible)
67{
68 // tidy up things from previous usage if any - base class method
69 CleanUp();
70
71 // test input parameters - set global options as default if not specified
72 TestInputParameters(length, tunnelThickness, tunnelSoilThickness, tunnelMaterial,
73 tunnelSoilMaterial, tunnel1, tunnel2);
74
75 // build the solids
76 // work out how wide the slab needs to be
77 slabXHalfWidth = std::max(tunnel1, tunnel2) * 2;
78
79 // lengthSafety ensures clean union with floor plane
80 G4double yDisp = tunnel2 + slabYHalfWidth + lengthSafety;
81
82 G4ThreeVector slabDisplacement = G4ThreeVector(0,-yDisp,0);
83
84 slabSolid = new G4Box(name + "_slab_solid", // name
85 slabXHalfWidth, // x half width
86 slabYHalfWidth, // y half width
87 0.5*length - lengthSafety); // z half width
88
89 G4VSolid* tunnelOuterSolid = new G4Box(name + "_tunnel_outer_solid", // name
90 tunnel1 + tunnelThickness, // x radius
91 tunnel2 + tunnelThickness, // y radius
92 0.5*length - lengthSafety); // z half length (to fit in container)
93
94 G4VSolid* tunnelRectSolid = new G4UnionSolid(name + "_tunnel_outer_solid", // name,
95 tunnelOuterSolid,
96 slabSolid,
97 0,
98 slabDisplacement);
99
100 G4VSolid* tunnelInnerSolid = new G4Box(name + "_tunnel_outer_solid", // name
101 tunnel1 + lengthSafety, // x radius
102 tunnel2 + lengthSafety, // y radius
103 length); // z half length - long for unambiguous subtraction
104
105 tunnelSolid = new G4SubtractionSolid(name + "_tunnel_solid",// name
106 tunnelRectSolid, // this
107 tunnelInnerSolid); // minus this
108
109 // register solids
110 allSolids.insert(tunnelOuterSolid);
111 allSolids.insert(tunnelRectSolid);
112 allSolids.insert(tunnelInnerSolid);
113 allSolids.insert(tunnelRectSolid);
114
115 containerSolid = BuildContainerStraight(name, length, tunnel1, tunnel2,
116 tunnelThickness, slabDisplacement);
117
118 CommonConstruction(name, tunnelMaterial, tunnelSoilMaterial, length, containerXRadius, containerYRadius, visible);
119
120 return tunnelSection;
121}
122
124 G4double length,
125 G4ThreeVector inputFace,
126 G4ThreeVector outputFace,
127 G4double tunnelThickness,
128 G4double tunnelSoilThickness,
129 G4Material* tunnelMaterial,
130 G4Material* tunnelSoilMaterial,
131 G4bool /*tunnelFloor*/,
132 G4double /*tunnelFloorOffset*/,
133 G4double tunnel1,
134 G4double tunnel2,
135 G4bool visible)
136{
137 // tidy up things from previous usage if any - base class method
138 CleanUp();
139
140 // test input parameters - set global options as default if not specified
141 TestInputParameters(length, tunnelThickness, tunnelSoilThickness, tunnelMaterial,
142 tunnelSoilMaterial, tunnel1, tunnel2);
143
144 // build the solids
145 // create an intersection cut tubs to get the faces - make it bigger than everything else
146 // then make elliptical solids longer than they need to be
147 G4double intersectionRadius = ( std::max(tunnel1,tunnel2) + tunnelThickness + tunnelSoilThickness ) * 3;
148 G4VSolid* faceSolid = new G4CutTubs(name + "_face_intersection_solid", // name
149 0, // inner radius
150 intersectionRadius, // outer radius
151 length*0.5 - lengthSafety, // z half length
152 0, // start angle
153 CLHEP::twopi, // sweep angle
154 inputFace, // input face normal vector
155 outputFace); // output face normal vector
156
157 // build the solids
158 // work out how wide the slab needs to be
159 slabXHalfWidth = std::max(tunnel1, tunnel2) * 2;
160
161 // lengthSafety ensures clean union with floor plane
162 G4double yDisp = tunnel2 + slabYHalfWidth + lengthSafety;
163
164 G4ThreeVector slabDisplacement = G4ThreeVector(0,-yDisp,0);
165
166 slabSolid = new G4Box(name + "_slab_solid", // name
167 slabXHalfWidth, // x half width
168 slabYHalfWidth, // y half width
169 1.2*length - lengthSafety); // z half width (long for uabig sub.)
170
171
172 // tunnel
173 G4VSolid* tunnelOuterSolid = new G4Box(name + "_tunnel_outer_solid", // name
174 tunnel1 + tunnelThickness, // x radius
175 tunnel2 + tunnelThickness, // y radius
176 length); // z half length
177
178 G4VSolid* tunnelRectSolid = new G4UnionSolid(name + "_tunnel_outer_solid", // name,
179 tunnelOuterSolid,
180 slabSolid,
181 0,
182 slabDisplacement);
183
184 G4VSolid* tunnelInnerSolid = new G4Box(name + "_tunnel_outer_solid", // name
185 tunnel1 + lengthSafety, // x radius
186 tunnel2 + lengthSafety, // y radius
187 length*1.5); // z half length - long for unambiguous subtraction
188
189 G4VSolid* tunnelSolidUnAngled = new G4SubtractionSolid(name + "_tunnel_square_solid", // name
190 tunnelRectSolid, // this
191 tunnelInnerSolid); // minus this
192
193 // register solids
194 allSolids.insert(tunnelOuterSolid);
195 allSolids.insert(tunnelRectSolid);
196 allSolids.insert(tunnelInnerSolid);
197 allSolids.insert(tunnelSolidUnAngled);
198
199 // cut off the faces with the angled face solid
200 tunnelSolid = new G4IntersectionSolid(name + "_tunnel_solid", // name
201 tunnelSolidUnAngled,
202 faceSolid);
203
204 G4VSolid* straightContainer = BuildContainerStraight(name, length*2.0, tunnel1, tunnel2,
205 tunnelThickness, slabDisplacement);
206
207 containerSolid = new G4IntersectionSolid(name + "_tunnel_container_solid", // name
208 straightContainer,
209 faceSolid);
210
211 CommonConstruction(name, tunnelMaterial, tunnelSoilMaterial, length, containerXRadius,
212 containerYRadius, visible);
213
214 return tunnelSection;
215}
216
219 G4double& tunnelThickness,
220 G4double& tunnelSoilThickness,
221 G4Material*& tunnelMaterial,
222 G4Material*& tunnelSoilMaterial,
223 G4double& tunnel1,
224 G4double& tunnel2)
225{
226 CommontTestInputParameters(length, tunnelThickness, tunnelSoilThickness, tunnelMaterial, tunnelSoilMaterial);
227
228 if (!BDS::IsFinite(tunnel1))
229 {tunnel1 = defaultModel->aper1;}
230
231 if (!BDS::IsFinite(tunnel2))
232 {tunnel2 = defaultModel->aper2;}
233}
234
235G4VSolid* BDSTunnelFactoryRectAboveGround::BuildContainerStraight(G4String name,
236 G4double lengthIn,
237 G4double tunnel1,
238 G4double tunnel2,
239 G4double tunnelThickness,
240 G4ThreeVector slabDisplacement)
241{
242 G4VSolid* containerSolidL; // local
243
244 containerXRadius = slabXHalfWidth + lengthSafety;
245 containerYRadius = tunnel2 + tunnelThickness + lengthSafety;
246
247 // have to do a subtraction
248 G4VSolid* tunnelContainerOuterSlab = new G4Box(name + "_cont_slab_solid", // name
249 slabXHalfWidth + lengthSafety, // x half width
250 slabYHalfWidth + lengthSafety, // y half width
251 0.5*lengthIn); // z half width
252 G4VSolid* tunnelContainerOuterTunnel = new G4Box(name + "_cont_tunnel_solid", // name
253 tunnel1 + tunnelThickness + lengthSafety, // x radius
254 tunnel2 + tunnelThickness + lengthSafety, // y radius
255 0.5*lengthIn); // z half length
256 G4VSolid* tunnelContainerOuter = new G4UnionSolid(name + "_cont_outer_solid",
257 tunnelContainerOuterTunnel,
258 tunnelContainerOuterSlab,
259 0,
260 slabDisplacement);
261
262 G4VSolid* tunnelContainerInner = new G4Box(name + "_tunnel_cont_solid_inner", // name
263 tunnel1, // x radius
264 tunnel2, // y radius
265 lengthIn);
266
267 // regsiter solids
268 allSolids.insert(tunnelContainerOuterSlab);
269 allSolids.insert(tunnelContainerOuterTunnel);
270 allSolids.insert(tunnelContainerOuter);
271 allSolids.insert(tunnelContainerInner);
272
273 containerSolidL = new G4SubtractionSolid(name + "_tunnel_cont_solid", // name
274 tunnelContainerOuter, // this
275 tunnelContainerInner); // minus this
276
277 return containerSolidL;
278}
const G4String name
Const protected member variable that may not be changed by derived classes.
G4double lengthSafety
Cache of global constants variable.
void CommontTestInputParameters(G4double &length, G4double &tunnelThickness, G4double &tunnelSoilThickness, G4Material *&tunnelMaterial, G4Material *&tunnelSoilMaterial)
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 &tunnel1, G4double &tunnel2)
functions below here are private to this particular factory
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.
G4double aper2
Tunnel aperture / shape parameter 2.
G4double aper1
Tunnel aperture / shape parameter 1.
Class that represents a section of tunnel.
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())