273 kineticEnergy = std::max(kineticEnergy, 10.*CLHEP::eV);
275 const G4double pt2 = kineticEnergy*(kineticEnergy + 2.0*electron_mass_c2);
276 const G4double beta2 = pt2/(pt2 + electron_mass_c2*electron_mass_c2);
283 if (fIsUseMottCorrection) {
284 fGSTable->GetMottCorrectionFactors(
G4Log(kineticEnergy), beta2, matindx, fMCtoScrA, fMCtoQ1, fMCtoG2PerG1);
287 }
else if (fIsUsePWACorrection) {
288 fPWACorrection->GetPWACorrectionFactors(
G4Log(kineticEnergy), beta2, matindx, fMCtoScrA, fMCtoQ1, fMCtoG2PerG1);
296 const G4double bc = fGSTable->GetMoliereBc(matindx);
297 fScrA = fGSTable->GetMoliereXc2(matindx)/(4.0*pt2*bc)*fMCtoScrA;
301 fLambda0 = beta2*(1.+fScrA)*fMCtoScrA/(bc*scpCor);
304 fG1 = 2.0*fScrA*((1.0+fScrA)*
G4Log(1.0/fScrA+1.0)-1.0);
306 fLambda1 = fLambda0/fG1;
308 return fLambda1 > 0.0 ? 1.0/fLambda1 : 1.0E+20;
317 kineticEnergy = std::max(kineticEnergy, 10.0*CLHEP::eV);
319 const G4double pt2 = kineticEnergy*(kineticEnergy + 2.0*electron_mass_c2);
320 const G4double beta2 = pt2/(pt2 + electron_mass_c2*electron_mass_c2);
321 const G4int matindx =
static_cast<G4int>(currentCouple->GetMaterial()->GetIndex());
328 if (fIsUseMottCorrection) {
329 fGSTable->GetMottCorrectionFactors(
G4Log(kineticEnergy), beta2, matindx, fMCtoScrA, fMCtoQ1, fMCtoG2PerG1);
330 scpCor = fGSTable->ComputeScatteringPowerCorrection(currentCouple, kineticEnergy);
331 }
else if (fIsUsePWACorrection) {
332 fPWACorrection->GetPWACorrectionFactors(
G4Log(kineticEnergy), beta2, matindx, fMCtoScrA, fMCtoQ1, fMCtoG2PerG1);
340 const G4double bc = fGSTable->GetMoliereBc(matindx);
341 fScrA = fGSTable->GetMoliereXc2(matindx)/(4.0*pt2*bc)*fMCtoScrA;
345 fLambda0 = beta2*(1.+fScrA)*fMCtoScrA/(bc*scpCor);
348 fG1 = 2.0*fScrA*((1.0+fScrA)*
G4Log(1.0/fScrA+1.0)-1.0);
350 fLambda1 = fLambda0/fG1;
375 fPWACorrection->GetPWACorrectionFactors(
G4Log(kineticEnergy), beta2, matindx, mctoScrA, mctoQ1, mctoG2PerG1);
404 currentMaterialIndex = (
G4int)currentCouple->GetMaterial()->GetIndex();
406 currentRange =
GetRange(particle,currentKinEnergy,currentCouple,
414 fTheTrueStepLenght = currentMinimalStep;
415 fTheZPathLenght = currentMinimalStep;
416 fTheDisplacementVector.set(0.0, 0.0, 0.0);
417 fTheNewDirection.set(0.0, 0.0, 1.0);
420 fIsMultipleScattering =
false;
422 fIsSingleScattering =
false;
424 fIsNoScatteringInMSC =
false;
427 presafety =
ComputeSafety(sp->GetPosition(), fTheTrueStepLenght);
429 fIsSimplified =
false;
430 if (fIsUseOptimisation && currentRange < presafety ) {
433 fIsSimplified =
true;
446 if ((stepStatus ==
fGeomBoundary) || (presafety < skindepth) || (fTheTrueStepLenght < skindepth)) {
458 if (sslimit < fTheTrueStepLenght) {
459 fTheTrueStepLenght = sslimit;
460 fIsSingleScattering =
true;
463 fTheZPathLenght = fTheTrueStepLenght;
471 fIsMultipleScattering =
true;
473 fTheTrueStepLenght = std::min(fTheTrueStepLenght,
facrange*currentRange);
476 if (fTheTrueStepLenght > presafety) {
477 fTheTrueStepLenght = std::min(fTheTrueStepLenght, presafety);
483 fTheTrueStepLenght = std::min(fTheTrueStepLenght, fLambda1*0.5);
488 if (fIsMultipleScattering) {
495 }
else if (fIsSingleScattering) {
501 const G4double pt2 = currentKinEnergy*(currentKinEnergy+2.0*CLHEP::electron_mass_c2);
502 const G4double beta2 = pt2/(pt2+CLHEP::electron_mass_c2*CLHEP::electron_mass_c2);
503 G4double cost = fGSTable->SingleScattering(1.0, fScrA, lekin, beta2, currentMaterialIndex);
504 cost = std::max(-1.0, std::min(cost, 1.0));
507 const G4double sint = std::sqrt(dum*(2.0 - dum));
509 const G4double sinPhi = std::sin(phi);
510 const G4double cosPhi = std::cos(phi);
511 fTheNewDirection.set(sint*cosPhi, sint*sinPhi, cost);
557 if (!fIsEndedUpOnBoundary) {
559 if (fIsSimplified && !fIsNoScatteringInMSC) {
560 fTheNewDirection.rotateUz(oldDirection);
561 fParticleChange->ProposeMomentumDirection(fTheNewDirection);
562 return fTheDisplacementVector;
565 if (fIsSingleScattering) {
566 fTheNewDirection.rotateUz(oldDirection);
567 fParticleChange->ProposeMomentumDirection(fTheNewDirection);
568 return fTheDisplacementVector;
571 if (fIsMultipleScattering && !fIsNoScatteringInMSC) {
572 fTheNewDirection.rotateUz(oldDirection);
573 fTheDisplacementVector.rotateUz(oldDirection);
574 fParticleChange->ProposeMomentumDirection(fTheNewDirection);
578 return fTheDisplacementVector;
582 fIsNoScatteringInMSC =
false;
588 const G4double eloss = currentKinEnergy -
GetEnergy(particle, currentRange - fTheTrueStepLenght, currentCouple);
589 const G4double midEkin = currentKinEnergy - 0.5*eloss;
590 const G4double tau = midEkin/electron_mass_c2;
592 const G4double eps0 = eloss/currentKinEnergy;
593 const G4double epsm = eloss/midEkin;
595 const G4double effEner = midEkin*(1.0 - epsm2*(6.0 + 10.0*tau + 5.0*tau2)/(24.0*tau2 + 72.0*tau + 48.0));
596 const G4double dum = 1.0/((tau + 1.0)*(tau + 2.0));
597 const G4double effStep = fTheTrueStepLenght*(1.0 - 0.166666*epsm2*dum*dum*(4.0 + tau*(6.0 + tau*(7.0 + tau*(4.0 + tau)))));
603 const G4double lambdan = fLambda0 > 0.0 ? effStep/fLambda0 : 0.0;
605 if (lambdan <= 1.0E-12) {
606 fTheZPathLenght = fTheTrueStepLenght;
607 fIsNoScatteringInMSC =
true;
624 G4double cosTheta1 = 1.0, sinTheta1 = 0.0, cosTheta2 = 1.0, sinTheta2 = 0.0;
629 const G4double pt2 = effEner*(effEner + 2.0*CLHEP::electron_mass_c2);
630 const G4double beta2 = pt2/(pt2 + CLHEP::electron_mass_c2*CLHEP::electron_mass_c2);
634 G4int mcEkinIdx = -1;
635 G4int mcDeltIdx = -1;
637 G4bool isMsc = fGSTable->Sampling(0.5*lambdan, 0.5*Qn1, fScrA, cosTheta1, sinTheta1, lekin, beta2,
638 currentMaterialIndex, &gsDtr, mcEkinIdx, mcDeltIdx, transfPar,
640 fGSTable->Sampling(0.5*lambdan, 0.5*Qn1, fScrA, cosTheta2, sinTheta2, lekin, beta2,
641 currentMaterialIndex, &gsDtr, mcEkinIdx, mcDeltIdx, transfPar, !isMsc);
642 if (cosTheta1 + cosTheta2 == 2.0) {
643 fTheZPathLenght = fTheTrueStepLenght;
644 fIsNoScatteringInMSC =
true;
650 sinTheta1 = std::sqrt((1.-cosTheta1)*(1.+cosTheta1));
652 sinTheta2 = std::sqrt((1.-cosTheta2)*(1.+cosTheta2));
656 const G4double sinPhi1 = std::sin(phi1);
657 const G4double cosPhi1 = std::cos(phi1);
659 const G4double sinPhi2 = std::sin(phi2);
660 const G4double cosPhi2 = std::cos(phi2);
662 const G4double u2 = sinTheta2*cosPhi2;
663 const G4double v2 = sinTheta2*sinPhi2;
664 const G4double tm = cosTheta1*u2 + sinTheta1*cosTheta2;
665 const G4double uf = tm*cosPhi1 - v2*sinPhi1;
666 const G4double vf = tm*sinPhi1 + v2*cosPhi1;
667 const G4double wf = cosTheta1*cosTheta2 - sinTheta1*u2;
669 fTheNewDirection.set(uf, vf, wf);
687 const G4double lgf1 = loga*(1.0 + fScrA) - 1.0;
688 const G4double lgf2 = loga*(1.0 + 2.0*fScrA) - 2.0;
690 const G4double alpha1 = ((2.0 + tau*tp2)/tp1 - tp1/lgf1)*epsm/tp2;
692 const G4double alpha2 = 0.4082483*(eps0*tp1/(tp2*lgf1*lgf2) - 0.25*alpha1*alpha1);
694 const G4double gamma = (6.0*fScrA*lgf2*(1.0 + fScrA)/fG1)*fMCtoG2PerG1;
696 const G4double delta = 0.9082483 - (0.1020621 - 0.0263747*gamma)*Qn1 +
alpha2;
701 const G4double eta0 = 0.5*(1 - eta)*(1.0 + alpha1);
703 const G4double eta2 = eta*(1.0 - delta);
707 const G4double a1 = 0.5*(1 - eta)*(1.0 - alpha1);
709 const G4double dum1 = eta1*sinTheta1;
710 const G4double xf = dum1*cosPhi1 + eta2*(cosPhi1*u2 - sinPhi1*w1v2) + a1*uf;
711 const G4double yf = dum1*sinPhi1 + eta2*(sinPhi1*u2 + cosPhi1*w1v2) + a1*vf;
712 const G4double zf = eta0 + eta1*cosTheta1 + eta2*cosTheta2 + a1*wf;
715 const G4double rx = xf*fTheTrueStepLenght;
716 const G4double ry = yf*fTheTrueStepLenght;
717 const G4double rz = zf*fTheTrueStepLenght;
719 const G4double transportDistance = std::min(std::sqrt(rx*rx + ry*ry + rz*rz), fTheTrueStepLenght);
723 fTheZPathLenght = transportDistance;
724 fTheDisplacementVector.set(rx, ry, rz - fTheZPathLenght);
G4double GetLogKineticEnergy() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const