58const std::vector<G4double>* G4DNARuddIonisationExtendedModel::fpWaterDensity =
nullptr;
63 const G4double scaleFactor = CLHEP::m*CLHEP::m;
64 const G4double tolerance = 1*CLHEP::eV;
66 const G4double Gj[5] = {0.99, 1.11, 1.11, 0.52, 1.};
69 const G4double Bj[5] = {12.60*CLHEP::eV, 14.70*CLHEP::eV, 18.40*CLHEP::eV,
70 32.20*CLHEP::eV, 539*CLHEP::eV};
81 fLowestEnergy = 100*CLHEP::eV;
82 fLimitEnergy = 1*CLHEP::keV;
96 for(
auto & i : xsdata) {
delete i; }
105 if(p != fParticle) { SetParticle(p); }
108 if(
nullptr == xsdata[0]) {
110 if(
nullptr == xsdata[0]) {
112 G4String filename(
"dna/sigma_ionisation_h_rudd");
116 filename =
"dna/sigma_ionisation_p_rudd";
120 filename =
"dna/sigma_ionisation_alphaplusplus_rudd";
124 filename =
"dna/sigma_ionisation_li_rudd";
128 filename =
"dna/sigma_ionisation_be_rudd";
132 filename =
"dna/sigma_ionisation_b_rudd";
136 filename =
"dna/sigma_ionisation_c_rudd";
140 filename =
"dna/sigma_ionisation_n_rudd";
144 filename =
"dna/sigma_ionisation_o_rudd";
148 filename =
"dna/sigma_ionisation_si_rudd";
152 filename =
"dna/sigma_ionisation_fe_rudd";
155 filename =
"dna/sigma_ionisation_alphaplus_rudd";
159 filename =
"dna/sigma_ionisation_he_rudd";
175 if(pname ==
"proton") {
177 xscurrent = xsdata[1];
178 fElow = fLowestEnergy;
179 }
else if(pname ==
"hydrogen") {
181 xscurrent = xsdata[0];
182 fElow = fLowestEnergy;
183 }
else if(pname ==
"alpha") {
185 xscurrent = xsdata[2];
187 fElow = fLimitEnergy;
188 }
else if(pname ==
"alpha+") {
191 xscurrent = xsalphaplus;
192 fElow = fLimitEnergy;
194 slaterEffectiveCharge[0]=2.0;
195 slaterEffectiveCharge[1]=2.0;
196 slaterEffectiveCharge[2]=2.0;
198 sCoefficient[1]=0.15;
199 sCoefficient[2]=0.15;
200 }
else if(pname ==
"helium") {
203 fElow = fLimitEnergy;
204 xscurrent = xshelium;
205 slaterEffectiveCharge[0]=1.7;
206 slaterEffectiveCharge[1]=1.15;
207 slaterEffectiveCharge[2]=1.15;
209 sCoefficient[1]=0.25;
210 sCoefficient[2]=0.25;
221 G4cout <<
"### G4DNARuddIonisationExtendedModel::Initialise(..) " << pname
222 <<
"/n idx=" << idx <<
" Amass=" << fAmass
223 <<
" isIon=" << isIon <<
" isHelium=" << isHelium <<
G4endl;
240 if (i < RUDDZMAX &&
nullptr != xsdata[i]) {
242 fElow = fAmass*fLowestEnergy;
257 ? (*fpWaterDensity)[material->
GetIndex()] : 0.0;
258 if (0.0 == density) {
return 0.0; }
261 if (fParticle != part) { SetParticle(part); }
267 if (kinE < fLowestEnergy) {
return DBL_MAX; }
273 if (idx == 0 || idx == 1) {
274 sigma = (kinE > fElow) ? xscurrent->
FindValue(kinE)
275 : xscurrent->
FindValue(fElow)*kinE/fElow;
278 }
else if (idx > 1) {
279 sigma = (kinE > fElow) ? xsdata[idx]->FindValue(kinE)
280 : xsdata[idx]->
FindValue(fElow)*kinE/fElow;
284 fMassRate = CLHEP::proton_mass_c2/fMass;
286 sigma = (e > fLowestEnergy) ? xsdata[1]->FindValue(e)
287 : xsdata[1]->
FindValue(fLowestEnergy)*e/fLowestEnergy;
294 <<
" Ekin(keV)=" << kinE/CLHEP::keV
295 <<
" sigma(cm^2)=" << sigma/CLHEP::cm2 <<
G4endl;
309 if (fParticle != pd) { SetParticle(pd); }
314 if (kinE <= fLowestEnergy) {
321 G4int shell = SelectShell(kinE);
322 G4double bindingEnergy = (useDNAWaterStructure)
326 if (kinE < bindingEnergy)
return;
328 G4double esec = SampleElectronEnergy(kinE, bindingEnergy, shell);
339 if(fAtomDeexcitation !=
nullptr && shell == 4) {
345 std::size_t nn = fvect->size();
346 for (std::size_t i=0; i<nn; ++i) {
347 esum += (*fvect)[i]->GetKineticEnergy();
352 G4double exc = bindingEnergy - esum;
355 G4double scatteredEnergy = kinE - bindingEnergy - esec;
356 if(scatteredEnergy < -tolerance || exc < -tolerance) {
357 G4cout <<
"G4DNARuddIonisationExtendedModel::SampleSecondaries: "
358 <<
"negative final E(keV)=" << scatteredEnergy/CLHEP::keV <<
" Ein(keV)="
360 <<
" Edelta(keV)=" << esec/CLHEP::keV <<
" MeV, Exc(keV)=" << exc/CLHEP::keV
375 fvect->push_back(dp);
385G4int G4DNARuddIonisationExtendedModel::SelectShell(
G4double e)
389 for(
G4int i=0; i<5; ++i) {
390 if (idx == 0 || idx == 1) {
392 xs = (e > fElow) ? ptr->
FindValue(e) : ptr->FindValue(fElow)*e/fElow;
394 }
else if (idx > 1) {
396 xs = (e > fElow) ? ptr->
FindValue(e) : ptr->FindValue(fElow)*e/fElow;
402 xs = (x >= fLowestEnergy) ? ptr->FindValue(x)
403 : ptr->FindValue(fLowestEnergy)*x/fLowestEnergy;
409 for(
G4int i=0; i<5; ++i) {
410 if(sum <= fTemp[i]) {
return i; }
417G4double G4DNARuddIonisationExtendedModel::SampleElectronEnergy(
G4double kine,
423 G4double emax = 2.0*CLHEP::electron_mass_c2*tau*(tau + 2.0);
427 nn = std::max(nn, 10);
431 G4double pmax = ProbabilityFunction(kine, 0.0, eexc, shell);
440 G4double prob = ProbabilityFunction(kine, e, eexc, shell);
454 e1 = e0 + 0.25*(emax - e0);
455 p1 = ProbabilityFunction(kine, e1, eexc, shell);
458 s2 /= (s2 + e1*pmax);
464 for (
G4int i = 0; i<100000; ++i) {
468 deltae = e1 * q / s1;
471 deltae = e1 + (emax - e1)* (q - s1) / s2;
473 y = ProbabilityFunction(kine, deltae, eexc, shell);
476 if (y > ymax && count < 10) {
478 G4cout <<
"G4DNARuddIonisationExtendedModel::SampleElectronEnergy warning: "
480 <<
" Edelta(keV)=" << deltae/CLHEP::keV
481 <<
" y=" << y <<
" ymax=" << ymax <<
" n=" << i <<
G4endl;
493G4double G4DNARuddIonisationExtendedModel::ProbabilityFunction(
G4double kine,
513 G4double A1, B1,
C1, D1, E1, A2, B2,
C2, D2, alphaConst;
546 G4double v2 = 0.5*CLHEP::electron_mass_c2*tau*(tau + 2.0)/(bEnergy*gam*gam);
548 G4double wc = 4.*v2 - 2.*v - 0.25*u;
556 G4double H2 = (A2 / v2) + (B2 / (v2 * v2));
559 G4double F2 = (L2 * H2) / (L2 + H2);
561 G4double res = CorrectionFactor(kine, shell) * (F1 + w*F2) * Gj[shell] /
562 (fGpow->
powN((1. + w)/u, 3) * y);
567 (sCoefficient[0] * S_1s(kine, energyTransfer, slaterEffectiveCharge[0], 1.) +
568 sCoefficient[1] * S_2s(kine, energyTransfer, slaterEffectiveCharge[1], 2.) +
569 sCoefficient[2] * S_2p(kine, energyTransfer, slaterEffectiveCharge[2], 2.) );
573 return std::max(res, 0.0);
581 if (fParticle != p) { SetParticle(p); }
582 G4double bEnergy = (useDNAWaterStructure)
584 return ProbabilityFunction(e, deltae, bEnergy, shell);
597 G4double r = Rh(kine, energyTransfer, slaterEffCharge, shellNumber);
598 G4double value = 1. -
G4Exp(-2 * r) * ( ( 2. * r + 2. ) * r + 1. );
612 G4double r = Rh(kine, energyTransfer, slaterEffCharge, shellNumber);
614 1. -
G4Exp(-2 * r) * (((2. * r * r + 2.) * r + 2.) * r + 1.);
629 G4double r = Rh(kine, energyTransfer, slaterEffCharge, shellNumber);
631 1. -
G4Exp(-2 * r) * (((( 2./3. * r + 4./3.) * r + 2.) * r + 2.) * r + 1.);
644 G4double escaled = CLHEP::electron_mass_c2/fMass * ekin;
645 const G4double H = 13.60569172 * CLHEP::eV;
646 G4double value = 2.0*std::sqrt(escaled / H)*q*H /(etrans*shell);
654G4DNARuddIonisationExtendedModel::CorrectionFactor(
G4double kine,
G4int shell)
658 if (shell < 4 && 0 != idx) {
662 res = 0.6/(1.0 +
G4Exp(x)) + 0.9;
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
#define G4MUTEX_INITIALIZER
G4GLOB_DLL std::ostream G4cout
static G4DNAChemistryManager * Instance()
void CreateWaterMolecule(ElectronicModification, G4int, const G4Track *)
G4bool LoadData(const G4String &argFileName) override
const G4VEMDataSet * GetComponent(G4int componentId) const override
G4double FindValue(G4double e, G4int componentId=0) const override
const std::vector< G4double > * GetNumMolPerVolTableFor(const G4Material *) const
Retrieve a table of molecular densities (number of molecules per unit volume) in the G4 unit system f...
static G4DNAMolecularMaterial * Instance()
G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *p, G4double ekin, G4double emin, G4double emax) override
G4ParticleChangeForGamma * fParticleChangeForGamma
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
G4double ComputeProbabilityFunction(const G4ParticleDefinition *, G4double kine, G4double deltae, G4int shell)
G4DNARuddIonisationExtendedModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="DNARuddIonisationExtendedModel")
~G4DNARuddIonisationExtendedModel() override
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
G4double IonisationEnergy(G4int level)
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
G4double EffectiveChargeSquareRatio(const G4ParticleDefinition *, const G4Material *, const G4double kineticEnergy)
static G4EmParameters * Instance()
G4bool DNAStationary() const
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
G4EmCorrections * EmCorrections()
const G4Material * GetMaterial() const
std::size_t GetIndex() const
G4Material * FindMaterial(const G4String &name) const
static G4NistManager * Instance()
void SetProposedKineticEnergy(G4double proposedKinEnergy)
G4int GetAtomicNumber() const
G4double GetPDGMass() const
G4int GetAtomicMass() const
const G4String & GetParticleName() const
static G4Pow * GetInstance()
G4double logZ(G4int Z) const
G4double powN(G4double x, G4int n) const
G4double powA(G4double A, G4double y) const
virtual const G4AtomicShell * GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell)=0
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
virtual G4double FindValue(G4double x, G4int componentId=0) const =0
virtual G4ThreeVector & SampleDirectionForShell(const G4DynamicParticle *dp, G4double finalTotalEnergy, G4int Z, G4int shellID, const G4Material *)
G4VEmAngularDistribution * GetAngularDistribution()
G4ParticleChangeForGamma * GetParticleChangeForGamma()
void SetDeexcitationFlag(G4bool val)
void SetAngularDistribution(G4VEmAngularDistribution *)
void ProposeTrackStatus(G4TrackStatus status)
const G4Track * GetCurrentTrack() const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
G4double bindingEnergy(G4int A, G4int Z)