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) 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 "BDSBeamPipeInfo.hh"
19#include "BDSBeamPipeType.hh"
20#include "BDSDebug.hh"
21#include "BDSException.hh"
22#include "BDSExtent.hh"
23#include "BDSMaterials.hh"
24#include "BDSUtilities.hh"
25
26#include "globals.hh" // geant4 types / globals
27#include "G4Material.hh"
28
29#include <algorithm>
30#include <array>
31
33 G4double aper1In,
34 G4double aper2In,
35 G4double aper3In,
36 G4double aper4In,
37 G4Material* vacuumMaterialIn,
38 G4double beamPipeThicknessIn,
39 G4Material* beamPipeMaterialIn,
40 const G4ThreeVector& inputFaceNormalIn,
41 const G4ThreeVector& outputFaceNormalIn,
42 const G4String& pointsFileNameIn,
43 const G4String& pointsUnitIn):
44 beamPipeType(beamPipeTypeIn),
45 aper1(aper1In), aper2(aper2In), aper3(aper3In), aper4(aper4In),
46 aperOffsetX(0), aperOffsetY(0),
47 vacuumMaterial(vacuumMaterialIn),
48 beamPipeThickness(beamPipeThicknessIn),
49 beamPipeMaterial(beamPipeMaterialIn),
50 inputFaceNormal(inputFaceNormalIn),
51 outputFaceNormal(outputFaceNormalIn),
52 pointsFileName(pointsFileNameIn),
53 pointsUnit(pointsUnitIn)
54{
56}
57
58BDSBeamPipeInfo::BDSBeamPipeInfo(const G4String& beamPipeTypeIn,
59 G4double aper1In,
60 G4double aper2In,
61 G4double aper3In,
62 G4double aper4In,
63 const G4String& vacuumMaterialIn,
64 G4double beamPipeThicknessIn,
65 const G4String& beamPipeMaterialIn,
66 const G4ThreeVector& inputFaceNormalIn,
67 const G4ThreeVector& outputFaceNormalIn):
68 aper1(aper1In), aper2(aper2In), aper3(aper3In), aper4(aper4In),
69 aperOffsetX(0), aperOffsetY(0),
70 beamPipeThickness(beamPipeThicknessIn),
71 inputFaceNormal(inputFaceNormalIn),
72 outputFaceNormal(outputFaceNormalIn),
73 pointsFileName(""),
74 pointsUnit("mm")
75{
79
80 if (beamPipeType == BDSBeamPipeType::pointsfile)
81 {CheckAndSetPointsInfo(beamPipeTypeIn);}
83}
84
86 const G4String& beamPipeTypeIn,
87 G4double aper1In,
88 G4double aper2In,
89 G4double aper3In,
90 G4double aper4In,
91 const G4String& vacuumMaterialIn,
92 G4double beamPipeThicknessIn,
93 const G4String& beamPipeMaterialIn,
94 const G4ThreeVector& inputFaceNormalIn,
95 const G4ThreeVector& outputFaceNormalIn):
96 aperOffsetX(0), aperOffsetY(0),
97 inputFaceNormal(inputFaceNormalIn),
98 outputFaceNormal(outputFaceNormalIn)
99{
100 if (beamPipeTypeIn.empty())
101 {
102 beamPipeType = defaultInfo->beamPipeType;
103 pointsFileName = defaultInfo->pointsFileName; // copy even if empty
104 pointsUnit = defaultInfo->pointsUnit;
105 }
106 else
107 {
109 if (beamPipeType == BDSBeamPipeType::pointsfile)
110 {CheckAndSetPointsInfo(beamPipeTypeIn);}
111 }
112
113 if (!BDS::IsFinite(aper1In))
114 {aper1 = defaultInfo->aper1;}
115 else
116 {aper1 = aper1In;}
117 if (!BDS::IsFinite(aper2In))
118 {aper2 = defaultInfo->aper2;}
119 else
120 {aper2 = aper2In;}
121 if (!BDS::IsFinite(aper3In))
122 {aper3 = defaultInfo->aper3;}
123 else
124 {aper3 = aper3In;}
125 if (!BDS::IsFinite(aper4In))
126 {aper4 = defaultInfo->aper4;}
127 else
128 {aper4 = aper4In;}
129 if (!BDS::IsFinite(beamPipeThicknessIn))
130 {beamPipeThickness = defaultInfo->beamPipeThickness;}
131 else
132 {beamPipeThickness = beamPipeThicknessIn;}
133
134 if (vacuumMaterialIn.empty())
135 {vacuumMaterial = defaultInfo->vacuumMaterial;}
136 else
137 {vacuumMaterial = BDSMaterials::Instance()->GetMaterial(vacuumMaterialIn);}
138 if (beamPipeMaterialIn.empty())
139 {beamPipeMaterial = defaultInfo->beamPipeMaterial;}
140 else
141 {beamPipeMaterial = BDSMaterials::Instance()->GetMaterial(beamPipeMaterialIn);}
142
144}
145
146
147void BDSBeamPipeInfo::CheckAndSetPointsInfo(const G4String& beamPipeTypeIn)
148{
149 auto typeAndFileName = BDS::SplitOnColon(beamPipeTypeIn); // find first colon
150 G4String fname = typeAndFileName.second;
151 if (BDS::StrContains(fname, ":"))
152 {// optional second colon with units after it
153 auto fileNameAndUnit = BDS::SplitOnColon(fname);
154 pointsFileName = fileNameAndUnit.first;
155 pointsUnit = fileNameAndUnit.second;
156 }
157 else
158 {
159 pointsFileName = fname;
160 pointsUnit = "mm";
161 }
162}
163
164
166{
167 BDSBeamPipeInfo result(*this); // make a copy
168
169 std::array<G4double*, 4> apers {&result.aper1, &result.aper2, &result.aper3, &result.aper4};
170 for (auto var : apers)
171 {
172 if (*var > 0)
173 { *var -= margin;}
174 }
175 return result;
176}
177
179{
180 switch (beamPipeType.underlying())
181 {
182 case BDSBeamPipeType::circular:
183 {InfoOKForCircular(); break;}
184 case BDSBeamPipeType::elliptical:
185 {InfoOKForElliptical(); break;}
186 case BDSBeamPipeType::rectangular:
187 {InfoOKForRectangular(); break;}
188 case BDSBeamPipeType::lhc:
189 {InfoOKForLHC(); break;}
190 case BDSBeamPipeType::lhcdetailed:
191 {InfoOKForLHCDetailed(); break;}
192 case BDSBeamPipeType::rectellipse:
193 {InfoOKForRectEllipse(); break;}
194 case BDSBeamPipeType::racetrack:
195 {InfoOKForRaceTrack(); break;}
196 case BDSBeamPipeType::octagonal:
197 {InfoOKForOctagonal(); break;}
198 case BDSBeamPipeType::clicpcl:
199 {InfoOKForClicPCL(); break;}
200 case BDSBeamPipeType::rhombus:
201 {InfoOKForRhombus(); break;}
202 default:
203 {InfoOKForCircular(); break;}
204 }
205}
206
208{
209 G4double extX = 0;
210 G4double extY = 0;
211 switch (beamPipeType.underlying())
212 {
213 case BDSBeamPipeType::circular:
214 case BDSBeamPipeType::circularvacuum:
215 {
216 extX = aper1;
217 extY = aper1;
218 break;
219 }
220 case BDSBeamPipeType::elliptical:
221 case BDSBeamPipeType::rectangular:
222 case BDSBeamPipeType::octagonal:
223 case BDSBeamPipeType::rhombus:
224 {
225 extX = aper1;
226 extY = aper2;
227 break;
228 }
229 case BDSBeamPipeType::lhc:
230 case BDSBeamPipeType::lhcdetailed:
231 case BDSBeamPipeType::rectellipse:
232 {
233 extX = std::min(aper1, aper3);
234 extY = std::min(aper2, aper3);
235 break;
236 }
237 case BDSBeamPipeType::racetrack:
238 {
239 extX = aper1 + aper3;
240 extY = aper2 + aper3;
241 break;
242 }
243 case BDSBeamPipeType::clicpcl:
244 {// this one is asymmetric so done separately
245 G4double extentX = aper1 + beamPipeThickness;
246 G4double extentYLow = -(std::abs(aper3) + beamPipeThickness);
247 G4double extentYHigh = aper2 + aper4 + beamPipeThickness;
248 BDSExtent ext = BDSExtent(-extentX, extentX,
249 extentYLow, extentYHigh,
250 0,0);
251 return ext;
252 break;
253 }
254 default:break;
255 }
256 BDSExtent ext = BDSExtent(extX, extY, 0);
257 return ext;
258}
259
261{
262 BDSExtent extentInner = ExtentInner();
263 G4double extX = extentInner.XPos(); // +ve values
264 G4double extY = extentInner.YPos();
265 extX += beamPipeThickness;
266 extY += beamPipeThickness;
267 return BDSExtent(extX, extY, 0);
268}
269
271{
272 BDSExtent ext = Extent();
273 return ext.MaximumAbsTransverse();
274}
275
277{
278 BDSExtent ext = ExtentInner();
279 return ext.MinimumAbsTransverse();
280}
281
283 G4bool setAper2,
284 G4bool setAper3,
285 G4bool setAper4)
286{
287 G4bool shouldExit = false;
288 if (setAper1)
289 {
290 if (!BDS::IsFinite(aper1))
291 {G4cerr << "\"aper1\" not set, but required to be" << G4endl; shouldExit = true;}
292 }
293
294 if (setAper2)
295 {
296 if (!BDS::IsFinite(aper2))
297 {G4cerr << "\"aper2\" not set, but required to be" << G4endl; shouldExit = true;}
298 }
299
300 if (setAper3)
301 {
302 if (!BDS::IsFinite(aper3))
303 {G4cerr << "\"aper3\" not set, but required to be" << G4endl; shouldExit = true;}
304 }
305
306 if (setAper4)
307 {
308 if (!BDS::IsFinite(aper4))
309 {G4cerr << "\"aper4\" not set, but required to be" << G4endl; shouldExit = true;}
310 }
311
312 if (shouldExit)
313 {throw BDSException(__METHOD_NAME__, "aperture parameter missing");}
314}
315
317{
318 CheckRequiredParametersSet(true, false, false, false);
319}
320
322{
323 CheckRequiredParametersSet(true, true, false, false);
324}
325
327{
328 CheckRequiredParametersSet(true, true, false, false);
329}
330
332{
333 CheckRequiredParametersSet(true, true, true, false);
334
335 if ((aper3 > aper1) && (aper2 < aper3))
336 {throw BDSException(__METHOD_NAME__, "\"aper3\" > \"aper1\" (or \"beamPipeRadius\") for lhc aperture model - will not produce desired shape");}
337
338 if ((aper3 > aper2) && (aper1 < aper3))
339 {throw BDSException(__METHOD_NAME__, "\"aper3\" > \"aper2\" (or \"beamPipeRadius\") for lhc aperture model - will not produce desired shape");}
340}
341
346
348{
349 CheckRequiredParametersSet(true, true, true, true);
350
351 // TODO
352}
353
355{
356 CheckRequiredParametersSet(true, true, true, false);
357}
358
360{
361 CheckRequiredParametersSet(true, true, true, true);
362
363 if (aper3 >= aper1)
364 {throw BDSException(__METHOD_NAME__, "aper3 is >= aper1 - invalid for an octagonal aperture");}
365 if (aper4 >= aper2)
366 {throw BDSException(__METHOD_NAME__, "aper4 is >= aper2 - invalid for an octagonal aperture");}
367}
368
370{
371 CheckRequiredParametersSet(true, true, true, false);
372}
373
375{
376 CheckRequiredParametersSet(true, true, false, false);
377
378 if (aper1 <= 0)
379 {throw BDSException(__METHOD_NAME__, "aper1 is <= 0 - invalid for a rhombus aperture");}
380 if (aper2 <= 0)
381 {throw BDSException(__METHOD_NAME__, "aper2 is <= 0 - invalid for a rhombus aperture");}
382 if (aper3 < 0)
383 {throw BDSException(__METHOD_NAME__, "aper3 is < 0 - invalid for a rhombus aperture");}
384 if (aper3 > 1.1*aper1)
385 {throw BDSException(__METHOD_NAME__, "aper3 is > 1.1 x aper1 - invalid for a rhombus aperture");}
386 if (aper3 > 1.1*aper2)
387 {throw BDSException(__METHOD_NAME__, "aper3 is > 1.1 x aper2 - invalid for a rhombus aperture");}
388}
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:38
G4double XPos() const
Accessor.
Definition BDSExtent.hh:65
G4double MaximumAbsTransverse() const
Return the maximum absolute value considering only x,y.
Definition BDSExtent.cc:170
G4double MinimumAbsTransverse() const
Return the minimum absolute value considering only x,y.
Definition BDSExtent.cc:176
G4double YPos() const
Accessor.
Definition BDSExtent.hh:67
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())