BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSCurvilinearBuilder.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 "BDSAcceleratorComponentRegistry.hh"
20#include "BDSBeamline.hh"
21#include "BDSBeamlineElement.hh"
22#include "BDSExtent.hh"
23#include "BDSCurvilinearBuilder.hh"
24#include "BDSCurvilinearFactory.hh"
25#include "BDSGlobalConstants.hh"
26#include "BDSSimpleComponent.hh"
27#include "BDSSamplerType.hh"
28#include "BDSTiltOffset.hh"
29#include "BDSTunnelInfo.hh"
30#include "BDSUtilities.hh"
31#include "BDSWarning.hh"
32
33#include "globals.hh" // geant4 types / globals
34#include "G4ThreeVector.hh"
35#include "G4RotationMatrix.hh"
36
37#include <algorithm>
38#include <cmath>
39#include <iterator>
40
41BDSCurvilinearBuilder::BDSCurvilinearBuilder()
42{
43 const BDSGlobalConstants* globals = BDSGlobalConstants::Instance(); // shortcut
44
46 defaultBridgeLength = paddingLength + 4*globals->LengthSafety();
47 curvilinearRadius = globals->CurvilinearDiameter()*0.5;
48 radiusTolerance = 0.8;
49 if (globals->BuildTunnel() || globals->BuildTunnelStraight())
50 {// query the default tunnel model
51 BDSExtent tunnelExtent = globals->TunnelInfo()->IndicativeExtent();
52 tunnelExtent = tunnelExtent.Translate(globals->TunnelOffsetX(), globals->TunnelOffsetY(), 0);
53 G4double maxTunnelR = tunnelExtent.MaximumAbs();
54 if (curvilinearRadius < maxTunnelR)
55 {
56 if (globals->CurvilinearDiameterShrunkForBends())
57 {
58 G4String message = "Strong bends necessitate smaller curvilinear geometry than the tunnel size, but\n";
59 message += "tunnel hits will need transform for curvilinear coordinates.";
60 BDS::Warning(message);
61 }
62 else
63 {curvilinearRadius = std::max(curvilinearRadius, maxTunnelR);}
64 }
65 }
66 bonusChordLength = 1*CLHEP::m;
67
69}
70
71BDSCurvilinearBuilder::~BDSCurvilinearBuilder()
72{
73 delete factory;
74}
75
77 const G4bool circular)
78{
79 BDSBeamline* result = new BDSBeamline();
80
81 //prepend small sections to machine when non-circular
82 G4bool bonusSections = (!circular && !beamline->empty());
83
84 if (bonusSections)
85 {//prepend small section to machine
86 BDSBeamlineElement* bonusBit = CreateBonusSectionStart(beamline);
87 result->AddBeamlineElement(bonusBit);
88 }
89
90 G4int i = 0;
91 for (BDSBeamline::const_iterator element = beamline->begin(); element != beamline->end(); ++element)
92 {
93 G4String name = (*element)->GetName() + "_cl_" + std::to_string(i);
94 i++;
95 const BDSBeamlineElement* pstEl = nullptr;
96 const BDSBeamlineElement* nxtEl = nullptr;
97 PreviousAndNext(element, beamline->begin(), beamline->end(), pstEl, nxtEl);
98 G4double crRadius = std::min({CurvilinearRadius(pstEl),
99 CurvilinearRadius(*element),
100 CurvilinearRadius(nxtEl)});
101 BDSBeamlineElement* temp = CreateCurvilinearElement(name, element, element, i, crRadius);
102 if (temp)
103 {result->AddBeamlineElement(temp);}
104 }
105
106 if (bonusSections)
107 {// append small section to machine
108 BDSBeamlineElement* bonusBit = CreateBonusSectionEnd(beamline);
109 if (bonusBit)
110 {result->AddBeamlineElement(bonusBit);}
111 }
112 return result;
113}
114
118 const BDSBeamlineElement*& previous,
119 const BDSBeamlineElement*& next) const
120{
121 G4bool isFirst = it == startIt;
122 G4bool isLast = std::next(it) == endIt; // end is one beyond the last
123
124 G4double minimumSize = 0.1*CLHEP::mm;
125 auto pst = std::prev(it);
126 if (isFirst)
127 {previous = nullptr;}
128 else
129 {
130 previous = *pst;
131 if (previous->GetArcLength() < minimumSize && pst != startIt)
132 {
133 pst = std::prev(pst);
134 if (pst != startIt)
135 {previous = *pst;}
136 }
137 }
138 auto nxt = std::next(it);
139 if (isLast)
140 {next = nullptr;}
141 else
142 {
143 next = *nxt;
144 if (next->GetArcLength() < minimumSize && nxt != endIt)
145 {
146 nxt = std::next(nxt);
147 if (nxt != endIt)
148 {next = *nxt;}
149 }
150 }
151}
152
154{
155 BDSBeamline* result = new BDSBeamline();
156
158
159 G4int numberOfUniqueComponents = 0;
160 G4int beamlineIndex = 0;
161 for (BDSBeamline::const_iterator element = beamline->begin(); element != beamline->end(); ++element)
162 {
163 auto nxt = std::next(element);
164 const BDSBeamlineElement* pstEl = nullptr;
165 const BDSBeamlineElement* nxtEl = nullptr;
166 PreviousAndNext(element, beamline->begin(), beamline->end(), pstEl, nxtEl);
167 G4double crRadius = std::min({CurvilinearRadius(pstEl),
168 CurvilinearRadius(*element),
169 CurvilinearRadius(nxtEl)});
170 BDSBeamlineElement* bridgeSection = CreateBridgeSection(defaultBridge, element, nxt,
171 beamline->end(), numberOfUniqueComponents,
172 beamlineIndex, crRadius);
173 if (bridgeSection)
174 {
175 result->AddBeamlineElement(bridgeSection);
176 beamlineIndex++;
177 }
178 }
179 return result;
180}
181
183{
184 if (!el)
185 {return curvilinearRadius;} // default in case there's no element
186 if (BDS::IsFinite(el->GetAngle()))
187 {
188 G4double radiusFromAngleLength = std::abs(el->GetArcLength()/el->GetAngle()); // s = r*theta -> r = s/theta
189 radiusFromAngleLength *= radiusTolerance;
190 return std::min(radiusFromAngleLength, curvilinearRadius);
191 }
192 else // no finite bending angle
193 {return curvilinearRadius;}
194}
195
197 BDSBeamline::const_iterator startElement,
198 BDSBeamline::const_iterator finishElement,
199 G4int index,
200 G4double crRadius)
201{
202 BDSSimpleComponent* component = nullptr;
203
204 // we'll take the tilt from the first element - they should only ever be the same when used here
205 G4bool tilted = BDS::IsFinite((*startElement)->GetTilt());
206 // variables to be defined to create component
207 G4double chordLength=0.0, angle=0.0, arcLength=0.0;
208
209 if (startElement == finishElement)
210 {// build 1:1
211 chordLength = (*startElement)->GetChordLength() + paddingLength;
212 angle = (*startElement)->GetAngle();
213 if (Angled(*startElement))
214 {
215 // Not strictly accurate to add on paddingLength to arcLength, but close for now.
216 arcLength = (*startElement)->GetArcLength() + paddingLength;
217 }
218 }
219 else
220 {// cover a few components
221 G4ThreeVector positionStart = (*startElement)->GetReferencePositionStart();
222 G4ThreeVector positionEnd = (*finishElement)->GetReferencePositionEnd();
223 chordLength = (positionEnd - positionStart).mag() + paddingLength;
224
225 G4double accumulatedAngle = 0;
226 for (auto it = startElement; it < finishElement; it++)
227 {accumulatedAngle += (*it)->GetAngle();}
228
229 angle = accumulatedAngle;
230 if (BDS::IsFinite(angle))
231 {
232 G4double meanBendingRadius = 0.5 * chordLength / std::sin(0.5*std::abs(angle));
233 arcLength = meanBendingRadius * std::abs(angle);
234 }
235 }
236
237 if (!BDS::IsFinite(angle))
238 {// straight
239 component = factory->CreateCurvilinearVolume(elementName,
240 chordLength,
241 crRadius);
242 }
243 else
244 {// angled - tilt matters
245 BDSTiltOffset* to = nullptr;
246 if (tilted)
247 {to = (*startElement)->GetTiltOffset();}
248
249 component = factory->CreateCurvilinearVolume(elementName,
250 arcLength,
251 chordLength,
252 crRadius,
253 angle,
254 to);
255 }
256
258
259 return CreateElementFromComponent(component, startElement, finishElement, index);
260}
261
264 BDSBeamline::const_iterator nextElement,
266 G4int& numberOfUniqueComponents,
267 const G4int beamlineIndex,
268 G4double crRadius)
269{
270 // we can safely assume faces match between two beam line elements so if one's angled, so is the other
271 BDSAcceleratorComponent* component = defaultBridge;
272 if ((*element)->AngledOutputFace()) // angled faces - make one to match to cover the angled gap
273 {component = CreateAngledBridgeComponent(element, numberOfUniqueComponents, crRadius);}
274 else if (BDS::IsFinite((*element)->GetAngle()))
275 {// width may be reduced due to bend - check if required
276 G4double width = (*element)->GetAcceleratorComponent()->GetExtent().DX();
277 width = std::min(width, crRadius);
278 component = CreateStraightBridgeComponent(width, numberOfUniqueComponents);
279 }
280
281 return CreateBridgeElementFromComponent(component, element, nextElement, end, beamlineIndex);
282}
283
284
286{
287 // we're ignoring any possible angled face of the curvilinear geometry
288 BDSSimpleComponent* component = factory->CreateCurvilinearVolume("clb_flat_face",
289 defaultBridgeLength,
291
293
294 return component;
295}
296
298 G4int& numberOfUniqueComponents)
299{
300 BDSSimpleComponent* component = factory->CreateCurvilinearVolume("clb_" + std::to_string(numberOfUniqueComponents),
301 defaultBridgeLength,
302 width);
304 numberOfUniqueComponents++;
305 return component;
306}
307
309 G4int& numberOfUniqueComponents,
310 G4double suggestedRadius)
311{
312 G4ThreeVector outputFaceNormal = (*element)->OutputFaceNormal(); // outgoing face normal
313
314 G4ThreeVector iFNormal = outputFaceNormal;
315 iFNormal *= -1;
316 G4ThreeVector oFNormal = outputFaceNormal; // we assume no angle for the bridge component so this is right.
317
318 G4double width = (*element)->GetAcceleratorComponent()->GetExtent().DX();
319 width = std::min(width, suggestedRadius);
320 // we're ignoring any possible angled face of the curvilinear geometry
321 BDSSimpleComponent* component = factory->CreateCurvilinearVolume("clb_" + std::to_string(numberOfUniqueComponents),
322 defaultBridgeLength,
323 defaultBridgeLength,
324 width*0.5,
325 0, /*angle*/
326 iFNormal,
327 oFNormal);
328
330 numberOfUniqueComponents++;
331 return component;
332}
333
336 BDSBeamline::const_iterator nextElement,
338 const G4int beamlineIndex)
339{
340 G4bool last = nextElement == end;
341 BDSBeamlineElement* pel = (*element); // convenience
342
343 BDSTiltOffset* copyTiltOffset = nullptr;
344 BDSTiltOffset* existingTiltOffset = pel->GetTiltOffset();
345 if (existingTiltOffset)
346 {copyTiltOffset = new BDSTiltOffset(*existingTiltOffset);}
347
348 const G4RotationMatrix* refRotEnd = pel->GetReferenceRotationEnd();
349
350 G4ThreeVector unitZ = G4ThreeVector(0,0,1);
351 unitZ = unitZ.transform(*refRotEnd);
352
353 G4ThreeVector startPosition = pel->GetReferencePositionEnd();
354 G4ThreeVector endPosition;
355 if (!last)
356 {endPosition = (*nextElement)->GetReferencePositionStart();}
357 else
358 {endPosition = startPosition + ( (component->GetChordLength()) * unitZ );}
359 G4ThreeVector midPosition = (startPosition + endPosition) * 0.5;
360
361 G4double startS = pel->GetSPositionEnd();
362 G4double endS;
363 if (!last)
364 {endS = pel->GetSPositionStart();}
365 else
366 {endS = startS + component->GetChordLength();}
367 G4double midS = (startS + endS) * 0.5;
368
369 BDSBeamlineElement* result = new BDSBeamlineElement(component,
370 startPosition, midPosition, endPosition,
371 new G4RotationMatrix(*refRotEnd),
372 new G4RotationMatrix(*refRotEnd),
373 new G4RotationMatrix(*refRotEnd),
374 startPosition, midPosition, endPosition,
375 new G4RotationMatrix(*refRotEnd),
376 new G4RotationMatrix(*refRotEnd),
377 new G4RotationMatrix(*refRotEnd),
378 startS, midS, endS,
379 0, 0, 0,
380 copyTiltOffset,
381 nullptr, // sampler info
382 beamlineIndex);
383 return result;
384}
385
387 BDSBeamline::const_iterator startElement,
388 BDSBeamline::const_iterator finishElement,
389 G4int index)
390{
391 BDSTiltOffset* copyTiltOffset = nullptr;
392 BDSTiltOffset* existingTiltOffset = (*startElement)->GetTiltOffset();
393 if (existingTiltOffset)
394 {copyTiltOffset = new BDSTiltOffset(*existingTiltOffset);}
395
396 BDSBeamlineElement* result = nullptr;
397
398 if (startElement == finishElement)
399 {// 1:1
400 BDSBeamlineElement* element = *startElement; // convenience
401
402 result = new BDSBeamlineElement(component,
403 element->GetReferencePositionStart(),
405 element->GetReferencePositionEnd(),
406 new G4RotationMatrix(*(element->GetRotationStart())),
407 new G4RotationMatrix(*(element->GetRotationMiddle())),
408 new G4RotationMatrix(*(element->GetRotationEnd())),
409 element->GetReferencePositionStart(),
411 element->GetReferencePositionEnd(),
412 new G4RotationMatrix(*(element->GetReferenceRotationStart())),
413 new G4RotationMatrix(*(element->GetReferenceRotationMiddle())),
414 new G4RotationMatrix(*(element->GetReferenceRotationEnd())),
415 element->GetSPositionStart(),
416 element->GetSPositionMiddle(),
417 element->GetSPositionEnd(),
418 element->GetSynchronousTMiddle(),
419 element->GetStartMomentum(),
420 element->GetStartKineticEnergy(),
421 copyTiltOffset,
422 nullptr, // sampler info
423 index);
424 }
425 else
426 {//must cover a few components
427 G4double sStart = (*startElement)->GetSPositionStart();
428 G4double sEnd = (*finishElement)->GetSPositionEnd();
429 G4double sMid = 0.5 * (sEnd + sStart);
430 G4ThreeVector posRefStart = (*startElement)->GetReferencePositionStart();
431 G4ThreeVector posRefEnd = (*finishElement)->GetReferencePositionEnd();
432 G4ThreeVector posRefMid = 0.5 * (posRefStart + posRefEnd);
433 G4RotationMatrix* rotRefStart = (*startElement)->GetReferenceRotationStart();
434 G4RotationMatrix* rotRefEnd = (*finishElement)->GetReferenceRotationEnd();
435
436 G4ThreeVector delta = posRefMid - posRefStart;
437 G4ThreeVector newUnitZ = delta.unit();
438 G4ThreeVector unitXPrevious = G4ThreeVector(1,0,0).transform(*rotRefStart);
439 G4ThreeVector newUnitY = newUnitZ.cross(unitXPrevious).unit();
440 G4ThreeVector unitYPrevious = G4ThreeVector(0,1,0).transform(*rotRefStart);
441 G4ThreeVector newUnitX = unitYPrevious.cross(newUnitZ).unit();
442
443 // create mid point rotation matrix from unit vectors at mid point
444 G4RotationMatrix rotRefMid = G4RotationMatrix(newUnitX, newUnitY, newUnitZ);
445
446 result = new BDSBeamlineElement(component,
447 posRefStart,
448 posRefMid,
449 posRefEnd,
450 new G4RotationMatrix(*rotRefStart),
451 new G4RotationMatrix(rotRefMid),
452 new G4RotationMatrix(*rotRefEnd),
453 posRefStart,
454 posRefMid,
455 posRefEnd,
456 new G4RotationMatrix(*rotRefStart),
457 new G4RotationMatrix(rotRefMid),
458 new G4RotationMatrix(*rotRefEnd),
459 sStart,
460 sMid,
461 sEnd,
462 0, 0, 0,
463 copyTiltOffset,
464 nullptr, // sampler info
465 index);
466
467 }
468
469 return result;
470}
471
472
474{
475 // we're ignoring any possible angled face of the curvilinear geometry
476 BDSSimpleComponent* component = factory->CreateCurvilinearVolume("cl_start",
479
481
482 const BDSBeamlineElement* firstElement = beamline->GetFirstItem();
483 const G4RotationMatrix* rotStart = firstElement->GetReferenceRotationStart();
484
485 G4ThreeVector unitDir = G4ThreeVector(0,0,1).transform(*rotStart);
486 G4ThreeVector endPos = firstElement->GetReferencePositionStart() - unitDir*0.5*paddingLength;
487 G4ThreeVector midPos = endPos - unitDir*0.5*bonusChordLength;
488 G4ThreeVector staPos = endPos - unitDir*bonusChordLength;
489
490 G4double sStart = firstElement->GetSPositionStart();
491
492 BDSBeamlineElement*result = new BDSBeamlineElement(component,
493 staPos,
494 midPos,
495 endPos,
496 new G4RotationMatrix(*rotStart),
497 new G4RotationMatrix(*rotStart),
498 new G4RotationMatrix(*rotStart),
499 staPos,
500 midPos,
501 endPos,
502 new G4RotationMatrix(*rotStart),
503 new G4RotationMatrix(*rotStart),
504 new G4RotationMatrix(*rotStart),
505 sStart - bonusChordLength,
506 sStart - 0.5*bonusChordLength,
507 sStart,
508 0, 0, 0,
509 nullptr,
510 nullptr, // sampler info
511 -1); // artificial index of -1 for before beam line
512 return result;
513}
514
516{
517 // we're ignoring any possible angled face of the curvilinear geometry
521
523
524 const BDSBeamlineElement* lastElement = beamline->GetLastItem();
525 const G4RotationMatrix* rotEnd = lastElement->GetReferenceRotationEnd();
526 const G4int lastIndex = lastElement->GetIndex();
527
528 G4ThreeVector unitDir = G4ThreeVector(0,0,1).transform(*rotEnd);
529 G4ThreeVector staPos = lastElement->GetReferencePositionEnd() + unitDir*0.5*paddingLength;
530 G4ThreeVector midPos = staPos + unitDir*0.5*bonusChordLength;
531 G4ThreeVector endPos = staPos + unitDir*bonusChordLength;
532
533 G4double sStart = lastElement->GetSPositionEnd();
534
535 BDSBeamlineElement*result = new BDSBeamlineElement(component,
536 staPos,
537 midPos,
538 endPos,
539 new G4RotationMatrix(*rotEnd),
540 new G4RotationMatrix(*rotEnd),
541 new G4RotationMatrix(*rotEnd),
542 staPos,
543 midPos,
544 endPos,
545 new G4RotationMatrix(*rotEnd),
546 new G4RotationMatrix(*rotEnd),
547 new G4RotationMatrix(*rotEnd),
548 sStart,
549 sStart + 0.5*bonusChordLength,
550 sStart + bonusChordLength,
551 0, 0, 0,
552 nullptr,
553 nullptr, // sampler info
554 lastIndex + 1); // artificial index of -1 for before beam line
555 return result;
556}
void RegisterCurvilinearComponent(BDSAcceleratorComponent *component)
static BDSAcceleratorComponentRegistry * Instance()
Singleton accessor.
Abstract class that represents a component of an accelerator.
virtual G4double GetChordLength() const
G4ThreeVector OutputFaceNormal() const
A class that holds a fully constructed BDSAcceleratorComponent as well as any information relevant to...
G4double GetSynchronousTMiddle() const
Accessor.
G4double GetAngle() const
Accessor.
G4double GetStartMomentum() const
Accessor.
G4ThreeVector GetReferencePositionEnd() const
Accessor.
G4RotationMatrix * GetReferenceRotationStart() const
Accessor.
G4RotationMatrix * GetRotationEnd() const
Accessor.
BDSTiltOffset * GetTiltOffset() const
Accessor.
G4RotationMatrix * GetReferenceRotationEnd() const
Accessor.
G4int GetIndex() const
Accessor.
G4ThreeVector GetReferencePositionMiddle() const
Accessor.
G4double GetSPositionEnd() const
Accessor.
G4RotationMatrix * GetRotationStart() const
Accessor.
G4double GetStartKineticEnergy() const
Accessor.
G4ThreeVector GetReferencePositionStart() const
Accessor.
G4RotationMatrix * GetReferenceRotationMiddle() const
Accessor.
G4double GetSPositionMiddle() const
Accessor.
G4double GetArcLength() const
Accessor.
G4RotationMatrix * GetRotationMiddle() const
Accessor.
G4double GetSPositionStart() const
Accessor.
A vector of BDSBeamlineElement instances - a beamline.
const BDSBeamlineElement * GetLastItem() const
Return a reference to the last element.
static G4double PaddingLength()
Access the padding length between each element added to the beamline.
const BDSBeamlineElement * GetFirstItem() const
Return a reference to the first element.
void AddBeamlineElement(BDSBeamlineElement *element)
G4bool empty() const
Iterator mechanics.
iterator begin()
Iterator mechanics.
iterator end()
Iterator mechanics.
BeamlineVector::const_iterator const_iterator
Iterator mechanics.
BDSBeamlineElement * CreateElementFromComponent(BDSSimpleComponent *component, BDSBeamline::const_iterator startElement, BDSBeamline::const_iterator finishElement, G4int index)
Create the BDSBeamlineElement by wrapping a BDSSimpleComponent.
BDSBeamlineElement * CreateBridgeSection(BDSAcceleratorComponent *defaultBridge, BDSBeamline::const_iterator element, BDSBeamline::const_iterator nextElement, BDSBeamline::const_iterator end, G4int &numberOfUniqueComponents, const G4int beamlineIndex, G4double crRadius)
BDSAcceleratorComponent * CreateStraightBridgeComponent(G4double width, G4int &numberOfUniqueComponents)
BDSBeamlineElement * CreateBridgeElementFromComponent(BDSAcceleratorComponent *component, BDSBeamline::const_iterator element, BDSBeamline::const_iterator nextElement, BDSBeamline::const_iterator end, const G4int beamlineIndex)
G4double curvilinearRadius
Radius for curvilinear geometry.
G4double paddingLength
Length that was used for padding on the beam line we're building with respesct to.
void PreviousAndNext(BDSBeamline::const_iterator it, BDSBeamline::const_iterator startIt, BDSBeamline::const_iterator endIt, const BDSBeamlineElement *&previous, const BDSBeamlineElement *&next) const
G4double CurvilinearRadius(const BDSBeamlineElement *el) const
BDSBeamline * BuildCurvilinearBeamLine1To1(BDSBeamline const *const beamline, const G4bool circular)
Build a beam line of curvilinear geometry based on another beam line.
BDSAcceleratorComponent * CreateAngledBridgeComponent(BDSBeamline::const_iterator element, G4int &numberOfUniqueComponents, G4double suggestedRadius)
Create a unique accelerator component for an element with angled faces.
G4bool Angled(BDSBeamlineElement const *const element) const
Simple interrogation function to determine if an element has a finite angle or not.
BDSBeamline * BuildCurvilinearBridgeBeamLine(BDSBeamline const *const beamline)
Build bridging volumes to join the curvilinear ones.
BDSCurvilinearFactory * factory
Factory to build curvilinear geometry.
BDSBeamlineElement * CreateBonusSectionStart(BDSBeamline const *const beamline)
Create a small section to extend a linear beam line.
BDSAcceleratorComponent * CreateDefaultBridgeComponent()
G4double bonusChordLength
Length of any possible bonus section added to beginning and end.
BDSBeamlineElement * CreateBonusSectionEnd(BDSBeamline const *const beamline)
Create a small section to extend a linear beam line.
BDSBeamlineElement * CreateCurvilinearElement(const G4String &elementName, BDSBeamline::const_iterator startElement, BDSBeamline::const_iterator finishElement, G4int index, G4double crRadius)
Factory to create curvilinear geometry for parallel world.
BDSSimpleComponent * CreateCurvilinearVolume(const G4String &name, G4double chordLength, G4double radius)
Build a straight curvilinear volume.
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:38
BDSExtent Translate(const G4ThreeVector &offset) const
Provide a new copy of this extent with an offset applied.
Definition BDSExtent.hh:124
G4double MaximumAbs() const
Return the maximum absolute value considering all dimensions.
Definition BDSExtent.cc:156
A class that holds global options and constants.
static BDSGlobalConstants * Instance()
Access method.
A BDSAcceleratorComponent wrapper for BDSGeometryComponent.
A holder for any placement offsets and rotations for a BDSAcceleratorComponent.
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())