BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSCurvilinearFactory.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
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 "BDSCurvilinearFactory.hh"
20#include "BDSExtent.hh"
21#include "BDSGlobalConstants.hh"
22#include "BDSSimpleComponent.hh"
23#include "BDSTiltOffset.hh"
24#include "BDSUtilities.hh"
25
26#include "globals.hh"
27#include "G4CutTubs.hh"
28#include "G4LogicalVolume.hh"
29#include "G4ThreeVector.hh"
30#include "G4Tubs.hh"
31#include "G4VSolid.hh"
32
33#include "CLHEP/Units/SystemOfUnits.h"
34
35#include <cmath>
36
37BDSCurvilinearFactory::BDSCurvilinearFactory():
38 lengthSafety(BDSGlobalConstants::Instance()->LengthSafety())
39{;}
40
41BDSCurvilinearFactory::~BDSCurvilinearFactory()
42{;}
43
45 G4double chordLength,
46 G4double radius)
47{
48 G4double halfLength = chordLength * 0.5 - lengthSafety;
49 G4Tubs* solid = new G4Tubs(name + "_solid", // name
50 0, // inner radius
51 radius, // outer radius
52 halfLength, // z half width
53 0, // start angle
54 CLHEP::twopi); // sweep angle
55
56 G4ThreeVector inputFaceNormal = G4ThreeVector(0, 0,-1);
57 G4ThreeVector outputFaceNormal = G4ThreeVector(0, 0, 1);
58
59 return CommonConstruction(name, chordLength, chordLength, radius,
60 solid, 0);
61}
62
64 const G4double arcLength,
65 const G4double chordLength,
66 const G4double radius,
67 const G4double angle,
68 const G4ThreeVector& inputFaceNormal,
69 const G4ThreeVector& outputFaceNormal,
70 const BDSTiltOffset* tiltOffset)
71{
72 // angle is finite!
73 // factor of 0.8 here is arbitrary tolerance as g4 cut tubs seems to fail
74 // with cutting entrance / exit planes close to limit.
75 // s = r*theta -> r = s/theta
76 G4double radiusFromAngleLength = radius;
77 if (BDS::IsFinite(angle)) // it could be 0
78 {radiusFromAngleLength = std::abs(chordLength / angle) * 0.8;}
79 G4double radiusLocal = std::min(radius, radiusFromAngleLength);
80
81 // copy in case we need to modify in the case of tilt offset
82 G4ThreeVector inputface = inputFaceNormal;
83 G4ThreeVector outputface = outputFaceNormal;
84
85 if (tiltOffset)
86 {// could be nullptr
87 G4double tilt = tiltOffset->GetTilt();
88 if (BDS::IsFinite(tilt))
89 {// rotate normal faces
90 inputface = inputface.rotateZ(tilt);
91 outputface = outputface.rotateZ(tilt);
92 }
93 }
94
95 G4double halfLength = chordLength * 0.5 - lengthSafety;
96 G4CutTubs* solid = new G4CutTubs(name + "_solid", // name
97 0, // inner radius
98 radiusLocal, // outer radius
99 halfLength, // half length (z)
100 0, // rotation start angle
101 CLHEP::twopi, // rotation sweep angle
102 inputface, // input face normal vector
103 outputface); // output face normal vector
104
105 return CommonConstruction(name, arcLength, chordLength, radiusLocal, solid, angle);
106}
107
109 G4double arcLength,
110 G4double chordLength,
111 G4double radius,
112 G4double angle,
113 const BDSTiltOffset* tiltOffset)
114{
115 std::pair<G4ThreeVector,G4ThreeVector> faces = BDS::CalculateFaces(-0.5*angle, -0.5*angle);
116 G4ThreeVector inputFaceNormal = faces.first;
117 G4ThreeVector outputFaceNormal = faces.second;
118
119 return CreateCurvilinearVolume(name, arcLength, chordLength, radius, angle, inputFaceNormal, outputFaceNormal, tiltOffset);
120}
121
123 G4double arcLength,
124 G4double chordLength,
125 G4double radius,
126 G4VSolid* solid,
127 G4double angle)
128{
129 // nullptr for material ONLY ok in parallel world!
130 G4LogicalVolume* lv = new G4LogicalVolume(solid, // solid
131 nullptr, // material
132 name + "_lv"); // name
133
134 // always debug visualisation for read out geometry - only viewed via explicit commands
135 lv->SetVisAttributes(BDSGlobalConstants::Instance()->VisibleDebugVisAttr());
136
137 // we don't specify the face normals as they are w.r.t the incoming or outgoing
138 // reference trajectory - to which the curvilinear faces will be perpendicular
139 BDSSimpleComponent* result = new BDSSimpleComponent(name,
140 arcLength,
141 angle,
142 solid,
143 lv,
144 BDSExtent(radius, radius, chordLength*0.5));
145 // we don't bother calling Initialise() as we don't need to set the vis attributes (waste of memory)
146 return result;
147}
BDSSimpleComponent * CommonConstruction(const G4String &name, G4double arcLength, G4double chordLength, G4double radius, G4VSolid *solid, G4double angle)
BDSSimpleComponent * CreateCurvilinearVolume(const G4String &name, G4double chordLength, G4double radius)
Build a straight curvilinear volume.
const G4double lengthSafety
Cache of length safety from BDSGlobalConstants.
Holder for +- extents in 3 dimensions.
Definition: BDSExtent.hh:39
A class that holds global options and constants.
static BDSGlobalConstants * Instance()
Access method.
A BDSAcceleratorComponent wrapper for BDSGeometryComponent.
A holder for any placement offsets and rotations for a BDSAcceleratorComponent.
G4double GetTilt() const
Accessor.
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())
std::pair< G4ThreeVector, G4ThreeVector > CalculateFaces(G4double angleInIn, G4double angleOutIn)
Calculate input and output normal vector.