109 theReflectivity = 1.;
111 theTransmittance = 0.;
117 PropertyPointer = NULL;
118 PropertyPointer1 = NULL;
119 PropertyPointer2 = NULL;
124 OpticalSurface = NULL;
130 thePhotonMomentum = 0.;
131 Rindex1 = Rindex2 = cost1 = cost2 = sint1 = sint2 = 0.;
181 Material1 = pPreStepPoint -> GetMaterial();
182 Material2 = pPostStepPoint -> GetMaterial();
191 G4cout <<
" Old Momentum Direction: " << OldMomentum <<
G4endl;
192 G4cout <<
" Old Polarization: " << OldPolarization <<
G4endl;
199 GetNavigatorForTracking();
208 theGlobalNormal = -theGlobalNormal;
213 ed <<
" G4OpBoundaryProcess/PostStepDoIt(): "
214 <<
" The Navigator reports that it returned an invalid normal"
216 G4Exception(
"G4OpBoundaryProcess::PostStepDoIt",
"OpBoun01",
218 "Invalid Surface Normal - Geometry must return valid surface normal");
221 if (OldMomentum * theGlobalNormal > 0.0) {
222 #ifdef G4OPTICAL_DEBUG
224 ed <<
" G4OpBoundaryProcess/PostStepDoIt(): "
225 <<
" theGlobalNormal points in a wrong direction. "
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;
234 G4Exception(
"G4OpBoundaryProcess::PostStepDoIt",
"OpBoun02",
237 "Invalid Surface Normal - Geometry must return valid surface normal pointing in the right direction");
239 theGlobalNormal = -theGlobalNormal;
247 if (aMaterialPropertiesTable) {
248 Rindex = aMaterialPropertiesTable->
GetProperty(
"RINDEX");
259 Rindex1 = Rindex->
Value(thePhotonMomentum);
269 theReflectivity = 1.;
271 theTransmittance = 0.;
279 OpticalSurface = NULL;
284 (pPreStepPoint ->GetPhysicalVolume(),
287 if (Surface == NULL){
312 if (Surface) OpticalSurface =
315 if (OpticalSurface) {
317 type = OpticalSurface->
GetType();
318 theModel = OpticalSurface->
GetModel();
321 aMaterialPropertiesTable = OpticalSurface->
322 GetMaterialPropertiesTable();
324 if (aMaterialPropertiesTable) {
328 Rindex = aMaterialPropertiesTable->
GetProperty(
"RINDEX");
330 Rindex2 = Rindex->
Value(thePhotonMomentum);
342 aMaterialPropertiesTable->
GetProperty(
"REFLECTIVITY");
344 aMaterialPropertiesTable->
GetProperty(
"REALRINDEX");
346 aMaterialPropertiesTable->
GetProperty(
"IMAGINARYRINDEX");
351 if (PropertyPointer) {
354 PropertyPointer->
Value(thePhotonMomentum);
356 }
else if (PropertyPointer1 && PropertyPointer2) {
358 CalculateReflectivity();
363 aMaterialPropertiesTable->
GetProperty(
"EFFICIENCY");
364 if (PropertyPointer) {
366 PropertyPointer->
Value(thePhotonMomentum);
370 aMaterialPropertiesTable->
GetProperty(
"TRANSMITTANCE");
371 if (PropertyPointer) {
373 PropertyPointer->
Value(thePhotonMomentum);
378 aMaterialPropertiesTable->
GetProperty(
"SPECULARLOBECONSTANT");
379 if (PropertyPointer) {
381 PropertyPointer->
Value(thePhotonMomentum);
387 aMaterialPropertiesTable->
GetProperty(
"SPECULARSPIKECONSTANT");
388 if (PropertyPointer) {
390 PropertyPointer->
Value(thePhotonMomentum);
396 aMaterialPropertiesTable->
GetProperty(
"BACKSCATTERCONSTANT");
397 if (PropertyPointer) {
399 PropertyPointer->
Value(thePhotonMomentum);
416 if (Material1 == Material2){
421 aMaterialPropertiesTable =
423 if (aMaterialPropertiesTable)
424 Rindex = aMaterialPropertiesTable->
GetProperty(
"RINDEX");
426 Rindex2 = Rindex->
Value(thePhotonMomentum);
458 DielectricDielectric();
461 if ( !G4BooleanRand(theReflectivity) ) {
473 DielectricDielectric();
480 G4cerr <<
" Error: G4BoundaryProcess: illegal boundary type " <<
G4endl;
485 NewMomentum = NewMomentum.
unit();
486 NewPolarization = NewPolarization.
unit();
489 G4cout <<
" New Momentum Direction: " << NewMomentum <<
G4endl;
490 G4cout <<
" New Polarization: " << NewPolarization <<
G4endl;
491 BoundaryProcessVerbose();
507 void G4OpBoundaryProcess::BoundaryProcessVerbose()
const
516 G4cout <<
" *** TotalInternalReflection *** " <<
G4endl;
526 G4cout <<
" *** PolishedLumirrorAirReflection *** " <<
G4endl;
528 G4cout <<
" *** PolishedLumirrorGlueReflection *** " <<
G4endl;
532 G4cout <<
" *** PolishedTeflonAirReflection *** " <<
G4endl;
534 G4cout <<
" *** PolishedTiOAirReflection *** " <<
G4endl;
536 G4cout <<
" *** PolishedTyvekAirReflection *** " <<
G4endl;
538 G4cout <<
" *** PolishedVM2000AirReflection *** " <<
G4endl;
540 G4cout <<
" *** PolishedVM2000GlueReflection *** " <<
G4endl;
542 G4cout <<
" *** EtchedLumirrorAirReflection *** " <<
G4endl;
544 G4cout <<
" *** EtchedLumirrorGlueReflection *** " <<
G4endl;
548 G4cout <<
" *** EtchedTeflonAirReflection *** " <<
G4endl;
552 G4cout <<
" *** EtchedTyvekAirReflection *** " <<
G4endl;
554 G4cout <<
" *** EtchedVM2000AirReflection *** " <<
G4endl;
556 G4cout <<
" *** EtchedVM2000GlueReflection *** " <<
G4endl;
558 G4cout <<
" *** GroundLumirrorAirReflection *** " <<
G4endl;
560 G4cout <<
" *** GroundLumirrorGlueReflection *** " <<
G4endl;
564 G4cout <<
" *** GroundTeflonAirReflection *** " <<
G4endl;
568 G4cout <<
" *** GroundTyvekAirReflection *** " <<
G4endl;
570 G4cout <<
" *** GroundVM2000AirReflection *** " <<
G4endl;
572 G4cout <<
" *** GroundVM2000GlueReflection *** " <<
G4endl;
588 G4OpBoundaryProcess::GetFacetNormal(
const G4ThreeVector& Momentum,
604 if (OpticalSurface) sigma_alpha = OpticalSurface->
GetSigmaAlpha();
606 if (sigma_alpha == 0.0)
return FacetNormal = Normal;
608 G4double f_max = std::min(1.0,4.*sigma_alpha);
612 alpha = G4RandGauss::shoot(0.0,sigma_alpha);
617 G4double SinAlpha = std::sin(alpha);
618 G4double CosAlpha = std::cos(alpha);
622 G4double unit_x = SinAlpha * CosPhi;
623 G4double unit_y = SinAlpha * SinPhi;
626 FacetNormal.
setX(unit_x);
627 FacetNormal.
setY(unit_y);
628 FacetNormal.
setZ(unit_z);
633 }
while (Momentum * FacetNormal >= 0.0);
638 if (OpticalSurface) polish = OpticalSurface->
GetPolish();
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();
654 FacetNormal = Normal;
660 void G4OpBoundaryProcess::DielectricMetal()
668 if( !G4BooleanRand(theReflectivity) && n == 1 ) {
680 if (PropertyPointer1 && PropertyPointer2) {
682 CalculateReflectivity();
683 if ( !G4BooleanRand(theReflectivity) ) {
696 if ( n == 1 ) ChooseReflection();
702 NewMomentum = -OldMomentum;
703 NewPolarization = -OldPolarization;
708 if ( PropertyPointer1 && PropertyPointer2 ){
711 GetFacetNormal(OldMomentum,theGlobalNormal);
715 G4double PdotN = OldMomentum * theFacetNormal;
716 NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
717 G4double EdotN = OldPolarization * theFacetNormal;
722 A_trans = OldMomentum.
cross(theFacetNormal);
723 A_trans = A_trans.
unit();
725 A_trans = OldPolarization;
727 A_paral = NewMomentum.
cross(A_trans);
728 A_paral = A_paral.
unit();
732 -OldPolarization + (2.*EdotN)*theFacetNormal;
734 NewPolarization = -A_trans;
736 NewPolarization = -A_paral;
743 OldMomentum = NewMomentum;
744 OldPolarization = NewPolarization;
748 }
while (NewMomentum * theGlobalNormal < 0.0);
751 void G4OpBoundaryProcess::DielectricLUT()
753 G4int thetaIndex, phiIndex;
754 G4double AngularDistributionValue, thetaRad, phiRad, EdotN;
755 G4ThreeVector PerpendicularVectorTheta, PerpendicularVectorPhi;
764 if ( !G4BooleanRand(theReflectivity) )
769 OldMomentum.
angle(-theGlobalNormal);
771 G4int angleIncident =
G4int(std::floor(180/
pi*anglePhotonToNormal+0.5));
779 AngularDistributionValue = OpticalSurface ->
780 GetAngularDistributionValue(angleIncident,
783 }
while ( !G4BooleanRand(AngularDistributionValue) );
785 thetaRad = (-90 + 4*thetaIndex)*
pi/180;
786 phiRad = (-90 + 5*phiIndex)*
pi/180;
788 NewMomentum = -OldMomentum;
789 PerpendicularVectorTheta = NewMomentum.
cross(theGlobalNormal);
790 if (PerpendicularVectorTheta.
mag() > kCarTolerance ) {
791 PerpendicularVectorPhi =
792 PerpendicularVectorTheta.
cross(NewMomentum);
795 PerpendicularVectorTheta = NewMomentum.
orthogonal();
796 PerpendicularVectorPhi =
797 PerpendicularVectorTheta.
cross(NewMomentum);
800 NewMomentum.
rotate(anglePhotonToNormal-thetaRad,
801 PerpendicularVectorTheta);
802 NewMomentum = NewMomentum.
rotate(-phiRad,PerpendicularVectorPhi);
804 theFacetNormal = (NewMomentum - OldMomentum).unit();
805 EdotN = OldPolarization * theFacetNormal;
806 NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
808 }
while (NewMomentum * theGlobalNormal <= 0.0);
811 void G4OpBoundaryProcess::DielectricDielectric()
826 theGlobalNormal = -theGlobalNormal;
832 theFacetNormal = theGlobalNormal;
836 GetFacetNormal(OldMomentum,theGlobalNormal);
839 G4double PdotN = OldMomentum * theFacetNormal;
840 G4double EdotN = OldPolarization * theFacetNormal;
843 if (std::abs(cost1) < 1.0-kCarTolerance){
844 sint1 = std::sqrt(1.-cost1*cost1);
845 sint2 = sint1*Rindex1/Rindex2;
856 if (Swap) Swap = !Swap;
867 NewMomentum = -OldMomentum;
868 NewPolarization = -OldPolarization;
872 PdotN = OldMomentum * theFacetNormal;
873 NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
874 EdotN = OldPolarization * theFacetNormal;
875 NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
879 else if (sint2 < 1.0) {
884 cost2 = std::sqrt(1.-sint2*sint2);
887 cost2 = -std::sqrt(1.-sint2*sint2);
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();
902 A_trans = OldPolarization;
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;
918 if (theTransmittance > 0) TransCoeff = theTransmittance;
919 else if (cost1 != 0.0) TransCoeff = s2/s1;
920 else TransCoeff = 0.0;
924 if ( !G4BooleanRand(TransCoeff) ) {
928 if (Swap) Swap = !Swap;
939 NewMomentum = -OldMomentum;
940 NewPolarization = -OldPolarization;
944 PdotN = OldMomentum * theFacetNormal;
945 NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
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;
958 NewPolarization = C_parl*A_paral + C_perp*A_trans;
964 if (Rindex2 > Rindex1) {
965 NewPolarization = - OldPolarization;
968 NewPolarization = OldPolarization;
984 G4double alpha = cost1 - cost2*(Rindex2/Rindex1);
985 NewMomentum = OldMomentum + alpha*theFacetNormal;
986 NewMomentum = NewMomentum.
unit();
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;
994 NewPolarization = C_parl*A_paral + C_perp*A_trans;
999 NewMomentum = OldMomentum;
1000 NewPolarization = OldPolarization;
1006 OldMomentum = NewMomentum.
unit();
1007 OldPolarization = NewPolarization.
unit();
1010 Done = (NewMomentum * theGlobalNormal <= 0.0);
1013 Done = (NewMomentum * theGlobalNormal >= 0.0);
1018 if (Inside && !Swap) {
1022 if( !G4BooleanRand(theReflectivity) ) {
1027 theGlobalNormal = -theGlobalNormal;
1039 theGlobalNormal = -theGlobalNormal;
1040 OldMomentum = NewMomentum;
1060 G4double G4OpBoundaryProcess::GetIncidentAngle()
1062 G4double PdotN = OldMomentum * theFacetNormal;
1064 G4double magN= theFacetNormal.mag();
1065 G4double incidentangle =
pi - std::acos(PdotN/(magP*magN));
1067 return incidentangle;
1077 G4complex Reflectivity, Reflectivity_TE, Reflectivity_TM;
1091 CosPhi=std::sqrt(u-((std::sin(incidentangle)*std::sin(incidentangle))/(
N*
N)));
1093 numeratorTE = std::cos(incidentangle) -
N*CosPhi;
1094 denominatorTE = std::cos(incidentangle) +
N*CosPhi;
1095 rTE = numeratorTE/denominatorTE;
1097 numeratorTM =
N*std::cos(incidentangle) - CosPhi;
1098 denominatorTM =
N*std::cos(incidentangle) + CosPhi;
1099 rTM = numeratorTM/denominatorTM;
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;
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);
1119 return real(Reflectivity);
1123 void G4OpBoundaryProcess::CalculateReflectivity()
1126 PropertyPointer1->
Value(thePhotonMomentum);
1128 PropertyPointer2->
Value(thePhotonMomentum);
1131 if ( theFinish ==
ground ) {
1133 GetFacetNormal(OldMomentum, theGlobalNormal);
1135 theFacetNormal = theGlobalNormal;
1138 G4double PdotN = OldMomentum * theFacetNormal;
1141 if (std::abs(cost1) < 1.0 - kCarTolerance) {
1142 sint1 = std::sqrt(1. - cost1*cost1);
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();
1159 A_trans = OldPolarization;
1168 G4double incidentangle = GetIncidentAngle();
1174 GetReflectivity(E1_perp, E1_parl, incidentangle,
1175 RealRindex, ImaginaryRindex);