59 slaterEffectiveCharge[0]=0.;
60 slaterEffectiveCharge[1]=0.;
61 slaterEffectiveCharge[2]=0.;
66 lowEnergyLimitForA[1] = 0 * eV;
67 lowEnergyLimitForA[2] = 0 * eV;
68 lowEnergyLimitForA[3] = 0 * eV;
69 lowEnergyLimitOfModelForA[1] = 100 * eV;
70 lowEnergyLimitOfModelForA[4] = 1 * keV;
71 lowEnergyLimitOfModelForA[5] = 0.5 * MeV;
72 killBelowEnergyForA[1] = lowEnergyLimitOfModelForA[1];
73 killBelowEnergyForA[4] = lowEnergyLimitOfModelForA[4];
74 killBelowEnergyForA[5] = lowEnergyLimitOfModelForA[5];
86 G4cout <<
"Rudd ionisation model is constructed " <<
G4endl;
105 std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
106 for (pos = tableData.begin(); pos != tableData.end(); ++pos)
121 if (isInitialised) {
return; }
122 if (verboseLevel > 3)
123 G4cout <<
"Calling G4DNARuddIonisationExtendedModel::Initialise()" <<
G4endl;
126 G4String fileProton(
"dna/sigma_ionisation_p_rudd");
127 G4String fileHydrogen(
"dna/sigma_ionisation_h_rudd");
128 G4String fileAlphaPlusPlus(
"dna/sigma_ionisation_alphaplusplus_rudd");
129 G4String fileAlphaPlus(
"dna/sigma_ionisation_alphaplus_rudd");
130 G4String fileHelium(
"dna/sigma_ionisation_he_rudd");
131 G4String fileCarbon(
"dna/sigma_ionisation_c_rudd");
132 G4String fileNitrogen(
"dna/sigma_ionisation_n_rudd");
133 G4String fileOxygen(
"dna/sigma_ionisation_o_rudd");
134 G4String fileSilicon(
"dna/sigma_ionisation_si_rudd");
135 G4String fileIron(
"dna/sigma_ionisation_fe_rudd");
142 hydrogenDef = instance->
GetIon(
"hydrogen");
144 alphaPlusDef = instance->
GetIon(
"alpha+");
145 heliumDef = instance->
GetIon(
"helium");
147 carbonDef = instance->
GetIon(
"carbon");
148 nitrogenDef = instance->
GetIon(
"nitrogen");
149 oxygenDef = instance->
GetIon(
"oxygen");
150 siliconDef = instance->
GetIon(
"silicon");
151 ironDef = instance->
GetIon(
"iron");
166 if(pname ==
"proton") {
167 localMinEnergy = lowEnergyLimitForA[1];
175 }
else if(pname ==
"hydrogen") {
177 localMinEnergy = lowEnergyLimitForA[1];
185 }
else if(pname ==
"alpha") {
187 localMinEnergy = lowEnergyLimitForA[4];
191 mainTable->
LoadData(fileAlphaPlusPlus);
195 }
else if(pname ==
"alpha+") {
197 localMinEnergy = lowEnergyLimitForA[4];
205 }
else if(pname ==
"helium") {
207 localMinEnergy = lowEnergyLimitForA[4];
215 }
else if(pname ==
"GenericIon") {
219 localMinEnergy = lowEnergyLimitForA[5]*massC12/proton_mass_c2;
225 tableData[carbon] = mainTable;
230 tableFile[oxygen] = fileOxygen;
236 tableData[oxygen] = tableOxygen;
241 tableFile[nitrogen] = fileNitrogen;
246 tableNitrogen->
LoadData(fileNitrogen);
247 tableData[nitrogen] = tableNitrogen;
252 tableFile[silicon] = fileSilicon;
257 tableSilicon->
LoadData(fileSilicon);
258 tableData[silicon] = tableSilicon;
263 tableFile[iron] = fileIron;
270 tableData[iron] = tableIron;
276 G4cout <<
"Rudd ionisation model is initialized " <<
G4endl
277 <<
"Energy range for model: "
281 <<
" internal low energy limit E(keV)=" << localMinEnergy / keV
292 isInitialised =
true;
303 if (verboseLevel > 3)
304 G4cout <<
"Calling CrossSectionPerVolume() of G4DNARuddIonisationExtendedModel" <<
G4endl;
306 currParticle = GetDNAIonParticleDefinition(partDef);
307 currentScaledEnergy = k;
310 currentTable = mainTable;
313 if (currParticle ==
nullptr) {
314 currentScaledEnergy *= massC12/partDef->
GetPDGMass();
317 e = currentScaledEnergy;
318 currParticle = carbonDef;
321 auto goodTable = tableData.find(pname);
322 currentTable = goodTable->second;
325 if (currentScaledEnergy < localMinEnergy) {
return DBL_MAX; }
329 if (
nullptr != currentTable) {
332 G4cout <<
"G4DNARuddIonisationExtendedModel - no data table for "
334 G4Exception(
"G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(...)",
"em0002",
337 if (verboseLevel > 2)
339 G4cout <<
"__________________________________" <<
G4endl;
340 G4cout <<
"G4DNARuddIonisationExtendedModel - XS INFO START" <<
G4endl;
342 G4cout <<
"Cross section per water molecule (cm^2)=" << sigma/cm/cm <<
G4endl;
343 G4cout <<
"Cross section per water molecule (cm^-1)=" << sigma*waterDensity/(1./cm) <<
G4endl;
344 G4cout <<
"G4DNARuddIonisationExtendedModel - XS INFO END" <<
G4endl;
346 return sigma*waterDensity;
357 if (verboseLevel > 3)
358 G4cout <<
"Calling SampleSecondaries() of G4DNARuddIonisationExtendedModel" <<
G4endl;
362 if (currentScaledEnergy < localMinEnergy) {
373 G4int ionizationShell = RandomSelect(currentScaledEnergy);
382 if (k < bindingEnergy)
return;
385 G4double secondaryKinetic = RandomizeEjectedElectronEnergy(definition,k,ionizationShell);
388 G4double scatteredEnergy = k - bindingEnergy - secondaryKinetic;
389 if(scatteredEnergy < 0.0) {
return; }
399 fvect->push_back(dp);
403 size_t secNumberInit = 0;
404 size_t secNumberFinal = 0;
407 if(fAtomDeexcitation !=
nullptr && ionizationShell == 4)
411 secNumberInit = fvect->size();
413 secNumberFinal = fvect->size();
415 if(secNumberFinal > secNumberInit)
417 for (
size_t i=secNumberInit; i<secNumberFinal; ++i)
420 if (bindingEnergy >= ((*fvect)[i])->GetKineticEnergy())
423 bindingEnergy -= ((*fvect)[i])->GetKineticEnergy();
477 proposed_energy = ProposedSampledEnergy(particleDefinition, k, shell);
481 for(
G4double en=0.; en<20.; en+=1.)
if(RejectionFunction(particleDefinition, k, en, shell) > max1)
482 max1=RejectionFunction(particleDefinition, k, en, shell);
486 value_sampling = RejectionFunction(particleDefinition, k, proposed_energy, shell);
488 }
while(random1 > value_sampling);
490 return(proposed_energy);
498 G4int ionizationLevelIndex)
500 const G4int j=ionizationLevelIndex;
503 const G4double Gj[5] = {0.99, 1.11, 1.11, 0.52, 1.};
508 const G4double Bj[5] = {12.60*eV, 14.70*eV, 18.40*eV, 32.20*eV, 540*eV};
520 Bj_energy = Bj[ionizationLevelIndex];
523 G4double energyTransfer = proposed_ws + Bj_energy;
524 proposed_ws/=Bj_energy;
528 tau = (electron_mass_c2 / particleDefinition->
GetPDGMass()) * k;
534 if((tau/MeV)<5.447761194e-2)
536 v2 = tau / Bj_energy;
537 beta2 = 2.*tau / electron_mass_c2;
542 v2 = (electron_mass_c2 / 2. / Bj_energy) * (1. - (1./ pow( (1.+ (tau/electron_mass_c2)),2) ));
543 beta2 =1. - 1./(1.+ (tau/electron_mass_c2/A_ion))/(1.+ (tau/electron_mass_c2/A_ion));
547 G4double wc = 4.*v2 - 2.*v - (Ry/(4.*Bj_energy));
548 G4double rejection_term = 1.+
G4Exp(alphaConst*(proposed_ws - wc) / v);
549 rejection_term = (1./rejection_term)*CorrectionFactor(particleDefinition,k,ionizationLevelIndex) * Gj[j];
554 if ( particleDefinition == protonDef
555 || particleDefinition == hydrogenDef
558 return(rejection_term);
567 rejection_term*=Zeffion*Zeffion;
570 else if (particleDefinition == alphaPlusPlusDef )
573 slaterEffectiveCharge[0]=0.;
574 slaterEffectiveCharge[1]=0.;
575 slaterEffectiveCharge[2]=0.;
581 else if (particleDefinition == alphaPlusDef )
584 slaterEffectiveCharge[0]=2.0;
586 slaterEffectiveCharge[1]=2.0;
587 slaterEffectiveCharge[2]=2.0;
590 sCoefficient[1]=0.15;
591 sCoefficient[2]=0.15;
594 else if (particleDefinition == heliumDef )
597 slaterEffectiveCharge[0]=1.7;
598 slaterEffectiveCharge[1]=1.15;
599 slaterEffectiveCharge[2]=1.15;
601 sCoefficient[1]=0.25;
602 sCoefficient[2]=0.25;
610 zEff -= ( sCoefficient[0] * S_1s(k, energyTransfer, slaterEffectiveCharge[0], 1.) +
611 sCoefficient[1] * S_2s(k, energyTransfer, slaterEffectiveCharge[1], 2.) +
612 sCoefficient[2] * S_2p(k, energyTransfer, slaterEffectiveCharge[2], 2.) );
614 rejection_term*= zEff * zEff;
617 return (rejection_term);
626 G4int ionizationLevelIndex)
629 const G4int j=ionizationLevelIndex;
638 const G4double Bj[5] = {12.60*eV, 14.70*eV, 18.40*eV, 32.20*eV, 540*eV};
674 Bj_energy = Bj[ionizationLevelIndex];
679 tau = (electron_mass_c2 / particle->
GetPDGMass()) * k;
685 if((tau/MeV)<5.447761194e-2)
687 v2 = tau / Bj_energy;
688 beta2 = 2.*tau / electron_mass_c2;
693 v2 = (electron_mass_c2 / 2. / Bj_energy) * (1. - (1./ pow( (1.+ (tau/electron_mass_c2)),2) ));
694 beta2 =1. - 1./(1.+ (tau/electron_mass_c2/A_ion))/(1.+ (tau/electron_mass_c2/A_ion));
702 G4double H2 = (A2/v2) + (B2/(v2*v2));
710 if( (k/MeV)/(particle->
GetPDGMass()/MeV) <= 0.1 )
712 maximumEnergy = 4.* (electron_mass_c2 / particle->
GetPDGMass()) * k;
718 maximumEnergy = 2.*electron_mass_c2*(gamma*gamma-1.)/
719 (1.+2.*gamma*(electron_mass_c2/particle->
GetPDGMass())+pow(electron_mass_c2/particle->
GetPDGMass(), 2.) );
726 G4double wmax = maximumEnergy/Bj_energy;
727 G4double c = wmax*(F2*wmax+F1*(2.+wmax))/(2.*(1.+wmax)*(1.+wmax));
730 G4double proposed_ws = F1*F1*c*c + 2.*F2*c*randVal - 2.*F1*c*randVal;
731 proposed_ws = -F1*c+2.*randVal+std::sqrt(proposed_ws);
733 proposed_ws/= ( F1*c + F2*c - 2.*randVal );
734 proposed_ws*=Bj_energy;
750 G4double r = R(t, energyTransferred, slaterEffectiveChg, shellNumber);
751 G4double value = 1. -
G4Exp(-2 * r) * ( ( 2. * r + 2. ) * r + 1. );
766 G4double r = R(t, energyTransferred, slaterEffectiveChg, shellNumber);
767 G4double value = 1. -
G4Exp(-2 * r) * (((2. * r * r + 2.) * r + 2.) * r + 1.);
783 G4double r = R(t, energyTransferred, slaterEffectiveChg, shellNumber);
784 G4double value = 1. -
G4Exp(-2 * r) * (((( 2./3. * r + 4./3.) * r + 2.) * r + 2.) * r + 1.);
799 G4double tElectron = 0.511/3728. * t;
802 G4double value = std::sqrt ( 2. * tElectron / H ) / ( energyTransferred / H ) * (slaterEffectiveChg/shellNumber);
813 if (particleDefinition == hydrogenDef && shell < 4)
817 return((0.6/(1+
G4Exp(value))) + 0.9);
827G4int G4DNARuddIonisationExtendedModel::RandomSelect(
G4double k)
835 if (table !=
nullptr)
848 value += valuesBuffer[i];
859 if (valuesBuffer[i] > value)
861 delete[] valuesBuffer;
864 value -= valuesBuffer[i];
867 if (valuesBuffer)
delete[] valuesBuffer;
875G4double G4DNARuddIonisationExtendedModel::PartialCrossSection(
const G4Track& track )
887 std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
888 pos1 = lowEnergyLimit.find(particleName);
890 if (pos1 != lowEnergyLimit.end())
892 lowLim = pos1->second;
895 std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
896 pos2 = highEnergyLimit.find(particleName);
898 if (pos2 != highEnergyLimit.end())
900 highLim = pos2->second;
903 if (k >= lowLim && k <= highLim)
905 std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator
pos;
906 pos = tableData.find(particleName);
908 if (pos != tableData.end())
918 G4Exception(
"G4DNARuddIonisationExtendedModel::PartialCrossSection",
"em0002",
946 if(PDGEncoding == 1000140280){
947 return instance->GetIon(
"silicon");
948 }
else if(PDGEncoding == 1000260560){
949 return instance->GetIon(
"iron");
950 }
else if(PDGEncoding == 1000080160){
951 return instance->GetIon(
"oxygen");
952 }
else if(PDGEncoding == 1000070140){
953 return instance->GetIon(
"nitrogen");
954 }
else if(PDGEncoding == 1000060120){
955 return instance->GetIon(
"carbon");
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)
G4GLOB_DLL std::ostream G4cout
static G4DNAChemistryManager * Instance()
void CreateWaterMolecule(ElectronicModification, G4int, const G4Track *)
virtual G4double FindValue(G4double e, G4int componentId=0) const
virtual size_t NumberOfComponents(void) const
virtual const G4VEMDataSet * GetComponent(G4int componentId) const
virtual G4bool LoadData(const G4String &argFileName)
static G4DNAGenericIonsManager * Instance(void)
G4ParticleDefinition * GetIon(const G4String &name)
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()
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
G4ParticleChangeForGamma * fParticleChangeForGamma
virtual ~G4DNARuddIonisationExtendedModel()
virtual G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *p, G4double ekin, G4double emin, G4double emax)
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &)
G4DNARuddIonisationExtendedModel(const G4ParticleDefinition *p=0, const G4String &nam="DNARuddIonisationExtendedModel")
G4double IonisationEnergy(G4int level)
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
static G4LossTableManager * Instance()
G4VAtomDeexcitation * AtomDeexcitation()
const G4Material * GetMaterial() const
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
G4int GetAtomicNumber() const
G4double GetPDGMass() const
G4int GetAtomicMass() const
G4int GetPDGEncoding() const
G4int GetLeptonNumber() const
G4double GetPDGCharge() const
const G4String & GetParticleName() const
static G4Pow * GetInstance()
G4double logZ(G4int Z) const
G4double powA(G4double A, G4double y) const
static G4Proton * ProtonDefinition()
const G4DynamicParticle * GetDynamicParticle() 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()
G4double LowEnergyLimit() const
G4double HighEnergyLimit() const
void SetDeexcitationFlag(G4bool val)
void SetAngularDistribution(G4VEmAngularDistribution *)
void ProposeTrackStatus(G4TrackStatus status)
const G4Track * GetCurrentTrack() const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)