61 oldMomentum(0.,0.,0.), previousMomentum(0.,0.,0.),
62 theGlobalNormal(0.,0.,0.), theFacetNormal(0.,0.,0.)
77 theParticleMomentum = 0.;
79 flag_franchissement_surface =
false;
81 flag_reflexion =
false;
82 teleportToDo = teleportDone =
false;
84 ekint = thetat = thetaft = energyThreshold = crossingProbability = 0.0;
104 if (isInitialised) {
return; }
111 for (
G4int i = 0; i < numOfCouples; ++i)
117 <<
" / " << numOfCouples <<
" : " << material->
GetName() <<
G4endl;
118 if (material->
GetName() ==
"Vacuum")
120 tableWF[material->
GetName()] = 0;
continue;
127 isInitialised =
true;
134 if (isInitialised) {
return; }
139 G4cout <<
"G4MicroElecSurface::Initialise: Ncouples= "
140 << numOfCouples <<
G4endl;
142 for (
G4int i = 0; i < numOfCouples; ++i)
147 G4cout <<
"G4Surface, Material " << i + 1 <<
" / "
149 if (material->
GetName() ==
"Vacuum")
151 tableWF[material->
GetName()] = 0;
158 isInitialised =
true;
176 material1 = pPreStepPoint -> GetMaterial();
177 material2 = pPostStepPoint -> GetMaterial();
184 previousMomentum = oldMomentum;
193 flag_franchissement_surface =
false;
194 flag_reflexion =
false;
200 if (material1 == material2)
212 G4cout <<
" Old Momentum Direction: " << oldMomentum <<
G4endl;
226 theGlobalNormal = -theGlobalNormal;
231 ed <<
" G4MicroElecSurface/PostStepDoIt(): "
232 <<
" The Navigator reports that it returned an invalid normal"
234 G4Exception(
"G4MuElecSurf::PostStepDoIt",
"OpBoun01",
236 "Invalid Surface Normal - Geometry must return valid surface normal");
240 if (oldMomentum * theGlobalNormal > 0.0)
242 theGlobalNormal = -theGlobalNormal;
247 if (flag_reflexion ==
true)
249 flag_reflexion =
false;
255 G4double energyThreshold_surface = 0.0*eV;
257 WorkFunctionTable::iterator postStepWF;
259 WorkFunctionTable::iterator preStepWF;
262 if (postStepWF == tableWF.end())
269 else if (preStepWF == tableWF.end())
278 G4double thresholdNew_surface = postStepWF->second;
279 G4double thresholdOld_surface = preStepWF->second;
280 energyThreshold_surface = thresholdNew_surface - thresholdOld_surface;
283 if (flag_franchissement_surface ==
true)
286 flag_franchissement_surface =
false;
288 if (flag_reflexion ==
true && flag_normal ==
true)
291 flag_reflexion =
false;
303 (pPreStepPoint ->GetPhysicalVolume(),
306 if (Surface ==
nullptr)
315 if(Surface ==
nullptr)
324 if(Surface ==
nullptr)
334 energyThreshold = 0.0*eV;
337 if ((thePrePV)&&(thePostPV))
339 WorkFunctionTable::iterator postStepWF;
341 WorkFunctionTable::iterator preStepWF;
344 if (postStepWF == tableWF.end())
351 else if (preStepWF == tableWF.end())
360 G4double thresholdNew = postStepWF->second;
361 G4double thresholdOld = preStepWF->second;
363 energyThreshold = thresholdNew - thresholdOld;
364 energyDelta = thresholdOld- thresholdNew;
369 thetat= GetIncidentAngle();
370 G4double ekinNormalt=ekint*std::cos(thetat)*std::cos(thetat);
372 thetaft=std::asin(std::sqrt(ekint/(ekint+energyThreshold))*std::sin(thetat));
373 if(std::sqrt(ekint/(ekint+energyThreshold))*std::sin(thetat)>1.0)
375 thetaft=std::asin(1.0);
380 G4double waveVectort=std::sqrt(2*9.1093826E-31*1.602176487E-19)/(6.6260755E-34/(2.0*pi));
385 crossingProbability=0;
387 G4double kft=waveVectort*std::sqrt(ekint+energyThreshold)*std::cos(thetaft);
388 G4double kit=waveVectort*std::sqrt(ekinNormalt);
390 crossingProbability=1-(std::pow(std::sinh(pi*at*(kit-kft)), 2.0)/std::pow(std::sinh(pi*at*(kit+kft)), 2.0));
393 if((aleat<=crossingProbability)&&(ekint> energyDelta))
399 flag_franchissement_surface =
true;
402 thetaft=std::abs(thetaft-thetat);
408 G4double xDirt = std::sqrt(1. - std::cos(thetaft)*std::cos(thetaft));
411 G4ThreeVector zPrimeVerst=((xDirt*xVerst + yDirt*yVerst + std::cos(thetaft)*zVerst));
415 else if ((aleat > crossingProbability) && (ekint> energyDelta))
417 flag_reflexion =
true;
437 flag_reflexion =
true;
453G4double G4MicroElecSurface::GetIncidentAngle()
455 theFacetNormal=theGlobalNormal;
457 G4double PdotN = oldMomentum * theFacetNormal;
459 G4double magN= theFacetNormal.mag();
461 G4double incidentangle = pi - std::acos(PdotN/(magP*magN));
463 return incidentangle;
486 d = -(Nx*PSx + Ny*PSy + Nz*PSz);
488 if (Ny == 0 && Nx == 0)
496 A = (Nz*Nz*
alpha) + (Nx*Nx*PSx) + (Nx*Nz*(PSz - gamma));
502 z = (x -
alpha)*(Nz / Nx) + gamma;
507 B = (beta / Ny)*(Nx*Nx + Nz*Nz) - (Nx*
alpha + Nz*gamma + d);
511 x = (y - beta)*(Nx / Ny) +
alpha;
512 z = (y - beta)*(Nz / Ny) + gamma;
516 PM2x = 2 * (x -
alpha); PM2y = 2 * (y - beta); PM2z = 2 * (z - gamma);
519 alpha += PM2x; beta += PM2y; gamma += PM2z;
524 return newMomentum.
unit();
539 flag_franchissement_surface =
false;
G4double B(G4double temperature)
G4double condition(const G4ErrorSymMatrix &m)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
Hep3Vector orthogonal() const
Hep3Vector cross(const Hep3Vector &) const
const G4ThreeVector & GetMomentumDirection() const
G4double GetTotalMomentum() const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
static G4LogicalBorderSurface * GetSurface(const G4VPhysicalVolume *vol1, const G4VPhysicalVolume *vol2)
static G4LogicalSkinSurface * GetSurface(const G4LogicalVolume *vol)
G4Material * GetMaterial() const
const G4Material * GetMaterial() const
const G4String & GetName() const
G4double GetWorkFunction()
G4MicroElecSurfaceStatus GetStatus() const
G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *condition) override
void SetFlagFranchissement()
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
~G4MicroElecSurface() override
void BuildPhysicsTable(const G4ParticleDefinition &) override
G4MicroElecSurface(const G4String &processName="MicroElecSurface", G4ProcessType type=fElectromagnetic)
G4bool IsApplicable(const G4ParticleDefinition &aParticleType) override
virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &point, G4bool *valid)
void Initialize(const G4Track &) override
void ProposeVelocity(G4double finalVelocity)
void ProposeEnergy(G4double finalEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4int GetPDGEncoding() const
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
static G4ProductionCutsTable * GetProductionCutsTable()
G4StepStatus GetStepStatus() const
G4Material * GetMaterial() const
const G4ThreeVector & GetPosition() const
const G4ThreeVector & GetMomentumDirection() const
G4VPhysicalVolume * GetPhysicalVolume() const
G4double GetKineticEnergy() const
G4StepPoint * GetPreStepPoint() const
G4StepPoint * GetPostStepPoint() const
G4double GetVelocity() const
const G4DynamicParticle * GetDynamicParticle() const
G4double GetStepLength() const
static G4TransportationManager * GetTransportationManager()
G4Navigator * GetNavigatorForTracking() const
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
G4ParticleChange aParticleChange
void SetProcessSubType(G4int)
const G4String & GetProcessName() const