65 oldMomentum(0.,0.,0.), previousMomentum(0.,0.,0.),
66 theGlobalNormal(0.,0.,0.), theFacetNormal(0.,0.,0.)
81 theParticleMomentum = 0.;
83 flag_franchissement_surface =
false;
85 flag_reflexion =
false;
86 teleportToDo = teleportDone =
false;
88 ekint = thetat = thetaft = energyThreshold = crossingProbability = 0.0;
108 if (isInitialised) {
return; }
113 G4cout <<
"G4MicroElecSurface::Initialise: Ncouples= "
114 << numOfCouples <<
G4endl;
116 for (
G4int i = 0; i < numOfCouples; ++i) {
120 G4cout <<
"G4Surface, Material " << i + 1 <<
" / " << numOfCouples <<
" : " << material->
GetName() <<
G4endl;
121 if (material->
GetName() ==
"Vacuum") { tableWF[material->
GetName()] = 0;
continue; }
126 isInitialised =
true;
142 material1 = pPreStepPoint -> GetMaterial();
143 material2 = pPostStepPoint -> GetMaterial();
148 previousMomentum = oldMomentum;
156 flag_franchissement_surface =
false;
157 flag_reflexion =
false;
164 if (material1 == material2)
177 G4cout <<
" Old Momentum Direction: " << oldMomentum <<
G4endl;
185 GetNavigatorForTracking();
194 theGlobalNormal = -theGlobalNormal;
199 ed <<
" G4MicroElecSurface/PostStepDoIt(): "
200 <<
" The Navigator reports that it returned an invalid normal.\n"
204 <<
" position: " << theGlobalPoint
205 <<
" direction: " << oldMomentum
207 G4Exception(
"G4MuElecSurf::PostStepDoIt",
"OpBoun01",
209 "Invalid Surface Normal - Geometry must return valid surface normal");
214 if (oldMomentum * theGlobalNormal > 0.0)
216 theGlobalNormal = -theGlobalNormal;
224 if (pPostStepPoint) {
226 WorkFunctionTable::iterator postStepWF;
228 WorkFunctionTable::iterator preStepWF;
231 if (postStepWF == tableWF.end()) {
238 else if (preStepWF == tableWF.end()) {
247 flag_franchissement_surface =
false;
249 if (flag_reflexion ==
true && flag_normal ==
true) {
251 flag_reflexion =
false;
259 flag_normal = (theGlobalNormal.
x() == 0.0 && theGlobalNormal.
y() == 0.0);
264 (pPreStepPoint ->GetPhysicalVolume(),
267 if (Surface ==
nullptr)
279 if(Surface ==
nullptr)
290 if(Surface ==
nullptr)
303 WorkFunctionTable::iterator postStepWF;
305 WorkFunctionTable::iterator preStepWF;
308 if (postStepWF == tableWF.end()) {
315 else if (preStepWF == tableWF.end()) {
324 G4double thresholdNew = postStepWF->second;
325 G4double thresholdOld = preStepWF->second;
326 energyThreshold = thresholdNew - thresholdOld;
331 thetat= GetIncidentAngle();
332 G4double ekinNormalt=ekint*std::cos(thetat)*std::cos(thetat);
334 G4double atet = std::sqrt(ekint/(ekint+energyThreshold))*std::sin(thetat);
335 thetaft = (atet > 1.0) ? pi*0.5 : std::asin(atet);
339 const G4double waveVectort=std::sqrt(2*9.1093826E-31*1.602176487E-19)/(6.6260755E-34/(2.0*pi));
345 crossingProbability=0;
347 G4double kft=waveVectort*std::sqrt(ekint+energyThreshold)*std::cos(thetaft);
348 G4double kit=waveVectort*std::sqrt(ekinNormalt);
350 G4double yy = std::sinh(pi*at*(kit-kft))/std::sinh(pi*at*(kit+kft));
351 crossingProbability = 1 - yy*yy;
354 if((aleat<=crossingProbability)&&(ekint>std::abs(energyThreshold)))
357 flag_franchissement_surface =
true;
360 thetaft=std::abs(thetaft-thetat);
367 G4double xDirt = std::sqrt(1. - cost*cost);
370 G4ThreeVector zPrimeVerst = xDirt*xVerst + yDirt*yVerst + cost*zVerst;
374 else if ((aleat > crossingProbability) && (ekint>std::abs(energyThreshold)))
376 flag_reflexion =
true;
385 flag_reflexion =
true;
402G4double G4MicroElecSurface::GetIncidentAngle()
404 theFacetNormal=theGlobalNormal;
406 G4double PdotN = oldMomentum * theFacetNormal;
408 G4double magN= theFacetNormal.mag();
410 G4double incidentangle = pi - std::acos(PdotN/(magP*magN));
412 return incidentangle;
435 d = -(Nx*PSx + Ny*PSy + Nz*PSz);
437 if (Ny == 0 && Nx == 0) {
444 A = (Nz*Nz*
alpha) + (Nx*Nx*PSx) + (Nx*Nz*(PSz - gamma));
450 z = (x -
alpha)*(Nz / Nx) + gamma;
456 B = (beta / Ny)*(Nx*Nx + Nz*Nz) - (Nx*
alpha + Nz*gamma + d);
460 x = (y - beta)*(Nx / Ny) +
alpha;
461 z = (y - beta)*(Nz / Ny) + gamma;
465 PM2x = 2 * (x -
alpha); PM2y = 2 * (y - beta); PM2z = 2 * (z - gamma);
468 alpha += PM2x; beta += PM2y; gamma += PM2z;
474 return newMomentum.
unit();
489 flag_franchissement_surface =
false;
double B(double temperature)
double A(double 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 ProposeVelocity(G4double finalVelocity)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
virtual void Initialize(const G4Track &)
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 GetKineticEnergy() const
G4double GetStepLength() const
static G4TransportationManager * GetTransportationManager()
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
G4LogicalVolume * GetMotherLogical() const
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
G4ParticleChange aParticleChange
void SetProcessSubType(G4int)
const G4String & GetProcessName() const