Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/optical/src/G4OpBoundaryProcess.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/optical/src/G4OpBoundaryProcess.cc (Version 11.3.0) and /processes/optical/src/G4OpBoundaryProcess.cc (Version 10.4)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 //////////////////////////////////////////////     26 ////////////////////////////////////////////////////////////////////////
 27 // Optical Photon Boundary Process Class Imple     27 // Optical Photon Boundary Process Class Implementation
 28 //////////////////////////////////////////////     28 ////////////////////////////////////////////////////////////////////////
 29 //                                                 29 //
 30 // File:        G4OpBoundaryProcess.cc             30 // File:        G4OpBoundaryProcess.cc
 31 // Description: Discrete Process -- reflection     31 // Description: Discrete Process -- reflection/refraction at
 32 //                                  optical in     32 //                                  optical interfaces
 33 // Version:     1.1                                33 // Version:     1.1
 34 // Created:     1997-06-18                         34 // Created:     1997-06-18
 35 // Modified:    1998-05-25 - Correct parallel      35 // Modified:    1998-05-25 - Correct parallel component of polarization
 36 //                           (thanks to: Stefa     36 //                           (thanks to: Stefano Magni + Giovanni Pieri)
 37 //              1998-05-28 - NULL Rindex point     37 //              1998-05-28 - NULL Rindex pointer before reuse
 38 //                           (thanks to: Stefa     38 //                           (thanks to: Stefano Magni)
 39 //              1998-06-11 - delete *sint1 in      39 //              1998-06-11 - delete *sint1 in oblique reflection
 40 //                           (thanks to: Giova     40 //                           (thanks to: Giovanni Pieri)
 41 //              1998-06-19 - move from GetLoca <<  41 //              1998-06-19 - move from GetLocalExitNormal() to the new 
 42 //                           method: GetLocalE     42 //                           method: GetLocalExitNormal(&valid) to get
 43 //                           the surface norma     43 //                           the surface normal in all cases
 44 //              1998-11-07 - NULL OpticalSurfa     44 //              1998-11-07 - NULL OpticalSurface pointer before use
 45 //                           comparison not sh     45 //                           comparison not sharp for: std::abs(cost1) < 1.0
 46 //                           remove sin1, sin2     46 //                           remove sin1, sin2 in lines 556,567
 47 //                           (thanks to Stefan     47 //                           (thanks to Stefano Magni)
 48 //              1999-10-10 - Accommodate chang     48 //              1999-10-10 - Accommodate changes done in DoAbsorption by
 49 //                           changing logic in     49 //                           changing logic in DielectricMetal
 50 //              2001-10-18 - avoid Linux (gcc-     50 //              2001-10-18 - avoid Linux (gcc-2.95.2) warning about variables
 51 //                           might be used uni     51 //                           might be used uninitialized in this function
 52 //                           moved E2_perp, E2     52 //                           moved E2_perp, E2_parl and E2_total out of 'if'
 53 //              2003-11-27 - Modified line 168     53 //              2003-11-27 - Modified line 168-9 to reflect changes made to
 54 //                           G4OpticalSurface      54 //                           G4OpticalSurface class ( by Fan Lei)
 55 //              2004-02-02 - Set theStatus = U     55 //              2004-02-02 - Set theStatus = Undefined at start of DoIt
 56 //              2005-07-28 - add G4ProcessType     56 //              2005-07-28 - add G4ProcessType to constructor
 57 //              2006-11-04 - add capability of     57 //              2006-11-04 - add capability of calculating the reflectivity
 58 //                           off a metal surfa <<  58 //                           off a metal surface by way of a complex index 
 59 //                           of refraction - T <<  59 //                           of refraction - Thanks to Sehwook Lee and John 
 60 //                           Hauptman (Dept. o     60 //                           Hauptman (Dept. of Physics - Iowa State Univ.)
 61 //              2009-11-10 - add capability of     61 //              2009-11-10 - add capability of simulating surface reflections
 62 //                           with Look-Up-Tabl     62 //                           with Look-Up-Tables (LUT) containing measured
 63 //                           optical reflectan     63 //                           optical reflectance for a variety of surface
 64 //                           treatments - Than     64 //                           treatments - Thanks to Martin Janecek and
 65 //                           William Moses (La     65 //                           William Moses (Lawrence Berkeley National Lab.)
 66 //              2013-06-01 - add the capabilit     66 //              2013-06-01 - add the capability of simulating the transmission
 67 //                           of a dichronic fi     67 //                           of a dichronic filter
 68 //              2017-02-24 - add capability of     68 //              2017-02-24 - add capability of simulating surface reflections
 69 //                           with Look-Up-Tabl     69 //                           with Look-Up-Tables (LUT) developed in DAVIS
 70 //                                                 70 //
 71 // Author:      Peter Gumplinger                   71 // Author:      Peter Gumplinger
 72 //    adopted from work by Werner Keil - April     72 //    adopted from work by Werner Keil - April 2/96
                                                   >>  73 // mail:        gum@triumf.ca
 73 //                                                 74 //
 74 //////////////////////////////////////////////     75 ////////////////////////////////////////////////////////////////////////
 75                                                    76 
 76 #include "G4OpBoundaryProcess.hh"              << 
 77                                                << 
 78 #include "G4ios.hh"                                77 #include "G4ios.hh"
 79 #include "G4GeometryTolerance.hh"              <<  78 #include "G4PhysicalConstants.hh"
 80 #include "G4LogicalBorderSurface.hh"           << 
 81 #include "G4LogicalSkinSurface.hh"             << 
 82 #include "G4OpProcessSubType.hh"                   79 #include "G4OpProcessSubType.hh"
 83 #include "G4OpticalParameters.hh"              <<  80 
                                                   >>  81 #include "G4OpBoundaryProcess.hh"
                                                   >>  82 #include "G4GeometryTolerance.hh"
                                                   >>  83 
                                                   >>  84 #include "G4VSensitiveDetector.hh"
 84 #include "G4ParallelWorldProcess.hh"               85 #include "G4ParallelWorldProcess.hh"
 85 #include "G4PhysicalConstants.hh"              <<  86 
 86 #include "G4SystemOfUnits.hh"                      87 #include "G4SystemOfUnits.hh"
 87 #include "G4TransportationManager.hh"          << 
 88 #include "G4VSensitiveDetector.hh"             << 
 89                                                    88 
 90 //....oooOO0OOooo........oooOO0OOooo........oo <<  89 /////////////////////////
                                                   >>  90 // Class Implementation
                                                   >>  91 /////////////////////////
                                                   >>  92 
                                                   >>  93         //////////////
                                                   >>  94         // Operators
                                                   >>  95         //////////////
                                                   >>  96 
                                                   >>  97 // G4OpBoundaryProcess::operator=(const G4OpBoundaryProcess &right)
                                                   >>  98 // {
                                                   >>  99 // }
                                                   >> 100 
                                                   >> 101         /////////////////
                                                   >> 102         // Constructors
                                                   >> 103         /////////////////
                                                   >> 104 
 91 G4OpBoundaryProcess::G4OpBoundaryProcess(const    105 G4OpBoundaryProcess::G4OpBoundaryProcess(const G4String& processName,
 92                                          G4Pro << 106                                                G4ProcessType type)
 93   : G4VDiscreteProcess(processName, ptype)     << 107              : G4VDiscreteProcess(processName, type)
 94 {                                                 108 {
 95   Initialise();                                << 109         if ( verboseLevel > 0) {
                                                   >> 110            G4cout << GetProcessName() << " is created " << G4endl;
                                                   >> 111         }
 96                                                   112 
 97   if(verboseLevel > 0)                         << 113         SetProcessSubType(fOpBoundary);
 98   {                                            << 
 99     G4cout << GetProcessName() << " is created << 
100   }                                            << 
101   SetProcessSubType(fOpBoundary);              << 
102                                                   114 
103   fStatus           = Undefined;               << 115         theStatus = Undefined;
104   fModel            = glisur;                  << 116         theModel = glisur;
105   fFinish           = polished;                << 117         theFinish = polished;
106   fReflectivity     = 1.;                      << 118         theReflectivity =  1.;
107   fEfficiency       = 0.;                      << 119         theEfficiency   =  0.;
108   fTransmittance    = 0.;                      << 120         theTransmittance = 0.;
109   fSurfaceRoughness = 0.;                      << 
110   fProb_sl          = 0.;                      << 
111   fProb_ss          = 0.;                      << 
112   fProb_bs          = 0.;                      << 
113                                                << 
114   fRealRIndexMPV  = nullptr;                   << 
115   fImagRIndexMPV  = nullptr;                   << 
116   fMaterial1      = nullptr;                   << 
117   fMaterial2      = nullptr;                   << 
118   fOpticalSurface = nullptr;                   << 
119   fCarTolerance   = G4GeometryTolerance::GetIn << 
120                                                << 
121   f_iTE = f_iTM   = 0;                         << 
122   fPhotonMomentum = 0.;                        << 
123   fRindex1 = fRindex2 = 1.;                    << 
124   fSint1              = 0.;                    << 
125   fDichroicVector     = nullptr;               << 
126 }                                              << 
127                                                   121 
128 //....oooOO0OOooo........oooOO0OOooo........oo << 122         theSurfaceRoughness = 0.;
129 G4OpBoundaryProcess::~G4OpBoundaryProcess() =  << 
130                                                   123 
131 //....oooOO0OOooo........oooOO0OOooo........oo << 124         prob_sl = 0.;
132 void G4OpBoundaryProcess::PreparePhysicsTable( << 125         prob_ss = 0.;
133 {                                              << 126         prob_bs = 0.;
134   Initialise();                                << 
135 }                                              << 
136                                                   127 
137 //....oooOO0OOooo........oooOO0OOooo........oo << 128         PropertyPointer  = NULL;
138 void G4OpBoundaryProcess::Initialise()         << 129         PropertyPointer1 = NULL;
139 {                                              << 130         PropertyPointer2 = NULL;
140   G4OpticalParameters* params = G4OpticalParam << 131 
141   SetInvokeSD(params->GetBoundaryInvokeSD());  << 132         Material1 = NULL;
142   SetVerboseLevel(params->GetBoundaryVerboseLe << 133         Material2 = NULL;
                                                   >> 134 
                                                   >> 135         OpticalSurface = NULL;
                                                   >> 136 
                                                   >> 137         kCarTolerance = G4GeometryTolerance::GetInstance()
                                                   >> 138                         ->GetSurfaceTolerance();
                                                   >> 139 
                                                   >> 140         iTE = iTM = 0;
                                                   >> 141         thePhotonMomentum = 0.;
                                                   >> 142         Rindex1 = Rindex2 = 1.;
                                                   >> 143         cost1 = cost2 = sint1 = sint2 = 0.;
                                                   >> 144 
                                                   >> 145         idx = idy = 0;
                                                   >> 146         DichroicVector = NULL;
                                                   >> 147 
                                                   >> 148         fInvokeSD = true;
143 }                                                 149 }
144                                                   150 
145 //....oooOO0OOooo........oooOO0OOooo........oo << 151 // G4OpBoundaryProcess::G4OpBoundaryProcess(const G4OpBoundaryProcess &right)
146 G4VParticleChange* G4OpBoundaryProcess::PostSt << 152 // {
147                                                << 153 // }
148 {                                              << 154 
149   fStatus = Undefined;                         << 155         ////////////////
150   aParticleChange.Initialize(aTrack);          << 156         // Destructors
151   aParticleChange.ProposeVelocity(aTrack.GetVe << 157         ////////////////
152                                                << 158 
153   // Get hyperStep from  G4ParallelWorldProces << 159 G4OpBoundaryProcess::~G4OpBoundaryProcess(){}
154   //  NOTE: PostSetpDoIt of this process to be << 160 
155   //  G4ParallelWorldProcess!                  << 161         ////////////
156   const G4Step* pStep = &aStep;                << 162         // Methods
157   const G4Step* hStep = G4ParallelWorldProcess << 163         ////////////
158   if(hStep != nullptr)                         << 
159     pStep = hStep;                             << 
160                                                << 
161   if(pStep->GetPostStepPoint()->GetStepStatus( << 
162   {                                            << 
163     fMaterial1 = pStep->GetPreStepPoint()->Get << 
164     fMaterial2 = pStep->GetPostStepPoint()->Ge << 
165   }                                            << 
166   else                                         << 
167   {                                            << 
168     fStatus = NotAtBoundary;                   << 
169     if(verboseLevel > 1)                       << 
170       BoundaryProcessVerbose();                << 
171     return G4VDiscreteProcess::PostStepDoIt(aT << 
172   }                                            << 
173                                                   164 
174   G4VPhysicalVolume* thePrePV  = pStep->GetPre << 165 // PostStepDoIt
175   G4VPhysicalVolume* thePostPV = pStep->GetPos << 166 // ------------
                                                   >> 167 //
176                                                   168 
177   if(verboseLevel > 1)                         << 169 G4VParticleChange*
178   {                                            << 170 G4OpBoundaryProcess::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep)
179     G4cout << " Photon at Boundary! " << G4end << 171 {
180     if(thePrePV != nullptr)                    << 172         theStatus = Undefined;
181       G4cout << " thePrePV:  " << thePrePV->Ge << 
182     if(thePostPV != nullptr)                   << 
183       G4cout << " thePostPV: " << thePostPV->G << 
184   }                                            << 
185                                                   173 
186   G4double stepLength = aTrack.GetStepLength() << 174         aParticleChange.Initialize(aTrack);
187   if(stepLength <= fCarTolerance)              << 175         aParticleChange.ProposeVelocity(aTrack.GetVelocity());
188   {                                            << 
189     fStatus = StepTooSmall;                    << 
190     if(verboseLevel > 1)                       << 
191       BoundaryProcessVerbose();                << 
192                                                << 
193     G4MaterialPropertyVector* groupvel = nullp << 
194     G4MaterialPropertiesTable* aMPT = fMateria << 
195     if(aMPT != nullptr)                        << 
196     {                                          << 
197       groupvel = aMPT->GetProperty(kGROUPVEL); << 
198     }                                          << 
199                                                << 
200     if(groupvel != nullptr)                    << 
201     {                                          << 
202       aParticleChange.ProposeVelocity(         << 
203         groupvel->Value(fPhotonMomentum, idx_g << 
204     }                                          << 
205     return G4VDiscreteProcess::PostStepDoIt(aT << 
206   }                                            << 
207   else if (stepLength <= 10.*fCarTolerance &&  << 
208   {  // see bug 2510                           << 
209     ++fNumSmallStepWarnings;                   << 
210     if(verboseLevel > 0)                       << 
211     {                                          << 
212       G4ExceptionDescription ed;               << 
213       ed << "G4OpBoundaryProcess: "            << 
214          << "Opticalphoton step length: " << s << 
215          << "This is larger than the threshold << 
216             "to set status StepTooSmall." << G << 
217          << "Boundary scattering may be incorr << 
218       if(fNumSmallStepWarnings == 10)          << 
219       {                                        << 
220         ed << G4endl << "*** Step size warning << 
221       }                                        << 
222       G4Exception("G4OpBoundaryProcess", "OpBo << 
223     }                                          << 
224   }                                            << 
225                                                   176 
226   const G4DynamicParticle* aParticle = aTrack. << 177         // Get hyperStep from  G4ParallelWorldProcess
                                                   >> 178         //  NOTE: PostSetpDoIt of this process should be
                                                   >> 179         //        invoked after G4ParallelWorldProcess!
227                                                   180 
228   fPhotonMomentum  = aParticle->GetTotalMoment << 181         const G4Step* pStep = &aStep;
229   fOldMomentum     = aParticle->GetMomentumDir << 
230   fOldPolarization = aParticle->GetPolarizatio << 
231                                                << 
232   if(verboseLevel > 1)                         << 
233   {                                            << 
234     G4cout << " Old Momentum Direction: " << f << 
235            << " Old Polarization:       " << f << 
236   }                                            << 
237                                                   182 
238   G4ThreeVector theGlobalPoint = pStep->GetPos << 183         const G4Step* hStep = G4ParallelWorldProcess::GetHyperStep();
239   G4bool valid;                                << 184         
                                                   >> 185         if (hStep) pStep = hStep;
240                                                   186 
241   // ID of Navigator which limits step         << 187         G4bool isOnBoundary =
242   G4int hNavId = G4ParallelWorldProcess::GetHy << 188                 (pStep->GetPostStepPoint()->GetStepStatus() == fGeomBoundary);
243   auto iNav    = G4TransportationManager::GetT << 
244                 ->GetActiveNavigatorsIterator( << 
245   fGlobalNormal = (iNav[hNavId])->GetGlobalExi << 
246                                                << 
247   if(valid)                                    << 
248   {                                            << 
249     fGlobalNormal = -fGlobalNormal;            << 
250   }                                            << 
251   else                                         << 
252   {                                            << 
253     G4ExceptionDescription ed;                 << 
254     ed << " G4OpBoundaryProcess/PostStepDoIt() << 
255        << " The Navigator reports that it retu << 
256     G4Exception(                               << 
257       "G4OpBoundaryProcess::PostStepDoIt", "Op << 
258       "Invalid Surface Normal - Geometry must  << 
259   }                                            << 
260                                                   189 
261   if(fOldMomentum * fGlobalNormal > 0.0)       << 190         if (isOnBoundary) {
262   {                                            << 191            Material1 = pStep->GetPreStepPoint()->GetMaterial();
263 #ifdef G4OPTICAL_DEBUG                         << 192            Material2 = pStep->GetPostStepPoint()->GetMaterial();
264     G4ExceptionDescription ed;                 << 193         } else {
265     ed << " G4OpBoundaryProcess/PostStepDoIt() << 194            theStatus = NotAtBoundary;
266           "wrong direction. "                  << 195            if ( verboseLevel > 0) BoundaryProcessVerbose();
267        << G4endl                               << 196            return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
268        << "   The momentum of the photon arriv << 197         }
269        << "   must exit the volume cross in th << 
270        << "   So it MUST have dot < 0 with the << 
271           "volume (globalNormal)."             << 
272        << G4endl << "   >> The dot product of  << 
273        << fOldMomentum * fGlobalNormal << G4en << 
274        << "     Old Momentum  (during step)    << 
275        << "     Global Normal (Exiting New Vol << 
276        << G4endl;                              << 
277     G4Exception("G4OpBoundaryProcess::PostStep << 
278                 EventMustBeAborted,  // Or Jus << 
279                                      // repeat << 
280                 ed,                            << 
281                 "Invalid Surface Normal - Geom << 
282                 "normal pointing in the right  << 
283 #else                                          << 
284     fGlobalNormal = -fGlobalNormal;            << 
285 #endif                                         << 
286   }                                            << 
287                                                   198 
288   G4MaterialPropertyVector* rIndexMPV = nullpt << 199         G4VPhysicalVolume* thePrePV  =
289   G4MaterialPropertiesTable* MPT = fMaterial1- << 200                                pStep->GetPreStepPoint() ->GetPhysicalVolume();
290   if(MPT != nullptr)                           << 201         G4VPhysicalVolume* thePostPV =
291   {                                            << 202                                pStep->GetPostStepPoint()->GetPhysicalVolume();
292     rIndexMPV = MPT->GetProperty(kRINDEX);     << 
293   }                                            << 
294   if(rIndexMPV != nullptr)                     << 
295   {                                            << 
296     fRindex1 = rIndexMPV->Value(fPhotonMomentu << 
297   }                                            << 
298   else                                         << 
299   {                                            << 
300     fStatus = NoRINDEX;                        << 
301     if(verboseLevel > 1)                       << 
302       BoundaryProcessVerbose();                << 
303     aParticleChange.ProposeLocalEnergyDeposit( << 
304     aParticleChange.ProposeTrackStatus(fStopAn << 
305     return G4VDiscreteProcess::PostStepDoIt(aT << 
306   }                                            << 
307                                                   203 
308   fReflectivity      = 1.;                     << 204         if ( verboseLevel > 0 ) {
309   fEfficiency        = 0.;                     << 205            G4cout << " Photon at Boundary! " << G4endl;
310   fTransmittance     = 0.;                     << 206            if (thePrePV)  G4cout << " thePrePV:  " << thePrePV->GetName()  << G4endl;
311   fSurfaceRoughness  = 0.;                     << 207            if (thePostPV) G4cout << " thePostPV: " << thePostPV->GetName() << G4endl;
312   fModel             = glisur;                 << 208         }
313   fFinish            = polished;               << 
314   G4SurfaceType type = dielectric_dielectric;  << 
315                                                << 
316   rIndexMPV       = nullptr;                   << 
317   fOpticalSurface = nullptr;                   << 
318                                                << 
319   G4LogicalSurface* surface =                  << 
320     G4LogicalBorderSurface::GetSurface(thePreP << 
321   if(surface == nullptr)                       << 
322   {                                            << 
323     if(thePostPV->GetMotherLogical() == thePre << 
324     {                                          << 
325       surface = G4LogicalSkinSurface::GetSurfa << 
326       if(surface == nullptr)                   << 
327       {                                        << 
328         surface =                              << 
329           G4LogicalSkinSurface::GetSurface(the << 
330       }                                        << 
331     }                                          << 
332     else                                       << 
333     {                                          << 
334       surface = G4LogicalSkinSurface::GetSurfa << 
335       if(surface == nullptr)                   << 
336       {                                        << 
337         surface =                              << 
338           G4LogicalSkinSurface::GetSurface(the << 
339       }                                        << 
340     }                                          << 
341   }                                            << 
342                                                   209 
343   if(surface != nullptr)                       << 210         if (aTrack.GetStepLength()<=kCarTolerance/2){
344   {                                            << 211                 theStatus = StepTooSmall;
345     fOpticalSurface =                          << 212                 if ( verboseLevel > 0) BoundaryProcessVerbose();
346       dynamic_cast<G4OpticalSurface*>(surface- << 213                 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
347   }                                            << 
348   if(fOpticalSurface != nullptr)               << 
349   {                                            << 
350     type    = fOpticalSurface->GetType();      << 
351     fModel  = fOpticalSurface->GetModel();     << 
352     fFinish = fOpticalSurface->GetFinish();    << 
353                                                << 
354     G4MaterialPropertiesTable* sMPT =          << 
355       fOpticalSurface->GetMaterialPropertiesTa << 
356     if(sMPT != nullptr)                        << 
357     {                                          << 
358       if(fFinish == polishedbackpainted || fFi << 
359       {                                        << 
360         rIndexMPV = sMPT->GetProperty(kRINDEX) << 
361         if(rIndexMPV != nullptr)               << 
362         {                                      << 
363           fRindex2 = rIndexMPV->Value(fPhotonM << 
364         }                                         214         }
365         else                                   << 215 
366         {                                      << 216         const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
367           fStatus = NoRINDEX;                  << 217 
368           if(verboseLevel > 1)                 << 218         thePhotonMomentum = aParticle->GetTotalMomentum();
369             BoundaryProcessVerbose();          << 219         OldMomentum       = aParticle->GetMomentumDirection();
370           aParticleChange.ProposeLocalEnergyDe << 220         OldPolarization   = aParticle->GetPolarization();
371           aParticleChange.ProposeTrackStatus(f << 221 
372           return G4VDiscreteProcess::PostStepD << 222         if ( verboseLevel > 0 ) {
                                                   >> 223            G4cout << " Old Momentum Direction: " << OldMomentum     << G4endl;
                                                   >> 224            G4cout << " Old Polarization:       " << OldPolarization << G4endl;
373         }                                         225         }
374       }                                        << 
375                                                   226 
376       fRealRIndexMPV = sMPT->GetProperty(kREAL << 227         G4ThreeVector theGlobalPoint = pStep->GetPostStepPoint()->GetPosition();
377       fImagRIndexMPV = sMPT->GetProperty(kIMAG << 228 
378       f_iTE = f_iTM = 1;                       << 229         G4bool valid;
379                                                << 230         //  Use the new method for Exit Normal in global coordinates,
380       G4MaterialPropertyVector* pp;            << 231         //    which provides the normal more reliably.
381       if((pp = sMPT->GetProperty(kREFLECTIVITY << 232 
382       {                                        << 233         // ID of Navigator which limits step
383         fReflectivity = pp->Value(fPhotonMomen << 234 
384       }                                        << 235         G4int hNavId = G4ParallelWorldProcess::GetHypNavigatorID();
385       else if(fRealRIndexMPV && fImagRIndexMPV << 236         std::vector<G4Navigator*>::iterator iNav =
386       {                                        << 237                 G4TransportationManager::GetTransportationManager()->
387         CalculateReflectivity();               << 238                                          GetActiveNavigatorsIterator();
388       }                                        << 239         theGlobalNormal =
389                                                << 240                    (iNav[hNavId])->GetGlobalExitNormal(theGlobalPoint,&valid);
390       if((pp = sMPT->GetProperty(kEFFICIENCY)) << 241 
391       {                                        << 242         if (valid) {
392         fEfficiency = pp->Value(fPhotonMomentu << 243           theGlobalNormal = -theGlobalNormal;
393       }                                        << 
394       if((pp = sMPT->GetProperty(kTRANSMITTANC << 
395       {                                        << 
396         fTransmittance = pp->Value(fPhotonMome << 
397       }                                        << 
398       if(sMPT->ConstPropertyExists(kSURFACEROU << 
399       {                                        << 
400         fSurfaceRoughness = sMPT->GetConstProp << 
401       }                                        << 
402                                                << 
403       if(fModel == unified)                    << 
404       {                                        << 
405         fProb_sl = (pp = sMPT->GetProperty(kSP << 
406                      ? pp->Value(fPhotonMoment << 
407                      : 0.;                     << 
408         fProb_ss = (pp = sMPT->GetProperty(kSP << 
409                      ? pp->Value(fPhotonMoment << 
410                      : 0.;                     << 
411         fProb_bs = (pp = sMPT->GetProperty(kBA << 
412                      ? pp->Value(fPhotonMoment << 
413                      : 0.;                     << 
414       }                                        << 
415     }  // end of if(sMPT)                      << 
416     else if(fFinish == polishedbackpainted ||  << 
417     {                                          << 
418       aParticleChange.ProposeLocalEnergyDeposi << 
419       aParticleChange.ProposeTrackStatus(fStop << 
420       return G4VDiscreteProcess::PostStepDoIt( << 
421     }                                          << 
422   }  // end of if(fOpticalSurface)             << 
423                                                << 
424   //  DIELECTRIC-DIELECTRIC                    << 
425   if(type == dielectric_dielectric)            << 
426   {                                            << 
427     if(fFinish == polished || fFinish == groun << 
428     {                                          << 
429       if(fMaterial1 == fMaterial2)             << 
430       {                                        << 
431         fStatus = SameMaterial;                << 
432         if(verboseLevel > 1)                   << 
433           BoundaryProcessVerbose();            << 
434         return G4VDiscreteProcess::PostStepDoI << 
435       }                                        << 
436       MPT       = fMaterial2->GetMaterialPrope << 
437       rIndexMPV = nullptr;                     << 
438       if(MPT != nullptr)                       << 
439       {                                        << 
440         rIndexMPV = MPT->GetProperty(kRINDEX); << 
441       }                                        << 
442       if(rIndexMPV != nullptr)                 << 
443       {                                        << 
444         fRindex2 = rIndexMPV->Value(fPhotonMom << 
445       }                                        << 
446       else                                     << 
447       {                                        << 
448         fStatus = NoRINDEX;                    << 
449         if(verboseLevel > 1)                   << 
450           BoundaryProcessVerbose();            << 
451         aParticleChange.ProposeLocalEnergyDepo << 
452         aParticleChange.ProposeTrackStatus(fSt << 
453         return G4VDiscreteProcess::PostStepDoI << 
454       }                                        << 
455     }                                          << 
456     if(fFinish == polishedbackpainted || fFini << 
457     {                                          << 
458       DielectricDielectric();                  << 
459     }                                          << 
460     else                                       << 
461     {                                          << 
462       G4double rand = G4UniformRand();         << 
463       if(rand > fReflectivity + fTransmittance << 
464       {                                        << 
465         DoAbsorption();                        << 
466       }                                        << 
467       else if(rand > fReflectivity)            << 
468       {                                        << 
469         fStatus          = Transmission;       << 
470         fNewMomentum     = fOldMomentum;       << 
471         fNewPolarization = fOldPolarization;   << 
472       }                                        << 
473       else                                     << 
474       {                                        << 
475         if(fFinish == polishedfrontpainted)    << 
476         {                                      << 
477           DoReflection();                      << 
478         }                                         244         }
479         else if(fFinish == groundfrontpainted) << 245         else 
480         {                                         246         {
481           fStatus = LambertianReflection;      << 247           G4ExceptionDescription ed;
482           DoReflection();                      << 248           ed << " G4OpBoundaryProcess/PostStepDoIt(): "
                                                   >> 249                  << " The Navigator reports that it returned an invalid normal"
                                                   >> 250                  << G4endl;
                                                   >> 251           G4Exception("G4OpBoundaryProcess::PostStepDoIt", "OpBoun01",
                                                   >> 252                       EventMustBeAborted,ed,
                                                   >> 253                       "Invalid Surface Normal - Geometry must return valid surface normal");
483         }                                         254         }
484         else                                   << 255 
485         {                                      << 256         if (OldMomentum * theGlobalNormal > 0.0) {
486           DielectricDielectric();              << 257 #ifdef G4OPTICAL_DEBUG
                                                   >> 258            G4ExceptionDescription ed;
                                                   >> 259            ed << " G4OpBoundaryProcess/PostStepDoIt(): "
                                                   >> 260               << " theGlobalNormal points in a wrong direction. "
                                                   >> 261               << G4endl;
                                                   >> 262            ed << "    The momentum of the photon arriving at interface (oldMomentum)"
                                                   >> 263               << " must exit the volume cross in the step. " << G4endl;
                                                   >> 264            ed << "  So it MUST have dot < 0 with the normal that Exits the new volume (globalNormal)." << G4endl;
                                                   >> 265            ed << "  >> The dot product of oldMomentum and global Normal is " << OldMomentum*theGlobalNormal << G4endl;
                                                   >> 266            ed << "     Old Momentum  (during step)     = " << OldMomentum << G4endl;
                                                   >> 267            ed << "     Global Normal (Exiting New Vol) = " << theGlobalNormal << G4endl;
                                                   >> 268            ed << G4endl;
                                                   >> 269            G4Exception("G4OpBoundaryProcess::PostStepDoIt", "OpBoun02",
                                                   >> 270                        EventMustBeAborted,  // Or JustWarning to see if it happens repeatedbly on one ray
                                                   >> 271                        ed,
                                                   >> 272                       "Invalid Surface Normal - Geometry must return valid surface normal pointing in the right direction");
                                                   >> 273 #else
                                                   >> 274            theGlobalNormal = -theGlobalNormal;
                                                   >> 275 #endif
487         }                                         276         }
488       }                                        << 277 
489     }                                          << 278   G4MaterialPropertiesTable* aMaterialPropertiesTable;
490   }                                            << 279         G4MaterialPropertyVector* Rindex;
491   else if(type == dielectric_metal)            << 280 
492   {                                            << 281   aMaterialPropertiesTable = Material1->GetMaterialPropertiesTable();
493     DielectricMetal();                         << 282         if (aMaterialPropertiesTable) {
494   }                                            << 283     Rindex = aMaterialPropertiesTable->GetProperty(kRINDEX);
495   else if(type == dielectric_LUT)              << 284   }
496   {                                            << 285   else {
497     DielectricLUT();                           << 286                 theStatus = NoRINDEX;
498   }                                            << 287                 if ( verboseLevel > 0) BoundaryProcessVerbose();
499   else if(type == dielectric_LUTDAVIS)         << 288                 aParticleChange.ProposeLocalEnergyDeposit(thePhotonMomentum);
500   {                                            << 289                 aParticleChange.ProposeTrackStatus(fStopAndKill);
501     DielectricLUTDAVIS();                      << 290                 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
502   }                                            << 291   }
503   else if(type == dielectric_dichroic)         << 292 
504   {                                            << 293         if (Rindex) {
505     DielectricDichroic();                      << 294            Rindex1 = Rindex->Value(thePhotonMomentum);
506   }                                            << 295         }
507   else if(type == coated)                      << 296         else {
508   {                                            << 297           theStatus = NoRINDEX;
509     CoatedDielectricDielectric();              << 298                 if ( verboseLevel > 0) BoundaryProcessVerbose();
510   }                                            << 299                 aParticleChange.ProposeLocalEnergyDeposit(thePhotonMomentum);
511   else                                         << 300                 aParticleChange.ProposeTrackStatus(fStopAndKill);
512   {                                            << 301                 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
513     if(fNumBdryTypeWarnings <= 10)             << 302   }
514     {                                          << 303 
515       ++fNumBdryTypeWarnings;                  << 304         theReflectivity =  1.;
516       if(verboseLevel > 0)                     << 305         theEfficiency   =  0.;
517       {                                        << 306         theTransmittance = 0.;
518         G4ExceptionDescription ed;             << 307 
519         ed << " PostStepDoIt(): Illegal bounda << 308         theSurfaceRoughness = 0.;
520         if(fNumBdryTypeWarnings == 10)         << 309 
521         {                                      << 310         theModel = glisur;
522           ed << "** Boundary type warnings sto << 311         theFinish = polished;
                                                   >> 312 
                                                   >> 313         G4SurfaceType type = dielectric_dielectric;
                                                   >> 314 
                                                   >> 315         Rindex = NULL;
                                                   >> 316         OpticalSurface = NULL;
                                                   >> 317 
                                                   >> 318         G4LogicalSurface* Surface = NULL;
                                                   >> 319 
                                                   >> 320         Surface = G4LogicalBorderSurface::GetSurface(thePrePV, thePostPV);
                                                   >> 321 
                                                   >> 322         if (Surface == NULL){
                                                   >> 323           G4bool enteredDaughter= (thePostPV->GetMotherLogical() ==
                                                   >> 324                                    thePrePV ->GetLogicalVolume());
                                                   >> 325     if(enteredDaughter){
                                                   >> 326       Surface = 
                                                   >> 327               G4LogicalSkinSurface::GetSurface(thePostPV->GetLogicalVolume());
                                                   >> 328       if(Surface == NULL)
                                                   >> 329         Surface =
                                                   >> 330                 G4LogicalSkinSurface::GetSurface(thePrePV->GetLogicalVolume());
                                                   >> 331     }
                                                   >> 332     else {
                                                   >> 333       Surface =
                                                   >> 334               G4LogicalSkinSurface::GetSurface(thePrePV->GetLogicalVolume());
                                                   >> 335       if(Surface == NULL)
                                                   >> 336         Surface =
                                                   >> 337                 G4LogicalSkinSurface::GetSurface(thePostPV->GetLogicalVolume());
                                                   >> 338     }
                                                   >> 339   }
                                                   >> 340 
                                                   >> 341         if (Surface) OpticalSurface = 
                                                   >> 342            dynamic_cast <G4OpticalSurface*> (Surface->GetSurfaceProperty());
                                                   >> 343 
                                                   >> 344         if (OpticalSurface) {
                                                   >> 345 
                                                   >> 346            type      = OpticalSurface->GetType();
                                                   >> 347            theModel  = OpticalSurface->GetModel();
                                                   >> 348            theFinish = OpticalSurface->GetFinish();
                                                   >> 349 
                                                   >> 350            aMaterialPropertiesTable = OpticalSurface->
                                                   >> 351                                         GetMaterialPropertiesTable();
                                                   >> 352 
                                                   >> 353            if (aMaterialPropertiesTable) {
                                                   >> 354 
                                                   >> 355               if (theFinish == polishedbackpainted ||
                                                   >> 356                   theFinish == groundbackpainted ) {
                                                   >> 357                   Rindex = aMaterialPropertiesTable->GetProperty(kRINDEX);
                                                   >> 358             if (Rindex) {
                                                   >> 359                      Rindex2 = Rindex->Value(thePhotonMomentum);
                                                   >> 360                   }
                                                   >> 361                   else {
                                                   >> 362                      theStatus = NoRINDEX;
                                                   >> 363                      if ( verboseLevel > 0) BoundaryProcessVerbose();
                                                   >> 364                      aParticleChange.ProposeLocalEnergyDeposit(thePhotonMomentum);
                                                   >> 365                      aParticleChange.ProposeTrackStatus(fStopAndKill);
                                                   >> 366                      return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
                                                   >> 367                   }
                                                   >> 368               }
                                                   >> 369 
                                                   >> 370               PropertyPointer =
                                                   >> 371                       aMaterialPropertiesTable->GetProperty(kREFLECTIVITY);
                                                   >> 372               PropertyPointer1 =
                                                   >> 373                       aMaterialPropertiesTable->GetProperty(kREALRINDEX);
                                                   >> 374               PropertyPointer2 =
                                                   >> 375                       aMaterialPropertiesTable->GetProperty(kIMAGINARYRINDEX);
                                                   >> 376 
                                                   >> 377               iTE = 1;
                                                   >> 378               iTM = 1;
                                                   >> 379 
                                                   >> 380               if (PropertyPointer) {
                                                   >> 381 
                                                   >> 382                  theReflectivity =
                                                   >> 383                           PropertyPointer->Value(thePhotonMomentum);
                                                   >> 384 
                                                   >> 385               } else if (PropertyPointer1 && PropertyPointer2) {
                                                   >> 386 
                                                   >> 387                  CalculateReflectivity();
                                                   >> 388 
                                                   >> 389               }
                                                   >> 390 
                                                   >> 391               PropertyPointer =
                                                   >> 392               aMaterialPropertiesTable->GetProperty(kEFFICIENCY);
                                                   >> 393               if (PropertyPointer) {
                                                   >> 394                       theEfficiency =
                                                   >> 395                       PropertyPointer->Value(thePhotonMomentum);
                                                   >> 396               }
                                                   >> 397 
                                                   >> 398               PropertyPointer =
                                                   >> 399               aMaterialPropertiesTable->GetProperty(kTRANSMITTANCE);
                                                   >> 400               if (PropertyPointer) {
                                                   >> 401                       theTransmittance =
                                                   >> 402                       PropertyPointer->Value(thePhotonMomentum);
                                                   >> 403               }
                                                   >> 404 
                                                   >> 405               if (aMaterialPropertiesTable->
                                                   >> 406                                      ConstPropertyExists("SURFACEROUGHNESS"))
                                                   >> 407                  theSurfaceRoughness = aMaterialPropertiesTable->
                                                   >> 408                                          GetConstProperty(kSURFACEROUGHNESS);
                                                   >> 409 
                                                   >> 410         if ( theModel == unified ) {
                                                   >> 411                  PropertyPointer =
                                                   >> 412                  aMaterialPropertiesTable->GetProperty(kSPECULARLOBECONSTANT);
                                                   >> 413                  if (PropertyPointer) {
                                                   >> 414                          prob_sl =
                                                   >> 415                          PropertyPointer->Value(thePhotonMomentum);
                                                   >> 416                  } else {
                                                   >> 417                          prob_sl = 0.0;
                                                   >> 418                  }
                                                   >> 419 
                                                   >> 420                  PropertyPointer =
                                                   >> 421                  aMaterialPropertiesTable->GetProperty(kSPECULARSPIKECONSTANT);
                                                   >> 422            if (PropertyPointer) {
                                                   >> 423                          prob_ss =
                                                   >> 424                          PropertyPointer->Value(thePhotonMomentum);
                                                   >> 425                  } else {
                                                   >> 426                          prob_ss = 0.0;
                                                   >> 427                  }
                                                   >> 428 
                                                   >> 429                  PropertyPointer =
                                                   >> 430                  aMaterialPropertiesTable->GetProperty(kBACKSCATTERCONSTANT);
                                                   >> 431                  if (PropertyPointer) {
                                                   >> 432                          prob_bs =
                                                   >> 433                          PropertyPointer->Value(thePhotonMomentum);
                                                   >> 434                  } else {
                                                   >> 435                          prob_bs = 0.0;
                                                   >> 436                  }
                                                   >> 437               }
                                                   >> 438            }
                                                   >> 439            else if (theFinish == polishedbackpainted ||
                                                   >> 440                     theFinish == groundbackpainted ) {
                                                   >> 441                       aParticleChange.ProposeLocalEnergyDeposit(thePhotonMomentum);
                                                   >> 442                       aParticleChange.ProposeTrackStatus(fStopAndKill);
                                                   >> 443                       return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
                                                   >> 444            }
                                                   >> 445         }
                                                   >> 446 
                                                   >> 447         if (type == dielectric_dielectric ) {
                                                   >> 448            if (theFinish == polished || theFinish == ground ) {
                                                   >> 449 
                                                   >> 450               if (Material1 == Material2){
                                                   >> 451                  theStatus = SameMaterial;
                                                   >> 452                  if ( verboseLevel > 0) BoundaryProcessVerbose();
                                                   >> 453      return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
                                                   >> 454         }
                                                   >> 455               aMaterialPropertiesTable =
                                                   >> 456                      Material2->GetMaterialPropertiesTable();
                                                   >> 457               if (aMaterialPropertiesTable)
                                                   >> 458                  Rindex = aMaterialPropertiesTable->GetProperty(kRINDEX);
                                                   >> 459               if (Rindex) {
                                                   >> 460                  Rindex2 = Rindex->Value(thePhotonMomentum);
                                                   >> 461               }
                                                   >> 462               else {
                                                   >> 463                  theStatus = NoRINDEX;
                                                   >> 464                  if ( verboseLevel > 0) BoundaryProcessVerbose();
                                                   >> 465                  aParticleChange.ProposeLocalEnergyDeposit(thePhotonMomentum);
                                                   >> 466                  aParticleChange.ProposeTrackStatus(fStopAndKill);
                                                   >> 467                  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
                                                   >> 468               }
                                                   >> 469            }
                                                   >> 470         }
                                                   >> 471 
                                                   >> 472   if (type == dielectric_metal) {
                                                   >> 473 
                                                   >> 474           DielectricMetal();
                                                   >> 475 
                                                   >> 476   }
                                                   >> 477         else if (type == dielectric_LUT) {
                                                   >> 478 
                                                   >> 479           DielectricLUT();
                                                   >> 480 
                                                   >> 481         }
                                                   >> 482         else if (type == dielectric_LUTDAVIS) {
                                                   >> 483 
                                                   >> 484           DielectricLUTDAVIS();
                                                   >> 485 
                                                   >> 486         }
                                                   >> 487         else if (type == dielectric_dichroic) {
                                                   >> 488 
                                                   >> 489           DielectricDichroic();
                                                   >> 490 
                                                   >> 491         }
                                                   >> 492         else if (type == dielectric_dielectric) {
                                                   >> 493 
                                                   >> 494           if ( theFinish == polishedbackpainted ||
                                                   >> 495                theFinish == groundbackpainted ) {
                                                   >> 496              DielectricDielectric();
                                                   >> 497           }
                                                   >> 498           else {
                                                   >> 499              G4double rand = G4UniformRand();
                                                   >> 500              if ( rand > theReflectivity ) {
                                                   >> 501                 if (rand > theReflectivity + theTransmittance) {
                                                   >> 502                    DoAbsorption();
                                                   >> 503                 } else {
                                                   >> 504                    theStatus = Transmission;
                                                   >> 505                    NewMomentum = OldMomentum;
                                                   >> 506                    NewPolarization = OldPolarization;
                                                   >> 507                 }
                                                   >> 508              }
                                                   >> 509              else {
                                                   >> 510                 if ( theFinish == polishedfrontpainted ) {
                                                   >> 511                    DoReflection();
                                                   >> 512                 }
                                                   >> 513                 else if ( theFinish == groundfrontpainted ) {
                                                   >> 514                    theStatus = LambertianReflection;
                                                   >> 515                    DoReflection();
                                                   >> 516                 }
                                                   >> 517                 else {
                                                   >> 518                    DielectricDielectric();
                                                   >> 519                 }
                                                   >> 520              }
                                                   >> 521           }
523         }                                         522         }
524         G4Exception("G4OpBoundaryProcess", "Op << 523         else {
525       }                                        << 
526     }                                          << 
527     return G4VDiscreteProcess::PostStepDoIt(aT << 
528   }                                            << 
529                                                   524 
530   fNewMomentum     = fNewMomentum.unit();      << 525           G4cerr << " Error: G4BoundaryProcess: illegal boundary type " << G4endl;
531   fNewPolarization = fNewPolarization.unit();  << 526           return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
532                                                   527 
533   if(verboseLevel > 1)                         << 528         }
534   {                                            << 
535     G4cout << " New Momentum Direction: " << f << 
536            << " New Polarization:       " << f << 
537     BoundaryProcessVerbose();                  << 
538   }                                            << 
539                                                   529 
540   aParticleChange.ProposeMomentumDirection(fNe << 530         NewMomentum = NewMomentum.unit();
541   aParticleChange.ProposePolarization(fNewPola << 531         NewPolarization = NewPolarization.unit();
542                                                   532 
543   if(fStatus == FresnelRefraction || fStatus = << 533         if ( verboseLevel > 0) {
544   {                                            << 534            G4cout << " New Momentum Direction: " << NewMomentum     << G4endl;
545     // not all surface types check that fMater << 535            G4cout << " New Polarization:       " << NewPolarization << G4endl;
546     G4MaterialPropertiesTable* aMPT = fMateria << 536            BoundaryProcessVerbose();
547     G4MaterialPropertyVector* groupvel = nullp << 537         }
548     if(aMPT != nullptr)                        << 
549     {                                          << 
550       groupvel = aMPT->GetProperty(kGROUPVEL); << 
551     }                                          << 
552     if(groupvel != nullptr)                    << 
553     {                                          << 
554       aParticleChange.ProposeVelocity(         << 
555         groupvel->Value(fPhotonMomentum, idx_g << 
556     }                                          << 
557   }                                            << 
558                                                   538 
559   if(fStatus == Detection && fInvokeSD)        << 539         aParticleChange.ProposeMomentumDirection(NewMomentum);
560     InvokeSD(pStep);                           << 540         aParticleChange.ProposePolarization(NewPolarization);
561   return G4VDiscreteProcess::PostStepDoIt(aTra << 541 
                                                   >> 542         if ( theStatus == FresnelRefraction || theStatus == Transmission ) {
                                                   >> 543            G4MaterialPropertyVector* groupvel =
                                                   >> 544            Material2->GetMaterialPropertiesTable()->GetProperty(kGROUPVEL);
                                                   >> 545            G4double finalVelocity = groupvel->Value(thePhotonMomentum);
                                                   >> 546            aParticleChange.ProposeVelocity(finalVelocity);
                                                   >> 547         }
                                                   >> 548 
                                                   >> 549         if ( theStatus == Detection && fInvokeSD ) InvokeSD(pStep);
                                                   >> 550 
                                                   >> 551         return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
562 }                                                 552 }
563                                                   553 
564 //....oooOO0OOooo........oooOO0OOooo........oo << 
565 void G4OpBoundaryProcess::BoundaryProcessVerbo    554 void G4OpBoundaryProcess::BoundaryProcessVerbose() const
566 {                                                 555 {
567   G4cout << " *** ";                           << 556         if ( theStatus == Undefined )
568   if(fStatus == Undefined)                     << 557                 G4cout << " *** Undefined *** " << G4endl;
569     G4cout << "Undefined";                     << 558         if ( theStatus == Transmission )
570   else if(fStatus == Transmission)             << 559                 G4cout << " *** Transmission *** " << G4endl;
571     G4cout << "Transmission";                  << 560         if ( theStatus == FresnelRefraction )
572   else if(fStatus == FresnelRefraction)        << 561                 G4cout << " *** FresnelRefraction *** " << G4endl;
573     G4cout << "FresnelRefraction";             << 562         if ( theStatus == FresnelReflection )
574   else if(fStatus == FresnelReflection)        << 563                 G4cout << " *** FresnelReflection *** " << G4endl;
575     G4cout << "FresnelReflection";             << 564         if ( theStatus == TotalInternalReflection )
576   else if(fStatus == TotalInternalReflection)  << 565                 G4cout << " *** TotalInternalReflection *** " << G4endl;
577     G4cout << "TotalInternalReflection";       << 566         if ( theStatus == LambertianReflection )
578   else if(fStatus == LambertianReflection)     << 567                 G4cout << " *** LambertianReflection *** " << G4endl;
579     G4cout << "LambertianReflection";          << 568         if ( theStatus == LobeReflection )
580   else if(fStatus == LobeReflection)           << 569                 G4cout << " *** LobeReflection *** " << G4endl;
581     G4cout << "LobeReflection";                << 570         if ( theStatus == SpikeReflection )
582   else if(fStatus == SpikeReflection)          << 571                 G4cout << " *** SpikeReflection *** " << G4endl;
583     G4cout << "SpikeReflection";               << 572         if ( theStatus == BackScattering )
584   else if(fStatus == BackScattering)           << 573                 G4cout << " *** BackScattering *** " << G4endl;
585     G4cout << "BackScattering";                << 574         if ( theStatus == PolishedLumirrorAirReflection )
586   else if(fStatus == PolishedLumirrorAirReflec << 575                 G4cout << " *** PolishedLumirrorAirReflection *** " << G4endl;
587     G4cout << "PolishedLumirrorAirReflection"; << 576         if ( theStatus == PolishedLumirrorGlueReflection )
588   else if(fStatus == PolishedLumirrorGlueRefle << 577                 G4cout << " *** PolishedLumirrorGlueReflection *** " << G4endl;
589     G4cout << "PolishedLumirrorGlueReflection" << 578         if ( theStatus == PolishedAirReflection )
590   else if(fStatus == PolishedAirReflection)    << 579                 G4cout << " *** PolishedAirReflection *** " << G4endl;
591     G4cout << "PolishedAirReflection";         << 580         if ( theStatus == PolishedTeflonAirReflection )
592   else if(fStatus == PolishedTeflonAirReflecti << 581                 G4cout << " *** PolishedTeflonAirReflection *** " << G4endl;
593     G4cout << "PolishedTeflonAirReflection";   << 582         if ( theStatus == PolishedTiOAirReflection )
594   else if(fStatus == PolishedTiOAirReflection) << 583                 G4cout << " *** PolishedTiOAirReflection *** " << G4endl;
595     G4cout << "PolishedTiOAirReflection";      << 584         if ( theStatus == PolishedTyvekAirReflection )
596   else if(fStatus == PolishedTyvekAirReflectio << 585                 G4cout << " *** PolishedTyvekAirReflection *** " << G4endl;
597     G4cout << "PolishedTyvekAirReflection";    << 586         if ( theStatus == PolishedVM2000AirReflection )
598   else if(fStatus == PolishedVM2000AirReflecti << 587                 G4cout << " *** PolishedVM2000AirReflection *** " << G4endl;
599     G4cout << "PolishedVM2000AirReflection";   << 588         if ( theStatus == PolishedVM2000GlueReflection )
600   else if(fStatus == PolishedVM2000GlueReflect << 589                 G4cout << " *** PolishedVM2000GlueReflection *** " << G4endl;
601     G4cout << "PolishedVM2000GlueReflection";  << 590         if ( theStatus == EtchedLumirrorAirReflection )
602   else if(fStatus == EtchedLumirrorAirReflecti << 591                 G4cout << " *** EtchedLumirrorAirReflection *** " << G4endl;
603     G4cout << "EtchedLumirrorAirReflection";   << 592         if ( theStatus == EtchedLumirrorGlueReflection )
604   else if(fStatus == EtchedLumirrorGlueReflect << 593                 G4cout << " *** EtchedLumirrorGlueReflection *** " << G4endl;
605     G4cout << "EtchedLumirrorGlueReflection";  << 594         if ( theStatus == EtchedAirReflection )
606   else if(fStatus == EtchedAirReflection)      << 595                 G4cout << " *** EtchedAirReflection *** " << G4endl;
607     G4cout << "EtchedAirReflection";           << 596         if ( theStatus == EtchedTeflonAirReflection )
608   else if(fStatus == EtchedTeflonAirReflection << 597                 G4cout << " *** EtchedTeflonAirReflection *** " << G4endl;
609     G4cout << "EtchedTeflonAirReflection";     << 598         if ( theStatus == EtchedTiOAirReflection )
610   else if(fStatus == EtchedTiOAirReflection)   << 599                 G4cout << " *** EtchedTiOAirReflection *** " << G4endl;
611     G4cout << "EtchedTiOAirReflection";        << 600         if ( theStatus == EtchedTyvekAirReflection )
612   else if(fStatus == EtchedTyvekAirReflection) << 601                 G4cout << " *** EtchedTyvekAirReflection *** " << G4endl;
613     G4cout << "EtchedTyvekAirReflection";      << 602         if ( theStatus == EtchedVM2000AirReflection )
614   else if(fStatus == EtchedVM2000AirReflection << 603                 G4cout << " *** EtchedVM2000AirReflection *** " << G4endl;
615     G4cout << "EtchedVM2000AirReflection";     << 604         if ( theStatus == EtchedVM2000GlueReflection )
616   else if(fStatus == EtchedVM2000GlueReflectio << 605                 G4cout << " *** EtchedVM2000GlueReflection *** " << G4endl;
617     G4cout << "EtchedVM2000GlueReflection";    << 606         if ( theStatus == GroundLumirrorAirReflection )
618   else if(fStatus == GroundLumirrorAirReflecti << 607                 G4cout << " *** GroundLumirrorAirReflection *** " << G4endl;
619     G4cout << "GroundLumirrorAirReflection";   << 608         if ( theStatus == GroundLumirrorGlueReflection )
620   else if(fStatus == GroundLumirrorGlueReflect << 609                 G4cout << " *** GroundLumirrorGlueReflection *** " << G4endl;
621     G4cout << "GroundLumirrorGlueReflection";  << 610         if ( theStatus == GroundAirReflection )
622   else if(fStatus == GroundAirReflection)      << 611                 G4cout << " *** GroundAirReflection *** " << G4endl;
623     G4cout << "GroundAirReflection";           << 612         if ( theStatus == GroundTeflonAirReflection )
624   else if(fStatus == GroundTeflonAirReflection << 613                 G4cout << " *** GroundTeflonAirReflection *** " << G4endl;
625     G4cout << "GroundTeflonAirReflection";     << 614         if ( theStatus == GroundTiOAirReflection )
626   else if(fStatus == GroundTiOAirReflection)   << 615                 G4cout << " *** GroundTiOAirReflection *** " << G4endl;
627     G4cout << "GroundTiOAirReflection";        << 616         if ( theStatus == GroundTyvekAirReflection )
628   else if(fStatus == GroundTyvekAirReflection) << 617                 G4cout << " *** GroundTyvekAirReflection *** " << G4endl;
629     G4cout << "GroundTyvekAirReflection";      << 618         if ( theStatus == GroundVM2000AirReflection )
630   else if(fStatus == GroundVM2000AirReflection << 619                 G4cout << " *** GroundVM2000AirReflection *** " << G4endl;
631     G4cout << "GroundVM2000AirReflection";     << 620         if ( theStatus == GroundVM2000GlueReflection )
632   else if(fStatus == GroundVM2000GlueReflectio << 621                 G4cout << " *** GroundVM2000GlueReflection *** " << G4endl;
633     G4cout << "GroundVM2000GlueReflection";    << 622         if ( theStatus == Absorption )
634   else if(fStatus == Absorption)               << 623                 G4cout << " *** Absorption *** " << G4endl;
635     G4cout << "Absorption";                    << 624         if ( theStatus == Detection )
636   else if(fStatus == Detection)                << 625                 G4cout << " *** Detection *** " << G4endl;
637     G4cout << "Detection";                     << 626         if ( theStatus == NotAtBoundary )
638   else if(fStatus == NotAtBoundary)            << 627                 G4cout << " *** NotAtBoundary *** " << G4endl;
639     G4cout << "NotAtBoundary";                 << 628         if ( theStatus == SameMaterial )
640   else if(fStatus == SameMaterial)             << 629                 G4cout << " *** SameMaterial *** " << G4endl;
641     G4cout << "SameMaterial";                  << 630         if ( theStatus == StepTooSmall )
642   else if(fStatus == StepTooSmall)             << 631                 G4cout << " *** StepTooSmall *** " << G4endl;
643     G4cout << "StepTooSmall";                  << 632         if ( theStatus == NoRINDEX )
644   else if(fStatus == NoRINDEX)                 << 633                 G4cout << " *** NoRINDEX *** " << G4endl;
645     G4cout << "NoRINDEX";                      << 634         if ( theStatus == Dichroic )
646   else if(fStatus == Dichroic)                 << 635                 G4cout << " *** Dichroic Transmission *** " << G4endl;
647     G4cout << "Dichroic Transmission";         << 
648   else if(fStatus == CoatedDielectricReflectio << 
649     G4cout << "Coated Dielectric Reflection";  << 
650   else if(fStatus == CoatedDielectricRefractio << 
651     G4cout << "Coated Dielectric Refraction";  << 
652   else if(fStatus == CoatedDielectricFrustrate << 
653     G4cout << "Coated Dielectric Frustrated Tr << 
654                                                << 
655   G4cout << " ***" << G4endl;                  << 
656 }                                                 636 }
657                                                   637 
658 //....oooOO0OOooo........oooOO0OOooo........oo << 638 G4ThreeVector
659 G4ThreeVector G4OpBoundaryProcess::GetFacetNor << 639 G4OpBoundaryProcess::GetFacetNormal(const G4ThreeVector& Momentum,
660   const G4ThreeVector& momentum, const G4Three << 640                   const G4ThreeVector&  Normal ) const
661 {                                                 641 {
662   G4ThreeVector facetNormal;                   << 642         G4ThreeVector FacetNormal;
663   if(fModel == unified || fModel == LUT || fMo << 643 
664   {                                            << 644         if (theModel == unified || theModel == LUT || theModel== DAVIS) {
665     /* This function codes alpha to a random v << 645 
666     distribution p(alpha) = g(alpha; 0, sigma_ << 646            /* This function code alpha to a random value taken from the
667     for alpha > 0 and alpha < 90, where g(alph << 647            distribution p(alpha) = g(alpha; 0, sigma_alpha)*std::sin(alpha),
668     gaussian distribution with mean 0 and stan << 648            for alpha > 0 and alpha < 90, where g(alpha; 0, sigma_alpha)
669                                                << 649            is a gaussian distribution with mean 0 and standard deviation
670     G4double sigma_alpha = 0.0;                << 650            sigma_alpha.  */
671     if(fOpticalSurface)                        << 651 
672       sigma_alpha = fOpticalSurface->GetSigmaA << 652            G4double alpha;
673     if(sigma_alpha == 0.0)                     << 653 
674     {                                          << 654            G4double sigma_alpha = 0.0;
675       return normal;                           << 655            if (OpticalSurface) sigma_alpha = OpticalSurface->GetSigmaAlpha();
676     }                                          << 656 
677                                                << 657            if (sigma_alpha == 0.0) return FacetNormal = Normal;
678     G4double f_max = std::min(1.0, 4. * sigma_ << 658 
679     G4double alpha, phi, sinAlpha;             << 659            G4double f_max = std::min(1.0,4.*sigma_alpha);
680                                                << 660 
681     do                                         << 661            G4double phi, SinAlpha, CosAlpha, SinPhi, CosPhi, unit_x, unit_y, unit_z;
682     {  // Loop checking, 13-Aug-2015, Peter Gu << 662            G4ThreeVector tmpNormal;
683       do                                       << 663 
684       {  // Loop checking, 13-Aug-2015, Peter  << 664            do {
685         alpha    = G4RandGauss::shoot(0.0, sig << 665               do {
686         sinAlpha = std::sin(alpha);            << 666                  alpha = G4RandGauss::shoot(0.0,sigma_alpha);
687       } while(G4UniformRand() * f_max > sinAlp << 667                  // Loop checking, 13-Aug-2015, Peter Gumplinger
688                                                << 668               } while (G4UniformRand()*f_max > std::sin(alpha) || alpha >= halfpi );
689       phi = G4UniformRand() * twopi;           << 669 
690       facetNormal.set(sinAlpha * std::cos(phi) << 670               phi = G4UniformRand()*twopi;
691                       std::cos(alpha));        << 671 
692       facetNormal.rotateUz(normal);            << 672               SinAlpha = std::sin(alpha);
693     } while(momentum * facetNormal >= 0.0);    << 673               CosAlpha = std::cos(alpha);
694   }                                            << 674               SinPhi = std::sin(phi);
695   else                                         << 675               CosPhi = std::cos(phi);
696   {                                            << 676 
697     G4double polish = 1.0;                     << 677               unit_x = SinAlpha * CosPhi;
698     if(fOpticalSurface)                        << 678               unit_y = SinAlpha * SinPhi;
699       polish = fOpticalSurface->GetPolish();   << 679               unit_z = CosAlpha;
700     if(polish < 1.0)                           << 680 
701     {                                          << 681               FacetNormal.setX(unit_x);
702       do                                       << 682               FacetNormal.setY(unit_y);
703       {  // Loop checking, 13-Aug-2015, Peter  << 683               FacetNormal.setZ(unit_z);
704         G4ThreeVector smear;                   << 684 
705         do                                     << 685               tmpNormal = Normal;
706         {  // Loop checking, 13-Aug-2015, Pete << 686 
707           smear.setX(2. * G4UniformRand() - 1. << 687               FacetNormal.rotateUz(tmpNormal);
708           smear.setY(2. * G4UniformRand() - 1. << 688               // Loop checking, 13-Aug-2015, Peter Gumplinger
709           smear.setZ(2. * G4UniformRand() - 1. << 689            } while (Momentum * FacetNormal >= 0.0);
710         } while(smear.mag2() > 1.0);           << 690   }
711         facetNormal = normal + (1. - polish) * << 691         else {
712       } while(momentum * facetNormal >= 0.0);  << 692 
713       facetNormal = facetNormal.unit();        << 693            G4double  polish = 1.0;
714     }                                          << 694            if (OpticalSurface) polish = OpticalSurface->GetPolish();
715     else                                       << 695 
716     {                                          << 696            if (polish < 1.0) {
717       facetNormal = normal;                    << 697               do {
718     }                                          << 698                  G4ThreeVector smear;
719   }                                            << 699                  do {
720   return facetNormal;                          << 700                     smear.setX(2.*G4UniformRand()-1.0);
                                                   >> 701                     smear.setY(2.*G4UniformRand()-1.0);
                                                   >> 702                     smear.setZ(2.*G4UniformRand()-1.0);
                                                   >> 703                     // Loop checking, 13-Aug-2015, Peter Gumplinger
                                                   >> 704                  } while (smear.mag()>1.0);
                                                   >> 705                  smear = (1.-polish) * smear;
                                                   >> 706                  FacetNormal = Normal + smear;
                                                   >> 707                  // Loop checking, 13-Aug-2015, Peter Gumplinger
                                                   >> 708               } while (Momentum * FacetNormal >= 0.0);
                                                   >> 709               FacetNormal = FacetNormal.unit();
                                                   >> 710            }
                                                   >> 711            else {
                                                   >> 712               FacetNormal = Normal;
                                                   >> 713            }
                                                   >> 714   }
                                                   >> 715         return FacetNormal;
721 }                                                 716 }
722                                                   717 
723 //....oooOO0OOooo........oooOO0OOooo........oo << 
724 void G4OpBoundaryProcess::DielectricMetal()       718 void G4OpBoundaryProcess::DielectricMetal()
725 {                                                 719 {
726   G4int n = 0;                                 << 720         G4int n = 0;
727   G4double rand;                               << 721         G4double rand, PdotN, EdotN;
728   G4ThreeVector A_trans;                       << 722         G4ThreeVector A_trans, A_paral;
729                                                << 723 
730   do                                           << 724         do {
731   {                                            << 725 
732     ++n;                                       << 726            n++;
733     rand = G4UniformRand();                    << 727 
734     if(rand > fReflectivity && n == 1)         << 728            rand = G4UniformRand();
735     {                                          << 729            if ( rand > theReflectivity && n == 1 ) {
736       if(rand > fReflectivity + fTransmittance << 730               if (rand > theReflectivity + theTransmittance) {
737       {                                        << 731                 DoAbsorption();
738         DoAbsorption();                        << 732               } else {
739       }                                        << 733                 theStatus = Transmission;
740       else                                     << 734                 NewMomentum = OldMomentum;
741       {                                        << 735                 NewPolarization = OldPolarization;
742         fStatus          = Transmission;       << 736               }
743         fNewMomentum     = fOldMomentum;       << 737               break;
744         fNewPolarization = fOldPolarization;   << 738            }
745       }                                        << 739            else {
746       break;                                   << 740 
747     }                                          << 741              if (PropertyPointer1 && PropertyPointer2) {
748     else                                       << 742                 if ( n > 1 ) {
749     {                                          << 743                    CalculateReflectivity();
750       if(fRealRIndexMPV && fImagRIndexMPV)     << 744                    if ( !G4BooleanRand(theReflectivity) ) {
751       {                                        << 745                       DoAbsorption();
752         if(n > 1)                              << 746                       break;
753         {                                      << 747                    }
754           CalculateReflectivity();             << 748                 }
755           if(!G4BooleanRand(fReflectivity))    << 749              }
756           {                                    << 750 
757             DoAbsorption();                    << 751              if ( theModel == glisur || theFinish == polished ) {
758             break;                             << 752 
759           }                                    << 753                 DoReflection();
760         }                                      << 754 
761       }                                        << 755              } else {
762       if(fModel == glisur || fFinish == polish << 756 
763       {                                        << 757                 if ( n == 1 ) ChooseReflection();
764         DoReflection();                        << 758                                                                                 
765       }                                        << 759                 if ( theStatus == LambertianReflection ) {
766       else                                     << 760                    DoReflection();
767       {                                        << 761                 }
768         if(n == 1)                             << 762                 else if ( theStatus == BackScattering ) {
769           ChooseReflection();                  << 763                    NewMomentum = -OldMomentum;
770         if(fStatus == LambertianReflection)    << 764                    NewPolarization = -OldPolarization;
771         {                                      << 765                 }
772           DoReflection();                      << 766                 else {
773         }                                      << 767 
774         else if(fStatus == BackScattering)     << 768                    if(theStatus==LobeReflection){
775         {                                      << 769                      if ( PropertyPointer1 && PropertyPointer2 ){
776           fNewMomentum     = -fOldMomentum;    << 770                      } else {
777           fNewPolarization = -fOldPolarization << 771                         theFacetNormal =
778         }                                      << 772                             GetFacetNormal(OldMomentum,theGlobalNormal);
779         else                                   << 773                      }
780         {                                      << 774                    }
781           if(fStatus == LobeReflection)        << 775 
782           {                                    << 776                    PdotN = OldMomentum * theFacetNormal;
783             if(!fRealRIndexMPV || !fImagRIndex << 777                    NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
784             {                                  << 778                    EdotN = OldPolarization * theFacetNormal;
785               fFacetNormal = GetFacetNormal(fO << 779 
786             }                                  << 780                    if (sint1 > 0.0 ) {
787             // else                            << 781                       A_trans = OldMomentum.cross(theFacetNormal);
788             //  case of complex rindex needs t << 782                       A_trans = A_trans.unit();
789           }                                    << 783                    } else {
790           fNewMomentum =                       << 784                       A_trans  = OldPolarization;
791             fOldMomentum - 2. * fOldMomentum * << 785                    }
                                                   >> 786                    A_paral   = NewMomentum.cross(A_trans);
                                                   >> 787                    A_paral   = A_paral.unit();
                                                   >> 788 
                                                   >> 789                    if(iTE>0&&iTM>0) {
                                                   >> 790                      NewPolarization = 
                                                   >> 791                            -OldPolarization + (2.*EdotN)*theFacetNormal;
                                                   >> 792                    } else if (iTE>0) {
                                                   >> 793                      NewPolarization = -A_trans;
                                                   >> 794                    } else if (iTM>0) {
                                                   >> 795                      NewPolarization = -A_paral;
                                                   >> 796                    }
792                                                   797 
793           if(f_iTE > 0 && f_iTM > 0)           << 798                 }
794           {                                    << 799 
795             fNewPolarization =                 << 800              }
796               -fOldPolarization +              << 801 
797               (2. * fOldPolarization * fFacetN << 802              OldMomentum = NewMomentum;
798           }                                    << 803              OldPolarization = NewPolarization;
799           else if(f_iTE > 0)                   << 804 
800           {                                    << 805      }
801             A_trans = (fSint1 > 0.0) ? fOldMom << 806 
802                                      : fOldPol << 807           // Loop checking, 13-Aug-2015, Peter Gumplinger
803             fNewPolarization = -A_trans;       << 808   } while (NewMomentum * theGlobalNormal < 0.0);
804           }                                    << 
805           else if(f_iTM > 0)                   << 
806           {                                    << 
807             fNewPolarization =                 << 
808               -fNewMomentum.cross(A_trans).uni << 
809           }                                    << 
810         }                                      << 
811       }                                        << 
812       fOldMomentum     = fNewMomentum;         << 
813       fOldPolarization = fNewPolarization;     << 
814     }                                          << 
815     // Loop checking, 13-Aug-2015, Peter Gumpl << 
816   } while(fNewMomentum * fGlobalNormal < 0.0); << 
817 }                                                 809 }
818                                                   810 
819 //....oooOO0OOooo........oooOO0OOooo........oo << 
820 void G4OpBoundaryProcess::DielectricLUT()         811 void G4OpBoundaryProcess::DielectricLUT()
821 {                                                 812 {
822   G4int thetaIndex, phiIndex;                  << 813         G4int thetaIndex, phiIndex;
823   G4double angularDistVal, thetaRad, phiRad;   << 814         G4double AngularDistributionValue, thetaRad, phiRad, EdotN;
824   G4ThreeVector perpVectorTheta, perpVectorPhi << 815         G4ThreeVector PerpendicularVectorTheta, PerpendicularVectorPhi;
825                                                << 816 
826   fStatus = G4OpBoundaryProcessStatus(         << 817         theStatus = G4OpBoundaryProcessStatus(G4int(theFinish) + 
827     G4int(fFinish) + (G4int(NoRINDEX) - G4int( << 818                            (G4int(NoRINDEX)-G4int(groundbackpainted)));
828                                                << 819 
829   G4int thetaIndexMax = fOpticalSurface->GetTh << 820         G4int thetaIndexMax = OpticalSurface->GetThetaIndexMax();
830   G4int phiIndexMax   = fOpticalSurface->GetPh << 821         G4int phiIndexMax   = OpticalSurface->GetPhiIndexMax();
831                                                << 822 
832   G4double rand;                               << 823         G4double rand;
833                                                << 824 
834   do                                           << 825         do {
835   {                                            << 826            rand = G4UniformRand();
836     rand = G4UniformRand();                    << 827            if ( rand > theReflectivity ) {
837     if(rand > fReflectivity)                   << 828               if (rand > theReflectivity + theTransmittance) {
838     {                                          << 829                  DoAbsorption();
839       if(rand > fReflectivity + fTransmittance << 830               } else {
840       {                                        << 831                  theStatus = Transmission;
841         DoAbsorption();                        << 832                  NewMomentum = OldMomentum;
842       }                                        << 833                  NewPolarization = OldPolarization;
843       else                                     << 834               }
844       {                                        << 835               break;
845         fStatus          = Transmission;       << 836            }
846         fNewMomentum     = fOldMomentum;       << 837            else {
847         fNewPolarization = fOldPolarization;   << 838               // Calculate Angle between Normal and Photon Momentum
848       }                                        << 839               G4double anglePhotonToNormal = 
849       break;                                   << 840                                           OldMomentum.angle(-theGlobalNormal);
850     }                                          << 841               // Round it to closest integer
851     else                                       << 842               G4int angleIncident = G4int(std::floor(180/pi*anglePhotonToNormal+0.5));
852     {                                          << 843 
853       // Calculate Angle between Normal and Ph << 844               // Take random angles THETA and PHI, 
854       G4double anglePhotonToNormal = fOldMomen << 845               // and see if below Probability - if not - Redo
855       // Round to closest integer: LBNL model  << 846               do {
856       G4int angleIncident = (G4int)std::lrint( << 847                  thetaIndex = G4RandFlat::shootInt(thetaIndexMax-1);
857                                                << 848                  phiIndex = G4RandFlat::shootInt(phiIndexMax-1);
858       // Take random angles THETA and PHI,     << 849                  // Find probability with the new indeces from LUT
859       // and see if below Probability - if not << 850                  AngularDistributionValue = OpticalSurface -> 
860       do                                       << 851                    GetAngularDistributionValue(angleIncident,
861       {                                        << 852                                                thetaIndex,
862         thetaIndex = (G4int)G4RandFlat::shootI << 853                                                phiIndex);
863         phiIndex   = (G4int)G4RandFlat::shootI << 854                 // Loop checking, 13-Aug-2015, Peter Gumplinger
864         // Find probability with the new indec << 855               } while ( !G4BooleanRand(AngularDistributionValue) );
865         angularDistVal = fOpticalSurface->GetA << 856 
866           angleIncident, thetaIndex, phiIndex) << 857               thetaRad = (-90 + 4*thetaIndex)*pi/180;
867         // Loop checking, 13-Aug-2015, Peter G << 858               phiRad = (-90 + 5*phiIndex)*pi/180;
868       } while(!G4BooleanRand(angularDistVal)); << 859               // Rotate Photon Momentum in Theta, then in Phi
869                                                << 860               NewMomentum = -OldMomentum;
870       thetaRad = G4double(-90 + 4 * thetaIndex << 861 
871       phiRad   = G4double(-90 + 5 * phiIndex)  << 862               PerpendicularVectorTheta = NewMomentum.cross(theGlobalNormal);
872       // Rotate Photon Momentum in Theta, then << 863               if (PerpendicularVectorTheta.mag() < kCarTolerance )
873       fNewMomentum = -fOldMomentum;            << 864                           PerpendicularVectorTheta = NewMomentum.orthogonal();
874                                                << 865               NewMomentum =
875       perpVectorTheta = fNewMomentum.cross(fGl << 866                  NewMomentum.rotate(anglePhotonToNormal-thetaRad,
876       if(perpVectorTheta.mag() < fCarTolerance << 867                                     PerpendicularVectorTheta);
877       {                                        << 868               PerpendicularVectorPhi = 
878         perpVectorTheta = fNewMomentum.orthogo << 869                                   PerpendicularVectorTheta.cross(NewMomentum);
879       }                                        << 870               NewMomentum = NewMomentum.rotate(-phiRad,PerpendicularVectorPhi);
880       fNewMomentum =                           << 871 
881         fNewMomentum.rotate(anglePhotonToNorma << 872               // Rotate Polarization too:
882       perpVectorPhi = perpVectorTheta.cross(fN << 873               theFacetNormal = (NewMomentum - OldMomentum).unit();
883       fNewMomentum  = fNewMomentum.rotate(-phi << 874               EdotN = OldPolarization * theFacetNormal;
884                                                << 875               NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
885       // Rotate Polarization too:              << 876            }
886       fFacetNormal     = (fNewMomentum - fOldM << 877           // Loop checking, 13-Aug-2015, Peter Gumplinger
887       fNewPolarization = -fOldPolarization +   << 878         } while (NewMomentum * theGlobalNormal <= 0.0);
888                          (2. * fOldPolarizatio << 
889     }                                          << 
890     // Loop checking, 13-Aug-2015, Peter Gumpl << 
891   } while(fNewMomentum * fGlobalNormal <= 0.0) << 
892 }                                                 879 }
893                                                   880 
894 //....oooOO0OOooo........oooOO0OOooo........oo << 
895 void G4OpBoundaryProcess::DielectricLUTDAVIS()    881 void G4OpBoundaryProcess::DielectricLUTDAVIS()
896 {                                                 882 {
897   G4int angindex, random, angleIncident;          883   G4int angindex, random, angleIncident;
898   G4double reflectivityValue, elevation, azimu << 884   G4double ReflectivityValue, elevation, azimuth, EdotN;
899   G4double anglePhotonToNormal;                   885   G4double anglePhotonToNormal;
900                                                   886 
901   G4int lutbin  = fOpticalSurface->GetLUTbins( << 887   G4int LUTbin = OpticalSurface->GetLUTbins();
                                                   >> 888 
902   G4double rand = G4UniformRand();                889   G4double rand = G4UniformRand();
903                                                   890 
904   G4double sinEl;                              << 891   do {
905   G4ThreeVector u, vNorm, w;                   << 
906                                                   892 
907   do                                           << 893      anglePhotonToNormal = OldMomentum.angle(-theGlobalNormal);
908   {                                            << 894      angleIncident = G4int(std::floor(180/pi*anglePhotonToNormal+0.5));
909     anglePhotonToNormal = fOldMomentum.angle(- << 
910                                                << 
911     // Davis model has 90 reflection bins: rou << 
912     // don't allow angleIncident to be 90 for  << 
913     angleIncident = std::min(                  << 
914       static_cast<G4int>(std::floor(anglePhoto << 
915     reflectivityValue = fOpticalSurface->GetRe << 
916                                                << 
917     if(rand > reflectivityValue)               << 
918     {                                          << 
919       if(fEfficiency > 0.)                     << 
920       {                                        << 
921         DoAbsorption();                        << 
922         break;                                 << 
923       }                                        << 
924       else                                     << 
925       {                                        << 
926         fStatus = Transmission;                << 
927                                                   895 
928         if(angleIncident <= 0.01)              << 896      ReflectivityValue = OpticalSurface -> GetReflectivityLUTValue(angleIncident);
929         {                                      << 897 
930           fNewMomentum = fOldMomentum;         << 898      if ( rand > ReflectivityValue ) {
931           break;                               << 899 
                                                   >> 900         if ( theEfficiency > 0 ) {
                                                   >> 901            DoAbsorption();
                                                   >> 902            break;
932         }                                         903         }
                                                   >> 904         else {
933                                                   905 
934         do                                     << 906            theStatus = Transmission;
935         {                                      << 907 
936           random = (G4int)G4RandFlat::shootInt << 908            if (angleIncident <= 0.01) {
937           angindex =                           << 909               NewMomentum = OldMomentum;
938             (((random * 2) - 1)) + angleIncide << 910               break;
939                                                << 911 
940           azimuth =                            << 912            }
941             fOpticalSurface->GetAngularDistrib << 913 
942           elevation = fOpticalSurface->GetAngu << 914            do {
943         } while(elevation == 0. && azimuth ==  << 915               random   = G4RandFlat::shootInt(1,LUTbin+1);
944                                                << 916               angindex = (((random*2)-1))+angleIncident*LUTbin*2 + 3640000;
945         sinEl = std::sin(elevation);           << 917 
946         vNorm = (fGlobalNormal.cross(fOldMomen << 918               azimuth  = OpticalSurface -> GetAngularDistributionValueLUT(angindex-1);
947         u     = vNorm.cross(fGlobalNormal) * ( << 919               elevation= OpticalSurface -> GetAngularDistributionValueLUT(angindex);
948         vNorm *= (sinEl * std::sin(azimuth));  << 920 
949         // fGlobalNormal shouldn't be modified << 921            } while ( elevation == 0 && azimuth == 0);
950         w            = (fGlobalNormal *= std:: << 922 
951         fNewMomentum = u + vNorm + w;          << 923            NewMomentum = -OldMomentum;
952                                                << 924 
953         // Rotate Polarization too:            << 925            G4ThreeVector v = theGlobalNormal.cross(-NewMomentum);
954         fFacetNormal     = (fNewMomentum - fOl << 926            G4ThreeVector vNorm = v/v.mag();
955         fNewPolarization = -fOldPolarization + << 927            G4ThreeVector u = vNorm.cross(theGlobalNormal);
956                                                << 928 
957       }                                        << 929            u = u *= (std::sin(elevation) * std::cos(azimuth));
958     }                                          << 930            v = vNorm *= (std::sin(elevation) * std::sin(azimuth));
959     else                                       << 931            G4ThreeVector w = theGlobalNormal *= (std::cos(elevation));
960     {                                          << 932            NewMomentum = G4ThreeVector(u+v+w);
961       fStatus = LobeReflection;                << 933 
962                                                << 934            // Rotate Polarization too:
963       if(angleIncident == 0)                   << 935            theFacetNormal = (NewMomentum - OldMomentum).unit();
964       {                                        << 936            EdotN = OldPolarization * theFacetNormal;
965         fNewMomentum = -fOldMomentum;          << 937            NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
966         break;                                 << 938         }
967       }                                        << 939      }
968                                                << 940      else {
969       do                                       << 941 
970       {                                        << 942         theStatus = LobeReflection;
971         random   = (G4int)G4RandFlat::shootInt << 943 
972         angindex = (((random * 2) - 1)) + (ang << 944         if (angleIncident == 0) {
973                                                << 945            NewMomentum = -OldMomentum;
974         azimuth = fOpticalSurface->GetAngularD << 946            break;
975         elevation = fOpticalSurface->GetAngula << 947         }
976       } while(elevation == 0. && azimuth == 0. << 948 
977                                                << 949         do {
978       sinEl = std::sin(elevation);             << 950            random   = G4RandFlat::shootInt(1,LUTbin+1);
979       vNorm = (fGlobalNormal.cross(fOldMomentu << 951            angindex = (((random*2)-1))+(angleIncident-1)*LUTbin*2;
980       u     = vNorm.cross(fGlobalNormal) * (si << 952 
981       vNorm *= (sinEl * std::sin(azimuth));    << 953            azimuth   = OpticalSurface -> GetAngularDistributionValueLUT(angindex-1);
982       // fGlobalNormal shouldn't be modified h << 954            elevation = OpticalSurface -> GetAngularDistributionValueLUT(angindex);
983       w = (fGlobalNormal *= std::cos(elevation << 955         } while (elevation == 0 && azimuth == 0);
984                                                << 956 
985       fNewMomentum = u + vNorm + w;            << 957         NewMomentum = -OldMomentum;
986                                                << 958 
987       // Rotate Polarization too: (needs revis << 959         G4ThreeVector v     = theGlobalNormal.cross(-NewMomentum);
988       fNewPolarization = fOldPolarization;     << 960         G4ThreeVector vNorm = v/v.mag();
989     }                                          << 961         G4ThreeVector u     = vNorm.cross(theGlobalNormal);
990   } while(fNewMomentum * fGlobalNormal <= 0.0) << 962 
                                                   >> 963         u = u *= (std::sin(elevation) * std::cos(azimuth));
                                                   >> 964         v = vNorm *= (std::sin(elevation) * std::sin(azimuth));
                                                   >> 965         G4ThreeVector w = theGlobalNormal*=(std::cos(elevation));
                                                   >> 966 
                                                   >> 967         NewMomentum = G4ThreeVector(u+v+w);
                                                   >> 968 
                                                   >> 969         // Rotate Polarization too: (needs revision)
                                                   >> 970         NewPolarization = OldPolarization;
                                                   >> 971      }
                                                   >> 972   } while (NewMomentum * theGlobalNormal <= 0.0);
991 }                                                 973 }
992                                                   974 
993 //....oooOO0OOooo........oooOO0OOooo........oo << 
994 void G4OpBoundaryProcess::DielectricDichroic()    975 void G4OpBoundaryProcess::DielectricDichroic()
995 {                                                 976 {
996   // Calculate Angle between Normal and Photon << 977         // Calculate Angle between Normal and Photon Momentum
997   G4double anglePhotonToNormal = fOldMomentum. << 978         G4double anglePhotonToNormal = OldMomentum.angle(-theGlobalNormal);
998                                                   979 
999   // Round it to closest integer               << 980         // Round it to closest integer
1000   G4double angleIncident = std::floor(180. /  << 981         G4double angleIncident = std::floor(180/pi*anglePhotonToNormal+0.5);
1001                                                  982 
1002   if(!fDichroicVector)                        << 983         if (!DichroicVector) {
1003   {                                           << 984            if (OpticalSurface) DichroicVector = OpticalSurface->GetDichroicVector();
1004     if(fOpticalSurface)                       << 985         }
1005       fDichroicVector = fOpticalSurface->GetD << 
1006   }                                           << 
1007                                                  986 
1008   if(fDichroicVector)                         << 
1009   {                                           << 
1010     G4double wavelength = h_Planck * c_light  << 
1011     fTransmittance      = fDichroicVector->Va << 
1012                                             i << 
1013                      perCent;                 << 
1014     //   G4cout << "wavelength: " << std::flo << 
1015     //                            << "nm" <<  << 
1016     //   G4cout << "Incident angle: " << angl << 
1017     //   G4cout << "Transmittance: "          << 
1018     //          << std::floor(fTransmittance/ << 
1019   }                                           << 
1020   else                                        << 
1021   {                                           << 
1022     G4ExceptionDescription ed;                << 
1023     ed << " G4OpBoundaryProcess/DielectricDic << 
1024        << " The dichroic surface has no G4Phy << 
1025     G4Exception("G4OpBoundaryProcess::Dielect << 
1026                 FatalException, ed,           << 
1027                 "A dichroic surface must have << 
1028   }                                           << 
1029                                                  987 
1030   if(!G4BooleanRand(fTransmittance))          << 988         if (DichroicVector) {
1031   {  // Not transmitted, so reflect           << 989            G4double wavelength = h_Planck*c_light/thePhotonMomentum;
1032     if(fModel == glisur || fFinish == polishe << 990            theTransmittance =
1033     {                                         << 991              DichroicVector->Value(wavelength/nm,angleIncident,idx,idy)*perCent;
1034       DoReflection();                         << 992 //            G4cout << "wavelength: " << std::floor(wavelength/nm) 
1035     }                                         << 993 //                                     << "nm" << G4endl;
1036     else                                      << 994 //            G4cout << "Incident angle: " << angleIncident << "deg" << G4endl;
1037     {                                         << 995 //            G4cout << "Transmittance: " 
1038       ChooseReflection();                     << 996 //                   << std::floor(theTransmittance/perCent) << "%" << G4endl;
1039       if(fStatus == LambertianReflection)     << 997         } else {
1040       {                                       << 998            G4ExceptionDescription ed;
1041         DoReflection();                       << 999            ed << " G4OpBoundaryProcess/DielectricDichroic(): "
1042       }                                       << 1000               << " The dichroic surface has no G4Physics2DVector"
1043       else if(fStatus == BackScattering)      << 1001               << G4endl;
1044       {                                       << 1002            G4Exception("G4OpBoundaryProcess::DielectricDichroic", "OpBoun03",
1045         fNewMomentum     = -fOldMomentum;     << 1003                        FatalException,ed,
1046         fNewPolarization = -fOldPolarization; << 1004                        "A dichroic surface must have an associated G4Physics2DVector");
1047       }                                       << 1005         }
1048       else                                    << 1006 
1049       {                                       << 1007         if ( !G4BooleanRand(theTransmittance) ) { // Not transmitted, so reflect
1050         G4double PdotN, EdotN;                << 1008 
1051         do                                    << 1009            if ( theModel == glisur || theFinish == polished ) {
1052         {                                     << 1010               DoReflection();
1053           if(fStatus == LobeReflection)       << 1011            } else {
1054           {                                   << 1012               ChooseReflection();
1055             fFacetNormal = GetFacetNormal(fOl << 1013               if ( theStatus == LambertianReflection ) {
1056           }                                   << 1014                  DoReflection();
1057           PdotN        = fOldMomentum * fFace << 1015               } else if ( theStatus == BackScattering ) {
1058           fNewMomentum = fOldMomentum - (2. * << 1016                  NewMomentum = -OldMomentum;
1059           // Loop checking, 13-Aug-2015, Pete << 1017                  NewPolarization = -OldPolarization;
1060         } while(fNewMomentum * fGlobalNormal  << 1018               } else {
                                                   >> 1019                 G4double PdotN, EdotN;
                                                   >> 1020                 do {
                                                   >> 1021                    if (theStatus==LobeReflection)
                                                   >> 1022                       theFacetNormal = GetFacetNormal(OldMomentum,theGlobalNormal);
                                                   >> 1023                    PdotN = OldMomentum * theFacetNormal;
                                                   >> 1024                    NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
                                                   >> 1025                   // Loop checking, 13-Aug-2015, Peter Gumplinger
                                                   >> 1026                 } while (NewMomentum * theGlobalNormal <= 0.0);
                                                   >> 1027                 EdotN = OldPolarization * theFacetNormal;
                                                   >> 1028                 NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
                                                   >> 1029               }
                                                   >> 1030            }
                                                   >> 1031 
                                                   >> 1032         } else {
                                                   >> 1033 
                                                   >> 1034            theStatus = Dichroic;
                                                   >> 1035            NewMomentum = OldMomentum;
                                                   >> 1036            NewPolarization = OldPolarization;
1061                                                  1037 
1062         EdotN            = fOldPolarization * << 1038         }
1063         fNewPolarization = -fOldPolarization  << 
1064       }                                       << 
1065     }                                         << 
1066   }                                           << 
1067   else                                        << 
1068   {                                           << 
1069     fStatus          = Dichroic;              << 
1070     fNewMomentum     = fOldMomentum;          << 
1071     fNewPolarization = fOldPolarization;      << 
1072   }                                           << 
1073 }                                                1039 }
1074                                                  1040 
1075 //....oooOO0OOooo........oooOO0OOooo........o << 
1076 void G4OpBoundaryProcess::DielectricDielectri    1041 void G4OpBoundaryProcess::DielectricDielectric()
1077 {                                                1042 {
1078   G4bool inside = false;                      << 1043         G4bool Inside = false;
1079   G4bool swap   = false;                      << 1044         G4bool Swap = false;
1080                                                  1045 
1081   if(fFinish == polished)                     << 1046         G4bool SurfaceRoughnessCriterionPass = 1;
1082   {                                           << 1047         if (theSurfaceRoughness != 0. && Rindex1 > Rindex2) {
1083     fFacetNormal = fGlobalNormal;             << 1048            G4double wavelength = h_Planck*c_light/thePhotonMomentum;
1084   }                                           << 1049            G4double SurfaceRoughnessCriterion =
1085   else                                        << 1050              std::exp(-std::pow((4*pi*theSurfaceRoughness*Rindex1*cost1/wavelength),2));
1086   {                                           << 1051            SurfaceRoughnessCriterionPass = 
1087     fFacetNormal = GetFacetNormal(fOldMomentu << 1052                                      G4BooleanRand(SurfaceRoughnessCriterion);
1088   }                                           << 1053         }
1089   G4double cost1 = -fOldMomentum * fFacetNorm << 
1090   G4double cost2 = 0.;                        << 
1091   G4double sint2 = 0.;                        << 
1092                                               << 
1093   G4bool surfaceRoughnessCriterionPass = true << 
1094   if(fSurfaceRoughness != 0. && fRindex1 > fR << 
1095   {                                           << 
1096     G4double wavelength                = h_Pl << 
1097     G4double surfaceRoughnessCriterion = std: << 
1098       (4. * pi * fSurfaceRoughness * fRindex1 << 
1099     surfaceRoughnessCriterionPass = G4Boolean << 
1100   }                                           << 
1101                                                  1054 
1102 leap:                                         << 1055         leap:
1103                                                  1056 
1104   G4bool through = false;                     << 1057         G4bool Through = false;
1105   G4bool done    = false;                     << 1058         G4bool Done = false;
1106                                                  1059 
1107   G4ThreeVector A_trans, A_paral, E1pp, E1pl; << 1060         G4double PdotN, EdotN;
1108   G4double E1_perp, E1_parl;                  << 
1109   G4double s1, s2, E2_perp, E2_parl, E2_total << 
1110   G4double E2_abs, C_parl, C_perp;            << 
1111   G4double alpha;                             << 
1112                                               << 
1113   do                                          << 
1114   {                                           << 
1115     if(through)                               << 
1116     {                                         << 
1117       swap          = !swap;                  << 
1118       through       = false;                  << 
1119       fGlobalNormal = -fGlobalNormal;         << 
1120       G4SwapPtr(fMaterial1, fMaterial2);      << 
1121       G4SwapObj(&fRindex1, &fRindex2);        << 
1122     }                                         << 
1123                                               << 
1124     if(fFinish == polished)                   << 
1125     {                                         << 
1126       fFacetNormal = fGlobalNormal;           << 
1127     }                                         << 
1128     else                                      << 
1129     {                                         << 
1130       fFacetNormal = GetFacetNormal(fOldMomen << 
1131     }                                         << 
1132                                               << 
1133     cost1 = -fOldMomentum * fFacetNormal;     << 
1134     if(std::abs(cost1) < 1.0 - fCarTolerance) << 
1135     {                                         << 
1136       fSint1 = std::sqrt(1. - cost1 * cost1); << 
1137       sint2  = fSint1 * fRindex1 / fRindex2;  << 
1138       // this isn't a sine as we might expect << 
1139     }                                         << 
1140     else                                      << 
1141     {                                         << 
1142       fSint1 = 0.0;                           << 
1143       sint2  = 0.0;                           << 
1144     }                                         << 
1145                                               << 
1146     // TOTAL INTERNAL REFLECTION              << 
1147     if(sint2 >= 1.0)                          << 
1148     {                                         << 
1149       swap = false;                           << 
1150                                               << 
1151       fStatus = TotalInternalReflection;      << 
1152       if(!surfaceRoughnessCriterionPass)      << 
1153         fStatus = LambertianReflection;       << 
1154       if(fModel == unified && fFinish != poli << 
1155         ChooseReflection();                   << 
1156       if(fStatus == LambertianReflection)     << 
1157       {                                       << 
1158         DoReflection();                       << 
1159       }                                       << 
1160       else if(fStatus == BackScattering)      << 
1161       {                                       << 
1162         fNewMomentum     = -fOldMomentum;     << 
1163         fNewPolarization = -fOldPolarization; << 
1164       }                                       << 
1165       else                                    << 
1166       {                                       << 
1167         fNewMomentum =                        << 
1168           fOldMomentum - 2. * fOldMomentum *  << 
1169         fNewPolarization = -fOldPolarization  << 
1170                                               << 
1171       }                                       << 
1172     }                                         << 
1173     // NOT TIR                                << 
1174     else if(sint2 < 1.0)                      << 
1175     {                                         << 
1176       // Calculate amplitude for transmission << 
1177       if(cost1 > 0.0)                         << 
1178       {                                       << 
1179         cost2 = std::sqrt(1. - sint2 * sint2) << 
1180       }                                       << 
1181       else                                    << 
1182       {                                       << 
1183         cost2 = -std::sqrt(1. - sint2 * sint2 << 
1184       }                                       << 
1185                                               << 
1186       if(fSint1 > 0.0)                        << 
1187       {                                       << 
1188         A_trans = (fOldMomentum.cross(fFacetN << 
1189         E1_perp = fOldPolarization * A_trans; << 
1190         E1pp    = E1_perp * A_trans;          << 
1191         E1pl    = fOldPolarization - E1pp;    << 
1192         E1_parl = E1pl.mag();                 << 
1193       }                                       << 
1194       else                                    << 
1195       {                                       << 
1196         A_trans = fOldPolarization;           << 
1197         // Here we Follow Jackson's conventio << 
1198         // component = 1 in case of a ray per << 
1199         E1_perp = 0.0;                        << 
1200         E1_parl = 1.0;                        << 
1201       }                                       << 
1202                                               << 
1203       s1       = fRindex1 * cost1;            << 
1204       E2_perp  = 2. * s1 * E1_perp / (fRindex << 
1205       E2_parl  = 2. * s1 * E1_parl / (fRindex << 
1206       E2_total = E2_perp * E2_perp + E2_parl  << 
1207       s2       = fRindex2 * cost2 * E2_total; << 
1208                                               << 
1209       // D.Sawkey, 24 May 24                  << 
1210       // Transmittance has already been taken << 
1211       // For e.g. specular surfaces, the rati << 
1212       // reflection should be given by the ma << 
1213       // TRANSMITTANCE                        << 
1214       //if(fTransmittance > 0.)               << 
1215       //  transCoeff = fTransmittance;        << 
1216       //else if(cost1 != 0.0)                 << 
1217       if(cost1 != 0.0)                        << 
1218         transCoeff = s2 / s1;                 << 
1219       else                                    << 
1220         transCoeff = 0.0;                     << 
1221                                               << 
1222       // NOT TIR: REFLECTION                  << 
1223       if(!G4BooleanRand(transCoeff))          << 
1224       {                                       << 
1225         swap    = false;                      << 
1226         fStatus = FresnelReflection;          << 
1227                                               << 
1228         if(!surfaceRoughnessCriterionPass)    << 
1229           fStatus = LambertianReflection;     << 
1230         if(fModel == unified && fFinish != po << 
1231           ChooseReflection();                 << 
1232         if(fStatus == LambertianReflection)   << 
1233         {                                     << 
1234           DoReflection();                     << 
1235         }                                     << 
1236         else if(fStatus == BackScattering)    << 
1237         {                                     << 
1238           fNewMomentum     = -fOldMomentum;   << 
1239           fNewPolarization = -fOldPolarizatio << 
1240         }                                     << 
1241         else                                  << 
1242         {                                     << 
1243           fNewMomentum =                      << 
1244             fOldMomentum - 2. * fOldMomentum  << 
1245           if(fSint1 > 0.0)                    << 
1246           {  // incident ray oblique          << 
1247             E2_parl  = fRindex2 * E2_parl / f << 
1248             E2_perp  = E2_perp - E1_perp;     << 
1249             E2_total = E2_perp * E2_perp + E2 << 
1250             A_paral  = (fNewMomentum.cross(A_ << 
1251             E2_abs   = std::sqrt(E2_total);   << 
1252             C_parl   = E2_parl / E2_abs;      << 
1253             C_perp   = E2_perp / E2_abs;      << 
1254                                                  1061 
1255             fNewPolarization = C_parl * A_par << 1062         G4ThreeVector A_trans, A_paral, E1pp, E1pl;
1256           }                                   << 1063         G4double E1_perp, E1_parl;
1257           else                                << 1064         G4double s1, s2, E2_perp, E2_parl, E2_total, TransCoeff;
1258           {  // incident ray perpendicular    << 1065         G4double E2_abs, C_parl, C_perp;
1259             if(fRindex2 > fRindex1)           << 1066         G4double alpha;
1260             {                                 << 1067 
1261               fNewPolarization = -fOldPolariz << 1068         do {
1262             }                                 << 1069 
1263             else                              << 1070            if (Through) {
1264             {                                 << 1071               Swap = !Swap;
1265               fNewPolarization = fOldPolariza << 1072               Through = false;
1266             }                                 << 1073               theGlobalNormal = -theGlobalNormal;
1267           }                                   << 1074               G4SwapPtr(Material1,Material2);
1268         }                                     << 1075               G4SwapObj(&Rindex1,&Rindex2);
1269       }                                       << 1076            }
1270       // NOT TIR: TRANSMISSION                << 1077 
1271       else                                    << 1078            if ( theFinish == polished ) {
1272       {                                       << 1079               theFacetNormal = theGlobalNormal;
1273         inside  = !inside;                    << 1080            }
1274         through = true;                       << 1081            else {
1275         fStatus = FresnelRefraction;          << 1082               theFacetNormal =
1276                                               << 1083                              GetFacetNormal(OldMomentum,theGlobalNormal);
1277         if(fSint1 > 0.0)                      << 1084            }
1278         {  // incident ray oblique            << 1085 
1279           alpha        = cost1 - cost2 * (fRi << 1086            PdotN = OldMomentum * theFacetNormal;
1280           fNewMomentum = (fOldMomentum + alph << 1087            EdotN = OldPolarization * theFacetNormal;
1281           A_paral      = (fNewMomentum.cross( << 1088 
1282           E2_abs       = std::sqrt(E2_total); << 1089            cost1 = - PdotN;
1283           C_parl       = E2_parl / E2_abs;    << 1090            if (std::abs(cost1) < 1.0-kCarTolerance){
1284           C_perp       = E2_perp / E2_abs;    << 1091               sint1 = std::sqrt(1.-cost1*cost1);
1285                                               << 1092               sint2 = sint1*Rindex1/Rindex2;     // *** Snell's Law ***
1286           fNewPolarization = C_parl * A_paral << 1093            }
1287         }                                     << 1094            else {
1288         else                                  << 1095               sint1 = 0.0;
1289         {  // incident ray perpendicular      << 1096               sint2 = 0.0;
1290           fNewMomentum     = fOldMomentum;    << 1097            }
1291           fNewPolarization = fOldPolarization << 1098 
1292         }                                     << 1099            if (sint2 >= 1.0) {
1293       }                                       << 1100 
1294     }                                         << 1101               // Simulate total internal reflection
1295                                               << 1102 
1296     fOldMomentum     = fNewMomentum.unit();   << 1103               if (Swap) Swap = !Swap;
1297     fOldPolarization = fNewPolarization.unit( << 1104 
1298                                               << 1105               theStatus = TotalInternalReflection;
1299     if(fStatus == FresnelRefraction)          << 1106 
1300     {                                         << 1107               if ( !SurfaceRoughnessCriterionPass ) theStatus =
1301       done = (fNewMomentum * fGlobalNormal <= << 1108                                                        LambertianReflection;
1302     }                                         << 1109 
1303     else                                      << 1110               if ( theModel == unified && theFinish != polished )
1304     {                                         << 1111                                                     ChooseReflection();
1305       done = (fNewMomentum * fGlobalNormal >= << 1112 
1306     }                                         << 1113               if ( theStatus == LambertianReflection ) {
1307     // Loop checking, 13-Aug-2015, Peter Gump << 1114                  DoReflection();
1308   } while(!done);                             << 1115               }
                                                   >> 1116               else if ( theStatus == BackScattering ) {
                                                   >> 1117                  NewMomentum = -OldMomentum;
                                                   >> 1118                  NewPolarization = -OldPolarization;
                                                   >> 1119               }
                                                   >> 1120               else {
                                                   >> 1121 
                                                   >> 1122                  PdotN = OldMomentum * theFacetNormal;
                                                   >> 1123                  NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
                                                   >> 1124                  EdotN = OldPolarization * theFacetNormal;
                                                   >> 1125                  NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
                                                   >> 1126 
                                                   >> 1127               }
                                                   >> 1128            }
                                                   >> 1129            else if (sint2 < 1.0) {
                                                   >> 1130 
                                                   >> 1131               // Calculate amplitude for transmission (Q = P x N)
                                                   >> 1132 
                                                   >> 1133               if (cost1 > 0.0) {
                                                   >> 1134                  cost2 =  std::sqrt(1.-sint2*sint2);
                                                   >> 1135               }
                                                   >> 1136               else {
                                                   >> 1137                  cost2 = -std::sqrt(1.-sint2*sint2);
                                                   >> 1138               }
                                                   >> 1139 
                                                   >> 1140               if (sint1 > 0.0) {
                                                   >> 1141                  A_trans = OldMomentum.cross(theFacetNormal);
                                                   >> 1142                  A_trans = A_trans.unit();
                                                   >> 1143                  E1_perp = OldPolarization * A_trans;
                                                   >> 1144                  E1pp    = E1_perp * A_trans;
                                                   >> 1145                  E1pl    = OldPolarization - E1pp;
                                                   >> 1146                  E1_parl = E1pl.mag();
                                                   >> 1147               }
                                                   >> 1148               else {
                                                   >> 1149                  A_trans  = OldPolarization;
                                                   >> 1150                  // Here we Follow Jackson's conventions and we set the
                                                   >> 1151                  // parallel component = 1 in case of a ray perpendicular
                                                   >> 1152                  // to the surface
                                                   >> 1153                  E1_perp  = 0.0;
                                                   >> 1154                  E1_parl  = 1.0;
                                                   >> 1155               }
                                                   >> 1156 
                                                   >> 1157               s1 = Rindex1*cost1;
                                                   >> 1158               E2_perp = 2.*s1*E1_perp/(Rindex1*cost1+Rindex2*cost2);
                                                   >> 1159               E2_parl = 2.*s1*E1_parl/(Rindex2*cost1+Rindex1*cost2);
                                                   >> 1160               E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
                                                   >> 1161               s2 = Rindex2*cost2*E2_total;
                                                   >> 1162 
                                                   >> 1163               if (theTransmittance > 0) TransCoeff = theTransmittance;
                                                   >> 1164               else if (cost1 != 0.0) TransCoeff = s2/s1;
                                                   >> 1165               else TransCoeff = 0.0;
                                                   >> 1166 
                                                   >> 1167               if ( !G4BooleanRand(TransCoeff) ) {
                                                   >> 1168 
                                                   >> 1169                  // Simulate reflection
                                                   >> 1170 
                                                   >> 1171                  if (Swap) Swap = !Swap;
                                                   >> 1172 
                                                   >> 1173                  theStatus = FresnelReflection;
                                                   >> 1174 
                                                   >> 1175                  if ( !SurfaceRoughnessCriterionPass ) theStatus =
                                                   >> 1176                                                           LambertianReflection;
                                                   >> 1177 
                                                   >> 1178                  if ( theModel == unified && theFinish != polished )
                                                   >> 1179                                                      ChooseReflection();
                                                   >> 1180 
                                                   >> 1181                  if ( theStatus == LambertianReflection ) {
                                                   >> 1182                     DoReflection();
                                                   >> 1183                  }
                                                   >> 1184                  else if ( theStatus == BackScattering ) {
                                                   >> 1185                     NewMomentum = -OldMomentum;
                                                   >> 1186                     NewPolarization = -OldPolarization;
                                                   >> 1187                  }
                                                   >> 1188                  else {
                                                   >> 1189 
                                                   >> 1190                     PdotN = OldMomentum * theFacetNormal;
                                                   >> 1191                     NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
                                                   >> 1192 
                                                   >> 1193                     if (sint1 > 0.0) {   // incident ray oblique
                                                   >> 1194 
                                                   >> 1195                        E2_parl   = Rindex2*E2_parl/Rindex1 - E1_parl;
                                                   >> 1196                        E2_perp   = E2_perp - E1_perp;
                                                   >> 1197                        E2_total  = E2_perp*E2_perp + E2_parl*E2_parl;
                                                   >> 1198                        A_paral   = NewMomentum.cross(A_trans);
                                                   >> 1199                        A_paral   = A_paral.unit();
                                                   >> 1200                        E2_abs    = std::sqrt(E2_total);
                                                   >> 1201                        C_parl    = E2_parl/E2_abs;
                                                   >> 1202                        C_perp    = E2_perp/E2_abs;
                                                   >> 1203 
                                                   >> 1204                        NewPolarization = C_parl*A_paral + C_perp*A_trans;
                                                   >> 1205 
                                                   >> 1206                     }
                                                   >> 1207 
                                                   >> 1208                     else {               // incident ray perpendicular
                                                   >> 1209 
                                                   >> 1210                        if (Rindex2 > Rindex1) {
                                                   >> 1211                           NewPolarization = - OldPolarization;
                                                   >> 1212                        }
                                                   >> 1213                        else {
                                                   >> 1214                           NewPolarization =   OldPolarization;
                                                   >> 1215                        }
                                                   >> 1216 
                                                   >> 1217                     }
                                                   >> 1218                  }
                                                   >> 1219               }
                                                   >> 1220               else { // photon gets transmitted
                                                   >> 1221 
                                                   >> 1222                 // Simulate transmission/refraction
                                                   >> 1223 
                                                   >> 1224                 Inside = !Inside;
                                                   >> 1225                 Through = true;
                                                   >> 1226                 theStatus = FresnelRefraction;
                                                   >> 1227 
                                                   >> 1228                 if (sint1 > 0.0) {      // incident ray oblique
                                                   >> 1229 
                                                   >> 1230                    alpha = cost1 - cost2*(Rindex2/Rindex1);
                                                   >> 1231                    NewMomentum = OldMomentum + alpha*theFacetNormal;
                                                   >> 1232                    NewMomentum = NewMomentum.unit();
                                                   >> 1233 //                   PdotN = -cost2;
                                                   >> 1234                    A_paral = NewMomentum.cross(A_trans);
                                                   >> 1235                    A_paral = A_paral.unit();
                                                   >> 1236                    E2_abs     = std::sqrt(E2_total);
                                                   >> 1237                    C_parl     = E2_parl/E2_abs;
                                                   >> 1238                    C_perp     = E2_perp/E2_abs;
                                                   >> 1239 
                                                   >> 1240                    NewPolarization = C_parl*A_paral + C_perp*A_trans;
                                                   >> 1241 
                                                   >> 1242                 }
                                                   >> 1243                 else {                  // incident ray perpendicular
                                                   >> 1244 
                                                   >> 1245                    NewMomentum = OldMomentum;
                                                   >> 1246                    NewPolarization = OldPolarization;
                                                   >> 1247 
                                                   >> 1248                 }
                                                   >> 1249               }
                                                   >> 1250            }
                                                   >> 1251 
                                                   >> 1252            OldMomentum = NewMomentum.unit();
                                                   >> 1253            OldPolarization = NewPolarization.unit();
                                                   >> 1254 
                                                   >> 1255            if (theStatus == FresnelRefraction) {
                                                   >> 1256               Done = (NewMomentum * theGlobalNormal <= 0.0);
                                                   >> 1257            } 
                                                   >> 1258            else {
                                                   >> 1259               Done = (NewMomentum * theGlobalNormal >= -kCarTolerance);
                                                   >> 1260      }
1309                                                  1261 
1310   if(inside && !swap)                         << 1262         // Loop checking, 13-Aug-2015, Peter Gumplinger
1311   {                                           << 1263   } while (!Done);
1312     if(fFinish == polishedbackpainted || fFin << 
1313     {                                         << 
1314       G4double rand = G4UniformRand();        << 
1315       if(rand > fReflectivity + fTransmittanc << 
1316       {                                       << 
1317         DoAbsorption();                       << 
1318       }                                       << 
1319       else if(rand > fReflectivity)           << 
1320       {                                       << 
1321         fStatus          = Transmission;      << 
1322         fNewMomentum     = fOldMomentum;      << 
1323         fNewPolarization = fOldPolarization;  << 
1324       }                                       << 
1325       else                                    << 
1326       {                                       << 
1327         if(fStatus != FresnelRefraction)      << 
1328         {                                     << 
1329           fGlobalNormal = -fGlobalNormal;     << 
1330         }                                     << 
1331         else                                  << 
1332         {                                     << 
1333           swap = !swap;                       << 
1334           G4SwapPtr(fMaterial1, fMaterial2);  << 
1335           G4SwapObj(&fRindex1, &fRindex2);    << 
1336         }                                     << 
1337         if(fFinish == groundbackpainted)      << 
1338           fStatus = LambertianReflection;     << 
1339                                                  1264 
1340         DoReflection();                       << 1265         if (Inside && !Swap) {
                                                   >> 1266           if( theFinish == polishedbackpainted ||
                                                   >> 1267               theFinish == groundbackpainted ) {
                                                   >> 1268 
                                                   >> 1269               G4double rand = G4UniformRand();
                                                   >> 1270               if ( rand > theReflectivity ) {
                                                   >> 1271                  if (rand > theReflectivity + theTransmittance) {
                                                   >> 1272                     DoAbsorption();
                                                   >> 1273                  } else {
                                                   >> 1274                     theStatus = Transmission;
                                                   >> 1275                     NewMomentum = OldMomentum;
                                                   >> 1276                     NewPolarization = OldPolarization;
                                                   >> 1277                  }
                                                   >> 1278               }
                                                   >> 1279         else {
                                                   >> 1280                  if (theStatus != FresnelRefraction ) {
                                                   >> 1281                     theGlobalNormal = -theGlobalNormal;
                                                   >> 1282                  }
                                                   >> 1283                  else {
                                                   >> 1284                     Swap = !Swap;
                                                   >> 1285                     G4SwapPtr(Material1,Material2);
                                                   >> 1286                     G4SwapObj(&Rindex1,&Rindex2);
                                                   >> 1287                  }
                                                   >> 1288                  if ( theFinish == groundbackpainted )
                                                   >> 1289                                         theStatus = LambertianReflection;
1341                                                  1290 
1342         fGlobalNormal = -fGlobalNormal;       << 1291                  DoReflection();
1343         fOldMomentum  = fNewMomentum;         << 
1344                                                  1292 
1345         goto leap;                            << 1293                  theGlobalNormal = -theGlobalNormal;
1346       }                                       << 1294                  OldMomentum = NewMomentum;
1347     }                                         << 1295 
1348   }                                           << 1296                  goto leap;
                                                   >> 1297               }
                                                   >> 1298           }
                                                   >> 1299         }
1349 }                                                1300 }
1350                                                  1301 
1351 //....oooOO0OOooo........oooOO0OOooo........o << 1302 // GetMeanFreePath
1352 G4double G4OpBoundaryProcess::GetMeanFreePath << 1303 // ---------------
                                                   >> 1304 //
                                                   >> 1305 G4double G4OpBoundaryProcess::GetMeanFreePath(const G4Track& ,
                                                   >> 1306                                               G4double ,
1353                                                  1307                                               G4ForceCondition* condition)
1354 {                                                1308 {
1355   *condition = Forced;                           1309   *condition = Forced;
                                                   >> 1310 
1356   return DBL_MAX;                                1311   return DBL_MAX;
1357 }                                                1312 }
1358                                                  1313 
1359 //....oooOO0OOooo........oooOO0OOooo........o << 1314 G4double G4OpBoundaryProcess::GetIncidentAngle() 
1360 G4double G4OpBoundaryProcess::GetIncidentAngl << 
1361 {                                                1315 {
1362   return pi - std::acos(fOldMomentum * fFacet << 1316   G4double PdotN = OldMomentum * theFacetNormal;
1363                         (fOldMomentum.mag() * << 1317   G4double magP= OldMomentum.mag();
                                                   >> 1318   G4double magN= theFacetNormal.mag();
                                                   >> 1319   G4double incidentangle = pi - std::acos(PdotN/(magP*magN));
                                                   >> 1320 
                                                   >> 1321   return incidentangle;
1364 }                                                1322 }
1365                                                  1323 
1366 //....oooOO0OOooo........oooOO0OOooo........o << 
1367 G4double G4OpBoundaryProcess::GetReflectivity    1324 G4double G4OpBoundaryProcess::GetReflectivity(G4double E1_perp,
1368                                                  1325                                               G4double E1_parl,
1369                                                  1326                                               G4double incidentangle,
1370                                               << 1327                                               G4double RealRindex,
1371                                               << 1328                                               G4double ImaginaryRindex)
1372 {                                                1329 {
1373   G4complex reflectivity, reflectivity_TE, re << 1330   G4complex Reflectivity, Reflectivity_TE, Reflectivity_TM;
1374   G4complex N1(fRindex1, 0.), N2(realRindex,  << 1331   G4complex N1(Rindex1, 0), N2(RealRindex, ImaginaryRindex);
1375   G4complex cosPhi;                           << 1332   G4complex CosPhi;
1376                                                  1333 
1377   G4complex u(1., 0.);  // unit number 1      << 1334   G4complex u(1,0);           //unit number 1
1378                                                  1335 
1379   G4complex numeratorTE;  // E1_perp=1 E1_par << 1336   G4complex numeratorTE;      // E1_perp=1 E1_parl=0 -> TE polarization
1380   G4complex numeratorTM;  // E1_parl=1 E1_per << 1337   G4complex numeratorTM;      // E1_parl=1 E1_perp=0 -> TM polarization
1381   G4complex denominatorTE, denominatorTM;        1338   G4complex denominatorTE, denominatorTM;
1382   G4complex rTM, rTE;                            1339   G4complex rTM, rTE;
1383                                                  1340 
1384   G4MaterialPropertiesTable* MPT = fMaterial1 << 1341   G4MaterialPropertiesTable* aMaterialPropertiesTable =
1385   G4MaterialPropertyVector* ppR  = MPT->GetPr << 1342                                     Material1->GetMaterialPropertiesTable();
1386   G4MaterialPropertyVector* ppI  = MPT->GetPr << 1343   G4MaterialPropertyVector* aPropertyPointerR =
1387   if(ppR && ppI)                              << 1344                       aMaterialPropertiesTable->GetProperty(kREALRINDEX);
1388   {                                           << 1345   G4MaterialPropertyVector* aPropertyPointerI =
1389     G4double rRindex = ppR->Value(fPhotonMome << 1346                       aMaterialPropertiesTable->GetProperty(kIMAGINARYRINDEX);
1390     G4double iRindex = ppI->Value(fPhotonMome << 1347   if (aPropertyPointerR && aPropertyPointerI) {
1391     N1               = G4complex(rRindex, iRi << 1348      G4double RRindex = aPropertyPointerR->Value(thePhotonMomentum);
                                                   >> 1349      G4double IRindex = aPropertyPointerI->Value(thePhotonMomentum);
                                                   >> 1350      N1 = G4complex(RRindex,IRindex);
1392   }                                              1351   }
1393                                                  1352 
1394   // Following two equations, rTM and rTE, ar    1353   // Following two equations, rTM and rTE, are from: "Introduction To Modern
1395   // Optics" written by Fowles                   1354   // Optics" written by Fowles
1396   cosPhi = std::sqrt(u - ((std::sin(incidenta << 
1397                           (N1 * N1) / (N2 * N << 
1398                                                  1355 
1399   numeratorTE   = N1 * std::cos(incidentangle << 1356   CosPhi=std::sqrt(u-((std::sin(incidentangle)*std::sin(incidentangle))*(N1*N1)/(N2*N2)));
1400   denominatorTE = N1 * std::cos(incidentangle << 
1401   rTE           = numeratorTE / denominatorTE << 
1402                                               << 
1403   numeratorTM   = N2 * std::cos(incidentangle << 
1404   denominatorTM = N2 * std::cos(incidentangle << 
1405   rTM           = numeratorTM / denominatorTM << 
1406                                                  1357 
1407   // This is my (PG) calculaton for reflectiv << 1358   numeratorTE   = N1*std::cos(incidentangle) - N2*CosPhi;
                                                   >> 1359   denominatorTE = N1*std::cos(incidentangle) + N2*CosPhi;
                                                   >> 1360   rTE = numeratorTE/denominatorTE;
                                                   >> 1361 
                                                   >> 1362   numeratorTM   = N2*std::cos(incidentangle) - N1*CosPhi;
                                                   >> 1363   denominatorTM = N2*std::cos(incidentangle) + N1*CosPhi;
                                                   >> 1364   rTM = numeratorTM/denominatorTM;
                                                   >> 1365 
                                                   >> 1366   // This is my calculaton for reflectivity on a metalic surface
1408   // depending on the fraction of TE and TM p    1367   // depending on the fraction of TE and TM polarization
1409   // when TE polarization, E1_parl=0 and E1_p    1368   // when TE polarization, E1_parl=0 and E1_perp=1, R=abs(rTE)^2 and
1410   // when TM polarization, E1_parl=1 and E1_p    1369   // when TM polarization, E1_parl=1 and E1_perp=0, R=abs(rTM)^2
1411                                                  1370 
1412   reflectivity_TE = (rTE * conj(rTE)) * (E1_p << 1371   Reflectivity_TE =  (rTE*conj(rTE))*(E1_perp*E1_perp)
1413                     (E1_perp * E1_perp + E1_p << 1372                     / (E1_perp*E1_perp + E1_parl*E1_parl);
1414   reflectivity_TM = (rTM * conj(rTM)) * (E1_p << 1373   Reflectivity_TM =  (rTM*conj(rTM))*(E1_parl*E1_parl)
1415                     (E1_perp * E1_perp + E1_p << 1374                     / (E1_perp*E1_perp + E1_parl*E1_parl);
1416   reflectivity = reflectivity_TE + reflectivi << 1375   Reflectivity    = Reflectivity_TE + Reflectivity_TM;
1417                                               << 1376 
1418   do                                          << 1377   do {
1419   {                                           << 1378      if(G4UniformRand()*real(Reflectivity) > real(Reflectivity_TE))
1420     if(G4UniformRand() * real(reflectivity) > << 1379        {iTE = -1;}else{iTE = 1;}
1421     {                                         << 1380      if(G4UniformRand()*real(Reflectivity) > real(Reflectivity_TM))
1422       f_iTE = -1;                             << 1381        {iTM = -1;}else{iTM = 1;}
1423     }                                         << 
1424     else                                      << 
1425     {                                         << 
1426       f_iTE = 1;                              << 
1427     }                                         << 
1428     if(G4UniformRand() * real(reflectivity) > << 
1429     {                                         << 
1430       f_iTM = -1;                             << 
1431     }                                         << 
1432     else                                      << 
1433     {                                         << 
1434       f_iTM = 1;                              << 
1435     }                                         << 
1436     // Loop checking, 13-Aug-2015, Peter Gump    1382     // Loop checking, 13-Aug-2015, Peter Gumplinger
1437   } while(f_iTE < 0 && f_iTM < 0);            << 1383   } while(iTE<0&&iTM<0);
                                                   >> 1384 
                                                   >> 1385   return real(Reflectivity);
1438                                                  1386 
1439   return real(reflectivity);                  << 
1440 }                                                1387 }
1441                                                  1388 
1442 //....oooOO0OOooo........oooOO0OOooo........o << 
1443 void G4OpBoundaryProcess::CalculateReflectivi    1389 void G4OpBoundaryProcess::CalculateReflectivity()
1444 {                                                1390 {
1445   G4double realRindex = fRealRIndexMPV->Value << 1391   G4double RealRindex =
1446   G4double imaginaryRindex =                  << 1392            PropertyPointer1->Value(thePhotonMomentum);
1447     fImagRIndexMPV->Value(fPhotonMomentum, id << 1393   G4double ImaginaryRindex =
                                                   >> 1394            PropertyPointer2->Value(thePhotonMomentum);
1448                                                  1395 
1449   // calculate FacetNormal                       1396   // calculate FacetNormal
1450   if(fFinish == ground)                       << 1397   if ( theFinish == ground ) {
1451   {                                           << 1398      theFacetNormal =
1452     fFacetNormal = GetFacetNormal(fOldMomentu << 1399                GetFacetNormal(OldMomentum, theGlobalNormal);
1453   }                                           << 1400   } else {
1454   else                                        << 1401      theFacetNormal = theGlobalNormal;
1455   {                                           << 
1456     fFacetNormal = fGlobalNormal;             << 
1457   }                                              1402   }
1458                                                  1403 
1459   G4double cost1 = -fOldMomentum * fFacetNorm << 1404   G4double PdotN = OldMomentum * theFacetNormal;
1460   if(std::abs(cost1) < 1.0 - fCarTolerance)   << 1405   cost1 = -PdotN;
1461   {                                           << 1406 
1462     fSint1 = std::sqrt(1. - cost1 * cost1);   << 1407   if (std::abs(cost1) < 1.0 - kCarTolerance) {
1463   }                                           << 1408      sint1 = std::sqrt(1. - cost1*cost1);
1464   else                                        << 1409   } else {
1465   {                                           << 1410      sint1 = 0.0;
1466     fSint1 = 0.0;                             << 
1467   }                                              1411   }
1468                                                  1412 
1469   G4ThreeVector A_trans, A_paral, E1pp, E1pl;    1413   G4ThreeVector A_trans, A_paral, E1pp, E1pl;
1470   G4double E1_perp, E1_parl;                     1414   G4double E1_perp, E1_parl;
1471                                                  1415 
1472   if(fSint1 > 0.0)                            << 1416   if (sint1 > 0.0 ) {
1473   {                                           << 1417      A_trans = OldMomentum.cross(theFacetNormal);
1474     A_trans = (fOldMomentum.cross(fFacetNorma << 1418      A_trans = A_trans.unit();
1475     E1_perp = fOldPolarization * A_trans;     << 1419      E1_perp = OldPolarization * A_trans;
1476     E1pp    = E1_perp * A_trans;              << 1420      E1pp    = E1_perp * A_trans;
1477     E1pl    = fOldPolarization - E1pp;        << 1421      E1pl    = OldPolarization - E1pp;
1478     E1_parl = E1pl.mag();                     << 1422      E1_parl = E1pl.mag();
1479   }                                           << 1423   }
1480   else                                        << 1424   else {
1481   {                                           << 1425      A_trans  = OldPolarization;
1482     A_trans = fOldPolarization;               << 1426      // Here we Follow Jackson's conventions and we set the
1483     // Here we Follow Jackson's conventions a << 1427      // parallel component = 1 in case of a ray perpendicular
1484     // component = 1 in case of a ray perpend << 1428      // to the surface
1485     E1_perp = 0.0;                            << 1429      E1_perp  = 0.0;
1486     E1_parl = 1.0;                            << 1430      E1_parl  = 1.0;
1487   }                                              1431   }
1488                                                  1432 
                                                   >> 1433   //calculate incident angle
1489   G4double incidentangle = GetIncidentAngle()    1434   G4double incidentangle = GetIncidentAngle();
1490                                                  1435 
1491   // calculate the reflectivity depending on  << 1436   //calculate the reflectivity depending on incident angle,
1492   // polarization and complex refractive      << 1437   //polarization and complex refractive
1493   fReflectivity = GetReflectivity(E1_perp, E1 << 1438 
1494                                   imaginaryRi << 1439   theReflectivity =
                                                   >> 1440              GetReflectivity(E1_perp, E1_parl, incidentangle,
                                                   >> 1441                                                  RealRindex, ImaginaryRindex);
1495 }                                                1442 }
1496                                                  1443 
1497 //....oooOO0OOooo........oooOO0OOooo........o << 
1498 G4bool G4OpBoundaryProcess::InvokeSD(const G4    1444 G4bool G4OpBoundaryProcess::InvokeSD(const G4Step* pStep)
1499 {                                                1445 {
1500   G4Step aStep = *pStep;                         1446   G4Step aStep = *pStep;
1501   aStep.AddTotalEnergyDeposit(fPhotonMomentum << 
1502                                               << 
1503   G4VSensitiveDetector* sd = aStep.GetPostSte << 
1504   if(sd != nullptr)                           << 
1505     return sd->Hit(&aStep);                   << 
1506   else                                        << 
1507     return false;                             << 
1508 }                                             << 
1509                                               << 
1510 //....oooOO0OOooo........oooOO0OOooo........o << 
1511 inline void G4OpBoundaryProcess::SetInvokeSD( << 
1512 {                                             << 
1513   fInvokeSD = flag;                           << 
1514   G4OpticalParameters::Instance()->SetBoundar << 
1515 }                                             << 
1516                                               << 
1517 //....oooOO0OOooo........oooOO0OOooo........o << 
1518 void G4OpBoundaryProcess::SetVerboseLevel(G4i << 
1519 {                                             << 
1520   verboseLevel = verbose;                     << 
1521   G4OpticalParameters::Instance()->SetBoundar << 
1522 }                                             << 
1523                                                  1447 
1524 //....oooOO0OOooo........oooOO0OOooo........o << 1448   aStep.AddTotalEnergyDeposit(thePhotonMomentum);
1525 void G4OpBoundaryProcess::CoatedDielectricDie << 
1526 {                                             << 
1527   G4MaterialPropertyVector* pp = nullptr;     << 
1528                                               << 
1529   G4MaterialPropertiesTable* MPT = fMaterial2 << 
1530   if((pp = MPT->GetProperty(kRINDEX)))        << 
1531   {                                           << 
1532     fRindex2 = pp->Value(fPhotonMomentum, idx << 
1533   }                                           << 
1534                                               << 
1535   MPT = fOpticalSurface->GetMaterialPropertie << 
1536   if((pp = MPT->GetProperty(kCOATEDRINDEX)))  << 
1537   {                                           << 
1538     fCoatedRindex = pp->Value(fPhotonMomentum << 
1539   }                                           << 
1540   if(MPT->ConstPropertyExists(kCOATEDTHICKNES << 
1541   {                                           << 
1542     fCoatedThickness = MPT->GetConstProperty( << 
1543   }                                           << 
1544   if(MPT->ConstPropertyExists(kCOATEDFRUSTRAT << 
1545   {                                           << 
1546     fCoatedFrustratedTransmission =           << 
1547       (G4bool)MPT->GetConstProperty(kCOATEDFR << 
1548   }                                           << 
1549                                                  1449 
1550   G4double sintTL;                            << 1450   G4VSensitiveDetector* sd = aStep.GetPostStepPoint()->GetSensitiveDetector();
1551   G4double wavelength = h_Planck * c_light /  << 1451   if (sd) return sd->Hit(&aStep);
1552   G4double PdotN;                             << 1452   else return false;
1553   G4double E1_perp, E1_parl;                  << 
1554   G4double s1, E2_perp, E2_parl, E2_total, tr << 
1555   G4double E2_abs, C_parl, C_perp;            << 
1556   G4double alpha;                             << 
1557   G4ThreeVector A_trans, A_paral, E1pp, E1pl; << 
1558   //G4bool Inside  = false;                   << 
1559   //G4bool Swap    = false;                   << 
1560   G4bool through = false;                     << 
1561   G4bool done    = false;                     << 
1562                                               << 
1563   do {                                        << 
1564     if (through)                              << 
1565     {                                         << 
1566       //Swap = !Swap;                         << 
1567       through = false;                        << 
1568       fGlobalNormal = -fGlobalNormal;         << 
1569       G4SwapPtr(fMaterial1, fMaterial2);      << 
1570       G4SwapObj(&fRindex1, &fRindex2);        << 
1571     }                                         << 
1572                                               << 
1573     if(fFinish == polished)                   << 
1574     {                                         << 
1575       fFacetNormal = fGlobalNormal;           << 
1576     }                                         << 
1577     else                                      << 
1578     {                                         << 
1579       fFacetNormal = GetFacetNormal(fOldMomen << 
1580     }                                         << 
1581                                               << 
1582     PdotN = fOldMomentum * fFacetNormal;      << 
1583     G4double cost1 = -PdotN;                  << 
1584     G4double sint2, cost2 = 0.;               << 
1585                                               << 
1586     if (std::abs(cost1) < 1.0 - fCarTolerance << 
1587     {                                         << 
1588       fSint1 = std::sqrt(1. - cost1 * cost1); << 
1589       sint2 = fSint1 * fRindex1 / fRindex2;   << 
1590       sintTL = fSint1 * fRindex1 / fCoatedRin << 
1591     } else                                    << 
1592     {                                         << 
1593       fSint1 = 0.0;                           << 
1594       sint2 = 0.0;                            << 
1595       sintTL = 0.0;                           << 
1596     }                                         << 
1597                                               << 
1598     if (fSint1 > 0.0)                         << 
1599     {                                         << 
1600       A_trans = fOldMomentum.cross(fFacetNorm << 
1601       A_trans = A_trans.unit();               << 
1602       E1_perp = fOldPolarization * A_trans;   << 
1603       E1pp = E1_perp * A_trans;               << 
1604       E1pl = fOldPolarization - E1pp;         << 
1605       E1_parl = E1pl.mag();                   << 
1606     }                                         << 
1607     else                                      << 
1608     {                                         << 
1609       A_trans = fOldPolarization;             << 
1610       E1_perp = 0.0;                          << 
1611       E1_parl = 1.0;                          << 
1612     }                                         << 
1613                                               << 
1614     s1 = fRindex1 * cost1;                    << 
1615                                               << 
1616     if (cost1 > 0.0)                          << 
1617     {                                         << 
1618       cost2 = std::sqrt(1. - sint2 * sint2);  << 
1619     }                                         << 
1620     else                                      << 
1621     {                                         << 
1622       cost2 = -std::sqrt(1. - sint2 * sint2); << 
1623     }                                         << 
1624                                               << 
1625     transCoeff = 0.0;                         << 
1626                                               << 
1627     if (sintTL >= 1.0)                        << 
1628     { // --> Angle > Angle Limit              << 
1629       //Swap = false;                         << 
1630     }                                         << 
1631     E2_perp = 2. * s1 * E1_perp / (fRindex1 * << 
1632     E2_parl = 2. * s1 * E1_parl / (fRindex2 * << 
1633     E2_total = E2_perp * E2_perp + E2_parl *  << 
1634                                               << 
1635     transCoeff = 1. - GetReflectivityThroughT << 
1636                         sintTL, E1_perp, E1_p << 
1637     if (!G4BooleanRand(transCoeff))           << 
1638     {                                         << 
1639       if(verboseLevel > 2)                    << 
1640         G4cout << "Reflection from " << fMate << 
1641                << fMaterial2->GetName() << G4 << 
1642                                               << 
1643       //Swap = false;                         << 
1644                                               << 
1645       if (sintTL >= 1.0)                      << 
1646       {                                       << 
1647         fStatus = TotalInternalReflection;    << 
1648       }                                       << 
1649       else                                    << 
1650       {                                       << 
1651         fStatus = CoatedDielectricReflection; << 
1652       }                                       << 
1653                                               << 
1654       PdotN = fOldMomentum * fFacetNormal;    << 
1655       fNewMomentum = fOldMomentum - (2. * Pdo << 
1656                                               << 
1657       if (fSint1 > 0.0) {   // incident ray o << 
1658                                               << 
1659         E2_parl = fRindex2 * E2_parl / fRinde << 
1660         E2_perp = E2_perp - E1_perp;          << 
1661         E2_total = E2_perp * E2_perp + E2_par << 
1662         A_paral = fNewMomentum.cross(A_trans) << 
1663         A_paral = A_paral.unit();             << 
1664         E2_abs = std::sqrt(E2_total);         << 
1665         C_parl = E2_parl / E2_abs;            << 
1666         C_perp = E2_perp / E2_abs;            << 
1667                                               << 
1668         fNewPolarization = C_parl * A_paral + << 
1669                                               << 
1670       }                                       << 
1671       else                                    << 
1672       {               // incident ray perpend << 
1673         if (fRindex2 > fRindex1)              << 
1674         {                                     << 
1675           fNewPolarization = -fOldPolarizatio << 
1676         }                                     << 
1677         else                                  << 
1678         {                                     << 
1679           fNewPolarization = fOldPolarization << 
1680         }                                     << 
1681       }                                       << 
1682                                               << 
1683     } else { // photon gets transmitted       << 
1684       if (verboseLevel > 2)                   << 
1685         G4cout << "Transmission from " << fMa << 
1686                << fMaterial2->GetName() << G4 << 
1687                                               << 
1688       //Inside = !Inside;                     << 
1689       through = true;                         << 
1690                                               << 
1691       if (fEfficiency > 0.)                   << 
1692       {                                       << 
1693         DoAbsorption();                       << 
1694         return;                               << 
1695       }                                       << 
1696       else                                    << 
1697       {                                       << 
1698         if (sintTL >= 1.0)                    << 
1699         {                                     << 
1700           fStatus = CoatedDielectricFrustrate << 
1701         }                                     << 
1702         else                                  << 
1703         {                                     << 
1704           fStatus = CoatedDielectricRefractio << 
1705         }                                     << 
1706                                               << 
1707         if (fSint1 > 0.0) {      // incident  << 
1708                                               << 
1709           alpha = cost1 - cost2 * (fRindex2 / << 
1710           fNewMomentum = fOldMomentum + alpha << 
1711           fNewMomentum = fNewMomentum.unit(); << 
1712           A_paral = fNewMomentum.cross(A_tran << 
1713           A_paral = A_paral.unit();           << 
1714           E2_abs = std::sqrt(E2_total);       << 
1715           C_parl = E2_parl / E2_abs;          << 
1716           C_perp = E2_perp / E2_abs;          << 
1717                                               << 
1718           fNewPolarization = C_parl * A_paral << 
1719                                               << 
1720         }                                     << 
1721         else                                  << 
1722         {                  // incident ray pe << 
1723           fNewMomentum = fOldMomentum;        << 
1724           fNewPolarization = fOldPolarization << 
1725         }                                     << 
1726       }                                       << 
1727     }                                         << 
1728                                               << 
1729     fOldMomentum = fNewMomentum.unit();       << 
1730     fOldPolarization = fNewPolarization.unit( << 
1731     if ((fStatus == CoatedDielectricFrustrate << 
1732         (fStatus == CoatedDielectricRefractio << 
1733     {                                         << 
1734       done = (fNewMomentum * fGlobalNormal <= << 
1735     }                                         << 
1736     else                                      << 
1737     {                                         << 
1738       done = (fNewMomentum * fGlobalNormal >= << 
1739     }                                         << 
1740                                               << 
1741   } while (!done);                            << 
1742 }                                             << 
1743                                               << 
1744 //....oooOO0OOooo........oooOO0OOooo........o << 
1745 G4double G4OpBoundaryProcess::GetReflectivity << 
1746                    G4double E1_perp,          << 
1747                    G4double E1_parl,          << 
1748                    G4double wavelength, G4dou << 
1749   G4complex Reflectivity, Reflectivity_TE, Re << 
1750   G4double gammaTL, costTL;                   << 
1751                                               << 
1752   G4complex i(0, 1);                          << 
1753   G4complex rTM, rTE;                         << 
1754   G4complex r1toTL, rTLto2;                   << 
1755   G4double k0 = 2 * pi / wavelength;          << 
1756                                               << 
1757   // Angle > Angle limit                      << 
1758   if (sinTL >= 1.0) {                         << 
1759     if (fCoatedFrustratedTransmission) { //Fr << 
1760                                               << 
1761       if (cost1 > 0.0)                        << 
1762       {                                       << 
1763         gammaTL = std::sqrt(fRindex1 * fRinde << 
1764                    fCoatedRindex * fCoatedRin << 
1765       }                                       << 
1766       else                                    << 
1767       {                                       << 
1768         gammaTL = -std::sqrt(fRindex1 * fRind << 
1769                    fCoatedRindex * fCoatedRin << 
1770       }                                       << 
1771                                               << 
1772       // TE                                   << 
1773       r1toTL = (fRindex1 * cost1 - i * gammaT << 
1774       rTLto2 = (i * gammaTL - fRindex2 * cost << 
1775       if (cost1 != 0.0)                       << 
1776       {                                       << 
1777         rTE = (r1toTL + rTLto2 * std::exp(-2  << 
1778                  (1.0 + r1toTL * rTLto2 * std << 
1779       }                                       << 
1780       // TM                                   << 
1781       r1toTL = (fRindex1 * i * gammaTL - fCoa << 
1782                   (fRindex1 * i * gammaTL + f << 
1783       rTLto2 = (fCoatedRindex * fCoatedRindex << 
1784                   (fCoatedRindex * fCoatedRin << 
1785       if (cost1 != 0.0)                       << 
1786       {                                       << 
1787         rTM = (r1toTL + rTLto2 * std::exp(-2  << 
1788                  (1.0 + r1toTL * rTLto2 * std << 
1789       }                                       << 
1790     }                                         << 
1791     else                                      << 
1792     { //Total reflection                      << 
1793       return(1.);                             << 
1794     }                                         << 
1795   }                                           << 
1796                                               << 
1797   // Angle <= Angle limit                     << 
1798   else //if (sinTL < 1.0)                     << 
1799   {                                           << 
1800     if (cost1 > 0.0)                          << 
1801     {                                         << 
1802       costTL = std::sqrt(1. - sinTL * sinTL); << 
1803     }                                         << 
1804     else                                      << 
1805     {                                         << 
1806       costTL = -std::sqrt(1. - sinTL * sinTL) << 
1807     }                                         << 
1808     // TE                                     << 
1809     r1toTL = (fRindex1 * cost1 - fCoatedRinde << 
1810     rTLto2 = (fCoatedRindex * costTL - fRinde << 
1811     if (cost1 != 0.0)                         << 
1812     {                                         << 
1813       rTE = (r1toTL + rTLto2 * std::exp(2.0 * << 
1814             (1.0 + r1toTL * rTLto2 * std::exp << 
1815     }                                         << 
1816     // TM                                     << 
1817     r1toTL = (fRindex1 * costTL - fCoatedRind << 
1818     rTLto2 = (fCoatedRindex * cost2 - fRindex << 
1819     if (cost1 != 0.0)                         << 
1820     {                                         << 
1821       rTM = (r1toTL + rTLto2 * std::exp(2.0 * << 
1822             (1.0 + r1toTL * rTLto2 * std::exp << 
1823     }                                         << 
1824   }                                           << 
1825                                               << 
1826   Reflectivity_TE = (rTE * conj(rTE)) * (E1_p << 
1827   Reflectivity_TM = (rTM * conj(rTM)) * (E1_p << 
1828   Reflectivity = Reflectivity_TE + Reflectivi << 
1829                                               << 
1830   return real(Reflectivity);                  << 
1831 }                                                1453 }
1832                                                  1454