Import Geant4 11.3.0 source tree

This commit is contained in:
Gabriele Cosmo
2024-12-06 11:11:40 +01:00
parent e58e650b32
commit 32390e802b
1984 changed files with 98713 additions and 83996 deletions
@@ -0,0 +1,171 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4DynamicParticleFluctuation
//
// Author: V. Ivanchenko
//
// Creation date: 23.08.2024
//
// -------------------------------------------------------------------
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
#include "G4DynamicParticleFluctuation.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "Randomize.hh"
#include "G4Poisson.hh"
#include "G4Material.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4DynamicParticle.hh"
#include "G4Log.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4DynamicParticleFluctuation::G4DynamicParticleFluctuation(const G4String& nam)
: G4UniversalFluctuation(nam)
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void G4DynamicParticleFluctuation::InitialiseLocal(const G4DynamicParticle* part)
{
particleMass = part->GetMass();
const G4double q = part->GetCharge()/CLHEP::eplus;
// Derived quantities
m_Inv_particleMass = 1.0 / particleMass;
m_massrate = CLHEP::electron_mass_c2 * m_Inv_particleMass;
chargeSquare = q*q;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DynamicParticleFluctuation::SampleFluctuations(
const G4MaterialCutsCouple* couple,
const G4DynamicParticle* dp,
const G4double tcut,
const G4double tmax,
const G4double length,
const G4double averageLoss)
{
// Calculate actual loss from the mean loss.
// The model used to get the fluctuations is essentially the same
// as in Glandz in Geant3 (Cern program library W5013, phys332).
// L. Urban et al. NIM A362, p.416 (1995) and Geant4 Physics Reference Manual
// shortcut for very small loss or from a step nearly equal to the range
// (out of validity of the model)
//
if (averageLoss < minLoss) { return averageLoss; }
meanLoss = averageLoss;
const G4double tkin = dp->GetKineticEnergy();
//G4cout<< "Emean= "<< meanLoss<< " tmax= "<< tmax<< " L= "<<length<<G4endl;
CLHEP::HepRandomEngine* rndmEngineF = G4Random::getTheEngine();
InitialiseLocal(dp);
const G4double gam = tkin * m_Inv_particleMass + 1.0;
const G4double gam2 = gam*gam;
const G4double beta = dp->GetBeta();
const G4double beta2 = beta*beta;
G4double loss(0.), siga(0.);
const G4Material* material = couple->GetMaterial();
// Gaussian regime
// for heavy particles only and conditions
// for Gauusian fluct. has been changed
//
if (particleMass > CLHEP::electron_mass_c2 &&
meanLoss >= minNumberInteractionsBohr*tcut && tmax <= 2.*tcut) {
siga = std::sqrt((tmax/beta2 - 0.5*tcut)*CLHEP::twopi_mc2_rcl2*
length*chargeSquare*material->GetElectronDensity());
const G4double sn = meanLoss/siga;
// thick target case
if (sn >= 2.0) {
const G4double twomeanLoss = meanLoss + meanLoss;
do {
loss = G4RandGauss::shoot(rndmEngineF, meanLoss, siga);
// Loop checking, 03-Aug-2015, Vladimir Ivanchenko
} while (0.0 > loss || twomeanLoss < loss);
// Gamma distribution
} else {
const G4double neff = sn*sn;
loss = meanLoss*G4RandGamma::shoot(rndmEngineF, neff, 1.0)/neff;
}
//G4cout << "Gauss: " << loss << G4endl;
return loss;
}
auto ioni = material->GetIonisation();
e0 = ioni->GetEnergy0fluct();
// very small step or low-density material
if(tcut <= e0) { return meanLoss; }
ipotFluct = ioni->GetMeanExcitationEnergy();
ipotLogFluct = ioni->GetLogMeanExcEnergy();
// width correction for small cuts
const G4double scaling = std::min(1.+0.5*CLHEP::keV/tcut, 1.50);
meanLoss /= scaling;
w2 = (tcut > ipotFluct) ?
G4Log(2.*CLHEP::electron_mass_c2*beta2*gam2) - beta2 : 0.0;
return SampleGlandz(rndmEngineF, material, tcut)*scaling;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4double G4DynamicParticleFluctuation::Dispersion(
const G4Material* material,
const G4DynamicParticle* dp,
const G4double tcut,
const G4double tmax,
const G4double length)
{
InitialiseLocal(dp);
const G4double beta = dp->GetBeta();
return (tmax/(beta*beta) - 0.5*tcut) * CLHEP::twopi_mc2_rcl2 * length
* material->GetElectronDensity() * chargeSquare;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
@@ -0,0 +1,358 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4DynamicParticleIonisation
//
// Author: Vladimir Ivanchenko
//
// Creation date: 17.08.2024
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4DynamicParticleIonisation.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4DynamicParticleFluctuation.hh"
#include "G4EmSecondaryParticleType.hh"
#include "G4Electron.hh"
#include "G4EmParameters.hh"
#include "G4EmProcessSubType.hh"
#include "G4LossTableManager.hh"
#include "G4MaterialCutsCouple.hh"
#include "G4ProductionCutsTable.hh"
#include "G4Material.hh"
#include "G4Step.hh"
#include "G4Track.hh"
#include "G4Log.hh"
namespace
{
constexpr G4double ekinLimit = 0.2*CLHEP::MeV;
const G4double twoln10 = 2*G4Log(10.0);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DynamicParticleIonisation::G4DynamicParticleIonisation()
: G4VContinuousDiscreteProcess("dynPartIoni")
{
SetVerboseLevel(1);
SetProcessSubType(fDynamicIonisation);
theElectron = G4Electron::Electron();
lManager = G4LossTableManager::Instance();
lManager->Register(this);
fUrban = new G4DynamicParticleFluctuation();
// define these flags only once
auto param = G4EmParameters::Instance();
fFluct = param->LossFluctuation();
fLinLimit = 5*param->LinearLossLimit();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DynamicParticleIonisation::~G4DynamicParticleIonisation()
{
lManager->DeRegister(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void
G4DynamicParticleIonisation::BuildPhysicsTable(const G4ParticleDefinition&)
{
auto theCoupleTable = G4ProductionCutsTable::GetProductionCutsTable();
fCuts = theCoupleTable->GetEnergyCutsVector(1);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4DynamicParticleIonisation::PreStepInitialisation(const G4Track& track)
{
fCouple = track.GetMaterialCutsCouple();
fMaterial = fCouple->GetMaterial();
auto dpart = track.GetDynamicParticle();
fEkinPreStep = dpart->GetKineticEnergy();
fMass = std::max(dpart->GetMass(), CLHEP::electron_mass_c2);
fCharge = dpart->GetCharge()/CLHEP::eplus;
fRatio = fMass/CLHEP::proton_mass_c2;
fLowestEkin = ekinLimit*fRatio;
G4double tau = fEkinPreStep/fMass;
G4double ratio = CLHEP::electron_mass_c2/fMass;
fTmax = 2.0*CLHEP::electron_mass_c2*tau*(tau + 2.) /
(1. + 2.0*(tau + 1.)*ratio + ratio*ratio);
fCut = (*fCuts)[fCouple->GetIndex()];
fCut = std::max(fCut, fMaterial->GetIonisation()->GetMeanExcitationEnergy());
fCut = std::min(fCut, fTmax);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DynamicParticleIonisation::AlongStepGetPhysicalInteractionLength(
const G4Track&, G4double, G4double, G4double&,
G4GPILSelection* selection)
{
*selection = CandidateForSelection;
// no step limit for the time being
return DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DynamicParticleIonisation::PostStepGetPhysicalInteractionLength(
const G4Track& track, G4double previousStepSize,
G4ForceCondition* condition)
{
*condition = NotForced;
G4double x = DBL_MAX;
G4double xsec = 0.0;
PreStepInitialisation(track);
if (fCharge != 0.0) {
xsec = ComputeCrossSection(fEkinPreStep);
}
if (xsec <= 0.0) {
theNumberOfInteractionLengthLeft = -1.0;
currentInteractionLength = DBL_MAX;
} else {
if (theNumberOfInteractionLengthLeft < 0.0) {
theNumberOfInteractionLengthLeft = -G4Log( G4UniformRand() );
theInitialNumberOfInteractionLength = theNumberOfInteractionLengthLeft;
} else if(currentInteractionLength < DBL_MAX) {
// subtract NumberOfInteractionLengthLeft using previous step
theNumberOfInteractionLengthLeft -=
previousStepSize/currentInteractionLength;
theNumberOfInteractionLengthLeft =
std::max(theNumberOfInteractionLengthLeft, 0.0);
}
currentInteractionLength = 1.0/xsec;
x = theNumberOfInteractionLengthLeft * currentInteractionLength;
}
#ifdef G4VERBOSE
if (verboseLevel>2) {
G4cout << "G4DynamicParticleIonisation::PostStepGetPhysicalInteractionLength ";
G4cout << " Process: " << GetProcessName()
<< " for unknown particle Mass(GeV)=" << fMass/CLHEP::GeV
<< " charge=" << fCharge
<< " Material " << fMaterial->GetName()
<< " Ekin(MeV)=" << fEkinPreStep/CLHEP::MeV
<< " MFP(cm)=" << currentInteractionLength/CLHEP::cm
<< " ProposedLength(cm)=" << x/CLHEP::cm <<G4endl;
}
#endif
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange*
G4DynamicParticleIonisation::AlongStepDoIt(const G4Track& track,
const G4Step& step)
{
fParticleChange.InitializeForAlongStep(track);
// no energy loss
if (fCharge == 0.0) { return &fParticleChange; }
// stop low-energy object
if (fEkinPreStep <= fLowestEkin) {
fParticleChange.SetProposedKineticEnergy(0.0);
fParticleChange.ProposeLocalEnergyDeposit(fEkinPreStep);
return &fParticleChange;
}
G4double length = step.GetStepLength();
G4double dedxPre = ComputeDEDX(fEkinPreStep);
G4double eloss = dedxPre*length;
G4double ekinPostStep = fEkinPreStep - eloss;
// correction for large step if it is not the last step
if (fEkinPreStep*fLinLimit < eloss && ekinPostStep > fLowestEkin) {
G4double dedxPost = ComputeDEDX(ekinPostStep);
eloss = (eloss + dedxPost*length)*0.5;
}
// do not sample fluctuations at the last step
if (fFluct && fEkinPreStep > eloss) {
eloss = fUrban->SampleFluctuations(fCouple, track.GetDynamicParticle(),
fCut, fTmax, length, eloss);
}
ekinPostStep = fEkinPreStep - eloss;
// stop low-energy object
if (ekinPostStep <= fLowestEkin) {
fParticleChange.SetProposedKineticEnergy(0.0);
fParticleChange.ProposeLocalEnergyDeposit(fEkinPreStep);
} else {
fParticleChange.SetProposedKineticEnergy(ekinPostStep);
fParticleChange.ProposeLocalEnergyDeposit(eloss);
}
return &fParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange*
G4DynamicParticleIonisation::PostStepDoIt(const G4Track& track, const G4Step&)
{
theNumberOfInteractionLengthLeft = -1.0;
fParticleChange.InitializeForPostStep(track);
auto dp = track.GetDynamicParticle();
G4double kinEnergy = dp->GetKineticEnergy();
const G4double totEnergy = kinEnergy + fMass;
const G4double beta2 = kinEnergy*(kinEnergy + 2.0*fMass)/(totEnergy*totEnergy);
G4double deltaKinEnergy, f;
CLHEP::HepRandomEngine* rndmEngineMod = G4Random::getTheEngine();
G4double rndm[2];
// sampling without nuclear size effect
do {
rndmEngineMod->flatArray(2, rndm);
deltaKinEnergy = fCut*fTmax/(fCut*(1.0 - rndm[0]) + fTmax*rndm[0]);
f = 1.0 - beta2*deltaKinEnergy/fTmax;
// Loop checking, 14-Aug-2024, Vladimir Ivanchenko
} while( rndm[1] > f);
G4double deltaMomentum =
std::sqrt(deltaKinEnergy * (deltaKinEnergy + 2.0*CLHEP::electron_mass_c2));
G4double cost = deltaKinEnergy * (totEnergy + CLHEP::electron_mass_c2) /
(deltaMomentum * dp->GetTotalMomentum());
cost = std::min(cost, 1.0);
const G4double sint = std::sqrt((1.0 - cost)*(1.0 + cost));
const G4double phi = CLHEP::twopi*rndmEngineMod->flat();
G4ThreeVector deltaDirection(sint*std::cos(phi), sint*std::sin(phi), cost);
deltaDirection.rotateUz(dp->GetMomentumDirection());
// create G4DynamicParticle object for delta ray
auto delta = new G4DynamicParticle(theElectron, deltaDirection, deltaKinEnergy);
auto t = new G4Track(delta, track.GetGlobalTime(), track.GetPosition());
t->SetTouchableHandle(track.GetTouchableHandle());
t->SetCreatorModelID(fSecID);
fParticleChange.AddSecondary(t);
// Change kinematics of primary particle
kinEnergy -= deltaKinEnergy;
G4ThreeVector finalP = dp->GetMomentum() - delta->GetMomentum();
finalP = finalP.unit();
fParticleChange.SetProposedKineticEnergy(kinEnergy);
fParticleChange.SetProposedMomentumDirection(finalP);
return &fParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DynamicParticleIonisation::ComputeDEDX(G4double ekin)
{
G4double tau = ekin/fMass;
G4double gam = tau + 1.0;
G4double bg2 = tau * (tau + 2.0);
G4double beta2 = bg2/(gam*gam);
G4double xc = fCut/fTmax;
G4double exc = fMaterial->GetIonisation()->GetMeanExcitationEnergy();
G4double exc2 = exc*exc;
// general Bethe-Bloch formula
G4double dedx = G4Log(2.0*CLHEP::electron_mass_c2*bg2*fCut/exc2) - (1.0 + xc)*beta2;
// density correction
G4double x = G4Log(bg2)/twoln10;
dedx -= fMaterial->GetIonisation()->DensityCorrection(x);
// now compute the total ionization loss per volume
dedx *= CLHEP::twopi_mc2_rcl2*fCharge*fCharge*fMaterial->GetElectronDensity()/beta2;
dedx = std::max(dedx, 0.0);
return dedx;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DynamicParticleIonisation::ComputeCrossSection(G4double ekin)
{
G4double cross = 0.0;
if (fCut < fTmax) {
G4double totEnergy = ekin + fMass;
G4double energy2 = totEnergy*totEnergy;
G4double beta2 = ekin*(ekin + 2.0*fMass)/energy2;
cross = (fTmax - fCut)/(fCut*fTmax*beta2) - G4Log(fTmax/fCut)/fTmax;
cross *= CLHEP::twopi_mc2_rcl2*fCharge*fCharge*fMaterial->GetElectronDensity();
}
return cross;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DynamicParticleIonisation::GetMeanFreePath(const G4Track& /* track */, G4double,
G4ForceCondition* condition)
{
// Note: this method is not used at run-time, so its implementation is simplified.
// It might be eventually refined later.
*condition = NotForced;
return DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DynamicParticleIonisation::GetContinuousStepLimit(const G4Track&, G4double,
G4double, G4double&)
{
return DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4DynamicParticleIonisation::ProcessDescription(std::ostream& out) const
{
out << "G4DynamicParticleIonisation: dynamic ionisation" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -0,0 +1,176 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4DynamicParticleMSC
//
// Author: Vladimir Ivanchenko
//
// Creation date: 17.08.2024
//
// -------------------------------------------------------------------
//
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#include "G4DynamicParticleMSC.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4EmProcessSubType.hh"
#include "G4LossTableManager.hh"
#include "G4Step.hh"
#include "G4Track.hh"
#include "G4Log.hh"
#include "G4Exp.hh"
namespace
{
constexpr G4double c_highland = 13.6*CLHEP::MeV;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DynamicParticleMSC::G4DynamicParticleMSC()
: G4VContinuousDiscreteProcess("dynPartMSC")
{
SetVerboseLevel(1);
SetProcessSubType(fDynamicMultipleScattering);
lManager = G4LossTableManager::Instance();
lManager->Register(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4DynamicParticleMSC::~G4DynamicParticleMSC()
{
lManager->DeRegister(this);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4DynamicParticleMSC::PreStepInitialisation(const G4Track& track)
{
fMaterial = track.GetMaterial();
fZeff = fMaterial->GetIonisation()->GetZeffective();
auto dpart = track.GetDynamicParticle();
fEkinPreStep = dpart->GetKineticEnergy();
fBeta = dpart->GetBeta();
fCharge = dpart->GetCharge()/CLHEP::eplus;
fMass = std::max(dpart->GetMass(), CLHEP::electron_mass_c2);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DynamicParticleMSC::AlongStepGetPhysicalInteractionLength(
const G4Track& track, G4double, G4double, G4double&,
G4GPILSelection* selection)
{
*selection = CandidateForSelection;
PreStepInitialisation(track);
// no step limit for the time being
return DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DynamicParticleMSC::PostStepGetPhysicalInteractionLength(
const G4Track&, G4double,
G4ForceCondition* condition)
{
*condition = NotForced;
return DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4VParticleChange* G4DynamicParticleMSC::AlongStepDoIt(const G4Track& track,
const G4Step& step)
{
fParticleChange.InitialiseMSC(track, step);
// no energy loss
if (fCharge == 0.0) { return &fParticleChange; }
G4double geomLength = step.GetStepLength();
G4double y = geomLength/fMaterial->GetRadlen();
G4double theta0 = c_highland*std::abs(fCharge)*std::sqrt(y)*
(1.0 + 0.038*G4Log(y*fCharge*fCharge/(fBeta*fBeta)))/fBeta;
if (theta0 < 0.001) { return &fParticleChange; }
G4double cost = 1.0;
G4double r = G4UniformRand();
if (theta0 < 1.0) {
G4double theta2 = theta0*theta0;
cost -= theta2*G4Log(1.0 + r*(G4Exp(2.0/theta2) - 1.0));
} else {
cost -= 2.0*r;
}
G4double phi = CLHEP::twopi*G4UniformRand();
G4double sint = std::sqrt((1.0 - cost)*(1.0 + cost));
fNewDir.set(sint*std::cos(phi), sint*std::sin(phi), cost);
fNewDir.rotateUz(step.GetPostStepPoint()->GetMomentumDirection());
fParticleChange.ProposeMomentumDirection(fNewDir);
fParticleChange.ProposeTrueStepLength(geomLength);
return &fParticleChange;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DynamicParticleMSC::GetMeanFreePath(const G4Track&, G4double,
G4ForceCondition* condition)
{
*condition = Forced;
return DBL_MAX;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4DynamicParticleMSC::GetContinuousStepLimit(const G4Track& track,
G4double previousStepSize,
G4double currentMinimalStep,
G4double& currentSafety)
{
G4GPILSelection selection = NotCandidateForSelection;
G4double x = AlongStepGetPhysicalInteractionLength(track, previousStepSize,
currentMinimalStep,
currentSafety, &selection);
return x;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4DynamicParticleMSC::ProcessDescription(std::ostream& out) const
{
out << "G4DynamicParticleMSC: no delta rays" << G4endl;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....