BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSCollimatorJaw.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 "BDSAcceleratorModel.hh"
20#include "BDSCollimatorJaw.hh"
21#include "BDSBeamPipeInfo.hh"
22#include "BDSColours.hh"
23#include "BDSDebug.hh"
24#include "BDSException.hh"
25#include "BDSMaterials.hh"
26#include "BDSSDType.hh"
27#include "BDSUtilities.hh"
28
29#include "G4Box.hh"
30#include "G4LogicalVolume.hh"
31#include "G4PVPlacement.hh"
32#include "G4VisAttributes.hh"
33
34#include <cmath>
35#include <map>
36#include <set>
37
39 G4double lengthIn,
40 G4double horizontalWidthIn,
41 G4double xHalfGapIn,
42 G4double yHalfHeightIn,
43 G4double xSizeLeftIn,
44 G4double xSizeRightIn,
45 G4bool buildLeftJawIn,
46 G4bool buildRightJawIn,
47 G4Material* collimatorMaterialIn,
48 G4Material* vacuumMaterialIn,
49 G4Colour* colourIn):
50 BDSCollimator(nameIn,
51 lengthIn,
52 horizontalWidthIn,
53 "jcol",
54 collimatorMaterialIn,
55 vacuumMaterialIn,
56 xHalfGapIn,
57 yHalfHeightIn,
58 xHalfGapIn,
59 yHalfHeightIn,
60 colourIn),
61 jawSolid(nullptr),
62 xSizeLeft(xSizeLeftIn),
63 xSizeRight(xSizeRightIn),
64 xHalfGap(xHalfGapIn),
65 jawHalfWidth(0),
66 yHalfHeight(yHalfHeightIn),
67 buildLeftJaw(buildLeftJawIn),
68 buildRightJaw(buildRightJawIn),
69 buildAperture(true)
70{
71 jawHalfWidth = 0.5 * (0.5*horizontalWidth - lengthSafetyLarge - xHalfGap);
72}
73
74BDSCollimatorJaw::~BDSCollimatorJaw()
75{;}
76
78{
79 // BDSCollimator::CheckParameters() <- we replace this and don't call it - 'tapered' is never set
80 if (!colour)
81 {colour = BDSColours::Instance()->GetColour("collimator");}
82
83 if (jawHalfWidth < 1e-3) // 1um minimum, could also be negative
84 {throw BDSException(__METHOD_NAME__, "horizontalWidth insufficient given xsize of jcol \"" + name + "\"");}
85
86 // set half height to half horizontal width if zero - finite height required.
89
90 if (BDS::IsFinite(yHalfHeight) && (yHalfHeight < 1e-3)) // 1um minimum
91 {throw BDSException(__METHOD_NAME__, "insufficient ysize for jcol \"" + name + "\"");}
92
93 if ((yHalfHeight < 0) || ((yHalfHeight > 0) && (yHalfHeight < 1e-3))) // 1um minimum and not negative
94 {throw BDSException(__METHOD_NAME__, "insufficient ysize for jcol \"" + name + "\"");}
95
96 if (xSizeLeft < 0)
97 {throw BDSException(__METHOD_NAME__, "left jcol jaw cannot have negative half aperture size: \"" + name + "\"");}
98 if (xSizeRight < 0)
99 {throw BDSException(__METHOD_NAME__, "left jcol jaw cannot have negative half aperture size: \"" + name + "\"");}
100
101 if (std::abs(xSizeLeft) > 0.5*horizontalWidth)
102 {
103 G4cerr << __METHOD_NAME__ << "jcol \"" << name
104 << "\" left jaw offset is greater the element half width, jaw "
105 << "will not be constructed" << G4endl;
106 buildLeftJaw = false;
107 }
108 if (std::abs(xSizeRight) > 0.5*horizontalWidth)
109 {
110 G4cerr << __METHOD_NAME__ << "jcol \"" << name
111 << "\" right jaw offset is greater the element half width, jaw "
112 << "will not be constructed" << G4endl;
113 buildRightJaw = false;
114 }
115
117 {throw BDSException(__METHOD_NAME__, "no jaws being built: \"" + name + "\"");}
118
120 {buildAperture = false;}
121}
122
124{
125 containerSolid = new G4Box(name + "_container_solid",
126 horizontalWidth*0.5,
128 chordLength*0.5);
129
130 containerLogicalVolume = new G4LogicalVolume(containerSolid,
132 name + "_container_lv");
134 SetExtent(ext);
135}
136
138{
140 BDSAcceleratorComponent::Build(); // calls BuildContainer and sets limits and vis for container
141
142 // set each jaws half gap default to aperture half size
143 G4double leftJawHalfGap = xHalfGap;
144 G4double rightJawHalfGap = xHalfGap;
145
146 // update jaw half gap with offsets
148 {leftJawHalfGap = xSizeLeft;}
150 {rightJawHalfGap = xSizeRight;}
151
152 // jaws have to fit inside containerLogicalVolume so calculate full jaw widths given offsets
153 G4double leftJawWidth = 0.5 * horizontalWidth - leftJawHalfGap;
154 G4double rightJawWidth = 0.5 * horizontalWidth - rightJawHalfGap;
155 G4double vacuumWidth = 0.5 * (leftJawHalfGap + rightJawHalfGap);
156
157 // centre of jaw and vacuum volumes for placements
158 G4double leftJawCentre = 0.5*leftJawWidth + leftJawHalfGap;
159 G4double rightJawCentre = 0.5*rightJawWidth + rightJawHalfGap;
160 G4double vacuumCentre = 0.5*(leftJawHalfGap - rightJawHalfGap);
161
162 G4ThreeVector leftJawPos = G4ThreeVector(leftJawCentre, 0, 0);
163 G4ThreeVector rightJawPos = G4ThreeVector(-rightJawCentre, 0, 0);
164 G4ThreeVector vacuumOffset = G4ThreeVector(vacuumCentre, 0, 0);
165
166 G4VisAttributes* collimatorVisAttr = new G4VisAttributes(*colour);
167 RegisterVisAttributes(collimatorVisAttr);
168
169 // get appropriate user limits for jaw material
170 G4UserLimits* collUserLimits = CollimatorUserLimits();
171
172 // build jaws as appropriate
174 {
175 G4VSolid* leftJawSolid = new G4Box(name + "_leftjaw_solid",
176 leftJawWidth * 0.5 - lengthSafety,
178 chordLength * 0.5 - lengthSafety);
179 RegisterSolid(leftJawSolid);
180
181 G4LogicalVolume* leftJawLV = new G4LogicalVolume(leftJawSolid, // solid
182 collimatorMaterial, // material
183 name + "_leftjaw_lv"); // name
184 leftJawLV->SetVisAttributes(collimatorVisAttr);
185
186 // user limits - provided by BDSAcceleratorComponent
187 leftJawLV->SetUserLimits(collUserLimits);
188
189 // register with base class (BDSGeometryComponent)
190 RegisterLogicalVolume(leftJawLV);
191 // register it in a set of collimator logical volumes
192 BDSAcceleratorModel::Instance()->VolumeSet("collimators")->insert(leftJawLV);
193 if (sensitiveOuter)
194 {RegisterSensitiveVolume(leftJawLV, BDSSDType::collimatorcomplete);}
195
196 // place the jaw
197 G4PVPlacement* leftJawPV = new G4PVPlacement(nullptr, // rotation
198 leftJawPos, // position
199 leftJawLV, // its logical volume
200 name + "_leftjaw_pv", // its name
201 containerLogicalVolume, // its mother volume
202 false, // no boolean operation
203 0, // copy number
205 RegisterPhysicalVolume(leftJawPV);
206 }
208 {
209 G4VSolid* rightJawSolid = new G4Box(name + "_rightjaw_solid",
210 rightJawWidth * 0.5 - lengthSafety,
212 chordLength * 0.5 - lengthSafety);
213 RegisterSolid(rightJawSolid);
214
215 G4LogicalVolume* rightJawLV = new G4LogicalVolume(rightJawSolid, // solid
216 collimatorMaterial, // material
217 name + "_rightjaw_lv"); // name
218 rightJawLV->SetVisAttributes(collimatorVisAttr);
219
220 // user limits - provided by BDSAcceleratorComponent
221 rightJawLV->SetUserLimits(collUserLimits);
222
223 // register with base class (BDSGeometryComponent)
224 RegisterLogicalVolume(rightJawLV);
225 // register it in a set of collimator logical volumes
226 BDSAcceleratorModel::Instance()->VolumeSet("collimators")->insert(rightJawLV);
227 if (sensitiveOuter)
228 {RegisterSensitiveVolume(rightJawLV, BDSSDType::collimatorcomplete);}
229
230 // place the jaw
231 G4PVPlacement* rightJawPV = new G4PVPlacement(nullptr, // rotation
232 rightJawPos, // position
233 rightJawLV, // its logical volume
234 name + "_rightjaw_pv", // its name
235 containerLogicalVolume, // its mother volume
236 false, // no boolean operation
237 0, // copy number
239 RegisterPhysicalVolume(rightJawPV);
240 }
241 // if no aperture but the code has got to this stage, build the collimator as a simple box.
242 if (!buildAperture)
243 {
244 collimatorSolid = new G4Box(name + "_solid",
247 chordLength * 0.5 - lengthSafety);
249
250 G4LogicalVolume* collimatorLV = new G4LogicalVolume(collimatorSolid, // solid
251 collimatorMaterial, // material
252 name + "_lv"); // name
253 collimatorLV->SetVisAttributes(collimatorVisAttr);
254
255 // user limits - provided by BDSAcceleratorComponent - don't use collUserLimits
256 collimatorLV->SetUserLimits(userLimits);
257
258 // register with base class (BDSGeometryComponent)
259 RegisterLogicalVolume(collimatorLV);
260 if (sensitiveOuter)
261 {RegisterSensitiveVolume(collimatorLV, BDSSDType::collimatorcomplete);}
262
263 // place the jaw
264 G4PVPlacement* collimatorPV = new G4PVPlacement(nullptr, // rotation
265 (G4ThreeVector) 0, // position
266 collimatorLV, // its logical volume
267 name + "_pv", // its name
268 containerLogicalVolume, // its mother volume
269 false, // no boolean operation
270 0, // copy number
272 RegisterPhysicalVolume(collimatorPV);
273 }
274
275 // build and place the vacuum volume only if the aperture is finite.
276 if (buildAperture)
277 {
278 vacuumSolid = new G4Box(name + "_vacuum_solid", // name
279 vacuumWidth - lengthSafety, // x half width
280 yHalfHeight - lengthSafety, // y half width
281 chordLength * 0.5); // z half length
282
284
285 G4LogicalVolume* vacuumLV = new G4LogicalVolume(vacuumSolid, // solid
286 vacuumMaterial, // material
287 name + "_vacuum_lv"); // name
288
289 vacuumLV->SetVisAttributes(containerVisAttr);
290 // user limits - provided by BDSAcceleratorComponent
291 vacuumLV->SetUserLimits(userLimits);
293 RegisterLogicalVolume(vacuumLV);
294 if (sensitiveVacuum)
295 {RegisterSensitiveVolume(vacuumLV, BDSSDType::energydepvacuum);}
296
297 G4PVPlacement* vacPV = new G4PVPlacement(nullptr, // rotation
298 vacuumOffset, // position
299 vacuumLV, // its logical volume
300 name + "_vacuum_pv", // its name
301 containerLogicalVolume, // its mother volume
302 false, // no boolean operation
303 0, // copy number
306 }
307}
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.
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.
G4double jawHalfWidth
Half width of each jaw.
G4bool buildAperture
Build aperture or not.
virtual void Build() override
Override function in BDSCollimator for totally different construction.
G4double xSizeRight
Offset of jaw 2.
virtual void BuildContainerLogicalVolume() override
Override function in BDSCollimator for different size based container.
G4double xSizeLeft
Offset of jaw 1.
G4double yHalfHeight
Half height of each jaw.
G4bool buildRightJaw
Build right jaw or not.
virtual void CheckParameters() override
G4double xHalfGap
Half gap separation between jaws.
G4bool buildLeftJaw
Build left jaw or not.
BDSCollimatorJaw()=delete
Private default constructor to force the use of the supplied one.
Base class for collimators with common construction.
G4UserLimits * CollimatorUserLimits()
Return either default user limits or custom ones based on optional minimumKineticEnergy.
G4Material * vacuumMaterial
Vacuum material.
G4double horizontalWidth
Horizontal width.
G4VSolid * vacuumSolid
Geometrical objects:
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:202
General exception with possible name of object and message.
Definition: BDSException.hh:35
Holder for +- extents in 3 dimensions.
Definition: BDSExtent.hh:39
void RegisterLogicalVolume(G4LogicalVolume *logicalVolume)
void RegisterPhysicalVolume(G4VPhysicalVolume *physicalVolume)
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())