91 constexpr G4double hc = CLHEP::h_Planck * CLHEP::c_light;
113 fSurfaceRoughness = 0.;
118 fRealRIndexMPV =
nullptr;
119 fImagRIndexMPV =
nullptr;
120 fMaterial1 =
nullptr;
121 fMaterial2 =
nullptr;
122 fOpticalSurface =
nullptr;
126 fPhotonMomentum = 0.;
127 fRindex1 = fRindex2 = 1.;
129 fDichroicVector =
nullptr;
160 const G4Step* pStep = (hStep !=
nullptr) ? hStep : &aStep;
171 BoundaryProcessVerbose();
181 if(thePrePV !=
nullptr)
183 if(thePostPV !=
nullptr)
188 if(stepLength <= fCarTolerance)
192 BoundaryProcessVerbose();
201 if(groupvel !=
nullptr)
204 groupvel->
Value(fPhotonMomentum, idx_groupvel));
208 else if (stepLength <= 10. * fCarTolerance && fNumSmallStepWarnings < 10)
210 ++fNumSmallStepWarnings;
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(fNumSmallStepWarnings == 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 a 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();
353 fFinish = fOpticalSurface->GetFinish();
356 fOpticalSurface->GetMaterialPropertiesTable();
359 if(IsBackpainted(fFinish))
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)
417 else if(IsBackpainted(fFinish))
430 if(fMaterial1 == fMaterial2)
434 BoundaryProcessVerbose();
437 MPT = fMaterial2->GetMaterialPropertiesTable();
443 if(rIndexMPV !=
nullptr)
445 fRindex2 = rIndexMPV->
Value(fPhotonMomentum, idx_rindex2);
451 BoundaryProcessVerbose();
457 if(IsBackpainted(fFinish))
459 DielectricDielectric();
464 if(rand > fReflectivity + fTransmittance)
468 else if(rand > fReflectivity)
485 DielectricDielectric();
500 DielectricLUTDAVIS();
504 DielectricDichroic();
508 CoatedDielectricDielectric();
512 if(fNumBdryTypeWarnings <= 10)
514 ++fNumBdryTypeWarnings;
518 ed <<
" PostStepDoIt(): Illegal boundary type." <<
G4endl;
519 if(fNumBdryTypeWarnings == 10)
521 ed <<
"** Boundary type warnings stopped." <<
G4endl;
529 fNewMomentum = fNewMomentum.unit();
530 fNewPolarization = fNewPolarization.unit();
534 G4cout <<
" New Momentum Direction: " << fNewMomentum <<
G4endl
535 <<
" New Polarization: " << fNewPolarization <<
G4endl;
536 BoundaryProcessVerbose();
551 if(groupvel !=
nullptr)
554 groupvel->
Value(fPhotonMomentum, idx_groupvel));
564void G4OpBoundaryProcess::BoundaryProcessVerbose()
const
572 G4cout <<
"FresnelRefraction";
574 G4cout <<
"FresnelReflection";
576 G4cout <<
"TotalInternalReflection";
578 G4cout <<
"LambertianReflection";
580 G4cout <<
"LobeReflection";
582 G4cout <<
"SpikeReflection";
584 G4cout <<
"BackScattering";
586 G4cout <<
"PolishedLumirrorAirReflection";
588 G4cout <<
"PolishedLumirrorGlueReflection";
590 G4cout <<
"PolishedAirReflection";
592 G4cout <<
"PolishedTeflonAirReflection";
594 G4cout <<
"PolishedTiOAirReflection";
596 G4cout <<
"PolishedTyvekAirReflection";
598 G4cout <<
"PolishedVM2000AirReflection";
600 G4cout <<
"PolishedVM2000GlueReflection";
602 G4cout <<
"EtchedLumirrorAirReflection";
604 G4cout <<
"EtchedLumirrorGlueReflection";
606 G4cout <<
"EtchedAirReflection";
608 G4cout <<
"EtchedTeflonAirReflection";
610 G4cout <<
"EtchedTiOAirReflection";
612 G4cout <<
"EtchedTyvekAirReflection";
614 G4cout <<
"EtchedVM2000AirReflection";
616 G4cout <<
"EtchedVM2000GlueReflection";
618 G4cout <<
"GroundLumirrorAirReflection";
620 G4cout <<
"GroundLumirrorGlueReflection";
622 G4cout <<
"GroundAirReflection";
624 G4cout <<
"GroundTeflonAirReflection";
626 G4cout <<
"GroundTiOAirReflection";
628 G4cout <<
"GroundTyvekAirReflection";
630 G4cout <<
"GroundVM2000AirReflection";
632 G4cout <<
"GroundVM2000GlueReflection";
638 G4cout <<
"NotAtBoundary";
646 G4cout <<
"Dichroic Transmission";
648 G4cout <<
"Coated Dielectric Reflection";
650 G4cout <<
"Coated Dielectric Refraction";
652 G4cout <<
"Coated Dielectric Frustrated Transmission";
671 sigma_alpha = fOpticalSurface->GetSigmaAlpha();
672 if(sigma_alpha == 0.0)
677 G4double f_max = std::min(1.0, 4. * sigma_alpha);
684 alpha = G4RandGauss::shoot(0.0, sigma_alpha);
685 sinAlpha = std::sin(alpha);
686 }
while(
G4UniformRand() * f_max > sinAlpha || alpha >= halfpi);
689 facetNormal.
set(sinAlpha * std::cos(phi), sinAlpha * std::sin(phi),
692 }
while(momentum * facetNormal >= 0.0);
698 polish = fOpticalSurface->GetPolish();
709 }
while(smear.
mag2() > 1.0);
710 facetNormal = normal + (1. - polish) * smear;
711 }
while(momentum * facetNormal >= 0.0);
712 facetNormal = facetNormal.
unit();
716 facetNormal = normal;
723void G4OpBoundaryProcess::DielectricMetal()
733 if(rand > fReflectivity && n == 1)
735 if(rand > fReflectivity + fTransmittance)
747 if(fRealRIndexMPV && fImagRIndexMPV)
751 CalculateReflectivity();
752 if(!G4BooleanRand(fReflectivity))
773 fNewMomentum = -fOldMomentum;
774 fNewPolarization = -fOldPolarization;
780 if(!fRealRIndexMPV || !fImagRIndexMPV)
782 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
787 fNewMomentum = fOldMomentum -
788 2. * (fOldMomentum * fFacetNormal) * fFacetNormal;
790 if(f_iTE > 0 && f_iTM > 0)
792 fNewPolarization = -fOldPolarization +
793 2. * (fOldPolarization * fFacetNormal) * fFacetNormal;
797 A_trans = (fSint1 > 0.0) ? fOldMomentum.
cross(fFacetNormal).
unit()
799 fNewPolarization = -A_trans;
804 -fNewMomentum.cross(A_trans).unit();
808 fOldMomentum = fNewMomentum;
809 fOldPolarization = fNewPolarization;
812 }
while(fNewMomentum * fGlobalNormal < 0.0);
816void G4OpBoundaryProcess::DielectricLUT()
818 G4int thetaIndex, phiIndex;
819 G4double angularDistVal, thetaRad, phiRad;
825 G4int thetaIndexMax = fOpticalSurface->GetThetaIndexMax();
826 G4int phiIndexMax = fOpticalSurface->GetPhiIndexMax();
833 if(rand > fReflectivity)
835 if(rand > fReflectivity + fTransmittance)
848 G4double anglePhotonToNormal = fOldMomentum.angle(-fGlobalNormal);
850 G4int angleIncident = (
G4int)std::lrint(anglePhotonToNormal / CLHEP::deg);
856 thetaIndex = (
G4int)G4RandFlat::shootInt(thetaIndexMax - 1);
857 phiIndex = (
G4int)G4RandFlat::shootInt(phiIndexMax - 1);
859 angularDistVal = fOpticalSurface->GetAngularDistributionValue(
860 angleIncident, thetaIndex, phiIndex);
862 }
while(!G4BooleanRand(angularDistVal));
864 thetaRad =
G4double(-90 + 4 * thetaIndex) *
pi / 180.;
865 phiRad =
G4double(-90 + 5 * phiIndex) *
pi / 180.;
867 fNewMomentum = -fOldMomentum;
869 perpVectorTheta = fNewMomentum.
cross(fGlobalNormal);
870 if(perpVectorTheta.
mag() < fCarTolerance)
875 fNewMomentum.
rotate(anglePhotonToNormal - thetaRad, perpVectorTheta);
876 perpVectorPhi = perpVectorTheta.
cross(fNewMomentum);
877 fNewMomentum = fNewMomentum.
rotate(-phiRad, perpVectorPhi);
880 fFacetNormal = (fNewMomentum - fOldMomentum).unit();
881 fNewPolarization = -fOldPolarization +
882 2. * (fOldPolarization * fFacetNormal) * fFacetNormal;
885 }
while(fNewMomentum * fGlobalNormal <= 0.0);
889void G4OpBoundaryProcess::DielectricLUTDAVIS()
891 G4int angindex, random, angleIncident;
892 G4double reflectivityValue, elevation, azimuth;
895 G4int lutbin = fOpticalSurface->GetLUTbins();
903 anglePhotonToNormal = fOldMomentum.angle(-fGlobalNormal);
907 angleIncident = std::min(
908 static_cast<G4int>(std::floor(anglePhotonToNormal / CLHEP::deg)), 89);
909 reflectivityValue = fOpticalSurface->GetReflectivityLUTValue(angleIncident);
911 if(rand > reflectivityValue)
922 if(angleIncident <= 0.01)
924 fNewMomentum = fOldMomentum;
930 random = (
G4int)G4RandFlat::shootInt(1, lutbin + 1);
932 (((random * 2) - 1)) + angleIncident * lutbin * 2 + 3640000;
935 fOpticalSurface->GetAngularDistributionValueLUT(angindex - 1);
936 elevation = fOpticalSurface->GetAngularDistributionValueLUT(angindex);
937 }
while(elevation == 0. && azimuth == 0.);
939 sinEl = std::sin(elevation);
940 vNorm = (fGlobalNormal.cross(fOldMomentum)).
unit();
941 u = vNorm.
cross(fGlobalNormal) * (sinEl * std::cos(azimuth));
942 vNorm *= (sinEl * std::sin(azimuth));
944 w = (fGlobalNormal *= std::cos(elevation));
945 fNewMomentum = u + vNorm + w;
948 fFacetNormal = (fNewMomentum - fOldMomentum).unit();
949 fNewPolarization = -fOldPolarization +
950 2. * (fOldPolarization * fFacetNormal) * fFacetNormal;
957 if(angleIncident == 0)
959 fNewMomentum = -fOldMomentum;
965 random = (
G4int)G4RandFlat::shootInt(1, lutbin + 1);
966 angindex = (((random * 2) - 1)) + (angleIncident - 1) * lutbin * 2;
968 azimuth = fOpticalSurface->GetAngularDistributionValueLUT(angindex - 1);
969 elevation = fOpticalSurface->GetAngularDistributionValueLUT(angindex);
970 }
while(elevation == 0. && azimuth == 0.);
972 sinEl = std::sin(elevation);
973 vNorm = (fGlobalNormal.cross(fOldMomentum)).
unit();
974 u = vNorm.
cross(fGlobalNormal) * (sinEl * std::cos(azimuth));
975 vNorm *= (sinEl * std::sin(azimuth));
977 w = (fGlobalNormal *= std::cos(elevation));
979 fNewMomentum = u + vNorm + w;
982 fNewPolarization = fOldPolarization;
984 }
while(fNewMomentum * fGlobalNormal <= 0.0);
988void G4OpBoundaryProcess::DielectricDichroic()
991 G4double anglePhotonToNormal = fOldMomentum.
angle(-fGlobalNormal);
994 G4double angleIncident = std::floor(180. / pi * anglePhotonToNormal + 0.5);
996 if(!fDichroicVector && fOpticalSurface)
998 fDichroicVector = fOpticalSurface->GetDichroicVector();
1004 fTransmittance = fDichroicVector->Value(wavelength / nm, angleIncident,
1005 idx_dichroicX, idx_dichroicY) *
1016 ed <<
" G4OpBoundaryProcess/DielectricDichroic(): "
1017 <<
" The dichroic surface has no G4Physics2DVector" <<
G4endl;
1018 G4Exception(
"G4OpBoundaryProcess::DielectricDichroic",
"OpBoun03",
1020 "A dichroic surface must have an associated G4Physics2DVector");
1023 if(!G4BooleanRand(fTransmittance))
1038 fNewMomentum = -fOldMomentum;
1039 fNewPolarization = -fOldPolarization;
1048 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
1050 PdotN = fOldMomentum * fFacetNormal;
1051 fNewMomentum = fOldMomentum - (2. * PdotN) * fFacetNormal;
1053 }
while(fNewMomentum * fGlobalNormal <= 0.0);
1055 EdotN = fOldPolarization * fFacetNormal;
1056 fNewPolarization = -fOldPolarization + (2. * EdotN) * fFacetNormal;
1063 fNewMomentum = fOldMomentum;
1064 fNewPolarization = fOldPolarization;
1069void G4OpBoundaryProcess::DielectricDielectric()
1071 fFacetNormal = (fFinish ==
polished) ? fGlobalNormal :
1072 GetFacetNormal(fOldMomentum, fGlobalNormal);
1074 G4double cost1 = -fOldMomentum * fFacetNormal;
1076 G4bool surfaceRoughnessCriterionPass =
true;
1077 if(fSurfaceRoughness != 0. && fRindex1 > fRindex2)
1080 G4double surfaceRoughnessCriterion = std::exp(-std::pow(
1081 (4. * pi * fSurfaceRoughness * fRindex1 * cost1 / wavelength), 2));
1082 surfaceRoughnessCriterionPass = G4BooleanRand(surfaceRoughnessCriterion);
1088 const G4int maxBoundaryActions = 100;
1089 G4int numBoundaryActions = 0;
1094 ApplyDielectricBoundaryTransition(cost1, surfaceRoughnessCriterionPass,
1098 if((inside && !
swap) && IsBackpainted(fFinish))
1101 if(rand > fReflectivity)
1103 if(rand > fReflectivity + fTransmittance)
1117 fGlobalNormal = -fGlobalNormal;
1130 fGlobalNormal = -fGlobalNormal;
1131 fOldMomentum = fNewMomentum;
1133 ++numBoundaryActions;
1141 }
while(numBoundaryActions < maxBoundaryActions);
1143 if(numBoundaryActions == maxBoundaryActions)
1146 ed <<
" DielectricDielectric(): numBoundaryActions exceeds"
1147 <<
" maxBoundaryActions = " << maxBoundaryActions <<
G4endl;
1153void G4OpBoundaryProcess::ApplyDielectricBoundaryTransition(
G4double cost1,
1154 G4bool roughnessCriterionPass,
1165 G4double s1, s2, E2_perp, E2_parl, E2_total;
1178 fGlobalNormal = -fGlobalNormal;
1183 fFacetNormal = (fFinish ==
polished) ? fGlobalNormal :
1184 GetFacetNormal(fOldMomentum, fGlobalNormal);
1186 cost1 = -fOldMomentum * fFacetNormal;
1187 if(std::abs(cost1) < 1.0 - fCarTolerance)
1189 fSint1 = std::sqrt(1. - cost1 * cost1);
1190 sint2 = fSint1 * fRindex1 / fRindex2;
1205 if(!roughnessCriterionPass)
1215 fNewMomentum = -fOldMomentum;
1216 fNewPolarization = -fOldPolarization;
1220 fNewMomentum = fOldMomentum -
1221 2. * (fOldMomentum * fFacetNormal) * fFacetNormal;
1222 fNewPolarization = -fOldPolarization +
1223 2. * (fOldPolarization * fFacetNormal) * fFacetNormal;
1230 cost2 = (cost1 > 0.0 ? 1.0 : -1.0) * std::sqrt(1. - sint2 * sint2);
1234 A_trans = (fOldMomentum.cross(fFacetNormal)).
unit();
1235 E1_perp = fOldPolarization * A_trans;
1236 E1pp = E1_perp * A_trans;
1237 E1pl = fOldPolarization - E1pp;
1238 E1_parl = E1pl.
mag();
1242 A_trans = fOldPolarization;
1249 s1 = fRindex1 * cost1;
1250 E2_perp = 2. * s1 * E1_perp / (fRindex1 * cost1 + fRindex2 * cost2);
1251 E2_parl = 2. * s1 * E1_parl / (fRindex2 * cost1 + fRindex1 * cost2);
1252 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1253 s2 = fRindex2 * cost2 * E2_total;
1263 G4double transCoeff = (cost1 != 0.0) ? s2 / s1 : 0.0;
1266 if(!G4BooleanRand(transCoeff))
1271 if(!roughnessCriterionPass)
1281 fNewMomentum = -fOldMomentum;
1282 fNewPolarization = -fOldPolarization;
1287 fOldMomentum - 2. * fOldMomentum * fFacetNormal * fFacetNormal;
1290 E2_parl = fRindex2 * E2_parl / fRindex1 - E1_parl;
1291 E2_perp = E2_perp - E1_perp;
1292 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1293 A_paral = (fNewMomentum.cross(A_trans)).
unit();
1294 E2_abs = std::sqrt(E2_total);
1295 fNewPolarization = (E2_parl * A_paral + E2_perp * A_trans) / E2_abs;
1300 (fRindex2 > fRindex1 ? -1.0 : 1.0) * fOldPolarization;
1313 alpha = cost1 - cost2 * (fRindex2 / fRindex1);
1314 fNewMomentum = (fOldMomentum +
alpha * fFacetNormal).unit();
1315 A_paral = (fNewMomentum.cross(A_trans)).
unit();
1316 E2_abs = std::sqrt(E2_total);
1318 fNewPolarization = (E2_parl * A_paral + E2_perp * A_trans) / E2_abs;
1322 fNewMomentum = fOldMomentum;
1323 fNewPolarization = fOldPolarization;
1328 fOldMomentum = fNewMomentum.unit();
1329 fOldPolarization = fNewPolarization.unit();
1333 done = (fNewMomentum * fGlobalNormal <= 0.0);
1337 done = (fNewMomentum * fGlobalNormal >= -fCarTolerance);
1352G4double G4OpBoundaryProcess::GetIncidentAngle()
1354 return pi - std::acos(fOldMomentum * fFacetNormal /
1355 (fOldMomentum.
mag() * fFacetNormal.mag()));
1366 G4complex N2(realRindex, imaginaryRindex);
1368 G4MaterialPropertiesTable* MPT = fMaterial1->GetMaterialPropertiesTable();
1373 G4double rRindex = ppR->
Value(fPhotonMomentum, idx_rrindex);
1374 G4double iRindex = ppI->
Value(fPhotonMomentum, idx_irindex);
1380 G4double sint = std::sin(incidentangle);
1381 G4double cost = std::cos(incidentangle);
1383 G4complex cosPhi = std::sqrt(u - ((sint * sint) * (N1 * N1) / (N2 * N2)));
1387 G4complex rTE = (N1 * cost - N2 * cosPhi) / (N1 * cost + N2 * cosPhi);
1388 G4complex rTM = (N2 * cost - N1 * cosPhi) / (N2 * cost + N1 * cosPhi);
1394 G4double E1_perp_sq = E1_perp * E1_perp;
1395 G4double E1_parl_sq = E1_parl * E1_parl;
1396 G4double E1_sq = E1_perp_sq + E1_parl_sq;
1398 G4complex reflectivity_TE = (rTE * conj(rTE)) * E1_perp_sq / E1_sq;
1399 G4complex reflectivity_TM = (rTM * conj(rTM)) * E1_parl_sq / E1_sq;
1400 G4complex reflectivity = reflectivity_TE + reflectivity_TM;
1406 f_iTE = (
G4UniformRand() * rr > real(reflectivity_TE)) ? -1 : 1;
1407 f_iTM = (
G4UniformRand() * rr > real(reflectivity_TM)) ? -1 : 1;
1409 }
while(f_iTE < 0 && f_iTM < 0);
1415void G4OpBoundaryProcess::CalculateReflectivity()
1417 G4double realRindex = fRealRIndexMPV->Value(fPhotonMomentum, idx_rrindex);
1418 G4double imagRindex = fImagRIndexMPV->Value(fPhotonMomentum, idx_irindex);
1421 fFacetNormal = (fFinish ==
ground) ?
1422 GetFacetNormal(fOldMomentum, fGlobalNormal) : fGlobalNormal;
1424 G4double cost1 = -fOldMomentum * fFacetNormal;
1425 fSint1 = (std::abs(cost1) < 1.0 - fCarTolerance) ?
1426 std::sqrt(1. - cost1 * cost1) : 0.0;
1433 A_trans = (fOldMomentum.cross(fFacetNormal)).
unit();
1434 E1_perp = fOldPolarization * A_trans;
1435 E1pp = E1_perp * A_trans;
1436 E1pl = fOldPolarization - E1pp;
1437 E1_parl = E1pl.
mag();
1441 A_trans = fOldPolarization;
1448 G4double incidentangle = GetIncidentAngle();
1452 fReflectivity = GetReflectivity(E1_perp, E1_parl, incidentangle, realRindex,
1457G4bool G4OpBoundaryProcess::InvokeSD(
const G4Step* pStep)
1459 G4Step aStep = *pStep;
1464 return sd->
Hit(&aStep);
1484void G4OpBoundaryProcess::CoatedDielectricDielectric()
1491 fRindex2 = pp->Value(fPhotonMomentum, idx_rindex2);
1494 MPT = fOpticalSurface->GetMaterialPropertiesTable();
1497 fCoatedRindex =
pp->Value(fPhotonMomentum, idx_coatedrindex);
1505 fCoatedFrustratedTransmission =
1513 G4double s1, E2_perp, E2_parl, E2_total;
1528 fGlobalNormal = -fGlobalNormal;
1533 fFacetNormal = (fFinish ==
polished) ? fGlobalNormal :
1534 GetFacetNormal(fOldMomentum, fGlobalNormal);
1536 PdotN = fOldMomentum * fFacetNormal;
1540 if (std::abs(cost1) < 1.0 - fCarTolerance)
1542 fSint1 = std::sqrt(1. - cost1 * cost1);
1543 sint2 = fSint1 * fRindex1 / fRindex2;
1544 sintTL = fSint1 * fRindex1 / fCoatedRindex;
1555 A_trans = fOldMomentum.
cross(fFacetNormal);
1556 A_trans = A_trans.
unit();
1557 E1_perp = fOldPolarization * A_trans;
1558 E1pp = E1_perp * A_trans;
1559 E1pl = fOldPolarization - E1pp;
1560 E1_parl = E1pl.
mag();
1564 A_trans = fOldPolarization;
1569 s1 = fRindex1 * cost1;
1571 cost2 = (cost1 > 0.0 ? 1.0 : -1.0) * std::sqrt(1. - sint2 * sint2);
1573 E2_perp = 2. * s1 * E1_perp / (fRindex1 * cost1 + fRindex2 * cost2);
1574 E2_parl = 2. * s1 * E1_parl / (fRindex2 * cost1 + fRindex1 * cost2);
1575 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1577 G4double transCoeff = 1. - GetReflectivityThroughThinLayer(
1578 sintTL, E1_perp, E1_parl, wavelength, cost1, cost2);
1579 if (!G4BooleanRand(transCoeff))
1582 G4cout <<
"Reflection from " << fMaterial1->GetName() <<
" to "
1583 << fMaterial2->GetName() <<
G4endl;
1587 fStatus = (sintTL >= 1.0) ?
1590 PdotN = fOldMomentum * fFacetNormal;
1591 fNewMomentum = fOldMomentum - (2. * PdotN) * fFacetNormal;
1595 E2_parl = fRindex2 * E2_parl / fRindex1 - E1_parl;
1596 E2_perp = E2_perp - E1_perp;
1597 E2_total = E2_perp * E2_perp + E2_parl * E2_parl;
1598 A_paral = fNewMomentum.
cross(A_trans);
1599 A_paral = A_paral.
unit();
1600 E2_abs = std::sqrt(E2_total);
1602 fNewPolarization = (E2_parl * A_paral + E2_perp * A_trans) / E2_abs;
1606 fNewPolarization = (fRindex2 > fRindex1 ? -1. : 1.) * fOldPolarization;
1612 G4cout <<
"Transmission from " << fMaterial1->GetName() <<
" to "
1613 << fMaterial2->GetName() <<
G4endl;
1618 if (fEfficiency > 0.)
1630 alpha = cost1 - cost2 * (fRindex2 / fRindex1);
1631 fNewMomentum = fOldMomentum +
alpha * fFacetNormal;
1632 fNewMomentum = fNewMomentum.unit();
1633 A_paral = fNewMomentum.
cross(A_trans);
1634 A_paral = A_paral.
unit();
1635 E2_abs = std::sqrt(E2_total);
1637 fNewPolarization = (E2_parl * A_paral + E2_perp * A_trans) / E2_abs;
1641 fNewMomentum = fOldMomentum;
1642 fNewPolarization = fOldPolarization;
1647 fOldMomentum = fNewMomentum.unit();
1648 fOldPolarization = fNewPolarization.unit();
1652 done = (fNewMomentum * fGlobalNormal <= 0.0);
1656 done = (fNewMomentum * fGlobalNormal >= -fCarTolerance);
1662G4double G4OpBoundaryProcess::GetReflectivityThroughThinLayer(
G4double sinTL,
1677 if (fCoatedFrustratedTransmission)
1679 G4double coatedRindex_sq = fCoatedRindex * fCoatedRindex;
1680 G4double gamma = fRindex1 * fRindex1 * fSint1 * fSint1 - coatedRindex_sq;
1681 gammaTL = (cost1 > 0.0 ? 1.0 : -1.0) * std::sqrt(gamma);
1683 G4double afact = std::exp(-2 * k0 * fCoatedThickness * gammaTL);
1688 r1toTL = (r1 - rc) / (r1 + rc);
1689 rTLto2 = (rc - r2) / (rc + r2);
1692 rTE = (r1toTL + rTLto2 * afact) / (1.0 + r1toTL * rTLto2 * afact);
1695 r1toTL = (fRindex1 * rc - coatedRindex_sq * cost1) /
1696 (fRindex1 * rc + coatedRindex_sq * cost1);
1697 rTLto2 = (coatedRindex_sq * cost2 - fRindex2 * rc) /
1698 (coatedRindex_sq * cost2 + fRindex2 * rc);
1701 rTM = (r1toTL + rTLto2 * afact) / (1.0 + r1toTL * rTLto2 * afact);
1713 costTL = (cost1 > 0.0 ? 1.0 : -1.0) * std::sqrt(1. - sinTL * sinTL);
1714 G4double rc = fCoatedRindex * costTL;
1715 G4complex afact = std::exp(2.0 * i * k0 * fCoatedThickness * rc);
1721 r1toTL = (r1 - rc) / (r1 + rc);
1722 rTLto2 = (rc - r2) / (r2 + rc);
1725 rTE = (r1toTL + rTLto2 * afact) / (1.0 + r1toTL * rTLto2 * afact);
1728 r1 = fRindex1 * costTL;
1729 r2 = fRindex2 * costTL;
1730 rc = fCoatedRindex * cost1;
1731 r1toTL = (r1 - rc) / (r1 + rc);
1733 rc = fCoatedRindex * cost2;
1734 rTLto2 = (rc - r2) / (rc + r2);
1737 rTM = (r1toTL + rTLto2 * afact) / (1.0 + r1toTL * rTLto2 * afact);
1741 G4double E1_perp_sq = E1_perp * E1_perp;
1742 G4double E1_parl_sq = E1_parl * E1_parl;
1743 G4double E1_sq = E1_perp_sq + E1_parl_sq;
1745 G4complex Reflectivity_TE = (rTE * conj(rTE)) * E1_perp_sq / E1_sq;
1746 G4complex Reflectivity_TM = (rTM * conj(rTM)) * E1_parl_sq / E1_sq;
1747 G4complex Reflectivity = Reflectivity_TE + Reflectivity_TM;
1749 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
G4PhysicsFreeVector G4MaterialPropertyVector
G4OpBoundaryProcessStatus
@ PolishedTiOAirReflection
@ GroundTeflonAirReflection
@ EtchedVM2000AirReflection
@ CoatedDielectricReflection
@ EtchedVM2000GlueReflection
@ GroundLumirrorGlueReflection
@ GroundTyvekAirReflection
@ PolishedVM2000GlueReflection
@ PolishedTeflonAirReflection
@ EtchedTyvekAirReflection
@ EtchedLumirrorGlueReflection
@ GroundVM2000AirReflection
@ PolishedTyvekAirReflection
@ PolishedVM2000AirReflection
@ EtchedTeflonAirReflection
@ GroundVM2000GlueReflection
@ PolishedLumirrorGlueReflection
@ TotalInternalReflection
@ CoatedDielectricFrustratedTransmission
@ PolishedLumirrorAirReflection
@ EtchedLumirrorAirReflection
@ GroundLumirrorAirReflection
@ CoatedDielectricRefraction
CLHEP::Hep3Vector G4ThreeVector
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)
G4LogicalSurface is an abstraction of a geometrical surface, it is an abstract base class for differe...
G4SurfaceProperty * GetSurfaceProperty() const
G4bool ConstPropertyExists(const G4String &key) const
G4double GetConstProperty(const G4String &key) const
G4MaterialPropertyVector * GetProperty(const char *key) const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() 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()
static const G4Step * GetHyperStep()
static G4int GetHypNavigatorID()
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
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 &)
G4VDiscreteProcess(const G4String &aName, G4ProcessType aType=fNotDefined)
G4VPhysicalVolume is an abstract base class for the representation of a positioned volume....
G4LogicalVolume * GetMotherLogical() const
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
G4ParticleChange aParticleChange
void SetProcessSubType(G4int)
const G4String & GetProcessName() const
G4bool Hit(G4Step *aStep)
const G4double hc
[MeV*fm]
void swap(T &lhs, T &rhs)
void G4SwapObj(T *a, T *b)
void G4SwapPtr(T *&a, T *&b)