Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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//
67// Author: Peter Gumplinger
68// adopted from work by Werner Keil - April 2/96
69// mail: [email protected]
70//
71////////////////////////////////////////////////////////////////////////
72
73#include "G4ios.hh"
75#include "G4OpProcessSubType.hh"
76
79
80/////////////////////////
81// Class Implementation
82/////////////////////////
83
84 //////////////
85 // Operators
86 //////////////
87
88// G4OpBoundaryProcess::operator=(const G4OpBoundaryProcess &right)
89// {
90// }
91
92 /////////////////
93 // Constructors
94 /////////////////
95
97 G4ProcessType type)
98 : G4VDiscreteProcess(processName, type)
99{
100 if ( verboseLevel > 0) {
101 G4cout << GetProcessName() << " is created " << G4endl;
102 }
103
105
106 theStatus = Undefined;
107 theModel = glisur;
108 theFinish = polished;
109 theReflectivity = 1.;
110 theEfficiency = 0.;
111 theTransmittance = 0.;
112
113 prob_sl = 0.;
114 prob_ss = 0.;
115 prob_bs = 0.;
116
117 PropertyPointer = NULL;
118 PropertyPointer1 = NULL;
119 PropertyPointer2 = NULL;
120
121 Material1 = NULL;
122 Material2 = NULL;
123
124 OpticalSurface = NULL;
125
126 kCarTolerance = G4GeometryTolerance::GetInstance()
128
129 iTE = iTM = 0;
130 thePhotonMomentum = 0.;
131 Rindex1 = Rindex2 = cost1 = cost2 = sint1 = sint2 = 0.;
132}
133
134// G4OpBoundaryProcess::G4OpBoundaryProcess(const G4OpBoundaryProcess &right)
135// {
136// }
137
138 ////////////////
139 // Destructors
140 ////////////////
141
143
144 ////////////
145 // Methods
146 ////////////
147
148// PostStepDoIt
149// ------------
150//
153{
154 theStatus = Undefined;
155
158
159 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
160 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
161
162 if ( verboseLevel > 0 ) {
163 G4cout << " Photon at Boundary! " << G4endl;
164 G4VPhysicalVolume* thePrePV = pPreStepPoint->GetPhysicalVolume();
165 G4VPhysicalVolume* thePostPV = pPostStepPoint->GetPhysicalVolume();
166 if (thePrePV) G4cout << " thePrePV: " << thePrePV->GetName() << G4endl;
167 if (thePostPV) G4cout << " thePostPV: " << thePostPV->GetName() << G4endl;
168 }
169
170 if (pPostStepPoint->GetStepStatus() != fGeomBoundary){
171 theStatus = NotAtBoundary;
172 if ( verboseLevel > 0) BoundaryProcessVerbose();
173 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
174 }
175 if (aTrack.GetStepLength()<=kCarTolerance/2){
176 theStatus = StepTooSmall;
177 if ( verboseLevel > 0) BoundaryProcessVerbose();
178 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
179 }
180
181 Material1 = pPreStepPoint -> GetMaterial();
182 Material2 = pPostStepPoint -> GetMaterial();
183
184 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
185
186 thePhotonMomentum = aParticle->GetTotalMomentum();
187 OldMomentum = aParticle->GetMomentumDirection();
188 OldPolarization = aParticle->GetPolarization();
189
190 if ( verboseLevel > 0 ) {
191 G4cout << " Old Momentum Direction: " << OldMomentum << G4endl;
192 G4cout << " Old Polarization: " << OldPolarization << G4endl;
193 }
194
195 G4ThreeVector theGlobalPoint = pPostStepPoint->GetPosition();
196
197 G4Navigator* theNavigator =
199 GetNavigatorForTracking();
200
201 G4bool valid;
202 // Use the new method for Exit Normal in global coordinates,
203 // which provides the normal more reliably.
204 theGlobalNormal =
205 theNavigator->GetGlobalExitNormal(theGlobalPoint,&valid);
206
207 if (valid) {
208 theGlobalNormal = -theGlobalNormal;
209 }
210 else
211 {
213 ed << " G4OpBoundaryProcess/PostStepDoIt(): "
214 << " The Navigator reports that it returned an invalid normal"
215 << G4endl;
216 G4Exception("G4OpBoundaryProcess::PostStepDoIt", "OpBoun01",
218 "Invalid Surface Normal - Geometry must return valid surface normal");
219 }
220
221 if (OldMomentum * theGlobalNormal > 0.0) {
222#ifdef G4OPTICAL_DEBUG
224 ed << " G4OpBoundaryProcess/PostStepDoIt(): "
225 << " theGlobalNormal points in a wrong direction. "
226 << G4endl;
227 ed << " The momentum of the photon arriving at interface (oldMomentum)"
228 << " must exit the volume cross in the step. " << G4endl;
229 ed << " So it MUST have dot < 0 with the normal that Exits the new volume (globalNormal)." << G4endl;
230 ed << " >> The dot product of oldMomentum and global Normal is " << OldMomentum*theGlobalNormal << G4endl;
231 ed << " Old Momentum (during step) = " << OldMomentum << G4endl;
232 ed << " Global Normal (Exiting New Vol) = " << theGlobalNormal << G4endl;
233 ed << G4endl;
234 G4Exception("G4OpBoundaryProcess::PostStepDoIt", "OpBoun02",
235 EventMustBeAborted, // Or JustWarning to see if it happens repeatedbly on one ray
236 ed,
237 "Invalid Surface Normal - Geometry must return valid surface normal pointing in the right direction");
238#else
239 theGlobalNormal = -theGlobalNormal;
240#endif
241 }
242
243 G4MaterialPropertiesTable* aMaterialPropertiesTable;
245
246 aMaterialPropertiesTable = Material1->GetMaterialPropertiesTable();
247 if (aMaterialPropertiesTable) {
248 Rindex = aMaterialPropertiesTable->GetProperty("RINDEX");
249 }
250 else {
251 theStatus = NoRINDEX;
252 if ( verboseLevel > 0) BoundaryProcessVerbose();
255 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
256 }
257
258 if (Rindex) {
259 Rindex1 = Rindex->Value(thePhotonMomentum);
260 }
261 else {
262 theStatus = NoRINDEX;
263 if ( verboseLevel > 0) BoundaryProcessVerbose();
266 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
267 }
268
269 theReflectivity = 1.;
270 theEfficiency = 0.;
271 theTransmittance = 0.;
272
273 theModel = glisur;
274 theFinish = polished;
275
277
278 Rindex = NULL;
279 OpticalSurface = NULL;
280
281 G4LogicalSurface* Surface = NULL;
282
284 (pPreStepPoint ->GetPhysicalVolume(),
285 pPostStepPoint->GetPhysicalVolume());
286
287 if (Surface == NULL){
288 G4bool enteredDaughter=(pPostStepPoint->GetPhysicalVolume()
289 ->GetMotherLogical() ==
290 pPreStepPoint->GetPhysicalVolume()
291 ->GetLogicalVolume());
292 if(enteredDaughter){
294 (pPostStepPoint->GetPhysicalVolume()->
295 GetLogicalVolume());
296 if(Surface == NULL)
298 (pPreStepPoint->GetPhysicalVolume()->
299 GetLogicalVolume());
300 }
301 else {
303 (pPreStepPoint->GetPhysicalVolume()->
304 GetLogicalVolume());
305 if(Surface == NULL)
307 (pPostStepPoint->GetPhysicalVolume()->
308 GetLogicalVolume());
309 }
310 }
311
312 if (Surface) OpticalSurface =
313 dynamic_cast <G4OpticalSurface*> (Surface->GetSurfaceProperty());
314
315 if (OpticalSurface) {
316
317 type = OpticalSurface->GetType();
318 theModel = OpticalSurface->GetModel();
319 theFinish = OpticalSurface->GetFinish();
320
321 aMaterialPropertiesTable = OpticalSurface->
322 GetMaterialPropertiesTable();
323
324 if (aMaterialPropertiesTable) {
325
326 if (theFinish == polishedbackpainted ||
327 theFinish == groundbackpainted ) {
328 Rindex = aMaterialPropertiesTable->GetProperty("RINDEX");
329 if (Rindex) {
330 Rindex2 = Rindex->Value(thePhotonMomentum);
331 }
332 else {
333 theStatus = NoRINDEX;
334 if ( verboseLevel > 0) BoundaryProcessVerbose();
337 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
338 }
339 }
340
341 PropertyPointer =
342 aMaterialPropertiesTable->GetProperty("REFLECTIVITY");
343 PropertyPointer1 =
344 aMaterialPropertiesTable->GetProperty("REALRINDEX");
345 PropertyPointer2 =
346 aMaterialPropertiesTable->GetProperty("IMAGINARYRINDEX");
347
348 iTE = 1;
349 iTM = 1;
350
351 if (PropertyPointer) {
352
353 theReflectivity =
354 PropertyPointer->Value(thePhotonMomentum);
355
356 } else if (PropertyPointer1 && PropertyPointer2) {
357
358 CalculateReflectivity();
359
360 }
361
362 PropertyPointer =
363 aMaterialPropertiesTable->GetProperty("EFFICIENCY");
364 if (PropertyPointer) {
365 theEfficiency =
366 PropertyPointer->Value(thePhotonMomentum);
367 }
368
369 PropertyPointer =
370 aMaterialPropertiesTable->GetProperty("TRANSMITTANCE");
371 if (PropertyPointer) {
372 theTransmittance =
373 PropertyPointer->Value(thePhotonMomentum);
374 }
375
376 if ( theModel == unified ) {
377 PropertyPointer =
378 aMaterialPropertiesTable->GetProperty("SPECULARLOBECONSTANT");
379 if (PropertyPointer) {
380 prob_sl =
381 PropertyPointer->Value(thePhotonMomentum);
382 } else {
383 prob_sl = 0.0;
384 }
385
386 PropertyPointer =
387 aMaterialPropertiesTable->GetProperty("SPECULARSPIKECONSTANT");
388 if (PropertyPointer) {
389 prob_ss =
390 PropertyPointer->Value(thePhotonMomentum);
391 } else {
392 prob_ss = 0.0;
393 }
394
395 PropertyPointer =
396 aMaterialPropertiesTable->GetProperty("BACKSCATTERCONSTANT");
397 if (PropertyPointer) {
398 prob_bs =
399 PropertyPointer->Value(thePhotonMomentum);
400 } else {
401 prob_bs = 0.0;
402 }
403 }
404 }
405 else if (theFinish == polishedbackpainted ||
406 theFinish == groundbackpainted ) {
409 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
410 }
411 }
412
413 if (type == dielectric_dielectric ) {
414 if (theFinish == polished || theFinish == ground ) {
415
416 if (Material1 == Material2){
417 theStatus = SameMaterial;
418 if ( verboseLevel > 0) BoundaryProcessVerbose();
419 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
420 }
421 aMaterialPropertiesTable =
422 Material2->GetMaterialPropertiesTable();
423 if (aMaterialPropertiesTable)
424 Rindex = aMaterialPropertiesTable->GetProperty("RINDEX");
425 if (Rindex) {
426 Rindex2 = Rindex->Value(thePhotonMomentum);
427 }
428 else {
429 theStatus = NoRINDEX;
430 if ( verboseLevel > 0) BoundaryProcessVerbose();
433 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
434 }
435 }
436 }
437
438 if (type == dielectric_metal) {
439
440 DielectricMetal();
441
442 // Uncomment the following lines if you wish to have
443 // Transmission instead of Absorption
444 // if (theStatus == Absorption) {
445 // return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
446 // }
447
448 }
449 else if (type == dielectric_LUT) {
450
451 DielectricLUT();
452
453 }
454 else if (type == dielectric_dielectric) {
455
456 if ( theFinish == polishedbackpainted ||
457 theFinish == groundbackpainted ) {
458 DielectricDielectric();
459 }
460 else {
461 if ( !G4BooleanRand(theReflectivity) ) {
462 DoAbsorption();
463 }
464 else {
465 if ( theFinish == polishedfrontpainted ) {
466 DoReflection();
467 }
468 else if ( theFinish == groundfrontpainted ) {
469 theStatus = LambertianReflection;
470 DoReflection();
471 }
472 else {
473 DielectricDielectric();
474 }
475 }
476 }
477 }
478 else {
479
480 G4cerr << " Error: G4BoundaryProcess: illegal boundary type " << G4endl;
481 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
482
483 }
484
485 NewMomentum = NewMomentum.unit();
486 NewPolarization = NewPolarization.unit();
487
488 if ( verboseLevel > 0) {
489 G4cout << " New Momentum Direction: " << NewMomentum << G4endl;
490 G4cout << " New Polarization: " << NewPolarization << G4endl;
491 BoundaryProcessVerbose();
492 }
493
495 aParticleChange.ProposePolarization(NewPolarization);
496
497 if ( theStatus == FresnelRefraction ) {
498 G4MaterialPropertyVector* groupvel =
499 Material2->GetMaterialPropertiesTable()->GetProperty("GROUPVEL");
500 G4double finalVelocity = groupvel->Value(thePhotonMomentum);
501 aParticleChange.ProposeVelocity(finalVelocity);
502 }
503
504 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
505}
506
507void G4OpBoundaryProcess::BoundaryProcessVerbose() const
508{
509 if ( theStatus == Undefined )
510 G4cout << " *** Undefined *** " << G4endl;
511 if ( theStatus == FresnelRefraction )
512 G4cout << " *** FresnelRefraction *** " << G4endl;
513 if ( theStatus == FresnelReflection )
514 G4cout << " *** FresnelReflection *** " << G4endl;
515 if ( theStatus == TotalInternalReflection )
516 G4cout << " *** TotalInternalReflection *** " << G4endl;
517 if ( theStatus == LambertianReflection )
518 G4cout << " *** LambertianReflection *** " << G4endl;
519 if ( theStatus == LobeReflection )
520 G4cout << " *** LobeReflection *** " << G4endl;
521 if ( theStatus == SpikeReflection )
522 G4cout << " *** SpikeReflection *** " << G4endl;
523 if ( theStatus == BackScattering )
524 G4cout << " *** BackScattering *** " << G4endl;
525 if ( theStatus == PolishedLumirrorAirReflection )
526 G4cout << " *** PolishedLumirrorAirReflection *** " << G4endl;
527 if ( theStatus == PolishedLumirrorGlueReflection )
528 G4cout << " *** PolishedLumirrorGlueReflection *** " << G4endl;
529 if ( theStatus == PolishedAirReflection )
530 G4cout << " *** PolishedAirReflection *** " << G4endl;
531 if ( theStatus == PolishedTeflonAirReflection )
532 G4cout << " *** PolishedTeflonAirReflection *** " << G4endl;
533 if ( theStatus == PolishedTiOAirReflection )
534 G4cout << " *** PolishedTiOAirReflection *** " << G4endl;
535 if ( theStatus == PolishedTyvekAirReflection )
536 G4cout << " *** PolishedTyvekAirReflection *** " << G4endl;
537 if ( theStatus == PolishedVM2000AirReflection )
538 G4cout << " *** PolishedVM2000AirReflection *** " << G4endl;
539 if ( theStatus == PolishedVM2000GlueReflection )
540 G4cout << " *** PolishedVM2000GlueReflection *** " << G4endl;
541 if ( theStatus == EtchedLumirrorAirReflection )
542 G4cout << " *** EtchedLumirrorAirReflection *** " << G4endl;
543 if ( theStatus == EtchedLumirrorGlueReflection )
544 G4cout << " *** EtchedLumirrorGlueReflection *** " << G4endl;
545 if ( theStatus == EtchedAirReflection )
546 G4cout << " *** EtchedAirReflection *** " << G4endl;
547 if ( theStatus == EtchedTeflonAirReflection )
548 G4cout << " *** EtchedTeflonAirReflection *** " << G4endl;
549 if ( theStatus == EtchedTiOAirReflection )
550 G4cout << " *** EtchedTiOAirReflection *** " << G4endl;
551 if ( theStatus == EtchedTyvekAirReflection )
552 G4cout << " *** EtchedTyvekAirReflection *** " << G4endl;
553 if ( theStatus == EtchedVM2000AirReflection )
554 G4cout << " *** EtchedVM2000AirReflection *** " << G4endl;
555 if ( theStatus == EtchedVM2000GlueReflection )
556 G4cout << " *** EtchedVM2000GlueReflection *** " << G4endl;
557 if ( theStatus == GroundLumirrorAirReflection )
558 G4cout << " *** GroundLumirrorAirReflection *** " << G4endl;
559 if ( theStatus == GroundLumirrorGlueReflection )
560 G4cout << " *** GroundLumirrorGlueReflection *** " << G4endl;
561 if ( theStatus == GroundAirReflection )
562 G4cout << " *** GroundAirReflection *** " << G4endl;
563 if ( theStatus == GroundTeflonAirReflection )
564 G4cout << " *** GroundTeflonAirReflection *** " << G4endl;
565 if ( theStatus == GroundTiOAirReflection )
566 G4cout << " *** GroundTiOAirReflection *** " << G4endl;
567 if ( theStatus == GroundTyvekAirReflection )
568 G4cout << " *** GroundTyvekAirReflection *** " << G4endl;
569 if ( theStatus == GroundVM2000AirReflection )
570 G4cout << " *** GroundVM2000AirReflection *** " << G4endl;
571 if ( theStatus == GroundVM2000GlueReflection )
572 G4cout << " *** GroundVM2000GlueReflection *** " << G4endl;
573 if ( theStatus == Absorption )
574 G4cout << " *** Absorption *** " << G4endl;
575 if ( theStatus == Detection )
576 G4cout << " *** Detection *** " << G4endl;
577 if ( theStatus == NotAtBoundary )
578 G4cout << " *** NotAtBoundary *** " << G4endl;
579 if ( theStatus == SameMaterial )
580 G4cout << " *** SameMaterial *** " << G4endl;
581 if ( theStatus == StepTooSmall )
582 G4cout << " *** StepTooSmall *** " << G4endl;
583 if ( theStatus == NoRINDEX )
584 G4cout << " *** NoRINDEX *** " << G4endl;
585}
586
588G4OpBoundaryProcess::GetFacetNormal(const G4ThreeVector& Momentum,
589 const G4ThreeVector& Normal ) const
590{
591 G4ThreeVector FacetNormal;
592
593 if (theModel == unified || theModel == LUT) {
594
595 /* This function code alpha to a random value taken from the
596 distribution p(alpha) = g(alpha; 0, sigma_alpha)*std::sin(alpha),
597 for alpha > 0 and alpha < 90, where g(alpha; 0, sigma_alpha)
598 is a gaussian distribution with mean 0 and standard deviation
599 sigma_alpha. */
600
602
603 G4double sigma_alpha = 0.0;
604 if (OpticalSurface) sigma_alpha = OpticalSurface->GetSigmaAlpha();
605
606 if (sigma_alpha == 0.0) return FacetNormal = Normal;
607
608 G4double f_max = std::min(1.0,4.*sigma_alpha);
609
610 do {
611 do {
612 alpha = G4RandGauss::shoot(0.0,sigma_alpha);
613 } while (G4UniformRand()*f_max > std::sin(alpha) || alpha >= halfpi );
614
615 G4double phi = G4UniformRand()*twopi;
616
617 G4double SinAlpha = std::sin(alpha);
618 G4double CosAlpha = std::cos(alpha);
619 G4double SinPhi = std::sin(phi);
620 G4double CosPhi = std::cos(phi);
621
622 G4double unit_x = SinAlpha * CosPhi;
623 G4double unit_y = SinAlpha * SinPhi;
624 G4double unit_z = CosAlpha;
625
626 FacetNormal.setX(unit_x);
627 FacetNormal.setY(unit_y);
628 FacetNormal.setZ(unit_z);
629
630 G4ThreeVector tmpNormal = Normal;
631
632 FacetNormal.rotateUz(tmpNormal);
633 } while (Momentum * FacetNormal >= 0.0);
634 }
635 else {
636
637 G4double polish = 1.0;
638 if (OpticalSurface) polish = OpticalSurface->GetPolish();
639
640 if (polish < 1.0) {
641 do {
642 G4ThreeVector smear;
643 do {
644 smear.setX(2.*G4UniformRand()-1.0);
645 smear.setY(2.*G4UniformRand()-1.0);
646 smear.setZ(2.*G4UniformRand()-1.0);
647 } while (smear.mag()>1.0);
648 smear = (1.-polish) * smear;
649 FacetNormal = Normal + smear;
650 } while (Momentum * FacetNormal >= 0.0);
651 FacetNormal = FacetNormal.unit();
652 }
653 else {
654 FacetNormal = Normal;
655 }
656 }
657 return FacetNormal;
658}
659
660void G4OpBoundaryProcess::DielectricMetal()
661{
662 G4int n = 0;
663
664 do {
665
666 n++;
667
668 if( !G4BooleanRand(theReflectivity) && n == 1 ) {
669
670 // Comment out DoAbsorption and uncomment theStatus = Absorption;
671 // if you wish to have Transmission instead of Absorption
672
673 DoAbsorption();
674 // theStatus = Absorption;
675 break;
676
677 }
678 else {
679
680 if (PropertyPointer1 && PropertyPointer2) {
681 if ( n > 1 ) {
682 CalculateReflectivity();
683 if ( !G4BooleanRand(theReflectivity) ) {
684 DoAbsorption();
685 break;
686 }
687 }
688 }
689
690 if ( theModel == glisur || theFinish == polished ) {
691
692 DoReflection();
693
694 } else {
695
696 if ( n == 1 ) ChooseReflection();
697
698 if ( theStatus == LambertianReflection ) {
699 DoReflection();
700 }
701 else if ( theStatus == BackScattering ) {
702 NewMomentum = -OldMomentum;
703 NewPolarization = -OldPolarization;
704 }
705 else {
706
707 if(theStatus==LobeReflection){
708 if ( PropertyPointer1 && PropertyPointer2 ){
709 } else {
710 theFacetNormal =
711 GetFacetNormal(OldMomentum,theGlobalNormal);
712 }
713 }
714
715 G4double PdotN = OldMomentum * theFacetNormal;
716 NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
717 G4double EdotN = OldPolarization * theFacetNormal;
718
719 G4ThreeVector A_trans, A_paral;
720
721 if (sint1 > 0.0 ) {
722 A_trans = OldMomentum.cross(theFacetNormal);
723 A_trans = A_trans.unit();
724 } else {
725 A_trans = OldPolarization;
726 }
727 A_paral = NewMomentum.cross(A_trans);
728 A_paral = A_paral.unit();
729
730 if(iTE>0&&iTM>0) {
731 NewPolarization =
732 -OldPolarization + (2.*EdotN)*theFacetNormal;
733 } else if (iTE>0) {
734 NewPolarization = -A_trans;
735 } else if (iTM>0) {
736 NewPolarization = -A_paral;
737 }
738
739 }
740
741 }
742
743 OldMomentum = NewMomentum;
744 OldPolarization = NewPolarization;
745
746 }
747
748 } while (NewMomentum * theGlobalNormal < 0.0);
749}
750
751void G4OpBoundaryProcess::DielectricLUT()
752{
753 G4int thetaIndex, phiIndex;
754 G4double AngularDistributionValue, thetaRad, phiRad, EdotN;
755 G4ThreeVector PerpendicularVectorTheta, PerpendicularVectorPhi;
756
757 theStatus = G4OpBoundaryProcessStatus(G4int(theFinish) +
759
760 G4int thetaIndexMax = OpticalSurface->GetThetaIndexMax();
761 G4int phiIndexMax = OpticalSurface->GetPhiIndexMax();
762
763 do {
764 if ( !G4BooleanRand(theReflectivity) ) // Not reflected, so Absorbed
765 DoAbsorption();
766 else {
767 // Calculate Angle between Normal and Photon Momentum
768 G4double anglePhotonToNormal =
769 OldMomentum.angle(-theGlobalNormal);
770 // Round it to closest integer
771 G4int angleIncident = G4int(std::floor(180/pi*anglePhotonToNormal+0.5));
772
773 // Take random angles THETA and PHI,
774 // and see if below Probability - if not - Redo
775 do {
776 thetaIndex = CLHEP::RandFlat::shootInt(thetaIndexMax-1);
777 phiIndex = CLHEP::RandFlat::shootInt(phiIndexMax-1);
778 // Find probability with the new indeces from LUT
779 AngularDistributionValue = OpticalSurface ->
780 GetAngularDistributionValue(angleIncident,
781 thetaIndex,
782 phiIndex);
783 } while ( !G4BooleanRand(AngularDistributionValue) );
784
785 thetaRad = (-90 + 4*thetaIndex)*pi/180;
786 phiRad = (-90 + 5*phiIndex)*pi/180;
787 // Rotate Photon Momentum in Theta, then in Phi
788 NewMomentum = -OldMomentum;
789 PerpendicularVectorTheta = NewMomentum.cross(theGlobalNormal);
790 if (PerpendicularVectorTheta.mag() > kCarTolerance ) {
791 PerpendicularVectorPhi =
792 PerpendicularVectorTheta.cross(NewMomentum);
793 }
794 else {
795 PerpendicularVectorTheta = NewMomentum.orthogonal();
796 PerpendicularVectorPhi =
797 PerpendicularVectorTheta.cross(NewMomentum);
798 }
799 NewMomentum =
800 NewMomentum.rotate(anglePhotonToNormal-thetaRad,
801 PerpendicularVectorTheta);
802 NewMomentum = NewMomentum.rotate(-phiRad,PerpendicularVectorPhi);
803 // Rotate Polarization too:
804 theFacetNormal = (NewMomentum - OldMomentum).unit();
805 EdotN = OldPolarization * theFacetNormal;
806 NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
807 }
808 } while (NewMomentum * theGlobalNormal <= 0.0);
809}
810
811void G4OpBoundaryProcess::DielectricDielectric()
812{
813 G4bool Inside = false;
814 G4bool Swap = false;
815
816 leap:
817
818 G4bool Through = false;
819 G4bool Done = false;
820
821 do {
822
823 if (Through) {
824 Swap = !Swap;
825 Through = false;
826 theGlobalNormal = -theGlobalNormal;
827 G4SwapPtr(Material1,Material2);
828 G4SwapObj(&Rindex1,&Rindex2);
829 }
830
831 if ( theFinish == polished ) {
832 theFacetNormal = theGlobalNormal;
833 }
834 else {
835 theFacetNormal =
836 GetFacetNormal(OldMomentum,theGlobalNormal);
837 }
838
839 G4double PdotN = OldMomentum * theFacetNormal;
840 G4double EdotN = OldPolarization * theFacetNormal;
841
842 cost1 = - PdotN;
843 if (std::abs(cost1) < 1.0-kCarTolerance){
844 sint1 = std::sqrt(1.-cost1*cost1);
845 sint2 = sint1*Rindex1/Rindex2; // *** Snell's Law ***
846 }
847 else {
848 sint1 = 0.0;
849 sint2 = 0.0;
850 }
851
852 if (sint2 >= 1.0) {
853
854 // Simulate total internal reflection
855
856 if (Swap) Swap = !Swap;
857
858 theStatus = TotalInternalReflection;
859
860 if ( theModel == unified && theFinish != polished )
861 ChooseReflection();
862
863 if ( theStatus == LambertianReflection ) {
864 DoReflection();
865 }
866 else if ( theStatus == BackScattering ) {
867 NewMomentum = -OldMomentum;
868 NewPolarization = -OldPolarization;
869 }
870 else {
871
872 PdotN = OldMomentum * theFacetNormal;
873 NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
874 EdotN = OldPolarization * theFacetNormal;
875 NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
876
877 }
878 }
879 else if (sint2 < 1.0) {
880
881 // Calculate amplitude for transmission (Q = P x N)
882
883 if (cost1 > 0.0) {
884 cost2 = std::sqrt(1.-sint2*sint2);
885 }
886 else {
887 cost2 = -std::sqrt(1.-sint2*sint2);
888 }
889
890 G4ThreeVector A_trans, A_paral, E1pp, E1pl;
891 G4double E1_perp, E1_parl;
892
893 if (sint1 > 0.0) {
894 A_trans = OldMomentum.cross(theFacetNormal);
895 A_trans = A_trans.unit();
896 E1_perp = OldPolarization * A_trans;
897 E1pp = E1_perp * A_trans;
898 E1pl = OldPolarization - E1pp;
899 E1_parl = E1pl.mag();
900 }
901 else {
902 A_trans = OldPolarization;
903 // Here we Follow Jackson's conventions and we set the
904 // parallel component = 1 in case of a ray perpendicular
905 // to the surface
906 E1_perp = 0.0;
907 E1_parl = 1.0;
908 }
909
910 G4double s1 = Rindex1*cost1;
911 G4double E2_perp = 2.*s1*E1_perp/(Rindex1*cost1+Rindex2*cost2);
912 G4double E2_parl = 2.*s1*E1_parl/(Rindex2*cost1+Rindex1*cost2);
913 G4double E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
914 G4double s2 = Rindex2*cost2*E2_total;
915
916 G4double TransCoeff;
917
918 if (theTransmittance > 0) TransCoeff = theTransmittance;
919 else if (cost1 != 0.0) TransCoeff = s2/s1;
920 else TransCoeff = 0.0;
921
922 G4double E2_abs, C_parl, C_perp;
923
924 if ( !G4BooleanRand(TransCoeff) ) {
925
926 // Simulate reflection
927
928 if (Swap) Swap = !Swap;
929
930 theStatus = FresnelReflection;
931
932 if ( theModel == unified && theFinish != polished )
933 ChooseReflection();
934
935 if ( theStatus == LambertianReflection ) {
936 DoReflection();
937 }
938 else if ( theStatus == BackScattering ) {
939 NewMomentum = -OldMomentum;
940 NewPolarization = -OldPolarization;
941 }
942 else {
943
944 PdotN = OldMomentum * theFacetNormal;
945 NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
946
947 if (sint1 > 0.0) { // incident ray oblique
948
949 E2_parl = Rindex2*E2_parl/Rindex1 - E1_parl;
950 E2_perp = E2_perp - E1_perp;
951 E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
952 A_paral = NewMomentum.cross(A_trans);
953 A_paral = A_paral.unit();
954 E2_abs = std::sqrt(E2_total);
955 C_parl = E2_parl/E2_abs;
956 C_perp = E2_perp/E2_abs;
957
958 NewPolarization = C_parl*A_paral + C_perp*A_trans;
959
960 }
961
962 else { // incident ray perpendicular
963
964 if (Rindex2 > Rindex1) {
965 NewPolarization = - OldPolarization;
966 }
967 else {
968 NewPolarization = OldPolarization;
969 }
970
971 }
972 }
973 }
974 else { // photon gets transmitted
975
976 // Simulate transmission/refraction
977
978 Inside = !Inside;
979 Through = true;
980 theStatus = FresnelRefraction;
981
982 if (sint1 > 0.0) { // incident ray oblique
983
984 G4double alpha = cost1 - cost2*(Rindex2/Rindex1);
985 NewMomentum = OldMomentum + alpha*theFacetNormal;
986 NewMomentum = NewMomentum.unit();
987 PdotN = -cost2;
988 A_paral = NewMomentum.cross(A_trans);
989 A_paral = A_paral.unit();
990 E2_abs = std::sqrt(E2_total);
991 C_parl = E2_parl/E2_abs;
992 C_perp = E2_perp/E2_abs;
993
994 NewPolarization = C_parl*A_paral + C_perp*A_trans;
995
996 }
997 else { // incident ray perpendicular
998
999 NewMomentum = OldMomentum;
1000 NewPolarization = OldPolarization;
1001
1002 }
1003 }
1004 }
1005
1006 OldMomentum = NewMomentum.unit();
1007 OldPolarization = NewPolarization.unit();
1008
1009 if (theStatus == FresnelRefraction) {
1010 Done = (NewMomentum * theGlobalNormal <= 0.0);
1011 }
1012 else {
1013 Done = (NewMomentum * theGlobalNormal >= 0.0);
1014 }
1015
1016 } while (!Done);
1017
1018 if (Inside && !Swap) {
1019 if( theFinish == polishedbackpainted ||
1020 theFinish == groundbackpainted ) {
1021
1022 if( !G4BooleanRand(theReflectivity) ) {
1023 DoAbsorption();
1024 }
1025 else {
1026 if (theStatus != FresnelRefraction ) {
1027 theGlobalNormal = -theGlobalNormal;
1028 }
1029 else {
1030 Swap = !Swap;
1031 G4SwapPtr(Material1,Material2);
1032 G4SwapObj(&Rindex1,&Rindex2);
1033 }
1034 if ( theFinish == groundbackpainted )
1035 theStatus = LambertianReflection;
1036
1037 DoReflection();
1038
1039 theGlobalNormal = -theGlobalNormal;
1040 OldMomentum = NewMomentum;
1041
1042 goto leap;
1043 }
1044 }
1045 }
1046}
1047
1048// GetMeanFreePath
1049// ---------------
1050//
1052 G4double ,
1054{
1055 *condition = Forced;
1056
1057 return DBL_MAX;
1058}
1059
1060G4double G4OpBoundaryProcess::GetIncidentAngle()
1061{
1062 G4double PdotN = OldMomentum * theFacetNormal;
1063 G4double magP= OldMomentum.mag();
1064 G4double magN= theFacetNormal.mag();
1065 G4double incidentangle = pi - std::acos(PdotN/(magP*magN));
1066
1067 return incidentangle;
1068}
1069
1070G4double G4OpBoundaryProcess::GetReflectivity(G4double E1_perp,
1071 G4double E1_parl,
1072 G4double incidentangle,
1073 G4double RealRindex,
1074 G4double ImaginaryRindex)
1075{
1076
1077 G4complex Reflectivity, Reflectivity_TE, Reflectivity_TM;
1078 G4complex N(RealRindex, ImaginaryRindex);
1079 G4complex CosPhi;
1080
1081 G4complex u(1,0); //unit number 1
1082
1083 G4complex numeratorTE; // E1_perp=1 E1_parl=0 -> TE polarization
1084 G4complex numeratorTM; // E1_parl=1 E1_perp=0 -> TM polarization
1085 G4complex denominatorTE, denominatorTM;
1086 G4complex rTM, rTE;
1087
1088 // Following two equations, rTM and rTE, are from: "Introduction To Modern
1089 // Optics" written by Fowles
1090
1091 CosPhi=std::sqrt(u-((std::sin(incidentangle)*std::sin(incidentangle))/(N*N)));
1092
1093 numeratorTE = std::cos(incidentangle) - N*CosPhi;
1094 denominatorTE = std::cos(incidentangle) + N*CosPhi;
1095 rTE = numeratorTE/denominatorTE;
1096
1097 numeratorTM = N*std::cos(incidentangle) - CosPhi;
1098 denominatorTM = N*std::cos(incidentangle) + CosPhi;
1099 rTM = numeratorTM/denominatorTM;
1100
1101 // This is my calculaton for reflectivity on a metalic surface
1102 // depending on the fraction of TE and TM polarization
1103 // when TE polarization, E1_parl=0 and E1_perp=1, R=abs(rTE)^2 and
1104 // when TM polarization, E1_parl=1 and E1_perp=0, R=abs(rTM)^2
1105
1106 Reflectivity_TE = (rTE*conj(rTE))*(E1_perp*E1_perp)
1107 / (E1_perp*E1_perp + E1_parl*E1_parl);
1108 Reflectivity_TM = (rTM*conj(rTM))*(E1_parl*E1_parl)
1109 / (E1_perp*E1_perp + E1_parl*E1_parl);
1110 Reflectivity = Reflectivity_TE + Reflectivity_TM;
1111
1112 do {
1113 if(G4UniformRand()*real(Reflectivity) > real(Reflectivity_TE))
1114 {iTE = -1;}else{iTE = 1;}
1115 if(G4UniformRand()*real(Reflectivity) > real(Reflectivity_TM))
1116 {iTM = -1;}else{iTM = 1;}
1117 } while(iTE<0&&iTM<0);
1118
1119 return real(Reflectivity);
1120
1121}
1122
1123void G4OpBoundaryProcess::CalculateReflectivity()
1124{
1125 G4double RealRindex =
1126 PropertyPointer1->Value(thePhotonMomentum);
1127 G4double ImaginaryRindex =
1128 PropertyPointer2->Value(thePhotonMomentum);
1129
1130 // calculate FacetNormal
1131 if ( theFinish == ground ) {
1132 theFacetNormal =
1133 GetFacetNormal(OldMomentum, theGlobalNormal);
1134 } else {
1135 theFacetNormal = theGlobalNormal;
1136 }
1137
1138 G4double PdotN = OldMomentum * theFacetNormal;
1139 cost1 = -PdotN;
1140
1141 if (std::abs(cost1) < 1.0 - kCarTolerance) {
1142 sint1 = std::sqrt(1. - cost1*cost1);
1143 } else {
1144 sint1 = 0.0;
1145 }
1146
1147 G4ThreeVector A_trans, A_paral, E1pp, E1pl;
1148 G4double E1_perp, E1_parl;
1149
1150 if (sint1 > 0.0 ) {
1151 A_trans = OldMomentum.cross(theFacetNormal);
1152 A_trans = A_trans.unit();
1153 E1_perp = OldPolarization * A_trans;
1154 E1pp = E1_perp * A_trans;
1155 E1pl = OldPolarization - E1pp;
1156 E1_parl = E1pl.mag();
1157 }
1158 else {
1159 A_trans = OldPolarization;
1160 // Here we Follow Jackson's conventions and we set the
1161 // parallel component = 1 in case of a ray perpendicular
1162 // to the surface
1163 E1_perp = 0.0;
1164 E1_parl = 1.0;
1165 }
1166
1167 //calculate incident angle
1168 G4double incidentangle = GetIncidentAngle();
1169
1170 //calculate the reflectivity depending on incident angle,
1171 //polarization and complex refractive
1172
1173 theReflectivity =
1174 GetReflectivity(E1_perp, E1_parl, incidentangle,
1175 RealRindex, ImaginaryRindex);
1176}
G4double condition(const G4ErrorSymMatrix &m)
@ EventMustBeAborted
G4ForceCondition
@ Forced
G4OpBoundaryProcessStatus
@ PolishedTiOAirReflection
@ GroundTeflonAirReflection
@ EtchedVM2000AirReflection
@ Undefined
@ NotAtBoundary
@ EtchedVM2000GlueReflection
@ GroundLumirrorGlueReflection
@ LobeReflection
@ GroundTiOAirReflection
@ GroundTyvekAirReflection
@ FresnelReflection
@ 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
@ fOpBoundary
@ unified
@ glisur
@ groundfrontpainted
@ polishedbackpainted
@ polished
@ ground
@ polishedfrontpainted
@ groundbackpainted
G4ProcessType
@ fGeomBoundary
Definition: G4StepStatus.hh:54
G4SurfaceType
@ dielectric_metal
@ dielectric_LUT
@ dielectric_dielectric
@ fStopAndKill
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
std::complex< G4double > G4complex
Definition: G4Types.hh:69
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
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 setX(double)
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:72
Hep3Vector & rotate(double, const Hep3Vector &)
Definition: ThreeVectorR.cc:28
static long shootInt(long n)
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)
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
Definition: G4Material.hh:251
virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &point, G4bool *valid)
G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *condition)
G4OpBoundaryProcess(const G4String &processName="OpBoundary", G4ProcessType type=fOptical)
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
G4OpticalSurfaceModel GetModel() const
G4double GetSigmaAlpha() const
G4OpticalSurfaceFinish GetFinish() const
G4int GetThetaIndexMax(void) const
G4int GetPhiIndexMax(void) const
G4double GetPolish() const
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 theEnergy)
G4StepStatus GetStepStatus() const
const G4ThreeVector & GetPosition() const
G4VPhysicalVolume * GetPhysicalVolume() const
Definition: G4Step.hh:78
G4StepPoint * GetPreStepPoint() const
G4StepPoint * GetPostStepPoint() const
const G4SurfaceType & GetType() const
G4double GetVelocity() const
const G4DynamicParticle * GetDynamicParticle() const
G4double GetStepLength() const
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
G4ParticleChange aParticleChange
Definition: G4VProcess.hh:289
G4int verboseLevel
Definition: G4VProcess.hh:368
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:403
const G4String & GetProcessName() const
Definition: G4VProcess.hh:379
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
void G4SwapObj(T *a, T *b)
Definition: templates.hh:129
void G4SwapPtr(T *&a, T *&b)
Definition: templates.hh:121
#define DBL_MAX
Definition: templates.hh:83