BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSLinkOpaqueBox.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2023.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSAcceleratorComponent.hh"
20#include "BDSApertureInfo.hh"
21#include "BDSApertureType.hh"
22#include "BDSBeamline.hh"
23#include "BDSColours.hh"
24#include "BDSDebug.hh"
25#include "BDSException.hh"
26#include "BDSExtent.hh"
27#include "BDSGlobalConstants.hh"
28#include "BDSLinkOpaqueBox.hh"
29#include "BDSMaterials.hh"
30#include "BDSSamplerCustom.hh"
31#include "BDSSamplerPlacementRecord.hh"
32#include "BDSSamplerPlane.hh"
33#include "BDSSamplerRegistry.hh"
34#include "BDSSDManager.hh"
35#include "BDSSDSamplerLink.hh"
36#include "BDSTiltOffset.hh"
37#include "BDSUtilities.hh"
38
39#include "G4Box.hh"
40#include "G4LogicalVolume.hh"
41#include "G4RotationMatrix.hh"
42#include "G4PVPlacement.hh"
43#include "G4SubtractionSolid.hh"
44#include "G4ThreeVector.hh"
45#include "G4Types.hh"
46#include "G4UserLimits.hh"
47#include "G4VisAttributes.hh"
48#include "G4TwoVector.hh"
49
50#include "CLHEP/Units/SystemOfUnits.h"
51
52#include <limits>
53
55 BDSTiltOffset* tiltOffsetIn,
56 G4double outputSamplerRadiusIn):
57 BDSGeometryComponent(nullptr, nullptr),
58 component(acceleratorComponentIn),
59 outputSamplerRadius(outputSamplerRadiusIn),
60 sampler(nullptr)
61{
62 if (tiltOffsetIn->HasFiniteTilt() && BDS::IsFinite(component->GetAngle()))
63 {throw BDSException(__METHOD_NAME__, "finite tilt with angled component unsupported.");}
64
65 G4double tilt = tiltOffsetIn->GetTilt();
66 G4double ox = tiltOffsetIn->GetXOffset();
67 G4double oy = tiltOffsetIn->GetYOffset();
68 BDSExtent extent = component->GetExtent();
69 extent = extent.TiltOffset(tiltOffsetIn);
70 const G4double gap = 10 * CLHEP::cm;
71 const G4double opaqueBoxThickness = 10 * CLHEP::mm;
72 G4String name = component->GetName();
73
74 G4double mx = extent.MaximumX();
75 G4double my = extent.MaximumY();
76 G4double mr = std::max({mx, my, outputSamplerRadius});
77 G4double mz = extent.MaximumZ();
78 G4Box* terminatorBoxOuter = new G4Box(name + "_terminator_box_outer_solid",
79 mr + gap + opaqueBoxThickness,
80 mr + gap + opaqueBoxThickness,
81 mz + gap + opaqueBoxThickness);
82 RegisterSolid(terminatorBoxOuter);
83 G4Box* terminatorBoxInner = new G4Box(name + "_terminator_box_inner_solid",
84 mr + gap,
85 mr + gap,
86 mz + gap);
87 RegisterSolid(terminatorBoxInner);
88 G4SubtractionSolid* opaqueBox = new G4SubtractionSolid(name + "_opaque_box_solid",
89 terminatorBoxOuter,
90 terminatorBoxInner);
91 RegisterSolid(opaqueBox);
92 G4LogicalVolume* opaqueBoxLV = new G4LogicalVolume(opaqueBox,
93 BDSMaterials::Instance()->GetMaterial("G4_Galactic"),
94 name + "_opaque_box_lv");
95 RegisterLogicalVolume(opaqueBoxLV);
96
97 G4UserLimits* termUL = new G4UserLimits();
98 termUL->SetUserMinEkine(std::numeric_limits<double>::max());
99 RegisterUserLimits(termUL);
100 opaqueBoxLV->SetUserLimits(termUL);
101
102 G4VisAttributes* obVis = new G4VisAttributes(*BDSColours::Instance()->GetColour("opaquebox"));
103 obVis->SetVisibility(true);
104 opaqueBoxLV->SetVisAttributes(obVis);
105 RegisterVisAttributes(obVis);
106
107 G4double ls = BDSGlobalConstants::Instance()->LengthSafetyLarge();
108 G4double margin = gap + opaqueBoxThickness + ls;
109 G4double xsize = mr + margin;
110 G4double ysize = mr + margin;
111 G4double zsize = mz + margin;
112 containerSolid = new G4Box(name + "_opaque_box_vacuum_solid",
113 xsize,
114 ysize,
115 zsize);
116
117 containerLogicalVolume = new G4LogicalVolume(containerSolid,
118 BDSMaterials::Instance()->GetMaterial("G4_Galactic"),
119 name + "_container_lv");
120 containerLogicalVolume->SetVisAttributes(BDSGlobalConstants::Instance()->ContainerVisAttr());
121
122 // auto boxPlacement =
123 new G4PVPlacement(nullptr,
124 G4ThreeVector(),
125 opaqueBoxLV,
126 name + "_opaque_box_pv",
127 containerLogicalVolume,
128 false,
129 1,
130 true);
131
132 G4ThreeVector of = G4ThreeVector(ox,oy,0);
133 G4RotationMatrix* rm = new G4RotationMatrix();
134 if (BDS::IsFinite(tilt))
135 {
136 rm->rotateZ(tilt);
137 }
138 G4Transform3D* placementTransform = new G4Transform3D(*rm, of);
139 delete rm;
140
141 new G4PVPlacement(*placementTransform,
142 component->GetContainerLogicalVolume(),
143 component->GetName() + "_pv",
144 containerLogicalVolume,
145 false,
146 1,
147 true);
148
149 outerExtent = BDSExtent(xsize, ysize, zsize);
150
151 G4RotationMatrix* rm2 = new G4RotationMatrix();
152 offsetToStart = G4ThreeVector(0.0, 0.0, -0.5*component->GetChordLength());
153 transformToStart = G4Transform3D(*rm2, offsetToStart);
154 delete rm2;
155}
156
157BDSLinkOpaqueBox::~BDSLinkOpaqueBox()
158{
159 delete sampler;
160}
161
163{
164 G4String samplerName = component->GetName() + "_out";
165 BDSApertureType apt = BDSApertureType::circular;
166 BDSApertureInfo ap = BDSApertureInfo(apt, outputSamplerRadius, 0, 0, 0);
167 sampler = new BDSSamplerCustom(samplerName, ap);
168 sampler->GetContainerLogicalVolume()->SetSensitiveDetector(BDSSDManager::Instance()->SamplerLink());
170 auto z2 = component->GetExtent();
171 G4ThreeVector position = G4ThreeVector(0,0,0.5*component->GetChordLength() + 2*BDSSamplerCustom::ChordLength());
172 G4RotationMatrix* rm = nullptr;
173 if (BDS::IsFinite(component->GetAngle()))
174 {
175 rm = new G4RotationMatrix();
176 rm->rotateY(0.5 * component->GetAngle()); // rotate to output face
178 position = G4ThreeVector(component->Sagitta(), 0, 0.5*component->GetChordLength());
179 G4ThreeVector gap = G4ThreeVector(0,0,2*BDSSamplerCustom::ChordLength());
180 position += gap.transform(*rm);
181 }
182 // if there's finite angle, we ensure (in constructor) there's no tilt
183 G4RotationMatrix* rml = rm ? new G4RotationMatrix(*rm) : new G4RotationMatrix();
184 BDSSamplerPlacementRecord info(samplerName, sampler, G4Transform3D(*rml, position));
185 delete rml;
186
187 G4int samplerID = BDSSamplerRegistry::Instance()->RegisterSampler(info);
188 new G4PVPlacement(rm,
189 position,
190 sampler->GetContainerLogicalVolume(),
191 samplerName + "_pv",
192 containerLogicalVolume,
193 false,
194 samplerID,
195 true);
196 return samplerID;
197}
Abstract class that represents a component of an accelerator.
G4double Sagitta() const
Calculate the sagitta - ie the distance between the chord and the arc at the centre.
virtual G4String GetName() const
The name of the component without modification.
virtual G4double GetChordLength() const
Holder class for all information required to describe an aperture.
static BDSColours * Instance()
singleton pattern
Definition: BDSColours.cc:33
General exception with possible name of object and message.
Definition: BDSException.hh:35
Holder for +- extents in 3 dimensions.
Definition: BDSExtent.hh:39
BDSExtent TiltOffset(const BDSTiltOffset *tiltOffset) const
Provide a new copy of this extent with both a tilt and an offset applied.
Definition: BDSExtent.cc:105
A generic geometry component for a bdsim model.
G4LogicalVolume * GetContainerLogicalVolume() const
Accessor - see member for more info.
BDSExtent GetExtent() const
Accessor - see member for more info.
void RegisterRotationMatrix(G4RotationMatrix *rotationMatrix)
static BDSGlobalConstants * Instance()
Access method.
BDSLinkOpaqueBox()=delete
Default constructor.
G4int PlaceOutputSampler()
Place the output sampler.
static BDSMaterials * Instance()
Singleton pattern access.
Definition: BDSMaterials.cc:39
Custom shaped sampler with fixed thickness.
static G4double ChordLength()
Access the sampler plane length in other classes.
Information about a registered sampler.
static BDSSamplerRegistry * Instance()
Accessor for registry.
G4int RegisterSampler(const G4String &name, BDSSampler *sampler, const G4Transform3D &transform=G4Transform3D(), G4double S=-1000, const BDSBeamlineElement *element=nullptr, BDSSamplerType type=BDSSamplerType::plane, G4double radius=0)
void MakeMaterialValidForUseInMassWorld()
Definition: BDSSampler.cc:50
A holder for any placement offsets and rotations for a BDSAcceleratorComponent.
G4double GetYOffset() const
Accessor.
G4double GetXOffset() const
Accessor.
G4bool HasFiniteTilt() const
Inspector.
G4double GetTilt() const
Accessor.
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())