19#include "BDSAcceleratorComponent.hh"
20#include "BDSAcceleratorComponentRegistry.hh"
21#include "BDSBeamline.hh"
22#include "BDSBeamlineElement.hh"
23#include "BDSExtent.hh"
24#include "BDSCurvilinearBuilder.hh"
25#include "BDSCurvilinearFactory.hh"
26#include "BDSGlobalConstants.hh"
27#include "BDSSimpleComponent.hh"
28#include "BDSSamplerType.hh"
29#include "BDSTiltOffset.hh"
30#include "BDSTunnelInfo.hh"
31#include "BDSUtilities.hh"
32#include "BDSWarning.hh"
35#include "G4ThreeVector.hh"
36#include "G4RotationMatrix.hh"
42BDSCurvilinearBuilder::BDSCurvilinearBuilder()
47 defaultBridgeLength =
paddingLength + 4*globals->LengthSafety();
49 radiusTolerance = 0.8;
50 if (globals->BuildTunnel() || globals->BuildTunnelStraight())
52 BDSExtent tunnelExtent = globals->TunnelInfo()->IndicativeExtent();
53 tunnelExtent = tunnelExtent.
Translate(globals->TunnelOffsetX(), globals->TunnelOffsetY(), 0);
54 G4double maxTunnelR = tunnelExtent.
MaximumAbs();
57 if (globals->CurvilinearDiameterShrunkForBends())
59 G4String message =
"Strong bends necessitate smaller curvilinear geometry than the tunnel size, but\n";
60 message +=
"tunnel hits will need transform for curvilinear coordinates.";
61 BDS::Warning(message);
72BDSCurvilinearBuilder::~BDSCurvilinearBuilder()
78 const G4bool circular)
83 G4bool bonusSections = (!circular && !beamline->
empty());
94 G4String name = (*element)->GetName() +
"_cl_" + std::to_string(i);
122 G4bool isFirst = it == startIt;
123 G4bool isLast = std::next(it) == endIt;
125 G4double minimumSize = 0.1*CLHEP::mm;
126 auto pst = std::prev(it);
128 {previous =
nullptr;}
132 if (previous->
GetArcLength() < minimumSize && pst != startIt)
134 pst = std::prev(pst);
139 auto nxt = std::next(it);
147 nxt = std::next(nxt);
160 G4int numberOfUniqueComponents = 0;
161 G4int beamlineIndex = 0;
164 auto nxt = std::next(element);
172 beamline->
end(), numberOfUniqueComponents,
173 beamlineIndex, crRadius);
190 radiusFromAngleLength *= radiusTolerance;
208 G4double chordLength=0.0, angle=0.0, arcLength=0.0;
210 if (startElement == finishElement)
212 chordLength = (*startElement)->GetChordLength() +
paddingLength;
213 angle = (*startElement)->GetAngle();
214 if (
Angled(*startElement))
222 G4ThreeVector positionStart = (*startElement)->GetReferencePositionStart();
223 G4ThreeVector positionEnd = (*finishElement)->GetReferencePositionEnd();
224 chordLength = (positionEnd - positionStart).mag() +
paddingLength;
226 G4double accumulatedAngle = 0;
227 for (
auto it = startElement; it < finishElement; it++)
228 {accumulatedAngle += (*it)->GetAngle();}
230 angle = accumulatedAngle;
233 G4double meanBendingRadius = 0.5 * chordLength / std::sin(0.5*std::abs(angle));
234 arcLength = meanBendingRadius * std::abs(angle);
248 {to = (*startElement)->GetTiltOffset();}
267 G4int& numberOfUniqueComponents,
268 const G4int beamlineIndex,
273 if ((*element)->AngledOutputFace())
277 G4double width = (*element)->GetAcceleratorComponent()->GetExtent().DX();
278 width = std::min(width, crRadius);
299 G4int& numberOfUniqueComponents)
305 numberOfUniqueComponents++;
310 G4int& numberOfUniqueComponents,
311 G4double suggestedRadius)
315 G4ThreeVector iFNormal = outputFaceNormal;
317 G4ThreeVector oFNormal = outputFaceNormal;
319 G4double width = (*element)->GetAcceleratorComponent()->GetExtent().DX();
320 width = std::min(width, suggestedRadius);
331 numberOfUniqueComponents++;
339 const G4int beamlineIndex)
341 G4bool last = nextElement == end;
346 if (existingTiltOffset)
351 G4ThreeVector unitZ = G4ThreeVector(0,0,1);
352 unitZ = unitZ.transform(*refRotEnd);
355 G4ThreeVector endPosition;
357 {endPosition = (*nextElement)->GetReferencePositionStart();}
359 {endPosition = startPosition + ( (component->
GetChordLength()) * unitZ );}
360 G4ThreeVector midPosition = (startPosition + endPosition) * 0.5;
368 G4double midS = (startS + endS) * 0.5;
371 startPosition, midPosition, endPosition,
372 new G4RotationMatrix(*refRotEnd),
373 new G4RotationMatrix(*refRotEnd),
374 new G4RotationMatrix(*refRotEnd),
375 startPosition, midPosition, endPosition,
376 new G4RotationMatrix(*refRotEnd),
377 new G4RotationMatrix(*refRotEnd),
378 new G4RotationMatrix(*refRotEnd),
392 BDSTiltOffset* existingTiltOffset = (*startElement)->GetTiltOffset();
393 if (existingTiltOffset)
398 if (startElement == finishElement)
424 G4double sStart = (*startElement)->GetSPositionStart();
425 G4double sEnd = (*finishElement)->GetSPositionEnd();
426 G4double sMid = 0.5 * (sEnd + sStart);
427 G4ThreeVector posRefStart = (*startElement)->GetReferencePositionStart();
428 G4ThreeVector posRefEnd = (*finishElement)->GetReferencePositionEnd();
429 G4ThreeVector posRefMid = 0.5 * (posRefStart + posRefEnd);
430 G4RotationMatrix* rotRefStart = (*startElement)->GetReferenceRotationStart();
431 G4RotationMatrix* rotRefEnd = (*finishElement)->GetReferenceRotationEnd();
433 G4ThreeVector delta = posRefMid - posRefStart;
434 G4ThreeVector newUnitZ = delta.unit();
435 G4ThreeVector unitXPrevious = G4ThreeVector(1,0,0).transform(*rotRefStart);
436 G4ThreeVector newUnitY = newUnitZ.cross(unitXPrevious).unit();
437 G4ThreeVector unitYPrevious = G4ThreeVector(0,1,0).transform(*rotRefStart);
438 G4ThreeVector newUnitX = unitYPrevious.cross(newUnitZ).unit();
441 G4RotationMatrix rotRefMid = G4RotationMatrix(newUnitX, newUnitY, newUnitZ);
447 new G4RotationMatrix(*rotRefStart),
448 new G4RotationMatrix(rotRefMid),
449 new G4RotationMatrix(*rotRefEnd),
453 new G4RotationMatrix(*rotRefStart),
454 new G4RotationMatrix(rotRefMid),
455 new G4RotationMatrix(*rotRefEnd),
481 G4ThreeVector unitDir = G4ThreeVector(0,0,1).transform(*rotStart);
492 new G4RotationMatrix(*rotStart),
493 new G4RotationMatrix(*rotStart),
494 new G4RotationMatrix(*rotStart),
498 new G4RotationMatrix(*rotStart),
499 new G4RotationMatrix(*rotStart),
500 new G4RotationMatrix(*rotStart),
521 const G4int lastIndex = lastElement->
GetIndex();
523 G4ThreeVector unitDir = G4ThreeVector(0,0,1).transform(*rotEnd);
534 new G4RotationMatrix(*rotEnd),
535 new G4RotationMatrix(*rotEnd),
536 new G4RotationMatrix(*rotEnd),
540 new G4RotationMatrix(*rotEnd),
541 new G4RotationMatrix(*rotEnd),
542 new G4RotationMatrix(*rotEnd),
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 GetAngle() 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.
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.
BDSExtent Translate(const G4ThreeVector &offset) const
Provide a new copy of this extent with an offset applied.
G4double MaximumAbs() const
Return the maximum absolute value considering all dimensions.
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())