BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSTeleporter.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 "BDSBeamline.hh"
20#include "BDSBeamlineElement.hh"
21#include "BDSDebug.hh"
22#include "BDSException.hh"
23#include "BDSFieldBuilder.hh"
24#include "BDSFieldInfo.hh"
25#include "BDSGlobalConstants.hh"
26#include "BDSSamplerPlane.hh"
27#include "BDSTeleporter.hh"
28#include "BDSUtilities.hh"
29
30#include "globals.hh" //G4 global constants & types
31#include "G4Box.hh"
32#include "G4LogicalVolume.hh"
33#include "G4ThreeVector.hh"
34#include "G4Transform3D.hh"
35#include "G4UserLimits.hh"
36
37#include <cmath>
38#include <string>
39
40
41BDSTeleporter::BDSTeleporter(const G4double length,
42 const G4double horizontalWidthIn,
43 BDSFieldInfo* vacuumFieldInfoIn):
44 BDSAcceleratorComponent("teleporter", length, 0, "teleporter"),
45 horizontalWidth(horizontalWidthIn),
46 vacuumFieldInfo(vacuumFieldInfoIn)
47{;}
48
50{
51 // We don't use BDSAcceleratorComponent::Build() so we can control the user limits
52 // to limit the step length in the volume.
54 // set user limits for container & visual attributes
55 if(containerLogicalVolume)
56 {
57 // user limits
58 auto defaultUL = BDSGlobalConstants::Instance()->DefaultUserLimits();
59 //copy the default and update with the length of the object rather than the default 1m
60 G4UserLimits* ul = new G4UserLimits(*defaultUL);
61 ul->SetMaxAllowedStep(1.1*chordLength);
63
64 containerLogicalVolume->SetUserLimits(ul);
65 containerLogicalVolume->SetVisAttributes(BDSGlobalConstants::Instance()->ContainerVisAttr());
66 }
68 containerLogicalVolume,
69 true);
70}
71
73{
74 containerSolid = new G4Box(name+"_container_solid",
75 horizontalWidth * 0.5,
76 horizontalWidth * 0.5,
77 chordLength*0.5);
78 containerLogicalVolume = new G4LogicalVolume(containerSolid,
80 name + "_container_lv");
81
82 // register extents with BDSGeometryComponent base class
84}
85
86G4Transform3D BDS::CalculateTeleporterDelta(const BDSBeamline* beamline,
87 G4double& teleporterLength)
88{
89 if (beamline->empty())
90 {// can't do anything for an empty beam line
91 teleporterLength = 0;
92 return G4Transform3D();
93 }
94
95 // get position of last item in beamline
96 // and then calculate necessary offset teleporter should apply
97 // remember beam line could have finite offset and rotation to start with
98 auto firstElement = beamline->front();
99 auto lastElement = beamline->back();
100 G4ThreeVector lastItemPosition = lastElement->GetReferencePositionEnd();
101 G4ThreeVector firstItemPosition = firstElement->GetReferencePositionStart();
102 G4ThreeVector positionDelta = firstItemPosition - lastItemPosition;
103
104 // we must subtract off the required padding length from the teleporter
105 // delta 3-vector (note, along the axis of the beam line at the end)
106 const G4double sL = BDSSamplerPlane::ChordLength();
107 const G4double pL = beamline->PaddingLength();
108
109 // unit z direction at end of current beam line
110 G4ThreeVector lastItemUnitDir = G4ThreeVector(0,0,1).transform(*(lastElement->GetReferenceRotationEnd()));
111
112 // project the length of the position delta onto the beam line direction.
113 G4double rawLength = positionDelta.dot(lastItemUnitDir);
114
115 // minimum space for the circular mechanics are:
116 // 1x terminator with sampler chord length
117 // 1x teleporter with (minimum) 1x sampler chord length
118 // 3x padding length
119 G4double minimumRequiredSpace = 2*sL + 3*pL;
120
121 if (rawLength > 1*CLHEP::m)
122 {
123 std::string msg = "\nError - the calculated teleporter delta is above 1m!\nThe teleporter was only intended for small shifts";
124 throw BDSException(__METHOD_NAME__, msg);
125 }
126 else if (rawLength < minimumRequiredSpace)
127 {// should protect against -ve length teleporter
128 std::string msg = "\nInsufficient space between the first and last elements\n";
129 msg += "in the beam line to fit the terminator and teleporter - these will not be built.\n";
130 msg += "Minimum space for circular mechanics is ";
131 msg += std::to_string( minimumRequiredSpace/CLHEP::um) + " um";
132 throw BDSException(__METHOD_NAME__, msg);
133 }
134
135 // update input reference variable (ie 2nd output variable)
136 teleporterLength = rawLength - (sL + 3*pL);
137 positionDelta -= lastItemUnitDir * (sL + 3*pL); // subtraction only in local z
138
139 auto firstItemRotation = firstElement->GetReferenceRotationStart();
140 auto lastItemRotation = lastElement->GetReferenceRotationEnd();
141 auto rotation = (*firstItemRotation) * (*lastItemRotation);
142
143 G4Transform3D result = G4Transform3D(rotation, positionDelta);
144
145 G4cout << "Calculating Teleporter delta" << G4endl;
146 G4cout << "Last item end position: " << lastItemPosition << " mm" << G4endl;
147 G4cout << "First item start position: " << firstItemPosition << " mm" << G4endl;
148 G4cout << "Teleporter delta (pos): " << positionDelta << " mm" << G4endl;
149 G4cout << "Rotation: " << rotation << G4endl;
150 return result;
151}
152
153BDSTeleporter::~BDSTeleporter()
154{
155 delete vacuumFieldInfo;
156}
Abstract class that represents a component of an accelerator.
const G4String name
Const protected member variable that may not be changed by derived classes.
static G4Material * emptyMaterial
Useful variable often used in construction.
G4double chordLength
Protected member variable that can be modified by derived classes.
G4ThreeVector GetReferencePositionEnd() const
Accessor.
A vector of BDSBeamlineElement instances - a beamline.
BDSBeamlineElement * front() const
Return a reference to the first element.
BDSBeamlineElement * back() const
Return a reference to the last element.
static G4double PaddingLength()
Access the padding length between each element added to the beamline.
G4bool empty() const
Iterator mechanics.
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:38
void RegisterFieldForConstruction(const BDSFieldInfo *info, G4LogicalVolume *logicalVolume, const G4bool propagateToDaughters=false, const BDSMagnetStrength *magnetStrengthForScaling=nullptr, const G4String &scalingKey="none")
static BDSFieldBuilder * Instance()
Singleton pattern accessor.
All info required to build complete field of any type.
void RegisterUserLimits(G4UserLimits *userLimit)
void SetExtent(const BDSExtent &extIn)
Set extent.
static BDSGlobalConstants * Instance()
Access method.
static G4double ChordLength()
Access the sampler plane length in other classes.
BDSTeleporter()=delete
Private default constructor to force the use of the supplied one.
BDSFieldInfo * vacuumFieldInfo
Recipe for teleporter 'field'.
G4double horizontalWidth
The full horizontal width of the teleporter.
virtual void Build()
Overridden method from BDSAcceleratorComponent that dictates the construction.
virtual void BuildContainerLogicalVolume()
G4Transform3D CalculateTeleporterDelta(const BDSBeamline *beamline, G4double &teleporterLength)