BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSMultilayerScreen.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 "BDSColourWheel.hh"
20#include "BDSDebug.hh"
21#include "BDSException.hh"
22#include "BDSGlobalConstants.hh"
23#include "BDSMaterials.hh"
24#include "BDSMultilayerScreen.hh"
25#include "BDSSamplerRegistry.hh"
26#include "BDSScreenLayer.hh"
27
28#include "G4Box.hh"
29#include "G4VisAttributes.hh"
30#include "G4LogicalBorderSurface.hh"
31#include "G4LogicalVolume.hh"
32#include "G4OpticalSurface.hh"
33#include "G4PVPlacement.hh"
34#include "G4VSolid.hh"
35#include "G4Version.hh"
36
37BDSMultilayerScreen::BDSMultilayerScreen(const G4TwoVector& xysizeIn,
38 const G4String& nameIn):
39 xysize(xysizeIn),
40 name(nameIn),
41 log(nullptr),
42 phys(nullptr),
43 solid(nullptr),
44 colourWheel(new BDSColourWheel())
45{
46 size.setX(xysize.x());
47 size.setY(xysize.y());
48 size.setZ(0); // starts as 0, but expands as layers added
49}
50
51BDSMultilayerScreen::~BDSMultilayerScreen()
52{
53 delete colourWheel;
54 for (auto layer : screenLayers)
55 {delete layer;}
56}
57
59 G4String material,
60 G4String nameIn,
61 G4int isSampler,
62 G4double grooveWidth,
63 G4double grooveSpatialFrequency)
64{
65 G4String layerName;
66 if (isSampler)
67 {
68 G4int nThisSampler = BDSSamplerRegistry::Instance()->NumberOfExistingSamplers() + 1;
69 G4String tempString = "Sampler_" + std::to_string(nThisSampler);
70 layerName = tempString + "_" + nameIn;
71 }
72 else
73 {layerName = nameIn;}
74
75 G4ThreeVector layerSize(xysize.x(), xysize.y(), thickness);
76 BDSScreenLayer* screen = new BDSScreenLayer(layerSize, layerName, material,
77 grooveWidth,grooveSpatialFrequency);
78 AddScreenLayer(screen, isSampler);
79}
80
82{
84 layer->SetColour(colourWheel->Colour());
85 if (isSampler)
86 {layer->AssignSampler();}
87 screenLayers.push_back(layer);
88 screenLayerNames[layer->GetName()] = layer;
89}
90
92{
93 auto result = screenLayerNames.find(layerName);
94 if (result == screenLayerNames.end())
95 {throw BDSException(__METHOD_NAME__, "screen layer \"" + layerName + "\" not found");}
96 else
97 {return result->second;}
98}
99
101{
104 PlaceLayers();
105}
106
107void BDSMultilayerScreen::Place(G4RotationMatrix* rot,
108 const G4ThreeVector& pos,
109 G4LogicalVolume* motherVol)
110{
111 SetPhys(new G4PVPlacement(rot,
112 pos,
113 log,
114 "multilayerScreen",
115 motherVol,
116 false,
117 0,
118 true
119 ));
120}
121
122void BDSMultilayerScreen::ReflectiveSurface(G4int layer1, G4int layer2)
123{
124 G4OpticalSurface* OpSurface=new G4OpticalSurface("OpSurface");
125 // G4LogicalBorderSurface* LogSurface =
126 new G4LogicalBorderSurface("LogSurface",
127 ScreenLayer(layer1)->GetPhys(),
128 ScreenLayer(layer2)->GetPhys(),
129 OpSurface);
130 // G4LogicalSkinSurface* LogSurface = new G4LogicalSkinSurface("LogSurface",screenLayer(1)->GetLog(),OpSurface);
131 OpSurface->SetType(dielectric_metal);
132 OpSurface->SetModel(unified);
133 OpSurface->SetFinish(polished);
134
135 G4MaterialPropertiesTable* SMPT = new G4MaterialPropertiesTable();
136#if G4VERSION_NUMBER > 1109
137 SMPT->AddConstProperty("REFLECTIVITY",0.8,true);
138#else
139 SMPT->AddConstProperty("REFLECTIVITY",0.8);
140#endif
141
142 /*
143 OpSurface->SetSigmaAlpha(0.7);
144 SMPT->AddConstProperty("SPECULARLOBECONSTANT",1.0);
145 SMPT->AddConstProperty("SPECULARSPIKECONSTANT",0.0);
146 SMPT->AddConstProperty("BACKSCATTERCONSTANT",0.0);
147 SMPT->AddConstProperty("EFFICIENCY",0.0);
148 // SMPT->AddConstProperty("RINDEX",1.5750);
149 */
150
151 OpSurface->SetMaterialPropertiesTable(SMPT);
152}
153
154void BDSMultilayerScreen::RoughSurface(G4int layer1, G4int layer2)
155{
156 G4OpticalSurface* OpSurface=new G4OpticalSurface("OpSurface");
157 OpSurface->SetType(dielectric_dielectric);
158 OpSurface->SetFinish(ground);
159 OpSurface->SetModel(unified);
160
161 // G4LogicalBorderSurface* LogSurface =
162 new G4LogicalBorderSurface("LogSurface",
163 ScreenLayer(layer1)->GetPhys(),
164 ScreenLayer(layer2)->GetPhys(),
165 OpSurface);
166
167 G4double sigma_alpha=0.7;
168 OpSurface->SetSigmaAlpha(sigma_alpha);
169 G4MaterialPropertiesTable* SMPT = new G4MaterialPropertiesTable();
170#if G4VERSION_NUMBER > 1109
171 SMPT->AddConstProperty("REFLECTIVITY",0.0, true);
172#else
173 SMPT->AddConstProperty("REFLECTIVITY",0.0);
174#endif
175 OpSurface->SetMaterialPropertiesTable(SMPT);
176}
177
179{
180 if (screenLayers.empty())
181 {throw BDSException(__METHOD_NAME__, "Screen \"" + name +"\" has no layers.");}
182
183 //Compute the total z thickness.
184 G4double temp = 0;
185 for (const auto& layer : screenLayers)
186 {temp += layer->GetSize().z();}
187 size.setZ(temp);
188
189 //Compute the z positions of all the layers.
190 //Position each layer after the previous one.
191 G4double pos = screenLayers[0]->GetSize().z()/2.0 -1.0*size.z()/2.0;
192 screenLayerZPos.push_back(pos);
193 for (unsigned int i=1; i<screenLayers.size(); i++)
194 {
195 pos += (screenLayers[i-1]->GetSize().z()+screenLayers[i]->GetSize().z())/2.0;
196 screenLayerZPos.push_back(pos);
197 }
198}
199
201{
202 // Make container marginally bigger to avoid overlaps
203 G4double lengthSafety = BDSGlobalConstants::Instance()->LengthSafety();
204
205 solid = new G4Box((name+"_solid").c_str(),
206 size.x()/2.0 + lengthSafety,
207 size.y()/2.0 + lengthSafety,
208 size.z()/2.0 + lengthSafety);
209 G4Material* mat = BDSMaterials::Instance()->GetMaterial(BDSGlobalConstants::Instance()->VacuumMaterial());
210
211 log = new G4LogicalVolume(solid,
212 mat,
213 (name+"_log").c_str());
214
215 G4VisAttributes* visAtt = new G4VisAttributes(G4Colour(0.0,0.0,1.0,0.3));
216 visAtt->SetForceWireframe(true);
217 log->SetVisAttributes(visAtt);
218}
219
221{
222 G4ThreeVector pos(0,0,0);
223
224 for (unsigned int i=0; i<screenLayers.size(); i++)
225 {
226 pos.setZ(screenLayerZPos[i]);
227#ifdef BDSDEBUG
228 G4cout << __METHOD_NAME__ << ": placing screen layer with ID: "
229 << screenLayers[i]->GetSamplerID() << G4endl;
230#endif
231 //Create a new physical volume placement for each groove in the screen.
232 screenLayers[i]->SetPhys(new G4PVPlacement(nullptr,
233 pos,
234 screenLayers[i]->GetLog(),
235 screenLayers[i]->GetName(),
236 log,
237 false,
238 screenLayers[i]->GetSamplerID(),
239 true));
240 }
241}
Three colours that are supplied sequentially.
void Spin()
Iterate colour choice from RGB.
G4Colour Colour()
Return current colour.
General exception with possible name of object and message.
Definition: BDSException.hh:35
static BDSGlobalConstants * Instance()
Access method.
static BDSMaterials * Instance()
Singleton pattern access.
Definition: BDSMaterials.cc:39
G4Material * GetMaterial(G4String material) const
Get material by name.
void AddScreenLayer(G4double thickness, G4String material, G4String name, G4int isSampler=0, G4double grooveWidth=0, G4double grooveSpatialFrequency=0)
Construct and add a screen layer.
std::vector< BDSScreenLayer * > screenLayers
Main storage of all layers.
void RoughSurface(G4int layer1, G4int layer2)
Construct a rough surface between two layers.
void SetPhys(G4PVPlacement *physIn)
Set a physical placement to member variable.
BDSMultilayerScreen()=delete
Private default constructor to force use of provided one.
G4ThreeVector size
Extent.
G4VSolid * solid
Geometrical objects:
void BuildMotherVolume()
Build a container volume.
std::map< G4String, BDSScreenLayer * > screenLayerNames
Map of names for looking up.
std::vector< G4double > screenLayerZPos
Cache of calculated z locations for layers.
virtual void Place(G4RotationMatrix *rot, const G4ThreeVector &pos, G4LogicalVolume *motherVol)
Place the member logical volume 'log' with a given transform in a given mother volume.
BDSScreenLayer * ScreenLayer(G4int layer)
Get a particular screen layer by index.
BDSColourWheel * colourWheel
void Build()
Construct container, compute dimensions then place layers.
G4LogicalVolume * log
Geometrical objects:
G4TwoVector xysize
X,Y size of multilayer screen.
void ReflectiveSurface(G4int layer1, G4int layer2)
Construct a reflective surface between two layers.
G4String name
Name of multilayer screen.
void PlaceLayers()
Place each layer in order in the container volume.
static BDSSamplerRegistry * Instance()
Accessor for registry.
G4int NumberOfExistingSamplers() const
Get number of registered samplers.
An individual screen layer for a multilayer screen.
void AssignSampler()
Make this plane a sampling plane.
G4String GetName() const
Accessor.