BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSCollimatorBeamMask.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2024.
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 "BDSCollimatorBeamMask.hh"
20#include "BDSBeamPipe.hh"
21#include "BDSBeamPipeFactory.hh"
22#include "BDSBeamPipeInfo.hh"
23#include "BDSColours.hh"
24#include "BDSDebug.hh"
25#include "BDSException.hh"
26#include "BDSGlobalConstants.hh"
27#include "BDSMaterials.hh"
28#include "BDSSDType.hh"
29#include "BDSUtilities.hh"
30#include "BDSWarning.hh"
31
32#include "globals.hh"
33#include "G4Box.hh"
34#include "G4Tubs.hh"
35#include "G4Trd.hh"
36#include "G4LogicalVolume.hh"
37#include "G4PVPlacement.hh"
38#include "G4SubtractionSolid.hh"
39#include "G4UnionSolid.hh"
40#include "G4UserLimits.hh"
41#include "G4VisAttributes.hh"
42
43
45 G4double lengthIn,
46 BDSBeamPipeInfo* beamPipeInfoIn,
47 G4double horizontalWidthIn,
48 G4Material* collimatorMaterialIn,
49 G4Material* vacuumMaterialIn,
50 G4double xApertureIn,
51 G4double yApertureIn,
52 G4double xApertureSlitIn,
53 G4double yApertureSlitIn,
54 G4double xOffsetIn,
55 G4double yOffsetIn,
56 G4double xOffsetSlitIn,
57 G4double yOffsetSlitIn,
58 G4double tiltSlitIn,
59 G4Colour* colourIn,
60 G4bool circularOuterIn):
61 BDSAcceleratorComponent(nameIn, lengthIn, 0, "bmcol", beamPipeInfoIn),
62 collimatorSolid(nullptr),
63 innerSolid(nullptr),
64 vacuumSolid(nullptr),
65 horizontalWidth(horizontalWidthIn),
66 collimatorMaterial(collimatorMaterialIn),
67 vacuumMaterial(vacuumMaterialIn),
68 xAperture(xApertureIn),
69 yAperture(yApertureIn),
70 xApertureSlit(xApertureSlitIn),
71 yApertureSlit(yApertureSlitIn),
72 xOffset(xOffsetIn),
73 yOffset(yOffsetIn),
74 xOffsetSlit(xOffsetSlitIn),
75 yOffsetSlit(yOffsetSlitIn),
76 tiltSlit(tiltSlitIn),
77 colour(colourIn),
78 minKineticEnergy(0),
79 circularOuter(circularOuterIn)
80{;}
81
83{
84 if ((xAperture > 0.5 * horizontalWidth) || (yAperture > 0.5 * horizontalWidth))
85 {
86 G4cerr << __METHOD_NAME__ << "half aperture bigger than width or height!" << G4endl;
87 G4cerr << "Full horizontal width is " << horizontalWidth << " mm for component named: \""
88 << name << "\"" << G4endl;
89 G4cerr << "x (half) aperture " << xAperture << " mm, y (half) aperture " << yAperture << " mm" << G4endl;
90 throw BDSException(__METHOD_NAME__, "Error in beam mask");
91 }
92
94 {
95 G4cerr << __METHOD_NAME__ << "no aperture set for the main slit!" << G4endl;
96 G4cerr << "In element named " << name << " we have a x (half) aperture " << xAperture <<
97 " mm, y (half) aperture " << yAperture << " mm" << G4endl;
98 throw BDSException(__METHOD_NAME__, "Error in beam mask");
99 }
100
103 {
104 G4cerr << __METHOD_NAME__ << "no aperture set for the side slit!" << G4endl;
105 G4cerr << "In element named " << name << " we have a x (half) aperture " << xApertureSlit <<
106 " mm, y (half) aperture " << yApertureSlit << " mm" << G4endl;
107 throw BDSException(__METHOD_NAME__, "Error in beam mask");
108 }
109
110 if (!colour)
111 {colour = BDSColours::Instance()->GetColour("collimator");}
112}
113
115{
117 {return collimatorMaterial->GetName();}
118 else
119 {return "none";}
120}
121
123{
125 BDSBeamPipe* pipe = factory->CreateBeamPipe(name + "_beampipe",
128 RegisterDaughter(pipe);
129
130 // make the beam pipe container, this object's container
131 containerLogicalVolume = pipe->GetContainerLogicalVolume();
132 containerSolid = pipe->GetContainerSolid();
133
134 // register vacuum volume (for biasing)
136
137 // update extents
138 InheritExtents(pipe);
139
140 // update faces
143}
144
145void BDSCollimatorBeamMask::BuildInner()
146{
147 G4Box* inner1 = new G4Box(name + "_inner_solid_1", // name
148 xAperture, // x half width
149 yAperture, // y half width
150 chordLength); // z half length
151 // z half length long for unambiguous subtraction
152
153 G4Box* inner2 = new G4Box(name + "_inner_solid_2", // name
154 xApertureSlit, // x half width
155 yApertureSlit, // y half width
156 chordLength); // z half length
157 // z half length long for unambiguous subtraction
158
159 G4ThreeVector Trans(xOffsetSlit, yOffsetSlit, 0);
160 G4RotationMatrix* Rot = new G4RotationMatrix;
161 Rot->rotateZ(tiltSlit);
162
163 innerSolid = new G4UnionSolid(name + "_inner_solid_union", inner1, inner2, Rot, Trans);
164
165 G4Box* vacuum1 = new G4Box(name + "_vacuum_solid_1", // name
166 xAperture - lengthSafety, // x half width
167 yAperture - lengthSafety, // y half width
168 chordLength*0.5); // z half length
169
170 G4Box* vacuum2 = new G4Box(name + "_vacuum_solid_2", // name
171 xApertureSlit - lengthSafety, // x half width
172 yApertureSlit - lengthSafety, // y half width
173 chordLength*0.5); // z half length
174
175 vacuumSolid = new G4UnionSolid(name + "_vacuum_solid_union", vacuum1, vacuum2, Rot, Trans);
176
179}
180
182{
184 BDSAcceleratorComponent::Build(); // calls BuildContainer and sets limits and vis for container
185
186 G4RotationMatrix* Rot = new G4RotationMatrix;
187 G4ThreeVector Trans(xOffset, yOffset, 0);
188
189 G4VSolid* outerSolid;
190 if (circularOuter)
191 {
192 outerSolid = new G4Tubs(name + "_outer_solid",
193 0,
196 0,
197 CLHEP::twopi);
198 }
199 else
200 {
201 outerSolid = new G4Box(name + "_outer_solid",
204 chordLength * 0.5 - lengthSafety);
205 }
206 RegisterSolid(outerSolid);
207
208 G4bool buildVacuumAndAperture = (BDS::IsFinite(xAperture) && BDS::IsFinite(yAperture));
209
210 // only do subtraction if aperture actually set
211 if (buildVacuumAndAperture)
212 {
213 BuildInner();
214
215 collimatorSolid = new G4SubtractionSolid(name + "_collimator_solid", // name
216 outerSolid, // solid 1
217 innerSolid); // minus solid 2
219 }
220 else
221 {collimatorSolid = outerSolid;}
222
223 G4LogicalVolume* collimatorLV = new G4LogicalVolume(collimatorSolid, // solid
224 collimatorMaterial, // material
225 name + "_collimator_lv"); // name
226
227
228 G4VisAttributes* collimatorVisAttr = new G4VisAttributes(*colour);
229 collimatorLV->SetVisAttributes(collimatorVisAttr);
230 RegisterVisAttributes(collimatorVisAttr);
231
232 collimatorLV->SetUserLimits(CollimatorUserLimits());
233
234 // register with base class (BDSGeometryComponent)
235 RegisterLogicalVolume(collimatorLV);
236 if (sensitiveOuter)
237 {RegisterSensitiveVolume(collimatorLV, BDSSDType::collimatorcomplete);}
238
239 G4PVPlacement* collPV = new G4PVPlacement(Rot, // rotation
240 Trans, // position
241 collimatorLV, // its logical volume
242 name + "_collimator_pv", // its name
243 containerLogicalVolume, // its mother volume
244 false, // no boolean operation
245 0, // copy number
247
249
250 if (buildVacuumAndAperture)
251 {
252 G4LogicalVolume* vacuumLV = new G4LogicalVolume(vacuumSolid, // solid
253 vacuumMaterial, // material
254 name + "_vacuum_lv"); // name
255
256 vacuumLV->SetVisAttributes(containerVisAttr);
257 // user limits - provided by BDSAcceleratorComponent
258 vacuumLV->SetUserLimits(userLimits);
260 RegisterLogicalVolume(vacuumLV);
261 if (sensitiveVacuum)
262 {RegisterSensitiveVolume(vacuumLV, BDSSDType::energydepvacuum);}
263
264 G4PVPlacement* vacPV = new G4PVPlacement(Rot, // rotation
265 Trans, // position
266 vacuumLV, // its logical volume
267 name + "_vacuum_pv", // its name
268 containerLogicalVolume, // its mother volume
269 false, // no boolean operation
270 0, // copy number
272
274 }
275}
276
278{
280 {
281 // copy default ones with correct length and global time etc provided
282 // by BDSAcceleratorComponent
283 G4UserLimits* collUserLimits = new G4UserLimits(*userLimits);
284 collUserLimits->SetUserMinEkine(minKineticEnergy);
285 RegisterUserLimits(collUserLimits);
286 return collUserLimits;
287 }
288 else // user limits - provided by BDSAcceleratorComponent
289 {return userLimits;}
290}
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 G4bool sensitiveOuter
Useful variable often used in construction.
virtual void SetOutputFaceNormal(const G4ThreeVector &output)
Allow updating of face normals. Virtual so derived class may apply it to daughters.
static G4double lengthSafety
Useful variable often used in construction.
static G4bool checkOverlaps
Useful variable often used in construction.
virtual void SetInputFaceNormal(const G4ThreeVector &input)
Allow updating of face normals. Virtual so derived class may apply it to daughters.
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.
BDSBeamPipeInfo * beamPipeInfo
Optional beam pipe recipe that is written out to the survey if it exists.
The main interface for using the beam pipe factories.
static BDSBeamPipeFactory * Instance()
Singleton accessor.
Holder class for all information required to describe a beam pipe model.
A holder class for a piece of beam pipe geometry.
G4LogicalVolume * GetVacuumLogicalVolume() const
Access the vacuum volume to set fields and limits.
G4ThreeVector InputFaceNormal() const
Accessor.
G4ThreeVector OutputFaceNormal() const
Accessor.
G4double yApertureSlit
Aperture of side slit in y dimension.
G4double yOffsetSlit
Offset of the side slit wrt the main slit in y.
G4double horizontalWidth
Horizontal width.
G4double yAperture
Aperture of main slit in y dimension.
virtual G4String Material() const
Accessor.
G4Colour * colour
Colour of beam mask.
G4Material * vacuumMaterial
Vacuum material.
G4Material * collimatorMaterial
Material.
G4VSolid * vacuumSolid
Geometrical objects:
G4bool circularOuter
Shape of the outer solid.
G4double yOffset
Offset of the mask in the pipe in y.
G4UserLimits * CollimatorUserLimits()
Return either default user limits or custom ones based on optional minimumKineticEnergy.
G4double xApertureSlit
Aperture of side slit in x dimension.
G4double xAperture
Aperture of main slit in x dimension.
G4double tiltSlit
Angle of the side slit.
virtual void BuildContainerLogicalVolume()
G4double xOffsetSlit
Offset of the side slit wrt the main slit in x.
G4VSolid * innerSolid
Geometrical objects:
BDSCollimatorBeamMask()
Private default constructor to force the use of the supplied one.
G4VSolid * collimatorSolid
Geometrical objects:
G4double xOffset
Offset of the mask in the pipe in x.
G4double minKineticEnergy
Optional minimum kinetic energy for collimator materials.
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:33
General exception with possible name of object and message.
G4LogicalVolume * GetContainerLogicalVolume() const
Accessor - see member for more info.
void InheritExtents(BDSGeometryComponent const *const anotherComponent)
Update the extents of this object with those of another object.
void RegisterDaughter(BDSGeometryComponent *anotherComponent)
void RegisterLogicalVolume(G4LogicalVolume *logicalVolume)
void RegisterPhysicalVolume(G4VPhysicalVolume *physicalVolume)
G4VSolid * GetContainerSolid() const
Accessor - see member for more info.
void RegisterUserLimits(G4UserLimits *userLimit)
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())