109 fSurfaceRoughness = 0.;
114 fRealRIndexMPV =
nullptr;
115 fImagRIndexMPV =
nullptr;
116 fMaterial1 =
nullptr;
117 fMaterial2 =
nullptr;
118 fOpticalSurface =
nullptr;
122 fPhotonMomentum = 0.;
123 fRindex1 = fRindex2 = 1.;
125 fDichroicVector =
nullptr;
156 const G4Step* pStep = &aStep;
170 BoundaryProcessVerbose();
180 if(thePrePV !=
nullptr)
182 if(thePostPV !=
nullptr)
187 if(stepLength <= fCarTolerance)
191 BoundaryProcessVerbose();
200 if(groupvel !=
nullptr)
203 groupvel->
Value(fPhotonMomentum, idx_groupvel));
207 else if (stepLength <= 10.*fCarTolerance && fNumSmallStepWarnings < 10)
209 ++fNumSmallStepWarnings;
213 ed <<
"G4OpBoundaryProcess: "
214 <<
"Opticalphoton step length: " << stepLength/mm <<
" mm." <<
G4endl
215 <<
"This is larger than the threshold " << fCarTolerance/mm <<
" mm "
216 "to set status StepTooSmall." <<
G4endl
217 <<
"Boundary scattering may be incorrect. ";
218 if(fNumSmallStepWarnings == 10)
220 ed <<
G4endl <<
"*** Step size warnings stopped.";
234 G4cout <<
" Old Momentum Direction: " << fOldMomentum <<
G4endl
235 <<
" Old Polarization: " << fOldPolarization <<
G4endl;
245 fGlobalNormal = (iNav[hNavId])->GetGlobalExitNormal(theGlobalPoint, &valid);
249 fGlobalNormal = -fGlobalNormal;
254 ed <<
" G4OpBoundaryProcess/PostStepDoIt(): "
255 <<
" The Navigator reports that it returned an invalid normal" <<
G4endl;
258 "Invalid Surface Normal - Geometry must return valid surface normal");
261 if(fOldMomentum * fGlobalNormal > 0.0)
263#ifdef G4OPTICAL_DEBUG
265 ed <<
" G4OpBoundaryProcess/PostStepDoIt(): fGlobalNormal points in a "
268 <<
" The momentum of the photon arriving at interface (oldMomentum)"
269 <<
" must exit the volume cross in the step. " <<
G4endl
270 <<
" So it MUST have dot < 0 with the normal that Exits the new "
271 "volume (globalNormal)."
272 <<
G4endl <<
" >> The dot product of oldMomentum and global Normal is "
273 << fOldMomentum * fGlobalNormal <<
G4endl
274 <<
" Old Momentum (during step) = " << fOldMomentum <<
G4endl
275 <<
" Global Normal (Exiting New Vol) = " << fGlobalNormal <<
G4endl
277 G4Exception(
"G4OpBoundaryProcess::PostStepDoIt",
"OpBoun02",
281 "Invalid Surface Normal - Geometry must return valid surface "
282 "normal pointing in the right direction");
284 fGlobalNormal = -fGlobalNormal;
294 if(rIndexMPV !=
nullptr)
296 fRindex1 = rIndexMPV->
Value(fPhotonMomentum, idx_rindex1);
302 BoundaryProcessVerbose();
311 fSurfaceRoughness = 0.;
317 fOpticalSurface =
nullptr;
321 if(surface ==
nullptr)
326 if(surface ==
nullptr)
335 if(surface ==
nullptr)
343 if(surface !=
nullptr)
348 if(fOpticalSurface !=
nullptr)
350 type = fOpticalSurface->
GetType();
351 fModel = fOpticalSurface->
GetModel();
361 if(rIndexMPV !=
nullptr)
363 fRindex2 = rIndexMPV->
Value(fPhotonMomentum, idx_rindex_surface);
369 BoundaryProcessVerbose();
383 fReflectivity = pp->Value(fPhotonMomentum, idx_reflect);
385 else if(fRealRIndexMPV && fImagRIndexMPV)
387 CalculateReflectivity();
392 fEfficiency = pp->Value(fPhotonMomentum, idx_eff);
396 fTransmittance = pp->Value(fPhotonMomentum, idx_trans);
406 ? pp->Value(fPhotonMomentum, idx_lobe)
409 ? pp->Value(fPhotonMomentum, idx_spike)
412 ? pp->Value(fPhotonMomentum, idx_back)
429 if(fMaterial1 == fMaterial2)
433 BoundaryProcessVerbose();
442 if(rIndexMPV !=
nullptr)
444 fRindex2 = rIndexMPV->
Value(fPhotonMomentum, idx_rindex2);
450 BoundaryProcessVerbose();
458 DielectricDielectric();
463 if(rand > fReflectivity + fTransmittance)
467 else if(rand > fReflectivity)
470 fNewMomentum = fOldMomentum;
471 fNewPolarization = fOldPolarization;
486 DielectricDielectric();
501 DielectricLUTDAVIS();
505 DielectricDichroic();
509 CoatedDielectricDielectric();
513 if(fNumBdryTypeWarnings <= 10)
515 ++fNumBdryTypeWarnings;
519 ed <<
" PostStepDoIt(): Illegal boundary type." <<
G4endl;
520 if(fNumBdryTypeWarnings == 10)
522 ed <<
"** Boundary type warnings stopped." <<
G4endl;
530 fNewMomentum = fNewMomentum.
unit();
531 fNewPolarization = fNewPolarization.
unit();
535 G4cout <<
" New Momentum Direction: " << fNewMomentum <<
G4endl
536 <<
" New Polarization: " << fNewPolarization <<
G4endl;
537 BoundaryProcessVerbose();
552 if(groupvel !=
nullptr)
555 groupvel->
Value(fPhotonMomentum, idx_groupvel));
565void G4OpBoundaryProcess::BoundaryProcessVerbose()
const
573 G4cout <<
"FresnelRefraction";
575 G4cout <<
"FresnelReflection";
577 G4cout <<
"TotalInternalReflection";
579 G4cout <<
"LambertianReflection";
581 G4cout <<
"LobeReflection";
583 G4cout <<
"SpikeReflection";
585 G4cout <<
"BackScattering";
587 G4cout <<
"PolishedLumirrorAirReflection";
589 G4cout <<
"PolishedLumirrorGlueReflection";
591 G4cout <<
"PolishedAirReflection";
593 G4cout <<
"PolishedTeflonAirReflection";
595 G4cout <<
"PolishedTiOAirReflection";
597 G4cout <<
"PolishedTyvekAirReflection";
599 G4cout <<
"PolishedVM2000AirReflection";
601 G4cout <<
"PolishedVM2000GlueReflection";
603 G4cout <<
"EtchedLumirrorAirReflection";
605 G4cout <<
"EtchedLumirrorGlueReflection";
607 G4cout <<
"EtchedAirReflection";
609 G4cout <<
"EtchedTeflonAirReflection";
611 G4cout <<
"EtchedTiOAirReflection";
613 G4cout <<
"EtchedTyvekAirReflection";
615 G4cout <<
"EtchedVM2000AirReflection";
617 G4cout <<
"EtchedVM2000GlueReflection";
619 G4cout <<
"GroundLumirrorAirReflection";
621 G4cout <<
"GroundLumirrorGlueReflection";
623 G4cout <<
"GroundAirReflection";
625 G4cout <<
"GroundTeflonAirReflection";
627 G4cout <<
"GroundTiOAirReflection";
629 G4cout <<
"GroundTyvekAirReflection";
631 G4cout <<
"GroundVM2000AirReflection";
633 G4cout <<
"GroundVM2000GlueReflection";
639 G4cout <<
"NotAtBoundary";
647 G4cout <<
"Dichroic Transmission";
649 G4cout <<
"Coated Dielectric Reflection";
651 G4cout <<
"Coated Dielectric Refraction";
653 G4cout <<
"Coated Dielectric Frustrated Transmission";
673 if(sigma_alpha == 0.0)
678 G4double f_max = std::min(1.0, 4. * sigma_alpha);
685 alpha = G4RandGauss::shoot(0.0, sigma_alpha);
686 sinAlpha = std::sin(alpha);
687 }
while(
G4UniformRand() * f_max > sinAlpha || alpha >= halfpi);
690 facetNormal.
set(sinAlpha * std::cos(phi), sinAlpha * std::sin(phi),
693 }
while(momentum * facetNormal >= 0.0);
710 }
while(smear.
mag2() > 1.0);
711 facetNormal = normal + (1. - polish) * smear;
712 }
while(momentum * facetNormal >= 0.0);
713 facetNormal = facetNormal.
unit();
717 facetNormal = normal;
724void G4OpBoundaryProcess::DielectricMetal()
734 if(rand > fReflectivity && n == 1)
736 if(rand > fReflectivity + fTransmittance)
743 fNewMomentum = fOldMomentum;
744 fNewPolarization = fOldPolarization;
750 if(fRealRIndexMPV && fImagRIndexMPV)
754 CalculateReflectivity();
755 if(!G4BooleanRand(fReflectivity))
776 fNewMomentum = -fOldMomentum;
777 fNewPolarization = -fOldPolarization;
783 if(!fRealRIndexMPV || !fImagRIndexMPV)
785 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
791 fOldMomentum - 2. * fOldMomentum * fFacetNormal * fFacetNormal;
793 if(f_iTE > 0 && f_iTM > 0)
797 (2. * fOldPolarization * fFacetNormal * fFacetNormal);
801 A_trans = (fSint1 > 0.0) ? fOldMomentum.
cross(fFacetNormal).
unit()
803 fNewPolarization = -A_trans;
812 fOldMomentum = fNewMomentum;
813 fOldPolarization = fNewPolarization;
816 }
while(fNewMomentum * fGlobalNormal < 0.0);
820void G4OpBoundaryProcess::DielectricLUT()
822 G4int thetaIndex, phiIndex;
823 G4double angularDistVal, thetaRad, phiRad;
837 if(rand > fReflectivity)
839 if(rand > fReflectivity + fTransmittance)
846 fNewMomentum = fOldMomentum;
847 fNewPolarization = fOldPolarization;
854 G4double anglePhotonToNormal = fOldMomentum.
angle(-fGlobalNormal);
856 G4int angleIncident = (
G4int)std::lrint(anglePhotonToNormal / CLHEP::deg);
862 thetaIndex = (
G4int)G4RandFlat::shootInt(thetaIndexMax - 1);
863 phiIndex = (
G4int)G4RandFlat::shootInt(phiIndexMax - 1);
866 angleIncident, thetaIndex, phiIndex);
868 }
while(!G4BooleanRand(angularDistVal));
870 thetaRad =
G4double(-90 + 4 * thetaIndex) * pi / 180.;
871 phiRad =
G4double(-90 + 5 * phiIndex) * pi / 180.;
873 fNewMomentum = -fOldMomentum;
875 perpVectorTheta = fNewMomentum.
cross(fGlobalNormal);
876 if(perpVectorTheta.
mag() < fCarTolerance)
881 fNewMomentum.
rotate(anglePhotonToNormal - thetaRad, perpVectorTheta);
882 perpVectorPhi = perpVectorTheta.
cross(fNewMomentum);
883 fNewMomentum = fNewMomentum.
rotate(-phiRad, perpVectorPhi);
886 fFacetNormal = (fNewMomentum - fOldMomentum).unit();
887 fNewPolarization = -fOldPolarization +
888 (2. * fOldPolarization * fFacetNormal * fFacetNormal);
891 }
while(fNewMomentum * fGlobalNormal <= 0.0);
895void G4OpBoundaryProcess::DielectricLUTDAVIS()
897 G4int angindex, random, angleIncident;
898 G4double reflectivityValue, elevation, azimuth;
909 anglePhotonToNormal = fOldMomentum.
angle(-fGlobalNormal);
913 angleIncident = std::min(
914 static_cast<G4int>(std::floor(anglePhotonToNormal / CLHEP::deg)), 89);
917 if(rand > reflectivityValue)
928 if(angleIncident <= 0.01)
930 fNewMomentum = fOldMomentum;
936 random = (
G4int)G4RandFlat::shootInt(1, lutbin + 1);
938 (((random * 2) - 1)) + angleIncident * lutbin * 2 + 3640000;
943 }
while(elevation == 0. && azimuth == 0.);
945 sinEl = std::sin(elevation);
946 vNorm = (fGlobalNormal.
cross(fOldMomentum)).
unit();
947 u = vNorm.
cross(fGlobalNormal) * (sinEl * std::cos(azimuth));
948 vNorm *= (sinEl * std::sin(azimuth));
950 w = (fGlobalNormal *= std::cos(elevation));
951 fNewMomentum = u + vNorm + w;
954 fFacetNormal = (fNewMomentum - fOldMomentum).unit();
955 fNewPolarization = -fOldPolarization + (2. * fOldPolarization *
956 fFacetNormal * fFacetNormal);
963 if(angleIncident == 0)
965 fNewMomentum = -fOldMomentum;
971 random = (
G4int)G4RandFlat::shootInt(1, lutbin + 1);
972 angindex = (((random * 2) - 1)) + (angleIncident - 1) * lutbin * 2;
976 }
while(elevation == 0. && azimuth == 0.);
978 sinEl = std::sin(elevation);
979 vNorm = (fGlobalNormal.
cross(fOldMomentum)).
unit();
980 u = vNorm.
cross(fGlobalNormal) * (sinEl * std::cos(azimuth));
981 vNorm *= (sinEl * std::sin(azimuth));
983 w = (fGlobalNormal *= std::cos(elevation));
985 fNewMomentum = u + vNorm + w;
988 fNewPolarization = fOldPolarization;
990 }
while(fNewMomentum * fGlobalNormal <= 0.0);
994void G4OpBoundaryProcess::DielectricDichroic()
997 G4double anglePhotonToNormal = fOldMomentum.
angle(-fGlobalNormal);
1000 G4double angleIncident = std::floor(180. / pi * anglePhotonToNormal + 0.5);
1002 if(!fDichroicVector)
1010 G4double wavelength = h_Planck * c_light / fPhotonMomentum;
1011 fTransmittance = fDichroicVector->
Value(wavelength / nm, angleIncident,
1012 idx_dichroicX, idx_dichroicY) *
1023 ed <<
" G4OpBoundaryProcess/DielectricDichroic(): "
1024 <<
" The dichroic surface has no G4Physics2DVector" <<
G4endl;
1025 G4Exception(
"G4OpBoundaryProcess::DielectricDichroic",
"OpBoun03",
1027 "A dichroic surface must have an associated G4Physics2DVector");
1030 if(!G4BooleanRand(fTransmittance))
1045 fNewMomentum = -fOldMomentum;
1046 fNewPolarization = -fOldPolarization;
1055 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1057 PdotN = fOldMomentum * fFacetNormal;
1058 fNewMomentum = fOldMomentum - (2. * PdotN) * fFacetNormal;
1060 }
while(fNewMomentum * fGlobalNormal <= 0.0);
1062 EdotN = fOldPolarization * fFacetNormal;
1063 fNewPolarization = -fOldPolarization + (2. * EdotN) * fFacetNormal;
1070 fNewMomentum = fOldMomentum;
1071 fNewPolarization = fOldPolarization;
1076void G4OpBoundaryProcess::DielectricDielectric()
1083 fFacetNormal = fGlobalNormal;
1087 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1089 G4double cost1 = -fOldMomentum * fFacetNormal;
1093 G4bool surfaceRoughnessCriterionPass =
true;
1094 if(fSurfaceRoughness != 0. && fRindex1 > fRindex2)
1096 G4double wavelength = h_Planck * c_light / fPhotonMomentum;
1097 G4double surfaceRoughnessCriterion = std::exp(-std::pow(
1098 (4. * pi * fSurfaceRoughness * fRindex1 * cost1 / wavelength), 2));
1099 surfaceRoughnessCriterionPass = G4BooleanRand(surfaceRoughnessCriterion);
1109 G4double s1, s2, E2_perp, E2_parl, E2_total, transCoeff;
1119 fGlobalNormal = -fGlobalNormal;
1126 fFacetNormal = fGlobalNormal;
1130 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1133 cost1 = -fOldMomentum * fFacetNormal;
1134 if(std::abs(cost1) < 1.0 - fCarTolerance)
1136 fSint1 = std::sqrt(1. - cost1 * cost1);
1137 sint2 = fSint1 * fRindex1 / fRindex2;
1152 if(!surfaceRoughnessCriterionPass)
1162 fNewMomentum = -fOldMomentum;
1163 fNewPolarization = -fOldPolarization;
1168 fOldMomentum - 2. * fOldMomentum * fFacetNormal * fFacetNormal;
1169 fNewPolarization = -fOldPolarization + (2. * fOldPolarization *
1170 fFacetNormal * fFacetNormal);
1174 else if(sint2 < 1.0)
1179 cost2 = std::sqrt(1. - sint2 * sint2);
1183 cost2 = -std::sqrt(1. - sint2 * sint2);
1188 A_trans = (fOldMomentum.
cross(fFacetNormal)).
unit();
1189 E1_perp = fOldPolarization * A_trans;
1190 E1pp = E1_perp * A_trans;
1191 E1pl = fOldPolarization - E1pp;
1192 E1_parl = E1pl.
mag();
1196 A_trans = fOldPolarization;
1203 s1 = fRindex1 * cost1;
1204 E2_perp = 2. * s1 * E1_perp / (fRindex1 * cost1 + fRindex2 * cost2);
1205 E2_parl = 2. * s1 * E1_parl / (fRindex2 * cost1 + fRindex1 * cost2);
1206 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1207 s2 = fRindex2 * cost2 * E2_total;
1218 transCoeff = s2 / s1;
1223 if(!G4BooleanRand(transCoeff))
1228 if(!surfaceRoughnessCriterionPass)
1238 fNewMomentum = -fOldMomentum;
1239 fNewPolarization = -fOldPolarization;
1244 fOldMomentum - 2. * fOldMomentum * fFacetNormal * fFacetNormal;
1247 E2_parl = fRindex2 * E2_parl / fRindex1 - E1_parl;
1248 E2_perp = E2_perp - E1_perp;
1249 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1250 A_paral = (fNewMomentum.
cross(A_trans)).
unit();
1251 E2_abs = std::sqrt(E2_total);
1252 C_parl = E2_parl / E2_abs;
1253 C_perp = E2_perp / E2_abs;
1255 fNewPolarization = C_parl * A_paral + C_perp * A_trans;
1259 if(fRindex2 > fRindex1)
1261 fNewPolarization = -fOldPolarization;
1265 fNewPolarization = fOldPolarization;
1279 alpha = cost1 - cost2 * (fRindex2 / fRindex1);
1280 fNewMomentum = (fOldMomentum +
alpha * fFacetNormal).unit();
1281 A_paral = (fNewMomentum.cross(A_trans)).
unit();
1282 E2_abs = std::sqrt(E2_total);
1283 C_parl = E2_parl / E2_abs;
1284 C_perp = E2_perp / E2_abs;
1286 fNewPolarization = C_parl * A_paral + C_perp * A_trans;
1290 fNewMomentum = fOldMomentum;
1291 fNewPolarization = fOldPolarization;
1296 fOldMomentum = fNewMomentum.
unit();
1297 fOldPolarization = fNewPolarization.
unit();
1301 done = (fNewMomentum * fGlobalNormal <= 0.0);
1305 done = (fNewMomentum * fGlobalNormal >= -fCarTolerance);
1315 if(rand > fReflectivity + fTransmittance)
1319 else if(rand > fReflectivity)
1322 fNewMomentum = fOldMomentum;
1323 fNewPolarization = fOldPolarization;
1329 fGlobalNormal = -fGlobalNormal;
1342 fGlobalNormal = -fGlobalNormal;
1343 fOldMomentum = fNewMomentum;
1360G4double G4OpBoundaryProcess::GetIncidentAngle()
1362 return pi - std::acos(fOldMomentum * fFacetNormal /
1363 (fOldMomentum.
mag() * fFacetNormal.mag()));
1373 G4complex reflectivity, reflectivity_TE, reflectivity_TM;
1374 G4complex N1(fRindex1, 0.), N2(realRindex, imaginaryRindex);
1389 G4double rRindex = ppR->
Value(fPhotonMomentum, idx_rrindex);
1390 G4double iRindex = ppI->
Value(fPhotonMomentum, idx_irindex);
1396 cosPhi = std::sqrt(u - ((std::sin(incidentangle) * std::sin(incidentangle)) *
1397 (N1 * N1) / (N2 * N2)));
1399 numeratorTE = N1 * std::cos(incidentangle) - N2 * cosPhi;
1400 denominatorTE = N1 * std::cos(incidentangle) + N2 * cosPhi;
1401 rTE = numeratorTE / denominatorTE;
1403 numeratorTM = N2 * std::cos(incidentangle) - N1 * cosPhi;
1404 denominatorTM = N2 * std::cos(incidentangle) + N1 * cosPhi;
1405 rTM = numeratorTM / denominatorTM;
1412 reflectivity_TE = (rTE * conj(rTE)) * (E1_perp * E1_perp) /
1413 (E1_perp * E1_perp + E1_parl * E1_parl);
1414 reflectivity_TM = (rTM * conj(rTM)) * (E1_parl * E1_parl) /
1415 (E1_perp * E1_perp + E1_parl * E1_parl);
1416 reflectivity = reflectivity_TE + reflectivity_TM;
1420 if(
G4UniformRand() * real(reflectivity) > real(reflectivity_TE))
1428 if(
G4UniformRand() * real(reflectivity) > real(reflectivity_TM))
1437 }
while(f_iTE < 0 && f_iTM < 0);
1439 return real(reflectivity);
1443void G4OpBoundaryProcess::CalculateReflectivity()
1445 G4double realRindex = fRealRIndexMPV->
Value(fPhotonMomentum, idx_rrindex);
1447 fImagRIndexMPV->
Value(fPhotonMomentum, idx_irindex);
1452 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1456 fFacetNormal = fGlobalNormal;
1459 G4double cost1 = -fOldMomentum * fFacetNormal;
1460 if(std::abs(cost1) < 1.0 - fCarTolerance)
1462 fSint1 = std::sqrt(1. - cost1 * cost1);
1474 A_trans = (fOldMomentum.
cross(fFacetNormal)).
unit();
1475 E1_perp = fOldPolarization * A_trans;
1476 E1pp = E1_perp * A_trans;
1477 E1pl = fOldPolarization - E1pp;
1478 E1_parl = E1pl.
mag();
1482 A_trans = fOldPolarization;
1489 G4double incidentangle = GetIncidentAngle();
1493 fReflectivity = GetReflectivity(E1_perp, E1_parl, incidentangle, realRindex,
1498G4bool G4OpBoundaryProcess::InvokeSD(
const G4Step* pStep)
1505 return sd->
Hit(&aStep);
1525void G4OpBoundaryProcess::CoatedDielectricDielectric()
1532 fRindex2 = pp->Value(fPhotonMomentum, idx_rindex2);
1538 fCoatedRindex =
pp->Value(fPhotonMomentum, idx_coatedrindex);
1546 fCoatedFrustratedTransmission =
1551 G4double wavelength = h_Planck * c_light / fPhotonMomentum;
1554 G4double s1, E2_perp, E2_parl, E2_total, transCoeff;
1568 fGlobalNormal = -fGlobalNormal;
1575 fFacetNormal = fGlobalNormal;
1579 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1582 PdotN = fOldMomentum * fFacetNormal;
1586 if (std::abs(cost1) < 1.0 - fCarTolerance)
1588 fSint1 = std::sqrt(1. - cost1 * cost1);
1589 sint2 = fSint1 * fRindex1 / fRindex2;
1590 sintTL = fSint1 * fRindex1 / fCoatedRindex;
1600 A_trans = fOldMomentum.
cross(fFacetNormal);
1601 A_trans = A_trans.
unit();
1602 E1_perp = fOldPolarization * A_trans;
1603 E1pp = E1_perp * A_trans;
1604 E1pl = fOldPolarization - E1pp;
1605 E1_parl = E1pl.
mag();
1609 A_trans = fOldPolarization;
1614 s1 = fRindex1 * cost1;
1618 cost2 = std::sqrt(1. - sint2 * sint2);
1622 cost2 = -std::sqrt(1. - sint2 * sint2);
1631 E2_perp = 2. * s1 * E1_perp / (fRindex1 * cost1 + fRindex2 * cost2);
1632 E2_parl = 2. * s1 * E1_parl / (fRindex2 * cost1 + fRindex1 * cost2);
1633 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1635 transCoeff = 1. - GetReflectivityThroughThinLayer(
1636 sintTL, E1_perp, E1_parl, wavelength, cost1, cost2);
1637 if (!G4BooleanRand(transCoeff))
1640 G4cout <<
"Reflection from " << fMaterial1->
GetName() <<
" to "
1654 PdotN = fOldMomentum * fFacetNormal;
1655 fNewMomentum = fOldMomentum - (2. * PdotN) * fFacetNormal;
1659 E2_parl = fRindex2 * E2_parl / fRindex1 - E1_parl;
1660 E2_perp = E2_perp - E1_perp;
1661 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1662 A_paral = fNewMomentum.
cross(A_trans);
1663 A_paral = A_paral.
unit();
1664 E2_abs = std::sqrt(E2_total);
1665 C_parl = E2_parl / E2_abs;
1666 C_perp = E2_perp / E2_abs;
1668 fNewPolarization = C_parl * A_paral + C_perp * A_trans;
1673 if (fRindex2 > fRindex1)
1675 fNewPolarization = -fOldPolarization;
1679 fNewPolarization = fOldPolarization;
1685 G4cout <<
"Transmission from " << fMaterial1->
GetName() <<
" to "
1691 if (fEfficiency > 0.)
1709 alpha = cost1 - cost2 * (fRindex2 / fRindex1);
1710 fNewMomentum = fOldMomentum +
alpha * fFacetNormal;
1711 fNewMomentum = fNewMomentum.unit();
1712 A_paral = fNewMomentum.
cross(A_trans);
1713 A_paral = A_paral.
unit();
1714 E2_abs = std::sqrt(E2_total);
1715 C_parl = E2_parl / E2_abs;
1716 C_perp = E2_perp / E2_abs;
1718 fNewPolarization = C_parl * A_paral + C_perp * A_trans;
1723 fNewMomentum = fOldMomentum;
1724 fNewPolarization = fOldPolarization;
1729 fOldMomentum = fNewMomentum.
unit();
1730 fOldPolarization = fNewPolarization.
unit();
1734 done = (fNewMomentum * fGlobalNormal <= 0.0);
1738 done = (fNewMomentum * fGlobalNormal >= -fCarTolerance);
1745G4double G4OpBoundaryProcess::GetReflectivityThroughThinLayer(
G4double sinTL,
1749 G4complex Reflectivity, Reflectivity_TE, Reflectivity_TM;
1759 if (fCoatedFrustratedTransmission) {
1763 gammaTL = std::sqrt(fRindex1 * fRindex1 * fSint1 * fSint1 -
1764 fCoatedRindex * fCoatedRindex);
1768 gammaTL = -std::sqrt(fRindex1 * fRindex1 * fSint1 * fSint1 -
1769 fCoatedRindex * fCoatedRindex);
1773 r1toTL = (fRindex1 * cost1 - i * gammaTL) / (fRindex1 * cost1 + i * gammaTL);
1774 rTLto2 = (i * gammaTL - fRindex2 * cost2) / (i * gammaTL + fRindex2 * cost2);
1777 rTE = (r1toTL + rTLto2 * std::exp(-2 * k0 * fCoatedThickness * gammaTL)) /
1778 (1.0 + r1toTL * rTLto2 * std::exp(-2 * k0 * fCoatedThickness * gammaTL));
1781 r1toTL = (fRindex1 * i * gammaTL - fCoatedRindex * fCoatedRindex * cost1) /
1782 (fRindex1 * i * gammaTL + fCoatedRindex * fCoatedRindex * cost1);
1783 rTLto2 = (fCoatedRindex * fCoatedRindex * cost2 - fRindex2 * i * gammaTL) /
1784 (fCoatedRindex * fCoatedRindex * cost2 + fRindex2 * i * gammaTL);
1787 rTM = (r1toTL + rTLto2 * std::exp(-2 * k0 * fCoatedThickness * gammaTL)) /
1788 (1.0 + r1toTL * rTLto2 * std::exp(-2 * k0 * fCoatedThickness * gammaTL));
1802 costTL = std::sqrt(1. - sinTL * sinTL);
1806 costTL = -std::sqrt(1. - sinTL * sinTL);
1809 r1toTL = (fRindex1 * cost1 - fCoatedRindex * costTL) / (fRindex1 * cost1 + fCoatedRindex * costTL);
1810 rTLto2 = (fCoatedRindex * costTL - fRindex2 * cost2) / (fCoatedRindex * costTL + fRindex2 * cost2);
1813 rTE = (r1toTL + rTLto2 * std::exp(2.0 * i * k0 * fCoatedRindex * fCoatedThickness * costTL)) /
1814 (1.0 + r1toTL * rTLto2 * std::exp(2.0 * i * k0 * fCoatedRindex * fCoatedThickness * costTL));
1817 r1toTL = (fRindex1 * costTL - fCoatedRindex * cost1) / (fRindex1 * costTL + fCoatedRindex * cost1);
1818 rTLto2 = (fCoatedRindex * cost2 - fRindex2 * costTL) / (fCoatedRindex * cost2 + fRindex2 * costTL);
1821 rTM = (r1toTL + rTLto2 * std::exp(2.0 * i * k0 * fCoatedRindex * fCoatedThickness * costTL)) /
1822 (1.0 + r1toTL * rTLto2 * std::exp(2.0 * i * k0 * fCoatedRindex * fCoatedThickness * costTL));
1826 Reflectivity_TE = (rTE * conj(rTE)) * (E1_perp * E1_perp) / (E1_perp * E1_perp + E1_parl * E1_parl);
1827 Reflectivity_TM = (rTM * conj(rTM)) * (E1_parl * E1_parl) / (E1_perp * E1_perp + E1_parl * E1_parl);
1828 Reflectivity = Reflectivity_TE + Reflectivity_TM;
1830 return real(Reflectivity);
G4double condition(const G4ErrorSymMatrix &m)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
@ kCOATEDFRUSTRATEDTRANSMISSION
G4OpBoundaryProcessStatus
@ PolishedTiOAirReflection
@ GroundTeflonAirReflection
@ EtchedVM2000AirReflection
@ CoatedDielectricReflection
@ EtchedVM2000GlueReflection
@ GroundLumirrorGlueReflection
@ GroundTyvekAirReflection
@ PolishedVM2000GlueReflection
@ PolishedTeflonAirReflection
@ EtchedTyvekAirReflection
@ EtchedLumirrorGlueReflection
@ GroundVM2000AirReflection
@ PolishedTyvekAirReflection
@ PolishedVM2000AirReflection
@ EtchedTeflonAirReflection
@ GroundVM2000GlueReflection
@ PolishedLumirrorGlueReflection
@ TotalInternalReflection
@ CoatedDielectricFrustratedTransmission
@ PolishedLumirrorAirReflection
@ EtchedLumirrorAirReflection
@ GroundLumirrorAirReflection
@ CoatedDielectricRefraction
std::complex< G4double > G4complex
G4GLOB_DLL std::ostream G4cout
Hep3Vector orthogonal() const
Hep3Vector cross(const Hep3Vector &) const
double angle(const Hep3Vector &) const
void set(double x, double y, double z)
Hep3Vector & rotateUz(const Hep3Vector &)
Hep3Vector & rotate(double, const Hep3Vector &)
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
G4bool ConstPropertyExists(const G4String &key) const
G4double GetConstProperty(const G4String &key) const
G4MaterialPropertyVector * GetProperty(const char *key) const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
const G4String & GetName() const
virtual ~G4OpBoundaryProcess()
G4OpBoundaryProcess(const G4String &processName="OpBoundary", G4ProcessType type=fOptical)
virtual void Initialise()
void SetVerboseLevel(G4int)
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
virtual void SetInvokeSD(G4bool)
virtual G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *condition) override
virtual void PreparePhysicsTable(const G4ParticleDefinition &) override
G4bool GetBoundaryInvokeSD() const
void SetBoundaryInvokeSD(G4bool)
void SetBoundaryVerboseLevel(G4int)
G4int GetBoundaryVerboseLevel() const
static G4OpticalParameters * Instance()
G4double GetAngularDistributionValueLUT(G4int)
G4OpticalSurfaceModel GetModel() const
G4double GetSigmaAlpha() const
G4OpticalSurfaceFinish GetFinish() const
G4int GetThetaIndexMax() const
G4double GetPolish() const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
G4Physics2DVector * GetDichroicVector()
G4int GetPhiIndexMax() const
G4double GetReflectivityLUTValue(G4int)
G4double GetAngularDistributionValue(G4int, G4int, G4int)
static const G4Step * GetHyperStep()
static G4int GetHypNavigatorID()
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
void Initialize(const G4Track &) override
void ProposeVelocity(G4double finalVelocity)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4double Value(G4double x, G4double y, std::size_t &lastidx, std::size_t &lastidy) const
G4double Value(const G4double energy, std::size_t &lastidx) const
G4StepStatus GetStepStatus() const
G4Material * GetMaterial() const
const G4ThreeVector & GetPosition() const
G4VSensitiveDetector * GetSensitiveDetector() const
G4VPhysicalVolume * GetPhysicalVolume() const
void AddTotalEnergyDeposit(G4double value)
G4StepPoint * GetPreStepPoint() const
G4StepPoint * GetPostStepPoint() const
const G4SurfaceType & GetType() const
G4double GetVelocity() const
const G4DynamicParticle * GetDynamicParticle() const
G4double GetStepLength() const
std::vector< G4Navigator * >::iterator GetActiveNavigatorsIterator()
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
G4bool Hit(G4Step *aStep)
void G4SwapObj(T *a, T *b)
void G4SwapPtr(T *&a, T *&b)