53 slaterEffectiveCharge[0] = 0.;
54 slaterEffectiveCharge[1] = 0.;
55 slaterEffectiveCharge[2] = 0.;
60 lowEnergyLimitForZ1 = 0 * eV;
61 lowEnergyLimitForZ2 = 0 * eV;
62 lowEnergyLimitOfModelForZ1 = 100 * eV;
63 lowEnergyLimitOfModelForZ2 = 1 * keV;
64 killBelowEnergyForZ1 = lowEnergyLimitOfModelForZ1;
65 killBelowEnergyForZ2 = lowEnergyLimitOfModelForZ2;
77 G4cout <<
"Rudd ionisation model is constructed " <<
G4endl;
97 std::map<G4String, G4DNACrossSectionDataSet*, std::less<G4String> >::iterator pos;
98 for (pos = tableData.begin(); pos != tableData.end(); ++pos)
116 if (verboseLevel > 3)
118 G4cout <<
"Calling G4DNARuddIonisationModel::Initialise()" <<
G4endl;
123 G4String fileProton(
"dna/sigma_ionisation_p_rudd");
124 G4String fileHydrogen(
"dna/sigma_ionisation_h_rudd");
125 G4String fileAlphaPlusPlus(
"dna/sigma_ionisation_alphaplusplus_rudd");
126 G4String fileAlphaPlus(
"dna/sigma_ionisation_alphaplus_rudd");
127 G4String fileHelium(
"dna/sigma_ionisation_he_rudd");
132 hydrogenDef =
instance->GetIon(
"hydrogen");
134 alphaPlusDef =
instance->GetIon(
"alpha+");
135 heliumDef =
instance->GetIon(
"helium");
149 proton = protonDef->GetParticleName();
150 tableFile[proton] = fileProton;
152 lowEnergyLimit[proton] = lowEnergyLimitForZ1;
153 highEnergyLimit[proton] = 500. * keV;
160 tableProton->LoadData(fileProton);
161 tableData[proton] = tableProton;
165 hydrogen = hydrogenDef->GetParticleName();
166 tableFile[hydrogen] = fileHydrogen;
168 lowEnergyLimit[hydrogen] = lowEnergyLimitForZ1;
169 highEnergyLimit[hydrogen] = 100. * MeV;
176 tableHydrogen->LoadData(fileHydrogen);
178 tableData[hydrogen] = tableHydrogen;
182 alphaPlusPlus = alphaPlusPlusDef->GetParticleName();
183 tableFile[alphaPlusPlus] = fileAlphaPlusPlus;
185 lowEnergyLimit[alphaPlusPlus] = lowEnergyLimitForZ2;
186 highEnergyLimit[alphaPlusPlus] = 400. * MeV;
193 tableAlphaPlusPlus->LoadData(fileAlphaPlusPlus);
195 tableData[alphaPlusPlus] = tableAlphaPlusPlus;
199 alphaPlus = alphaPlusDef->GetParticleName();
200 tableFile[alphaPlus] = fileAlphaPlus;
202 lowEnergyLimit[alphaPlus] = lowEnergyLimitForZ2;
203 highEnergyLimit[alphaPlus] = 400. * MeV;
210 tableAlphaPlus->LoadData(fileAlphaPlus);
211 tableData[alphaPlus] = tableAlphaPlus;
215 helium = heliumDef->GetParticleName();
216 tableFile[helium] = fileHelium;
218 lowEnergyLimit[helium] = lowEnergyLimitForZ2;
219 highEnergyLimit[helium] = 400. * MeV;
226 tableHelium->LoadData(fileHelium);
227 tableData[helium] = tableHelium;
231 if (particle==protonDef)
237 if (particle==hydrogenDef)
243 if (particle==heliumDef)
249 if (particle==alphaPlusDef)
255 if (particle==alphaPlusPlusDef)
261 if (isInitialised) {
return; }
274 isInitialised =
true;
276 if (verboseLevel > 0)
278 G4cout <<
"Rudd ionisation model is initialized " <<
G4endl
295 if (verboseLevel > 3)
297 G4cout <<
"Calling CrossSectionPerVolume() of G4DNARuddIonisationModel"
304 particleDefinition != protonDef
306 particleDefinition != hydrogenDef
308 particleDefinition != alphaPlusPlusDef
310 particleDefinition != alphaPlusDef
312 particleDefinition != heliumDef
319 if ( particleDefinition == protonDef
320 || particleDefinition == hydrogenDef
323 lowLim = lowEnergyLimitOfModelForZ1;
325 if ( particleDefinition == alphaPlusPlusDef
326 || particleDefinition == alphaPlusDef
327 || particleDefinition == heliumDef
330 lowLim = lowEnergyLimitOfModelForZ2;
350 std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
351 pos2 = highEnergyLimit.find(particleName);
353 if (pos2 != highEnergyLimit.end())
355 highLim = pos2->second;
362 if (k < lowLim) k = lowLim;
366 std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
367 pos = tableData.find(particleName);
369 if (pos != tableData.end())
372 if (table !=
nullptr)
374 sigma = table->FindValue(k);
379 G4Exception(
"G4DNARuddIonisationModel::CrossSectionPerVolume",
"em0002",
385 if (verboseLevel > 2)
387 G4cout <<
"__________________________________" <<
G4endl;
388 G4cout <<
"G4DNARuddIonisationModel - XS INFO START" <<
G4endl;
390 G4cout <<
"Cross section per water molecule (cm^2)=" << sigma/cm/cm <<
G4endl;
391 G4cout <<
"Cross section per water molecule (cm^-1)=" << sigma*waterDensity/(1./cm) <<
G4endl;
394 G4cout <<
"G4DNARuddIonisationModel - XS INFO END" <<
G4endl;
397 return sigma*waterDensity;
409 if (verboseLevel > 3)
411 G4cout <<
"Calling SampleSecondaries() of G4DNARuddIonisationModel"
422 lowLim = killBelowEnergyForZ1;
429 lowLim = killBelowEnergyForZ2;
446 std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
447 pos2 = highEnergyLimit.find(particleName);
449 if (pos2 != highEnergyLimit.end())
451 highLim = pos2->second;
454 if (k >= lowLim && k <= highLim)
465 G4int ionizationShell = RandomSelect(k,particleName);
468 bindingEnergy = waterStructure.IonisationEnergy(ionizationShell);
471 if (k<bindingEnergy)
return;
478 G4double secondaryKinetic = RandomizeEjectedElectronEnergy(definition,k,ionizationShell);
486 fvect->push_back(dp);
512 size_t secNumberInit = 0;
513 size_t secNumberFinal = 0;
515 G4double scatteredEnergy = k-bindingEnergy-secondaryKinetic;
518 if((fAtomDeexcitation !=
nullptr) && ionizationShell == 4)
522 secNumberInit = fvect->size();
523 fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
524 secNumberFinal = fvect->size();
526 if(secNumberFinal > secNumberInit)
528 for (
size_t i=secNumberInit; i<secNumberFinal; ++i)
531 if (bindingEnergy >= ((*fvect)[i])->GetKineticEnergy())
534 bindingEnergy -= ((*fvect)[i])->GetKineticEnergy();
549 if(bindingEnergy < 0.0)
550 G4Exception(
"G4DNAEmfietzoglouIonisatioModel1::SampleSecondaries()",
602 G4double maximumKineticEnergyTransfer = 0.;
604 if (particleDefinition == protonDef
605 || particleDefinition == hydrogenDef)
607 maximumKineticEnergyTransfer = 4. * (electron_mass_c2 / proton_mass_c2) * k;
610 else if (particleDefinition == heliumDef
611 || particleDefinition == alphaPlusDef
612 || particleDefinition == alphaPlusPlusDef)
614 maximumKineticEnergyTransfer = 4. * (0.511 / 3728) * k;
619 for (
G4double value = waterStructure.IonisationEnergy(shell);
620 value <= 5. * waterStructure.IonisationEnergy(shell) && k >= value;
624 DifferentialCrossSection(particleDefinition, k, value, shell);
625 if (differentialCrossSection >= crossSectionMaximum)
626 crossSectionMaximum = differentialCrossSection;
633 secElecKinetic =
G4UniformRand()* maximumKineticEnergyTransfer;
634 }
while(
G4UniformRand()*crossSectionMaximum > DifferentialCrossSection(particleDefinition,
636 secElecKinetic+waterStructure.IonisationEnergy(shell),
639 return (secElecKinetic);
687 G4int ionizationLevelIndex)
705 const G4int j = ionizationLevelIndex;
720 const G4double Bj[5] = { 12.60 * eV, 14.70 * eV, 18.40 * eV, 32.20 * eV, 540
754 const G4double Gj[5] = { 0.99, 1.11, 1.11, 0.52, 1. };
757 - waterStructure.IonisationEnergy(ionizationLevelIndex));
761 G4double w = wBig / Bj[ionizationLevelIndex];
764 w = wBig / waterStructure.IonisationEnergy(ionizationLevelIndex);
770 G4bool isProtonOrHydrogen =
false;
773 if (particleDefinition == protonDef
774 || particleDefinition == hydrogenDef)
776 isProtonOrHydrogen =
true;
777 tau = (electron_mass_c2 / proton_mass_c2) * k;
780 else if (particleDefinition == heliumDef
781 || particleDefinition == alphaPlusDef
782 || particleDefinition == alphaPlusPlusDef)
785 tau = (0.511 / 3728.) * k;
789 * gpow->
powN((Ry / Bj[ionizationLevelIndex]), 2);
791 S = 4. *
pi * Bohr_radius * Bohr_radius *
n
792 * gpow->
powN((Ry / waterStructure.IonisationEnergy(ionizationLevelIndex)),
795 G4double v2 = tau / Bj[ionizationLevelIndex];
797 v2 = tau / waterStructure.IonisationEnergy(ionizationLevelIndex);
800 G4double wc = 4. * v2 - 2. * v - (Ry / (4. * Bj[ionizationLevelIndex]));
802 wc = 4. * v2 - 2. * v
803 - (Ry / (4. * waterStructure.IonisationEnergy(ionizationLevelIndex)));
808 G4double H2 = (A2 / v2) + (B2 / (v2 * v2));
811 G4double F2 = (L2 * H2) / (L2 + H2);
814 CorrectionFactor(particleDefinition, k) * Gj[j]
815 * (
S / Bj[ionizationLevelIndex])
817 / (gpow->
powN((1. + w), 3)
818 * (1. +
G4Exp(alphaConst * (w - wc) / v))));
821 sigma = CorrectionFactor(particleDefinition, k) * Gj[j]
822 * (
S / waterStructure.IonisationEnergy(ionizationLevelIndex))
824 / (gpow->
powN((1. + w), 3)
825 * (1. +
G4Exp(alphaConst * (w - wc) / v))));
827 if ((particleDefinition == hydrogenDef)
828 && (ionizationLevelIndex == 4))
831 sigma = Gj[j] * (
S / waterStructure.IonisationEnergy(ionizationLevelIndex))
833 / (gpow->
powN((1. + w), 3)
834 * (1. +
G4Exp(alphaConst * (w - wc) / v))));
841 if (isProtonOrHydrogen)
846 if (particleDefinition == alphaPlusPlusDef)
848 slaterEffectiveCharge[0] = 0.;
849 slaterEffectiveCharge[1] = 0.;
850 slaterEffectiveCharge[2] = 0.;
851 sCoefficient[0] = 0.;
852 sCoefficient[1] = 0.;
853 sCoefficient[2] = 0.;
856 else if (particleDefinition == alphaPlusDef)
858 slaterEffectiveCharge[0] = 2.0;
860 slaterEffectiveCharge[1] = 2.0;
861 slaterEffectiveCharge[2] = 2.0;
863 sCoefficient[0] = 0.7;
864 sCoefficient[1] = 0.15;
865 sCoefficient[2] = 0.15;
868 else if (particleDefinition == heliumDef)
870 slaterEffectiveCharge[0] = 1.7;
871 slaterEffectiveCharge[1] = 1.15;
872 slaterEffectiveCharge[2] = 1.15;
873 sCoefficient[0] = 0.5;
874 sCoefficient[1] = 0.25;
875 sCoefficient[2] = 0.25;
884 sigma = Gj[j] * (
S / Bj[ionizationLevelIndex])
886 / (gpow->
powN((1. + w), 3)
887 * (1. +
G4Exp(alphaConst * (w - wc) / v))));
891 * (
S / waterStructure.IonisationEnergy(ionizationLevelIndex))
893 / (gpow->
powN((1. + w), 3)
894 * (1. +
G4Exp(alphaConst * (w - wc) / v))));
899 zEff -= (sCoefficient[0]
900 * S_1s(k, energyTransfer, slaterEffectiveCharge[0], 1.)
902 * S_2s(k, energyTransfer, slaterEffectiveCharge[1], 2.)
904 * S_2p(k, energyTransfer, slaterEffectiveCharge[2], 2.));
906 return zEff * zEff * sigma;
922 G4double r = R(t, energyTransferred, slaterEffectiveChg, shellNumber);
923 G4double value = 1. -
G4Exp(-2 * r) * ((2. * r + 2.) * r + 1.);
938 G4double r = R(t, energyTransferred, slaterEffectiveChg, shellNumber);
940 -
G4Exp(-2 * r) * (((2. * r * r + 2.) * r + 2.) * r + 1.);
956 G4double r = R(t, energyTransferred, slaterEffectiveChg, shellNumber);
959 * ((((2. / 3. * r + 4. / 3.) * r + 2.) * r + 2.) * r + 1.);
974 G4double tElectron = 0.511 / 3728. * t;
977 G4double value = std::sqrt(2. * tElectron / H) / (energyTransferred / H)
978 * (slaterEffectiveChg / shellNumber);
993 if (particleDefinition == hydrogenDef)
997 return ((0.6 / (1 +
G4Exp(value))) + 0.9);
1016 std::map<G4String, G4DNACrossSectionDataSet*, std::less<G4String> >::iterator
pos;
1017 pos = tableData.find(particle);
1019 if (pos != tableData.end())
1021 G4DNACrossSectionDataSet*
table =
pos->second;
1023 if (table !=
nullptr)
1025 auto valuesBuffer =
new G4double[
table->NumberOfComponents()];
1027 const auto n = (
G4int)
table->NumberOfComponents();
1034 valuesBuffer[i] =
table->GetComponent(i)->FindValue(k);
1035 value += valuesBuffer[i];
1046 if (valuesBuffer[i] > value)
1048 delete[] valuesBuffer;
1051 value -= valuesBuffer[i];
1055 delete[] valuesBuffer;
1060 G4Exception(
"G4DNARuddIonisationModel::RandomSelect",
1063 "Model not applicable to particle type.");
1071G4double G4DNARuddIonisationModel::PartialCrossSection(
const G4Track& track)
1083 std::map<G4String, G4double, std::less<G4String> >::iterator pos1;
1084 pos1 = lowEnergyLimit.find(particleName);
1086 if (pos1 != lowEnergyLimit.end())
1088 lowLim = pos1->second;
1091 std::map<G4String, G4double, std::less<G4String> >::iterator pos2;
1092 pos2 = highEnergyLimit.find(particleName);
1094 if (pos2 != highEnergyLimit.end())
1096 highLim = pos2->second;
1099 if (k >= lowLim && k <= highLim)
1101 std::map<G4String, G4DNACrossSectionDataSet*, std::less<G4String> >::iterator
pos;
1102 pos = tableData.find(particleName);
1104 if (pos != tableData.end())
1106 G4DNACrossSectionDataSet*
table =
pos->second;
1107 if (table !=
nullptr)
1109 sigma =
table->FindValue(k);
1113 G4Exception(
"G4DNARuddIonisationModel::PartialCrossSection",
1116 "Model not applicable to particle type.");
G4double S(G4double temp)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4double G4Log(G4double x)
G4ThreeVector G4ParticleMomentum
G4TemplateRNGHelper< G4long > * G4TemplateRNGHelper< G4long >::instance
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
static G4DNAChemistryManager * Instance()
void CreateWaterMolecule(ElectronicModification, G4int, const G4Track *)
static G4DNAGenericIonsManager * Instance()
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()
G4ParticleChangeForGamma * fParticleChangeForGamma
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *p, G4double ekin, G4double emin, G4double emax) override
~G4DNARuddIonisationModel() override
G4DNARuddIonisationModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="DNARuddIonisationModel")
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
static G4EmParameters * Instance()
G4bool DNAStationary() const
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
const G4Material * GetMaterial() const
std::size_t GetIndex() const
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
G4int GetLeptonNumber() const
G4double GetPDGCharge() 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
static G4Proton * ProtonDefinition()
static G4Proton * Proton()
const G4DynamicParticle * GetDynamicParticle() const
virtual G4ThreeVector & SampleDirectionForShell(const G4DynamicParticle *dp, G4double finalTotalEnergy, G4int Z, G4int shellID, const G4Material *)
void SetHighEnergyLimit(G4double)
G4VEmAngularDistribution * GetAngularDistribution()
G4ParticleChangeForGamma * GetParticleChangeForGamma()
G4double LowEnergyLimit() const
G4double HighEnergyLimit() const
void SetLowEnergyLimit(G4double)
void SetDeexcitationFlag(G4bool val)
G4VEmModel(const G4String &nam)
void SetAngularDistribution(G4VEmAngularDistribution *)