Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4OpBoundaryProcess.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26////////////////////////////////////////////////////////////////////////
27// Optical Photon Boundary Process Class Implementation
28////////////////////////////////////////////////////////////////////////
29//
30// File: G4OpBoundaryProcess.cc
31// Description: Discrete Process -- reflection/refraction at
32// optical interfaces
33// Version: 1.1
34// Created: 1997-06-18
35// Modified: 1998-05-25 - Correct parallel component of polarization
36// (thanks to: Stefano Magni + Giovanni Pieri)
37// 1998-05-28 - NULL Rindex pointer before reuse
38// (thanks to: Stefano Magni)
39// 1998-06-11 - delete *sint1 in oblique reflection
40// (thanks to: Giovanni Pieri)
41// 1998-06-19 - move from GetLocalExitNormal() to the new
42// method: GetLocalExitNormal(&valid) to get
43// the surface normal in all cases
44// 1998-11-07 - NULL OpticalSurface pointer before use
45// comparison not sharp for: std::abs(cost1) < 1.0
46// remove sin1, sin2 in lines 556,567
47// (thanks to Stefano Magni)
48// 1999-10-10 - Accommodate changes done in DoAbsorption by
49// changing logic in DielectricMetal
50// 2001-10-18 - avoid Linux (gcc-2.95.2) warning about variables
51// might be used uninitialized in this function
52// moved E2_perp, E2_parl and E2_total out of 'if'
53// 2003-11-27 - Modified line 168-9 to reflect changes made to
54// G4OpticalSurface class ( by Fan Lei)
55// 2004-02-02 - Set theStatus = Undefined at start of DoIt
56// 2005-07-28 - add G4ProcessType to constructor
57// 2006-11-04 - add capability of calculating the reflectivity
58// off a metal surface by way of a complex index
59// of refraction - Thanks to Sehwook Lee and John
60// Hauptman (Dept. of Physics - Iowa State Univ.)
61// 2009-11-10 - add capability of simulating surface reflections
62// with Look-Up-Tables (LUT) containing measured
63// optical reflectance for a variety of surface
64// treatments - Thanks to Martin Janecek and
65// William Moses (Lawrence Berkeley National Lab.)
66// 2013-06-01 - add the capability of simulating the transmission
67// of a dichronic filter
68// 2017-02-24 - add capability of simulating surface reflections
69// with Look-Up-Tables (LUT) developed in DAVIS
70//
71// Author: Peter Gumplinger
72// adopted from work by Werner Keil - April 2/96
73//
74////////////////////////////////////////////////////////////////////////
75
76#include "G4ios.hh"
77#include "G4SystemOfUnits.hh"
79#include "G4OpProcessSubType.hh"
86
89
90//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
92 G4ProcessType type)
93 : G4VDiscreteProcess(processName, type)
94{
95 Initialise();
96
97 if(verboseLevel > 0)
98 {
99 G4cout << GetProcessName() << " is created " << G4endl;
100 }
102
103 theStatus = Undefined;
104 theModel = glisur;
105 theFinish = polished;
106 theReflectivity = 1.;
107 theEfficiency = 0.;
108 theTransmittance = 0.;
109 theSurfaceRoughness = 0.;
110 prob_sl = 0.;
111 prob_ss = 0.;
112 prob_bs = 0.;
113
114 fRealRIndexMPV = nullptr;
115 fImagRIndexMPV = nullptr;
116 Material1 = nullptr;
117 Material2 = nullptr;
118 OpticalSurface = nullptr;
120
121 iTE = iTM = 0;
122 thePhotonMomentum = 0.;
123 Rindex1 = Rindex2 = 1.;
124 cost1 = cost2 = sint1 = sint2 = 0.;
125 idx = idy = 0;
126 DichroicVector = nullptr;
127}
128
129//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
131
132//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
134{
135 Initialise();
136}
137
138//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
140{
144}
145
146//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
148 const G4Step& aStep)
149{
150 theStatus = Undefined;
153
154 // Get hyperStep from G4ParallelWorldProcess
155 // NOTE: PostSetpDoIt of this process to be invoked after
156 // G4ParallelWorldProcess!
157 const G4Step* pStep = &aStep;
159 if(hStep)
160 pStep = hStep;
161
162 G4bool isOnBoundary =
164 if(isOnBoundary)
165 {
166 Material1 = pStep->GetPreStepPoint()->GetMaterial();
167 Material2 = pStep->GetPostStepPoint()->GetMaterial();
168 }
169 else
170 {
171 theStatus = NotAtBoundary;
172 if(verboseLevel > 1)
173 BoundaryProcessVerbose();
174 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
175 }
176
179
180 if(verboseLevel > 1)
181 {
182 G4cout << " Photon at Boundary! " << G4endl;
183 if(thePrePV)
184 G4cout << " thePrePV: " << thePrePV->GetName() << G4endl;
185 if(thePostPV)
186 G4cout << " thePostPV: " << thePostPV->GetName() << G4endl;
187 }
188
189 if(aTrack.GetStepLength() <= kCarTolerance)
190 {
191 theStatus = StepTooSmall;
192 if(verboseLevel > 1)
193 BoundaryProcessVerbose();
194 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
195 }
196
197 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
198
199 thePhotonMomentum = aParticle->GetTotalMomentum();
200 OldMomentum = aParticle->GetMomentumDirection();
201 OldPolarization = aParticle->GetPolarization();
202
203 if(verboseLevel > 1)
204 {
205 G4cout << " Old Momentum Direction: " << OldMomentum << G4endl
206 << " Old Polarization: " << OldPolarization << G4endl;
207 }
208
209 G4ThreeVector theGlobalPoint = pStep->GetPostStepPoint()->GetPosition();
210 G4bool valid;
211
212 // ID of Navigator which limits step
216 theGlobalNormal = (iNav[hNavId])->GetGlobalExitNormal(theGlobalPoint, &valid);
217
218 if(valid)
219 {
220 theGlobalNormal = -theGlobalNormal;
221 }
222 else
223 {
225 ed << " G4OpBoundaryProcess/PostStepDoIt(): "
226 << " The Navigator reports that it returned an invalid normal" << G4endl;
228 "G4OpBoundaryProcess::PostStepDoIt", "OpBoun01", EventMustBeAborted, ed,
229 "Invalid Surface Normal - Geometry must return valid surface normal");
230 }
231
232 if(OldMomentum * theGlobalNormal > 0.0)
233 {
234#ifdef G4OPTICAL_DEBUG
236 ed << " G4OpBoundaryProcess/PostStepDoIt(): theGlobalNormal points in a "
237 "wrong direction. "
238 << G4endl
239 << " The momentum of the photon arriving at interface (oldMomentum)"
240 << " must exit the volume cross in the step. " << G4endl
241 << " So it MUST have dot < 0 with the normal that Exits the new "
242 "volume (globalNormal)."
243 << G4endl << " >> The dot product of oldMomentum and global Normal is "
244 << OldMomentum * theGlobalNormal << G4endl
245 << " Old Momentum (during step) = " << OldMomentum << G4endl
246 << " Global Normal (Exiting New Vol) = " << theGlobalNormal << G4endl
247 << G4endl;
248 G4Exception("G4OpBoundaryProcess::PostStepDoIt", "OpBoun02",
249 EventMustBeAborted, // Or JustWarning to see if it happens
250 // repeatedly on one ray
251 ed,
252 "Invalid Surface Normal - Geometry must return valid surface "
253 "normal pointing in the right direction");
254#else
255 theGlobalNormal = -theGlobalNormal;
256#endif
257 }
258
259 G4MaterialPropertyVector* RindexMPV = nullptr;
261 if(MPT)
262 {
263 RindexMPV = MPT->GetProperty(kRINDEX);
264 }
265 else
266 {
267 theStatus = NoRINDEX;
268 if(verboseLevel > 1)
269 BoundaryProcessVerbose();
272 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
273 }
274
275 if(RindexMPV)
276 {
277 Rindex1 = RindexMPV->Value(thePhotonMomentum, idx_rindex1);
278 }
279 else
280 {
281 theStatus = NoRINDEX;
282 if(verboseLevel > 1)
283 BoundaryProcessVerbose();
286 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
287 }
288
289 theReflectivity = 1.;
290 theEfficiency = 0.;
291 theTransmittance = 0.;
292 theSurfaceRoughness = 0.;
293 theModel = glisur;
294 theFinish = polished;
296
297 RindexMPV = nullptr;
298 OpticalSurface = nullptr;
299 G4LogicalSurface* Surface =
300 G4LogicalBorderSurface::GetSurface(thePrePV, thePostPV);
301
302 if(Surface == nullptr)
303 {
304 if(thePostPV->GetMotherLogical() == thePrePV->GetLogicalVolume())
305 {
307 if(Surface == nullptr)
308 {
309 Surface =
311 }
312 }
313 else
314 {
316 if(Surface == nullptr)
317 {
318 Surface =
320 }
321 }
322 }
323
324 if(Surface)
325 {
326 OpticalSurface =
327 dynamic_cast<G4OpticalSurface*>(Surface->GetSurfaceProperty());
328 }
329 if(OpticalSurface)
330 {
331 type = OpticalSurface->GetType();
332 theModel = OpticalSurface->GetModel();
333 theFinish = OpticalSurface->GetFinish();
334
336 OpticalSurface->GetMaterialPropertiesTable();
337 if(sMPT)
338 {
339 if(theFinish == polishedbackpainted || theFinish == groundbackpainted)
340 {
341 RindexMPV = sMPT->GetProperty(kRINDEX);
342 if(RindexMPV)
343 {
344 Rindex2 = RindexMPV->Value(thePhotonMomentum, idx_rindex_surface);
345 }
346 else
347 {
348 theStatus = NoRINDEX;
349 if(verboseLevel > 1)
350 BoundaryProcessVerbose();
353 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
354 }
355 }
356
357 fRealRIndexMPV = sMPT->GetProperty(kREALRINDEX);
358 fImagRIndexMPV = sMPT->GetProperty(kIMAGINARYRINDEX);
359 iTE = iTM = 1;
360
362 if((pp = sMPT->GetProperty(kREFLECTIVITY)))
363 {
364 theReflectivity = pp->Value(thePhotonMomentum, idx_reflect);
365 }
366 else if(fRealRIndexMPV && fImagRIndexMPV)
367 {
368 CalculateReflectivity();
369 }
370
371 if((pp = sMPT->GetProperty(kEFFICIENCY)))
372 {
373 theEfficiency = pp->Value(thePhotonMomentum, idx_eff);
374 }
375 if((pp = sMPT->GetProperty(kTRANSMITTANCE)))
376 {
377 theTransmittance = pp->Value(thePhotonMomentum, idx_trans);
378 }
380 {
381 theSurfaceRoughness = sMPT->GetConstProperty(kSURFACEROUGHNESS);
382 }
383
384 if(theModel == unified)
385 {
386 prob_sl = (pp = sMPT->GetProperty(kSPECULARLOBECONSTANT))
387 ? pp->Value(thePhotonMomentum, idx_lobe)
388 : 0.;
389 prob_ss = (pp = sMPT->GetProperty(kSPECULARSPIKECONSTANT))
390 ? pp->Value(thePhotonMomentum, idx_spike)
391 : 0.;
392 prob_bs = (pp = sMPT->GetProperty(kBACKSCATTERCONSTANT))
393 ? pp->Value(thePhotonMomentum, idx_back)
394 : 0.;
395 }
396 } // end of if(sMPT)
397 else if(theFinish == polishedbackpainted || theFinish == groundbackpainted)
398 {
401 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
402 }
403 } // end of if(OpticalSurface)
404
405 // DIELECTRIC-DIELECTRIC
406 if(type == dielectric_dielectric)
407 {
408 if(theFinish == polished || theFinish == ground)
409 {
410 if(Material1 == Material2)
411 {
412 theStatus = SameMaterial;
413 if(verboseLevel > 1)
414 BoundaryProcessVerbose();
415 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
416 }
417 MPT = Material2->GetMaterialPropertiesTable();
418 if(MPT)
419 {
420 RindexMPV = MPT->GetProperty(kRINDEX);
421 }
422 if(RindexMPV)
423 {
424 Rindex2 = RindexMPV->Value(thePhotonMomentum, idx_rindex2);
425 }
426 else
427 {
428 theStatus = NoRINDEX;
429 if(verboseLevel > 1)
430 BoundaryProcessVerbose();
433 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
434 }
435 }
436 if(theFinish == polishedbackpainted || theFinish == groundbackpainted)
437 {
438 DielectricDielectric();
439 }
440 else
441 {
442 G4double rand = G4UniformRand();
443 if(rand > theReflectivity + theTransmittance)
444 {
445 DoAbsorption();
446 }
447 else if(rand > theReflectivity)
448 {
449 theStatus = Transmission;
450 NewMomentum = OldMomentum;
451 NewPolarization = OldPolarization;
452 }
453 else
454 {
455 if(theFinish == polishedfrontpainted)
456 {
457 DoReflection();
458 }
459 else if(theFinish == groundfrontpainted)
460 {
461 theStatus = LambertianReflection;
462 DoReflection();
463 }
464 else
465 {
466 DielectricDielectric();
467 }
468 }
469 }
470 }
471 else if(type == dielectric_metal)
472 {
473 DielectricMetal();
474 }
475 else if(type == dielectric_LUT)
476 {
477 DielectricLUT();
478 }
479 else if(type == dielectric_LUTDAVIS)
480 {
481 DielectricLUTDAVIS();
482 }
483 else if(type == dielectric_dichroic)
484 {
485 DielectricDichroic();
486 }
487 else
488 {
490 ed << " PostStepDoIt(): Illegal boundary type." << G4endl;
491 G4Exception("G4OpBoundaryProcess", "OpBoun04", JustWarning, ed);
492 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
493 }
494
495 NewMomentum = NewMomentum.unit();
496 NewPolarization = NewPolarization.unit();
497
498 if(verboseLevel > 1)
499 {
500 G4cout << " New Momentum Direction: " << NewMomentum << G4endl
501 << " New Polarization: " << NewPolarization << G4endl;
502 BoundaryProcessVerbose();
503 }
504
506 aParticleChange.ProposePolarization(NewPolarization);
507
508 if(theStatus == FresnelRefraction || theStatus == Transmission)
509 {
510 G4MaterialPropertyVector* groupvel =
512 if(groupvel)
513 {
515 groupvel->Value(thePhotonMomentum, idx_groupvel));
516 }
517 }
518
519 if(theStatus == Detection && fInvokeSD)
520 InvokeSD(pStep);
521 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
522}
523
524//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
525void G4OpBoundaryProcess::BoundaryProcessVerbose() const
526{
527 G4cout << " *** ";
528 if(theStatus == Undefined)
529 G4cout << "Undefined";
530 else if(theStatus == Transmission)
531 G4cout << "Transmission";
532 else if(theStatus == FresnelRefraction)
533 G4cout << "FresnelRefraction";
534 else if(theStatus == FresnelReflection)
535 G4cout << "FresnelReflection";
536 else if(theStatus == TotalInternalReflection)
537 G4cout << "TotalInternalReflection";
538 else if(theStatus == LambertianReflection)
539 G4cout << "LambertianReflection";
540 else if(theStatus == LobeReflection)
541 G4cout << "LobeReflection";
542 else if(theStatus == SpikeReflection)
543 G4cout << "SpikeReflection";
544 else if(theStatus == BackScattering)
545 G4cout << "BackScattering";
546 else if(theStatus == PolishedLumirrorAirReflection)
547 G4cout << "PolishedLumirrorAirReflection";
548 else if(theStatus == PolishedLumirrorGlueReflection)
549 G4cout << "PolishedLumirrorGlueReflection";
550 else if(theStatus == PolishedAirReflection)
551 G4cout << "PolishedAirReflection";
552 else if(theStatus == PolishedTeflonAirReflection)
553 G4cout << "PolishedTeflonAirReflection";
554 else if(theStatus == PolishedTiOAirReflection)
555 G4cout << "PolishedTiOAirReflection";
556 else if(theStatus == PolishedTyvekAirReflection)
557 G4cout << "PolishedTyvekAirReflection";
558 else if(theStatus == PolishedVM2000AirReflection)
559 G4cout << "PolishedVM2000AirReflection";
560 else if(theStatus == PolishedVM2000GlueReflection)
561 G4cout << "PolishedVM2000GlueReflection";
562 else if(theStatus == EtchedLumirrorAirReflection)
563 G4cout << "EtchedLumirrorAirReflection";
564 else if(theStatus == EtchedLumirrorGlueReflection)
565 G4cout << "EtchedLumirrorGlueReflection";
566 else if(theStatus == EtchedAirReflection)
567 G4cout << "EtchedAirReflection";
568 else if(theStatus == EtchedTeflonAirReflection)
569 G4cout << "EtchedTeflonAirReflection";
570 else if(theStatus == EtchedTiOAirReflection)
571 G4cout << "EtchedTiOAirReflection";
572 else if(theStatus == EtchedTyvekAirReflection)
573 G4cout << "EtchedTyvekAirReflection";
574 else if(theStatus == EtchedVM2000AirReflection)
575 G4cout << "EtchedVM2000AirReflection";
576 else if(theStatus == EtchedVM2000GlueReflection)
577 G4cout << "EtchedVM2000GlueReflection";
578 else if(theStatus == GroundLumirrorAirReflection)
579 G4cout << "GroundLumirrorAirReflection";
580 else if(theStatus == GroundLumirrorGlueReflection)
581 G4cout << "GroundLumirrorGlueReflection";
582 else if(theStatus == GroundAirReflection)
583 G4cout << "GroundAirReflection";
584 else if(theStatus == GroundTeflonAirReflection)
585 G4cout << "GroundTeflonAirReflection";
586 else if(theStatus == GroundTiOAirReflection)
587 G4cout << "GroundTiOAirReflection";
588 else if(theStatus == GroundTyvekAirReflection)
589 G4cout << "GroundTyvekAirReflection";
590 else if(theStatus == GroundVM2000AirReflection)
591 G4cout << "GroundVM2000AirReflection";
592 else if(theStatus == GroundVM2000GlueReflection)
593 G4cout << "GroundVM2000GlueReflection";
594 else if(theStatus == Absorption)
595 G4cout << "Absorption";
596 else if(theStatus == Detection)
597 G4cout << "Detection";
598 else if(theStatus == NotAtBoundary)
599 G4cout << "NotAtBoundary";
600 else if(theStatus == SameMaterial)
601 G4cout << "SameMaterial";
602 else if(theStatus == StepTooSmall)
603 G4cout << "StepTooSmall";
604 else if(theStatus == NoRINDEX)
605 G4cout << "NoRINDEX";
606 else if(theStatus == Dichroic)
607 G4cout << "Dichroic Transmission";
608 G4cout << " ***" << G4endl;
609}
610
611//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
612G4ThreeVector G4OpBoundaryProcess::GetFacetNormal(
613 const G4ThreeVector& Momentum, const G4ThreeVector& Normal) const
614{
615 G4ThreeVector facetNormal;
616 if(theModel == unified || theModel == LUT || theModel == DAVIS)
617 {
618 /* This function codes alpha to a random value taken from the
619 distribution p(alpha) = g(alpha; 0, sigma_alpha)*std::sin(alpha),
620 for alpha > 0 and alpha < 90, where g(alpha; 0, sigma_alpha) is a
621 gaussian distribution with mean 0 and standard deviation sigma_alpha. */
622
623 G4double sigma_alpha = 0.0;
624 if(OpticalSurface)
625 sigma_alpha = OpticalSurface->GetSigmaAlpha();
626 if(sigma_alpha == 0.0)
627 {
628 return Normal;
629 }
630
631 G4double f_max = std::min(1.0, 4. * sigma_alpha);
632 G4double alpha, phi, sinAlpha; //, cosPhi, sinPhi;
633
634 do
635 { // Loop checking, 13-Aug-2015, Peter Gumplinger
636 do
637 { // Loop checking, 13-Aug-2015, Peter Gumplinger
638 alpha = G4RandGauss::shoot(0.0, sigma_alpha);
639 } while(G4UniformRand() * f_max > std::sin(alpha) || alpha >= halfpi);
640
641 phi = G4UniformRand() * twopi;
642 sinAlpha = std::sin(alpha);
643 facetNormal.set(sinAlpha * std::cos(phi), sinAlpha * std::sin(phi),
644 std::cos(alpha));
645 facetNormal.rotateUz(Normal);
646 } while(Momentum * facetNormal >= 0.0);
647 }
648 else
649 {
650 G4double polish = 1.0;
651 if(OpticalSurface)
652 polish = OpticalSurface->GetPolish();
653 if(polish < 1.0)
654 {
655 do
656 { // Loop checking, 13-Aug-2015, Peter Gumplinger
657 G4ThreeVector smear;
658 do
659 { // Loop checking, 13-Aug-2015, Peter Gumplinger
660 smear.setX(2. * G4UniformRand() - 1.);
661 smear.setY(2. * G4UniformRand() - 1.);
662 smear.setZ(2. * G4UniformRand() - 1.);
663 } while(smear.mag() > 1.0);
664 facetNormal = Normal + (1. - polish) * smear;
665 } while(Momentum * facetNormal >= 0.0);
666 facetNormal = facetNormal.unit();
667 }
668 else
669 {
670 facetNormal = Normal;
671 }
672 }
673 return facetNormal;
674}
675
676//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
677void G4OpBoundaryProcess::DielectricMetal()
678{
679 G4int n = 0;
680 G4double rand, EdotN;
681 G4ThreeVector A_trans, A_paral;
682
683 do
684 {
685 ++n;
686 rand = G4UniformRand();
687 if(rand > theReflectivity && n == 1)
688 {
689 if(rand > theReflectivity + theTransmittance)
690 {
691 DoAbsorption();
692 }
693 else
694 {
695 theStatus = Transmission;
696 NewMomentum = OldMomentum;
697 NewPolarization = OldPolarization;
698 }
699 break;
700 }
701 else
702 {
703 if(fRealRIndexMPV && fImagRIndexMPV)
704 {
705 if(n > 1)
706 {
707 CalculateReflectivity();
708 if(!G4BooleanRand(theReflectivity))
709 {
710 DoAbsorption();
711 break;
712 }
713 }
714 }
715 if(theModel == glisur || theFinish == polished)
716 {
717 DoReflection();
718 }
719 else
720 {
721 if(n == 1)
722 ChooseReflection();
723 if(theStatus == LambertianReflection)
724 {
725 DoReflection();
726 }
727 else if(theStatus == BackScattering)
728 {
729 NewMomentum = -OldMomentum;
730 NewPolarization = -OldPolarization;
731 }
732 else
733 {
734 if(theStatus == LobeReflection)
735 {
736 if(fRealRIndexMPV && fImagRIndexMPV)
737 {
738 //
739 }
740 else
741 {
742 theFacetNormal = GetFacetNormal(OldMomentum, theGlobalNormal);
743 }
744 }
745 NewMomentum =
746 OldMomentum - 2. * OldMomentum * theFacetNormal * theFacetNormal;
747 EdotN = OldPolarization * theFacetNormal;
748
749 A_trans = (sint1 > 0.0) ? OldMomentum.cross(theFacetNormal).unit()
750 : OldPolarization;
751 A_paral = NewMomentum.cross(A_trans).unit();
752
753 if(iTE > 0 && iTM > 0)
754 {
755 NewPolarization = -OldPolarization + (2. * EdotN) * theFacetNormal;
756 }
757 else if(iTE > 0)
758 {
759 NewPolarization = -A_trans;
760 }
761 else if(iTM > 0)
762 {
763 NewPolarization = -A_paral;
764 }
765 }
766 }
767 OldMomentum = NewMomentum;
768 OldPolarization = NewPolarization;
769 }
770 // Loop checking, 13-Aug-2015, Peter Gumplinger
771 } while(NewMomentum * theGlobalNormal < 0.0);
772}
773
774//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
775void G4OpBoundaryProcess::DielectricLUT()
776{
777 G4int thetaIndex, phiIndex;
778 G4double AngularDistributionValue, thetaRad, phiRad, EdotN;
779 G4ThreeVector PerpendicularVectorTheta, PerpendicularVectorPhi;
780
781 theStatus = G4OpBoundaryProcessStatus(
782 G4int(theFinish) + (G4int(NoRINDEX) - G4int(groundbackpainted)));
783
784 G4int thetaIndexMax = OpticalSurface->GetThetaIndexMax();
785 G4int phiIndexMax = OpticalSurface->GetPhiIndexMax();
786
787 G4double rand;
788
789 do
790 {
791 rand = G4UniformRand();
792 if(rand > theReflectivity)
793 {
794 if(rand > theReflectivity + theTransmittance)
795 {
796 DoAbsorption();
797 }
798 else
799 {
800 theStatus = Transmission;
801 NewMomentum = OldMomentum;
802 NewPolarization = OldPolarization;
803 }
804 break;
805 }
806 else
807 {
808 // Calculate Angle between Normal and Photon Momentum
809 G4double anglePhotonToNormal = OldMomentum.angle(-theGlobalNormal);
810 // Round to closest integer: LBNL model array has 91 values
811 G4int angleIncident = G4lrint(anglePhotonToNormal / CLHEP::deg);
812
813 // Take random angles THETA and PHI,
814 // and see if below Probability - if not - Redo
815 do
816 {
817 thetaIndex = G4RandFlat::shootInt(thetaIndexMax - 1);
818 phiIndex = G4RandFlat::shootInt(phiIndexMax - 1);
819 // Find probability with the new indeces from LUT
820 AngularDistributionValue = OpticalSurface->GetAngularDistributionValue(
821 angleIncident, thetaIndex, phiIndex);
822 // Loop checking, 13-Aug-2015, Peter Gumplinger
823 } while(!G4BooleanRand(AngularDistributionValue));
824
825 thetaRad = (-90 + 4 * thetaIndex) * pi / 180.;
826 phiRad = (-90 + 5 * phiIndex) * pi / 180.;
827 // Rotate Photon Momentum in Theta, then in Phi
828 NewMomentum = -OldMomentum;
829
830 PerpendicularVectorTheta = NewMomentum.cross(theGlobalNormal);
831 if(PerpendicularVectorTheta.mag() < kCarTolerance)
832 {
833 PerpendicularVectorTheta = NewMomentum.orthogonal();
834 }
835 NewMomentum = NewMomentum.rotate(anglePhotonToNormal - thetaRad,
836 PerpendicularVectorTheta);
837 PerpendicularVectorPhi = PerpendicularVectorTheta.cross(NewMomentum);
838 NewMomentum = NewMomentum.rotate(-phiRad, PerpendicularVectorPhi);
839
840 // Rotate Polarization too:
841 theFacetNormal = (NewMomentum - OldMomentum).unit();
842 EdotN = OldPolarization * theFacetNormal;
843 NewPolarization = -OldPolarization + (2. * EdotN) * theFacetNormal;
844 }
845 // Loop checking, 13-Aug-2015, Peter Gumplinger
846 } while(NewMomentum * theGlobalNormal <= 0.0);
847}
848
849//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
850void G4OpBoundaryProcess::DielectricLUTDAVIS()
851{
852 G4int angindex, random, angleIncident;
853 G4double ReflectivityValue, elevation, azimuth, EdotN;
854 G4double anglePhotonToNormal;
855
856 G4int LUTbin = OpticalSurface->GetLUTbins();
857 G4double rand = G4UniformRand();
858
859 do
860 {
861 anglePhotonToNormal = OldMomentum.angle(-theGlobalNormal);
862
863 // Davis model has 90 reflection bins: round down
864 angleIncident = G4lint(anglePhotonToNormal / CLHEP::deg);
865 ReflectivityValue = OpticalSurface->GetReflectivityLUTValue(angleIncident);
866
867 if(rand > ReflectivityValue)
868 {
869 if(theEfficiency > 0.)
870 {
871 DoAbsorption();
872 break;
873 }
874 else
875 {
876 theStatus = Transmission;
877
878 if(angleIncident <= 0.01)
879 {
880 NewMomentum = OldMomentum;
881 break;
882 }
883
884 do
885 {
886 random = G4RandFlat::shootInt(1, LUTbin + 1);
887 angindex =
888 (((random * 2) - 1)) + angleIncident * LUTbin * 2 + 3640000;
889
890 azimuth =
891 OpticalSurface->GetAngularDistributionValueLUT(angindex - 1);
892 elevation = OpticalSurface->GetAngularDistributionValueLUT(angindex);
893 } while(elevation == 0. && azimuth == 0.);
894
895 NewMomentum = -OldMomentum;
896
897 G4ThreeVector v = theGlobalNormal.cross(-NewMomentum);
898 G4ThreeVector vNorm = v / v.mag();
899 G4ThreeVector u = vNorm.cross(theGlobalNormal);
900
901 u = u *= (std::sin(elevation) * std::cos(azimuth));
902 v = vNorm *= (std::sin(elevation) * std::sin(azimuth));
903 G4ThreeVector w = theGlobalNormal *= (std::cos(elevation));
904 NewMomentum = G4ThreeVector(u + v + w);
905
906 // Rotate Polarization too:
907 theFacetNormal = (NewMomentum - OldMomentum).unit();
908 EdotN = OldPolarization * theFacetNormal;
909 NewPolarization = -OldPolarization + (2. * EdotN) * theFacetNormal;
910 }
911 }
912 else
913 {
914 theStatus = LobeReflection;
915
916 if(angleIncident == 0)
917 {
918 NewMomentum = -OldMomentum;
919 break;
920 }
921
922 do
923 {
924 random = G4RandFlat::shootInt(1, LUTbin + 1);
925 angindex = (((random * 2) - 1)) + (angleIncident - 1) * LUTbin * 2;
926
927 azimuth = OpticalSurface->GetAngularDistributionValueLUT(angindex - 1);
928 elevation = OpticalSurface->GetAngularDistributionValueLUT(angindex);
929 } while(elevation == 0. && azimuth == 0.);
930
931 NewMomentum = -OldMomentum;
932
933 G4ThreeVector v = theGlobalNormal.cross(-NewMomentum);
934 G4ThreeVector vNorm = v / v.mag();
935 G4ThreeVector u = vNorm.cross(theGlobalNormal);
936
937 u = u *= (std::sin(elevation) * std::cos(azimuth));
938 v = vNorm *= (std::sin(elevation) * std::sin(azimuth));
939 G4ThreeVector w = theGlobalNormal *= (std::cos(elevation));
940
941 NewMomentum = G4ThreeVector(u + v + w);
942
943 // Rotate Polarization too: (needs revision)
944 NewPolarization = OldPolarization;
945 }
946 } while(NewMomentum * theGlobalNormal <= 0.0);
947}
948
949//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
950void G4OpBoundaryProcess::DielectricDichroic()
951{
952 // Calculate Angle between Normal and Photon Momentum
953 G4double anglePhotonToNormal = OldMomentum.angle(-theGlobalNormal);
954
955 // Round it to closest integer
956 G4double angleIncident = std::floor(180. / pi * anglePhotonToNormal + 0.5);
957
958 if(!DichroicVector)
959 {
960 if(OpticalSurface)
961 DichroicVector = OpticalSurface->GetDichroicVector();
962 }
963
964 if(DichroicVector)
965 {
966 G4double wavelength = h_Planck * c_light / thePhotonMomentum;
967 theTransmittance =
968 DichroicVector->Value(wavelength / nm, angleIncident, idx, idy) * perCent;
969 // G4cout << "wavelength: " << std::floor(wavelength/nm)
970 // << "nm" << G4endl;
971 // G4cout << "Incident angle: " << angleIncident << "deg" << G4endl;
972 // G4cout << "Transmittance: "
973 // << std::floor(theTransmittance/perCent) << "%" << G4endl;
974 }
975 else
976 {
978 ed << " G4OpBoundaryProcess/DielectricDichroic(): "
979 << " The dichroic surface has no G4Physics2DVector" << G4endl;
980 G4Exception("G4OpBoundaryProcess::DielectricDichroic", "OpBoun03",
981 FatalException, ed,
982 "A dichroic surface must have an associated G4Physics2DVector");
983 }
984
985 if(!G4BooleanRand(theTransmittance))
986 { // Not transmitted, so reflect
987 if(theModel == glisur || theFinish == polished)
988 {
989 DoReflection();
990 }
991 else
992 {
993 ChooseReflection();
994 if(theStatus == LambertianReflection)
995 {
996 DoReflection();
997 }
998 else if(theStatus == BackScattering)
999 {
1000 NewMomentum = -OldMomentum;
1001 NewPolarization = -OldPolarization;
1002 }
1003 else
1004 {
1005 G4double PdotN, EdotN;
1006 do
1007 {
1008 if(theStatus == LobeReflection)
1009 {
1010 theFacetNormal = GetFacetNormal(OldMomentum, theGlobalNormal);
1011 }
1012 PdotN = OldMomentum * theFacetNormal;
1013 NewMomentum = OldMomentum - (2. * PdotN) * theFacetNormal;
1014 // Loop checking, 13-Aug-2015, Peter Gumplinger
1015 } while(NewMomentum * theGlobalNormal <= 0.0);
1016
1017 EdotN = OldPolarization * theFacetNormal;
1018 NewPolarization = -OldPolarization + (2. * EdotN) * theFacetNormal;
1019 }
1020 }
1021 }
1022 else
1023 {
1024 theStatus = Dichroic;
1025 NewMomentum = OldMomentum;
1026 NewPolarization = OldPolarization;
1027 }
1028}
1029
1030//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1031void G4OpBoundaryProcess::DielectricDielectric()
1032{
1033 G4bool Inside = false;
1034 G4bool Swap = false;
1035
1036 G4bool SurfaceRoughnessCriterionPass = true;
1037 if(theSurfaceRoughness != 0. && Rindex1 > Rindex2)
1038 {
1039 G4double wavelength = h_Planck * c_light / thePhotonMomentum;
1040 G4double SurfaceRoughnessCriterion = std::exp(-std::pow(
1041 (4. * pi * theSurfaceRoughness * Rindex1 * cost1 / wavelength), 2));
1042 SurfaceRoughnessCriterionPass = G4BooleanRand(SurfaceRoughnessCriterion);
1043 }
1044
1045leap:
1046
1047 G4bool Through = false;
1048 G4bool Done = false;
1049
1050 G4double EdotN;
1051 G4ThreeVector A_trans, A_paral, E1pp, E1pl;
1052 G4double E1_perp, E1_parl;
1053 G4double s1, s2, E2_perp, E2_parl, E2_total, TransCoeff;
1054 G4double E2_abs, C_parl, C_perp;
1056
1057 do
1058 {
1059 if(Through)
1060 {
1061 Swap = !Swap;
1062 Through = false;
1063 theGlobalNormal = -theGlobalNormal;
1064 G4SwapPtr(Material1, Material2);
1065 G4SwapObj(&Rindex1, &Rindex2);
1066 }
1067
1068 if(theFinish == polished)
1069 {
1070 theFacetNormal = theGlobalNormal;
1071 }
1072 else
1073 {
1074 theFacetNormal = GetFacetNormal(OldMomentum, theGlobalNormal);
1075 }
1076
1077 // PdotN = OldMomentum * theFacetNormal;
1078 EdotN = OldPolarization * theFacetNormal;
1079
1080 cost1 = -OldMomentum * theFacetNormal;
1081 if(std::abs(cost1) < 1.0 - kCarTolerance)
1082 {
1083 sint1 = std::sqrt(1. - cost1 * cost1);
1084 sint2 = sint1 * Rindex1 / Rindex2; // *** Snell's Law ***
1085 // this isn't a sine as we might
1086 // expect from the name; can be > 1
1087 }
1088 else
1089 {
1090 sint1 = 0.0;
1091 sint2 = 0.0;
1092 }
1093
1094 // TOTAL INTERNAL REFLECTION
1095 if(sint2 >= 1.0)
1096 {
1097 Swap = false;
1098
1099 theStatus = TotalInternalReflection;
1100 if(!SurfaceRoughnessCriterionPass)
1101 theStatus = LambertianReflection;
1102 if(theModel == unified && theFinish != polished)
1103 ChooseReflection();
1104 if(theStatus == LambertianReflection)
1105 {
1106 DoReflection();
1107 }
1108 else if(theStatus == BackScattering)
1109 {
1110 NewMomentum = -OldMomentum;
1111 NewPolarization = -OldPolarization;
1112 }
1113 else
1114 {
1115 // PdotN = OldMomentum * theFacetNormal;
1116 NewMomentum =
1117 OldMomentum - 2. * OldMomentum * theFacetNormal * theFacetNormal;
1118 EdotN = OldPolarization * theFacetNormal;
1119 NewPolarization = -OldPolarization + (2. * EdotN) * theFacetNormal;
1120 }
1121 }
1122 // NOT TIR
1123 else if(sint2 < 1.0)
1124 {
1125 // Calculate amplitude for transmission (Q = P x N)
1126 if(cost1 > 0.0)
1127 {
1128 cost2 = std::sqrt(1. - sint2 * sint2);
1129 }
1130 else
1131 {
1132 cost2 = -std::sqrt(1. - sint2 * sint2);
1133 }
1134
1135 if(sint1 > 0.0)
1136 {
1137 A_trans = (OldMomentum.cross(theFacetNormal)).unit();
1138 E1_perp = OldPolarization * A_trans;
1139 E1pp = E1_perp * A_trans;
1140 E1pl = OldPolarization - E1pp;
1141 E1_parl = E1pl.mag();
1142 }
1143 else
1144 {
1145 A_trans = OldPolarization;
1146 // Here we Follow Jackson's conventions and set the parallel
1147 // component = 1 in case of a ray perpendicular to the surface
1148 E1_perp = 0.0;
1149 E1_parl = 1.0;
1150 }
1151
1152 s1 = Rindex1 * cost1;
1153 E2_perp = 2. * s1 * E1_perp / (Rindex1 * cost1 + Rindex2 * cost2);
1154 E2_parl = 2. * s1 * E1_parl / (Rindex2 * cost1 + Rindex1 * cost2);
1155 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1156 s2 = Rindex2 * cost2 * E2_total;
1157
1158 if(theTransmittance > 0.)
1159 TransCoeff = theTransmittance;
1160 else if(cost1 != 0.0)
1161 TransCoeff = s2 / s1;
1162 else
1163 TransCoeff = 0.0;
1164
1165 // NOT TIR: REFLECTION
1166 if(!G4BooleanRand(TransCoeff))
1167 {
1168 Swap = false;
1169 theStatus = FresnelReflection;
1170
1171 if(!SurfaceRoughnessCriterionPass)
1172 theStatus = LambertianReflection;
1173 if(theModel == unified && theFinish != polished)
1174 ChooseReflection();
1175 if(theStatus == LambertianReflection)
1176 {
1177 DoReflection();
1178 }
1179 else if(theStatus == BackScattering)
1180 {
1181 NewMomentum = -OldMomentum;
1182 NewPolarization = -OldPolarization;
1183 }
1184 else
1185 {
1186 NewMomentum =
1187 OldMomentum - 2. * OldMomentum * theFacetNormal * theFacetNormal;
1188 if(sint1 > 0.0)
1189 { // incident ray oblique
1190 E2_parl = Rindex2 * E2_parl / Rindex1 - E1_parl;
1191 E2_perp = E2_perp - E1_perp;
1192 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1193 A_paral = (NewMomentum.cross(A_trans)).unit();
1194 E2_abs = std::sqrt(E2_total);
1195 C_parl = E2_parl / E2_abs;
1196 C_perp = E2_perp / E2_abs;
1197
1198 NewPolarization = C_parl * A_paral + C_perp * A_trans;
1199 }
1200 else
1201 { // incident ray perpendicular
1202 if(Rindex2 > Rindex1)
1203 {
1204 NewPolarization = -OldPolarization;
1205 }
1206 else
1207 {
1208 NewPolarization = OldPolarization;
1209 }
1210 }
1211 }
1212 }
1213 // NOT TIR: TRANSMISSION
1214 else
1215 {
1216 Inside = !Inside;
1217 Through = true;
1218 theStatus = FresnelRefraction;
1219
1220 if(sint1 > 0.0)
1221 { // incident ray oblique
1222 alpha = cost1 - cost2 * (Rindex2 / Rindex1);
1223 NewMomentum = (OldMomentum + alpha * theFacetNormal).unit();
1224 A_paral = (NewMomentum.cross(A_trans)).unit();
1225 E2_abs = std::sqrt(E2_total);
1226 C_parl = E2_parl / E2_abs;
1227 C_perp = E2_perp / E2_abs;
1228
1229 NewPolarization = C_parl * A_paral + C_perp * A_trans;
1230 }
1231 else
1232 { // incident ray perpendicular
1233 NewMomentum = OldMomentum;
1234 NewPolarization = OldPolarization;
1235 }
1236 }
1237 }
1238
1239 OldMomentum = NewMomentum.unit();
1240 OldPolarization = NewPolarization.unit();
1241
1242 if(theStatus == FresnelRefraction)
1243 {
1244 Done = (NewMomentum * theGlobalNormal <= 0.0);
1245 }
1246 else
1247 {
1248 Done = (NewMomentum * theGlobalNormal >= -kCarTolerance);
1249 }
1250 // Loop checking, 13-Aug-2015, Peter Gumplinger
1251 } while(!Done);
1252
1253 if(Inside && !Swap)
1254 {
1255 if(theFinish == polishedbackpainted || theFinish == groundbackpainted)
1256 {
1257 G4double rand = G4UniformRand();
1258 if(rand > theReflectivity + theTransmittance)
1259 {
1260 DoAbsorption();
1261 }
1262 else if(rand > theReflectivity)
1263 {
1264 theStatus = Transmission;
1265 NewMomentum = OldMomentum;
1266 NewPolarization = OldPolarization;
1267 }
1268 else
1269 {
1270 if(theStatus != FresnelRefraction)
1271 {
1272 theGlobalNormal = -theGlobalNormal;
1273 }
1274 else
1275 {
1276 Swap = !Swap;
1277 G4SwapPtr(Material1, Material2);
1278 G4SwapObj(&Rindex1, &Rindex2);
1279 }
1280 if(theFinish == groundbackpainted)
1281 theStatus = LambertianReflection;
1282
1283 DoReflection();
1284
1285 theGlobalNormal = -theGlobalNormal;
1286 OldMomentum = NewMomentum;
1287
1288 goto leap;
1289 }
1290 }
1291 }
1292}
1293
1294//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1297{
1298 *condition = Forced;
1299 return DBL_MAX;
1300}
1301
1302//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1303G4double G4OpBoundaryProcess::GetIncidentAngle()
1304{
1305 G4double PdotN = OldMomentum * theFacetNormal;
1306 G4double magP = OldMomentum.mag();
1307 G4double magN = theFacetNormal.mag();
1308 G4double incidentangle = pi - std::acos(PdotN / (magP * magN));
1309
1310 return incidentangle;
1311}
1312
1313//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1314G4double G4OpBoundaryProcess::GetReflectivity(G4double E1_perp,
1315 G4double E1_parl,
1316 G4double incidentangle,
1317 G4double RealRindex,
1318 G4double ImaginaryRindex)
1319{
1320 G4complex Reflectivity, Reflectivity_TE, Reflectivity_TM;
1321 G4complex N1(Rindex1, 0.), N2(RealRindex, ImaginaryRindex);
1322 G4complex CosPhi;
1323
1324 G4complex u(1., 0.); // unit number 1
1325
1326 G4complex numeratorTE; // E1_perp=1 E1_parl=0 -> TE polarization
1327 G4complex numeratorTM; // E1_parl=1 E1_perp=0 -> TM polarization
1328 G4complex denominatorTE, denominatorTM;
1329 G4complex rTM, rTE;
1330
1334 if(ppR && ppI)
1335 {
1336 G4double RRindex = ppR->Value(thePhotonMomentum, idx_rrindex);
1337 G4double IRindex = ppI->Value(thePhotonMomentum, idx_irindex);
1338 N1 = G4complex(RRindex, IRindex);
1339 }
1340
1341 // Following two equations, rTM and rTE, are from: "Introduction To Modern
1342 // Optics" written by Fowles
1343 CosPhi = std::sqrt(u - ((std::sin(incidentangle) * std::sin(incidentangle)) *
1344 (N1 * N1) / (N2 * N2)));
1345
1346 numeratorTE = N1 * std::cos(incidentangle) - N2 * CosPhi;
1347 denominatorTE = N1 * std::cos(incidentangle) + N2 * CosPhi;
1348 rTE = numeratorTE / denominatorTE;
1349
1350 numeratorTM = N2 * std::cos(incidentangle) - N1 * CosPhi;
1351 denominatorTM = N2 * std::cos(incidentangle) + N1 * CosPhi;
1352 rTM = numeratorTM / denominatorTM;
1353
1354 // This is my calculaton for reflectivity on a metalic surface
1355 // depending on the fraction of TE and TM polarization
1356 // when TE polarization, E1_parl=0 and E1_perp=1, R=abs(rTE)^2 and
1357 // when TM polarization, E1_parl=1 and E1_perp=0, R=abs(rTM)^2
1358
1359 Reflectivity_TE = (rTE * conj(rTE)) * (E1_perp * E1_perp) /
1360 (E1_perp * E1_perp + E1_parl * E1_parl);
1361 Reflectivity_TM = (rTM * conj(rTM)) * (E1_parl * E1_parl) /
1362 (E1_perp * E1_perp + E1_parl * E1_parl);
1363 Reflectivity = Reflectivity_TE + Reflectivity_TM;
1364
1365 do
1366 {
1367 if(G4UniformRand() * real(Reflectivity) > real(Reflectivity_TE))
1368 {
1369 iTE = -1;
1370 }
1371 else
1372 {
1373 iTE = 1;
1374 }
1375 if(G4UniformRand() * real(Reflectivity) > real(Reflectivity_TM))
1376 {
1377 iTM = -1;
1378 }
1379 else
1380 {
1381 iTM = 1;
1382 }
1383 // Loop checking, 13-Aug-2015, Peter Gumplinger
1384 } while(iTE < 0 && iTM < 0);
1385
1386 return real(Reflectivity);
1387}
1388
1389//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1390
1391void G4OpBoundaryProcess::CalculateReflectivity()
1392{
1393 G4double RealRindex = fRealRIndexMPV->Value(thePhotonMomentum, idx_rrindex);
1394 G4double ImaginaryRindex =
1395 fImagRIndexMPV->Value(thePhotonMomentum, idx_irindex);
1396
1397 // calculate FacetNormal
1398 if(theFinish == ground)
1399 {
1400 theFacetNormal = GetFacetNormal(OldMomentum, theGlobalNormal);
1401 }
1402 else
1403 {
1404 theFacetNormal = theGlobalNormal;
1405 }
1406
1407 cost1 = -OldMomentum * theFacetNormal;
1408 if(std::abs(cost1) < 1.0 - kCarTolerance)
1409 {
1410 sint1 = std::sqrt(1. - cost1 * cost1);
1411 }
1412 else
1413 {
1414 sint1 = 0.0;
1415 }
1416
1417 G4ThreeVector A_trans, A_paral, E1pp, E1pl;
1418 G4double E1_perp, E1_parl;
1419
1420 if(sint1 > 0.0)
1421 {
1422 A_trans = (OldMomentum.cross(theFacetNormal)).unit();
1423 E1_perp = OldPolarization * A_trans;
1424 E1pp = E1_perp * A_trans;
1425 E1pl = OldPolarization - E1pp;
1426 E1_parl = E1pl.mag();
1427 }
1428 else
1429 {
1430 A_trans = OldPolarization;
1431 // Here we Follow Jackson's conventions and we set the parallel
1432 // component = 1 in case of a ray perpendicular to the surface
1433 E1_perp = 0.0;
1434 E1_parl = 1.0;
1435 }
1436
1437 G4double incidentangle = GetIncidentAngle();
1438
1439 // calculate the reflectivity depending on incident angle,
1440 // polarization and complex refractive
1441 theReflectivity = GetReflectivity(E1_perp, E1_parl, incidentangle, RealRindex,
1442 ImaginaryRindex);
1443}
1444
1445//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1446G4bool G4OpBoundaryProcess::InvokeSD(const G4Step* pStep)
1447{
1448 G4Step aStep = *pStep;
1449 aStep.AddTotalEnergyDeposit(thePhotonMomentum);
1450
1452 if(sd)
1453 return sd->Hit(&aStep);
1454 else
1455 return false;
1456}
G4double condition(const G4ErrorSymMatrix &m)
@ JustWarning
@ FatalException
@ EventMustBeAborted
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
G4ForceCondition
@ Forced
@ kBACKSCATTERCONSTANT
@ kSPECULARLOBECONSTANT
@ kSPECULARSPIKECONSTANT
G4OpBoundaryProcessStatus
@ PolishedTiOAirReflection
@ GroundTeflonAirReflection
@ EtchedVM2000AirReflection
@ Undefined
@ NotAtBoundary
@ Transmission
@ EtchedVM2000GlueReflection
@ GroundLumirrorGlueReflection
@ LobeReflection
@ GroundTiOAirReflection
@ GroundTyvekAirReflection
@ FresnelReflection
@ NoRINDEX
@ GroundAirReflection
@ EtchedAirReflection
@ PolishedVM2000GlueReflection
@ PolishedAirReflection
@ PolishedTeflonAirReflection
@ SameMaterial
@ EtchedTyvekAirReflection
@ SpikeReflection
@ EtchedLumirrorGlueReflection
@ GroundVM2000AirReflection
@ PolishedTyvekAirReflection
@ PolishedVM2000AirReflection
@ EtchedTiOAirReflection
@ EtchedTeflonAirReflection
@ GroundVM2000GlueReflection
@ BackScattering
@ PolishedLumirrorGlueReflection
@ Absorption
@ TotalInternalReflection
@ StepTooSmall
@ PolishedLumirrorAirReflection
@ EtchedLumirrorAirReflection
@ GroundLumirrorAirReflection
@ LambertianReflection
@ FresnelRefraction
@ Detection
@ fOpBoundary
@ unified
@ DAVIS
@ glisur
@ groundfrontpainted
@ polishedbackpainted
@ polished
@ ground
@ polishedfrontpainted
@ groundbackpainted
G4ProcessType
@ fGeomBoundary
Definition: G4StepStatus.hh:43
G4SurfaceType
@ dielectric_metal
@ dielectric_LUT
@ dielectric_dielectric
@ dielectric_LUTDAVIS
@ dielectric_dichroic
CLHEP::Hep3Vector G4ThreeVector
@ fStopAndKill
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
std::complex< G4double > G4complex
Definition: G4Types.hh:88
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector unit() const
Hep3Vector orthogonal() const
void setY(double)
Hep3Vector cross(const Hep3Vector &) const
double angle(const Hep3Vector &) const
void setZ(double)
double mag() const
void set(double x, double y, double z)
void setX(double)
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:33
Hep3Vector & rotate(double, const Hep3Vector &)
Definition: ThreeVectorR.cc:24
const G4ThreeVector & GetMomentumDirection() const
G4double GetTotalMomentum() const
const G4ThreeVector & GetPolarization() const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
static G4LogicalBorderSurface * GetSurface(const G4VPhysicalVolume *vol1, const G4VPhysicalVolume *vol2)
static G4LogicalSkinSurface * GetSurface(const G4LogicalVolume *vol)
G4SurfaceProperty * GetSurfaceProperty() const
G4MaterialPropertyVector * GetProperty(const char *key, G4bool warning=false)
G4bool ConstPropertyExists(const G4String &key) const
G4double GetConstProperty(const G4String &key) const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
Definition: G4Material.hh:254
G4OpBoundaryProcess(const G4String &processName="OpBoundary", G4ProcessType type=fOptical)
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
virtual void SetInvokeSD(G4bool)
virtual G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *condition) override
virtual void PreparePhysicsTable(const G4ParticleDefinition &) override
G4bool GetBoundaryInvokeSD() const
G4int GetBoundaryVerboseLevel() const
static G4OpticalParameters * Instance()
G4double GetAngularDistributionValueLUT(G4int)
G4OpticalSurfaceModel GetModel() const
G4double GetSigmaAlpha() const
G4OpticalSurfaceFinish GetFinish() const
G4int GetThetaIndexMax(void) const
G4int GetPhiIndexMax(void) const
G4double GetPolish() const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
G4Physics2DVector * GetDichroicVector()
G4double GetReflectivityLUTValue(G4int)
G4int GetLUTbins(void) const
G4double GetAngularDistributionValue(G4int, G4int, G4int)
static const G4Step * GetHyperStep()
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
void ProposeVelocity(G4double finalVelocity)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
virtual void Initialize(const G4Track &)
G4double Value(G4double x, G4double y, std::size_t &lastidx, std::size_t &lastidy) const
G4double Value(G4double theEnergy, std::size_t &lastidx) const
G4StepStatus GetStepStatus() const
G4Material * GetMaterial() const
const G4ThreeVector & GetPosition() const
G4VSensitiveDetector * GetSensitiveDetector() const
G4VPhysicalVolume * GetPhysicalVolume() const
Definition: G4Step.hh:62
void AddTotalEnergyDeposit(G4double value)
G4StepPoint * GetPreStepPoint() const
G4StepPoint * GetPostStepPoint() const
const G4SurfaceType & GetType() const
G4double GetVelocity() const
const G4DynamicParticle * GetDynamicParticle() const
G4double GetStepLength() const
std::vector< G4Navigator * >::iterator GetActiveNavigatorsIterator()
static G4TransportationManager * GetTransportationManager()
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
G4LogicalVolume * GetMotherLogical() const
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
void SetVerboseLevel(G4int value)
Definition: G4VProcess.hh:412
G4ParticleChange aParticleChange
Definition: G4VProcess.hh:327
G4int verboseLevel
Definition: G4VProcess.hh:356
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:406
const G4String & GetProcessName() const
Definition: G4VProcess.hh:382
G4bool Hit(G4Step *aStep)
void G4SwapObj(T *a, T *b)
Definition: templates.hh:112
int G4lint(double ad)
Definition: templates.hh:139
int G4lrint(double ad)
Definition: templates.hh:134
void G4SwapPtr(T *&a, T *&b)
Definition: templates.hh:104
#define DBL_MAX
Definition: templates.hh:62