88 aMaterialPropertiesTable1 = NULL;
89 aMaterialPropertiesTable2 = NULL;
91 UseMicroRoughnessReflection =
false;
92 DoMicroRoughnessReflection =
false;
94 nNoMPT = nNoMRT = nNoMRCondition = 0;
95 nAbsorption = nEzero = nFlip = 0;
96 aSpecularReflection = bSpecularReflection = 0;
97 bLambertianReflection = 0;
98 aMRDiffuseReflection = bMRDiffuseReflection = 0;
99 nSnellTransmit = mSnellTransmit = 0;
100 aMRDiffuseTransmit = 0;
101 ftheta_o = fphi_o = 0;
119 const G4Step* pStep = &aStep;
123 if (hStep) pStep = hStep;
144 GetMaterialPropertiesTable();
146 GetMaterialPropertiesTable();
153 G4cout <<
" vol1: " << volnam1 <<
", vol2: " << volnam2 <<
G4endl;
158 if (Material1 == Material2) {
173 std::vector<G4Navigator*>::iterator iNav =
175 GetActiveNavigatorsIterator();
178 (iNav[hNavId])->GetGlobalExitNormal(theGlobalPoint,&valid);
181 theGlobalNormal = -theGlobalNormal;
186 ed <<
" G4UCNBoundaryProcess/PostStepDoIt(): "
187 <<
" The Navigator reports that it returned an invalid normal"
189 G4Exception(
"G4UCNBoundaryProcess::PostStepDoIt",
"UCNBoun01",
191 "Invalid Surface Normal - Geometry must return valid surface normal");
198 if (OldMomentum * theGlobalNormal > 0.0) {
199#ifdef G4OPTICAL_DEBUG
201 ed <<
" G4UCNBoundaryProcess/PostStepDoIt(): "
202 <<
" theGlobalNormal points in a wrong direction. "
204 ed <<
" The momentum of the photon arriving at interface (oldMomentum)"
205 <<
" must exit the volume cross in the step. " <<
G4endl;
206 ed <<
" So it MUST have dot < 0 with the normal that Exits the new volume (globalNormal)." <<
G4endl;
207 ed <<
" >> The dot product of oldMomentum and global Normal is " << OldMomentum*theGlobalNormal <<
G4endl;
208 ed <<
" Old Momentum (during step) = " << OldMomentum <<
G4endl;
209 ed <<
" Global Normal (Exiting New Vol) = " << theGlobalNormal <<
G4endl;
211 G4Exception(
"G4UCNBoundaryProcess::PostStepDoIt",
"UCNBoun02",
214 "Invalid Surface Normal - Geometry must return valid surface normal pointing in the right direction");
216 theGlobalNormal = -theGlobalNormal;
222 G4double theMomentumNormal = theNeutronMomentum*theGlobalNormal;
224 (OldMomentum * theGlobalNormal);
226 G4double Enormal = theMomentumNormal*theMomentumNormal/2./neutron_mass_c2;
234 if (aMaterialPropertiesTable2) {
242 if (aMaterialPropertiesTable1)
245 G4double FermiPotDiff = FermiPot2 - FermiPot1;
248 G4cout <<
"UCNBoundaryProcess: new FermiPot: " << FermiPot2/neV
249 <<
"neV, old FermiPot:" << FermiPot1/neV <<
"neV" <<
G4endl;
253 DoMicroRoughnessReflection = UseMicroRoughnessReflection;
257 if (!aMaterialPropertiesTable2) {
262 DoMicroRoughnessReflection =
false;
272 DoMicroRoughnessReflection =
false;
278 theta_i = OldMomentum.
angle(-theGlobalNormal);
282 if (!aMaterialPropertiesTable2->
283 ConditionsValid(Energy, FermiPotDiff, theta_i)) {
289 DoMicroRoughnessReflection =
false;
298 if (DoMicroRoughnessReflection) {
302 MRpDiffuse = aMaterialPropertiesTable2->
303 GetMRIntProbability(theta_i, Energy);
307 MRpDiffuseTrans = aMaterialPropertiesTable2->
308 GetMRIntTransProbability(theta_i, Energy);
311 G4cout <<
"theta: " << theta_i/degree <<
"degree" <<
G4endl;
312 G4cout <<
"Energy: " << Energy/neV <<
"neV"
313 <<
", Enormal: " << Enormal/neV <<
"neV" <<
G4endl;
314 G4cout <<
"FermiPotDiff: " << FermiPotDiff/neV <<
"neV " <<
G4endl;
315 G4cout <<
"Reflection_prob: " << MRpDiffuse
316 <<
", Transmission_prob: " << MRpDiffuseTrans <<
G4endl;
320 if (!High(Enormal, FermiPotDiff)) {
328 if (Loss(pUpScatter, theVelocityNormal, FermiPotDiff)) {
343 if (SpinFlip(pSpinFlip)) {
358 if (DoMicroRoughnessReflection)
359 NewMomentum =
MRreflect(MRpDiffuse, OldMomentum, theGlobalNormal,
360 Energy, FermiPotDiff);
365 NewMomentum = Reflect(pDiffuse, OldMomentum, theGlobalNormal);
383 if (DoMicroRoughnessReflection) {
389 theGlobalNormal, Energy, FermiPotDiff, Enew);
404 G4double reflectivity = Reflectivity(FermiPotDiff, Enormal);
407 << reflectivity <<
G4endl;
413 NewMomentum = Reflect(pDiffuse, OldMomentum, theGlobalNormal);
420 G4double Enew = Transmit(FermiPotDiff, Energy);
425 G4double mass = -std::sqrt(theMomentumNormal*theMomentumNormal -
426 neutron_mass_c2*2.*FermiPotDiff);
431 theNeutronMomentum - (theMomentumNormal-mass)*theGlobalNormal;
443 G4cout <<
"Energy: " << Energy/neV <<
"neV, Enormal: "
444 << Enormal/neV <<
"neV, fpdiff " << FermiPotDiff/neV
445 <<
"neV, Enew " << Enew/neV <<
"neV" <<
G4endl;
446 G4cout <<
"UCNBoundaryProcess: Transmit and set the new Energy "
475 G4double vBound = std::sqrt(2.*FermiPot/neutron_mass_c2*c_squared);
476 G4double vRatio = theVelocityNormal/vBound;
478 G4double pLoss = (2*pUpScatter*vRatio)/(std::sqrt(1-(vRatio*vRatio)));
482 if (DoMicroRoughnessReflection) {
483 if (aMaterialPropertiesTable2) {
484 const G4double hdm = hbar_Planck*c_squared/neutron_mass_c2;
490 pLoss *= std::sqrt(1+2*b*b*vBound*vBound/
491 (hdm*hdm+0.85*hdm*vBound*w+2*vBound*vBound*w*w));
505 G4double r = (std::sqrt(Enormal) - std::sqrt(Enormal - FermiPot)) /
506 (std::sqrt(Enormal) + std::sqrt(Enormal - FermiPot));
515 G4double PdotN = OldMomentum * Normal;
522 if (NewMomentum == OldMomentum ||
G4UniformRand() < pDiffuse) {
524 NewMomentum = LDiffRefl(Normal);
526 bLambertianReflection++;
535 bSpecularReflection++;
561 MRDiffRefl(Normal, Energy, FermiPot, OldMomentum, pDiffuse);
563 bMRDiffuseReflection++;
573 G4double PdotN = OldMomentum * Normal;
575 NewMomentum = OldMomentum - (2.*PdotN)*Normal;
578 bSpecularReflection++;
597 G4double costheta = OldMomentum*Normal;
599 G4double Enormal = Energy * (costheta*costheta);
602 G4double pSpecular = Reflectivity(FermiPot,Enormal)*
603 (1.-pDiffuse-pDiffuseTrans-pLoss);
609 if (decide < pSpecular) {
613 G4double PdotN = OldMomentum * Normal;
614 NewMomentum = OldMomentum - (2.*PdotN)*Normal;
619 aSpecularReflection++;
626 if (decide < pSpecular + pDiffuse) {
633 MRDiffRefl(Normal, Energy, FermiPot, OldMomentum, pDiffuse);
636 <<
", " << NewMomentum <<
G4endl;
639 aMRDiffuseReflection++;
646 if (decide < pSpecular + pDiffuse + pDiffuseTrans) {
653 MRDiffTrans(Normal, Energy, FermiPot, OldMomentum, pDiffuseTrans);
655 Enew = Energy - FermiPot;
657 aMRDiffuseTransmit++;
664 if (decide < pSpecular + pDiffuse + pDiffuseTrans + pLoss) {
679 Enew = Energy - FermiPot;
681 G4double palt = std::sqrt(2*neutron_mass_c2/c_squared*Energy);
682 G4double produ = OldMomentum * Normal;
684 NewMomentum = palt*OldMomentum-
685 (palt*produ+std::sqrt(palt*palt*produ*produ-2*neutron_mass_c2/
686 c_squared*FermiPot))*Normal;
692 return NewMomentum.
unit();
721 aMaterialPropertiesTable2->
722 GetMRMaxProbability(theta_i, Energy)/pDiffuse <=
723 aMaterialPropertiesTable2->
724 GetMRProbability(theta_i,Energy,FermiPot,theta_o,phi_o)/pDiffuse)
730 if (aMaterialPropertiesTable2->
731 GetMRProbability(theta_i, Energy, FermiPot, theta_o, phi_o)/
732 (1.5*aMaterialPropertiesTable2->
733 GetMRMaxProbability(theta_i, Energy)) > 1) {
734 G4cout <<
"MRMax Wahrscheinlichkeitsueberschreitung!" <<
G4endl;
735 G4cout << aMaterialPropertiesTable2->
736 GetMRProbability(theta_i, Energy, FermiPot, theta_o, phi_o)/
737 (1.5*aMaterialPropertiesTable2->
738 GetMRMaxProbability(theta_i, Energy)) <<
G4endl;
739 aMaterialPropertiesTable2->
740 SetMRMaxProbability(theta_i, Energy,
741 aMaterialPropertiesTable2->
742 GetMRProbability(theta_i, Energy,
743 FermiPot, theta_o, phi_o));
746 if(++count > 10000) { accepted =
true; }
760 GetCoordinateTransformMatrix(Normal, OldMomentum);
768 if (momentum * Normal<0) {
771 G4cout <<
"G4UCNBoundaryProcess::MRDiffRefl: !" <<
G4endl;
774 return momentum.
unit();
803 aMaterialPropertiesTable2->
804 GetMRMaxTransProbability(theta_i, Energy)/pDiffuseTrans <=
805 aMaterialPropertiesTable2->
806 GetMRTransProbability(theta_i,Energy,FermiPot,theta_o,phi_o)/
813 if(aMaterialPropertiesTable2->
814 GetMRTransProbability(theta_i, Energy, FermiPot, theta_o, phi_o)/
815 (1.5*aMaterialPropertiesTable2->
816 GetMRMaxTransProbability(theta_i, Energy)) > 1) {
817 G4cout <<
"MRMaxTrans Wahrscheinlichkeitsueberschreitung!" <<
G4endl;
818 G4cout << aMaterialPropertiesTable2->
819 GetMRTransProbability(theta_i, Energy, FermiPot, theta_o, phi_o)/
820 (1.5*aMaterialPropertiesTable2->
821 GetMRMaxTransProbability(theta_i, Energy)) <<
G4endl;
822 aMaterialPropertiesTable2->
823 SetMRMaxTransProbability(theta_i, Energy,
824 aMaterialPropertiesTable2->
825 GetMRTransProbability(theta_i, Energy,
826 FermiPot, theta_o, phi_o));
829 if(++count > 10000) { accepted =
true; }
840 GetCoordinateTransformMatrix(Normal, OldMomentum);
846 if (momentum*Normal<0) {
849 G4cout <<
"G4UCNBoundaryProcess::MRDiffTrans: !" <<
G4endl;
852 return momentum.
unit();
857 return (Energy - FermiPot);
869 if (momentum*Normal < 0) {
871 G4cout <<
"G4UCNBoundaryProcess::LDiffRefl: !" <<
G4endl;
874 return momentum.
unit();
899 es2.
rotate(90.*degree, es3);
909void G4UCNBoundaryProcess::BoundaryProcessVerbose()
const
919 if ( theStatus ==
NoMPT )
920 G4cout <<
" *** No G4UCNMaterialPropertiesTable *** " <<
G4endl;
921 if ( theStatus ==
NoMRT )
922 G4cout <<
" *** No MicroRoughness Table *** " <<
G4endl;
924 G4cout <<
" *** MicroRoughness Condition not satisfied *** " <<
G4endl;
927 if ( theStatus ==
Ezero )
929 if ( theStatus ==
Flip )
936 G4cout <<
" *** MR Model Diffuse Reflection *** " <<
G4endl;
940 G4cout <<
" *** MR Model Diffuse Transmission *** " <<
G4endl;
949 G4cout <<
"Sum NoMRCondition: "
950 << nNoMRCondition <<
G4endl;
951 G4cout <<
"Sum No. E < V Loss: "
953 G4cout <<
"Sum No. E > V Ezero: "
955 G4cout <<
"Sum No. E < V SpinFlip: "
957 G4cout <<
"Sum No. E > V Specular Reflection: "
958 << aSpecularReflection <<
G4endl;
959 G4cout <<
"Sum No. E < V Specular Reflection: "
960 << bSpecularReflection <<
G4endl;
961 G4cout <<
"Sum No. E < V Lambertian Reflection: "
962 << bLambertianReflection <<
G4endl;
963 G4cout <<
"Sum No. E > V MR DiffuseReflection: "
964 << aMRDiffuseReflection <<
G4endl;
965 G4cout <<
"Sum No. E < V MR DiffuseReflection: "
966 << bMRDiffuseReflection <<
G4endl;
967 G4cout <<
"Sum No. E > V SnellTransmit: "
968 << nSnellTransmit <<
G4endl;
969 G4cout <<
"Sum No. E > V MR SnellTransmit: "
970 << mSnellTransmit <<
G4endl;
971 G4cout <<
"Sum No. E > V DiffuseTransmit: "
972 << aMRDiffuseTransmit <<
G4endl;
976G4bool G4UCNBoundaryProcess::InvokeSD(
const G4Step* pStep)
983 if (sd)
return sd->
Hit(&aStep);
G4double condition(const G4ErrorSymMatrix &m)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4GLOB_DLL std::ostream G4cout
void setRThetaPhi(double r, double theta, double phi)
double angle(const Hep3Vector &) const
Hep3Vector perpPart() const
Hep3Vector & rotateUz(const Hep3Vector &)
Hep3Vector & rotate(double, const Hep3Vector &)
double polarAngle(const Hep3Vector &v2) const
const G4ThreeVector & GetMomentumDirection() const
const G4ThreeVector & GetPolarization() const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4double GetConstProperty(const G4String &key) const
static const G4Step * GetHyperStep()
static G4int GetHypNavigatorID()
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
G4double GetEnergy() const
void Initialize(const G4Track &) override
void ProposeVelocity(G4double finalVelocity)
void ProposeEnergy(G4double finalEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4Material * GetMaterial() const
const G4ThreeVector & GetPosition() const
G4VSensitiveDetector * GetSensitiveDetector() const
G4VPhysicalVolume * GetPhysicalVolume() const
G4Track * GetTrack() const
void AddTotalEnergyDeposit(G4double value)
G4StepPoint * GetPreStepPoint() const
G4StepPoint * GetPostStepPoint() const
G4double GetVelocity() const
G4ThreeVector GetMomentum() const
const G4DynamicParticle * GetDynamicParticle() const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
G4double GetStepLength() const
static G4TransportationManager * GetTransportationManager()
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *condition)
void BoundaryProcessSummary() const
virtual ~G4UCNBoundaryProcess()
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
G4ThreeVector MRreflectHigh(G4double, G4double, G4double, G4ThreeVector, G4ThreeVector, G4double, G4double, G4double &)
G4UCNBoundaryProcess(const G4String &processName="UCNBoundaryProcess", G4ProcessType type=fUCN)
G4ThreeVector MRreflect(G4double, G4ThreeVector, G4ThreeVector, G4double, G4double)
G4double * GetMicroRoughnessTable()
G4double GetCorrLen() const
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
const G4String & GetName() const
G4ParticleChange aParticleChange
void SetProcessSubType(G4int)
const G4String & GetProcessName() const
G4bool Hit(G4Step *aStep)