BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSGaborLens.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 "BDSAcceleratorComponent.hh"
20#include "BDSBeamPipe.hh"
21#include "BDSBeamPipeFactory.hh"
22#include "BDSBeamPipeInfo.hh"
23#include "BDSColours.hh"
24#include "BDSDebug.hh"
25#include "BDSFieldBuilder.hh"
26#include "BDSFieldInfo.hh"
27#include "BDSGaborLens.hh"
28#include "BDSExtent.hh"
29#include "BDSException.hh"
30#include "BDSMaterials.hh"
31#include "BDSSDType.hh"
32
33#include "G4Box.hh"
34#include "G4ExtrudedSolid.hh"
35#include "G4LogicalVolume.hh"
36#include "G4PVPlacement.hh"
37#include "G4RotationMatrix.hh"
38#include "G4Tubs.hh"
39#include "G4TwoVector.hh"
40#include "G4ThreeVector.hh"
41#include "G4VisAttributes.hh"
42#include "G4VSolid.hh"
43
44#include "globals.hh" // geant4 globals / types
45#include <string>
46#include <vector>
47
48#include "CLHEP/Units/SystemOfUnits.h"
49
50BDSGaborLens::BDSGaborLens(const G4String& nameIn,
51 G4double lengthIn,
52 G4double horizontalWidthIn,
53 G4double anodeLengthIn,
54 G4Material* anodeMaterialIn,
55 G4double anodeRadiusIn,
56 G4double anodeThicknessIn,
57 G4double electrodeLengthIn,
58 G4Material* electrodeMaterialIn,
59 G4double electrodeRadiusIn,
60 G4double electrodeThicknessIn,
61 G4Material* outerMaterialIn,
62 G4Colour* colourIn,
63 BDSBeamPipeInfo* beamPipeInfoIn,
64 BDSFieldInfo* vacuumFieldInfoIn):
65 BDSAcceleratorComponent(nameIn, lengthIn, 0, "gaborlens", beamPipeInfoIn),
66 horizontalWidth(horizontalWidthIn),
67 anodeRadius(anodeRadiusIn),
68 anodeLength(anodeLengthIn),
69 anodeMaterial(anodeMaterialIn),
70 anodeThickness(anodeThicknessIn),
71 electrodeRadius(electrodeRadiusIn),
72 electrodeLength(electrodeLengthIn),
73 electrodeMaterial(electrodeMaterialIn),
74 electrodeThickness(electrodeThicknessIn),
75 outerMaterial(outerMaterialIn),
76 colour(colourIn),
77 vacuumFieldInfo(vacuumFieldInfoIn)
78{
79 if (vacuumFieldInfo)
80 {vacuumFieldInfo->SetBeamPipeRadius(beamPipeInfoIn->IndicativeRadius());}
81
82 endcapsLength = 10;
83
84 if (chordLength <= endcapsLength)
85 {throw BDSException(__METHOD_NAME__,"the element length must be greater than 20 mm for element \"" + name + "\"");}
86
87 vacuumLength = chordLength - 2*endcapsLength;
88
89 // Input Checks
90 if (horizontalWidth <= 0)
91 {throw BDSException(__METHOD_NAME__,"option \"horizontalWidth\" is not defined or must be greater than 0 for element \"" + name + "\"");}
92
93 if (anodeLength <= 0)
94 {throw BDSException(__METHOD_NAME__,"option \"anodeLength\" is not defined or must be greater than 0 for element \"" + name + "\"");}
95
96 if (anodeRadius <= 0)
97 {throw BDSException(__METHOD_NAME__,"option \"anodeRadius\" is not defined or must be greater than 0 for element \"" + name + "\"");}
98
99 if (anodeThickness <= 0)
100 {throw BDSException(__METHOD_NAME__,"option \"anodeThickness\" is not defined or must be greater than 0 for element \"" + name + "\"");}
101
102 if (electrodeLength <= 0)
103 {throw BDSException(__METHOD_NAME__,"option \"electrodeLength\" is not defined or must be greater than 0 for element \"" + name + "\"");}
104
105 if (electrodeRadius <= 0)
106 {throw BDSException(__METHOD_NAME__,"option \"electrodeRadius\" is not defined or must be greater than 0 for element \"" + name + "\"");}
107
108 if (electrodeThickness <= 0)
109 {throw BDSException(__METHOD_NAME__,"option \"electrodeThickness\" is not defined or must be greater than 0 for element \"" + name + "\"");}
110
111 if ((anodeRadius + anodeThickness) > beamPipeInfo->ExtentInner().MinimumAbsTransverse())
112 {throw BDSException(__METHOD_NAME__,"\"anodeRadius\" must be smaller than the beam pipe aperture for element \"" + name + "\"");}
113
114 if (anodeLength > vacuumLength)
115 {throw BDSException(__METHOD_NAME__,"\"anodeLength\" must be shorter than the element length minus 20mm for element \"" + name + "\"");}
116
117 if ((electrodeRadius + electrodeThickness) > anodeRadius)
118 {throw BDSException(__METHOD_NAME__,"\"anodeRadius\" cannot be smaller than \"electrodeRadius\" + \"electrodeThickness\" for element \"" + name + "\"");}
119
120 if (electrodeLength > 0.5*vacuumLength)
121 {throw BDSException(__METHOD_NAME__,"\"electrodeLength\" must be smaller than half element length minus 20mm for element \"" + name + "\"");}
122
123}
124
125BDSGaborLens::~BDSGaborLens()
126{;}
127
129{
130 containerSolid = new G4Tubs(name + "_container_solid",
131 0, horizontalWidth + lengthSafety,
132 chordLength*0.5,
133 0, CLHEP::twopi);
134
135 containerLogicalVolume = new G4LogicalVolume(containerSolid,
137 name + "_container_lv");
138}
139
146
148{
149 BDSExtent extent = beamPipeInfo->Extent();
150 G4double bpMaxExtent = extent.MaximumAbsTransverse();
151
152 G4double coilOuterRadius = horizontalWidth*0.5 *0.9;
153 G4Tubs* coils = new G4Tubs(name + "_coils_solid", // name
154 bpMaxExtent + lengthSafetyLarge*2, // inner radius
155 coilOuterRadius, // outer radius
156 0.5*(vacuumLength- lengthSafetyLarge*10), // half length
157 0, CLHEP::twopi); // start and finish angle
158 RegisterSolid(coils);
159 G4Material* coilMaterial = BDSMaterials::Instance()->GetMaterial("copper");
160 G4LogicalVolume* coilsLV = new G4LogicalVolume(coils, // solid
161 coilMaterial, // material
162 name + "_coils_lv"); // name
163 G4Colour* coil = BDSColours::Instance()->GetColour("coil");
164 G4VisAttributes* coilVisAttr = new G4VisAttributes(*coil);
165 coilVisAttr->SetVisibility(true);
166 coilsLV->SetVisAttributes(coilVisAttr);
167
168 RegisterLogicalVolume(coilsLV);
169
170 // coils placement
171 G4PVPlacement* coilsPV = new G4PVPlacement(nullptr, // rotation
172 G4ThreeVector(0,0,0), // position
173 coilsLV, // its logical volume
174 name + "_coils_pv", // its name
175 containerLogicalVolume,
176 false, // no boolean operation
177 0, // copy number
179 RegisterPhysicalVolume(coilsPV);
180
181 G4Tubs* outer = new G4Tubs(name + "_outer_solid", // name
182 coilOuterRadius + lengthSafetyLarge*10, // inner radius
183 horizontalWidth*0.5 - lengthSafety, // outer radius
184 vacuumLength*0.5, // half length
185 0, CLHEP::twopi); // start and finish angle
186 RegisterSolid(outer);
187 G4LogicalVolume* outerLV = new G4LogicalVolume(outer, // solid
188 outerMaterial, // material
189 name + "_outer_lv"); // name
190 G4Colour* outercolour = BDSColours::Instance()->GetColour("gaborlens");
191 G4VisAttributes* outerVisAttr = new G4VisAttributes(*outercolour);
192 outerVisAttr->SetVisibility(true);
193 outerLV->SetVisAttributes(outerVisAttr);
194
195 RegisterLogicalVolume(outerLV);
196
197 // outer placement
198 G4PVPlacement* outerPV = new G4PVPlacement(nullptr, // rotation
199 G4ThreeVector(0,0,0),// position
200 outerLV, // its logical volume
201 name + "_outer_pv", // its name
202 containerLogicalVolume,
203 false, // no boolean operation
204 0, // copy number
206 RegisterPhysicalVolume(outerPV);
207
208 G4Tubs* endcap = new G4Tubs(name + "_endcap_solid", // name
209 electrodeRadius, // inner radius
210 horizontalWidth*0.5 - lengthSafety, // outer radius
211 endcapsLength*0.5 - lengthSafetyLarge, // half length
212 0, CLHEP::twopi); // start and finish angle
213 RegisterSolid(endcap);
214 G4Material* endcapMaterial = BDSMaterials::Instance()->GetMaterial("stainlesssteel");
215 G4LogicalVolume* endcapLV = new G4LogicalVolume(endcap, // solid
216 endcapMaterial, // material
217 name + "_endcap_lv"); // name
218 G4Colour* endcapcolour = BDSColours::Instance()->GetColour("beampipe");
219 G4VisAttributes* endcapVisAttr = new G4VisAttributes(*endcapcolour);
220 endcapVisAttr->SetVisibility(true);
221 endcapLV->SetVisAttributes(endcapVisAttr);
222
223 RegisterLogicalVolume(endcapLV);
224
225 // end cap placement
226 G4double endcapZ = (chordLength-endcapsLength)*0.5;
227 G4PVPlacement* endcapInPV = new G4PVPlacement(nullptr, // rotation
228 G4ThreeVector(0,0,-endcapZ), // position
229 endcapLV, // its logical volume
230 name + "_endcapIn_pv", // its name
231 containerLogicalVolume,
232 false, // no boolean operation
233 0, // copy number
235 RegisterPhysicalVolume(endcapInPV);
236
237 G4PVPlacement* endcapOutPV = new G4PVPlacement(nullptr, // rotation
238 G4ThreeVector(0,0,endcapZ), // position
239 endcapLV, // its logical volume
240 name + "_endcapOut_pv", // its name
241 containerLogicalVolume,
242 false, // no boolean operation
243 0, // copy number
245 RegisterPhysicalVolume(endcapOutPV);
246}
247
249{
251 BDSBeamPipe* pipe = factory->CreateBeamPipe(name + "_beampipe",
252 vacuumLength,
254 RegisterDaughter(pipe);
255
256 G4PVPlacement* bpPV = new G4PVPlacement(nullptr,
257 G4ThreeVector(),
259 name+"_beampipe_pv",
260 containerLogicalVolume,
261 false,
262 0,
264
266
267 // register vacuum volume (for biasing)
269
270 // update extents
271 InheritExtents(pipe);
272
275 true);
276
277 G4Tubs* anode = new G4Tubs(name + "_anode_solid", // name
278 anodeRadius, // inner radius
279 anodeRadius + anodeThickness, // outer radius
280 anodeLength*0.5, // half length
281 0, CLHEP::twopi); // start and finish angle
282 RegisterSolid(anode);
283
284 G4LogicalVolume* anodeLV = new G4LogicalVolume(anode, // solid
285 anodeMaterial, // material
286 name + "_anode_lv"); // name
287 G4Colour* anodecolour = BDSColours::Instance()->GetColour("coil");
288 G4VisAttributes* anodeVisAttr = new G4VisAttributes(*anodecolour);
289 anodeVisAttr->SetVisibility(true);
290 anodeLV->SetVisAttributes(anodeVisAttr);
291 RegisterLogicalVolume(anodeLV);
292
293 // anode placement
294 G4LogicalVolume* vac = *(GetAcceleratorVacuumLogicalVolumes().begin()); // take the first one
295 G4PVPlacement* anodePV = new G4PVPlacement(nullptr, // rotation
296 G4ThreeVector(0,0,0), // position
297 anodeLV, // its logical volume
298 name + "_anode_pv", // its name
299 vac,
300 false, // no boolean operation
301 0, // copy number
303 RegisterPhysicalVolume(anodePV);
304
305 G4Tubs* electrode = new G4Tubs(name + "_electrode_solid", // name
306 electrodeRadius, // inner radius
307 electrodeRadius + electrodeThickness, // outer radius
308 electrodeLength*0.5 - lengthSafetyLarge, // half length
309 0, CLHEP::twopi); // start and finish angle
310 RegisterSolid(electrode);
311
312 G4LogicalVolume* electrodeLV = new G4LogicalVolume(electrode, // solid
313 electrodeMaterial, // material
314 name + "_electrode_lv"); // name
315 G4Colour* electrodecolour = BDSColours::Instance()->GetColour("copper");
316 G4VisAttributes* electrodeVisAttr = new G4VisAttributes(*electrodecolour);
317 electrodeVisAttr->SetVisibility(true);
318 electrodeLV->SetVisAttributes(electrodeVisAttr);
319 RegisterLogicalVolume(electrodeLV);
320
321 G4double elecZ = chordLength*0.5 - endcapsLength - electrodeLength*0.5 - lengthSafety; // abs(z) electrode position
322
323 // electrode placement
324 G4PVPlacement* electrodeInPV = new G4PVPlacement(nullptr, // rotation
325 G4ThreeVector(0,0,-elecZ), // position
326 electrodeLV, // its logical volume
327 name + "_electrodeIn_pv", // its name
328 vac,
329 false, // no boolean operation
330 0, // copy number
332 RegisterPhysicalVolume(electrodeInPV);
333
334 G4PVPlacement* electrodeOutPV = new G4PVPlacement(nullptr, // rotation
335 G4ThreeVector(0,0,elecZ), // position
336 electrodeLV, // its logical volume
337 name + "_electrodeOut_pv", // its name
338 vac,
339 false, // no boolean operation
340 0, // copy number
342 RegisterPhysicalVolume(electrodeOutPV);
343}
Abstract class that represents a component of an accelerator.
void SetAcceleratorVacuumLogicalVolume(G4LogicalVolume *accVacLVIn)
const G4String name
Const protected member variable that may not be changed by derived classes.
static G4double lengthSafety
Useful variable often used in construction.
static G4bool checkOverlaps
Useful variable often used in construction.
virtual std::set< G4LogicalVolume * > GetAcceleratorVacuumLogicalVolumes() const
Access the 'vacuum' volume(s) in this component if any. Default is empty set.
G4double chordLength
Protected member variable that can be modified by derived classes.
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.
BDSExtent Extent() const
G4Material * vacuumMaterial
Public member for direct access.
G4double IndicativeRadius() const
Return an indicative extent of the beam pipe - typically the maximum of x or y extent.
A holder class for a piece of beam pipe geometry.
G4LogicalVolume * GetVacuumLogicalVolume() const
Access the vacuum volume to set fields and limits.
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.
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:39
G4double MaximumAbsTransverse() const
Return the maximum absolute value considering only x,y.
Definition BDSExtent.cc:171
void RegisterFieldForConstruction(const BDSFieldInfo *info, G4LogicalVolume *logicalVolume, const G4bool propagateToDaughters=false, const BDSMagnetStrength *magnetStrengthForScaling=nullptr, const G4String &scalingKey="none")
static BDSFieldBuilder * Instance()
Singleton pattern accessor.
All info required to build complete field of any type.
void BuildOuter()
Build the outer volume.
BDSGaborLens()=delete
total length of both end caps
virtual void Build()
void BuildBeamPipe()
Build the beam pipe.
virtual void BuildContainerLogicalVolume()
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)
void RegisterSolid(G4VSolid *solid)
static BDSMaterials * Instance()
Singleton pattern access.
G4Material * GetMaterial(G4String material) const
Get material by name.