19#include "BDSAcceleratorComponent.hh"
20#include "BDSAcceleratorModel.hh"
21#include "BDSBeamPipe.hh"
22#include "BDSBeamPipeFactory.hh"
23#include "BDSBeamPipeInfo.hh"
24#include "BDSCollimatorCrystal.hh"
25#include "BDSCrystalFactory.hh"
26#include "BDSCrystalInfo.hh"
28#include "BDSException.hh"
29#include "BDSGeometryComponent.hh"
30#include "BDSSDType.hh"
31#include "BDSUtilities.hh"
32#include "BDSWarning.hh"
35#include "G4Material.hh"
36#include "G4PVPlacement.hh"
37#include "G4RotationMatrix.hh"
38#include "G4ThreeVector.hh"
47 G4double halfGapLeftIn,
48 G4double halfGapRightIn,
49 G4double angleYAxisLeftIn,
50 G4double angleYAxisRightIn):
52 crystalInfoLeft(crystalInfoLeftIn),
53 crystalInfoRight(crystalInfoRightIn),
54 halfGapLeft(halfGapLeftIn),
55 halfGapRight(halfGapRightIn),
56 angleYAxisLeft(angleYAxisLeftIn),
57 angleYAxisRight(angleYAxisRightIn),
61#ifdef USE_SIXTRACKLINK
62 G4cout <<
"Left " << crystalInfoLeftIn << G4endl;
63 G4cout <<
"Right " << crystalInfoRightIn << G4endl;
67#ifdef USE_SIXTRACKLINK
68 G4cout <<
"halfGapLeftIn " << halfGapLeftIn << G4endl;
69 G4cout <<
"halfGapRightIn " << halfGapRightIn << G4endl;
73BDSCollimatorCrystal::~BDSCollimatorCrystal()
122 G4ThreeVector colOffsetL = G4ThreeVector(halfGapLeft+dx,0,0);
123 G4ThreeVector placementOffsetL = objectOffset + colOffsetL;
129 placementRot =
new G4RotationMatrix();
132 G4ThreeVector localUnitY = G4ThreeVector(0,1,0).transform(*placementRot);
133 placementRot->rotate(-angleYAxisLeft, localUnitY);
146 G4bool safe2 = innerRadius.
Encompasses(extShifted);
148 {BDS::Warning(__METHOD_NAME__,
"Left crystal potential overlap in component \"" +
name +
"\"");}
151#ifdef USE_SIXTRACKLINK
152 G4cout <<
"left crystal placement offset " << placementOffsetL << G4endl;
155 G4cout <<
"left crystal placement rotation " << *placementRot << G4endl;
160 auto cL =
new G4PVPlacement(placementRot,
163 name +
"_crystal_left_pv",
169#ifdef USE_SIXTRACKLINK
170 G4cout <<
"Placement of left crystal " << placementOffsetL << G4endl;
177 G4ThreeVector colOffsetR = G4ThreeVector(-(halfGapRight+dx),0,0);
178 G4ThreeVector placementOffsetL = objectOffset + colOffsetR;
184 placementRot =
new G4RotationMatrix();
187 G4ThreeVector localUnitY = G4ThreeVector(0,1,0).transform(*placementRot);
188 placementRot->rotate(angleYAxisRight, localUnitY);
199 G4bool safe2 = innerRadius.
Encompasses(extShifted);
201 {BDS::Warning(__METHOD_NAME__,
"Right crystal potential overlap in component \"" +
name +
"\"");}
204#ifdef USE_SIXTRACKLINK
205 G4cout <<
"right crystal placement offset " << placementOffsetL << G4endl;
208 G4cout <<
"right crystal placement rotation " << *placementRot << G4endl;
213 auto cR =
new G4PVPlacement(placementRot,
216 name +
"_crystal_right_pv",
223 if (!crystalLeft && !crystalRight)
224 {
throw BDSException(__METHOD_NAME__,
"Error in crystal construction in component \"" +
name +
"\"");}
231 {
return bpMat->GetName();}
237 G4double crystalAngle,
238 const G4String& side)
const
240 G4double zExt = extCrystal.MaximumZ();
241 G4double dz = zExt*std::tan(crystalAngle);
247 G4cout <<
"Crystal of length " << 2*zExt/CLHEP::mm <<
" mm is at angle "
248 << crystalAngle / CLHEP::mrad <<
" mrad and container is "
250 throw BDSException(__METHOD_NAME__, side +
" crystal won't fit in collimator due to rotation.");
256 auto crystals = BDSAcceleratorModel::Instance()->
VolumeSet(
"crystals");
257 auto collimators = BDSAcceleratorModel::Instance()->
VolumeSet(
"collimators");
260 crystals->insert(lv);
261 collimators->insert(lv);
266 G4double placementAngle,
271 G4double factor = left ? 1.0 : -1.0;
274 case BDSCrystalType::box:
276 result = 0.5*recipe->
lengthZ * std::sin(placementAngle);
277 result += 0.5*recipe->
lengthX * std::cos(placementAngle);
280 case BDSCrystalType::cylinder:
281 case BDSCrystalType::torus:
286 result = 0.5*recipe->
lengthZ * std::sin(placementAngle);
287 result += 0.5*recipe->
lengthX * std::cos(placementAngle);
293 G4TwoVector a(recipe->BendingRadiusHorizontal(), 0);
295 b.rotate(-halfAngle);
298 G4TwoVector dxy = b - a;
302 G4TwoVector frontFaceX = dxy.orthogonal() * factor;
305 G4TwoVector frontCentreToEdge = frontFaceX.unit() * 0.5*recipe->
lengthX;
307 G4TwoVector resultV = dxy + frontCentreToEdge;
309 resultV.rotate(-factor*placementAngle);
311 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())