File indexing completed on 2026-09-21 09:10:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 #ifndef G4OpBoundaryProcess_h
0065 #define G4OpBoundaryProcess_h 1
0066
0067 #include "G4OpticalPhoton.hh"
0068 #include "G4OpticalSurface.hh"
0069 #include "G4RandomTools.hh"
0070 #include "G4VDiscreteProcess.hh"
0071
0072 enum G4OpBoundaryProcessStatus
0073 {
0074 Undefined,
0075 Transmission,
0076 FresnelRefraction,
0077 FresnelReflection,
0078 TotalInternalReflection,
0079 LambertianReflection,
0080 LobeReflection,
0081 SpikeReflection,
0082 BackScattering,
0083 Absorption,
0084 Detection,
0085 NotAtBoundary,
0086 SameMaterial,
0087 StepTooSmall,
0088 NoRINDEX,
0089 PolishedLumirrorAirReflection,
0090 PolishedLumirrorGlueReflection,
0091 PolishedAirReflection,
0092 PolishedTeflonAirReflection,
0093 PolishedTiOAirReflection,
0094 PolishedTyvekAirReflection,
0095 PolishedVM2000AirReflection,
0096 PolishedVM2000GlueReflection,
0097 EtchedLumirrorAirReflection,
0098 EtchedLumirrorGlueReflection,
0099 EtchedAirReflection,
0100 EtchedTeflonAirReflection,
0101 EtchedTiOAirReflection,
0102 EtchedTyvekAirReflection,
0103 EtchedVM2000AirReflection,
0104 EtchedVM2000GlueReflection,
0105 GroundLumirrorAirReflection,
0106 GroundLumirrorGlueReflection,
0107 GroundAirReflection,
0108 GroundTeflonAirReflection,
0109 GroundTiOAirReflection,
0110 GroundTyvekAirReflection,
0111 GroundVM2000AirReflection,
0112 GroundVM2000GlueReflection,
0113 Dichroic,
0114 CoatedDielectricReflection,
0115 CoatedDielectricRefraction,
0116 CoatedDielectricFrustratedTransmission
0117 };
0118
0119 class G4OpBoundaryProcess : public G4VDiscreteProcess
0120 {
0121 public:
0122 explicit G4OpBoundaryProcess(const G4String& processName = "OpBoundary",
0123 G4ProcessType type = fOptical);
0124 virtual ~G4OpBoundaryProcess();
0125
0126 virtual G4bool IsApplicable(
0127 const G4ParticleDefinition& aParticleType) override;
0128
0129
0130 virtual G4double GetMeanFreePath(const G4Track&, G4double,
0131 G4ForceCondition* condition) override;
0132
0133
0134
0135
0136 G4VParticleChange* PostStepDoIt(const G4Track& aTrack,
0137 const G4Step& aStep) override;
0138
0139
0140 virtual G4OpBoundaryProcessStatus GetStatus() const;
0141
0142
0143 virtual void SetInvokeSD(G4bool);
0144
0145
0146 virtual void PreparePhysicsTable(const G4ParticleDefinition&) override;
0147
0148 virtual void Initialise();
0149
0150 void SetVerboseLevel(G4int);
0151
0152 private:
0153 G4OpBoundaryProcess(const G4OpBoundaryProcess& right) = delete;
0154 G4OpBoundaryProcess& operator=(const G4OpBoundaryProcess& right) = delete;
0155
0156 G4bool G4BooleanRand(const G4double prob) const;
0157
0158 G4ThreeVector GetFacetNormal(const G4ThreeVector& Momentum,
0159 const G4ThreeVector& Normal) const;
0160
0161 void DielectricMetal();
0162 void DielectricDielectric();
0163
0164 void DielectricLUT();
0165 void DielectricLUTDAVIS();
0166
0167 void DielectricDichroic();
0168 void CoatedDielectricDielectric();
0169
0170 void ChooseReflection();
0171 void DoAbsorption();
0172 void DoReflection();
0173 void DoTransmission();
0174
0175 void ApplyDielectricBoundaryTransition(G4double cost, G4bool roughnessPass,
0176 G4bool& inside, G4bool& swap);
0177
0178
0179 G4double GetIncidentAngle();
0180
0181
0182 G4double GetReflectivity(G4double E1_perp, G4double E1_parl,
0183 G4double incidentangle, G4double RealRindex,
0184 G4double ImaginaryRindex);
0185
0186
0187 G4double GetReflectivityThroughThinLayer(G4double sinTL, G4double E1_perp,
0188 G4double E1_parl, G4double wavelength,
0189 G4double cost1, G4double cost2);
0190
0191
0192 void CalculateReflectivity();
0193
0194 void BoundaryProcessVerbose() const;
0195
0196
0197 G4bool InvokeSD(const G4Step* step);
0198
0199
0200 static constexpr G4bool IsBackpainted(G4OpticalSurfaceFinish finish) noexcept
0201 {
0202 return finish == polishedbackpainted || finish == groundbackpainted;
0203 }
0204
0205 G4ThreeVector fOldMomentum;
0206 G4ThreeVector fOldPolarization;
0207
0208 G4ThreeVector fNewMomentum;
0209 G4ThreeVector fNewPolarization;
0210
0211 G4ThreeVector fGlobalNormal;
0212 G4ThreeVector fFacetNormal;
0213
0214 const G4Material* fMaterial1;
0215 const G4Material* fMaterial2;
0216
0217 G4OpticalSurface* fOpticalSurface;
0218
0219 G4MaterialPropertyVector* fRealRIndexMPV;
0220 G4MaterialPropertyVector* fImagRIndexMPV;
0221 G4Physics2DVector* fDichroicVector;
0222
0223 G4double fPhotonMomentum;
0224 G4double fRindex1;
0225 G4double fRindex2;
0226
0227 G4double fSint1;
0228
0229 G4double fReflectivity;
0230 G4double fEfficiency;
0231 G4double fTransmittance;
0232 G4double fSurfaceRoughness;
0233
0234 G4double fProb_sl, fProb_ss, fProb_bs;
0235 G4double fCarTolerance;
0236
0237
0238 G4double fCoatedRindex, fCoatedThickness;
0239
0240 G4OpBoundaryProcessStatus fStatus;
0241 G4OpticalSurfaceModel fModel;
0242 G4OpticalSurfaceFinish fFinish;
0243
0244 G4int f_iTE, f_iTM;
0245
0246 G4int fNumSmallStepWarnings = 0;
0247 G4int fNumBdryTypeWarnings = 0;
0248
0249 size_t idx_dichroicX = 0;
0250 size_t idx_dichroicY = 0;
0251 size_t idx_rindex1 = 0;
0252 size_t idx_rindex_surface = 0;
0253 size_t idx_reflect = 0;
0254 size_t idx_eff = 0;
0255 size_t idx_trans = 0;
0256 size_t idx_lobe = 0;
0257 size_t idx_spike = 0;
0258 size_t idx_back = 0;
0259 size_t idx_rindex2 = 0;
0260 size_t idx_groupvel = 0;
0261 size_t idx_rrindex = 0;
0262 size_t idx_irindex = 0;
0263 size_t idx_coatedrindex = 0;
0264
0265
0266 G4bool fCoatedFrustratedTransmission = true;
0267
0268 G4bool fInvokeSD;
0269 };
0270
0271
0272
0273
0274
0275 inline G4bool G4OpBoundaryProcess::G4BooleanRand(const G4double prob) const
0276 {
0277
0278 return (G4UniformRand() < prob);
0279 }
0280
0281 inline G4bool G4OpBoundaryProcess::IsApplicable(
0282 const G4ParticleDefinition& aParticleType)
0283 {
0284 return (&aParticleType == G4OpticalPhoton::OpticalPhoton());
0285 }
0286
0287 inline G4OpBoundaryProcessStatus G4OpBoundaryProcess::GetStatus() const
0288 {
0289 return fStatus;
0290 }
0291
0292 inline void G4OpBoundaryProcess::ChooseReflection()
0293 {
0294 G4double rand = G4UniformRand();
0295 if(rand < fProb_ss)
0296 {
0297 fStatus = SpikeReflection;
0298 fFacetNormal = fGlobalNormal;
0299 }
0300 else if(rand < fProb_ss + fProb_sl)
0301 {
0302 fStatus = LobeReflection;
0303 }
0304 else if(rand < fProb_ss + fProb_sl + fProb_bs)
0305 {
0306 fStatus = BackScattering;
0307 }
0308 else
0309 {
0310 fStatus = LambertianReflection;
0311 }
0312 }
0313
0314 inline void G4OpBoundaryProcess::DoAbsorption()
0315 {
0316 fStatus = Absorption;
0317
0318 if(G4BooleanRand(fEfficiency))
0319 {
0320
0321 fStatus = Detection;
0322 aParticleChange.ProposeLocalEnergyDeposit(fPhotonMomentum);
0323 }
0324 else
0325 {
0326 aParticleChange.ProposeLocalEnergyDeposit(0.0);
0327 }
0328
0329 fNewMomentum = fOldMomentum;
0330 fNewPolarization = fOldPolarization;
0331
0332 aParticleChange.ProposeTrackStatus(fStopAndKill);
0333 }
0334
0335 inline void G4OpBoundaryProcess::DoTransmission()
0336 {
0337
0338
0339 fStatus = Transmission;
0340 fNewMomentum = fOldMomentum;
0341 fNewPolarization = fOldPolarization;
0342 }
0343
0344 inline void G4OpBoundaryProcess::DoReflection()
0345 {
0346 if(fStatus == LambertianReflection)
0347 {
0348 fNewMomentum = G4LambertianRand(fGlobalNormal);
0349 fFacetNormal = (fNewMomentum - fOldMomentum).unit();
0350 }
0351 else if(fFinish == ground)
0352 {
0353 fStatus = LobeReflection;
0354 if(!fRealRIndexMPV || !fImagRIndexMPV)
0355 {
0356 fFacetNormal = GetFacetNormal(fOldMomentum, fGlobalNormal);
0357 }
0358
0359
0360 fNewMomentum =
0361 fOldMomentum - (2. * fOldMomentum * fFacetNormal * fFacetNormal);
0362 }
0363 else
0364 {
0365 fStatus = SpikeReflection;
0366 fFacetNormal = fGlobalNormal;
0367 fNewMomentum =
0368 fOldMomentum - (2. * fOldMomentum * fFacetNormal * fFacetNormal);
0369 }
0370 fNewPolarization =
0371 -fOldPolarization + (2. * fOldPolarization * fFacetNormal * fFacetNormal);
0372 }
0373
0374 #endif