70 #include "G4GeometryTolerance.hh"
73 using namespace TelescopeSimulatorLX ;
93 : G4VDiscreteProcess(processName, type)
95 if ( verboseLevel > 0) {
96 G4cerr << GetProcessName() <<
" is created " << G4endl;
110 ->GetSurfaceTolerance();
136 aParticleChange.Initialize(aTrack);
138 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
139 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
141 if (pPostStepPoint->GetStepStatus() != fGeomBoundary){
143 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
147 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
150 Material1 = pPreStepPoint -> GetMaterial();
151 Material2 = pPostStepPoint -> GetMaterial();
153 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
159 G4ThreeVector theGlobalPoint = pPostStepPoint->GetPosition();
161 G4Navigator* theNavigator =
162 G4TransportationManager::GetTransportationManager()->
163 GetNavigatorForTracking();
165 G4ThreeVector theLocalPoint = theNavigator->
166 GetGlobalToLocalTransform().
167 TransformPoint(theGlobalPoint);
169 G4ThreeVector theLocalNormal;
172 theLocalNormal = theNavigator->GetLocalExitNormal(&valid);
175 theLocalNormal = -theLocalNormal;
178 G4cerr <<
" FDsimG4OpBoundaryProcess/PostStepDoIt(): "
179 <<
" The Navigator reports that it returned an invalid normal"
184 TransformAxis(theLocalNormal);
187 #ifdef G4DEBUG_OPTICAL
188 G4cerr <<
" FDsimG4OpBoundaryProcess/PostStepDoIt(): "
189 <<
" theGlobalNormal points the wrong direction "
195 G4MaterialPropertiesTable* aMaterialPropertiesTable;
196 G4MaterialPropertyVector* Rindex;
198 aMaterialPropertiesTable =
Material1->GetMaterialPropertiesTable();
199 if (aMaterialPropertiesTable) {
200 Rindex = aMaterialPropertiesTable->GetProperty(
"RINDEX");
204 aParticleChange.ProposeTrackStatus(fStopAndKill);
205 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
213 aParticleChange.ProposeTrackStatus(fStopAndKill);
214 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
220 G4SurfaceType type = dielectric_dielectric;
225 G4LogicalSurface* Surface = G4LogicalBorderSurface::GetSurface
226 (pPreStepPoint ->GetPhysicalVolume(),
227 pPostStepPoint->GetPhysicalVolume());
229 if (Surface == NULL){
230 G4bool enteredDaughter=(pPostStepPoint->GetPhysicalVolume()
231 ->GetMotherLogical() ==
232 pPreStepPoint->GetPhysicalVolume()
233 ->GetLogicalVolume());
235 Surface = G4LogicalSkinSurface::GetSurface
236 (pPostStepPoint->GetPhysicalVolume()->
239 Surface = G4LogicalSkinSurface::GetSurface
240 (pPreStepPoint->GetPhysicalVolume()->
244 Surface = G4LogicalSkinSurface::GetSurface
245 (pPreStepPoint->GetPhysicalVolume()->
248 Surface = G4LogicalSkinSurface::GetSurface
249 (pPostStepPoint->GetPhysicalVolume()->
255 if (Surface)
OpticalSurface = (G4OpticalSurface*) Surface->GetSurfaceProperty();
264 GetMaterialPropertiesTable();
266 if (aMaterialPropertiesTable) {
270 Rindex = aMaterialPropertiesTable->GetProperty(
"RINDEX");
276 aParticleChange.ProposeTrackStatus(fStopAndKill);
277 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
281 G4MaterialPropertyVector* PropertyPointer;
282 G4MaterialPropertyVector* PropertyPointer1;
283 G4MaterialPropertyVector* PropertyPointer2;
286 aMaterialPropertiesTable->GetProperty(
"REFLECTIVITY");
288 aMaterialPropertiesTable->GetProperty(
"REALRINDEX");
290 aMaterialPropertiesTable->GetProperty(
"IMAGINARYRINDEX");
295 if (PropertyPointer) {
300 }
else if (PropertyPointer1 && PropertyPointer2) {
302 G4double RealRindex =
304 G4double ImaginaryRindex =
324 G4ThreeVector A_trans, A_paral, E1pp, E1pl;
325 G4double E1_perp, E1_parl;
329 A_trans = A_trans.unit();
331 E1pp = E1_perp * A_trans;
333 E1_parl = E1pl.mag();
351 G4double thickness = 0.0;
352 if (aMaterialPropertiesTable->ConstPropertyExists(
"THICKNESS"))
353 thickness = aMaterialPropertiesTable->GetConstProperty(
"THICKNESS");
355 if (thickness != 0.0) {
356 G4complex RindexCmplx = G4complex(RealRindex, -ImaginaryRindex);
357 G4double Rindex3 = 1.0;
375 RealRindex, ImaginaryRindex);
383 aMaterialPropertiesTable->GetProperty(
"EFFICIENCY");
384 if (PropertyPointer) {
393 aMaterialPropertiesTable->GetProperty(
"SPECULARLOBECONSTANT");
394 if (PropertyPointer) {
402 aMaterialPropertiesTable->GetProperty(
"SPECULARSPIKECONSTANT");
403 if (PropertyPointer) {
411 aMaterialPropertiesTable->GetProperty(
"BACKSCATTERCONSTANT");
412 if (PropertyPointer) {
420 else if (
theFinish == polishedbackpainted ||
422 aParticleChange.ProposeTrackStatus(fStopAndKill);
423 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
427 if (type == dielectric_dielectric ) {
432 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
434 aMaterialPropertiesTable =
436 if (aMaterialPropertiesTable)
437 Rindex = aMaterialPropertiesTable->GetProperty(
"RINDEX");
443 aParticleChange.ProposeTrackStatus(fStopAndKill);
444 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
449 if ( verboseLevel > 0 ) {
450 G4cerr <<
" Photon at Boundary! " << G4endl;
451 G4cerr <<
" Old Momentum Direction: " <<
OldMomentum << G4endl;
455 if (type == dielectric_metal) {
460 else if (type == dielectric_dielectric) {
462 if (
theFinish == polishedfrontpainted ||
480 G4cerr <<
" Error: G4BoundaryProcess: illegal boundary type " << G4endl;
481 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
488 if ( verboseLevel > 0) {
489 G4cerr <<
" New Momentum Direction: " <<
NewMomentum << G4endl;
492 G4cerr <<
" *** Undefined *** " << G4endl;
494 G4cerr <<
" *** FresnelRefraction *** " << G4endl;
496 G4cerr <<
" *** FresnelReflection *** " << G4endl;
498 G4cerr <<
" *** TotalInternalReflection *** " << G4endl;
500 G4cerr <<
" *** LambertianReflection *** " << G4endl;
502 G4cerr <<
" *** LobeReflection *** " << G4endl;
504 G4cerr <<
" *** SpikeReflection *** " << G4endl;
506 G4cerr <<
" *** BackScattering *** " << G4endl;
508 G4cerr <<
" *** Absorption *** " << G4endl;
510 G4cerr <<
" *** Detection *** " << G4endl;
512 G4cerr <<
" *** NotAtBoundary *** " << G4endl;
514 G4cerr <<
" *** SameMaterial *** " << G4endl;
516 G4cerr <<
" *** StepTooSmall *** " << G4endl;
518 G4cerr <<
" *** NoRINDEX *** " << G4endl;
521 aParticleChange.ProposeMomentumDirection(
NewMomentum);
524 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
529 const G4ThreeVector& Normal )
const
531 G4ThreeVector FacetNormal;
543 G4double sigma_alpha = 0.0;
546 G4double f_max = std::min(1.0,4.*sigma_alpha);
550 alpha = G4RandGauss::shoot(0.0,sigma_alpha);
551 }
while (G4UniformRand()*f_max > std::sin(alpha) || alpha >= halfpi );
553 G4double phi = G4UniformRand()*twopi;
555 G4double SinAlpha = std::sin(alpha);
556 G4double CosAlpha = std::cos(alpha);
557 G4double SinPhi = std::sin(phi);
558 G4double CosPhi = std::cos(phi);
560 G4double unit_x = SinAlpha * CosPhi;
561 G4double unit_y = SinAlpha * SinPhi;
562 G4double unit_z = CosAlpha;
564 FacetNormal.setX(unit_x);
565 FacetNormal.setY(unit_y);
566 FacetNormal.setZ(unit_z);
568 G4ThreeVector tmpNormal = Normal;
570 FacetNormal.rotateUz(tmpNormal);
571 }
while (Momentum * FacetNormal >= 0.0);
575 G4double polish = 1.0;
582 smear.setX(2.*G4UniformRand()-1.0);
583 smear.setY(2.*G4UniformRand()-1.0);
584 smear.setZ(2.*G4UniformRand()-1.0);
585 }
while (smear.mag()>1.0);
586 smear = (1.-polish) * smear;
587 FacetNormal = Normal + smear;
588 }
while (Momentum * FacetNormal >= 0.0);
589 FacetNormal = FacetNormal.unit();
592 FacetNormal = Normal;
638 G4ThreeVector A_trans, A_paral;
642 A_trans = A_trans.unit();
647 A_paral = A_paral.unit();
672 G4bool Inside =
false;
677 G4bool Through =
false;
715 if (Swap) Swap = !Swap;
738 else if (
sint2 < 1.0) {
749 G4ThreeVector A_trans, A_paral, E1pp, E1pl;
750 G4double E1_perp, E1_parl;
754 A_trans = A_trans.unit();
756 E1pp = E1_perp * A_trans;
758 E1_parl = E1pl.mag();
772 G4double E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
784 G4double E2_abs, C_parl, C_perp;
790 if (Swap) Swap = !Swap;
812 E2_perp = E2_perp - E1_perp;
813 E2_total = E2_perp*E2_perp + E2_parl*E2_parl;
815 A_paral = A_paral.unit();
817 C_parl = E2_parl/E2_abs;
818 C_perp = E2_perp/E2_abs;
848 NewMomentum = NewMomentum.unit();
850 A_paral = NewMomentum.cross(A_trans);
851 A_paral = A_paral.unit();
853 C_parl = E2_parl/E2_abs;
854 C_perp = E2_perp/E2_abs;
880 if (Inside && !Swap) {
915 G4ForceCondition* condition)
926 G4double magN= theFacetNormal.mag();
927 G4double incidentangle = pi - std::acos(PdotN/(magP*magN));
929 return incidentangle;
934 G4double incidentangle,
936 G4double ImaginaryRindex)
939 G4complex Reflectivity, Reflectivity_TE, Reflectivity_TM;
940 G4complex N(RealRindex, ImaginaryRindex);
945 G4complex numeratorTE;
946 G4complex numeratorTM;
947 G4complex denominatorTE, denominatorTM;
953 CosPhi=
std::sqrt(u-((std::sin(incidentangle)*std::sin(incidentangle))/(N*N)));
955 numeratorTE = std::cos(incidentangle) - N*CosPhi;
956 denominatorTE = std::cos(incidentangle) + N*CosPhi;
957 rTE = numeratorTE/denominatorTE;
959 numeratorTM = N*std::cos(incidentangle) - CosPhi;
960 denominatorTM = N*std::cos(incidentangle) + CosPhi;
961 rTM = numeratorTM/denominatorTM;
968 Reflectivity_TE = (rTE*conj(rTE))*(E1_perp*E1_perp)
969 / (E1_perp*E1_perp + E1_parl*E1_parl);
970 Reflectivity_TM = (rTM*conj(rTM))*(E1_parl*E1_parl)
971 / (E1_perp*E1_perp + E1_parl*E1_parl);
972 Reflectivity = Reflectivity_TE + Reflectivity_TM;
982 if(G4UniformRand()*real(Reflectivity) > real(Reflectivity_TE))
984 if(G4UniformRand()*real(Reflectivity) > real(Reflectivity_TM))
988 return real(Reflectivity);
994 G4double n1,G4complex n2, G4double n3,
997 G4double sinth = sin(incidentangle);
1001 return Reflectivity;
G4ThreeVector theFacetNormal
G4double GetReflectivity(G4double E1_perp, G4double E1_parl, G4double incidentangle, G4double RealRindex, G4double ImaginaryRindex)
~FDsimG4OpBoundaryProcess()
G4OpticalSurfaceModel theModel
G4ThreeVector GetFacetNormal(const G4ThreeVector &Momentum, const G4ThreeVector &Normal) const
G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *condition)
G4double GetIncidentAngle()
G4double GetReflectivityThinFilm(G4double incidentangle, G4double n1, G4complex n2, G4double n3, G4double thickness)
G4OpticalSurfaceFinish theFinish
FDsimG4OpBoundaryProcessStatus theStatus
double abs(const SVector< n, T > &v)
FDsimG4OpBoundaryProcess(const G4String &processName="OpBoundary", G4ProcessType type=fOptical)
void G4Swap(G4double *a, G4double *b) const
G4OpticalSurface * OpticalSurface
G4ThreeVector NewMomentum
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
G4bool G4BooleanRand(const G4double prob) const
G4double thePhotonMomentum
G4ThreeVector NewPolarization
static double GetReflectance(const double nIndex1, const dcomplex &nIndex2, const double nIndex3, const double sinTheta1, const double thickness, const double wavelength)
G4ThreeVector OldPolarization
G4ThreeVector OldMomentum
G4ThreeVector theGlobalNormal
void DielectricDielectric()