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) 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 "BDSAcceleratorComponent.hh"
19#include "BDSBeamPipe.hh"
20#include "BDSBeamPipeFactory.hh"
21#include "BDSBeamPipeInfo.hh"
22#include "BDSColours.hh"
23#include "BDSDebug.hh"
24#include "BDSFieldBuilder.hh"
25#include "BDSFieldInfo.hh"
26#include "BDSGaborLens.hh"
27#include "BDSExtent.hh"
28#include "BDSException.hh"
29#include "BDSMaterials.hh"
30#include "BDSSDType.hh"
31
32#include "G4Box.hh"
33#include "G4ExtrudedSolid.hh"
34#include "G4LogicalVolume.hh"
35#include "G4PVPlacement.hh"
36#include "G4RotationMatrix.hh"
37#include "G4Tubs.hh"
38#include "G4TwoVector.hh"
39#include "G4ThreeVector.hh"
40#include "G4VisAttributes.hh"
41#include "G4VSolid.hh"
42
43#include "globals.hh" // geant4 globals / types
44#include <string>
45#include <vector>
46
47#include "CLHEP/Units/SystemOfUnits.h"
48
49BDSGaborLens::BDSGaborLens(const G4String& nameIn,
50 G4double lengthIn,
51 G4double horizontalWidthIn,
52 G4double anodeLengthIn,
53 G4Material* anodeMaterialIn,
54 G4double anodeRadiusIn,
55 G4double anodeThicknessIn,
56 G4double electrodeLengthIn,
57 G4Material* electrodeMaterialIn,
58 G4double electrodeRadiusIn,
59 G4double electrodeThicknessIn,
60 G4Material* outerMaterialIn,
61 G4Colour* colourIn,
62 BDSBeamPipeInfo* beamPipeInfoIn,
63 BDSFieldInfo* vacuumFieldInfoIn):
64 BDSAcceleratorComponent(nameIn, lengthIn, 0, "gaborlens", beamPipeInfoIn),
65 horizontalWidth(horizontalWidthIn),
66 anodeRadius(anodeRadiusIn),
67 anodeLength(anodeLengthIn),
68 anodeMaterial(anodeMaterialIn),
69 anodeThickness(anodeThicknessIn),
70 electrodeRadius(electrodeRadiusIn),
71 electrodeLength(electrodeLengthIn),
72 electrodeMaterial(electrodeMaterialIn),
73 electrodeThickness(electrodeThicknessIn),
74 outerMaterial(outerMaterialIn),
75 colour(colourIn),
76 vacuumFieldInfo(vacuumFieldInfoIn)
77{
78 if (vacuumFieldInfo)
79 {vacuumFieldInfo->SetBeamPipeRadius(beamPipeInfoIn->IndicativeRadius());}
80
81 endcapsLength = 10;
82
83 if (chordLength <= endcapsLength)
84 {throw BDSException(__METHOD_NAME__,"the element length must be greater than 20 mm for element \"" + name + "\"");}
85
86 vacuumLength = chordLength - 2*endcapsLength;
87
88 // Input Checks
89 if (horizontalWidth <= 0)
90 {throw BDSException(__METHOD_NAME__,"option \"horizontalWidth\" is not defined or must be greater than 0 for element \"" + name + "\"");}
91
92 if (anodeLength <= 0)
93 {throw BDSException(__METHOD_NAME__,"option \"anodeLength\" is not defined or must be greater than 0 for element \"" + name + "\"");}
94
95 if (anodeRadius <= 0)
96 {throw BDSException(__METHOD_NAME__,"option \"anodeRadius\" is not defined or must be greater than 0 for element \"" + name + "\"");}
97
98 if (anodeThickness <= 0)
99 {throw BDSException(__METHOD_NAME__,"option \"anodeThickness\" is not defined or must be greater than 0 for element \"" + name + "\"");}
100
101 if (electrodeLength <= 0)
102 {throw BDSException(__METHOD_NAME__,"option \"electrodeLength\" is not defined or must be greater than 0 for element \"" + name + "\"");}
103
104 if (electrodeRadius <= 0)
105 {throw BDSException(__METHOD_NAME__,"option \"electrodeRadius\" is not defined or must be greater than 0 for element \"" + name + "\"");}
106
107 if (electrodeThickness <= 0)
108 {throw BDSException(__METHOD_NAME__,"option \"electrodeThickness\" is not defined or must be greater than 0 for element \"" + name + "\"");}
109
110 if ((anodeRadius + anodeThickness) > beamPipeInfo->ExtentInner().MinimumAbsTransverse())
111 {throw BDSException(__METHOD_NAME__,"\"anodeRadius\" must be smaller than the beam pipe aperture for element \"" + name + "\"");}
112
113 if (anodeLength > vacuumLength)
114 {throw BDSException(__METHOD_NAME__,"\"anodeLength\" must be shorter than the element length minus 20mm for element \"" + name + "\"");}
115
116 if ((electrodeRadius + electrodeThickness) > anodeRadius)
117 {throw BDSException(__METHOD_NAME__,"\"anodeRadius\" cannot be smaller than \"electrodeRadius\" + \"electrodeThickness\" for element \"" + name + "\"");}
118
119 if (electrodeLength > 0.5*vacuumLength)
120 {throw BDSException(__METHOD_NAME__,"\"electrodeLength\" must be smaller than half element length minus 20mm for element \"" + name + "\"");}
121
122}
123
124BDSGaborLens::~BDSGaborLens()
125{;}
126
128{
129 containerSolid = new G4Tubs(name + "_container_solid",
130 0, horizontalWidth + lengthSafety,
131 chordLength*0.5,
132 0, CLHEP::twopi);
133
134 containerLogicalVolume = new G4LogicalVolume(containerSolid,
136 name + "_container_lv");
137}
138
145
147{
148 BDSExtent extent = beamPipeInfo->Extent();
149 G4double bpMaxExtent = extent.MaximumAbsTransverse();
150
151 G4double coilOuterRadius = horizontalWidth*0.5 *0.9;
152 G4Tubs* coils = new G4Tubs(name + "_coils_solid", // name
153 bpMaxExtent + lengthSafetyLarge*2, // inner radius
154 coilOuterRadius, // outer radius
155 0.5*(vacuumLength- lengthSafetyLarge*10), // half length
156 0, CLHEP::twopi); // start and finish angle
157 RegisterSolid(coils);
158 G4Material* coilMaterial = BDSMaterials::Instance()->GetMaterial("copper");
159 G4LogicalVolume* coilsLV = new G4LogicalVolume(coils, // solid
160 coilMaterial, // material
161 name + "_coils_lv"); // name
162 G4Colour* coil = BDSColours::Instance()->GetColour("coil");
163 G4VisAttributes* coilVisAttr = new G4VisAttributes(*coil);
164 coilVisAttr->SetVisibility(true);
165 coilsLV->SetVisAttributes(coilVisAttr);
166
167 RegisterLogicalVolume(coilsLV);
168
169 // coils placement
170 G4PVPlacement* coilsPV = new G4PVPlacement(nullptr, // rotation
171 G4ThreeVector(0,0,0), // position
172 coilsLV, // its logical volume
173 name + "_coils_pv", // its name
174 containerLogicalVolume,
175 false, // no boolean operation
176 0, // copy number
178 RegisterPhysicalVolume(coilsPV);
179
180 G4Tubs* outer = new G4Tubs(name + "_outer_solid", // name
181 coilOuterRadius + lengthSafetyLarge*10, // inner radius
182 horizontalWidth*0.5 - lengthSafety, // outer radius
183 vacuumLength*0.5, // half length
184 0, CLHEP::twopi); // start and finish angle
185 RegisterSolid(outer);
186 G4LogicalVolume* outerLV = new G4LogicalVolume(outer, // solid
187 outerMaterial, // material
188 name + "_outer_lv"); // name
189 G4Colour* outercolour = BDSColours::Instance()->GetColour("gaborlens");
190 G4VisAttributes* outerVisAttr = new G4VisAttributes(*outercolour);
191 outerVisAttr->SetVisibility(true);
192 outerLV->SetVisAttributes(outerVisAttr);
193
194 RegisterLogicalVolume(outerLV);
195
196 // outer placement
197 G4PVPlacement* outerPV = new G4PVPlacement(nullptr, // rotation
198 G4ThreeVector(0,0,0),// position
199 outerLV, // its logical volume
200 name + "_outer_pv", // its name
201 containerLogicalVolume,
202 false, // no boolean operation
203 0, // copy number
205 RegisterPhysicalVolume(outerPV);
206
207 G4Tubs* endcap = new G4Tubs(name + "_endcap_solid", // name
208 electrodeRadius, // inner radius
209 horizontalWidth*0.5 - lengthSafety, // outer radius
210 endcapsLength*0.5 - lengthSafetyLarge, // half length
211 0, CLHEP::twopi); // start and finish angle
212 RegisterSolid(endcap);
213 G4Material* endcapMaterial = BDSMaterials::Instance()->GetMaterial("stainlesssteel");
214 G4LogicalVolume* endcapLV = new G4LogicalVolume(endcap, // solid
215 endcapMaterial, // material
216 name + "_endcap_lv"); // name
217 G4Colour* endcapcolour = BDSColours::Instance()->GetColour("beampipe");
218 G4VisAttributes* endcapVisAttr = new G4VisAttributes(*endcapcolour);
219 endcapVisAttr->SetVisibility(true);
220 endcapLV->SetVisAttributes(endcapVisAttr);
221
222 RegisterLogicalVolume(endcapLV);
223
224 // end cap placement
225 G4double endcapZ = (chordLength-endcapsLength)*0.5;
226 G4PVPlacement* endcapInPV = new G4PVPlacement(nullptr, // rotation
227 G4ThreeVector(0,0,-endcapZ), // position
228 endcapLV, // its logical volume
229 name + "_endcapIn_pv", // its name
230 containerLogicalVolume,
231 false, // no boolean operation
232 0, // copy number
234 RegisterPhysicalVolume(endcapInPV);
235
236 G4PVPlacement* endcapOutPV = new G4PVPlacement(nullptr, // rotation
237 G4ThreeVector(0,0,endcapZ), // position
238 endcapLV, // its logical volume
239 name + "_endcapOut_pv", // its name
240 containerLogicalVolume,
241 false, // no boolean operation
242 0, // copy number
244 RegisterPhysicalVolume(endcapOutPV);
245}
246
248{
250 BDSBeamPipe* pipe = factory->CreateBeamPipe(name + "_beampipe",
251 vacuumLength,
253 RegisterDaughter(pipe);
254
255 G4PVPlacement* bpPV = new G4PVPlacement(nullptr,
256 G4ThreeVector(),
258 name+"_beampipe_pv",
259 containerLogicalVolume,
260 false,
261 0,
263
265
266 // register vacuum volume (for biasing)
268
269 // update extents
270 InheritExtents(pipe);
271
274 true);
275
276 G4Tubs* anode = new G4Tubs(name + "_anode_solid", // name
277 anodeRadius, // inner radius
278 anodeRadius + anodeThickness, // outer radius
279 anodeLength*0.5, // half length
280 0, CLHEP::twopi); // start and finish angle
281 RegisterSolid(anode);
282
283 G4LogicalVolume* anodeLV = new G4LogicalVolume(anode, // solid
284 anodeMaterial, // material
285 name + "_anode_lv"); // name
286 G4Colour* anodecolour = BDSColours::Instance()->GetColour("coil");
287 G4VisAttributes* anodeVisAttr = new G4VisAttributes(*anodecolour);
288 anodeVisAttr->SetVisibility(true);
289 anodeLV->SetVisAttributes(anodeVisAttr);
290 RegisterLogicalVolume(anodeLV);
291
292 // anode placement
293 G4LogicalVolume* vac = *(GetAcceleratorVacuumLogicalVolumes().begin()); // take the first one
294 G4PVPlacement* anodePV = new G4PVPlacement(nullptr, // rotation
295 G4ThreeVector(0,0,0), // position
296 anodeLV, // its logical volume
297 name + "_anode_pv", // its name
298 vac,
299 false, // no boolean operation
300 0, // copy number
302 RegisterPhysicalVolume(anodePV);
303
304 G4Tubs* electrode = new G4Tubs(name + "_electrode_solid", // name
305 electrodeRadius, // inner radius
306 electrodeRadius + electrodeThickness, // outer radius
307 electrodeLength*0.5 - lengthSafetyLarge, // half length
308 0, CLHEP::twopi); // start and finish angle
309 RegisterSolid(electrode);
310
311 G4LogicalVolume* electrodeLV = new G4LogicalVolume(electrode, // solid
312 electrodeMaterial, // material
313 name + "_electrode_lv"); // name
314 G4Colour* electrodecolour = BDSColours::Instance()->GetColour("copper");
315 G4VisAttributes* electrodeVisAttr = new G4VisAttributes(*electrodecolour);
316 electrodeVisAttr->SetVisibility(true);
317 electrodeLV->SetVisAttributes(electrodeVisAttr);
318 RegisterLogicalVolume(electrodeLV);
319
320 G4double elecZ = chordLength*0.5 - endcapsLength - electrodeLength*0.5 - lengthSafety; // abs(z) electrode position
321
322 // electrode placement
323 G4PVPlacement* electrodeInPV = new G4PVPlacement(nullptr, // rotation
324 G4ThreeVector(0,0,-elecZ), // position
325 electrodeLV, // its logical volume
326 name + "_electrodeIn_pv", // its name
327 vac,
328 false, // no boolean operation
329 0, // copy number
331 RegisterPhysicalVolume(electrodeInPV);
332
333 G4PVPlacement* electrodeOutPV = new G4PVPlacement(nullptr, // rotation
334 G4ThreeVector(0,0,elecZ), // position
335 electrodeLV, // its logical volume
336 name + "_electrodeOut_pv", // its name
337 vac,
338 false, // no boolean operation
339 0, // copy number
341 RegisterPhysicalVolume(electrodeOutPV);
342}
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:32
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:38
G4double MaximumAbsTransverse() const
Return the maximum absolute value considering only x,y.
Definition BDSExtent.cc:170
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.