Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // 27 28 // Created by Z. Francis 29 30 #include "G4DNASancheExcitationModel.hh" 31 #include "G4SystemOfUnits.hh" 32 #include "G4DNAMolecularMaterial.hh" 33 34 //....oooOO0OOooo........oooOO0OOooo........oo 35 36 using namespace std; 37 38 //#define SANCHE_VERBOSE 39 40 //....oooOO0OOooo........oooOO0OOooo........oo 41 42 G4DNASancheExcitationModel::G4DNASancheExcitat 43 44 G4VEmModel(nam) 45 { 46 fpWaterDensity = nullptr; 47 48 SetLowEnergyLimit(2.*eV); 49 SetHighEnergyLimit(100*eV); 50 nLevels = 9; 51 52 verboseLevel = 0; 53 // Verbosity scale: 54 // 0 = nothing 55 // 1 = warning for energy non-conservation 56 // 2 = details of energy budget 57 // 3 = calculation of cross sections, file o 58 // 4 = entering in methods 59 60 #ifdef SANCHE_VERBOSE 61 if (verboseLevel > 0) 62 { 63 G4cout << "Sanche Excitation model is cons 64 << G4endl 65 << "Energy range: " 66 << LowEnergyLimit() / eV << " eV - 67 << HighEnergyLimit() / eV << " eV" 68 << G4endl; 69 } 70 #endif 71 72 fParticleChangeForGamma = nullptr; 73 fpWaterDensity = nullptr; 74 75 // Selection of stationary mode 76 77 statCode = false; 78 } 79 80 //....oooOO0OOooo........oooOO0OOooo........oo 81 82 G4DNASancheExcitationModel::~G4DNASancheExcita 83 = default; 84 85 //....oooOO0OOooo........oooOO0OOooo........oo 86 87 void 88 G4DNASancheExcitationModel:: 89 Initialise(const G4ParticleDefinition* /*parti 90 const G4DataVector& /*cuts*/) 91 { 92 93 #ifdef SANCHE_VERBOSE 94 if (verboseLevel > 3) 95 { 96 G4cout << "Calling G4DNASancheExcitationMo 97 << G4endl; 98 } 99 #endif 100 101 // Energy limits 102 103 if (LowEnergyLimit() < 2.*eV) 104 { 105 G4Exception("*** WARNING : the G4DNASanche 106 "validated below 2 eV !", 107 "", JustWarning, ""); 108 } 109 110 if (HighEnergyLimit() > 100.*eV) 111 { 112 G4cout << "G4DNASancheExcitationModel: hig 113 HighEnergyLimit()/eV << " eV to " << 100. 114 SetHighEnergyLimit(100.*eV); 115 } 116 117 // 118 #ifdef SANCHE_VERBOSE 119 if (verboseLevel > 0) 120 { 121 G4cout << "Sanche Excitation model is init 122 << "Energy range: " 123 << LowEnergyLimit() / eV << " eV - " 124 << HighEnergyLimit() / eV << " eV" 125 << G4endl; 126 } 127 #endif 128 129 // Initialize water density pointer 130 fpWaterDensity = G4DNAMolecularMaterial::Ins 131 GetNumMolPerVolTableFor(G4Material::GetM 132 133 if (isInitialised) {return;} 134 135 fParticleChangeForGamma = GetParticleChangeF 136 isInitialised = true; 137 138 const char *path = G4FindDataDir("G4LEDATA") 139 std::ostringstream eFullFileName; 140 eFullFileName << path << "/dna/sigma_excitat 141 std::ifstream input(eFullFileName.str().c_st 142 143 if (!input) 144 { 145 G4Exception("G4DNASancheExcitationModel::I 146 FatalException,"Missing data file:/dna 147 } 148 149 // March 25th, 2014 - Vaclav Stepan, Sebasti 150 // Added clear for MT 151 tdummyVec.clear(); 152 // 153 154 G4double t; 155 G4double xs; 156 157 while(!input.eof()) 158 { 159 input>>t; 160 tdummyVec.push_back(t); 161 162 fEnergyLevelXS.emplace_back(); 163 fEnergyTotalXS.push_back(0); 164 std::vector<G4double>& levelXS = fEnergyLe 165 levelXS.reserve(9); 166 167 // G4cout<<t; 168 169 for(size_t i = 0 ; i < 9 ;++i) 170 { 171 input>>xs; 172 levelXS.push_back(xs); 173 fEnergyTotalXS.back() += xs; 174 // G4cout <<" " << levelXS[i]; 175 } 176 177 // G4cout << G4endl; 178 } 179 } 180 181 //....oooOO0OOooo........oooOO0OOooo........oo 182 183 G4double G4DNASancheExcitationModel::CrossSect 184 185 #ifdef SANCHE_VERBOSE 186 187 #endif 188 189 190 191 192 { 193 #ifdef SANCHE_VERBOSE 194 if (verboseLevel > 3) 195 { 196 G4cout << "Calling CrossSectionPerVolume() 197 << G4endl; 198 } 199 #endif 200 201 // Calculate total cross section for model 202 203 G4double sigma = 0.; 204 205 G4double waterDensity = (*fpWaterDensity)[ma 206 207 if (ekin >= LowEnergyLimit() && ekin <= High 208 sigma = TotalCrossSection(ekin); 209 210 #ifdef SANCHE_VERBOSE 211 if (verboseLevel > 2) 212 { 213 G4cout << "_______________________________ 214 G4cout << "=== G4DNASancheExcitationModel 215 G4cout << "=== Kinetic energy(eV)=" << eki 216 G4cout << "=== Cross section per water mol 217 G4cout << "=== Cross section per water mol 218 G4cout << "=== G4DNASancheExcitationModel 219 } 220 #endif 221 222 return sigma*2.*waterDensity; 223 // see papers for factor 2 description (liqu 224 } 225 226 //....oooOO0OOooo........oooOO0OOooo........oo 227 228 void G4DNASancheExcitationModel::SampleSeconda 229 230 231 232 233 234 { 235 #ifdef SANCHE_VERBOSE 236 if (verboseLevel > 3) 237 { 238 G4cout << "Calling SampleSecondaries() of 239 << G4endl; 240 } 241 #endif 242 243 G4double electronEnergy0 = aDynamicElectron- 244 G4int level = RandomSelect(electronEnergy0); 245 G4double excitationEnergy = VibrationEnergy( 246 G4double newEnergy = electronEnergy0 - excit 247 248 /* 249 if (electronEnergy0 < highEnergyLimit) 250 { 251 if (newEnergy >= lowEnergyLimit) 252 { 253 fParticleChangeForGamma->ProposeMomentu 254 fParticleChangeForGamma->SetProposedKin 255 fParticleChangeForGamma->ProposeLocalEn 256 } 257 258 else 259 { 260 fParticleChangeForGamma->ProposeTrackSt 261 fParticleChangeForGamma->ProposeLocalEn 262 } 263 } 264 */ 265 266 if (electronEnergy0 <= HighEnergyLimit() && 267 { 268 269 if (!statCode) 270 { 271 fParticleChangeForGamma->ProposeMomentum 272 fParticleChangeForGamma->SetProposedKine 273 fParticleChangeForGamma->ProposeLocalEne 274 } 275 276 else 277 { 278 fParticleChangeForGamma->ProposeMomentum 279 fParticleChangeForGamma->SetProposedKine 280 fParticleChangeForGamma->ProposeLocalEne 281 } 282 283 } 284 285 // 286 } 287 288 //....oooOO0OOooo........oooOO0OOooo........oo 289 290 G4double G4DNASancheExcitationModel::PartialCr 291 292 { 293 // Protection against out of boundary access 294 if (t/eV==tdummyVec.back()) t=t*(1.-1e-12); 295 // 296 297 auto t2 = std::upper_bound(tdummyVec.begin() 298 299 auto t1 = t2 - 1; 300 301 size_t i1 = t1 - tdummyVec.begin(); 302 size_t i2 = t2 - tdummyVec.begin(); 303 304 G4double sigma = LinInterpolate((*t1), (*t2) 305 t / eV, 306 fEnergyLevelXS 307 fEnergyLevelXS 308 309 static const G4double conv_factor = 1e-16 * 310 311 sigma *= conv_factor; 312 if (sigma == 0.) sigma = 1e-30; 313 return (sigma); 314 } 315 316 //....oooOO0OOooo........oooOO0OOooo........oo 317 318 G4double G4DNASancheExcitationModel::TotalCros 319 { 320 // Protection against out of boundary access 321 if (t/eV==tdummyVec.back()) t=t*(1.-1e-12); 322 // 323 324 auto t2 = std::upper_bound(tdummyVec.begin() 325 326 auto t1 = t2 - 1; 327 328 size_t i1 = t1 - tdummyVec.begin(); 329 size_t i2 = t2 - tdummyVec.begin(); 330 331 G4double sigma = LinInterpolate((*t1), (*t2) 332 t / eV, 333 fEnergyTotalXS 334 fEnergyTotalXS 335 336 static const G4double conv_factor = 1e-16 * 337 338 sigma *= conv_factor; 339 if (sigma == 0.) sigma = 1e-30; 340 return (sigma); 341 } 342 343 //....oooOO0OOooo........oooOO0OOooo........oo 344 345 G4double G4DNASancheExcitationModel::Vibration 346 { 347 static G4double energies[9] = { 0.01, 0.024, 348 0.500, 0.835 }; 349 return (energies[level] * eV); 350 } 351 352 //....oooOO0OOooo........oooOO0OOooo........oo 353 354 G4int G4DNASancheExcitationModel::RandomSelect 355 { 356 357 // Level Selection Counting can be done here 358 359 G4int i = nLevels; 360 G4double value = 0.; 361 std::deque<G4double> values; 362 363 while (i > 0) 364 { 365 i--; 366 G4double partial = PartialCrossSection(k, 367 values.push_front(partial); 368 value += partial; 369 } 370 371 value *= G4UniformRand(); 372 373 i = nLevels; 374 375 while (i > 0) 376 { 377 i--; 378 if (values[i] > value) 379 { 380 //outcount<<i<<" "<<VibrationEnergy(i)< 381 return i; 382 } 383 value -= values[i]; 384 } 385 386 //outcount<<0<<" "<<VibrationEnergy(0)<<G4e 387 388 return 0; 389 } 390 391 //....oooOO0OOooo........oooOO0OOooo........oo 392 393 G4double G4DNASancheExcitationModel::Sum(G4dou 394 { 395 G4double totalCrossSection = 0.; 396 397 for (G4int i = 0; i < nLevels; i++) 398 { 399 totalCrossSection += PartialCrossSection(k 400 } 401 402 return totalCrossSection; 403 } 404 405 //....oooOO0OOooo........oooOO0OOooo........oo 406 407 G4double G4DNASancheExcitationModel::LinInterp 408 409 410 411 412 { 413 G4double a = (xs2 - xs1) / (e2 - e1); 414 G4double b = xs2 - a * e2; 415 G4double value = a * e + b; 416 // G4cout<<"interP >> "<<e1<<" "<<e2<<" " 417 // <<xs1<<" "<<xs2<<" "<<a<<" "<<b<<" "< 418 419 return value; 420 } 421 422