BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSCollimator.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 "BDSAcceleratorModel.hh"
20#include "BDSBeamPipeInfo.hh"
21#include "BDSCollimator.hh"
22#include "BDSColours.hh"
23#include "BDSDebug.hh"
24#include "BDSException.hh"
25#include "BDSGlobalConstants.hh"
26#include "BDSMaterials.hh"
27#include "BDSSDType.hh"
28#include "BDSUtilities.hh"
29#include "BDSWarning.hh"
30
31#include "globals.hh"
32#include "G4Box.hh"
33#include "G4LogicalVolume.hh"
34#include "G4PVPlacement.hh"
35#include "G4SubtractionSolid.hh"
36#include "G4Tubs.hh"
37#include "G4UserLimits.hh"
38#include "G4VisAttributes.hh"
39
40#include <map>
41
42BDSCollimator::BDSCollimator(const G4String& nameIn,
43 G4double lengthIn,
44 G4double horizontalWidthIn,
45 const G4String& typeIn,
46 G4Material* collimatorMaterialIn,
47 G4Material* vacuumMaterialIn,
48 G4double xApertureIn,
49 G4double yApertureIn,
50 G4double xApertureOutIn,
51 G4double yApertureOutIn,
52 G4Colour* colourIn,
53 G4bool circularOuterIn):
54 BDSAcceleratorComponent(nameIn, lengthIn, 0, typeIn),
55 collimatorSolid(nullptr),
56 innerSolid(nullptr),
57 vacuumSolid(nullptr),
58 horizontalWidth(horizontalWidthIn),
59 collimatorMaterial(collimatorMaterialIn),
60 vacuumMaterial(vacuumMaterialIn),
61 xAperture(xApertureIn),
62 yAperture(yApertureIn),
63 xApertureOut(xApertureOutIn),
64 yApertureOut(yApertureOutIn),
65 tapered(false),
66 colour(colourIn),
67 minKineticEnergy(0),
68 circularOuter(circularOuterIn)
69{;}
70
71BDSCollimator::~BDSCollimator()
72{;}
73
75{
76 if ((xAperture > 0.5 * horizontalWidth) || (yAperture > 0.5 * horizontalWidth))
77 {
78 G4cerr << __METHOD_NAME__ << "half aperture bigger than width or height!" << G4endl;
79 G4cerr << "Full horizontal width is " << horizontalWidth << " mm for component named: \""
80 << name << "\"" << G4endl;
81 G4cerr << "x (half) aperture " << xAperture << " mm, y (half) aperture " << yAperture << " mm" << G4endl;
82 throw BDSException(__METHOD_NAME__, "Error in collimator");
83 }
84
86 {
87 G4cerr << __METHOD_NAME__ << "half aperture exit bigger than width or height!" << G4endl;
88 G4cerr << "Full horizontal width is " << horizontalWidth << " mm for component named: \""
89 << name << "\"" << G4endl;
90 G4cerr << "x (half) aperture " << xApertureOut << " mm, y (half) aperture " << yApertureOut << " mm" << G4endl;
91 throw BDSException(__METHOD_NAME__, "Error in collimator");
92 }
93
95 {BDS::Warning(__METHOD_NAME__, "element: \"" + name + "\": no entrance aperture set for collimator - exit aperture parameters will be ignored");}
96
98 if (!tapered)
99 {// copy for consistency in output and aperture prediction
102 }
103
104 if (!colour)
105 {colour = BDSColours::Instance()->GetColour("collimator");}
106}
107
109{
111 {return collimatorMaterial->GetName();}
112 else
113 {return "none";}
114}
115
117{
118 if (circularOuter)
119 {
120 containerSolid = new G4Tubs(name + "_solid",
121 0,
122 0.5*horizontalWidth,
123 0.5*chordLength,
124 0,
125 CLHEP::twopi);
126 }
127 else
128 {
129 containerSolid = new G4Box(name + "_container_solid",
130 horizontalWidth*0.5,
131 horizontalWidth*0.5,
132 chordLength*0.5);
133 }
134
135 containerLogicalVolume = new G4LogicalVolume(containerSolid,
137 name + "_container_lv");
139 chordLength * 0.5);
140 SetExtent(ext);
141}
142
144{
146 BDSAcceleratorComponent::Build(); // calls BuildContainer and sets limits and vis for container
147
148 // Swap variables around if exit size is larger than entrance size
149 // Rotation for tapered collimator (needed for tapered elliptical collimator)
150 G4bool isOutLarger = ((xApertureOut > xAperture) && (yApertureOut > yAperture));
151 G4RotationMatrix* colRotate;
152 if (tapered && isOutLarger)
153 {
154 std::swap(xAperture,xApertureOut);
155 std::swap(yAperture,yApertureOut);
156 colRotate = new G4RotationMatrix;
157 colRotate->rotateX(CLHEP::pi);
158 RegisterRotationMatrix(colRotate);
159 }
160 else
161 {colRotate = nullptr;}
162
163 G4VSolid* outerSolid;
164 if (circularOuter)
165 {
166 outerSolid = new G4Tubs(name + "_outer_solid",
167 0,
170 0,
171 CLHEP::twopi);
172 }
173 else
174 {
175 outerSolid = new G4Box(name + "_outer_solid",
178 chordLength * 0.5 - lengthSafety);
179 }
180 RegisterSolid(outerSolid);
181
182 G4bool buildVacuumAndAperture = (BDS::IsFinite(xAperture) && BDS::IsFinite(yAperture));
183
184 // only do subtraction if aperture actually set
185 if (buildVacuumAndAperture)
186 {
188
189 collimatorSolid = new G4SubtractionSolid(name + "_collimator_solid", // name
190 outerSolid, // solid 1
191 innerSolid); // minus solid 2
193 }
194 else
195 {collimatorSolid = outerSolid;}
196
197 G4LogicalVolume* collimatorLV = new G4LogicalVolume(collimatorSolid, // solid
198 collimatorMaterial, // material
199 name + "_collimator_lv"); // name
200
201 // register it in a set of collimator logical volumes
202 BDSAcceleratorModel::Instance()->VolumeSet("collimators")->insert(collimatorLV);
203
204 G4VisAttributes* collimatorVisAttr = new G4VisAttributes(*colour);
205 collimatorLV->SetVisAttributes(collimatorVisAttr);
206 RegisterVisAttributes(collimatorVisAttr);
207
208 collimatorLV->SetUserLimits(CollimatorUserLimits());
209
210 // register with base class (BDSGeometryComponent)
211 RegisterLogicalVolume(collimatorLV);
212 if (sensitiveOuter)
213 {RegisterSensitiveVolume(collimatorLV, BDSSDType::collimatorcomplete);}
214
215 G4PVPlacement* collPV = new G4PVPlacement(colRotate, // rotation
216 G4ThreeVector(), // position
217 collimatorLV, // its logical volume
218 name + "_collimator_pv", // its name
219 containerLogicalVolume, // its mother volume
220 false, // no boolean operation
221 0, // copy number
223
225
226 if (buildVacuumAndAperture)
227 {
228 G4LogicalVolume* vacuumLV = new G4LogicalVolume(vacuumSolid, // solid
229 vacuumMaterial, // material
230 name + "_vacuum_lv"); // name
231
232 vacuumLV->SetVisAttributes(containerVisAttr);
233 // user limits - provided by BDSAcceleratorComponent
234 vacuumLV->SetUserLimits(userLimits);
236 RegisterLogicalVolume(vacuumLV);
237 if (sensitiveVacuum)
238 {RegisterSensitiveVolume(vacuumLV, BDSSDType::energydepvacuum);}
239
240 G4PVPlacement* vacPV = new G4PVPlacement(colRotate, // rotation
241 (G4ThreeVector) 0, // position
242 vacuumLV, // its logical volume
243 name + "_vacuum_pv", // its name
244 containerLogicalVolume, // its mother volume
245 false, // no boolean operation
246 0, // copy number
248
250 }
251}
252
254{
256 {
257 // copy default ones with correct length and global time etc provided
258 // by BDSAcceleratorComponent
259 G4UserLimits* collUserLimits = new G4UserLimits(*userLimits);
260 collUserLimits->SetUserMinEkine(minKineticEnergy);
261 RegisterUserLimits(collUserLimits);
262 return collUserLimits;
263 }
264 else // user limits - provided by BDSAcceleratorComponent
265 {return userLimits;}
266}
Abstract class that represents a component of an accelerator.
G4UserLimits * userLimits
Cache of user limits.
void SetAcceleratorVacuumLogicalVolume(G4LogicalVolume *accVacLVIn)
const G4String name
Const protected member variable that may not be changed by derived classes.
static G4Material * emptyMaterial
Useful variable often used in construction.
static G4bool sensitiveOuter
Useful variable often used in construction.
static G4double lengthSafety
Useful variable often used in construction.
static G4bool checkOverlaps
Useful variable often used in construction.
G4double chordLength
Protected member variable that can be modified by derived classes.
static G4VisAttributes * containerVisAttr
Useful variable often used in construction.
static G4bool sensitiveVacuum
Useful variable often used in construction.
std::set< G4LogicalVolume * > * VolumeSet(const G4String &name)
Returns pointer to a set of logical volumes. If no set by that name exits, create it.
G4bool circularOuter
Aperture type of the collimator.
G4double minKineticEnergy
Optional minimum kinetic energy for collimator materials.
G4double xAperture
Aperture at entrance in x dimension.
G4UserLimits * CollimatorUserLimits()
Return either default user limits or custom ones based on optional minimumKineticEnergy.
G4bool tapered
Flag for tapered collimator.
virtual void BuildInnerCollimator()=0
G4double yApertureOut
Aperture at exit in y dimension.
G4VSolid * innerSolid
Geometrical objects:
virtual void CheckParameters()
G4double xApertureOut
Aperture at exit in x dimension.
virtual G4String Material() const
Accessor.
G4Material * vacuumMaterial
Vacuum material.
G4double horizontalWidth
Horizontal width.
G4VSolid * vacuumSolid
Geometrical objects:
G4double yAperture
Aperture at entrance in y dimension.
virtual void BuildContainerLogicalVolume()
virtual void Build()
BDSCollimator()=delete
Private default constructor to force the use of the supplied one.
G4Material * collimatorMaterial
Material.
G4VSolid * collimatorSolid
Geometrical objects:
G4Colour * colour
Colour of collimator.
static BDSColours * Instance()
singleton pattern
Definition: BDSColours.cc:33
G4Colour * GetColour(const G4String &type, G4bool normaliseTo255=true)
Get colour from name.
Definition: BDSColours.cc:204
General exception with possible name of object and message.
Definition: BDSException.hh:35
Holder for +- extents in 3 dimensions.
Definition: BDSExtent.hh:39
void RegisterRotationMatrix(G4RotationMatrix *rotationMatrix)
void RegisterLogicalVolume(G4LogicalVolume *logicalVolume)
void RegisterPhysicalVolume(G4VPhysicalVolume *physicalVolume)
void RegisterUserLimits(G4UserLimits *userLimit)
void SetExtent(const BDSExtent &extIn)
Set extent.
void RegisterVisAttributes(G4VisAttributes *visAttribute)
void RegisterSolid(G4VSolid *solid)
void RegisterSensitiveVolume(G4LogicalVolume *sensitiveVolume, BDSSDType sensitivityType)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())