Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // >> 26 // $Id$ 26 // 27 // 27 28 28 #include "G4DNADingfelderChargeIncreaseModel.h 29 #include "G4DNADingfelderChargeIncreaseModel.hh" 29 #include "G4PhysicalConstants.hh" 30 #include "G4PhysicalConstants.hh" 30 #include "G4SystemOfUnits.hh" 31 #include "G4SystemOfUnits.hh" 31 #include "G4DNAMolecularMaterial.hh" 32 #include "G4DNAMolecularMaterial.hh" 32 #include "G4Log.hh" << 33 #include "G4Pow.hh" << 34 #include "G4Alpha.hh" << 35 << 36 static G4Pow * gpow = G4Pow::GetInstance(); << 37 33 38 //....oooOO0OOooo........oooOO0OOooo........oo 34 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 39 35 40 using namespace std; 36 using namespace std; 41 37 42 //....oooOO0OOooo........oooOO0OOooo........oo 38 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 43 39 44 G4DNADingfelderChargeIncreaseModel::G4DNADingf 40 G4DNADingfelderChargeIncreaseModel::G4DNADingfelderChargeIncreaseModel(const G4ParticleDefinition*, 45 << 41 const G4String& nam) 46 G4VEmModel(nam) << 42 :G4VEmModel(nam),isInitialised(false) 47 { 43 { 48 if (verboseLevel > 0) << 44 // nistwater = G4NistManager::Instance()->FindOrBuildMaterial("G4_WATER"); 49 { << 45 fpMolWaterDensity = 0; 50 G4cout << "Dingfelder charge increase mode << 46 51 } << 47 numberOfPartialCrossSections[0]=0; >> 48 numberOfPartialCrossSections[1]=0; >> 49 >> 50 verboseLevel= 0; >> 51 // Verbosity scale: >> 52 // 0 = nothing >> 53 // 1 = warning for energy non-conservation >> 54 // 2 = details of energy budget >> 55 // 3 = calculation of cross sections, file openings, sampling of atoms >> 56 // 4 = entering in methods >> 57 >> 58 if( verboseLevel>0 ) >> 59 { >> 60 G4cout << "Dingfelder charge increase model is constructed " << G4endl; >> 61 } >> 62 fParticleChangeForGamma = 0; 52 } 63 } 53 64 54 //....oooOO0OOooo........oooOO0OOooo........oo 65 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 55 66 >> 67 G4DNADingfelderChargeIncreaseModel::~G4DNADingfelderChargeIncreaseModel() >> 68 {} >> 69 >> 70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... >> 71 56 void G4DNADingfelderChargeIncreaseModel::Initi 72 void G4DNADingfelderChargeIncreaseModel::Initialise(const G4ParticleDefinition* particle, 57 73 const G4DataVector& /*cuts*/) 58 { 74 { 59 75 60 if (verboseLevel > 3) << 76 if (verboseLevel > 3) 61 { << 77 G4cout << "Calling G4DNADingfelderChargeIncreaseModel::Initialise()" << G4endl; 62 G4cout << "Calling G4DNADingfelderChargeIn << 78 63 << G4endl; << 79 // Energy limits 64 } << 80 65 << 81 G4DNAGenericIonsManager *instance; 66 // Energy limits << 82 instance = G4DNAGenericIonsManager::Instance(); 67 << 83 G4ParticleDefinition* hydrogenDef = instance->GetIon("hydrogen"); 68 G4DNAGenericIonsManager *instance; << 84 G4ParticleDefinition* alphaPlusDef = instance->GetIon("alpha+"); 69 instance = G4DNAGenericIonsManager::Instance << 85 G4ParticleDefinition* heliumDef = instance->GetIon("helium"); 70 hydrogenDef = instance->GetIon("hydrogen"); << 86 71 alphaPlusPlusDef = G4Alpha::Alpha(); << 87 G4String hydrogen; 72 alphaPlusDef = instance->GetIon("alpha+"); << 88 G4String alphaPlus; 73 heliumDef = instance->GetIon("helium"); << 89 G4String helium; 74 << 90 75 G4String hydrogen; << 91 // LIMITS 76 G4String alphaPlus; << 92 77 G4String helium; << 93 hydrogen = hydrogenDef->GetParticleName(); 78 << 94 lowEnergyLimit[hydrogen] = 100. * eV; 79 // Limits << 95 highEnergyLimit[hydrogen] = 100. * MeV; 80 << 96 81 hydrogen = hydrogenDef->GetParticleName(); << 97 alphaPlus = alphaPlusDef->GetParticleName(); 82 lowEnergyLimit[hydrogen] = 100. * eV; << 98 lowEnergyLimit[alphaPlus] = 1. * keV; 83 highEnergyLimit[hydrogen] = 100. * MeV; << 99 highEnergyLimit[alphaPlus] = 400. * MeV; 84 << 100 85 alphaPlus = alphaPlusDef->GetParticleName(); << 101 helium = heliumDef->GetParticleName(); 86 lowEnergyLimit[alphaPlus] = 1. * keV; << 102 lowEnergyLimit[helium] = 1. * keV; 87 highEnergyLimit[alphaPlus] = 400. * MeV; << 103 highEnergyLimit[helium] = 400. * MeV; 88 << 104 89 helium = heliumDef->GetParticleName(); << 105 // 90 lowEnergyLimit[helium] = 1. * keV; << 106 91 highEnergyLimit[helium] = 400. * MeV; << 107 if (particle==hydrogenDef) 92 << 108 { 93 // << 109 SetLowEnergyLimit(lowEnergyLimit[hydrogen]); 94 << 110 SetHighEnergyLimit(highEnergyLimit[hydrogen]); 95 if (particle==hydrogenDef) << 111 } 96 { << 112 97 SetLowEnergyLimit(lowEnergyLimit[hydrogen] << 113 if (particle==alphaPlusDef) 98 SetHighEnergyLimit(highEnergyLimit[hydroge << 114 { 99 } << 115 SetLowEnergyLimit(lowEnergyLimit[alphaPlus]); 100 << 116 SetHighEnergyLimit(highEnergyLimit[alphaPlus]); 101 if (particle==alphaPlusDef) << 117 } 102 { << 118 103 SetLowEnergyLimit(lowEnergyLimit[alphaPlus << 119 if (particle==heliumDef) 104 SetHighEnergyLimit(highEnergyLimit[alphaPl << 120 { 105 } << 121 SetLowEnergyLimit(lowEnergyLimit[helium]); 106 << 122 SetHighEnergyLimit(highEnergyLimit[helium]); 107 if (particle==heliumDef) << 123 } 108 { << 124 109 SetLowEnergyLimit(lowEnergyLimit[helium]); << 125 // Final state 110 SetHighEnergyLimit(highEnergyLimit[helium] << 126 111 } << 127 //ALPHA+ 112 << 128 113 // Final state << 129 f0[0][0]=1.; 114 << 130 a0[0][0]=2.25; 115 //ALPHA+ << 131 a1[0][0]=-0.75; 116 << 132 b0[0][0]=-32.10; 117 f0[0][0]=1.; << 133 c0[0][0]=0.600; 118 a0[0][0]=2.25; << 134 d0[0][0]=2.40; 119 a1[0][0]=-0.75; << 135 x0[0][0]=4.60; 120 b0[0][0]=-32.10; << 136 121 c0[0][0]=0.600; << 137 x1[0][0]=-1.; 122 d0[0][0]=2.40; << 138 b1[0][0]=-1.; 123 x0[0][0]=4.60; << 139 124 << 140 numberOfPartialCrossSections[0]=1; 125 x1[0][0]=-1.; << 141 126 b1[0][0]=-1.; << 142 //HELIUM 127 << 143 128 numberOfPartialCrossSections[0]=1; << 144 f0[0][1]=1.; 129 << 145 a0[0][1]=2.25; 130 //HELIUM << 146 a1[0][1]=-0.75; 131 << 147 b0[0][1]=-30.93; 132 f0[0][1]=1.; << 148 c0[0][1]=0.590; 133 a0[0][1]=2.25; << 149 d0[0][1]=2.35; 134 a1[0][1]=-0.75; << 150 x0[0][1]=4.29; 135 b0[0][1]=-30.93; << 151 136 c0[0][1]=0.590; << 152 f0[1][1]=1.; 137 d0[0][1]=2.35; << 153 a0[1][1]=2.25; 138 x0[0][1]=4.29; << 154 a1[1][1]=-0.75; 139 << 155 b0[1][1]=-32.61; 140 f0[1][1]=1.; << 156 c0[1][1]=0.435; 141 a0[1][1]=2.25; << 157 d0[1][1]=2.70; 142 a1[1][1]=-0.75; << 158 x0[1][1]=4.45; 143 b0[1][1]=-32.61; << 159 144 c0[1][1]=0.435; << 160 x1[0][1]=-1.; 145 d0[1][1]=2.70; << 161 b1[0][1]=-1.; 146 x0[1][1]=4.45; << 147 << 148 x1[0][1]=-1.; << 149 b1[0][1]=-1.; << 150 << 151 x1[1][1]=-1.; << 152 b1[1][1]=-1.; << 153 << 154 numberOfPartialCrossSections[1]=2; << 155 << 156 // << 157 << 158 if( verboseLevel>0 ) << 159 { << 160 G4cout << "Dingfelder charge increase mode << 161 << "Energy range: " << 162 << LowEnergyLimit() / keV << " keV - " << 163 << HighEnergyLimit() / MeV << " MeV for " << 164 << particle->GetParticleName() << 165 << G4endl; << 166 } << 167 162 168 // Initialize water density pointer << 163 x1[1][1]=-1.; 169 fpMolWaterDensity = G4DNAMolecularMaterial:: << 164 b1[1][1]=-1.; 170 165 171 if (isInitialised) return; << 166 numberOfPartialCrossSections[1]=2; 172 167 173 fParticleChangeForGamma = GetParticleChangeF << 168 // 174 isInitialised = true; << 169 >> 170 if( verboseLevel>0 ) >> 171 { >> 172 G4cout << "Dingfelder charge increase model is initialized " << G4endl >> 173 << "Energy range: " >> 174 << LowEnergyLimit() / keV << " keV - " >> 175 << HighEnergyLimit() / MeV << " MeV for " >> 176 << particle->GetParticleName() >> 177 << G4endl; >> 178 } >> 179 >> 180 // Initialize water density pointer >> 181 fpMolWaterDensity = G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(G4Material::GetMaterial("G4_WATER")); >> 182 >> 183 if (isInitialised) { return; } >> 184 fParticleChangeForGamma = GetParticleChangeForGamma(); >> 185 isInitialised = true; 175 } 186 } 176 187 177 //....oooOO0OOooo........oooOO0OOooo........oo 188 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 178 189 179 G4double G4DNADingfelderChargeIncreaseModel::C 190 G4double G4DNADingfelderChargeIncreaseModel::CrossSectionPerVolume(const G4Material* material, 180 191 const G4ParticleDefinition* particleDefinition, 181 192 G4double k, 182 193 G4double, 183 194 G4double) 184 { 195 { 185 if (verboseLevel > 3) << 196 if (verboseLevel > 3) 186 { << 197 G4cout << "Calling CrossSectionPerVolume() of G4DNADingfelderChargeIncreaseModel" << G4endl; 187 G4cout << 198 188 << "Calling CrossSectionPerVolume() of << 199 // Calculate total cross section for model 189 << G4endl; << 200 190 } << 201 G4DNAGenericIonsManager *instance; 191 << 202 instance = G4DNAGenericIonsManager::Instance(); 192 // Calculate total cross section for model << 203 193 << 204 if ( 194 if ( << 205 particleDefinition != instance->GetIon("hydrogen") 195 particleDefinition != hydrogenDef << 206 && 196 && << 207 particleDefinition != instance->GetIon("alpha+") 197 particleDefinition != alphaPlusDef << 208 && 198 && << 209 particleDefinition != instance->GetIon("helium") 199 particleDefinition != heliumDef << 210 ) 200 ) << 211 201 << 212 return 0; 202 return 0; << 213 203 << 214 G4double lowLim = 0; 204 G4double lowLim = 0; << 215 G4double highLim = 0; 205 G4double highLim = 0; << 216 G4double totalCrossSection = 0.; 206 G4double totalCrossSection = 0.; << 217 207 << 218 G4double waterDensity = (*fpMolWaterDensity)[material->GetIndex()]; 208 G4double waterDensity = (*fpMolWaterDensity) << 219 209 << 220 if(waterDensity!= 0.0) 210 const G4String& particleName = particleDefin << 221 // if (material == nistwater || material->GetBaseMaterial() == nistwater) 211 << 212 std::map< G4String,G4double,std::less<G4Stri << 213 pos1 = lowEnergyLimit.find(particleName); << 214 << 215 if (pos1 != lowEnergyLimit.end()) << 216 { << 217 lowLim = pos1->second; << 218 } << 219 << 220 std::map< G4String,G4double,std::less<G4Stri << 221 pos2 = highEnergyLimit.find(particleName); << 222 << 223 if (pos2 != highEnergyLimit.end()) << 224 { << 225 highLim = pos2->second; << 226 } << 227 << 228 if (k >= lowLim && k <= highLim) << 229 { << 230 //HYDROGEN << 231 if (particleDefinition == hydrogenDef) << 232 { << 233 const G4double aa = 2.835; << 234 const G4double bb = 0.310; << 235 const G4double cc = 2.100; << 236 const G4double dd = 0.760; << 237 const G4double fac = 1.0e-18; << 238 const G4double rr = 13.606 * eV; << 239 << 240 G4double t = k / (proton_mass_c2/electro << 241 G4double x = t / rr; << 242 G4double temp = 4.0 * pi * Bohr_radius/n << 243 G4double sigmal = temp * cc * (gpow->pow << 244 G4double sigmah = temp * (aa * G4Log(1.0 << 245 totalCrossSection = 1.0/(1.0/sigmal + 1. << 246 } << 247 else << 248 { 222 { 249 totalCrossSection = Sum(k,particleDefini << 223 const G4String& particleName = particleDefinition->GetParticleName(); 250 } << 251 } << 252 224 253 if (verboseLevel > 2) << 225 std::map< G4String,G4double,std::less<G4String> >::iterator pos1; 254 { << 226 pos1 = lowEnergyLimit.find(particleName); 255 G4cout << "_______________________________ << 227 256 G4cout << "G4DNADingfelderChargeIncreaseMo << 228 if (pos1 != lowEnergyLimit.end()) 257 G4cout << "Kinetic energy(eV)=" << k/eV << << 229 { 258 G4cout << "Cross section per water molecul << 230 lowLim = pos1->second; 259 G4cout << "Cross section per water molecul << 231 } 260 // G4cout << " - Cross section per water << 232 261 // << sigma*material->GetAtomicNumDensity << 233 std::map< G4String,G4double,std::less<G4String> >::iterator pos2; 262 G4cout << "G4DNADingfelderChargeIncreaseMo << 234 pos2 = highEnergyLimit.find(particleName); 263 } << 235 >> 236 if (pos2 != highEnergyLimit.end()) >> 237 { >> 238 highLim = pos2->second; >> 239 } >> 240 >> 241 if (k >= lowLim && k < highLim) >> 242 { >> 243 //HYDROGEN >> 244 if (particleDefinition == instance->GetIon("hydrogen")) >> 245 { >> 246 const G4double aa = 2.835; >> 247 const G4double bb = 0.310; >> 248 const G4double cc = 2.100; >> 249 const G4double dd = 0.760; >> 250 const G4double fac = 1.0e-18; >> 251 const G4double rr = 13.606 * eV; >> 252 >> 253 G4double t = k / (proton_mass_c2/electron_mass_c2); >> 254 G4double x = t / rr; >> 255 G4double temp = 4.0 * pi * Bohr_radius/nm * Bohr_radius/nm * fac; >> 256 G4double sigmal = temp * cc * (std::pow(x,dd)); >> 257 G4double sigmah = temp * (aa * std::log(1.0 + x) + bb) / x; >> 258 totalCrossSection = 1.0/(1.0/sigmal + 1.0/sigmah) *m*m; >> 259 } >> 260 else >> 261 { >> 262 totalCrossSection = Sum(k,particleDefinition); >> 263 } >> 264 } >> 265 >> 266 if (verboseLevel > 2) >> 267 { >> 268 G4cout << "__________________________________" << G4endl; >> 269 G4cout << "°°° G4DNADingfelderChargeIncreaseModel - XS INFO START" << G4endl; >> 270 G4cout << "°°° Kinetic energy(eV)=" << k/eV << " particle : " << particleName << G4endl; >> 271 G4cout << "°°° Cross section per water molecule (cm^2)=" << totalCrossSection/cm/cm << G4endl; >> 272 G4cout << "°°° Cross section per water molecule (cm^-1)=" << totalCrossSection*waterDensity/(1./cm) << G4endl; >> 273 // G4cout << " - Cross section per water molecule (cm^-1)=" << sigma*material->GetAtomicNumDensityVector()[1]/(1./cm) << G4endl; >> 274 G4cout << "°°° G4DNADingfelderChargeIncreaseModel - XS INFO END" << G4endl; >> 275 } >> 276 >> 277 } 264 278 265 return totalCrossSection*waterDensity; << 279 return totalCrossSection*waterDensity; 266 // return totalCrossSection*material->GetAto << 280 // return totalCrossSection*material->GetAtomicNumDensityVector()[1]; 267 281 268 } 282 } 269 283 270 //....oooOO0OOooo........oooOO0OOooo........oo 284 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.... 271 285 272 void G4DNADingfelderChargeIncreaseModel::Sampl << 286 void G4DNADingfelderChargeIncreaseModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect, 273 << 274 287 const G4MaterialCutsCouple* /*couple*/, 275 288 const G4DynamicParticle* aDynamicParticle, 276 289 G4double, 277 290 G4double) 278 { 291 { 279 if (verboseLevel > 3) << 292 if (verboseLevel > 3) 280 { << 293 G4cout << "Calling SampleSecondaries() of G4DNADingfelderChargeIncreaseModel" << G4endl; 281 G4cout << 282 << "Calling SampleSecondaries() of G4D << 283 << G4endl; << 284 } << 285 << 286 if (!statCode) fParticleChangeForGamma->Prop << 287 << 288 G4ParticleDefinition* definition = aDynamicP << 289 << 290 G4double particleMass = definition->GetPDGMa << 291 << 292 G4double inK = aDynamicParticle->GetKineticE << 293 << 294 G4int finalStateIndex = RandomSelect(inK,def << 295 << 296 G4int n = NumberOfFinalStates(definition,fin << 297 << 298 G4double outK = 0.; << 299 << 300 if (!statCode) outK = inK - IncomingParticle << 301 << 302 else outK = inK; << 303 << 304 if (statCode) << 305 fParticleChangeForGamma-> << 306 ProposeLocalEnergyDeposit(IncomingPartic << 307 << 308 fParticleChangeForGamma->ProposeTrackStatus( << 309 << 310 G4double electronK; << 311 if (definition == hydrogenDef) electronK = i << 312 else electronK = inK*electron_mass_c2/(parti << 313 << 314 if (outK<0) << 315 { << 316 G4Exception("G4DNADingfelderChargeIncrease << 317 FatalException,"Final kinetic energy i << 318 } << 319 << 320 auto dp = new G4DynamicParticle(OutgoingPart << 321 aDynamicParticle->GetMomentumDirection() << 322 outK); << 323 << 324 fvect->push_back(dp); << 325 << 326 n = n - 1; << 327 << 328 while (n>0) << 329 { << 330 n--; << 331 fvect->push_back(new G4DynamicParticle << 332 (G4Electron::Electron(), aDynamicParti << 333 } << 334 } << 335 294 336 //....oooOO0OOooo........oooOO0OOooo........oo << 295 fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill); >> 296 fParticleChangeForGamma->ProposeLocalEnergyDeposit(0.); 337 297 338 G4int G4DNADingfelderChargeIncreaseModel::Numb << 298 G4ParticleDefinition* definition = aDynamicParticle->GetDefinition(); 339 << 340 299 341 { << 300 G4double particleMass = definition->GetPDGMass(); >> 301 >> 302 G4double inK = aDynamicParticle->GetKineticEnergy(); >> 303 >> 304 G4int finalStateIndex = RandomSelect(inK,definition); >> 305 >> 306 G4int n = NumberOfFinalStates(definition,finalStateIndex); 342 307 343 if (particleDefinition == hydrogenDef) << 308 G4double outK = inK - IncomingParticleBindingEnergyConstant(definition,finalStateIndex); 344 return 2; << 345 309 346 if (particleDefinition == alphaPlusDef) << 310 G4DNAGenericIonsManager* instance; 347 return 2; << 311 instance = G4DNAGenericIonsManager::Instance(); 348 312 349 if (particleDefinition == heliumDef) << 313 G4double electronK; 350 { << 314 if (definition == instance->GetIon("hydrogen")) electronK = inK*electron_mass_c2/proton_mass_c2; 351 if (finalStateIndex == 0) << 315 else electronK = inK*electron_mass_c2/(particleMass); 352 return 2; << 316 353 return 3; << 317 if (outK<0) 354 } << 318 { >> 319 G4Exception("G4DNADingfelderChargeIncreaseModel::SampleSecondaries","em0004", >> 320 FatalException,"Final kinetic energy is negative."); >> 321 } >> 322 >> 323 G4DynamicParticle* dp = new G4DynamicParticle >> 324 >> 325 (OutgoingParticleDefinition(definition,finalStateIndex), >> 326 aDynamicParticle->GetMomentumDirection(), >> 327 outK) ; >> 328 >> 329 fvect->push_back(dp); >> 330 >> 331 n = n - 1; >> 332 >> 333 while (n>0) >> 334 { >> 335 n--; >> 336 fvect->push_back(new G4DynamicParticle >> 337 (G4Electron::Electron(), aDynamicParticle->GetMomentumDirection(), electronK) ); >> 338 } 355 339 356 return 0; << 357 } 340 } 358 341 359 //....oooOO0OOooo........oooOO0OOooo........oo 342 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 360 343 361 G4ParticleDefinition* G4DNADingfelderChargeInc << 344 G4int G4DNADingfelderChargeIncreaseModel::NumberOfFinalStates(G4ParticleDefinition* particleDefinition, 362 << 345 G4int finalStateIndex ) 363 { << 364 346 365 if (particleDefinition == hydrogenDef) << 347 { 366 return G4Proton::Proton(); << 348 G4DNAGenericIonsManager* instance; >> 349 instance = G4DNAGenericIonsManager::Instance(); >> 350 if (particleDefinition == instance->GetIon("hydrogen")) return 2; >> 351 if (particleDefinition == instance->GetIon("alpha+")) return 2; >> 352 >> 353 if (particleDefinition == instance->GetIon("helium")) >> 354 { if (finalStateIndex==0) return 2; >> 355 return 3; >> 356 } >> 357 return 0; >> 358 } 367 359 368 if (particleDefinition == alphaPlusDef) << 360 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 369 return alphaPlusPlusDef; << 370 361 371 if (particleDefinition == heliumDef) << 362 G4ParticleDefinition* G4DNADingfelderChargeIncreaseModel::OutgoingParticleDefinition (G4ParticleDefinition* particleDefinition, 372 { << 363 G4int finalStateIndex) 373 if (finalStateIndex == 0) << 364 { 374 return alphaPlusDef; << 365 G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance()); 375 return alphaPlusPlusDef; << 366 if (particleDefinition == instance->GetIon("hydrogen")) return G4Proton::Proton(); 376 } << 367 if (particleDefinition == instance->GetIon("alpha+")) return instance->GetIon("alpha++"); 377 368 378 return nullptr; << 369 if (particleDefinition == instance->GetIon("helium")) >> 370 { >> 371 if (finalStateIndex==0) return instance->GetIon("alpha+"); >> 372 return instance->GetIon("alpha++"); >> 373 } >> 374 return 0; 379 } 375 } 380 376 381 //....oooOO0OOooo........oooOO0OOooo........oo 377 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 382 378 383 G4double G4DNADingfelderChargeIncreaseModel::I << 379 G4double G4DNADingfelderChargeIncreaseModel::IncomingParticleBindingEnergyConstant(G4ParticleDefinition* particleDefinition, 384 << 380 G4int finalStateIndex ) 385 { 381 { >> 382 G4DNAGenericIonsManager * instance(G4DNAGenericIonsManager::Instance()); >> 383 if(particleDefinition == instance->GetIon("hydrogen")) return 13.6*eV; >> 384 >> 385 if(particleDefinition == instance->GetIon("alpha+")) >> 386 { >> 387 // Binding energy for He+ -> He++ + e- 54.509 eV >> 388 // Binding energy for He -> He+ + e- 24.587 eV >> 389 return 54.509*eV; >> 390 } 386 391 387 if (particleDefinition == hydrogenDef) << 392 if(particleDefinition == instance->GetIon("helium")) 388 return 13.6 * eV; << 393 { >> 394 // Binding energy for He+ -> He++ + e- 54.509 eV >> 395 // Binding energy for He -> He+ + e- 24.587 eV 389 396 390 if (particleDefinition == alphaPlusDef) << 397 if (finalStateIndex==0) return 24.587*eV; 391 { << 398 return (54.509 + 24.587)*eV; 392 // Binding energy for He+ -> He++ + e- << 399 } 393 // Binding energy for He -> He+ + e- << 394 return 54.509 * eV; << 395 } << 396 << 397 if (particleDefinition == heliumDef) << 398 { << 399 // Binding energy for He+ -> He++ + e- << 400 // Binding energy for He -> He+ + e- << 401 << 402 if (finalStateIndex == 0) << 403 return 24.587 * eV; << 404 return (54.509 + 24.587) * eV; << 405 } << 406 400 407 return 0; << 401 return 0; 408 } 402 } 409 403 410 //....oooOO0OOooo........oooOO0OOooo........oo 404 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 411 405 412 G4double G4DNADingfelderChargeIncreaseModel::P << 406 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 413 << 407 >> 408 G4double G4DNADingfelderChargeIncreaseModel::PartialCrossSection(G4double k, G4int index, 414 409 const G4ParticleDefinition* particleDefinition) 415 { 410 { 416 G4int particleTypeIndex = 0; << 417 << 418 if (particleDefinition == alphaPlusDef) << 419 particleTypeIndex = 0; << 420 411 421 if (particleDefinition == heliumDef) << 412 G4int particleTypeIndex = 0; 422 particleTypeIndex = 1; << 413 G4DNAGenericIonsManager *instance; >> 414 instance = G4DNAGenericIonsManager::Instance(); 423 415 424 // << 416 if (particleDefinition == instance->GetIon("alpha+")) particleTypeIndex=0; 425 // sigma(T) = f0 10 ^ y(log10(T/eV)) << 417 if (particleDefinition == instance->GetIon("helium")) particleTypeIndex=1; 426 // << 427 // / a0 x + b0 x << 428 // | << 429 // y(x) = < a0 x + b0 - c0 (x - x0)^d0 x << 430 // | << 431 // \ a1 x + b1 x << 432 // << 433 // << 434 // f0, a0, a1, b0, b1, c0, d0, x0, x1 are pa << 435 // << 436 // f0 has been added to the code in order to << 437 // (if no shell dependence is present. f0=1. << 438 // << 439 // From Rad. Phys. and Chem. 59 (2000) 255-2 << 440 // Inelastic-collision cross sections of liq << 441 // << 442 418 443 if (x1[index][particleTypeIndex] < x0[index] << 444 { << 445 // 419 // 446 // if x1 < x0 means that x1 and b1 will be << 420 // sigma(T) = f0 10 ^ y(log10(T/eV)) 447 // (this piece of code is run on all alpha << 421 // >> 422 // / a0 x + b0 x < x0 >> 423 // | >> 424 // y(x) = < a0 x + b0 - c0 (x - x0)^d0 x0 <= x < x1 >> 425 // | >> 426 // \ a1 x + b1 x >= x1 >> 427 // >> 428 // >> 429 // f0, a0, a1, b0, b1, c0, d0, x0, x1 are parameters that change for protons and helium (0, +, ++) 448 // 430 // 449 // x1 = x0 + ((a0 - a1)/(c0 * d0)) ^ (1 / << 431 // f0 has been added to the code in order to manage partial (shell-dependent) cross sections (if no shell dependence is present. f0=1. Sum of f0 over the considered shells should give 1) 450 // 432 // 451 // b1 = (a0 - a1) * x1 + b0 - c0 * (x1 - x << 433 // From Rad. Phys. and Chem. 59 (2000) 255-275, M. Dingfelder et al. >> 434 // Inelastic-collision cross sections of liquid water for interactions of energetic proton 452 // 435 // 453 436 454 x1[index][particleTypeIndex] = x0[index][p << 437 if (x1[index][particleTypeIndex]<x0[index][particleTypeIndex]) 455 + gpow->powA((a0[index][particleTypeIn << 438 { 456 / (c0[index][particleTy << 439 // 457 * d0[index][particl << 440 // if x1 < x0 means that x1 and b1 will be calculated with the following formula (this piece of code is run on all alphas and not on protons) 458 1. / (d0[index][particleTyp << 441 // 459 b1[index][particleTypeIndex] = (a0[index][ << 442 // x1 = x0 + ((a0 - a1)/(c0 * d0)) ^ (1 / (d0 - 1)) 460 - a1[index][particleTypeIndex]) * x1[i << 443 // 461 + b0[index][particleTypeIndex] << 444 // b1 = (a0 - a1) * x1 + b0 - c0 * (x1 - x0) ^ d0 462 - c0[index][particleTypeIndex] << 445 // 463 * gpow->powA(x1[index][particleTyp << 446 464 - x0[index][particl << 447 x1[index][particleTypeIndex]=x0[index][particleTypeIndex] + std::pow((a0[index][particleTypeIndex] - a1[index][particleTypeIndex]) / (c0[index][particleTypeIndex] * d0[index][particleTypeIndex]), 1. / (d0[index][particleTypeIndex] - 1.)); 465 d0[index][particleTypeI << 448 b1[index][particleTypeIndex]=(a0[index][particleTypeIndex] - a1[index][particleTypeIndex]) * x1[index][particleTypeIndex] + b0[index][particleTypeIndex] - c0[index][particleTypeIndex] * std::pow(x1[index][particleTypeIndex] - x0[index][particleTypeIndex], d0[index][particleTypeIndex]); 466 } << 449 } 467 << 450 468 G4double x(G4Log(k / eV)/gpow->logZ(10)); << 451 G4double x(std::log10(k/eV)); 469 G4double y; << 452 G4double y; 470 << 453 471 if (x < x0[index][particleTypeIndex]) << 454 if (x<x0[index][particleTypeIndex]) 472 y = a0[index][particleTypeIndex] * x + b0[ << 455 y=a0[index][particleTypeIndex] * x + b0[index][particleTypeIndex]; 473 else if (x < x1[index][particleTypeIndex]) << 456 else if (x<x1[index][particleTypeIndex]) 474 y = a0[index][particleTypeIndex] * x + b0[ << 457 y=a0[index][particleTypeIndex] * x + b0[index][particleTypeIndex] - c0[index][particleTypeIndex] * std::pow(x - x0[index][particleTypeIndex], d0[index][particleTypeIndex]); 475 - c0[index][particleTypeIndex] << 458 else 476 * gpow->powA(x - x0[index][particl << 459 y=a1[index][particleTypeIndex] * x + b1[index][particleTypeIndex]; 477 d0[index][particleTypeI << 478 else << 479 y = a1[index][particleTypeIndex] * x + b1[ << 480 460 481 return f0[index][particleTypeIndex] * gpow-> << 461 return f0[index][particleTypeIndex] * std::pow(10., y)*m*m; 482 462 483 } 463 } 484 464 485 //....oooOO0OOooo........oooOO0OOooo........oo 465 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 486 466 487 G4int G4DNADingfelderChargeIncreaseModel::Rand << 467 G4int G4DNADingfelderChargeIncreaseModel::RandomSelect(G4double k, 488 468 const G4ParticleDefinition* particleDefinition) 489 { 469 { 490 G4int particleTypeIndex = 0; << 491 470 492 if (particleDefinition == hydrogenDef) << 471 G4int particleTypeIndex = 0; 493 return 0; << 472 G4DNAGenericIonsManager *instance; 494 << 473 instance = G4DNAGenericIonsManager::Instance(); 495 if (particleDefinition == alphaPlusDef) << 474 496 particleTypeIndex = 0; << 475 if (particleDefinition == instance->GetIon("hydrogen")) return 0; 497 << 476 if (particleDefinition == instance->GetIon("alpha+")) particleTypeIndex=0; 498 if (particleDefinition == heliumDef) << 477 if (particleDefinition == instance->GetIon("helium")) particleTypeIndex=1; 499 particleTypeIndex = 1; << 478 >> 479 const G4int n = numberOfPartialCrossSections[particleTypeIndex]; >> 480 G4double* values(new G4double[n]); >> 481 G4double value = 0; >> 482 G4int i = n; 500 483 501 const G4int n = numberOfPartialCrossSections << 484 while (i>0) 502 auto values(new G4double[n]); << 485 { 503 G4double value = 0; << 486 i--; 504 G4int i = n; << 487 values[i]=PartialCrossSection(k, i, particleDefinition); 505 << 488 value+=values[i]; 506 while (i > 0) << 489 } 507 { << 508 i--; << 509 values[i] = PartialCrossSection(k, i, part << 510 value += values[i]; << 511 } << 512 490 513 value *= G4UniformRand(); << 491 value*=G4UniformRand(); 514 492 515 i = n; << 493 i=n; 516 while (i > 0) << 494 while (i>0) 517 { << 495 { 518 i--; << 496 i--; 519 497 520 if (values[i] > value) << 498 if (values[i]>value) 521 break; << 499 break; 522 500 523 value -= values[i]; << 501 value-=values[i]; 524 } << 502 } 525 503 526 delete[] values; << 504 delete[] values; 527 505 528 return i; << 506 return i; 529 } 507 } 530 508 531 //....oooOO0OOooo........oooOO0OOooo........oo 509 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 532 510 533 G4double G4DNADingfelderChargeIncreaseModel::S << 511 G4double G4DNADingfelderChargeIncreaseModel::Sum(G4double k, const G4ParticleDefinition* particleDefinition) 534 << 535 { 512 { 536 G4int particleTypeIndex = 0; << 513 G4int particleTypeIndex = 0; 537 << 514 G4DNAGenericIonsManager *instance; 538 if (particleDefinition == alphaPlusDef) << 515 instance = G4DNAGenericIonsManager::Instance(); 539 particleTypeIndex = 0; << 540 516 541 if (particleDefinition == heliumDef) << 517 if (particleDefinition == instance->GetIon("alpha+")) particleTypeIndex=0; 542 particleTypeIndex = 1; << 518 if (particleDefinition == instance->GetIon("helium")) particleTypeIndex=1; 543 519 544 G4double totalCrossSection = 0.; << 520 G4double totalCrossSection = 0.; 545 521 546 for (G4int i = 0; i < numberOfPartialCrossSe << 522 for (G4int i=0; i<numberOfPartialCrossSections[particleTypeIndex]; i++) 547 { << 523 { 548 totalCrossSection += PartialCrossSection(k << 524 totalCrossSection += PartialCrossSection(k,i,particleDefinition); 549 } << 525 } 550 << 526 return totalCrossSection; 551 return totalCrossSection; << 552 } 527 } 553 528