BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSScreenLayer.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 "BDSDebug.hh"
19#include "BDSException.hh"
20#include "BDSGlobalConstants.hh"
21#include "BDSMaterials.hh"
22#include "BDSSamplerRegistry.hh"
23#include "BDSScreenLayer.hh"
24#include "BDSSDManager.hh"
25#include "BDSSDSampler.hh"
26#include "BDSUtilities.hh"
27
28#include "globals.hh"
29#include "G4Box.hh"
30#include "G4LogicalBorderSurface.hh"
31#include "G4LogicalVolume.hh"
32#include "G4MaterialPropertiesTable.hh"
33#include "G4OpticalSurface.hh"
34#include "G4PVPlacement.hh"
35#include "G4ThreeVector.hh"
36#include "G4VisAttributes.hh"
37
40
41BDSScreenLayer::BDSScreenLayer(G4ThreeVector sizeIn,
42 G4String nameIn,
43 G4String materialIn,
44 G4double grooveWidthIn,
45 G4double grooveSpatialFrequencyIn):
46 size(sizeIn),
47 name(nameIn),
48 material(materialIn),
49 grooveWidth(grooveWidthIn),
50 grooveSpatialFrequency(grooveSpatialFrequencyIn)
51{
52 if (!BDS::IsFinite(size.z()))
53 {throw BDSException(__METHOD_NAME__, "Insufficent length for screen layer \"" + name + "\"");}
54 colour=G4Colour(0.1,0.8,0.1,0.3);
55 Build();
56}
57
58void BDSScreenLayer::Build()
59{
60 BuildGroove();
61 BuildScreen();
62 SetVisAttributes();
63}
64
65void BDSScreenLayer::BuildGroove()
66{
67 //There may or may not be grooves in the screen layer.
68 if (!BDS::IsFinite(grooveWidth))
69 {return;}
70
71 grooveSolid = new G4Box((name+"_grooveSolid").c_str(),
72 grooveWidth/2.0,
73 size.y()/2.0,
74 size.z()/2.0);
75 grooveLog = new G4LogicalVolume(grooveSolid,
76 BDSMaterials::Instance()->GetMaterial("air"),
77 (name+"_grooveLog").c_str());
78}
79
80void BDSScreenLayer::BuildScreen()
81{
82 //A small safety length to separate the screen layers.
83 G4double tinyLenSaf = 1e-3*CLHEP::nm;
84 solid = new G4Box((name+"_solid").c_str(),
85 size.x()/2.0,
86 size.y()/2.0,
87 size.z()/2.0-tinyLenSaf);
88 log = new G4LogicalVolume(solid,
89 BDSMaterials::Instance()->GetMaterial(material),
90 (name+"_log").c_str());
91 CutGrooves();
92
93 log->SetUserLimits(BDSGlobalConstants::Instance()->DefaultUserLimits());
94}
95
96void BDSScreenLayer::CutGrooves()
97{
98 if(grooveWidth>0)
99 {
100 for(G4double xPosition=-size.x()/2.0+grooveWidth/2.0;
101 xPosition<((size.x()/2.0)-grooveWidth/2.0);
102 xPosition+=grooveSpatialFrequency)
103 { CutGroove(xPosition);}
104 }
105}
106
107void BDSScreenLayer::CutGroove(G4double xPosition)
108{
109 if (!grooveLog)
110 {return;}
111 G4ThreeVector pos(xPosition, 0, 0);
112
113 //Create a new physical volume placement for each groove in the screen.
114 new G4PVPlacement(nullptr,
115 pos,
116 grooveLog,
117 (G4String)(name+"_groove"),
118 log,
119 true,
120 nGrooves,
121 false);
122
123 nGrooves++; //Increment the counter for the number of grooves in the screen.
124}
125
126void BDSScreenLayer::SetVisAttributes()
127{
128 G4VisAttributes* visAtt=new G4VisAttributes(colour);
129 visAtt->SetForceSolid(true);
130 G4VisAttributes* visAttGroove=new G4VisAttributes(G4Colour(0.0,0.0,0.0));
131 visAttGroove->SetForceSolid(true);
132 log->SetVisAttributes(visAtt);
133 if(grooveLog)
134 {grooveLog->SetVisAttributes(visAttGroove);}
135}
136
137void BDSScreenLayer::SetPhys(G4PVPlacement* physIn)
138{
139 if (physIn->GetLogicalVolume() != GetLog())
140 {throw BDSException(__METHOD_NAME__, "physical volume placement does not match logical volume.");}
141 phys = physIn;
142}
143
144void BDSScreenLayer::SetColour(G4Colour col)
145{
146 colour=col;
147 SetVisAttributes();
148}
149
150
152{
153 G4String samplerName = name;
154 log->SetSensitiveDetector(BDSSDManager::Instance()->SamplerPlane());
155 samplerID=BDSSamplerRegistry::Instance()->RegisterSampler(samplerName,nullptr);
156 log->SetUserLimits(BDSGlobalConstants::Instance()->DefaultUserLimits());
157}
158
159/*
160void BDSScreenLayer::backInternalMirror()
161{
162 internalMirror = new InternalMirror(InternalMirror::BACK, size,material,log,phys);
163}
164
165void BDSScreenLayer::frontInternalMirror()
166{
167 internalMirror = new InternalMirror(InternalMirror::FRONT,size,material,log,phys);
168}
169
170BDSScreenLayer::InternalMirror::~InternalMirror()
171{;}
172
173BDSScreenLayer::InternalMirror::InternalMirror(G4int varsideIn,
174 G4ThreeVector sizeIn,
175 G4String materialIn,
176 G4LogicalVolume* motherLogIn,
177 G4PVPlacement* motherPhysIn):
178 side(varsideIn),
179 motherSize(sizeIn),
180 motherMaterial(materialIn),
181 motherLog(motherLogIn),
182 motherPhys(motherPhysIn)
183{
184 thickness=1e-9*CLHEP::m;
185 compute();
186 geom();
187 place();
188 optical();
189}
190
191void BDSScreenLayer::InternalMirror::geom()
192{
193 G4double tinyLenSaf = 1e-6*CLHEP::nm;
194 solid = new G4Box("internalMirrorSolid",
195 motherSize.x()/2.0,
196 motherSize.y()/2.0,
197 thickness - tinyLenSaf);
198 log = new G4LogicalVolume(solid,
199 BDSMaterials::Instance()->GetMaterial("titanium"),
200 "internalMirrorLog");
201}
202
203void BDSScreenLayer::InternalMirror::place()
204{
205 phys=new G4PVPlacement(nullptr, //Create a new physical volume placement for each groove in the screen.
206 G4ThreeVector(0,0,pos),
207 log,
208 "internalMirrorPhys",
209 motherLog,
210 false,
211 0,
212 true);
213}
214
215void BDSScreenLayer::InternalMirror::optical()
216{
217 G4OpticalSurface* OpSurface=new G4OpticalSurface("OpSurface");
218 //G4LogicalBorderSurface* LogSurface =
219 new G4LogicalBorderSurface("LogSurface", motherPhys, phys, OpSurface);
220 // G4LogicalSkinSurface* LogSurface = new G4LogicalSkinSurface("LogSurface",screenLayer(1)->log(),OpSurface);
221 OpSurface->SetType(dielectric_metal);
222 OpSurface->SetModel(unified);
223 OpSurface->SetFinish(polished);
224 G4MaterialPropertiesTable* SMPT = new G4MaterialPropertiesTable();
225 SMPT->AddConstProperty("REFLECTIVITY",0.8);
226 // SMPT->AddConstProperty("RINDEX",1.5750);
227 OpSurface->SetMaterialPropertiesTable(SMPT);
228}
229
230void BDSScreenLayer::InternalMirror::compute()
231{
232 G4double sign=0;
233 try{
234 if(side==BACK){
235 sign = 1;
236 }else if(side==FRONT){
237 sign = -1;
238 }else{
239 throw 1;
240 }
241 }catch(int e){
242 G4cerr<< "BDSScreenLayer::computInternalMirror - exception number " << e << " occurred. Exiting." << G4endl;
243 exit(e);
244 }
245
246 pos = sign*(motherSize.z()/2.0-thickness/2.0);
247}
248*/
General exception with possible name of object and message.
static BDSGlobalConstants * Instance()
Access method.
static BDSMaterials * Instance()
Singleton pattern access.
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)
G4LogicalVolume * GetLog() const
Accessor.
void AssignSampler()
Make this plane a sampling plane.
G4int nGrooves
Counter for the number of grooves etched into the screen.
BDSScreenLayer()
Used in modules/AWAKE/include/BDSMultiFacetLayer.hh.
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())