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();
507void 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;
588G4OpBoundaryProcess::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);
613 }
while (
G4UniformRand()*f_max > std::sin(alpha) || alpha >= halfpi );
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;
660void 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);
751void 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);
811void 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;
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;
1060G4double 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;
1078 G4complex N(RealRindex, ImaginaryRindex);
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);
1123void 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);
G4double condition(const G4ErrorSymMatrix &m)
G4OpBoundaryProcessStatus
@ PolishedTiOAirReflection
@ GroundTeflonAirReflection
@ EtchedVM2000AirReflection
@ EtchedVM2000GlueReflection
@ GroundLumirrorGlueReflection
@ GroundTyvekAirReflection
@ PolishedVM2000GlueReflection
@ PolishedTeflonAirReflection
@ EtchedTyvekAirReflection
@ EtchedLumirrorGlueReflection
@ GroundVM2000AirReflection
@ PolishedTyvekAirReflection
@ PolishedVM2000AirReflection
@ EtchedTeflonAirReflection
@ GroundVM2000GlueReflection
@ PolishedLumirrorGlueReflection
@ TotalInternalReflection
@ PolishedLumirrorAirReflection
@ EtchedLumirrorAirReflection
@ GroundLumirrorAirReflection
std::complex< G4double > G4complex
G4DLLIMPORT std::ostream G4cerr
G4DLLIMPORT std::ostream G4cout
Hep3Vector orthogonal() const
Hep3Vector cross(const Hep3Vector &) const
double angle(const Hep3Vector &) const
Hep3Vector & rotateUz(const Hep3Vector &)
Hep3Vector & rotate(double, const Hep3Vector &)
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
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
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
void SetProcessSubType(G4int)
const G4String & GetProcessName() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
std::ostringstream G4ExceptionDescription
void G4SwapObj(T *a, T *b)
void G4SwapPtr(T *&a, T *&b)