116 theReflectivity = 1.;
118 theTransmittance = 0.;
124 PropertyPointer = NULL;
125 PropertyPointer1 = NULL;
126 PropertyPointer2 = NULL;
131 OpticalSurface = NULL;
137 thePhotonMomentum = 0.;
138 Rindex1 = Rindex2 = cost1 = cost2 = sint1 = sint2 = 0.;
141 DichroicVector = NULL;
174 const G4Step* pStep = &aStep;
178 if (hStep) pStep = hStep;
216 G4cout <<
" Old Momentum Direction: " << OldMomentum <<
G4endl;
217 G4cout <<
" Old Polarization: " << OldPolarization <<
G4endl;
229 std::vector<G4Navigator*>::iterator iNav =
231 GetActiveNavigatorsIterator();
233 (iNav[hNavId])->GetGlobalExitNormal(theGlobalPoint,&valid);
236 theGlobalNormal = -theGlobalNormal;
241 ed <<
" G4OpBoundaryProcess/PostStepDoIt(): "
242 <<
" The Navigator reports that it returned an invalid normal"
244 G4Exception(
"G4OpBoundaryProcess::PostStepDoIt",
"OpBoun01",
246 "Invalid Surface Normal - Geometry must return valid surface normal");
249 if (OldMomentum * theGlobalNormal > 0.0) {
250 #ifdef G4OPTICAL_DEBUG
252 ed <<
" G4OpBoundaryProcess/PostStepDoIt(): "
253 <<
" theGlobalNormal points in a wrong direction. "
255 ed <<
" The momentum of the photon arriving at interface (oldMomentum)"
256 <<
" must exit the volume cross in the step. " <<
G4endl;
257 ed <<
" So it MUST have dot < 0 with the normal that Exits the new volume (globalNormal)." <<
G4endl;
258 ed <<
" >> The dot product of oldMomentum and global Normal is " << OldMomentum*theGlobalNormal <<
G4endl;
259 ed <<
" Old Momentum (during step) = " << OldMomentum <<
G4endl;
260 ed <<
" Global Normal (Exiting New Vol) = " << theGlobalNormal <<
G4endl;
262 G4Exception(
"G4OpBoundaryProcess::PostStepDoIt",
"OpBoun02",
265 "Invalid Surface Normal - Geometry must return valid surface normal pointing in the right direction");
267 theGlobalNormal = -theGlobalNormal;
275 if (aMaterialPropertiesTable) {
276 Rindex = aMaterialPropertiesTable->
GetProperty(
"RINDEX");
287 Rindex1 = Rindex->
Value(thePhotonMomentum);
297 theReflectivity = 1.;
299 theTransmittance = 0.;
307 OpticalSurface = NULL;
313 if (Surface == NULL){
332 if (Surface) OpticalSurface =
335 if (OpticalSurface) {
337 type = OpticalSurface->
GetType();
338 theModel = OpticalSurface->
GetModel();
341 aMaterialPropertiesTable = OpticalSurface->
342 GetMaterialPropertiesTable();
344 if (aMaterialPropertiesTable) {
348 Rindex = aMaterialPropertiesTable->
GetProperty(
"RINDEX");
350 Rindex2 = Rindex->
Value(thePhotonMomentum);
362 aMaterialPropertiesTable->
GetProperty(
"REFLECTIVITY");
364 aMaterialPropertiesTable->
GetProperty(
"REALRINDEX");
366 aMaterialPropertiesTable->
GetProperty(
"IMAGINARYRINDEX");
371 if (PropertyPointer) {
374 PropertyPointer->
Value(thePhotonMomentum);
376 }
else if (PropertyPointer1 && PropertyPointer2) {
378 CalculateReflectivity();
383 aMaterialPropertiesTable->
GetProperty(
"EFFICIENCY");
384 if (PropertyPointer) {
386 PropertyPointer->
Value(thePhotonMomentum);
390 aMaterialPropertiesTable->
GetProperty(
"TRANSMITTANCE");
391 if (PropertyPointer) {
393 PropertyPointer->
Value(thePhotonMomentum);
398 aMaterialPropertiesTable->
GetProperty(
"SPECULARLOBECONSTANT");
399 if (PropertyPointer) {
401 PropertyPointer->
Value(thePhotonMomentum);
407 aMaterialPropertiesTable->
GetProperty(
"SPECULARSPIKECONSTANT");
408 if (PropertyPointer) {
410 PropertyPointer->
Value(thePhotonMomentum);
416 aMaterialPropertiesTable->
GetProperty(
"BACKSCATTERCONSTANT");
417 if (PropertyPointer) {
419 PropertyPointer->
Value(thePhotonMomentum);
436 if (Material1 == Material2){
441 aMaterialPropertiesTable =
443 if (aMaterialPropertiesTable)
444 Rindex = aMaterialPropertiesTable->
GetProperty(
"RINDEX");
446 Rindex2 = Rindex->
Value(thePhotonMomentum);
476 DielectricDichroic();
483 DielectricDielectric();
486 if ( !G4BooleanRand(theReflectivity) ) {
498 DielectricDielectric();
505 G4cerr <<
" Error: G4BoundaryProcess: illegal boundary type " <<
G4endl;
510 NewMomentum = NewMomentum.
unit();
511 NewPolarization = NewPolarization.
unit();
514 G4cout <<
" New Momentum Direction: " << NewMomentum <<
G4endl;
515 G4cout <<
" New Polarization: " << NewPolarization <<
G4endl;
516 BoundaryProcessVerbose();
529 if ( theStatus ==
Detection ) InvokeSD(pStep);
534 void G4OpBoundaryProcess::BoundaryProcessVerbose()
const
543 G4cout <<
" *** TotalInternalReflection *** " <<
G4endl;
553 G4cout <<
" *** PolishedLumirrorAirReflection *** " <<
G4endl;
555 G4cout <<
" *** PolishedLumirrorGlueReflection *** " <<
G4endl;
559 G4cout <<
" *** PolishedTeflonAirReflection *** " <<
G4endl;
561 G4cout <<
" *** PolishedTiOAirReflection *** " <<
G4endl;
563 G4cout <<
" *** PolishedTyvekAirReflection *** " <<
G4endl;
565 G4cout <<
" *** PolishedVM2000AirReflection *** " <<
G4endl;
567 G4cout <<
" *** PolishedVM2000GlueReflection *** " <<
G4endl;
569 G4cout <<
" *** EtchedLumirrorAirReflection *** " <<
G4endl;
571 G4cout <<
" *** EtchedLumirrorGlueReflection *** " <<
G4endl;
575 G4cout <<
" *** EtchedTeflonAirReflection *** " <<
G4endl;
579 G4cout <<
" *** EtchedTyvekAirReflection *** " <<
G4endl;
581 G4cout <<
" *** EtchedVM2000AirReflection *** " <<
G4endl;
583 G4cout <<
" *** EtchedVM2000GlueReflection *** " <<
G4endl;
585 G4cout <<
" *** GroundLumirrorAirReflection *** " <<
G4endl;
587 G4cout <<
" *** GroundLumirrorGlueReflection *** " <<
G4endl;
591 G4cout <<
" *** GroundTeflonAirReflection *** " <<
G4endl;
595 G4cout <<
" *** GroundTyvekAirReflection *** " <<
G4endl;
597 G4cout <<
" *** GroundVM2000AirReflection *** " <<
G4endl;
599 G4cout <<
" *** GroundVM2000GlueReflection *** " <<
G4endl;
617 G4OpBoundaryProcess::GetFacetNormal(
const G4ThreeVector& Momentum,
633 if (OpticalSurface) sigma_alpha = OpticalSurface->
GetSigmaAlpha();
635 if (sigma_alpha == 0.0)
return FacetNormal = Normal;
646 G4double SinAlpha = std::sin(alpha);
647 G4double CosAlpha = std::cos(alpha);
651 G4double unit_x = SinAlpha * CosPhi;
652 G4double unit_y = SinAlpha * SinPhi;
655 FacetNormal.
setX(unit_x);
656 FacetNormal.
setY(unit_y);
657 FacetNormal.
setZ(unit_z);
662 }
while (Momentum * FacetNormal >= 0.0);
667 if (OpticalSurface) polish = OpticalSurface->
GetPolish();
676 }
while (smear.
mag()>1.0);
677 smear = (1.-polish) * smear;
678 FacetNormal = Normal + smear;
679 }
while (Momentum * FacetNormal >= 0.0);
680 FacetNormal = FacetNormal.
unit();
683 FacetNormal = Normal;
689 void G4OpBoundaryProcess::DielectricMetal()
697 if( !G4BooleanRand(theReflectivity) && n == 1 ) {
709 if (PropertyPointer1 && PropertyPointer2) {
711 CalculateReflectivity();
712 if ( !G4BooleanRand(theReflectivity) ) {
725 if ( n == 1 ) ChooseReflection();
731 NewMomentum = -OldMomentum;
732 NewPolarization = -OldPolarization;
737 if ( PropertyPointer1 && PropertyPointer2 ){
740 GetFacetNormal(OldMomentum,theGlobalNormal);
744 G4double PdotN = OldMomentum * theFacetNormal;
745 NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
746 G4double EdotN = OldPolarization * theFacetNormal;
751 A_trans = OldMomentum.
cross(theFacetNormal);
752 A_trans = A_trans.
unit();
754 A_trans = OldPolarization;
756 A_paral = NewMomentum.
cross(A_trans);
757 A_paral = A_paral.
unit();
761 -OldPolarization + (2.*EdotN)*theFacetNormal;
763 NewPolarization = -A_trans;
765 NewPolarization = -A_paral;
772 OldMomentum = NewMomentum;
773 OldPolarization = NewPolarization;
777 }
while (NewMomentum * theGlobalNormal < 0.0);
780 void G4OpBoundaryProcess::DielectricLUT()
782 G4int thetaIndex, phiIndex;
783 G4double AngularDistributionValue, thetaRad, phiRad, EdotN;
784 G4ThreeVector PerpendicularVectorTheta, PerpendicularVectorPhi;
793 if ( !G4BooleanRand(theReflectivity) )
798 OldMomentum.
angle(-theGlobalNormal);
800 G4int angleIncident =
G4int(std::floor(180/
pi*anglePhotonToNormal+0.5));
805 thetaIndex = G4RandFlat::shootInt(thetaIndexMax-1);
806 phiIndex = G4RandFlat::shootInt(phiIndexMax-1);
808 AngularDistributionValue = OpticalSurface ->
809 GetAngularDistributionValue(angleIncident,
812 }
while ( !G4BooleanRand(AngularDistributionValue) );
814 thetaRad = (-90 + 4*thetaIndex)*
pi/180;
815 phiRad = (-90 + 5*phiIndex)*
pi/180;
817 NewMomentum = -OldMomentum;
818 PerpendicularVectorTheta = NewMomentum.
cross(theGlobalNormal);
819 if (PerpendicularVectorTheta.
mag() > kCarTolerance ) {
820 PerpendicularVectorPhi =
821 PerpendicularVectorTheta.
cross(NewMomentum);
824 PerpendicularVectorTheta = NewMomentum.
orthogonal();
825 PerpendicularVectorPhi =
826 PerpendicularVectorTheta.
cross(NewMomentum);
829 NewMomentum.
rotate(anglePhotonToNormal-thetaRad,
830 PerpendicularVectorTheta);
831 NewMomentum = NewMomentum.
rotate(-phiRad,PerpendicularVectorPhi);
833 theFacetNormal = (NewMomentum - OldMomentum).unit();
834 EdotN = OldPolarization * theFacetNormal;
835 NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
837 }
while (NewMomentum * theGlobalNormal <= 0.0);
840 void G4OpBoundaryProcess::DielectricDichroic()
843 G4double anglePhotonToNormal = OldMomentum.
angle(-theGlobalNormal);
846 G4double angleIncident = std::floor(180/
pi*anglePhotonToNormal+0.5);
848 if (!DichroicVector) {
853 if (DichroicVector) {
856 DichroicVector->
Value(wavelength/nm,angleIncident,idx,idy)*
perCent;
864 ed <<
" G4OpBoundaryProcess/DielectricDichroic(): "
865 <<
" The dichroic surface has no G4Physics2DVector"
867 G4Exception(
"G4OpBoundaryProcess::DielectricDichroic",
"OpBoun03",
869 "A dichroic surface must have an associated G4Physics2DVector");
872 if ( !G4BooleanRand(theTransmittance) )
876 NewMomentum = OldMomentum;
877 NewPolarization = OldPolarization;
881 void G4OpBoundaryProcess::DielectricDielectric()
896 theGlobalNormal = -theGlobalNormal;
902 theFacetNormal = theGlobalNormal;
906 GetFacetNormal(OldMomentum,theGlobalNormal);
909 G4double PdotN = OldMomentum * theFacetNormal;
910 G4double EdotN = OldPolarization * theFacetNormal;
913 if (std::abs(cost1) < 1.0-kCarTolerance){
914 sint1 = std::sqrt(1.-cost1*cost1);
915 sint2 = sint1*Rindex1/Rindex2;
926 if (Swap) Swap = !Swap;
937 NewMomentum = -OldMomentum;
938 NewPolarization = -OldPolarization;
942 PdotN = OldMomentum * theFacetNormal;
943 NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
944 EdotN = OldPolarization * theFacetNormal;
945 NewPolarization = -OldPolarization + (2.*EdotN)*theFacetNormal;
949 else if (sint2 < 1.0) {
954 cost2 = std::sqrt(1.-sint2*sint2);
957 cost2 = -std::sqrt(1.-sint2*sint2);
964 A_trans = OldMomentum.
cross(theFacetNormal);
965 A_trans = A_trans.
unit();
966 E1_perp = OldPolarization * A_trans;
967 E1pp = E1_perp * A_trans;
968 E1pl = OldPolarization - E1pp;
969 E1_parl = E1pl.
mag();
972 A_trans = OldPolarization;
981 G4double E2_perp = 2.*s1*E1_perp/(Rindex1*cost1+Rindex2*cost2);
982 G4double E2_parl = 2.*s1*E1_parl/(Rindex2*cost1+Rindex1*cost2);
983 G4double E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
984 G4double s2 = Rindex2*cost2*E2_total;
988 if (theTransmittance > 0) TransCoeff = theTransmittance;
989 else if (cost1 != 0.0) TransCoeff = s2/s1;
990 else TransCoeff = 0.0;
994 if ( !G4BooleanRand(TransCoeff) ) {
998 if (Swap) Swap = !Swap;
1009 NewMomentum = -OldMomentum;
1010 NewPolarization = -OldPolarization;
1014 PdotN = OldMomentum * theFacetNormal;
1015 NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
1019 E2_parl = Rindex2*E2_parl/Rindex1 - E1_parl;
1020 E2_perp = E2_perp - E1_perp;
1021 E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
1022 A_paral = NewMomentum.
cross(A_trans);
1023 A_paral = A_paral.
unit();
1024 E2_abs = std::sqrt(E2_total);
1025 C_parl = E2_parl/E2_abs;
1026 C_perp = E2_perp/E2_abs;
1028 NewPolarization = C_parl*A_paral + C_perp*A_trans;
1034 if (Rindex2 > Rindex1) {
1035 NewPolarization = - OldPolarization;
1038 NewPolarization = OldPolarization;
1054 G4double alpha = cost1 - cost2*(Rindex2/Rindex1);
1055 NewMomentum = OldMomentum + alpha*theFacetNormal;
1056 NewMomentum = NewMomentum.
unit();
1058 A_paral = NewMomentum.
cross(A_trans);
1059 A_paral = A_paral.
unit();
1060 E2_abs = std::sqrt(E2_total);
1061 C_parl = E2_parl/E2_abs;
1062 C_perp = E2_perp/E2_abs;
1064 NewPolarization = C_parl*A_paral + C_perp*A_trans;
1069 NewMomentum = OldMomentum;
1070 NewPolarization = OldPolarization;
1076 OldMomentum = NewMomentum.
unit();
1077 OldPolarization = NewPolarization.
unit();
1080 Done = (NewMomentum * theGlobalNormal <= 0.0);
1083 Done = (NewMomentum * theGlobalNormal >= 0.0);
1088 if (Inside && !Swap) {
1092 if( !G4BooleanRand(theReflectivity) ) {
1097 theGlobalNormal = -theGlobalNormal;
1109 theGlobalNormal = -theGlobalNormal;
1110 OldMomentum = NewMomentum;
1130 G4double G4OpBoundaryProcess::GetIncidentAngle()
1132 G4double PdotN = OldMomentum * theFacetNormal;
1134 G4double magN= theFacetNormal.mag();
1135 G4double incidentangle =
pi - std::acos(PdotN/(magP*magN));
1137 return incidentangle;
1147 G4complex Reflectivity, Reflectivity_TE, Reflectivity_TM;
1161 CosPhi=std::sqrt(u-((std::sin(incidentangle)*std::sin(incidentangle))/(
N*
N)));
1163 numeratorTE = std::cos(incidentangle) -
N*CosPhi;
1164 denominatorTE = std::cos(incidentangle) +
N*CosPhi;
1165 rTE = numeratorTE/denominatorTE;
1167 numeratorTM =
N*std::cos(incidentangle) - CosPhi;
1168 denominatorTM =
N*std::cos(incidentangle) + CosPhi;
1169 rTM = numeratorTM/denominatorTM;
1176 Reflectivity_TE = (rTE*conj(rTE))*(E1_perp*E1_perp)
1177 / (E1_perp*E1_perp + E1_parl*E1_parl);
1178 Reflectivity_TM = (rTM*conj(rTM))*(E1_parl*E1_parl)
1179 / (E1_perp*E1_perp + E1_parl*E1_parl);
1180 Reflectivity = Reflectivity_TE + Reflectivity_TM;
1183 if(
G4UniformRand()*real(Reflectivity) > real(Reflectivity_TE))
1184 {iTE = -1;}
else{iTE = 1;}
1185 if(
G4UniformRand()*real(Reflectivity) > real(Reflectivity_TM))
1186 {iTM = -1;}
else{iTM = 1;}
1187 }
while(iTE<0&&iTM<0);
1189 return real(Reflectivity);
1193 void G4OpBoundaryProcess::CalculateReflectivity()
1196 PropertyPointer1->
Value(thePhotonMomentum);
1198 PropertyPointer2->
Value(thePhotonMomentum);
1201 if ( theFinish ==
ground ) {
1203 GetFacetNormal(OldMomentum, theGlobalNormal);
1205 theFacetNormal = theGlobalNormal;
1208 G4double PdotN = OldMomentum * theFacetNormal;
1211 if (std::abs(cost1) < 1.0 - kCarTolerance) {
1212 sint1 = std::sqrt(1. - cost1*cost1);
1221 A_trans = OldMomentum.
cross(theFacetNormal);
1222 A_trans = A_trans.
unit();
1223 E1_perp = OldPolarization * A_trans;
1224 E1pp = E1_perp * A_trans;
1225 E1pl = OldPolarization - E1pp;
1226 E1_parl = E1pl.
mag();
1229 A_trans = OldPolarization;
1238 G4double incidentangle = GetIncidentAngle();
1244 GetReflectivity(E1_perp, E1_parl, incidentangle,
1245 RealRindex, ImaginaryRindex);
1248 G4bool G4OpBoundaryProcess::InvokeSD(
const G4Step* pStep)
1255 if (sd)
return sd->
Hit(&aStep);
G4double condition(const G4ErrorSymMatrix &m)
ThreeVector shoot(const G4int Ap, const G4int Af)
void G4SwapObj(T *a, T *b)
G4MaterialPropertyVector * GetProperty(const char *key)
G4OpticalSurfaceModel GetModel() const
double angle(const Hep3Vector &) const
std::ostringstream G4ExceptionDescription
G4double GetVelocity() const
const G4DynamicParticle * GetDynamicParticle() const
G4StepStatus GetStepStatus() const
G4Material * GetMaterial() const
G4double GetSurfaceTolerance() const
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
const G4SurfaceType & GetType() const
G4OpBoundaryProcessStatus
G4OpBoundaryProcess(const G4String &processName="OpBoundary", G4ProcessType type=fOptical)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
static G4LogicalBorderSurface * GetSurface(const G4VPhysicalVolume *vol1, const G4VPhysicalVolume *vol2)
G4double GetTotalMomentum() const
G4StepPoint * GetPreStepPoint() const
static G4int GetHypNavigatorID()
std::complex< G4double > G4complex
G4GLOB_DLL std::ostream G4cout
G4double Value(G4double x, G4double y, size_t &lastidx, size_t &lastidy) const
G4double GetPolish() const
G4VPhysicalVolume * GetPhysicalVolume() const
const G4String & GetName() const
const G4ThreeVector & GetPosition() const
G4int GetPhiIndexMax(void) const
const G4ThreeVector & GetMomentumDirection() const
Hep3Vector & rotateUz(const Hep3Vector &)
G4bool Hit(G4Step *aStep)
void SetProcessSubType(G4int)
G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *condition)
G4LogicalVolume * GetMotherLogical() const
G4double Value(G4double theEnergy, size_t &lastidx) const
const G4String & GetProcessName() const
G4OpticalSurfaceFinish GetFinish() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
static G4TransportationManager * GetTransportationManager()
virtual void Initialize(const G4Track &)
G4LogicalVolume * GetLogicalVolume() const
G4Physics2DVector * GetDichroicVector()
void G4SwapPtr(T *&a, T *&b)
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
G4StepPoint * GetPostStepPoint() const
void AddTotalEnergyDeposit(G4double value)
Hep3Vector orthogonal() const
const G4ThreeVector & GetPolarization() const
G4ParticleChange aParticleChange
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4SurfaceProperty * GetSurfaceProperty() const
Hep3Vector cross(const Hep3Vector &) const
G4VSensitiveDetector * GetSensitiveDetector() const
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
void ProposeTrackStatus(G4TrackStatus status)
G4double GetSigmaAlpha() const
void ProposeVelocity(G4double finalVelocity)
G4int GetThetaIndexMax(void) const
Hep3Vector & rotate(double, const Hep3Vector &)
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
G4double GetStepLength() const
static G4GeometryTolerance * GetInstance()
static const G4Step * GetHyperStep()
G4GLOB_DLL std::ostream G4cerr
static G4LogicalSkinSurface * GetSurface(const G4LogicalVolume *vol)