BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSBeamPipeFactoryPointsFile.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 "BDSAperturePointsLoader.hh"
19#include "BDSBeamPipeFactoryPointsFile.hh"
20
21#include "G4Types.hh"
22#include "G4TwoVector.hh"
23
24#include <algorithm>
25#include <vector>
26
27BDSBeamPipeFactoryPointsFile::BDSBeamPipeFactoryPointsFile():
28 maximumRadius(0)
29{;}
30
31void BDSBeamPipeFactoryPointsFile::GeneratePoints(G4double, G4double, G4double, G4double,
32 G4double beamPipeThickness, G4int)
33{
34 maximumRadius = 0;
35
36 // the product will not own this points vector pointer - the cache does inside this function
37 std::vector<G4TwoVector>* rawPoints = BDS::LoadAperturePoints(pointsFile, pointsUnit);
38
39 // create a local copy
40 vacuumEdge = std::vector<G4TwoVector>(rawPoints->begin(), rawPoints->end());
41
42 // determine the winding order and if wrong, flip it
43 // we rely on this order, so we calculate the outward facing normals correctly
44 // further down - the sign of the pi/2
45 auto detV1 = vacuumEdge[1] - vacuumEdge[0];
46 auto detV2 = vacuumEdge[2] - vacuumEdge[1];
47 G4double det = Determinant(detV1, detV2);
48
49 if (det < 0)
50 {std::reverse(vacuumEdge.begin(), vacuumEdge.end());}
51
52 // calculate the unit vector for each point - so a direction from the 0,0 point to that point
53 std::vector<G4TwoVector> vertexNormals;
54 vertexNormals.reserve(vacuumEdge.size());
55
56 // Loop round the polygon and calculate the normal of each segment
57 // sum the normals of two segments and normalise to give an outwards
58 // pointing unit vector at each vertex. We have a bit of if else for
59 // the boundaries of the loop for back / front.
60 G4TwoVector v1;
61 G4TwoVector v2;
62 G4TwoVector v3;
63 for (G4int i = 0; i < (G4int)vacuumEdge.size(); i++)
64 {
65 if (i == 0)
66 {
67 v1 = vacuumEdge.back();
68 v3 = vacuumEdge[i+1];
69 }
70 else if (i == (G4int)vacuumEdge.size() - 1)
71 {
72 v1 = vacuumEdge[i-1];
73 v3 = vacuumEdge[0];
74 }
75 else
76 {
77 v1 = vacuumEdge[i-1];
78 v3 = vacuumEdge[i+1];
79 }
80 v2 = vacuumEdge[i];
81
82 auto normal1 = v2 - v1;
83 auto normal2 = v3 - v2;
84 normal1.rotate(-CLHEP::halfpi); // now it's a normal
85 normal2.rotate(-CLHEP::halfpi);
86
87 auto vertexNormal = (normal1 + normal2).unit();
88
89 vertexNormals.push_back(vertexNormal); // outward pointing direction for expansion
90 }
91
92 for (G4int i = 0; i < (G4int)vacuumEdge.size(); i++)
93 {
94 auto ur = vertexNormals[i];
95 beamPipeInnerEdge.emplace_back( vacuumEdge[i] + ur*lengthSafetyLarge);
96 beamPipeOuterEdge.emplace_back( vacuumEdge[i] + ur*(lengthSafetyLarge + beamPipeThickness));
97 containerEdge.emplace_back( vacuumEdge[i] + ur*(5*lengthSafetyLarge + beamPipeThickness));
98 containerSubtractionEdge.emplace_back(vacuumEdge[i] + ur*(7*lengthSafetyLarge + beamPipeThickness));
99 maximumRadius = std::max(maximumRadius, containerSubtractionEdge.back().mag());
100 }
101}
102
103G4double BDSBeamPipeFactoryPointsFile::CalculateIntersectionRadius(G4double, G4double, G4double, G4double, G4double)
104{
105 return maximumRadius*1.01; // 1% margin on absolute size
106}
107
108G4double BDSBeamPipeFactoryPointsFile::Determinant(const G4TwoVector& v1,
109 const G4TwoVector& v2) const
110{
111 G4double det = v1.x()*v2.y() - v2.x()*v1.y();
112 return det;
113}
G4double Determinant(const G4TwoVector &v1, const G4TwoVector &v2) const
Calculate the determinant of 2x G4TwoVectors.
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.
virtual void GeneratePoints(G4double, G4double, G4double, G4double, G4double beamPipeThickness, G4int=40)
Purely to fulfill interface - should not be used!
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.
std::vector< G4TwoVector > vacuumEdge
Vector of x,y coordinates for vacuum extruded solid edge.
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.
G4double lengthSafetyLarge
Cache of global constants variable.
std::vector< G4TwoVector > * LoadAperturePoints(const G4String &fileName, const G4String &unit="")