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;
225 WorkFunctionTable::iterator postStepWF;
227 WorkFunctionTable::iterator preStepWF;
230 if (postStepWF == tableWF.end()) {
237 else if (preStepWF == tableWF.end()) {
246 flag_franchissement_surface =
false;
248 if (flag_reflexion ==
true && flag_normal ==
true) {
250 flag_reflexion =
false;
257 flag_normal = (theGlobalNormal.
x() == 0.0 && theGlobalNormal.
y() == 0.0);
262 (pPreStepPoint ->GetPhysicalVolume(),
265 if (Surface ==
nullptr)
277 if(Surface ==
nullptr)
288 if(Surface ==
nullptr)
300 WorkFunctionTable::iterator postStepWF;
302 WorkFunctionTable::iterator preStepWF;
305 if (postStepWF == tableWF.end()) {
311 else if (preStepWF == tableWF.end()) {
319 G4double thresholdNew = postStepWF->second;
320 G4double thresholdOld = preStepWF->second;
321 energyThreshold = thresholdNew - thresholdOld;
326 thetat= GetIncidentAngle();
327 G4double ekinNormalt=ekint*std::cos(thetat)*std::cos(thetat);
329 G4double atet = std::sqrt(ekint/(ekint+energyThreshold))*std::sin(thetat);
330 thetaft = (atet > 1.0) ? pi*0.5 : std::asin(atet);
334 const G4double waveVectort=std::sqrt(2*9.1093826E-31*1.602176487E-19)/(6.6260755E-34/(2.0*pi));
340 crossingProbability=0;
342 G4double kft=waveVectort*std::sqrt(ekint+energyThreshold)*std::cos(thetaft);
343 G4double kit=waveVectort*std::sqrt(ekinNormalt);
345 G4double yy = std::sinh(pi*at*(kit-kft))/std::sinh(pi*at*(kit+kft));
346 crossingProbability = 1 - yy*yy;
349 if((aleat<=crossingProbability)&&(ekint>std::abs(energyThreshold)))
352 flag_franchissement_surface =
true;
355 thetaft=std::abs(thetaft-thetat);
362 G4double xDirt = std::sqrt(1. - cost*cost);
365 G4ThreeVector zPrimeVerst = xDirt*xVerst + yDirt*yVerst + cost*zVerst;
369 else if ((aleat > crossingProbability) && (ekint>std::abs(energyThreshold)))
371 flag_reflexion =
true;
380 flag_reflexion =
true;
397G4double G4MicroElecSurface::GetIncidentAngle()
399 theFacetNormal=theGlobalNormal;
401 G4double PdotN = oldMomentum * theFacetNormal;
403 G4double magN= theFacetNormal.mag();
405 G4double incidentangle = pi - std::acos(PdotN/(magP*magN));
407 return incidentangle;
430 d = -(Nx*PSx + Ny*PSy + Nz*PSz);
432 if (Ny == 0 && Nx == 0) {
438 A = (Nz*Nz*
alpha) + (Nx*Nx*PSx) + (Nx*Nz*(PSz - gamma));
444 z = (x -
alpha)*(Nz / Nx) + gamma;
450 B = (beta / Ny)*(Nx*Nx + Nz*Nz) - (Nx*
alpha + Nz*gamma + d);
454 x = (y - beta)*(Nx / Ny) +
alpha;
455 z = (y - beta)*(Nz / Ny) + gamma;
459 PM2x = 2 * (x -
alpha); PM2y = 2 * (y - beta); PM2z = 2 * (z - gamma);
462 alpha += PM2x; beta += PM2y; gamma += PM2z;
467 return newMomentum.
unit();
482 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 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 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