BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSBeamPipeFactoryRhombus.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 "BDSBeamPipeFactoryRhombus.hh"
20#include "BDSBeamPipeFactoryPoints.hh"
21
22#include "G4TwoVector.hh"
23#include "G4Types.hh"
24
25#include <algorithm>
26#include <cmath>
27#include <vector>
28
29BDSBeamPipeFactoryRhombus::BDSBeamPipeFactoryRhombus()
30{;}
31
32void BDSBeamPipeFactoryRhombus::GenerateRhombus(std::vector<G4TwoVector>& vec,
33 G4double x1,
34 G4double y1,
35 G4double cornerRadius,
36 G4int pointsPerTwoPi)
37{
38 G4double frac = cornerRadius / std::max(std::abs(x1), std::abs(y1));
39 if (frac > 1e-3)
40 {// build with corner radius
41 // The rhombus may be asymmetric, in which case building a pi/2 range of curve
42 // won't result in a smooth transition to the straight sections. We need to work
43 // out what range of angle to cover to come to the right tangent.
44 // consider top curved point -> alpha = angle between y axis and (0,y1) -> (x1,0) line
45 G4double alpha = std::atan2(std::abs(x1), std::abs(y1));
46 G4double halfAngle = CLHEP::halfpi - alpha;
47 std::vector<G4TwoVector> topBit;
48 G4double nPointsTopDouble = (2*halfAngle/CLHEP::twopi) * pointsPerTwoPi;
49 G4int nPointsTop = std::max(4, (G4int)std::ceil(nPointsTopDouble)); // ensure at least 4 points
50 G4double currentAngle = -halfAngle;
51 G4double dAngle = 2*halfAngle / (G4double)nPointsTop;
52 G4TwoVector rotationPointTop(0, y1-cornerRadius);
53 for (G4int i = 0; i <= nPointsTop; i++)
54 {
55 G4TwoVector r(0, cornerRadius);
56 r.rotate(-currentAngle);
57 topBit.push_back(rotationPointTop + r);
58 currentAngle += dAngle;
59 }
60
61 std::vector<G4TwoVector> rightBit;
62 G4double nPointsRightDouble = (2*alpha/CLHEP::twopi) * pointsPerTwoPi;
63 G4int nPointsRight = std::max(4, (G4int)std::ceil(nPointsRightDouble)); // ensure at least 4 points
64 currentAngle = -alpha;
65 dAngle = 2*alpha / (G4double)nPointsRight;
66 G4TwoVector rotationPointRight(x1-cornerRadius, 0);
67 for (G4int i = 0; i <= nPointsRight; i++)
68 {
69 G4TwoVector r(cornerRadius, 0);
70 r.rotate(-currentAngle);
71 topBit.push_back(rotationPointRight + r);
72 currentAngle += dAngle;
73 }
74
75 for (const auto& p : topBit)
76 {vec.push_back(p);}
77 for (const auto& p : rightBit)
78 {vec.push_back(p);}
79 for (const auto& p : topBit)
80 {vec.emplace_back(-p.x(), -p.y());}
81 for (const auto& p : rightBit)
82 {vec.emplace_back(-p.x(), -p.y());}
83 std::reverse(vec.begin(), vec.end());
84 }
85 else
86 {// build just as a rhombus
87 AppendPoint(vec, x1, 0);
88 AppendPoint(vec, 0, -y1);
89 AppendPoint(vec, -x1, 0);
90 AppendPoint(vec, 0, y1);
91 }
92}
93
95 G4double aper2,
96 G4double aper3,
97 G4double distance)
98{
99 G4double a1 = aper1 + distance;
100 G4double a2 = aper2 + distance;
101 G4double a3 = aper3 > 0 ? aper3 + distance : aper3;
102
103 BDS::ThreePoints result = {a1,a2,a3};
104 return result;
105}
106
108 G4double aper2,
109 G4double aper3,
110 G4double /*aper4*/,
111 G4double beamPipeThickness,
112 G4int pointsPerTwoPi)
113{
114 GenerateRhombus(vacuumEdge, aper1, aper2, aper3, pointsPerTwoPi);
115 BDS::ThreePoints ai = ExpandRhombus(aper1, aper2, aper3, lengthSafetyLarge);
116 GenerateRhombus(beamPipeInnerEdge, ai.aper1, ai.aper2, ai.aper3, pointsPerTwoPi);
117 BDS::ThreePoints ao = ExpandRhombus(aper1, aper2, aper3, lengthSafetyLarge + beamPipeThickness);
118 GenerateRhombus(beamPipeOuterEdge, ao.aper1, ao.aper2, ao.aper3, pointsPerTwoPi);
119 BDS::ThreePoints ac = ExpandRhombus(aper1, aper2, aper3, beamPipeThickness + 2*lengthSafetyLarge);
120 GenerateRhombus(containerEdge, ac.aper1, ac.aper2, ac.aper3, pointsPerTwoPi);
121 BDS::ThreePoints acs = ExpandRhombus(aper1, aper2, aper3, beamPipeThickness + 3*lengthSafetyLarge);
122 GenerateRhombus(containerSubtractionEdge, acs.aper1, acs.aper2, acs.aper3, pointsPerTwoPi);
123
124 extentX = acs.aper1;
125 extentY = acs.aper2;
126}
127
129 G4double aper2,
130 G4double /*aper3*/,
131 G4double /*aper4*/,
132 G4double beamPipeThickness)
133{
134 G4double dThickness = beamPipeThickness + 2*lengthSafetyLarge;
135
136 G4double result = std::max(aper1 + dThickness, aper2 + dThickness);
137 result += lengthSafetyLarge;
138 return result;
139}
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.
G4double extentY
Extents prepared by GeneratePoints function as only it knows the extents.
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.
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.
BDS::ThreePoints ExpandRhombus(G4double aper1, G4double aper2, G4double aper3, G4double distance)
Expand the rhombus as needed.
void GenerateRhombus(std::vector< G4TwoVector > &vec, G4double x1, G4double y1, G4double cornerRadius, G4int pointsPerTwoPi)
Generate either 4 points or set of points with curved edges.
virtual void GeneratePoints(G4double aper1, G4double aper2, G4double aper3, G4double aper4, G4double beamPipeThickness, G4int pointsPerTwoPi=40)
Generate all the sets of required points for each surface.
virtual G4double CalculateIntersectionRadius(G4double aper1, G4double aper2, G4double aper3, G4double aper4, G4double beamPipeThickness)
Calculate the radius of the solid used for intersection for angled faces.
G4double lengthSafetyLarge
Cache of global constants variable.