Deprecated/UpgradeASCIITests/G4TankSimulatorASCII/G4TankOpBoundaryProcess.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: G4TankOpBoundaryProcess.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 using namespace G4TankSimulatorASCII;
64 using CLHEP::RandGauss;
65 
66 
67 // Class Implementation
68 
69 
70 // Operators
71 
72 /*G4TankOpBoundaryProcess::operator=(const G4TankOpBoundaryProcess& right)
73 { }*/
74 
75 
76 // Constructors
77 
78 G4TankOpBoundaryProcess::G4TankOpBoundaryProcess(const G4String& processName, G4ProcessType /*type*/) :
79  G4VDiscreteProcess(processName, fOptical)
80 {
81  if (verboseLevel > 0)
82  G4cerr << GetProcessName() << " is created " << G4endl;
83 
85  theModel = glisur;
86  theFinish = polished;
87 }
88 
89 
90 /*G4TankOpBoundaryProcess::G4TankOpBoundaryProcess(const G4TankOpBoundaryProcess& right)
91 { }*/
92 
93 
94 // Destructors
95 
97 { }
98 
99 
100 // Methods
101 
102 // PostStepDoIt
103 G4VParticleChange*
104 G4TankOpBoundaryProcess::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep)
105 {
106  aParticleChange.Initialize(aTrack);
107 
108  G4StepPoint *pPreStepPoint = aStep.GetPreStepPoint();
109  G4StepPoint *pPostStepPoint = aStep.GetPostStepPoint();
110 
111  if (pPostStepPoint->GetStepStatus() != fGeomBoundary)
112  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
113 
114  if (aTrack.GetStepLength() <= 0.5*kCarTolerance)
115  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
116 
117  Material1 = pPreStepPoint->GetPhysicalVolume()->GetLogicalVolume()->GetMaterial();
118  Material2 = pPostStepPoint->GetPhysicalVolume()->GetLogicalVolume()->GetMaterial();
119 
120  if (Material1 == Material2)
121  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
122 
123  const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
124 
125  thePhotonMomentum = aParticle->GetTotalMomentum();
126  OldMomentum = aParticle->GetMomentumDirection();
127  OldPolarization = aParticle->GetPolarization();
128 
129  if (verboseLevel > 0)
130  G4cerr << " Photon at Boundary! \n"
131  " Old Momentum Direction: " << OldMomentum << "\n"
132  " Old Polarization: " << OldPolarization << G4endl;
133 
134  G4MaterialPropertyVector* Rindex;
135 
136  G4MaterialPropertiesTable* aMaterialPropertiesTable = Material1->GetMaterialPropertiesTable();
137 
138  if (aMaterialPropertiesTable) {
139 
140  Rindex = aMaterialPropertiesTable->GetProperty("RINDEX");
141 
142  } else {
143 
144 #ifdef GEANT4_V7 // ----------- see note on top of file --------------------
145  aParticleChange.ProposeTrackStatus(fStopAndKill);
146 #else
147  aParticleChange.SetStatusChange(fStopAndKill);
148 #endif // ------------------------------------------------------------------
149 
150  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
151 
152  }
153 
154  if (Rindex) {
155 
156  Rindex1 = Rindex->GetProperty(thePhotonMomentum);
157 
158  } else {
159 
160 #ifdef GEANT4_V7 // ----------- see note on top of file --------------------
161  aParticleChange.ProposeTrackStatus(fStopAndKill);
162 #else
163  aParticleChange.SetStatusChange(fStopAndKill);
164 #endif // ------------------------------------------------------------------
165 
166  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
167 
168  }
169 
170  Rindex = NULL;
171  OpticalSurface = NULL;
172 
173  aMaterialPropertiesTable = Material2->GetMaterialPropertiesTable();
174 
175  if (aMaterialPropertiesTable) {
176 
177  Rindex = aMaterialPropertiesTable->GetProperty("RINDEX");
178 
179  }
180 
181  G4LogicalSurface* Surface =
182  G4LogicalBorderSurface::GetSurface(pPreStepPoint ->GetPhysicalVolume(),
183  pPostStepPoint->GetPhysicalVolume());
184 
185  if (Surface == NULL) {
186 
187  Surface =
188  G4LogicalSkinSurface::GetSurface(pPreStepPoint->GetPhysicalVolume()
189  ->GetLogicalVolume());
190 
191  }
192 
193  if (Surface != NULL) {
194 
195  //OpticalSurface = Surface->GetOpticalSurface();
196  OpticalSurface = (G4OpticalSurface*) Surface->GetSurfaceProperty();
197  }
198 
199  theModel = glisur;
200  theFinish = polished;
201 
202  //G4OpticalSurfaceType type;
203 
204  G4SurfaceType type;
205 
206  if (Rindex) {
207 
208  type = dielectric_dielectric;
209  Rindex2 = Rindex->GetProperty(thePhotonMomentum);
210 
211  } else if (OpticalSurface) {
212 
213  type = OpticalSurface->GetType();
214 
215  } else {
216 
217 #ifdef GEANT4_V7 // ----------- see note on top of file --------------------
218  aParticleChange.ProposeTrackStatus(fStopAndKill);
219 #else
220  aParticleChange.SetStatusChange(fStopAndKill);
221 #endif // ------------------------------------------------------------------
222 
223  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
224 
225  }
226 
227  if (OpticalSurface) {
228 
229  theModel = OpticalSurface->GetModel();
230  theFinish = OpticalSurface->GetFinish();
231 
232  aMaterialPropertiesTable = OpticalSurface->GetMaterialPropertiesTable();
233 
234  if (aMaterialPropertiesTable) {
235 
236  G4MaterialPropertyVector* PropertyPointer;
237 
238  if (!Rindex) {
239 
240  PropertyPointer = aMaterialPropertiesTable->GetProperty("RINDEX");
241 
242  if (PropertyPointer)
243  Rindex2 = PropertyPointer->GetProperty(thePhotonMomentum);
244 
245  }
246 
247  PropertyPointer = aMaterialPropertiesTable->GetProperty("REFLECTIVITY");
248 
249  if (PropertyPointer)
250  theReflectivity = PropertyPointer->GetProperty(thePhotonMomentum);
251 
252  PropertyPointer = aMaterialPropertiesTable->GetProperty("EFFICIENCY");
253 
254  if (PropertyPointer)
255  theEfficiency = PropertyPointer->GetProperty(thePhotonMomentum);
256 
257  if (theModel == unified) {
258 
259  PropertyPointer = aMaterialPropertiesTable->GetProperty("SPECULARLOBECONSTANT");
260 
261  if (PropertyPointer)
262  prob_sl = PropertyPointer->GetProperty(thePhotonMomentum);
263 
264  PropertyPointer = aMaterialPropertiesTable->GetProperty("SPECULARSPIKECONSTANT");
265 
266  if (PropertyPointer)
267  prob_ss = PropertyPointer->GetProperty(thePhotonMomentum);
268 
269  PropertyPointer = aMaterialPropertiesTable->GetProperty("BACKSCATTERCONSTANT");
270 
271  if (PropertyPointer)
272  prob_bs = PropertyPointer->GetProperty(thePhotonMomentum);
273 
274  }
275 
276  }
277 
278  }
279 
280  // No optical surface
281 
282  G4ThreeVector theGlobalPoint = pPostStepPoint->GetPosition();
283 
284  G4Navigator* theNavigator =
285  G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking();
286 
287  G4ThreeVector theLocalPoint =
288  theNavigator->GetGlobalToLocalTransform().TransformPoint(theGlobalPoint);
289 
290  G4ThreeVector theLocalNormal; // Normal points back into volume
291 
292  G4bool valid;
293 
294  theLocalNormal = theNavigator->GetLocalExitNormal(&valid);
295 
296  if (valid) {
297 
298  theLocalNormal = -theLocalNormal;
299 
300  } else {
301 
302  G4cerr << " G4TankOpBoundaryProcess/PostStepDoIt(): "
303  " The Navigator reports that it returned an invalid normal"
304  << G4endl;
305 
306  }
307 
308  theGlobalNormal = theNavigator->GetLocalToGlobalTransform().TransformAxis(theLocalNormal);
309 
310  /*
311  //tm//
312  if ( Material2->GetName() == "HDPE" )
313  {
314  double MdotN = OldMomentum * theLocalNormal;
315  MdotN = -MdotN;
316  double angle = acos(MdotN)/deg;
317  }
318  */
319 
321 
322  if (type == dielectric_metal) {
323 
324  DielectricMetal();
325 
326  } else if (type == dielectric_dielectric) {
327 
328  if (theFinish == polishedfrontpainted || theFinish == groundfrontpainted) {
329 
331 
332  DoAbsorption();
333 
334  } else {
335 
336  if (theFinish == groundfrontpainted)
338  DoReflection();
339 
340  }
341 
342  } else {
343 
344  // MY HACK (tp)
345  // (I added the DoAbsorption option so that it
346  // takes effect even for the ground finish. I had to
347  // do this because groundbackpainted option causes a crash
348  // somewhere in G4Tubs..)
349  // tm : Oct. 19, 2001
350  // This hack creates a problem when the photons go
351  // directly from the water to a surface where the
352  // OpticalSurface machinery has not been used (like the dome)
353  // The reflectivity is then 0 and all the photon are
354  // absorbed. Also, this hack screws up a normal
355  // optical interface because it checks against the
356  // reflectivity instead of doing it the way it should,
357  // in for example, Jackson. Only check against the
358  // reflectivity for tyvek...
359 
360  if (Material2->GetName() == "HDPE") {
361 
363  DoAbsorption();
364  else
366 
367  } else {
368 
370 
371  }
372 
373  }
374 
375  } else {
376 
377  G4cerr << " Error: G4BoundaryProcess: illegal boundary type" << G4endl;
378  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
379 
380  }
381 
382  NewMomentum = NewMomentum.unit();
384 
385 #ifdef GEANT4_V7 // ----------- see note on top of file --------------------
386  aParticleChange.ProposeMomentumDirection(NewMomentum);
387  aParticleChange.ProposePolarization(NewPolarization);
388 #else
389  aParticleChange.SetMomentumChange(NewMomentum);
390  aParticleChange.SetPolarizationChange(NewPolarization);
391 #endif // ------------------------------------------------------------------
392 
393  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
394 
395 }
396 
397 G4ThreeVector
398 G4TankOpBoundaryProcess::GetFacetNormal(const G4ThreeVector& Momentum, const G4ThreeVector& Normal)
399  const
400 {
401  G4ThreeVector FacetNormal;
402 
403  if (theModel == unified) {
404 
405  /* This function code alpha to a random value taken from the
406  distribution p(alpha) = g(alpha; 0, sigma_alpha)*sin(alpha),
407  for alpha > 0 and alpha < 90, where g(alpha; 0, sigma_alpha)
408  is a gaussian distribution with mean 0 and standard deviation
409  sigma_alpha. */
410 
411  G4double alpha;
412 
413  G4double sigma_alpha = 0;
414 
415  if (OpticalSurface)
416  sigma_alpha = OpticalSurface->GetSigmaAlpha();
417 
418  G4double f_max = std::min(1., 4.*sigma_alpha);
419 
420  do {
421 
422  do {
423  alpha = RandGauss::shoot(0, sigma_alpha);
424  } while (G4UniformRand()*f_max > std::sin(alpha) || alpha >= halfpi);
425 
426  G4double phi = G4UniformRand()*twopi;
427 
428  G4double SinAlpha = std::sin(alpha);
429  G4double CosAlpha = std::cos(alpha);
430  G4double SinPhi = std::sin(phi);
431  G4double CosPhi = std::cos(phi);
432 
433  G4double unit_x = SinAlpha * CosPhi;
434  G4double unit_y = SinAlpha * SinPhi;
435  G4double unit_z = CosAlpha;
436 
437  FacetNormal.setX(unit_x);
438  FacetNormal.setY(unit_y);
439  FacetNormal.setZ(unit_z);
440 
441  G4ThreeVector tmpNormal = Normal;
442 
443  FacetNormal.rotateUz(tmpNormal);
444 
445  } while (Momentum * FacetNormal >= 0);
446 
447  } else {
448 
449  G4double polish = 1;
450 
451  if (OpticalSurface)
452  polish = OpticalSurface->GetPolish();
453 
454  if (polish < 1) {
455 
456  do {
457 
458  G4ThreeVector smear;
459 
460  do {
461 
462  smear.setX(2.*G4UniformRand() - 1);
463  smear.setY(2.*G4UniformRand() - 1);
464  smear.setZ(2.*G4UniformRand() - 1);
465 
466  } while (smear.mag() > 1);
467 
468  smear = (1 - polish) * smear;
469  FacetNormal = Normal + smear;
470 
471  } while (Momentum * FacetNormal >= 0);
472 
473  FacetNormal = FacetNormal.unit();
474 
475  } else {
476 
477  FacetNormal = Normal;
478 
479  }
480 
481  }
482 
483  return FacetNormal;
484 }
485 
486 
487 void
489 {
490  do {
491 
493 
494  DoAbsorption();
495  break;
496 
497  } else {
498 
499  DoReflection();
500 
503 
504  }
505 
506  } while (NewMomentum * theGlobalNormal < 0);
507 }
508 
509 
510 void
512 {
513  G4bool Inside = false;
514  G4bool Swap = false;
515 
516 leap:
517 
518  G4bool Through = false;
519  G4bool Done = false;
520 
521  do {
522 
523  if (Through) {
524 
525  Swap = !Swap;
526  Through = false;
529  G4Swap(&Rindex1, &Rindex2);
530 
531  }
532 
533  if (theFinish == ground || theFinish == groundbackpainted)
535  else
537 
538  G4double PdotN = OldMomentum * theFacetNormal;
539  G4double EdotN = OldPolarization * theFacetNormal;
540 
541  cost1 = - PdotN;
542 
543  if (std::fabs(cost1) < 1. - kCarTolerance) {
544 
545  sint1 = std::sqrt(1 - cost1*cost1);
546  sint2 = sint1*Rindex1/Rindex2; // *** Snell's Law ***
547 
548  } else {
549 
550  sint1 = 0;
551  sint2 = 0;
552 
553  }
554 
555  if (sint2 >= 1) {
556 
557  // Simulate total internal reflection
558 
559  if (Swap)
560  Swap = !Swap;
561 
563 
564  if (theModel == unified && theFinish != polished)
566 
568  DoReflection();
569  else if (theStatus == BackScattering) {
572  } else {
573  PdotN = OldMomentum * theFacetNormal;
574  NewMomentum = OldMomentum - (2.*PdotN) * theFacetNormal;
576  NewPolarization = -OldPolarization + (2.*EdotN) * theFacetNormal;
577  }
578 
579  } else if (sint2 < 1) {
580 
581  // Calculate amplitude for transmission (Q = P x N)
582 
583  if (cost1 > 0)
584  cost2 = std::sqrt(1 - sint2*sint2);
585  else
586  cost2 = -std::sqrt(1 - sint2*sint2);
587 
588  G4ThreeVector A_trans, Atrans, E1pp, E1pl;
589  G4double E1_perp, E1_parl;
590 
591  if (sint1 > 0) {
592 
593  A_trans = OldMomentum.cross(theFacetNormal);
594  Atrans = A_trans.unit();
595  E1_perp = OldPolarization * Atrans;
596  E1pp = E1_perp * Atrans;
597  E1pl = OldPolarization - E1pp;
598  E1_parl = E1pl.mag();
599 
600  } else {
601 
602  A_trans = OldPolarization;
603  // Here we Follow Jackson's conventions and we set the
604  // parallel component = 1 in case of a ray perpendicular
605  // to the surface
606  E1_perp = 0;
607  E1_parl = 1;
608 
609  }
610 
611  G4double E2_perp = 0;
612  G4double E2_parl = 0;
613  G4double E2_total = 0;
614  G4double TransCoeff = 0;
615 
616  if (cost1 != 0) {
617 
618  G4double s1 = Rindex1*cost1;
619  E2_perp = 2.*s1*E1_perp / (Rindex1*cost1 + Rindex2*cost2);
620  E2_parl = 2.*s1*E1_parl / (Rindex2*cost1 + Rindex1*cost2);
621  E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
622  G4double s2 = Rindex2*cost2*E2_total;
623  TransCoeff = s2/s1;
624 
625  }
626 
627  G4ThreeVector Refracted, Deflected;
628  G4double E2_abs, C_parl, C_perp;
629 
630  if (!G4BooleanRand(TransCoeff)) {
631 
632  // Simulate reflection
633 
634  if (Swap)
635  Swap = !Swap;
636 
638 
639  if (theModel == unified && theFinish != polished)
641 
643  DoReflection();
644  else if (theStatus == BackScattering) {
647  } else {
648  PdotN = OldMomentum * theFacetNormal;
649  NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
650 
651  if (sint1 > 0) {// incident ray oblique
652 
653  E2_parl = Rindex2*E2_parl/Rindex1 - E1_parl;
654  E2_perp = E2_perp - E1_perp;
655  E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
656  Refracted = theFacetNormal + PdotN * NewMomentum;
657  E2_abs = std::sqrt(E2_total);
658  C_parl = E2_parl/E2_abs;
659  C_perp = E2_perp/E2_abs;
660 
661  NewPolarization = C_parl*Refracted - C_perp*A_trans;
662 
663  } else if (Rindex2 > Rindex1) // incident ray perpendicular
665 
666  }
667 
668  } else { // photon gets transmitted
669 
670  // Simulate transmission/refraction
671 
672  Inside = !Inside;
673  Through = true;
675 
676  if (sint1 > 0) { // incident ray oblique
677 
678  G4double alpha = cost1 - cost2*(Rindex2/Rindex1);
679  Deflected = OldMomentum + alpha*theFacetNormal;
680  NewMomentum = Deflected.unit();
681  PdotN = -cost2;
682  Refracted = theFacetNormal - PdotN*NewMomentum;
683  E2_abs = std::sqrt(E2_total);
684  C_parl = E2_parl/E2_abs;
685  C_perp = E2_perp/E2_abs;
686  NewPolarization = C_parl*Refracted + C_perp*A_trans;
687 
688  } else { // incident ray perpendicular
689 
692 
693  }
694 
695  }
696 
697  }
698 
701 
703  Done = (NewMomentum * theGlobalNormal <= 0);
704  else
705  Done = (NewMomentum * theGlobalNormal >= 0);
706 
707  } while (!Done);
708 
709  if (Inside && !Swap) {
710 
711  if (theFinish == polishedbackpainted || theFinish == groundbackpainted) {
712 
714  DoAbsorption();
715  else {
716 
719  else {
720  Swap = !Swap;
722  G4Swap(&Rindex1, &Rindex2);
723  }
724 
725  if (theFinish == groundbackpainted)
727 
728  DoReflection();
729 
732 
733  goto leap;
734 
735  }
736 
737  }
738 
739  }
740 
741 }
742 
743 
744 // GetMeanFreePath
745 // ---------------
746 //
747 G4double
748 G4TankOpBoundaryProcess::GetMeanFreePath(const G4Track&, G4double, G4ForceCondition* condition)
749 {
750  *condition = Forced;
751  return DBL_MAX;
752 }
G4ThreeVector GetFacetNormal(const G4ThreeVector &Momentum, const G4ThreeVector &Normal) const

, generated on Tue Sep 26 2023.