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;
138 G4cout <<
"G4MicroElecSurface::Initialise: Ncouples= "
139 << numOfCouples <<
G4endl;
141 for (
G4int i = 0; i < numOfCouples; ++i)
146 G4cout <<
"G4Surface, Material " << i + 1 <<
" / "
148 if (material->
GetName() ==
"Vacuum")
150 tableWF[material->
GetName()] = 0;
157 isInitialised =
true;
175 material1 = pPreStepPoint -> GetMaterial();
176 material2 = pPostStepPoint -> GetMaterial();
183 previousMomentum = oldMomentum;
191 flag_franchissement_surface =
false;
192 flag_reflexion =
false;
198 if (material1 == material2)
210 G4cout <<
" Old Momentum Direction: " << oldMomentum <<
G4endl;
224 theGlobalNormal = -theGlobalNormal;
229 ed <<
" G4MicroElecSurface/PostStepDoIt(): "
230 <<
" The Navigator reports that it returned an invalid normal"
232 G4Exception(
"G4MuElecSurf::PostStepDoIt",
"OpBoun01",
234 "Invalid Surface Normal - Geometry must return valid surface normal");
238 if (oldMomentum * theGlobalNormal > 0.0)
240 theGlobalNormal = -theGlobalNormal;
245 if (flag_reflexion ==
true)
247 flag_reflexion =
false;
253 G4double energyThreshold_surface = 0.0*eV;
255 WorkFunctionTable::iterator postStepWF;
257 WorkFunctionTable::iterator preStepWF;
260 if (postStepWF == tableWF.end())
267 else if (preStepWF == tableWF.end())
276 G4double thresholdNew_surface = postStepWF->second;
277 G4double thresholdOld_surface = preStepWF->second;
278 energyThreshold_surface = thresholdNew_surface - thresholdOld_surface;
281 if (flag_franchissement_surface ==
true)
284 flag_franchissement_surface =
false;
286 if (flag_reflexion ==
true && flag_normal ==
true)
289 flag_reflexion =
false;
301 (pPreStepPoint ->GetPhysicalVolume(),
304 if (Surface ==
nullptr)
313 if(Surface ==
nullptr)
322 if(Surface ==
nullptr)
332 energyThreshold = 0.0*eV;
335 if ((thePrePV)&&(thePostPV))
337 WorkFunctionTable::iterator postStepWF;
339 WorkFunctionTable::iterator preStepWF;
342 if (postStepWF == tableWF.end())
349 else if (preStepWF == tableWF.end())
358 G4double thresholdNew = postStepWF->second;
359 G4double thresholdOld = preStepWF->second;
361 energyThreshold = thresholdNew - thresholdOld;
362 energyDelta = thresholdOld- thresholdNew;
367 thetat= GetIncidentAngle();
368 G4double ekinNormalt=ekint*std::cos(thetat)*std::cos(thetat);
369 G4double sin_thetaft = std::sqrt(ekint/(ekint+energyThreshold))*std::sin(thetat);
373 if (1.0-sin_thetaft*sin_thetaft>0) {
374 cos_thetaft = std::sqrt(1.0-sin_thetaft*sin_thetaft);
381 G4double waveVectort=std::sqrt(2*9.1093826E-31*1.602176487E-19)/(6.6260755E-34/(2.0*pi));
386 crossingProbability=0;
388 G4double kft=waveVectort*std::sqrt(ekint+energyThreshold)*cos_thetaft;
389 G4double kit=waveVectort*std::sqrt(ekinNormalt);
391 crossingProbability=1-(std::pow(std::sinh(pi*at*(kit-kft)), 2.0)/std::pow(std::sinh(pi*at*(kit+kft)), 2.0));
394 if((aleat<=crossingProbability)&&(ekint> energyDelta))
400 flag_franchissement_surface =
true;
404 cos_thetaft = cos_thetaft*std::cos(thetat)+sin_thetaft*std::sin(thetat);
410 G4double xDirt = std::sqrt(1. - cos_thetaft*cos_thetaft);
413 G4ThreeVector zPrimeVerst=((xDirt*xVerst + yDirt*yVerst + cos_thetaft*zVerst));
417 else if ((aleat > crossingProbability) && (ekint> energyDelta))
419 flag_reflexion =
true;
439 flag_reflexion =
true;
455G4double G4MicroElecSurface::GetIncidentAngle()
457 theFacetNormal=theGlobalNormal;
459 G4double PdotN = oldMomentum * theFacetNormal;
461 G4double magN= theFacetNormal.mag();
463 G4double incidentangle = pi - std::acos(PdotN/(magP*magN));
465 return incidentangle;
484 G4double beta = PSy + oldMomentum.y();
485 G4double gamma = PSz + oldMomentum.z();
488 d = -(Nx*PSx + Ny*PSy + Nz*PSz);
490 if (Ny == 0 && Nx == 0)
498 A = (Nz*Nz*
alpha) + (Nx*Nx*PSx) + (Nx*Nz*(PSz - gamma));
504 z = (x -
alpha)*(Nz / Nx) + gamma;
509 B = (beta / Ny)*(Nx*Nx + Nz*Nz) - (Nx*
alpha + Nz*gamma + d);
513 x = (y - beta)*(Nx / Ny) +
alpha;
514 z = (y - beta)*(Nz / Ny) + gamma;
518 PM2x = 2 * (x -
alpha); PM2y = 2 * (y - beta); PM2z = 2 * (z - gamma);
521 alpha += PM2x; beta += PM2y; gamma += PM2z;
526 return newMomentum.
unit();
541 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)
G4LogicalSurface is an abstraction of a geometrical surface, it is an abstract base class for differe...
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
G4Navigator is a class for use by the tracking management, able to obtain/calculate dynamic tracking ...
virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &point, G4bool *valid)
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 &)
G4VDiscreteProcess(const G4String &aName, G4ProcessType aType=fNotDefined)
G4VPhysicalVolume is an abstract base class for the representation of a positioned volume....
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
G4ParticleChange aParticleChange
void SetProcessSubType(G4int)
const G4String & GetProcessName() const