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) 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 "BDSAcceleratorModel.hh"
19#include "BDSBeamPipeInfo.hh"
20#include "BDSCollimator.hh"
21#include "BDSColours.hh"
22#include "BDSDebug.hh"
23#include "BDSException.hh"
24#include "BDSGlobalConstants.hh"
25#include "BDSMaterials.hh"
26#include "BDSSDType.hh"
27#include "BDSUtilities.hh"
28#include "BDSWarning.hh"
29
30#include "globals.hh"
31#include "G4Box.hh"
32#include "G4LogicalVolume.hh"
33#include "G4PVPlacement.hh"
34#include "G4SubtractionSolid.hh"
35#include "G4Tubs.hh"
36#include "G4UserLimits.hh"
37#include "G4VisAttributes.hh"
38
39#include <map>
40
41BDSCollimator::BDSCollimator(const G4String& nameIn,
42 G4double lengthIn,
43 G4double horizontalWidthIn,
44 const G4String& typeIn,
45 G4Material* collimatorMaterialIn,
46 G4Material* vacuumMaterialIn,
47 G4double xApertureIn,
48 G4double yApertureIn,
49 G4double xApertureOutIn,
50 G4double yApertureOutIn,
51 G4Colour* colourIn,
52 G4bool circularOuterIn):
53 BDSAcceleratorComponent(nameIn, lengthIn, 0, typeIn),
54 collimatorSolid(nullptr),
55 innerSolid(nullptr),
56 vacuumSolid(nullptr),
57 horizontalWidth(horizontalWidthIn),
58 collimatorMaterial(collimatorMaterialIn),
59 vacuumMaterial(vacuumMaterialIn),
60 xAperture(xApertureIn),
61 yAperture(yApertureIn),
62 xApertureOut(xApertureOutIn),
63 yApertureOut(yApertureOutIn),
64 tapered(false),
65 colour(colourIn),
66 minKineticEnergy(0),
67 circularOuter(circularOuterIn),
68 collimatorTypeSensitivity(true)
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 {
215 {RegisterSensitiveVolume(collimatorLV, BDSSDType::collimatorcomplete);}
216 else
217 {RegisterSensitiveVolume(collimatorLV, BDSSDType::energydep);}
218 }
219
220 G4PVPlacement* collPV = new G4PVPlacement(colRotate, // rotation
221 G4ThreeVector(), // position
222 collimatorLV, // its logical volume
223 name + "_collimator_pv", // its name
224 containerLogicalVolume, // its mother volume
225 false, // no boolean operation
226 0, // copy number
228
230
231 if (buildVacuumAndAperture)
232 {
233 G4LogicalVolume* vacuumLV = new G4LogicalVolume(vacuumSolid, // solid
234 vacuumMaterial, // material
235 name + "_vacuum_lv"); // name
236
237 vacuumLV->SetVisAttributes(containerVisAttr);
238 // user limits - provided by BDSAcceleratorComponent
239 vacuumLV->SetUserLimits(userLimits);
241 RegisterLogicalVolume(vacuumLV);
242 if (sensitiveVacuum)
243 {RegisterSensitiveVolume(vacuumLV, BDSSDType::energydepvacuum);}
244
245 G4PVPlacement* vacPV = new G4PVPlacement(colRotate, // rotation
246 (G4ThreeVector) 0, // position
247 vacuumLV, // its logical volume
248 name + "_vacuum_pv", // its name
249 containerLogicalVolume, // its mother volume
250 false, // no boolean operation
251 0, // copy number
253
255 }
256}
257
259{
261 {
262 // copy default ones with correct length and global time etc provided
263 // by BDSAcceleratorComponent
264 G4UserLimits* collUserLimits = new G4UserLimits(*userLimits);
265 collUserLimits->SetUserMinEkine(minKineticEnergy);
266 RegisterUserLimits(collUserLimits);
267 return collUserLimits;
268 }
269 else // user limits - provided by BDSAcceleratorComponent
270 {return userLimits;}
271}
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.
G4bool collimatorTypeSensitivity
Whether to use special collimator hits or not.
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()
G4Material * collimatorMaterial
Material.
G4VSolid * collimatorSolid
Geometrical objects:
G4Colour * colour
Colour of collimator.
G4Colour * GetColour(G4double red, G4double green, G4double blue, G4double alpha=1)
Get a cached anonymous colour by values.
static BDSColours * Instance()
singleton pattern
Definition BDSColours.cc:32
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:38
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())