89 aMaterialPropertiesTable1 = NULL;
90 aMaterialPropertiesTable2 = NULL;
92 UseMicroRoughnessReflection =
false;
93 DoMicroRoughnessReflection =
false;
95 nNoMPT = nNoMRT = nNoMRCondition = 0;
96 nAbsorption = nEzero = nFlip = 0;
97 aSpecularReflection = bSpecularReflection = 0;
98 bLambertianReflection = 0;
99 aMRDiffuseReflection = bMRDiffuseReflection = 0;
100 nSnellTransmit = mSnellTransmit = 0;
101 aMRDiffuseTransmit = 0;
102 ftheta_o = fphi_o = 0;
120 const G4Step* pStep = &aStep;
124 if (hStep) pStep = hStep;
145 GetMaterialPropertiesTable();
147 GetMaterialPropertiesTable();
154 G4cout <<
" vol1: " << volnam1 <<
", vol2: " << volnam2 <<
G4endl;
159 if (Material1 == Material2) {
174 std::vector<G4Navigator*>::iterator iNav =
176 GetActiveNavigatorsIterator();
179 (iNav[hNavId])->GetGlobalExitNormal(theGlobalPoint,&valid);
182 theGlobalNormal = -theGlobalNormal;
187 ed <<
" G4UCNBoundaryProcess/PostStepDoIt(): "
188 <<
" The Navigator reports that it returned an invalid normal"
190 G4Exception(
"G4UCNBoundaryProcess::PostStepDoIt",
"UCNBoun01",
192 "Invalid Surface Normal - Geometry must return valid surface normal");
199 if (OldMomentum * theGlobalNormal > 0.0) {
200 #ifdef G4OPTICAL_DEBUG
202 ed <<
" G4UCNBoundaryProcess/PostStepDoIt(): "
203 <<
" theGlobalNormal points in a wrong direction. "
205 ed <<
" The momentum of the photon arriving at interface (oldMomentum)"
206 <<
" must exit the volume cross in the step. " <<
G4endl;
207 ed <<
" So it MUST have dot < 0 with the normal that Exits the new volume (globalNormal)." <<
G4endl;
208 ed <<
" >> The dot product of oldMomentum and global Normal is " << OldMomentum*theGlobalNormal <<
G4endl;
209 ed <<
" Old Momentum (during step) = " << OldMomentum <<
G4endl;
210 ed <<
" Global Normal (Exiting New Vol) = " << theGlobalNormal <<
G4endl;
212 G4Exception(
"G4UCNBoundaryProcess::PostStepDoIt",
"UCNBoun02",
215 "Invalid Surface Normal - Geometry must return valid surface normal pointing in the right direction");
217 theGlobalNormal = -theGlobalNormal;
223 G4double theMomentumNormal = theNeutronMomentum*theGlobalNormal;
225 (OldMomentum * theGlobalNormal);
235 if (aMaterialPropertiesTable2) {
243 if (aMaterialPropertiesTable1)
246 G4double FermiPotDiff = FermiPot2 - FermiPot1;
249 G4cout <<
"UCNBoundaryProcess: new FermiPot: " << FermiPot2/neV
250 <<
"neV, old FermiPot:" << FermiPot1/neV <<
"neV" <<
G4endl;
254 DoMicroRoughnessReflection = UseMicroRoughnessReflection;
258 if (!aMaterialPropertiesTable2) {
263 DoMicroRoughnessReflection =
false;
273 DoMicroRoughnessReflection =
false;
279 theta_i = OldMomentum.
angle(-theGlobalNormal);
283 if (!aMaterialPropertiesTable2->
284 ConditionsValid(Energy, FermiPotDiff, theta_i)) {
290 DoMicroRoughnessReflection =
false;
299 if (DoMicroRoughnessReflection) {
303 MRpDiffuse = aMaterialPropertiesTable2->
304 GetMRIntProbability(theta_i, Energy);
308 MRpDiffuseTrans = aMaterialPropertiesTable2->
309 GetMRIntTransProbability(theta_i, Energy);
313 G4cout <<
"Energy: " << Energy/neV <<
"neV"
314 <<
", Enormal: " << Enormal/neV <<
"neV" <<
G4endl;
315 G4cout <<
"FermiPotDiff: " << FermiPotDiff/neV <<
"neV " <<
G4endl;
316 G4cout <<
"Reflection_prob: " << MRpDiffuse
317 <<
", Transmission_prob: " << MRpDiffuseTrans <<
G4endl;
321 if (!High(Enormal, FermiPotDiff)) {
329 if (Loss(pUpScatter, theVelocityNormal, FermiPotDiff)) {
344 if (SpinFlip(pSpinFlip)) {
359 if (DoMicroRoughnessReflection)
360 NewMomentum =
MRreflect(MRpDiffuse, OldMomentum, theGlobalNormal,
361 Energy, FermiPotDiff);
366 NewMomentum = Reflect(pDiffuse, OldMomentum, theGlobalNormal);
384 if (DoMicroRoughnessReflection) {
390 theGlobalNormal, Energy, FermiPotDiff, Enew);
405 G4double reflectivity = Reflectivity(FermiPotDiff, Enormal);
408 << reflectivity <<
G4endl;
414 NewMomentum = Reflect(pDiffuse, OldMomentum, theGlobalNormal);
421 G4double Enew = Transmit(FermiPotDiff, Energy);
426 G4double mass = -std::sqrt(theMomentumNormal*theMomentumNormal -
432 theNeutronMomentum - (theMomentumNormal-mass)*theGlobalNormal;
444 G4cout <<
"Energy: " << Energy/neV <<
"neV, Enormal: "
445 << Enormal/neV <<
"neV, fpdiff " << FermiPotDiff/neV
446 <<
"neV, Enew " << Enew/neV <<
"neV" <<
G4endl;
447 G4cout <<
"UCNBoundaryProcess: Transmit and set the new Energy "
477 G4double vRatio = theVelocityNormal/vBound;
479 G4double pLoss = (2*pUpScatter*vRatio)/(std::sqrt(1-(vRatio*vRatio)));
483 if (DoMicroRoughnessReflection) {
484 if (aMaterialPropertiesTable2) {
491 pLoss *= std::sqrt(1+2*b*b*vBound*vBound/
492 (hdm*hdm+0.85*hdm*vBound*w+2*vBound*vBound*w*w));
506 G4double r = (std::sqrt(Enormal) - std::sqrt(Enormal - FermiPot)) /
507 (std::sqrt(Enormal) + std::sqrt(Enormal - FermiPot));
516 G4double PdotN = OldMomentum * Normal;
523 if (NewMomentum == OldMomentum ||
G4UniformRand() < pDiffuse) {
525 NewMomentum = LDiffRefl(Normal);
527 bLambertianReflection++;
536 bSpecularReflection++;
562 MRDiffRefl(Normal, Energy, FermiPot, OldMomentum, pDiffuse);
564 bMRDiffuseReflection++;
574 G4double PdotN = OldMomentum * Normal;
576 NewMomentum = OldMomentum - (2.*PdotN)*Normal;
579 bSpecularReflection++;
598 G4double costheta = OldMomentum*Normal;
600 G4double Enormal = Energy * (costheta*costheta);
603 G4double pSpecular = Reflectivity(FermiPot,Enormal)*
604 (1.-pDiffuse-pDiffuseTrans-pLoss);
610 if (decide < pSpecular) {
614 G4double PdotN = OldMomentum * Normal;
615 NewMomentum = OldMomentum - (2.*PdotN)*Normal;
620 aSpecularReflection++;
627 if (decide < pSpecular + pDiffuse) {
634 MRDiffRefl(Normal, Energy, FermiPot, OldMomentum, pDiffuse);
637 <<
", " << NewMomentum <<
G4endl;
640 aMRDiffuseReflection++;
647 if (decide < pSpecular + pDiffuse + pDiffuseTrans) {
654 MRDiffTrans(Normal, Energy, FermiPot, OldMomentum, pDiffuseTrans);
656 Enew = Energy - FermiPot;
658 aMRDiffuseTransmit++;
665 if (decide < pSpecular + pDiffuse + pDiffuseTrans + pLoss) {
680 Enew = Energy - FermiPot;
683 G4double produ = OldMomentum * Normal;
685 NewMomentum = palt*OldMomentum-
693 return NewMomentum.
unit();
722 aMaterialPropertiesTable2->
723 GetMRMaxProbability(theta_i, Energy)/pDiffuse <=
724 aMaterialPropertiesTable2->
725 GetMRProbability(theta_i,Energy,FermiPot,theta_o,phi_o)/pDiffuse)
731 if (aMaterialPropertiesTable2->
732 GetMRProbability(theta_i, Energy, FermiPot, theta_o, phi_o)/
733 (1.5*aMaterialPropertiesTable2->
734 GetMRMaxProbability(theta_i, Energy)) > 1) {
735 G4cout <<
"MRMax Wahrscheinlichkeitsueberschreitung!" <<
G4endl;
736 G4cout << aMaterialPropertiesTable2->
737 GetMRProbability(theta_i, Energy, FermiPot, theta_o, phi_o)/
738 (1.5*aMaterialPropertiesTable2->
739 GetMRMaxProbability(theta_i, Energy)) << G4endl;
740 aMaterialPropertiesTable2->
741 SetMRMaxProbability(theta_i, Energy,
742 aMaterialPropertiesTable2->
743 GetMRProbability(theta_i, Energy,
744 FermiPot, theta_o, phi_o));
747 if(++count > 10000) { accepted =
true; }
761 GetCoordinateTransformMatrix(Normal, OldMomentum);
769 if (momentum * Normal<0) {
772 G4cout <<
"G4UCNBoundaryProcess::MRDiffRefl: !" <<
G4endl;
775 return momentum.
unit();
804 aMaterialPropertiesTable2->
805 GetMRMaxTransProbability(theta_i, Energy)/pDiffuseTrans <=
806 aMaterialPropertiesTable2->
807 GetMRTransProbability(theta_i,Energy,FermiPot,theta_o,phi_o)/
814 if(aMaterialPropertiesTable2->
815 GetMRTransProbability(theta_i, Energy, FermiPot, theta_o, phi_o)/
816 (1.5*aMaterialPropertiesTable2->
817 GetMRMaxTransProbability(theta_i, Energy)) > 1) {
818 G4cout <<
"MRMaxTrans Wahrscheinlichkeitsueberschreitung!" <<
G4endl;
819 G4cout << aMaterialPropertiesTable2->
820 GetMRTransProbability(theta_i, Energy, FermiPot, theta_o, phi_o)/
821 (1.5*aMaterialPropertiesTable2->
822 GetMRMaxTransProbability(theta_i, Energy)) << G4endl;
823 aMaterialPropertiesTable2->
824 SetMRMaxTransProbability(theta_i, Energy,
825 aMaterialPropertiesTable2->
826 GetMRTransProbability(theta_i, Energy,
827 FermiPot, theta_o, phi_o));
830 if(++count > 10000) { accepted =
true; }
841 GetCoordinateTransformMatrix(Normal, OldMomentum);
847 if (momentum*Normal<0) {
850 G4cout <<
"G4UCNBoundaryProcess::MRDiffTrans: !" <<
G4endl;
853 return momentum.
unit();
858 return (Energy - FermiPot);
870 if (momentum*Normal < 0) {
872 G4cout <<
"G4UCNBoundaryProcess::LDiffRefl: !" <<
G4endl;
875 return momentum.
unit();
910 void G4UCNBoundaryProcess::BoundaryProcessVerbose()
const
920 if ( theStatus ==
NoMPT )
921 G4cout <<
" *** No G4UCNMaterialPropertiesTable *** " <<
G4endl;
922 if ( theStatus ==
NoMRT )
923 G4cout <<
" *** No MicroRoughness Table *** " <<
G4endl;
925 G4cout <<
" *** MicroRoughness Condition not satisfied *** " <<
G4endl;
928 if ( theStatus ==
Ezero )
930 if ( theStatus ==
Flip )
937 G4cout <<
" *** MR Model Diffuse Reflection *** " <<
G4endl;
941 G4cout <<
" *** MR Model Diffuse Transmission *** " <<
G4endl;
950 G4cout <<
"Sum NoMRCondition: "
951 << nNoMRCondition <<
G4endl;
952 G4cout <<
"Sum No. E < V Loss: "
954 G4cout <<
"Sum No. E > V Ezero: "
956 G4cout <<
"Sum No. E < V SpinFlip: "
958 G4cout <<
"Sum No. E > V Specular Reflection: "
959 << aSpecularReflection <<
G4endl;
960 G4cout <<
"Sum No. E < V Specular Reflection: "
961 << bSpecularReflection <<
G4endl;
962 G4cout <<
"Sum No. E < V Lambertian Reflection: "
963 << bLambertianReflection <<
G4endl;
964 G4cout <<
"Sum No. E > V MR DiffuseReflection: "
965 << aMRDiffuseReflection <<
G4endl;
966 G4cout <<
"Sum No. E < V MR DiffuseReflection: "
967 << bMRDiffuseReflection <<
G4endl;
968 G4cout <<
"Sum No. E > V SnellTransmit: "
969 << nSnellTransmit <<
G4endl;
970 G4cout <<
"Sum No. E > V MR SnellTransmit: "
971 << mSnellTransmit <<
G4endl;
972 G4cout <<
"Sum No. E > V DiffuseTransmit: "
973 << aMRDiffuseTransmit <<
G4endl;
977 G4bool G4UCNBoundaryProcess::InvokeSD(
const G4Step* pStep)
984 if (sd)
return sd->
Hit(&aStep);
G4double condition(const G4ErrorSymMatrix &m)
double angle(const Hep3Vector &) const
std::ostringstream G4ExceptionDescription
G4double GetVelocity() const
const G4DynamicParticle * GetDynamicParticle() const
G4StepStatus GetStepStatus() const
G4Material * GetMaterial() const
G4double GetSurfaceTolerance() const
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
G4StepPoint * GetPreStepPoint() const
static G4int GetHypNavigatorID()
G4double GetKineticEnergy() const
G4GLOB_DLL std::ostream G4cout
G4VPhysicalVolume * GetPhysicalVolume() const
G4UCNBoundaryProcess(const G4String &processName="UCNBoundaryProcess", G4ProcessType type=fUCN)
const G4String & GetName() const
static constexpr double degree
const G4ThreeVector & GetPosition() const
const G4ThreeVector & GetMomentumDirection() const
Hep3Vector & rotateUz(const Hep3Vector &)
static constexpr double neutron_mass_c2
static constexpr double eV
G4bool Hit(G4Step *aStep)
void SetProcessSubType(G4int)
Hep3Vector perpPart() const
const G4String & GetProcessName() const
void setRThetaPhi(double r, double theta, double phi)
void BoundaryProcessSummary() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
static constexpr double c_squared
static G4TransportationManager * GetTransportationManager()
G4double GetCorrLen() const
G4ThreeVector MRreflect(G4double, G4ThreeVector, G4ThreeVector, G4double, G4double)
G4ThreeVector GetMomentum() const
virtual void Initialize(const G4Track &)
const G4ThreeVector & GetMomentumDirection() const
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *condition)
G4ThreeVector MRreflectHigh(G4double, G4double, G4double, G4ThreeVector, G4ThreeVector, G4double, G4double, G4double &)
G4double * GetMicroRoughnessTable()
G4StepPoint * GetPostStepPoint() const
void AddTotalEnergyDeposit(G4double value)
static constexpr double c_light
const G4ThreeVector & GetPolarization() const
void ProposeEnergy(G4double finalEnergy)
G4ParticleChange aParticleChange
G4double GetEnergy() const
static constexpr double pi
G4VSensitiveDetector * GetSensitiveDetector() const
virtual ~G4UCNBoundaryProcess()
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
void ProposeTrackStatus(G4TrackStatus status)
G4Track * GetTrack() const
void ProposeVelocity(G4double finalVelocity)
static constexpr double hbar_Planck
Hep3Vector & rotate(double, const Hep3Vector &)
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
G4double GetStepLength() const
static G4GeometryTolerance * GetInstance()
static const G4Step * GetHyperStep()
G4double GetConstProperty(const char *key) const
double polarAngle(const Hep3Vector &v2) const