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) 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 "BDSCollimatorBeamMask.hh"
19#include "BDSBeamPipe.hh"
20#include "BDSBeamPipeFactory.hh"
21#include "BDSBeamPipeInfo.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 "G4Tubs.hh"
34#include "G4Trd.hh"
35#include "G4LogicalVolume.hh"
36#include "G4PVPlacement.hh"
37#include "G4SubtractionSolid.hh"
38#include "G4UnionSolid.hh"
39#include "G4UserLimits.hh"
40#include "G4VisAttributes.hh"
41
42
43BDSCollimatorBeamMask::BDSCollimatorBeamMask(const G4String& nameIn,
44 G4double lengthIn,
45 BDSBeamPipeInfo* beamPipeInfoIn,
46 G4double horizontalWidthIn,
47 G4Material* collimatorMaterialIn,
48 G4Material* vacuumMaterialIn,
49 G4double xApertureIn,
50 G4double yApertureIn,
51 G4double xApertureSlitIn,
52 G4double yApertureSlitIn,
53 G4double xOffsetIn,
54 G4double yOffsetIn,
55 G4double xOffsetSlitIn,
56 G4double yOffsetSlitIn,
57 G4double tiltSlitIn,
58 G4Colour* colourIn,
59 G4bool circularOuterIn):
60 BDSAcceleratorComponent(nameIn, lengthIn, 0, "bmcol", beamPipeInfoIn),
61 collimatorSolid(nullptr),
62 innerSolid(nullptr),
63 vacuumSolid(nullptr),
64 horizontalWidth(horizontalWidthIn),
65 collimatorMaterial(collimatorMaterialIn),
66 vacuumMaterial(vacuumMaterialIn),
67 xAperture(xApertureIn),
68 yAperture(yApertureIn),
69 xApertureSlit(xApertureSlitIn),
70 yApertureSlit(yApertureSlitIn),
71 xOffset(xOffsetIn),
72 yOffset(yOffsetIn),
73 xOffsetSlit(xOffsetSlitIn),
74 yOffsetSlit(yOffsetSlitIn),
75 tiltSlit(tiltSlitIn),
76 colour(colourIn),
77 minKineticEnergy(0),
78 circularOuter(circularOuterIn)
79{;}
80
82{
83 if ((xAperture > 0.5 * horizontalWidth) || (yAperture > 0.5 * horizontalWidth))
84 {
85 G4cerr << __METHOD_NAME__ << "half aperture bigger than width or height!" << G4endl;
86 G4cerr << "Full horizontal width is " << horizontalWidth << " mm for component named: \""
87 << name << "\"" << G4endl;
88 G4cerr << "x (half) aperture " << xAperture << " mm, y (half) aperture " << yAperture << " mm" << G4endl;
89 throw BDSException(__METHOD_NAME__, "Error in beam mask");
90 }
91
93 {
94 G4cerr << __METHOD_NAME__ << "no aperture set for the main slit!" << G4endl;
95 G4cerr << "In element named " << name << " we have a x (half) aperture " << xAperture
96 << " mm, y (half) aperture " << yAperture << " mm" << G4endl;
97 throw BDSException(__METHOD_NAME__, "Error in beam mask");
98 }
99
102 {
103 G4cerr << __METHOD_NAME__ << "no aperture set for the side slit!" << G4endl;
104 G4cerr << "In element named " << name << " we have a x (half) aperture " << xApertureSlit
105 << " mm, y (half) aperture " << yApertureSlit << " mm" << G4endl;
106 throw BDSException(__METHOD_NAME__, "Error in beam mask");
107 }
108
109 if (!colour)
110 {colour = BDSColours::Instance()->GetColour("collimator");}
111}
112
114{
116 {return collimatorMaterial->GetName();}
117 else
118 {return "none";}
119}
120
122{
124 BDSBeamPipe* pipe = factory->CreateBeamPipe(name + "_beampipe",
127 RegisterDaughter(pipe);
128
129 // make the beam pipe container, this object's container
130 containerLogicalVolume = pipe->GetContainerLogicalVolume();
131 containerSolid = pipe->GetContainerSolid();
132
133 // register vacuum volume (for biasing)
135
136 // update extents
137 InheritExtents(pipe);
138
139 // update faces
142}
143
144void BDSCollimatorBeamMask::BuildInner()
145{
146 G4Box* inner1 = new G4Box(name + "_inner_solid_1", // name
147 xAperture, // x half width
148 yAperture, // y half width
149 chordLength); // z half length
150 // z half length long for unambiguous subtraction
151
152 G4Box* inner2 = new G4Box(name + "_inner_solid_2", // name
153 xApertureSlit, // x half width
154 yApertureSlit, // y half width
155 chordLength); // z half length
156 // z half length long for unambiguous subtraction
157
158 G4ThreeVector trans(xOffsetSlit, yOffsetSlit, 0);
159 G4RotationMatrix* rot = new G4RotationMatrix;
160 rot->rotateZ(tiltSlit);
161
162 innerSolid = new G4UnionSolid(name + "_inner_solid_union", inner1, inner2, rot, trans);
164 RegisterSolid(inner1);
165 RegisterSolid(inner2);
167
168 G4Box* vacuum1 = new G4Box(name + "_vacuum_solid_1", // name
169 xAperture - lengthSafety, // x half width
170 yAperture - lengthSafety, // y half width
171 chordLength*0.5); // z half length
172
173 G4Box* vacuum2 = new G4Box(name + "_vacuum_solid_2", // name
174 xApertureSlit - lengthSafety, // x half width
175 yApertureSlit - lengthSafety, // y half width
176 chordLength*0.5); // z half length
177
178 vacuumSolid = new G4UnionSolid(name + "_vacuum_solid_union", vacuum1, vacuum2, rot, trans);
180}
181
183{
185 BDSAcceleratorComponent::Build(); // calls BuildContainer and sets limits and vis for container
186
187 G4RotationMatrix* rot = new G4RotationMatrix;
188 G4ThreeVector trans(xOffset, yOffset, 0);
189
190 G4VSolid* outerSolid;
191 if (circularOuter)
192 {
193 outerSolid = new G4Tubs(name + "_outer_solid",
194 0,
197 0,
198 CLHEP::twopi);
199 }
200 else
201 {
202 outerSolid = new G4Box(name + "_outer_solid",
205 chordLength * 0.5 - lengthSafety);
206 }
207 RegisterSolid(outerSolid);
208
209 G4bool buildVacuumAndAperture = (BDS::IsFinite(xAperture) && BDS::IsFinite(yAperture));
210
211 // only do subtraction if aperture actually set
212 if (buildVacuumAndAperture)
213 {
214 BuildInner();
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 G4VisAttributes* collimatorVisAttr = new G4VisAttributes(*colour);
228 collimatorLV->SetVisAttributes(collimatorVisAttr);
229 RegisterVisAttributes(collimatorVisAttr);
230
231 collimatorLV->SetUserLimits(CollimatorUserLimits());
232
233 // register with base class (BDSGeometryComponent)
234 RegisterLogicalVolume(collimatorLV);
235 if (sensitiveOuter)
236 {RegisterSensitiveVolume(collimatorLV, BDSSDType::collimatorcomplete);}
237
238 G4PVPlacement* collPV = new G4PVPlacement(rot, // rotation
239 trans, // position
240 collimatorLV, // its logical volume
241 name + "_collimator_pv", // its name
242 containerLogicalVolume, // its mother volume
243 false, // no boolean operation
244 0, // copy number
246
248
249 if (buildVacuumAndAperture)
250 {
251 G4LogicalVolume* vacuumLV = new G4LogicalVolume(vacuumSolid, // solid
252 vacuumMaterial, // material
253 name + "_vacuum_lv"); // name
254
255 vacuumLV->SetVisAttributes(containerVisAttr);
256 // user limits - provided by BDSAcceleratorComponent
257 vacuumLV->SetUserLimits(userLimits);
259 RegisterLogicalVolume(vacuumLV);
260 if (sensitiveVacuum)
261 {RegisterSensitiveVolume(vacuumLV, BDSSDType::energydepvacuum);}
262
263 G4PVPlacement* vacPV = new G4PVPlacement(rot, // rotation
264 trans, // position
265 vacuumLV, // its logical volume
266 name + "_vacuum_pv", // its name
267 containerLogicalVolume, // its mother volume
268 false, // no boolean operation
269 0, // copy number
272 }
273}
274
276{
278 {
279 // copy default ones with correct length and global time etc provided
280 // by BDSAcceleratorComponent
281 G4UserLimits* collUserLimits = new G4UserLimits(*userLimits);
282 collUserLimits->SetUserMinEkine(minKineticEnergy);
283 RegisterUserLimits(collUserLimits);
284 return collUserLimits;
285 }
286 else // user limits - provided by BDSAcceleratorComponent
287 {return userLimits;}
288}
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:
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:32
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 RegisterRotationMatrix(G4RotationMatrix *rotationMatrix)
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())