18#include "BDSAcceleratorComponent.hh"
19#include "BDSAcceleratorModel.hh"
20#include "BDSBeamPipe.hh"
21#include "BDSBeamPipeFactory.hh"
22#include "BDSBeamPipeInfo.hh"
23#include "BDSCollimatorCrystal.hh"
24#include "BDSCrystalFactory.hh"
25#include "BDSCrystalInfo.hh"
27#include "BDSException.hh"
28#include "BDSGeometryComponent.hh"
29#include "BDSSDType.hh"
30#include "BDSUtilities.hh"
31#include "BDSWarning.hh"
34#include "G4Material.hh"
35#include "G4PVPlacement.hh"
36#include "G4RotationMatrix.hh"
37#include "G4ThreeVector.hh"
46 G4double halfGapLeftIn,
47 G4double halfGapRightIn,
48 G4double angleYAxisLeftIn,
49 G4double angleYAxisRightIn):
51 crystalInfoLeft(crystalInfoLeftIn),
52 crystalInfoRight(crystalInfoRightIn),
53 halfGapLeft(halfGapLeftIn),
54 halfGapRight(halfGapRightIn),
55 angleYAxisLeft(angleYAxisLeftIn),
56 angleYAxisRight(angleYAxisRightIn),
60#ifdef USE_SIXTRACKLINK
61 G4cout <<
"Left " << crystalInfoLeftIn << G4endl;
62 G4cout <<
"Right " << crystalInfoRightIn << G4endl;
66#ifdef USE_SIXTRACKLINK
67 G4cout <<
"halfGapLeftIn " << halfGapLeftIn << G4endl;
68 G4cout <<
"halfGapRightIn " << halfGapRightIn << G4endl;
72BDSCollimatorCrystal::~BDSCollimatorCrystal()
121 G4ThreeVector colOffsetL = G4ThreeVector(halfGapLeft+dx,0,0);
122 G4ThreeVector placementOffsetL = objectOffset + colOffsetL;
128 placementRot =
new G4RotationMatrix();
131 G4ThreeVector localUnitY = G4ThreeVector(0,1,0).transform(*placementRot);
132 placementRot->rotate(-angleYAxisLeft, localUnitY);
145 G4bool safe2 = innerRadius.
Encompasses(extShifted);
147 {BDS::Warning(__METHOD_NAME__,
"Left crystal potential overlap in component \"" +
name +
"\"");}
150#ifdef USE_SIXTRACKLINK
151 G4cout <<
"left crystal placement offset " << placementOffsetL << G4endl;
154 G4cout <<
"left crystal placement rotation " << *placementRot << G4endl;
159 auto cL =
new G4PVPlacement(placementRot,
162 name +
"_crystal_left_pv",
168#ifdef USE_SIXTRACKLINK
169 G4cout <<
"Placement of left crystal " << placementOffsetL << G4endl;
176 G4ThreeVector colOffsetR = G4ThreeVector(-(halfGapRight+dx),0,0);
177 G4ThreeVector placementOffsetL = objectOffset + colOffsetR;
183 placementRot =
new G4RotationMatrix();
186 G4ThreeVector localUnitY = G4ThreeVector(0,1,0).transform(*placementRot);
187 placementRot->rotate(angleYAxisRight, localUnitY);
198 G4bool safe2 = innerRadius.
Encompasses(extShifted);
200 {BDS::Warning(__METHOD_NAME__,
"Right crystal potential overlap in component \"" +
name +
"\"");}
203#ifdef USE_SIXTRACKLINK
204 G4cout <<
"right crystal placement offset " << placementOffsetL << G4endl;
207 G4cout <<
"right crystal placement rotation " << *placementRot << G4endl;
212 auto cR =
new G4PVPlacement(placementRot,
215 name +
"_crystal_right_pv",
222 if (!crystalLeft && !crystalRight)
223 {
throw BDSException(__METHOD_NAME__,
"Error in crystal construction in component \"" +
name +
"\"");}
230 {
return bpMat->GetName();}
236 G4double crystalAngle,
237 const G4String& side)
const
239 G4double zExt = extCrystal.MaximumZ();
240 G4double dz = zExt*std::tan(crystalAngle);
246 G4cout <<
"Crystal of length " << 2*zExt/CLHEP::mm <<
" mm is at angle "
247 << crystalAngle / CLHEP::mrad <<
" mrad and container is "
249 throw BDSException(__METHOD_NAME__, side +
" crystal won't fit in collimator due to rotation.");
255 auto crystals = BDSAcceleratorModel::Instance()->
VolumeSet(
"crystals");
256 auto collimators = BDSAcceleratorModel::Instance()->
VolumeSet(
"collimators");
259 crystals->insert(lv);
260 collimators->insert(lv);
265 G4double placementAngle,
270 G4double factor = left ? 1.0 : -1.0;
273 case BDSCrystalType::box:
275 result = 0.5*recipe->
lengthZ * std::sin(placementAngle);
276 result += 0.5*recipe->
lengthX * std::cos(placementAngle);
279 case BDSCrystalType::cylinder:
280 case BDSCrystalType::torus:
285 result = 0.5*recipe->
lengthZ * std::sin(placementAngle);
286 result += 0.5*recipe->
lengthX * std::cos(placementAngle);
292 G4TwoVector a(recipe->BendingRadiusHorizontal(), 0);
294 b.rotate(-halfAngle);
297 G4TwoVector dxy = b - a;
301 G4TwoVector frontFaceX = dxy.orthogonal() * factor;
304 G4TwoVector frontCentreToEdge = frontFaceX.unit() * 0.5*recipe->
lengthX;
306 G4TwoVector resultV = dxy + frontCentreToEdge;
308 resultV.rotate(-factor*placementAngle);
310 result = -factor * resultV.x();
Abstract class that represents a component of an accelerator.
virtual G4String Material() const
Return the name of a material associated with the component - ie the primary material.
void SetAcceleratorVacuumLogicalVolume(G4LogicalVolume *accVacLVIn)
const G4String name
Const protected member variable that may not be changed by derived classes.
virtual void SetOutputFaceNormal(const G4ThreeVector &output)
Allow updating of face normals. Virtual so derived class may apply it to daughters.
static G4double lengthSafety
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.
BDSBeamPipeInfo * GetBeamPipeInfo() const
virtual void SetInputFaceNormal(const G4ThreeVector &input)
Allow updating of face normals. Virtual so derived class may apply it to daughters.
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.
std::set< G4LogicalVolume * > * VolumeSet(const G4String &name)
Returns pointer to a set of logical volumes. If no set by that name exits, create it.
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.
G4double IndicativeRadiusInner() const
Return an indicative inner extent for the beam pipe vacuum.
G4Material * beamPipeMaterial
Public member for direct access.
A holder class for a piece of beam pipe geometry.
G4LogicalVolume * GetVacuumLogicalVolume() const
Access the vacuum volume to set fields and limits.
G4ThreeVector InputFaceNormal() const
Accessor.
G4ThreeVector OutputFaceNormal() const
Accessor.
void RegisterCrystalLVs(const BDSCrystal *crystal) const
Register logical volumes in crystals and collimator sets in accelerator model.
BDSCrystalInfo * crystalInfoRight
Model associated with right crystal.
BDSCollimatorCrystal()=delete
No default constructor.
virtual G4String Material() const
Override base class version and return crystal material.
BDSCrystalInfo * crystalInfoLeft
Model associated with left crystal.
virtual void Build()
Construct geometry.
G4double TransverseOffsetToEdge(const BDSCrystal *crystal, G4double placementAngle, G4bool left) const
void LongitudinalOverlap(const BDSExtent &extCrystal, G4double crystalAngle, const G4String &side) const
Abstract base class for crystal factory classes.
BDSCrystal * CreateCrystal(const G4String &nameIn, const BDSCrystalInfo *recipe)
Main interface to create a crystal.
Holder for all information required to create a crystal.
G4double lengthZ
Z dimension.
G4double lengthX
X dimension.
BDSCrystalType shape
Shape of geometry.
G4double bendingAngleYAxis
Bending angle about Y axis.
An object for both a crystal from a factory.
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
G4bool Encompasses(const G4ThreeVector &point) const
Return whether the extent encompasses the point. True if point lies inside the extent.
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.
G4RotationMatrix * GetPlacementRotation() const
Accessor - see member for more info.
BDSExtent GetExtent() const
Accessor - see member for more info.
void RegisterRotationMatrix(G4RotationMatrix *rotationMatrix)
void RegisterDaughter(BDSGeometryComponent *anotherComponent)
virtual std::set< G4LogicalVolume * > GetAllLogicalVolumes() const
Access all logical volumes belonging to this component.
void RegisterPhysicalVolume(G4VPhysicalVolume *physicalVolume)
G4VSolid * GetContainerSolid() const
Accessor - see member for more info.
G4ThreeVector GetPlacementOffset() const
Accessor - see member for more info.
type underlying() const
return underlying value (can be used in switch statement)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())