BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSBeamPipeInfo.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 "BDSBeamPipeInfo.hh"
20#include "BDSBeamPipeType.hh"
21#include "BDSDebug.hh"
22#include "BDSException.hh"
23#include "BDSExtent.hh"
24#include "BDSMaterials.hh"
25#include "BDSUtilities.hh"
26
27#include "globals.hh" // geant4 types / globals
28#include "G4Material.hh"
29
30#include <algorithm>
31#include <array>
32
34 G4double aper1In,
35 G4double aper2In,
36 G4double aper3In,
37 G4double aper4In,
38 G4Material* vacuumMaterialIn,
39 G4double beamPipeThicknessIn,
40 G4Material* beamPipeMaterialIn,
41 const G4ThreeVector& inputFaceNormalIn,
42 const G4ThreeVector& outputFaceNormalIn,
43 const G4String& pointsFileNameIn,
44 const G4String& pointsUnitIn):
45 beamPipeType(beamPipeTypeIn),
46 aper1(aper1In), aper2(aper2In), aper3(aper3In), aper4(aper4In),
47 aperOffsetX(0), aperOffsetY(0),
48 vacuumMaterial(vacuumMaterialIn),
49 beamPipeThickness(beamPipeThicknessIn),
50 beamPipeMaterial(beamPipeMaterialIn),
51 inputFaceNormal(inputFaceNormalIn),
52 outputFaceNormal(outputFaceNormalIn),
53 pointsFileName(pointsFileNameIn),
54 pointsUnit(pointsUnitIn)
55{
57}
58
59BDSBeamPipeInfo::BDSBeamPipeInfo(const G4String& beamPipeTypeIn,
60 G4double aper1In,
61 G4double aper2In,
62 G4double aper3In,
63 G4double aper4In,
64 const G4String& vacuumMaterialIn,
65 G4double beamPipeThicknessIn,
66 const G4String& beamPipeMaterialIn,
67 const G4ThreeVector& inputFaceNormalIn,
68 const G4ThreeVector& outputFaceNormalIn):
69 aper1(aper1In), aper2(aper2In), aper3(aper3In), aper4(aper4In),
70 aperOffsetX(0), aperOffsetY(0),
71 beamPipeThickness(beamPipeThicknessIn),
72 inputFaceNormal(inputFaceNormalIn),
73 outputFaceNormal(outputFaceNormalIn),
74 pointsFileName(""),
75 pointsUnit("mm")
76{
80
81 if (beamPipeType == BDSBeamPipeType::pointsfile)
82 {CheckAndSetPointsInfo(beamPipeTypeIn);}
84}
85
87 const G4String& beamPipeTypeIn,
88 G4double aper1In,
89 G4double aper2In,
90 G4double aper3In,
91 G4double aper4In,
92 const G4String& vacuumMaterialIn,
93 G4double beamPipeThicknessIn,
94 const G4String& beamPipeMaterialIn,
95 const G4ThreeVector& inputFaceNormalIn,
96 const G4ThreeVector& outputFaceNormalIn):
97 aperOffsetX(0), aperOffsetY(0),
98 inputFaceNormal(inputFaceNormalIn),
99 outputFaceNormal(outputFaceNormalIn)
100{
101 if (beamPipeTypeIn.empty())
102 {
103 beamPipeType = defaultInfo->beamPipeType;
104 pointsFileName = defaultInfo->pointsFileName; // copy even if empty
105 pointsUnit = defaultInfo->pointsUnit;
106 }
107 else
108 {
110 if (beamPipeType == BDSBeamPipeType::pointsfile)
111 {CheckAndSetPointsInfo(beamPipeTypeIn);}
112 }
113
114 if (!BDS::IsFinite(aper1In))
115 {aper1 = defaultInfo->aper1;}
116 else
117 {aper1 = aper1In;}
118 if (!BDS::IsFinite(aper2In))
119 {aper2 = defaultInfo->aper2;}
120 else
121 {aper2 = aper2In;}
122 if (!BDS::IsFinite(aper3In))
123 {aper3 = defaultInfo->aper3;}
124 else
125 {aper3 = aper3In;}
126 if (!BDS::IsFinite(aper4In))
127 {aper4 = defaultInfo->aper4;}
128 else
129 {aper4 = aper4In;}
130 if (!BDS::IsFinite(beamPipeThicknessIn))
131 {beamPipeThickness = defaultInfo->beamPipeThickness;}
132 else
133 {beamPipeThickness = beamPipeThicknessIn;}
134
135 if (vacuumMaterialIn.empty())
136 {vacuumMaterial = defaultInfo->vacuumMaterial;}
137 else
138 {vacuumMaterial = BDSMaterials::Instance()->GetMaterial(vacuumMaterialIn);}
139 if (beamPipeMaterialIn.empty())
140 {beamPipeMaterial = defaultInfo->beamPipeMaterial;}
141 else
142 {beamPipeMaterial = BDSMaterials::Instance()->GetMaterial(beamPipeMaterialIn);}
143
145}
146
147
148void BDSBeamPipeInfo::CheckAndSetPointsInfo(const G4String& beamPipeTypeIn)
149{
150 auto typeAndFileName = BDS::SplitOnColon(beamPipeTypeIn); // find first colon
151 G4String fname = typeAndFileName.second;
152 if (BDS::StrContains(fname, ":"))
153 {// optional second colon with units after it
154 auto fileNameAndUnit = BDS::SplitOnColon(fname);
155 pointsFileName = fileNameAndUnit.first;
156 pointsUnit = fileNameAndUnit.second;
157 }
158 else
159 {
160 pointsFileName = fname;
161 pointsUnit = "mm";
162 }
163}
164
165
167{
168 BDSBeamPipeInfo result(*this); // make a copy
169
170 std::array<G4double*, 4> apers {&result.aper1, &result.aper2, &result.aper3, &result.aper4};
171 for (auto var : apers)
172 {
173 if (*var > 0)
174 { *var -= margin;}
175 }
176 return result;
177}
178
180{
181 switch (beamPipeType.underlying())
182 {
183 case BDSBeamPipeType::circular:
184 {InfoOKForCircular(); break;}
185 case BDSBeamPipeType::elliptical:
186 {InfoOKForElliptical(); break;}
187 case BDSBeamPipeType::rectangular:
188 {InfoOKForRectangular(); break;}
189 case BDSBeamPipeType::lhc:
190 {InfoOKForLHC(); break;}
191 case BDSBeamPipeType::lhcdetailed:
192 {InfoOKForLHCDetailed(); break;}
193 case BDSBeamPipeType::rectellipse:
194 {InfoOKForRectEllipse(); break;}
195 case BDSBeamPipeType::racetrack:
196 {InfoOKForRaceTrack(); break;}
197 case BDSBeamPipeType::octagonal:
198 {InfoOKForOctagonal(); break;}
199 case BDSBeamPipeType::clicpcl:
200 {InfoOKForClicPCL(); break;}
201 case BDSBeamPipeType::rhombus:
202 {InfoOKForRhombus(); break;}
203 default:
204 {InfoOKForCircular(); break;}
205 }
206}
207
209{
210 G4double extX = 0;
211 G4double extY = 0;
212 switch (beamPipeType.underlying())
213 {
214 case BDSBeamPipeType::circular:
215 case BDSBeamPipeType::circularvacuum:
216 {
217 extX = aper1;
218 extY = aper1;
219 break;
220 }
221 case BDSBeamPipeType::elliptical:
222 case BDSBeamPipeType::rectangular:
223 case BDSBeamPipeType::octagonal:
224 case BDSBeamPipeType::rhombus:
225 {
226 extX = aper1;
227 extY = aper2;
228 break;
229 }
230 case BDSBeamPipeType::lhc:
231 case BDSBeamPipeType::lhcdetailed:
232 case BDSBeamPipeType::rectellipse:
233 {
234 extX = std::min(aper1, aper3);
235 extY = std::min(aper2, aper3);
236 break;
237 }
238 case BDSBeamPipeType::racetrack:
239 {
240 extX = aper1 + aper3;
241 extY = aper2 + aper3;
242 break;
243 }
244 case BDSBeamPipeType::clicpcl:
245 {// this one is asymmetric so done separately
246 G4double extentX = aper1 + beamPipeThickness;
247 G4double extentYLow = -(std::abs(aper3) + beamPipeThickness);
248 G4double extentYHigh = aper2 + aper4 + beamPipeThickness;
249 BDSExtent ext = BDSExtent(-extentX, extentX,
250 extentYLow, extentYHigh,
251 0,0);
252 return ext;
253 break;
254 }
255 default:break;
256 }
257 BDSExtent ext = BDSExtent(extX, extY, 0);
258 return ext;
259}
260
262{
263 BDSExtent extentInner = ExtentInner();
264 G4double extX = extentInner.XPos(); // +ve values
265 G4double extY = extentInner.YPos();
266 extX += beamPipeThickness;
267 extY += beamPipeThickness;
268 return BDSExtent(extX, extY, 0);
269}
270
272{
273 BDSExtent ext = Extent();
274 return ext.MaximumAbsTransverse();
275}
276
278{
279 BDSExtent ext = ExtentInner();
280 return ext.MinimumAbsTransverse();
281}
282
284 G4bool setAper2,
285 G4bool setAper3,
286 G4bool setAper4)
287{
288 G4bool shouldExit = false;
289 if (setAper1)
290 {
291 if (!BDS::IsFinite(aper1))
292 {G4cerr << "\"aper1\" not set, but required to be" << G4endl; shouldExit = true;}
293 }
294
295 if (setAper2)
296 {
297 if (!BDS::IsFinite(aper2))
298 {G4cerr << "\"aper2\" not set, but required to be" << G4endl; shouldExit = true;}
299 }
300
301 if (setAper3)
302 {
303 if (!BDS::IsFinite(aper3))
304 {G4cerr << "\"aper3\" not set, but required to be" << G4endl; shouldExit = true;}
305 }
306
307 if (setAper4)
308 {
309 if (!BDS::IsFinite(aper4))
310 {G4cerr << "\"aper4\" not set, but required to be" << G4endl; shouldExit = true;}
311 }
312
313 if (shouldExit)
314 {throw BDSException(__METHOD_NAME__, "aperture parameter missing");}
315}
316
318{
319 CheckRequiredParametersSet(true, false, false, false);
320}
321
323{
324 CheckRequiredParametersSet(true, true, false, false);
325}
326
328{
329 CheckRequiredParametersSet(true, true, false, false);
330}
331
333{
334 CheckRequiredParametersSet(true, true, true, false);
335
336 if ((aper3 > aper1) && (aper2 < aper3))
337 {throw BDSException(__METHOD_NAME__, "\"aper3\" > \"aper1\" (or \"beamPipeRadius\") for lhc aperture model - will not produce desired shape");}
338
339 if ((aper3 > aper2) && (aper1 < aper3))
340 {throw BDSException(__METHOD_NAME__, "\"aper3\" > \"aper2\" (or \"beamPipeRadius\") for lhc aperture model - will not produce desired shape");}
341}
342
347
349{
350 CheckRequiredParametersSet(true, true, true, true);
351
352 // TODO
353}
354
356{
357 CheckRequiredParametersSet(true, true, true, false);
358}
359
361{
362 CheckRequiredParametersSet(true, true, true, true);
363
364 if (aper3 >= aper1)
365 {throw BDSException(__METHOD_NAME__, "aper3 is >= aper1 - invalid for an octagonal aperture");}
366 if (aper4 >= aper2)
367 {throw BDSException(__METHOD_NAME__, "aper4 is >= aper2 - invalid for an octagonal aperture");}
368}
369
371{
372 CheckRequiredParametersSet(true, true, true, false);
373}
374
376{
377 CheckRequiredParametersSet(true, true, false, false);
378
379 if (aper1 <= 0)
380 {throw BDSException(__METHOD_NAME__, "aper1 is <= 0 - invalid for a rhombus aperture");}
381 if (aper2 <= 0)
382 {throw BDSException(__METHOD_NAME__, "aper2 is <= 0 - invalid for a rhombus aperture");}
383 if (aper3 < 0)
384 {throw BDSException(__METHOD_NAME__, "aper3 is < 0 - invalid for a rhombus aperture");}
385 if (aper3 > 1.1*aper1)
386 {throw BDSException(__METHOD_NAME__, "aper3 is > 1.1 x aper1 - invalid for a rhombus aperture");}
387 if (aper3 > 1.1*aper2)
388 {throw BDSException(__METHOD_NAME__, "aper3 is > 1.1 x aper2 - invalid for a rhombus aperture");}
389}
Holder class for all information required to describe a beam pipe model.
G4double IndicativeRadiusInner() const
Return an indicative inner extent for the beam pipe vacuum.
BDSExtent Extent() const
G4Material * beamPipeMaterial
Public member for direct access.
G4double aper3
Public member for direct access.
G4String pointsUnit
Public member for direct access.
BDSBeamPipeInfo()=delete
Deleted default constructor to ensure one of supplied constructors is used.
void InfoOKForLHC()
Aperture info check for lhc aperture.
BDSBeamPipeInfo ShrinkBy(G4double margin) const
Return a copy that's shrunk by value margin.
G4double aper1
Public member for direct access.
void InfoOKForOctagonal()
Aperture info check for octagonal aperture.
G4Material * vacuumMaterial
Public member for direct access.
void CheckAndSetPointsInfo(const G4String &beamPipeTypeIn)
Parse the type string to extract the file name and the optional units and assign to member variables.
void InfoOKForClicPCL()
Aperture info check for CLIC PCL aperture.
G4double beamPipeThickness
Public member for direct access.
void InfoOKForRaceTrack()
Aperture info check for racetrack aperture.
void InfoOKForElliptical()
Aperture info check for elliptical aperture.
BDSExtent ExtentInner() const
Return an extent for just the raw aperture.
void InfoOKForRectEllipse()
Aperture info check for rectellipse aperture.
void InfoOKForRhombus()
Aperture info check for Rhombus aperture.
G4String pointsFileName
Public member for direct access.
G4double aper4
Public member for direct access.
void InfoOKForLHCDetailed()
Aperture info check for lhc detailed aperture.
void InfoOKForCircular()
Aperture info check for circular aperture.
void CheckRequiredParametersSet(G4bool setAper1, G4bool setAper2, G4bool setAper3, G4bool setAper4)
void InfoOKForRectangular()
Aperture info check for rectangular aperture.
G4double IndicativeRadius() const
Return an indicative extent of the beam pipe - typically the maximum of x or y extent.
G4double aper2
Public member for direct access.
BDSBeamPipeType beamPipeType
Public member for direct access.
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:39
G4double XPos() const
Accessor.
Definition BDSExtent.hh:66
G4double MaximumAbsTransverse() const
Return the maximum absolute value considering only x,y.
Definition BDSExtent.cc:171
G4double MinimumAbsTransverse() const
Return the minimum absolute value considering only x,y.
Definition BDSExtent.cc:177
G4double YPos() const
Accessor.
Definition BDSExtent.hh:68
static BDSMaterials * Instance()
Singleton pattern access.
G4Material * GetMaterial(G4String material) const
Get material by name.
type underlying() const
return underlying value (can be used in switch statement)
std::pair< G4String, G4String > SplitOnColon(const G4String &formatAndPath)
G4bool StrContains(const G4String &str, const G4String &test)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
BDSBeamPipeType DetermineBeamPipeType(G4String apertureType)
Function that gives corresponding enum value for string (case-insensitive).
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())