OMSim
Geant4 for IceCube optical module studies
OMSimOpBoundaryProcess.hh
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 //
28 //
30 // Optical Photon Boundary Process Class Definition
32 //
33 // File: G4OpBoundaryProcess.hh
34 // Description: Discrete Process -- reflection/refraction at
35 // optical interfaces
36 // Version: 1.1
37 // Created: 1997-06-18
38 // Modified: 2005-07-28 add G4ProcessType to constructor
39 // 1999-10-29 add method and class descriptors
40 // 1999-10-10 - Fill NewMomentum/NewPolarization in
41 // DoAbsorption. These members need to be
42 // filled since DoIt calls
43 // aParticleChange.SetMomentumChange etc.
44 // upon return (thanks to: Clark McGrew)
45 // 2006-11-04 - add capability of calculating the reflectivity
46 // off a metal surface by way of a complex index
47 // of refraction - Thanks to Sehwook Lee and John
48 // Hauptman (Dept. of Physics - Iowa State Univ.)
49 // 2009-11-10 - add capability of simulating surface reflections
50 // with Look-Up-Tables (LUT) containing measured
51 // optical reflectance for a variety of surface
52 // treatments - Thanks to Martin Janecek and
53 // William Moses (Lawrence Berkeley National Lab.)
54 // 2013-06-01 - add the capability of simulating the transmission
55 // of a dichronic filter
56 // 2017-02-24 - add capability of simulating surface reflections
57 // with Look-Up-Tables (LUT) developed in DAVIS
58 //
59 // Author: Peter Gumplinger
60 // adopted from work by Werner Keil - April 2/96
61 //
63 
64 #pragma once
65 #include "G4OpticalPhoton.hh"
66 #include "G4OpticalSurface.hh"
67 #include "G4RandomTools.hh"
68 #include "G4VDiscreteProcess.hh"
69 #include "G4VUserTrackInformation.hh"
70 #include <G4AutoLock.hh>
71 #include <G4Threading.hh>
72 
73 class PhotonMaterialTracking : public G4VUserTrackInformation
74 {
75 public:
76  PhotonMaterialTracking() : G4VUserTrackInformation() {}
77  virtual ~PhotonMaterialTracking() {}
78 
79  void addVolume(G4MaterialPropertiesTable* mpt) {
80  if (mVolumeHistory.empty() || mpt != mVolumeHistory.back()) {
81  mVolumeHistory.push_back(mpt);
82  }
83  }
84 
85  G4MaterialPropertiesTable* getNthPreviousVolume(G4int n) {
86  if (n < mVolumeHistory.size())
87  return mVolumeHistory[mVolumeHistory.size() - 1 - n];
88  return nullptr;
89  }
90 
91  G4int getVolumeHistorySize() const { return mVolumeHistory.size(); }
92 
93 private:
94  std::vector<G4MaterialPropertiesTable*> mVolumeHistory;
95 };
96 
98 {
99  G4double Reflectivity;
100  G4double Transmittance;
101  G4double Absorption;
102 };
104 {
105  G4complex rTE;
106  G4complex rTM;
107  G4complex tTE;
108  G4complex tTM;
109 };
110 
111 enum G4OpBoundaryProcessStatus
112 {
113  Undefined,
114  Transmission,
115  FresnelRefraction,
116  FresnelReflection,
117  TotalInternalReflection,
118  LambertianReflection,
119  LobeReflection,
120  SpikeReflection,
121  BackScattering,
122  Absorption,
123  Detection,
124  NotAtBoundary,
125  SameMaterial,
126  StepTooSmall,
127  NoRINDEX,
128  PolishedLumirrorAirReflection,
129  PolishedLumirrorGlueReflection,
130  PolishedAirReflection,
131  PolishedTeflonAirReflection,
132  PolishedTiOAirReflection,
133  PolishedTyvekAirReflection,
134  PolishedVM2000AirReflection,
135  PolishedVM2000GlueReflection,
136  EtchedLumirrorAirReflection,
137  EtchedLumirrorGlueReflection,
138  EtchedAirReflection,
139  EtchedTeflonAirReflection,
140  EtchedTiOAirReflection,
141  EtchedTyvekAirReflection,
142  EtchedVM2000AirReflection,
143  EtchedVM2000GlueReflection,
144  GroundLumirrorAirReflection,
145  GroundLumirrorGlueReflection,
146  GroundAirReflection,
147  GroundTeflonAirReflection,
148  GroundTiOAirReflection,
149  GroundTyvekAirReflection,
150  GroundVM2000AirReflection,
151  GroundVM2000GlueReflection,
152  Dichroic,
153  CoatedDielectricReflection,
154  CoatedDielectricRefraction,
155  CoatedDielectricFrustratedTransmission
156 };
157 
158 class G4OpBoundaryProcess : public G4VDiscreteProcess
159 {
160 public:
161  explicit G4OpBoundaryProcess(const G4String &processName = "OpBoundary",
162  G4ProcessType type = fOptical);
163  virtual ~G4OpBoundaryProcess();
164 
165  virtual G4bool IsApplicable(
166  const G4ParticleDefinition &aParticleType) override;
167  // Returns true -> 'is applicable' only for an optical photon.
168 
169  virtual G4double GetMeanFreePath(const G4Track &, G4double,
170  G4ForceCondition *condition) override;
171  // Returns infinity; i. e. the process does not limit the step, but sets the
172  // 'Forced' condition for the DoIt to be invoked at every step. However, only
173  // at a boundary will any action be taken.
174 
175  G4VParticleChange *PostStepDoIt(const G4Track &aTrack,
176  const G4Step &aStep) override;
177  // This is the method implementing boundary processes.
178 
179  virtual G4OpBoundaryProcessStatus GetStatus() const;
180  // Returns the current status.
181 
182  virtual void SetInvokeSD(G4bool);
183  // Set flag for call to InvokeSD method.
184 
185  virtual void PreparePhysicsTable(const G4ParticleDefinition &) override;
186 
187  virtual void Initialise();
188 
189  void SetVerboseLevel(G4int);
190 
191 private:
192  G4OpBoundaryProcess(const G4OpBoundaryProcess &right) = delete;
193  G4OpBoundaryProcess &operator=(const G4OpBoundaryProcess &right) = delete;
194 
195  G4bool G4BooleanRand(const G4double prob) const;
196 
197  G4ThreeVector GetFacetNormal(const G4ThreeVector &Momentum,
198  const G4ThreeVector &Normal) const;
199  G4Mutex boundaryProcessMutex;
200  void DielectricMetal();
201  void DielectricDielectric();
202 
203  void DielectricLUT();
204  void DielectricLUTDAVIS();
205 
206  void DielectricDichroic();
207  void PhotocathodeCoatedComplex(const G4Track* pTrack);
208 
209  void ChooseReflection();
210  void DoAbsorption();
211  void DoReflection();
212 
213  G4double GetIncidentAngle();
214  // Returns the incident angle of optical photon
215 
216  G4double GetReflectivity(G4double E1_perp, G4double E1_parl,
217  G4double incidentangle, G4double RealRindex,
218  G4double ImaginaryRindex);
219  // Returns the Reflectivity on a metallic surface
220 
221  FresnelCoefficients ThreeLayerSystem(FresnelCoefficients pCoefficientsL1, FresnelCoefficients pCoefficientsL2, G4complex pFactor);
222 
223  G4OpBoundaryProcessStatus getStatus(OpticalLayerResult pResults);
224 
225  // complex angle functions
226  OpticalLayerResult CalculateThinLayerCoefficientsComplex(G4double sinTL, G4double wavelength,
227  G4complex cost1, G4complex cost2, G4Track pTrack);
228  FresnelCoefficients CalculateFresnelCoefficientsComplex(G4complex pComplexRindex1,
229  G4complex pComplexRindex2,
230  G4complex pCost1,
231  G4complex pCost2);
232 
233  OpticalLayerResult Fresnel2ProbabilityComplex(FresnelCoefficients pCoefficients,
234  G4double pRindex1,
235  G4double pRindex2,
236  G4double pImagRIndex1,
237  G4double pImagRIndex2,
238  G4complex pCost1,
239  G4complex pCost2);
240 
241  void CalculateReflectivity();
242 
243  void BoundaryProcessVerbose() const;
244 
245  // Invoke SD for post step point if the photon is 'detected'
246  G4bool InvokeSD(const G4Step *step);
247 
248  G4ThreeVector fOldMomentum;
249  G4ThreeVector fOldPolarization;
250 
251  G4ThreeVector fNewMomentum;
252  G4ThreeVector fNewPolarization;
253 
254  G4ThreeVector fGlobalNormal;
255  G4ThreeVector fFacetNormal;
256 
257  const G4Material *fMaterial1;
258  const G4Material *fMaterial2;
259 
260  G4OpticalSurface *fOpticalSurface;
261 
262  G4MaterialPropertyVector *fRealRIndexMPV;
263  G4MaterialPropertyVector *fImagRIndexMPV;
264  G4Physics2DVector *fDichroicVector;
265 
266  G4double fPhotonMomentum;
267  G4double fRindex1;
268  G4double fRindex2;
269  // newly added
270  G4double fAbsorptionLength1;
271  G4double fAbsorptionLength2;
272 
273  G4double sint1;
274 
275  G4double fReflectivity;
276  G4double fEfficiency;
277  G4double fTransmittance;
278  G4double fSurfaceRoughness;
279 
280  G4double fProb_sl, fProb_ss, fProb_bs;
281  G4double fCarTolerance;
282 
283  // Used by CoatedDielectricDielectric()
284  G4double fCoatedRindex, fCoatedThickness;
285 
286  G4OpBoundaryProcessStatus fStatus;
287  G4OpticalSurfaceModel fModel;
288  G4OpticalSurfaceFinish fFinish;
289 
290  G4int f_iTE, f_iTM;
291 
292  G4int fNumWarnings; // number of times small step warning printed
293 
294  size_t idx_dichroicX = 0;
295  size_t idx_dichroicY = 0;
296  size_t idx_rindex1 = 0;
297  size_t idx_rindex_surface = 0;
298  size_t idx_reflect = 0;
299  size_t idx_eff = 0;
300  size_t idx_trans = 0;
301  size_t idx_lobe = 0;
302  size_t idx_spike = 0;
303  size_t idx_back = 0;
304  size_t idx_rindex2 = 0;
305  size_t idx_groupvel = 0;
306  size_t idx_rrindex = 0;
307  size_t idx_irindex = 0;
308  size_t idx_coatedrindex = 0;
309  // newly added
310  size_t idx_abslength1 = 0;
311  size_t idx_abslength2 = 0;
312  size_t idx_coatedimagindex = 0;
313  size_t idx_coatedabslength = 0;
314 
315  G4bool fInvokeSD;
316 };
317 
319 // Inline methods
321 
322 inline G4bool G4OpBoundaryProcess::G4BooleanRand(const G4double prob) const
323 {
324  // Returns a random boolean variable with the specified probability
325  return (G4UniformRand() < prob);
326 }
327 
328 inline G4bool G4OpBoundaryProcess::IsApplicable(
329  const G4ParticleDefinition &aParticleType)
330 {
331  return (&aParticleType == G4OpticalPhoton::OpticalPhoton());
332 }
333 
334 inline G4OpBoundaryProcessStatus G4OpBoundaryProcess::GetStatus() const
335 {
336 
337  return fStatus;
338 }
339 
340 inline void G4OpBoundaryProcess::ChooseReflection()
341 {
342  G4double rand = G4UniformRand();
343  if (rand < fProb_ss)
344  {
345  fStatus = SpikeReflection;
346  fFacetNormal = fGlobalNormal;
347  }
348  else if (rand < fProb_ss + fProb_sl)
349  {
350  fStatus = LobeReflection;
351  }
352  else if (rand < fProb_ss + fProb_sl + fProb_bs)
353  {
354  fStatus = BackScattering;
355  }
356  else
357  {
358  fStatus = LambertianReflection;
359  }
360 }
361 
362 inline void G4OpBoundaryProcess::DoAbsorption()
363 {
364  fStatus = Absorption;
365 
366  if (G4BooleanRand(fEfficiency))
367  {
368  // EnergyDeposited =/= 0 means: photon has been detected
369  fStatus = Detection;
370  aParticleChange.ProposeLocalEnergyDeposit(fPhotonMomentum);
371  }
372  else
373  {
374  aParticleChange.ProposeLocalEnergyDeposit(0.0);
375  }
376 
377  fNewMomentum = fOldMomentum;
378  fNewPolarization = fOldPolarization;
379 
380  aParticleChange.ProposeTrackStatus(fStopAndKill);
381 }
382 
383 inline void G4OpBoundaryProcess::DoReflection()
384 {
385  if (fStatus == LambertianReflection)
386  {
387  fNewMomentum = G4LambertianRand(fGlobalNormal);
388  fFacetNormal = (fNewMomentum - fOldMomentum).unit();
389  }
390  else if (fFinish == ground)
391  {
392  fStatus = LobeReflection;
393  if (!fRealRIndexMPV || !fImagRIndexMPV)
394  {
395  fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
396  }
397  // else
398  // complex ref. index to be implemented
399  fNewMomentum =
400  fOldMomentum - (2. * fOldMomentum * fFacetNormal * fFacetNormal);
401  }
402  else
403  {
404  fStatus = SpikeReflection;
405  fFacetNormal = fGlobalNormal;
406  fNewMomentum =
407  fOldMomentum - (2. * fOldMomentum * fFacetNormal * fFacetNormal);
408  }
409  fNewPolarization =
410  -fOldPolarization + (2. * fOldPolarization * fFacetNormal * fFacetNormal);
411 }
412 
Definition: OMSimOpBoundaryProcess.hh:159
Definition: OMSimOpBoundaryProcess.hh:74
Definition: OMSimOpBoundaryProcess.hh:104
Definition: OMSimOpBoundaryProcess.hh:98