G4XTankOpBoundaryProcess.cc
Go to the documentation of this file.
1 /*
2  Note by RU Mi Jan 12 17:07:05 CET 2005
3 
4  This is a modified standart G4 file. It is part of the G4 distribution and
5  modified occasionally by the G4 developers.
6 
7  One should keep an eye on bug-fixes available in G4!
8 
9  From G4 version 6.2 to G4 version 7.0 there was kinf of a rupture in some
10  G4 base classes. For details see:
11  http://geant4.web.cern.ch/geant4/source/source/migration_70.html
12  This means, that code written for 6.2 is not running under 7.0 neccesarily.
13  For G4OpBoundaryProcess this was the case. To take care of this the
14  Offline configure script is now testing for G4 version >= 7.0 and is
15  defining a pre-processor flag: GEANT4_v7
16  This is now used to choose the proper methods for G4.
17 */
18 
19 #include <config.h>
20 #define GEANT4_V7 1
21 
23 // Optical Photon Boundary Process Class Implementation
25 //
26 // File: G4XTankOpBoundaryProcess.cc
27 // Description: Discrete Process -- reflection/refraction at
28 // optical interfaces
29 // Version: 1.1
30 // Created: 1997-06-18
31 // Modified: 1998-05-25 - Correct parallel component of polarization
32 // (thanks to: Stefano Magni + Giovanni Pieri)
33 // 1998-05-28 - NULL Rindex pointer before reuse
34 // (thanks to: Stefano Magni)
35 // 1998-06-11 - delete *sint1 in oblique reflection
36 // (thanks to: Giovanni Pieri)
37 // 1998-06-19 - move from GetLocalExitNormal() to the new
38 // method: GetLocalExitNormal(&valid) to get
39 // the surface normal in all cases
40 // 1998-11-07 - NULL OpticalSurface pointer before use
41 // comparison not sharp for: abs(cost1) < 1.0
42 // remove sin1, sin2 in lines 556,567
43 // (thanks to Stefano Magni)
44 // 1999-10-10 - Accommodate changes done in DoAbsorption by
45 // changing logic in DielectricMetal
46 //
47 // Author: Peter Gumplinger
48 // adopted from work by Werner Keil - April 2/96
49 // mail: gum@triumf.ca
50 //
52 
53 #include "G4ios.hh"
54 #include "G4ProcessType.hh"
55 
57 
58 #include <utl/config.h>
59 
60 #include <iostream>
61 
62 using namespace std;
63 
64 using namespace G4XTankSimulatorAG;
65 
67 // Class Implementation
69 
71 // Operators
73 
74 // G4XTankOpBoundaryProcess::operator=(const G4XTankOpBoundaryProcess& right)
75 // {
76 // }
77 
78 using CLHEP::RandGauss;
79 
80 
82 // Constructors
84 
85 //#ifdef GEANT4_V7_1_p1
86 G4XTankOpBoundaryProcess::G4XTankOpBoundaryProcess(const G4String& processName,
87  G4ProcessType /*type*/) :
88  G4VDiscreteProcess(processName, fOptical)
89 {
90 /*#else
91 G4XTankOpBoundaryProcess::G4XTankOpBoundaryProcess(const G4String& processName)
92  : G4VDiscreteProcess(processName, fOptical) {
93 #endif*/
94 
95  if (verboseLevel > 0)
96  G4cerr << GetProcessName() << " is created " << G4endl;
97 
99  theModel = glisur;
100  theFinish = polished;
101 }
102 
103 
104 // G4XTankOpBoundaryProcess::G4XTankOpBoundaryProcess(const G4XTankOpBoundaryProcess& right)
105 // {
106 // }
107 
109 // Destructors
111 
113 
115 // Methods
117 
118 // PostStepDoIt
119 // ------------
120 //
121 G4VParticleChange *G4XTankOpBoundaryProcess::PostStepDoIt(const G4Track& aTrack,
122  const G4Step& aStep) {
123 
124  aParticleChange.Initialize(aTrack);
125 
126  G4StepPoint *pPreStepPoint = aStep.GetPreStepPoint();
127  G4StepPoint *pPostStepPoint = aStep.GetPostStepPoint();
128 
129  if (pPostStepPoint->GetStepStatus() != fGeomBoundary)
130  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
131 
132  if (aTrack.GetStepLength()<=kCarTolerance/2)
133  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
134 
135  Material1 =
136  pPreStepPoint ->GetPhysicalVolume()->GetLogicalVolume()->GetMaterial();
137  Material2 =
138  pPostStepPoint->GetPhysicalVolume()->GetLogicalVolume()->GetMaterial();
139 
140  if (Material1 == Material2)
141  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
142 
143  const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
144 
145  thePhotonMomentum = aParticle->GetTotalMomentum();
146  OldMomentum = aParticle->GetMomentumDirection();
147  OldPolarization = aParticle->GetPolarization();
148 
149  if (verboseLevel > 0) {
150 
151  G4cerr << " Photon at Boundary! " << G4endl;
152  G4cerr << " Old Momentum Direction: " << OldMomentum << G4endl;
153  G4cerr << " Old Polarization: " << OldPolarization << G4endl;
154 
155  }
156 
157  G4MaterialPropertiesTable* aMaterialPropertiesTable;
158  G4MaterialPropertyVector* Rindex;
159 
160  aMaterialPropertiesTable = Material1->GetMaterialPropertiesTable();
161 
162  if (aMaterialPropertiesTable) {
163 
164  Rindex = aMaterialPropertiesTable->GetProperty("RINDEX");
165 
166  } else {
167 
168 #ifdef GEANT4_V7 // ----------- see note on top of file --------------------
169  aParticleChange.ProposeTrackStatus (fStopAndKill);
170 #else
171  aParticleChange.SetStatusChange (fStopAndKill);
172 #endif // ------------------------------------------------------------------
173 
174  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
175 
176  }
177 
178 
179  if (Rindex) {
180 
181  Rindex1 = Rindex->GetProperty(thePhotonMomentum);
182 
183  } else {
184 
185 #ifdef GEANT4_V7 // ----------- see note on top of file --------------------
186  aParticleChange.ProposeTrackStatus (fStopAndKill);
187 #else
188  aParticleChange.SetStatusChange (fStopAndKill);
189 #endif // ------------------------------------------------------------------
190 
191  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
192 
193  }
194 
195  Rindex = NULL;
196  OpticalSurface = NULL;
197 
198  aMaterialPropertiesTable = Material2->GetMaterialPropertiesTable();
199 
200  if (aMaterialPropertiesTable) {
201 
202  Rindex = aMaterialPropertiesTable->GetProperty("RINDEX");
203 
204  }
205 
206  G4LogicalSurface* Surface =
207  G4LogicalBorderSurface::GetSurface(pPreStepPoint ->GetPhysicalVolume(),
208  pPostStepPoint->GetPhysicalVolume());
209 
210  if (Surface == NULL) {
211 
212  Surface =
213  G4LogicalSkinSurface::GetSurface(pPreStepPoint->GetPhysicalVolume()
214  ->GetLogicalVolume());
215 
216  }
217 
218  if (Surface != NULL) {
219 
220  //OpticalSurface = Surface->GetOpticalSurface();
221  OpticalSurface = (G4OpticalSurface*) Surface->GetSurfaceProperty();
222  }
223 
224  theModel = glisur;
225  theFinish = polished;
226 
227  //G4OpticalSurfaceType type;
228 
229  G4SurfaceType type;
230 
231  if (Rindex) {
232 
233  type = dielectric_dielectric;
234  Rindex2 = Rindex->GetProperty(thePhotonMomentum);
235 
236  } else if (OpticalSurface) {
237 
238  type = OpticalSurface->GetType();
239 
240  } else {
241 
242 #ifdef GEANT4_V7 // ----------- see note on top of file --------------------
243  aParticleChange.ProposeTrackStatus (fStopAndKill);
244 #else
245  aParticleChange.SetStatusChange (fStopAndKill);
246 #endif // ------------------------------------------------------------------
247 
248  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
249 
250  }
251 
252  if (OpticalSurface) {
253 
254  theModel = OpticalSurface->GetModel();
255  theFinish = OpticalSurface->GetFinish();
256 
257  aMaterialPropertiesTable = OpticalSurface->GetMaterialPropertiesTable();
258 
259  if (aMaterialPropertiesTable) {
260 
261  G4MaterialPropertyVector* PropertyPointer;
262 
263  if (!Rindex) {
264 
265  PropertyPointer = aMaterialPropertiesTable->GetProperty("RINDEX");
266 
267  if (PropertyPointer)
268  Rindex2 = PropertyPointer->GetProperty(thePhotonMomentum);
269 
270  }
271 
272  PropertyPointer = aMaterialPropertiesTable->GetProperty("REFLECTIVITY");
273 
274  if (PropertyPointer)
275  theReflectivity = PropertyPointer->GetProperty(thePhotonMomentum);
276 
277  PropertyPointer = aMaterialPropertiesTable->GetProperty("EFFICIENCY");
278 
279  if (PropertyPointer)
280  theEfficiency = PropertyPointer->GetProperty(thePhotonMomentum);
281 
282  if (theModel == unified) {
283 
284  PropertyPointer =
285  aMaterialPropertiesTable->GetProperty("SPECULARLOBECONSTANT");
286 
287  if (PropertyPointer)
288  prob_sl = PropertyPointer->GetProperty(thePhotonMomentum);
289 
290  PropertyPointer =
291  aMaterialPropertiesTable->GetProperty("SPECULARSPIKECONSTANT");
292 
293  if (PropertyPointer)
294  prob_ss = PropertyPointer->GetProperty(thePhotonMomentum);
295 
296  PropertyPointer =
297  aMaterialPropertiesTable->GetProperty("BACKSCATTERCONSTANT");
298 
299  if (PropertyPointer)
300  prob_bs = PropertyPointer->GetProperty(thePhotonMomentum);
301 
302  }
303 
304  }
305 
306  }
307 
308  // No optical surface
309 
310  G4ThreeVector theGlobalPoint = pPostStepPoint->GetPosition();
311 
312  G4Navigator *theNavigator =
313  G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking();
314 
315  G4ThreeVector theLocalPoint =
316  theNavigator->GetGlobalToLocalTransform().TransformPoint(theGlobalPoint);
317 
318  G4ThreeVector theLocalNormal; // Normal points back into volume
319 
320  G4bool valid;
321 
322  theLocalNormal = theNavigator->GetLocalExitNormal(&valid);
323 
324  if (valid) {
325 
326  theLocalNormal = -theLocalNormal;
327 
328  } else {
329 
330  G4cerr << " G4XTankOpBoundaryProcess/PostStepDoIt(): "
331  << " The Navigator reports that it returned an invalid normal"
332  << G4endl;
333 
334  }
335 
337  theNavigator->GetLocalToGlobalTransform().TransformAxis(theLocalNormal);
338 
339  /*
340  //tm//
341  if ( Material2->GetName() == "HDPE" )
342  {
343  double MdotN = OldMomentum * theLocalNormal;
344  MdotN = -MdotN;
345  double angle = acos(MdotN)/deg;
346  }
347  */
348 
350 
351  if (type == dielectric_metal) {
352 
353  DielectricMetal();
354 
355  } else if (type == dielectric_dielectric) {
356 
357  if (theFinish == polishedfrontpainted || theFinish == groundfrontpainted) {
358 
360 
361  DoAbsorption();
362 
363  } else {
364 
365  if (theFinish == groundfrontpainted)
367  DoReflection();
368 
369  }
370 
371  } else {
372 
373  // MY HACK (tp)
374  // (I added the DoAbsorption option so that it
375  // takes effect even for the ground finish. I had to
376  // do this because groundbackpainted option causes a crash
377  // somewhere in G4Tubs..)
378  // tm : Oct. 19, 2001
379  // This hack creates a problem when the photons go
380  // directly from the water to a surface where the
381  // OpticalSurface machinery has not been used (like the dome)
382  // The reflectivity is then 0 and all the photon are
383  // absorbed. Also, this hack screws up a normal
384  // optical interface because it checks against the
385  // reflectivity instead of doing it the way it should,
386  // in for example, Jackson. Only check against the
387  // reflectivity for tyvek...
388 
389  if (Material2->GetName() == "HDPE") {
390 
392  DoAbsorption();
393  else
395 
396  } else {
397 
399 
400  }
401 
402  }
403 
404  } else {
405 
406  G4cerr << " Error: G4BoundaryProcess: illegal boundary type " << G4endl;
407  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
408 
409  }
410 
411  NewMomentum = NewMomentum.unit();
413 
414 #ifdef GEANT4_V7 // ----------- see note on top of file --------------------
415  aParticleChange.ProposeMomentumDirection (NewMomentum);
416  aParticleChange.ProposePolarization (NewPolarization);
417 #else
418  aParticleChange.SetMomentumChange (NewMomentum);
419  aParticleChange.SetPolarizationChange (NewPolarization);
420 #endif // ------------------------------------------------------------------
421 
422  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
423 
424 }
425 
426 G4ThreeVector
427 G4XTankOpBoundaryProcess::GetFacetNormal(const G4ThreeVector& Momentum,
428  const G4ThreeVector& Normal) const {
429 
430  G4ThreeVector FacetNormal;
431 
432  if (theModel == unified) {
433 
434  /* This function code alpha to a random value taken from the
435  distribution p(alpha) = g(alpha; 0, sigma_alpha)*sin(alpha),
436  for alpha > 0 and alpha < 90, where g(alpha; 0, sigma_alpha)
437  is a gaussian distribution with mean 0 and standard deviation
438  sigma_alpha. */
439 
440  G4double alpha;
441 
442  G4double sigma_alpha = 0.0;
443 
444  if (OpticalSurface) sigma_alpha = OpticalSurface->GetSigmaAlpha();
445 
446  G4double f_max = std::min(1.0,4.*sigma_alpha);
447 
448  do {
449 
450  do {
451  alpha = RandGauss::shoot(0.0,sigma_alpha);
452  } while (G4UniformRand()*f_max > std::sin(alpha) || alpha >= halfpi);
453 
454  G4double phi = G4UniformRand()*twopi;
455 
456  G4double SinAlpha = std::sin(alpha);
457  G4double CosAlpha = std::cos(alpha);
458  G4double SinPhi = std::sin(phi);
459  G4double CosPhi = std::cos(phi);
460 
461  G4double unit_x = SinAlpha * CosPhi;
462  G4double unit_y = SinAlpha * SinPhi;
463  G4double unit_z = CosAlpha;
464 
465  FacetNormal.setX(unit_x);
466  FacetNormal.setY(unit_y);
467  FacetNormal.setZ(unit_z);
468 
469  G4ThreeVector tmpNormal = Normal;
470 
471  FacetNormal.rotateUz(tmpNormal);
472 
473  } while (Momentum * FacetNormal >= 0.0);
474 
475  } else {
476 
477  G4double polish = 1.0;
478 
479  if (OpticalSurface) polish = OpticalSurface->GetPolish();
480 
481  if (polish < 1.0) {
482 
483  do {
484 
485  G4ThreeVector smear;
486 
487  do {
488 
489  smear.setX(2.*G4UniformRand()-1.0);
490  smear.setY(2.*G4UniformRand()-1.0);
491  smear.setZ(2.*G4UniformRand()-1.0);
492 
493  } while (smear.mag() > 1.0);
494 
495  smear = (1.-polish) * smear;
496  FacetNormal = Normal + smear;
497 
498  } while (Momentum * FacetNormal >= 0.0);
499 
500  FacetNormal = FacetNormal.unit();
501 
502  } else {
503 
504  FacetNormal = Normal;
505 
506  }
507 
508  }
509 
510  return FacetNormal;
511 
512 }
513 
515 {
516 
517  do {
518 
520 
521  DoAbsorption();
522  break;
523 
524  } else {
525 
526  DoReflection();
527 
530 
531  }
532 
533  } while (NewMomentum * theGlobalNormal < 0.0);
534 
535 }
536 
538 {
539 
540  G4bool Inside = false;
541  G4bool Swap = false;
542 
543  leap:
544 
545  G4bool Through = false;
546  G4bool Done = false;
547 
548  do {
549 
550  if (Through) {
551 
552  Swap = !Swap;
553  Through = false;
557 
558  }
559 
560  if (theFinish == ground || theFinish == groundbackpainted) {
561 
563 
564  } else {
565 
567 
568  }
569 
570  G4double PdotN = OldMomentum * theFacetNormal;
571  G4double EdotN = OldPolarization * theFacetNormal;
572 
573  cost1 = - PdotN;
574 
575  if (std::abs(cost1) < 1.0-kCarTolerance) {
576 
577  sint1 = std::sqrt(1.-cost1*cost1);
578  sint2 = sint1*Rindex1/Rindex2; // *** Snell's Law ***
579 
580  } else {
581 
582  sint1 = 0.0;
583  sint2 = 0.0;
584 
585  }
586 
587  if (sint2 >= 1.0) {
588 
589  // Simulate total internal reflection
590 
591  if (Swap) Swap = !Swap;
592 
594 
595  if (theModel == unified && theFinish != polished)
597 
599 
600  DoReflection();
601 
602  } else if (theStatus == BackScattering) {
603 
606 
607  } else {
608 
609  PdotN = OldMomentum * theFacetNormal;
610  NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
612  NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
613 
614  }
615 
616  } else if (sint2 < 1.0) {
617 
618  // Calculate amplitude for transmission (Q = P x N)
619 
620  if (cost1 > 0.0) {
621 
622  cost2 = std::sqrt(1.-sint2*sint2);
623 
624  } else {
625 
626  cost2 = -std::sqrt(1.-sint2*sint2);
627 
628  }
629 
630  G4ThreeVector A_trans, Atrans, E1pp, E1pl;
631  G4double E1_perp, E1_parl;
632 
633  if (sint1 > 0.0) {
634 
635  A_trans = OldMomentum.cross(theFacetNormal);
636  Atrans = A_trans.unit();
637  E1_perp = OldPolarization * Atrans;
638  E1pp = E1_perp * Atrans;
639  E1pl = OldPolarization - E1pp;
640  E1_parl = E1pl.mag();
641 
642  } else {
643 
644  A_trans = OldPolarization;
645  // Here we Follow Jackson's conventions and we set the
646  // parallel component = 1 in case of a ray perpendicular
647  // to the surface
648  E1_perp = 0.0;
649  E1_parl = 1.0;
650 
651  }
652 
653  G4double E2_perp = 0;
654  G4double E2_parl = 0;
655  G4double E2_total = 0;
656  G4double TransCoeff = 0;
657 
658  if (cost1 != 0.0) {
659 
660  G4double s1 = Rindex1*cost1;
661  E2_perp = 2.*s1*E1_perp/(Rindex1*cost1+Rindex2*cost2);
662  E2_parl = 2.*s1*E1_parl/(Rindex2*cost1+Rindex1*cost2);
663  E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
664  G4double s2 = Rindex2*cost2*E2_total;
665  TransCoeff = s2/s1;
666 
667  }
668 
669  G4ThreeVector Refracted, Deflected;
670  G4double E2_abs, C_parl, C_perp;
671 
672  if (!G4BooleanRand(TransCoeff)) {
673 
674  // Simulate reflection
675 
676  if (Swap) Swap = !Swap;
677 
679 
680  if (theModel == unified && theFinish != polished)
682 
684 
685  DoReflection();
686 
687  } else if (theStatus == BackScattering) {
688 
691 
692  } else {
693 
694  PdotN = OldMomentum * theFacetNormal;
695  NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
696 
697  if (sint1 > 0.0) {// incident ray oblique
698 
699  E2_parl = Rindex2*E2_parl/Rindex1 - E1_parl;
700  E2_perp = E2_perp - E1_perp;
701  E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
702  Refracted = theFacetNormal + PdotN * NewMomentum;
703  E2_abs = std::sqrt(E2_total);
704  C_parl = E2_parl/E2_abs;
705  C_perp = E2_perp/E2_abs;
706 
707  NewPolarization = C_parl*Refracted - C_perp*A_trans;
708 
709  } else if (Rindex2 > Rindex1) { // incident ray perpendicular
710 
712 
713  }
714 
715  }
716 
717  } else { // photon gets transmitted
718 
719  // Simulate transmission/refraction
720 
721  Inside = !Inside;
722  Through = true;
724 
725  if (sint1 > 0.0) {// incident ray oblique
726 
727  G4double alpha = cost1 - cost2*(Rindex2/Rindex1);
728  Deflected = OldMomentum + alpha*theFacetNormal;
729  NewMomentum = Deflected.unit();
730  PdotN = -cost2;
731  Refracted = theFacetNormal - PdotN*NewMomentum;
732  E2_abs = std::sqrt(E2_total);
733  C_parl = E2_parl/E2_abs;
734  C_perp = E2_perp/E2_abs;
735  NewPolarization = C_parl*Refracted + C_perp*A_trans;
736 
737  } else {// incident ray perpendicular
738 
741 
742  }
743 
744  }
745 
746  }
747 
750 
751  if (theStatus == FresnelRefraction) {
752 
753  Done = (NewMomentum * theGlobalNormal <= 0.0);
754 
755  } else {
756 
757  Done = (NewMomentum * theGlobalNormal >= 0.0);
758 
759  }
760 
761  } while (!Done);
762 
763  if (Inside && !Swap) {
764 
765  if (theFinish == polishedbackpainted || theFinish == groundbackpainted) {
766 
768 
769  DoAbsorption();
770 
771  } else {
772 
773  if (theStatus != FresnelRefraction) {
774 
776 
777  } else {
778 
779  Swap = !Swap;
782 
783  }
784 
785  if (theFinish == groundbackpainted) theStatus = LambertianReflection;
786 
787  DoReflection();
788 
791 
792  goto leap;
793 
794  }
795 
796  }
797 
798  }
799 
800 }
801 
802 // GetMeanFreePath
803 // ---------------
804 //
806  G4double ,
807  G4ForceCondition* condition) {
808 
809  *condition = Forced;
810  return DBL_MAX;
811 
812 }
G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *condition)
void G4Swap(G4double *a, G4double *b) const
G4bool G4BooleanRand(const G4double prob) const
double abs(const SVector< n, T > &v)
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
G4ThreeVector GetFacetNormal(const G4ThreeVector &Momentum, const G4ThreeVector &Normal) const

, generated on Tue Sep 26 2023.