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;
158 const G4Step* pStep = &aStep;
172 BoundaryProcessVerbose();
182 if(thePrePV !=
nullptr)
184 if(thePostPV !=
nullptr)
189 if(stepLength <= fCarTolerance)
193 BoundaryProcessVerbose();
202 if(groupvel !=
nullptr)
205 groupvel->
Value(fPhotonMomentum, idx_groupvel));
209 else if (stepLength <= 10.*fCarTolerance && fNumWarnings < 10)
214 ed <<
"G4OpBoundaryProcess: "
215 <<
"Opticalphoton step length: " << stepLength/mm <<
" mm." <<
G4endl
216 <<
"This is larger than the threshold " << fCarTolerance/mm <<
" mm "
217 "to set status StepTooSmall." <<
G4endl
218 <<
"Boundary scattering may be incorrect. ";
219 if(fNumWarnings == 10)
221 ed <<
G4endl <<
"*** Step size warnings stopped.";
235 G4cout <<
" Old Momentum Direction: " << fOldMomentum <<
G4endl
236 <<
" Old Polarization: " << fOldPolarization <<
G4endl;
246 fGlobalNormal = (iNav[hNavId])->GetGlobalExitNormal(theGlobalPoint, &valid);
250 fGlobalNormal = -fGlobalNormal;
255 ed <<
" G4OpBoundaryProcess/PostStepDoIt(): "
256 <<
" The Navigator reports that it returned an invalid normal" <<
G4endl;
259 "Invalid Surface Normal - Geometry must return valid surface normal");
262 if(fOldMomentum * fGlobalNormal > 0.0)
264#ifdef G4OPTICAL_DEBUG
266 ed <<
" G4OpBoundaryProcess/PostStepDoIt(): fGlobalNormal points in a "
269 <<
" The momentum of the photon arriving at interface (oldMomentum)"
270 <<
" must exit the volume cross in the step. " <<
G4endl
271 <<
" So it MUST have dot < 0 with the normal that Exits the new "
272 "volume (globalNormal)."
273 <<
G4endl <<
" >> The dot product of oldMomentum and global Normal is "
274 << fOldMomentum * fGlobalNormal <<
G4endl
275 <<
" Old Momentum (during step) = " << fOldMomentum <<
G4endl
276 <<
" Global Normal (Exiting New Vol) = " << fGlobalNormal <<
G4endl
278 G4Exception(
"G4OpBoundaryProcess::PostStepDoIt",
"OpBoun02",
282 "Invalid Surface Normal - Geometry must return valid surface "
283 "normal pointing in the right direction");
285 fGlobalNormal = -fGlobalNormal;
295 if(rIndexMPV !=
nullptr)
297 fRindex1 = rIndexMPV->
Value(fPhotonMomentum, idx_rindex1);
303 BoundaryProcessVerbose();
312 fSurfaceRoughness = 0.;
318 fOpticalSurface =
nullptr;
322 if(surface ==
nullptr)
327 if(surface ==
nullptr)
336 if(surface ==
nullptr)
344 if(surface !=
nullptr)
349 if(fOpticalSurface !=
nullptr)
351 type = fOpticalSurface->
GetType();
352 fModel = fOpticalSurface->
GetModel();
362 if(rIndexMPV !=
nullptr)
364 fRindex2 = rIndexMPV->
Value(fPhotonMomentum, idx_rindex_surface);
370 BoundaryProcessVerbose();
384 fReflectivity = pp->Value(fPhotonMomentum, idx_reflect);
386 else if(fRealRIndexMPV && fImagRIndexMPV)
388 CalculateReflectivity();
393 fEfficiency = pp->Value(fPhotonMomentum, idx_eff);
397 fTransmittance = pp->Value(fPhotonMomentum, idx_trans);
407 ? pp->Value(fPhotonMomentum, idx_lobe)
410 ? pp->Value(fPhotonMomentum, idx_spike)
413 ? pp->Value(fPhotonMomentum, idx_back)
430 if(fMaterial1 == fMaterial2)
434 BoundaryProcessVerbose();
443 if(rIndexMPV !=
nullptr)
445 fRindex2 = rIndexMPV->
Value(fPhotonMomentum, idx_rindex2);
451 BoundaryProcessVerbose();
459 DielectricDielectric();
464 if(rand > fReflectivity + fTransmittance)
468 else if(rand > fReflectivity)
471 fNewMomentum = fOldMomentum;
472 fNewPolarization = fOldPolarization;
487 DielectricDielectric();
502 DielectricLUTDAVIS();
506 DielectricDichroic();
510 CoatedDielectricDielectric();
515 ed <<
" PostStepDoIt(): Illegal boundary type." <<
G4endl;
520 fNewMomentum = fNewMomentum.
unit();
521 fNewPolarization = fNewPolarization.
unit();
525 G4cout <<
" New Momentum Direction: " << fNewMomentum <<
G4endl
526 <<
" New Polarization: " << fNewPolarization <<
G4endl;
527 BoundaryProcessVerbose();
542 if(groupvel !=
nullptr)
545 groupvel->
Value(fPhotonMomentum, idx_groupvel));
555void G4OpBoundaryProcess::BoundaryProcessVerbose()
const
563 G4cout <<
"FresnelRefraction";
565 G4cout <<
"FresnelReflection";
567 G4cout <<
"TotalInternalReflection";
569 G4cout <<
"LambertianReflection";
571 G4cout <<
"LobeReflection";
573 G4cout <<
"SpikeReflection";
575 G4cout <<
"BackScattering";
577 G4cout <<
"PolishedLumirrorAirReflection";
579 G4cout <<
"PolishedLumirrorGlueReflection";
581 G4cout <<
"PolishedAirReflection";
583 G4cout <<
"PolishedTeflonAirReflection";
585 G4cout <<
"PolishedTiOAirReflection";
587 G4cout <<
"PolishedTyvekAirReflection";
589 G4cout <<
"PolishedVM2000AirReflection";
591 G4cout <<
"PolishedVM2000GlueReflection";
593 G4cout <<
"EtchedLumirrorAirReflection";
595 G4cout <<
"EtchedLumirrorGlueReflection";
597 G4cout <<
"EtchedAirReflection";
599 G4cout <<
"EtchedTeflonAirReflection";
601 G4cout <<
"EtchedTiOAirReflection";
603 G4cout <<
"EtchedTyvekAirReflection";
605 G4cout <<
"EtchedVM2000AirReflection";
607 G4cout <<
"EtchedVM2000GlueReflection";
609 G4cout <<
"GroundLumirrorAirReflection";
611 G4cout <<
"GroundLumirrorGlueReflection";
613 G4cout <<
"GroundAirReflection";
615 G4cout <<
"GroundTeflonAirReflection";
617 G4cout <<
"GroundTiOAirReflection";
619 G4cout <<
"GroundTyvekAirReflection";
621 G4cout <<
"GroundVM2000AirReflection";
623 G4cout <<
"GroundVM2000GlueReflection";
629 G4cout <<
"NotAtBoundary";
637 G4cout <<
"Dichroic Transmission";
639 G4cout <<
"Coated Dielectric Reflection";
641 G4cout <<
"Coated Dielectric Refraction";
643 G4cout <<
"Coated Dielectric Frustrated Transmission";
663 if(sigma_alpha == 0.0)
668 G4double f_max = std::min(1.0, 4. * sigma_alpha);
675 alpha = G4RandGauss::shoot(0.0, sigma_alpha);
676 sinAlpha = std::sin(alpha);
677 }
while(
G4UniformRand() * f_max > sinAlpha || alpha >= halfpi);
680 facetNormal.
set(sinAlpha * std::cos(phi), sinAlpha * std::sin(phi),
683 }
while(momentum * facetNormal >= 0.0);
700 }
while(smear.
mag2() > 1.0);
701 facetNormal = normal + (1. - polish) * smear;
702 }
while(momentum * facetNormal >= 0.0);
703 facetNormal = facetNormal.
unit();
707 facetNormal = normal;
714void G4OpBoundaryProcess::DielectricMetal()
724 if(rand > fReflectivity && n == 1)
726 if(rand > fReflectivity + fTransmittance)
733 fNewMomentum = fOldMomentum;
734 fNewPolarization = fOldPolarization;
740 if(fRealRIndexMPV && fImagRIndexMPV)
744 CalculateReflectivity();
745 if(!G4BooleanRand(fReflectivity))
766 fNewMomentum = -fOldMomentum;
767 fNewPolarization = -fOldPolarization;
773 if(!fRealRIndexMPV || !fImagRIndexMPV)
775 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
781 fOldMomentum - 2. * fOldMomentum * fFacetNormal * fFacetNormal;
783 if(f_iTE > 0 && f_iTM > 0)
787 (2. * fOldPolarization * fFacetNormal * fFacetNormal);
791 A_trans = (fSint1 > 0.0) ? fOldMomentum.
cross(fFacetNormal).
unit()
793 fNewPolarization = -A_trans;
802 fOldMomentum = fNewMomentum;
803 fOldPolarization = fNewPolarization;
806 }
while(fNewMomentum * fGlobalNormal < 0.0);
810void G4OpBoundaryProcess::DielectricLUT()
812 G4int thetaIndex, phiIndex;
813 G4double angularDistVal, thetaRad, phiRad;
827 if(rand > fReflectivity)
829 if(rand > fReflectivity + fTransmittance)
836 fNewMomentum = fOldMomentum;
837 fNewPolarization = fOldPolarization;
844 G4double anglePhotonToNormal = fOldMomentum.
angle(-fGlobalNormal);
846 G4int angleIncident = (
G4int)std::lrint(anglePhotonToNormal / CLHEP::deg);
852 thetaIndex = (
G4int)G4RandFlat::shootInt(thetaIndexMax - 1);
853 phiIndex = (
G4int)G4RandFlat::shootInt(phiIndexMax - 1);
856 angleIncident, thetaIndex, phiIndex);
858 }
while(!G4BooleanRand(angularDistVal));
860 thetaRad =
G4double(-90 + 4 * thetaIndex) *
pi / 180.;
861 phiRad =
G4double(-90 + 5 * phiIndex) *
pi / 180.;
863 fNewMomentum = -fOldMomentum;
865 perpVectorTheta = fNewMomentum.
cross(fGlobalNormal);
866 if(perpVectorTheta.
mag() < fCarTolerance)
871 fNewMomentum.
rotate(anglePhotonToNormal - thetaRad, perpVectorTheta);
872 perpVectorPhi = perpVectorTheta.
cross(fNewMomentum);
873 fNewMomentum = fNewMomentum.
rotate(-phiRad, perpVectorPhi);
876 fFacetNormal = (fNewMomentum - fOldMomentum).unit();
877 fNewPolarization = -fOldPolarization +
878 (2. * fOldPolarization * fFacetNormal * fFacetNormal);
881 }
while(fNewMomentum * fGlobalNormal <= 0.0);
885void G4OpBoundaryProcess::DielectricLUTDAVIS()
887 G4int angindex, random, angleIncident;
888 G4double reflectivityValue, elevation, azimuth;
899 anglePhotonToNormal = fOldMomentum.
angle(-fGlobalNormal);
903 angleIncident = std::min(
904 static_cast<G4int>(std::floor(anglePhotonToNormal / CLHEP::deg)), 89);
907 if(rand > reflectivityValue)
918 if(angleIncident <= 0.01)
920 fNewMomentum = fOldMomentum;
926 random = (
G4int)G4RandFlat::shootInt(1, lutbin + 1);
928 (((random * 2) - 1)) + angleIncident * lutbin * 2 + 3640000;
933 }
while(elevation == 0. && azimuth == 0.);
935 sinEl = std::sin(elevation);
936 vNorm = (fGlobalNormal.
cross(fOldMomentum)).unit();
937 u = vNorm.
cross(fGlobalNormal) * (sinEl * std::cos(azimuth));
938 vNorm *= (sinEl * std::sin(azimuth));
940 w = (fGlobalNormal *= std::cos(elevation));
941 fNewMomentum = u + vNorm + w;
944 fFacetNormal = (fNewMomentum - fOldMomentum).unit();
945 fNewPolarization = -fOldPolarization + (2. * fOldPolarization *
946 fFacetNormal * fFacetNormal);
953 if(angleIncident == 0)
955 fNewMomentum = -fOldMomentum;
961 random = (
G4int)G4RandFlat::shootInt(1, lutbin + 1);
962 angindex = (((random * 2) - 1)) + (angleIncident - 1) * lutbin * 2;
966 }
while(elevation == 0. && azimuth == 0.);
968 sinEl = std::sin(elevation);
969 vNorm = (fGlobalNormal.
cross(fOldMomentum)).unit();
970 u = vNorm.
cross(fGlobalNormal) * (sinEl * std::cos(azimuth));
971 vNorm *= (sinEl * std::sin(azimuth));
973 w = (fGlobalNormal *= std::cos(elevation));
975 fNewMomentum = u + vNorm + w;
978 fNewPolarization = fOldPolarization;
980 }
while(fNewMomentum * fGlobalNormal <= 0.0);
984void G4OpBoundaryProcess::DielectricDichroic()
987 G4double anglePhotonToNormal = fOldMomentum.
angle(-fGlobalNormal);
990 G4double angleIncident = std::floor(180. / pi * anglePhotonToNormal + 0.5);
1000 G4double wavelength = h_Planck * c_light / fPhotonMomentum;
1001 fTransmittance = fDichroicVector->
Value(wavelength / nm, angleIncident,
1002 idx_dichroicX, idx_dichroicY) *
1013 ed <<
" G4OpBoundaryProcess/DielectricDichroic(): "
1014 <<
" The dichroic surface has no G4Physics2DVector" <<
G4endl;
1015 G4Exception(
"G4OpBoundaryProcess::DielectricDichroic",
"OpBoun03",
1017 "A dichroic surface must have an associated G4Physics2DVector");
1020 if(!G4BooleanRand(fTransmittance))
1035 fNewMomentum = -fOldMomentum;
1036 fNewPolarization = -fOldPolarization;
1045 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1047 PdotN = fOldMomentum * fFacetNormal;
1048 fNewMomentum = fOldMomentum - (2. * PdotN) * fFacetNormal;
1050 }
while(fNewMomentum * fGlobalNormal <= 0.0);
1052 EdotN = fOldPolarization * fFacetNormal;
1053 fNewPolarization = -fOldPolarization + (2. * EdotN) * fFacetNormal;
1060 fNewMomentum = fOldMomentum;
1061 fNewPolarization = fOldPolarization;
1066void G4OpBoundaryProcess::DielectricDielectric()
1073 fFacetNormal = fGlobalNormal;
1077 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1079 G4double cost1 = -fOldMomentum * fFacetNormal;
1083 G4bool surfaceRoughnessCriterionPass =
true;
1084 if(fSurfaceRoughness != 0. && fRindex1 > fRindex2)
1086 G4double wavelength = h_Planck * c_light / fPhotonMomentum;
1087 G4double surfaceRoughnessCriterion = std::exp(-std::pow(
1088 (4. * pi * fSurfaceRoughness * fRindex1 * cost1 / wavelength), 2));
1089 surfaceRoughnessCriterionPass = G4BooleanRand(surfaceRoughnessCriterion);
1099 G4double s1, s2, E2_perp, E2_parl, E2_total, transCoeff;
1109 fGlobalNormal = -fGlobalNormal;
1116 fFacetNormal = fGlobalNormal;
1120 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1123 cost1 = -fOldMomentum * fFacetNormal;
1124 if(std::abs(cost1) < 1.0 - fCarTolerance)
1126 fSint1 = std::sqrt(1. - cost1 * cost1);
1127 sint2 = fSint1 * fRindex1 / fRindex2;
1142 if(!surfaceRoughnessCriterionPass)
1152 fNewMomentum = -fOldMomentum;
1153 fNewPolarization = -fOldPolarization;
1158 fOldMomentum - 2. * fOldMomentum * fFacetNormal * fFacetNormal;
1159 fNewPolarization = -fOldPolarization + (2. * fOldPolarization *
1160 fFacetNormal * fFacetNormal);
1164 else if(sint2 < 1.0)
1169 cost2 = std::sqrt(1. - sint2 * sint2);
1173 cost2 = -std::sqrt(1. - sint2 * sint2);
1178 A_trans = (fOldMomentum.
cross(fFacetNormal)).unit();
1179 E1_perp = fOldPolarization * A_trans;
1180 E1pp = E1_perp * A_trans;
1181 E1pl = fOldPolarization - E1pp;
1182 E1_parl = E1pl.
mag();
1186 A_trans = fOldPolarization;
1193 s1 = fRindex1 * cost1;
1194 E2_perp = 2. * s1 * E1_perp / (fRindex1 * cost1 + fRindex2 * cost2);
1195 E2_parl = 2. * s1 * E1_parl / (fRindex2 * cost1 + fRindex1 * cost2);
1196 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1197 s2 = fRindex2 * cost2 * E2_total;
1199 if(fTransmittance > 0.)
1200 transCoeff = fTransmittance;
1201 else if(cost1 != 0.0)
1202 transCoeff = s2 / s1;
1207 if(!G4BooleanRand(transCoeff))
1212 if(!surfaceRoughnessCriterionPass)
1222 fNewMomentum = -fOldMomentum;
1223 fNewPolarization = -fOldPolarization;
1228 fOldMomentum - 2. * fOldMomentum * fFacetNormal * fFacetNormal;
1231 E2_parl = fRindex2 * E2_parl / fRindex1 - E1_parl;
1232 E2_perp = E2_perp - E1_perp;
1233 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1234 A_paral = (fNewMomentum.
cross(A_trans)).unit();
1235 E2_abs = std::sqrt(E2_total);
1236 C_parl = E2_parl / E2_abs;
1237 C_perp = E2_perp / E2_abs;
1239 fNewPolarization = C_parl * A_paral + C_perp * A_trans;
1243 if(fRindex2 > fRindex1)
1245 fNewPolarization = -fOldPolarization;
1249 fNewPolarization = fOldPolarization;
1263 alpha = cost1 - cost2 * (fRindex2 / fRindex1);
1264 fNewMomentum = (fOldMomentum +
alpha * fFacetNormal).unit();
1265 A_paral = (fNewMomentum.cross(A_trans)).unit();
1266 E2_abs = std::sqrt(E2_total);
1267 C_parl = E2_parl / E2_abs;
1268 C_perp = E2_perp / E2_abs;
1270 fNewPolarization = C_parl * A_paral + C_perp * A_trans;
1274 fNewMomentum = fOldMomentum;
1275 fNewPolarization = fOldPolarization;
1280 fOldMomentum = fNewMomentum.
unit();
1281 fOldPolarization = fNewPolarization.
unit();
1285 done = (fNewMomentum * fGlobalNormal <= 0.0);
1289 done = (fNewMomentum * fGlobalNormal >= -fCarTolerance);
1299 if(rand > fReflectivity + fTransmittance)
1303 else if(rand > fReflectivity)
1306 fNewMomentum = fOldMomentum;
1307 fNewPolarization = fOldPolarization;
1313 fGlobalNormal = -fGlobalNormal;
1326 fGlobalNormal = -fGlobalNormal;
1327 fOldMomentum = fNewMomentum;
1344G4double G4OpBoundaryProcess::GetIncidentAngle()
1346 return pi - std::acos(fOldMomentum * fFacetNormal /
1347 (fOldMomentum.
mag() * fFacetNormal.mag()));
1357 G4complex reflectivity, reflectivity_TE, reflectivity_TM;
1358 G4complex N1(fRindex1, 0.), N2(realRindex, imaginaryRindex);
1373 G4double rRindex = ppR->
Value(fPhotonMomentum, idx_rrindex);
1374 G4double iRindex = ppI->
Value(fPhotonMomentum, idx_irindex);
1380 cosPhi = std::sqrt(u - ((std::sin(incidentangle) * std::sin(incidentangle)) *
1381 (N1 * N1) / (N2 * N2)));
1383 numeratorTE = N1 * std::cos(incidentangle) - N2 * cosPhi;
1384 denominatorTE = N1 * std::cos(incidentangle) + N2 * cosPhi;
1385 rTE = numeratorTE / denominatorTE;
1387 numeratorTM = N2 * std::cos(incidentangle) - N1 * cosPhi;
1388 denominatorTM = N2 * std::cos(incidentangle) + N1 * cosPhi;
1389 rTM = numeratorTM / denominatorTM;
1396 reflectivity_TE = (rTE * conj(rTE)) * (E1_perp * E1_perp) /
1397 (E1_perp * E1_perp + E1_parl * E1_parl);
1398 reflectivity_TM = (rTM * conj(rTM)) * (E1_parl * E1_parl) /
1399 (E1_perp * E1_perp + E1_parl * E1_parl);
1400 reflectivity = reflectivity_TE + reflectivity_TM;
1404 if(
G4UniformRand() * real(reflectivity) > real(reflectivity_TE))
1412 if(
G4UniformRand() * real(reflectivity) > real(reflectivity_TM))
1421 }
while(f_iTE < 0 && f_iTM < 0);
1423 return real(reflectivity);
1427void G4OpBoundaryProcess::CalculateReflectivity()
1429 G4double realRindex = fRealRIndexMPV->
Value(fPhotonMomentum, idx_rrindex);
1431 fImagRIndexMPV->
Value(fPhotonMomentum, idx_irindex);
1436 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1440 fFacetNormal = fGlobalNormal;
1443 G4double cost1 = -fOldMomentum * fFacetNormal;
1444 if(std::abs(cost1) < 1.0 - fCarTolerance)
1446 fSint1 = std::sqrt(1. - cost1 * cost1);
1458 A_trans = (fOldMomentum.
cross(fFacetNormal)).unit();
1459 E1_perp = fOldPolarization * A_trans;
1460 E1pp = E1_perp * A_trans;
1461 E1pl = fOldPolarization - E1pp;
1462 E1_parl = E1pl.
mag();
1466 A_trans = fOldPolarization;
1473 G4double incidentangle = GetIncidentAngle();
1477 fReflectivity = GetReflectivity(E1_perp, E1_parl, incidentangle, realRindex,
1482G4bool G4OpBoundaryProcess::InvokeSD(
const G4Step* pStep)
1489 return sd->
Hit(&aStep);
1509void G4OpBoundaryProcess::CoatedDielectricDielectric()
1516 fRindex2 = pp->Value(fPhotonMomentum, idx_rindex2);
1522 fCoatedRindex =
pp->Value(fPhotonMomentum, idx_coatedrindex);
1530 fCoatedFrustratedTransmission =
1535 G4double wavelength = h_Planck * c_light / fPhotonMomentum;
1538 G4double s1, E2_perp, E2_parl, E2_total, transCoeff;
1552 fGlobalNormal = -fGlobalNormal;
1559 fFacetNormal = fGlobalNormal;
1563 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1566 PdotN = fOldMomentum * fFacetNormal;
1570 if (std::abs(cost1) < 1.0 - fCarTolerance)
1572 fSint1 = std::sqrt(1. - cost1 * cost1);
1573 sint2 = fSint1 * fRindex1 / fRindex2;
1574 sintTL = fSint1 * fRindex1 / fCoatedRindex;
1584 A_trans = fOldMomentum.
cross(fFacetNormal);
1585 A_trans = A_trans.
unit();
1586 E1_perp = fOldPolarization * A_trans;
1587 E1pp = E1_perp * A_trans;
1588 E1pl = fOldPolarization - E1pp;
1589 E1_parl = E1pl.
mag();
1593 A_trans = fOldPolarization;
1598 s1 = fRindex1 * cost1;
1602 cost2 = std::sqrt(1. - sint2 * sint2);
1606 cost2 = -std::sqrt(1. - sint2 * sint2);
1615 E2_perp = 2. * s1 * E1_perp / (fRindex1 * cost1 + fRindex2 * cost2);
1616 E2_parl = 2. * s1 * E1_parl / (fRindex2 * cost1 + fRindex1 * cost2);
1617 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1619 transCoeff = 1. - GetReflectivityThroughThinLayer(
1620 sintTL, E1_perp, E1_parl, wavelength, cost1, cost2);
1621 if (!G4BooleanRand(transCoeff))
1624 G4cout <<
"Reflection from " << fMaterial1->
GetName() <<
" to "
1638 PdotN = fOldMomentum * fFacetNormal;
1639 fNewMomentum = fOldMomentum - (2. * PdotN) * fFacetNormal;
1643 E2_parl = fRindex2 * E2_parl / fRindex1 - E1_parl;
1644 E2_perp = E2_perp - E1_perp;
1645 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1646 A_paral = fNewMomentum.
cross(A_trans);
1647 A_paral = A_paral.
unit();
1648 E2_abs = std::sqrt(E2_total);
1649 C_parl = E2_parl / E2_abs;
1650 C_perp = E2_perp / E2_abs;
1652 fNewPolarization = C_parl * A_paral + C_perp * A_trans;
1657 if (fRindex2 > fRindex1)
1659 fNewPolarization = -fOldPolarization;
1663 fNewPolarization = fOldPolarization;
1669 G4cout <<
"Transmission from " << fMaterial1->
GetName() <<
" to "
1675 if (fEfficiency > 0.)
1693 alpha = cost1 - cost2 * (fRindex2 / fRindex1);
1694 fNewMomentum = fOldMomentum +
alpha * fFacetNormal;
1695 fNewMomentum = fNewMomentum.unit();
1696 A_paral = fNewMomentum.
cross(A_trans);
1697 A_paral = A_paral.
unit();
1698 E2_abs = std::sqrt(E2_total);
1699 C_parl = E2_parl / E2_abs;
1700 C_perp = E2_perp / E2_abs;
1702 fNewPolarization = C_parl * A_paral + C_perp * A_trans;
1707 fNewMomentum = fOldMomentum;
1708 fNewPolarization = fOldPolarization;
1713 fOldMomentum = fNewMomentum.
unit();
1714 fOldPolarization = fNewPolarization.
unit();
1718 done = (fNewMomentum * fGlobalNormal <= 0.0);
1722 done = (fNewMomentum * fGlobalNormal >= -fCarTolerance);
1729G4double G4OpBoundaryProcess::GetReflectivityThroughThinLayer(
G4double sinTL,
1733 G4complex Reflectivity, Reflectivity_TE, Reflectivity_TM;
1743 if (fCoatedFrustratedTransmission) {
1747 gammaTL = std::sqrt(fRindex1 * fRindex1 * fSint1 * fSint1 -
1748 fCoatedRindex * fCoatedRindex);
1752 gammaTL = -std::sqrt(fRindex1 * fRindex1 * fSint1 * fSint1 -
1753 fCoatedRindex * fCoatedRindex);
1757 r1toTL = (fRindex1 * cost1 - i * gammaTL) / (fRindex1 * cost1 + i * gammaTL);
1758 rTLto2 = (i * gammaTL - fRindex2 * cost2) / (i * gammaTL + fRindex2 * cost2);
1761 rTE = (r1toTL + rTLto2 * std::exp(-2 * k0 * fCoatedThickness * gammaTL)) /
1762 (1.0 + r1toTL * rTLto2 * std::exp(-2 * k0 * fCoatedThickness * gammaTL));
1765 r1toTL = (fRindex1 * i * gammaTL - fCoatedRindex * fCoatedRindex * cost1) /
1766 (fRindex1 * i * gammaTL + fCoatedRindex * fCoatedRindex * cost1);
1767 rTLto2 = (fCoatedRindex * fCoatedRindex * cost2 - fRindex2 * i * gammaTL) /
1768 (fCoatedRindex * fCoatedRindex * cost2 + fRindex2 * i * gammaTL);
1771 rTM = (r1toTL + rTLto2 * std::exp(-2 * k0 * fCoatedThickness * gammaTL)) /
1772 (1.0 + r1toTL * rTLto2 * std::exp(-2 * k0 * fCoatedThickness * gammaTL));
1786 costTL = std::sqrt(1. - sinTL * sinTL);
1790 costTL = -std::sqrt(1. - sinTL * sinTL);
1793 r1toTL = (fRindex1 * cost1 - fCoatedRindex * costTL) / (fRindex1 * cost1 + fCoatedRindex * costTL);
1794 rTLto2 = (fCoatedRindex * costTL - fRindex2 * cost2) / (fCoatedRindex * costTL + fRindex2 * cost2);
1797 rTE = (r1toTL + rTLto2 * std::exp(2.0 * i * k0 * fCoatedRindex * fCoatedThickness * costTL)) /
1798 (1.0 + r1toTL * rTLto2 * std::exp(2.0 * i * k0 * fCoatedRindex * fCoatedThickness * costTL));
1801 r1toTL = (fRindex1 * costTL - fCoatedRindex * cost1) / (fRindex1 * costTL + fCoatedRindex * cost1);
1802 rTLto2 = (fCoatedRindex * cost2 - fRindex2 * costTL) / (fCoatedRindex * cost2 + fRindex2 * costTL);
1805 rTM = (r1toTL + rTLto2 * std::exp(2.0 * i * k0 * fCoatedRindex * fCoatedThickness * costTL)) /
1806 (1.0 + r1toTL * rTLto2 * std::exp(2.0 * i * k0 * fCoatedRindex * fCoatedThickness * costTL));
1810 Reflectivity_TE = (rTE * conj(rTE)) * (E1_perp * E1_perp) / (E1_perp * E1_perp + E1_parl * E1_parl);
1811 Reflectivity_TM = (rTM * conj(rTM)) * (E1_parl * E1_parl) / (E1_perp * E1_perp + E1_parl * E1_parl);
1812 Reflectivity = Reflectivity_TE + Reflectivity_TM;
1814 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)