BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSBeamPipeFactoryPoints.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 "BDSBeamPipeFactoryPoints.hh"
19#include "BDSBeamPipe.hh"
20#include "BDSExtent.hh"
21#include "BDSUtilities.hh"
22
23#include "globals.hh" // geant4 globals / types
24#include "G4CutTubs.hh"
25#include "G4ExtrudedSolid.hh"
26#include "G4IntersectionSolid.hh"
27#include "G4SubtractionSolid.hh"
28#include "G4ThreeVector.hh"
29#include "G4TwoVector.hh"
30#include "G4VSolid.hh"
31
32#include <cmath>
33#include <vector>
34
35BDSBeamPipeFactoryPoints::BDSBeamPipeFactoryPoints()
36{
38}
39
40BDSBeamPipeFactoryPoints::~BDSBeamPipeFactoryPoints()
41{;}
42
44{
46 BDSBeamPipeFactoryBase::CleanUp();
47}
48
50{
52 extentX = 0;
53 extentY = 0;
54
55 vacuumEdge.clear();
56 beamPipeInnerEdge.clear();
57 beamPipeOuterEdge.clear();
58 containerEdge.clear();
60
61 beamPipeInnerSolid = nullptr;
62 beamPipeOuterSolid = nullptr;
63
64 pointsFile = "";
65 pointsUnit = "";
66}
67
68void BDSBeamPipeFactoryPoints::AppendPoint(std::vector<G4TwoVector>& vec,
69 G4double x,
70 G4double y)
71{
72 vec.emplace_back(G4TwoVector(x,y));
73}
74
75void BDSBeamPipeFactoryPoints::AppendAngle(std::vector<G4TwoVector>& vec,
76 G4double startAngle,
77 G4double finishAngle,
78 G4double radius,
79 G4int nPoints,
80 G4double xOffset,
81 G4double yOffset)
82{
83 AppendAngleEllipse(vec, startAngle, finishAngle, radius, radius,nPoints, xOffset, yOffset);
84}
85
86void BDSBeamPipeFactoryPoints::AppendAngleEllipse(std::vector<G4TwoVector>& vec,
87 G4double startAngle,
88 G4double finishAngle,
89 G4double radiusA,
90 G4double radiusB,
91 G4int nPoints,
92 G4double xOffset,
93 G4double yOffset)
94{
95 G4double diff = finishAngle - startAngle;
96 G4double delta = diff / (G4double)nPoints;
97 G4double ang = startAngle;
98 for (G4int i = 0; i < nPoints; i++)
99 { // l for local
100 G4double xl = xOffset + radiusA*std::sin(ang);
101 G4double yl = yOffset + radiusB*std::cos(ang);
102 AppendPoint(vec, xl, yl);
103 ang += delta;
104 }
105}
106
108 G4double length,
109 G4bool buildLongForIntersection)
110{
112 G4double zHalfLength = 0.5*length;
113 if (buildLongForIntersection)
114 {zHalfLength *= 1.5;}
115
116 G4TwoVector zOffsets(0,0); // the transverse offset of each plane from 0,0
117 G4double zScale = 1; // the scale at each end of the points = 1
118 vacuumSolid = new G4ExtrudedSolid(name + "_vacuum_solid", // name
119 vacuumEdge, // vector of TwoVector points
120 zHalfLength - lengthSafety, // half length for +- planes
121 zOffsets, zScale, // dx,dy offset for each face, scaling
122 zOffsets, zScale); // dx,dy offset for each face, scaling
123
124 beamPipeInnerSolid = new G4ExtrudedSolid(name + "_bp_inner_solid",
126 zHalfLength * 4,
127 zOffsets, zScale,
128 zOffsets, zScale);
129
130 beamPipeOuterSolid = new G4ExtrudedSolid(name + "_bp_outer_solid",
132 zHalfLength - 4*lengthSafety,
133 zOffsets, zScale,
134 zOffsets, zScale);
135
136 allSolids.insert(beamPipeInnerSolid);
137 allSolids.insert(beamPipeOuterSolid);
138
139 beamPipeSolid = new G4SubtractionSolid(name + "_pipe_solid", // name
140 beamPipeOuterSolid, // this
141 beamPipeInnerSolid); // minus this
142
143 containerSolid = new G4ExtrudedSolid(name + "_container_solid",
145 zHalfLength,
146 zOffsets, zScale,
147 zOffsets, zScale);
148
149 containerSubtractionSolid = new G4ExtrudedSolid(name + "_container_subtraction_solid",
151 zHalfLength*4,
152 zOffsets, zScale,
153 zOffsets, zScale);
154}
155
157 G4double length,
158 const G4ThreeVector& inputFace,
159 const G4ThreeVector& outputFace)
160{
161 // long length for unambiguous boolean - ensure no gaps in beam pipe geometry
162 // extra factor 2 to be safe
163 G4double angledVolumeLength = BDS::CalculateSafeAngledVolumeLength(inputFace, outputFace, length*2, intersectionRadius);
164
165 // create straight solids that are a bit long
166 CreateSolids(name + "_straight", angledVolumeLength, true);
167
168 // now intersect them with one G4CutTubs to get the angled faces
169 G4double zHalfLength = length*0.5 - lengthSafety;
170 G4double zHalfLengthContainer = length*0.5;
171
172 // check faces of angled volume don't intersect - if it can be built, remaining angled volumes can be built
173 CheckAngledVolumeCanBeBuilt(length, inputFace, outputFace, intersectionRadius, name);
174
175 G4VSolid* faceSolid = new G4CutTubs(name + "_face_solid", // name
176 0, // inner radius
177 intersectionRadius, // outer radius
178 zHalfLength, // z half length
179 0, // start angle
180 CLHEP::twopi, // sweep angle
181 inputFace, // input face normal
182 outputFace); // output face normal
183
184 // different only by container length > length of inner section
185 G4VSolid* faceSolidContainer = new G4CutTubs(name + "_cont_face_solid", // name
186 0, // inner radius
187 intersectionRadius, // outer radius
188 zHalfLengthContainer, // z half length
189 0, // start angle
190 CLHEP::twopi, // sweep angle
191 inputFace, // input face normal
192 outputFace); // output face normal
193
194 allSolids.insert(faceSolid);
195 allSolids.insert(faceSolidContainer);
196
197 // copy pointers to do intersection with then reassign member pointer
198 // to point to new solid
199 G4VSolid* vacuumTemp = vacuumSolid;
200 vacuumSolid = new G4IntersectionSolid(name + "_vacuum_solid",
201 vacuumTemp,
202 faceSolid);
203
204 G4VSolid* beamPipeTemp = beamPipeSolid;
205 beamPipeSolid = new G4IntersectionSolid(name + "_pipe_solid",
206 beamPipeTemp,
207 faceSolid);
208
209 G4VSolid* containerTemp = containerSolid;
210 containerSolid = new G4IntersectionSolid(name + "_container_solid",
211 containerTemp,
212 faceSolidContainer);
213
214 // container subtraction solid can just be long with flat edges as
215 // only used transversely
216}
217
219 G4double lengthIn,
220 G4double aper1In,
221 G4double aper2In,
222 G4double aper3In,
223 G4double aper4In,
224 G4Material* vacuumMaterialIn,
225 G4double beamPipeThicknessIn,
226 G4Material* beamPipeMaterialIn,
227 const G4String& pointsFileIn,
228 const G4String& pointsUnitIn)
229{
230 // clean up after last usage
231 CleanUp();
232
233 pointsFile = pointsFileIn;
234 pointsUnit = pointsUnitIn;
235
236 // generate extruded solid edges - provided by derived class
237 GeneratePoints(aper1In, aper2In, aper3In, aper4In, beamPipeThicknessIn);
238
239 // calculate and set the intersection solid radius
240 intersectionRadius = CalculateIntersectionRadius(aper1In, aper2In, aper3In, aper4In, beamPipeThicknessIn);
241
242 // create solids based on the member vectors of points
243 CreateSolids(nameIn, lengthIn);
244
245 return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn, lengthIn);
246}
247
249 G4double lengthIn,
250 const G4ThreeVector& inputFaceNormalIn,
251 const G4ThreeVector& outputFaceNormalIn,
252 G4double aper1In,
253 G4double aper2In,
254 G4double aper3In,
255 G4double aper4In,
256 G4Material* vacuumMaterialIn,
257 G4double beamPipeThicknessIn,
258 G4Material* beamPipeMaterialIn,
259 const G4String& pointsFileIn,
260 const G4String& pointsUnitIn)
261{
262 // clean up after last usage
263 CleanUp();
264
265 pointsFile = pointsFileIn;
266 pointsUnit = pointsUnitIn;
267
268 // generate extruded solid edges - provided by derived class
269 GeneratePoints(aper1In, aper2In, aper3In, aper4In, beamPipeThicknessIn);
270
271 inputFaceNormal = inputFaceNormalIn;
272 outputFaceNormal = outputFaceNormalIn;
273
274 // calculate and set the intersection solid radius
275 intersectionRadius = CalculateIntersectionRadius(aper1In, aper2In, aper3In, aper4In, beamPipeThicknessIn);
276
277 // create solids based on the member vectors of points
279
280 return CommonFinalConstruction(nameIn, vacuumMaterialIn, beamPipeMaterialIn, lengthIn);
281}
282
284 G4Material* vacuumMaterialIn,
285 G4Material* beamPipeMaterialIn,
286 G4double lengthIn)
287{
288 BDSBeamPipeFactoryBase::CommonConstruction(nameIn, vacuumMaterialIn,
289 beamPipeMaterialIn, lengthIn);
290
291 // record extents
292 BDSExtent ext = BDSExtent(extentX, extentY, lengthIn*0.5);
293
294 // calculate radius if a tube were to be place around it
295 G4double containerRadius = intersectionRadius;
296
297 BDSBeamPipe* aPipe = BuildBeamPipeAndRegisterVolumes(ext,containerRadius);
298
299 return aPipe;
300}
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
static void CheckAngledVolumeCanBeBuilt(G4double length, const G4ThreeVector &inputfaceAngle, const G4ThreeVector &outputfaceAngle, G4double horizontalWidth, const G4String &name)
check if a beam pipe volume with angled faces can be constructed
G4VSolid * containerSubtractionSolid
Longer (in length) version of container solid for unambiguous subtraction.
G4VSolid * beamPipeInnerSolid
Solid for inner surface of beam pipe.
std::vector< G4TwoVector > containerSubtractionEdge
Vector of x,y coordinates for the container subtraction volume.
std::vector< G4TwoVector > beamPipeInnerEdge
Vector of x,y coordinates for beam pipe inner edge.
virtual void CleanUp()
Clear member vectors and run base class clean up to clear pointers between runs.
G4VSolid * beamPipeOuterSolid
Solid for outer surface of beam pipe.
virtual void GeneratePoints(G4double aper1, G4double aper2, G4double aper3, G4double aper4, G4double beamPipeThickness, G4int pointsPerTwoPi=40)=0
G4double extentY
Extents prepared by GeneratePoints function as only it knows the extents.
virtual G4double CalculateIntersectionRadius(G4double aper1, G4double aper2, G4double aper3, G4double aper4, G4double beamPipeThickness)=0
void CleanUpPoints()
Actual clean up here for this class only.
virtual BDSBeamPipe * CommonFinalConstruction(const G4String &nameIn, G4Material *vacuumMaterialIn, G4Material *beamPipeMaterialIn, G4double lengthIn)
G4double extentX
Extents prepared by GeneratePoints function as only it knows the extents.
std::vector< G4TwoVector > vacuumEdge
Vector of x,y coordinates for vacuum extruded solid edge.
virtual BDSBeamPipe * CreateBeamPipe(const G4String &nameIn, G4double lengthIn, G4double aper1In, G4double aper2In, G4double aper3In, G4double aper4In, G4Material *vacuumMaterialIn, G4double beamPipeThicknessIn, G4Material *beamPipeMaterialIn, const G4String &pointsFileIn="", const G4String &pointsUnitIn="")
Required overloaded method from BDSBeamPipeFactoryBase to build straight piece of beam pipe.
void CreateSolidsAngled(const G4String &name, G4double length, const G4ThreeVector &inputFace, const G4ThreeVector &outputFace)
Create angled solids. Uses CreateSolids() method.
void AppendAngle(std::vector< G4TwoVector > &vec, G4double startAngle, G4double finishAngle, G4double radius, G4int nPoints=10, G4double xOffset=0, G4double yOffset=0)
void CreateSolids(const G4String &name, G4double length, G4bool buildLongForIntersection=false)
G4String pointsFile
Temporary copy of input variables.
std::vector< G4TwoVector > containerEdge
Vector of x,y coordinates for the container volume.
std::vector< G4TwoVector > beamPipeOuterEdge
Vector of x,y coordinates for beam pipe outer edge.
G4String pointsUnit
Temporary copy of input variables.
void AppendAngleEllipse(std::vector< G4TwoVector > &vec, G4double startAngle, G4double finishAngle, G4double radiusA, G4double radiusB, G4int nPoints=10, G4double xOffset=0, G4double yOffset=0)
Generate 2-vector points (and append them) about an ellipse.
A holder class for a piece of beam pipe geometry.
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:38
G4double lengthSafety
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.