Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4INCLParticleTable.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// INCL++ intra-nuclear cascade model
27// Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
28// Davide Mancusi, CEA
29// Alain Boudard, CEA
30// Sylvie Leray, CEA
31// Joseph Cugnon, University of Liege
32//
33// INCL++ revision: v5.1.8
34//
35#define INCLXX_IN_GEANT4_MODE 1
36
37#include "globals.hh"
38
40#include "G4SystemOfUnits.hh"
41
42#include <algorithm>
43// #include <cassert>
44#include <cmath>
45#include <cctype>
46#include <sstream>
47
48namespace G4INCL {
49
50 /// \brief Static instance of the NaturalIsotopicAbundances class
51 const NaturalIsotopicDistributions *ParticleTable::theNaturalIsotopicDistributions = NULL;
52
53 /// \brief Static pointer to the mass function for nuclei
55 /// \brief Static pointer to the mass function for particles
57 /// \brief Static pointer to the separation-energy function
59
60 const G4double ParticleTable::theINCLNucleonMass = 938.2796;
61 const G4double ParticleTable::theINCLPionMass = 138.0;
62 G4double ParticleTable::protonMass = 0.0;
63 G4double ParticleTable::neutronMass = 0.0;
64 G4double ParticleTable::piPlusMass = 0.0;
65 G4double ParticleTable::piMinusMass = 0.0;
66 G4double ParticleTable::piZeroMass = 0.0;
67
68 // e^2/(4 pi epsilon_0) [MeV fm]
69 const G4double ParticleTable::eSquared = 1.439964;
70
71 // Hard-coded values of the real particle masses (MeV/c^2)
72 G4double ParticleTable::theRealProtonMass = 938.27203;
73 G4double ParticleTable::theRealNeutronMass = 939.56536;
74 G4double ParticleTable::theRealChargedPiMass = 139.57018;
75 G4double ParticleTable::theRealPiZeroMass = 134.9766;
76
77 const G4double ParticleTable::mediumDiffuseness[mediumNucleiTableSize] =
78 {0.0,0.0,0.0,0.0,0.0,1.78,1.77,1.77,1.77,1.71,
79 1.69,1.69,1.635,1.730,1.81,1.833,1.798,
80 1.841,0.567,0.571, 0.560,0.549,0.550,0.551,
81 0.580,0.575,0.569,0.537,0.0,0.0};
82 const G4double ParticleTable::mediumRadius[mediumNucleiTableSize] =
83 {0.0,0.0,0.0,0.0,0.0,0.334,0.327,0.479,0.631,0.838,
84 0.811,1.07,1.403,1.335,1.25,1.544,1.498,1.513,
85 2.58,2.77, 2.775,2.78,2.88,2.98,3.22,3.03,2.84,
86 3.14,0.0,0.0};
87 const G4double ParticleTable::positionRMS[clusterTableZSize][clusterTableASize] = {
88/* A= 0 1 2 3 4 5 6 7 8 9 10 11 12 */
89/* Z=0 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
90/* Z=1 */ {0.00, 0.00, 2.10, 1.80, 1.70, 1.83, 2.60, 2.50, 0.00, 0.00, 0.00, 0.00, 0.00},
91/* Z=2 */ {0.00, 0.00, 0.00, 1.80, 1.68, 1.70, 2.60, 2.50, 2.50, 2.50, 2.50, 0.00, 0.00},
92/* Z=3 */ {0.00, 0.00, 0.00, 0.00, 1.70, 1.83, 2.56, 2.40, 2.50, 2.50, 2.50, 2.50, 2.50},
93/* Z=4 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.60, 2.50, 2.50, 2.51, 2.50, 2.50, 2.50},
94/* Z=5 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.50, 2.50, 2.50, 2.50, 2.45, 2.40, 2.50},
95/* Z=6 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.50, 2.50, 2.50, 2.50, 2.47},
96/* Z=7 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.50, 2.50, 2.50},
97/* Z=8 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 2.50}
98 };
99
100 const G4double ParticleTable::momentumRMS[clusterTableZSize][clusterTableASize] = {
101/* A= 0 1 2 3 4 5 6 7 8 9 10 11 12 */
102/* Z=0 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
103/* Z=1 */ {0.00, 0.00, 77.0, 110., 153., 100., 100., 100., 0.00, 0.00, 0.00, 0.00, 0.00},
104/* Z=2 */ {0.00, 0.00, 0.00, 110., 153., 100., 100., 100., 100., 100., 100., 0.00, 0.00},
105/* Z=3 */ {0.00, 0.00, 0.00, 0.00, 153., 100., 100., 100., 100., 100., 100., 100., 100.},
106/* Z=4 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100., 100., 100., 100., 100.},
107/* Z=5 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100., 100., 100., 100., 100.},
108/* Z=6 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100., 100., 100.},
109/* Z=7 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100., 100., 100.},
110/* Z=8 */ {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 100.}
111 };
112
113 /// \brief Table of chemical element names
114 const std::string ParticleTable::elementTable[elementTableSize] = {
115 "",
116 "H",
117 "He",
118 "Li",
119 "Be",
120 "B",
121 "C",
122 "N",
123 "O",
124 "F",
125 "Ne",
126 "Na",
127 "Mg",
128 "Al",
129 "Si",
130 "P",
131 "S",
132 "Cl",
133 "Ar",
134 "K",
135 "Ca",
136 "Sc",
137 "Ti",
138 "V",
139 "Cr",
140 "Mn",
141 "Fe",
142 "Co",
143 "Ni",
144 "Cu",
145 "Zn",
146 "Ga",
147 "Ge",
148 "As",
149 "Se",
150 "Br",
151 "Kr",
152 "Rb",
153 "Sr",
154 "Y",
155 "Zr",
156 "Nb",
157 "Mo",
158 "Tc",
159 "Ru",
160 "Rh",
161 "Pd",
162 "Ag",
163 "Cd",
164 "In",
165 "Sn",
166 "Sb",
167 "Te",
168 "I",
169 "Xe",
170 "Cs",
171 "Ba",
172 "La",
173 "Ce",
174 "Pr",
175 "Nd",
176 "Pm",
177 "Sm",
178 "Eu",
179 "Gd",
180 "Tb",
181 "Dy",
182 "Ho",
183 "Er",
184 "Tm",
185 "Yb",
186 "Lu",
187 "Hf",
188 "Ta",
189 "W",
190 "Re",
191 "Os",
192 "Ir",
193 "Pt",
194 "Au",
195 "Hg",
196 "Tl",
197 "Pb",
198 "Bi",
199 "Po",
200 "At",
201 "Rn",
202 "Fr",
203 "Ra",
204 "Ac",
205 "Th",
206 "Pa",
207 "U",
208 "Np",
209 "Pu",
210 "Am",
211 "Cm",
212 "Bk",
213 "Cf",
214 "Es",
215 "Fm",
216 "Md",
217 "No",
218 "Lr",
219 "Rf",
220 "Db",
221 "Sg",
222 "Bh",
223 "Hs",
224 "Mt",
225 "Ds",
226 "Rg",
227 "Cn"
228 };
229
230 /// \brief Digit names to compose IUPAC element names
231 const std::string ParticleTable::elementIUPACDigits = "nubtqphsoe";
232
233 /* Table for cluster decays
234 * Definition of "Stable": halflife > 1 ms
235 *
236 * These table includes decay data for clusters that INCL presently does
237 * not produce. It can't hurt.
238 *
239 * Unphysical nuclides (A<Z) are marked as stable, but should never be
240 * produced by INCL. If you find them in the output, something is fishy.
241 */
242 const ParticleTable::ClusterDecayType ParticleTable::clusterDecayMode[clusterTableZSize][clusterTableASize] =
243 {
244/* A = 0 1 2 3 4 5 6 7 8 9 10 11 12 */
245/* Z = 0 */ {StableCluster, StableCluster, NeutronDecay, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound},
246/* Z = 1 */ {StableCluster, StableCluster, StableCluster, StableCluster, NeutronDecay, TwoNeutronDecay, NeutronDecay, TwoNeutronDecay, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound, NeutronUnbound},
247/* Z = 2 */ {StableCluster, StableCluster, ProtonDecay, StableCluster, StableCluster, NeutronDecay, StableCluster, NeutronDecay, StableCluster, NeutronDecay, TwoNeutronDecay, NeutronUnbound, NeutronUnbound},
248/* Z = 3 */ {StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonDecay, ProtonDecay, StableCluster, StableCluster, StableCluster, StableCluster, NeutronDecay, StableCluster, NeutronDecay},
249/* Z = 4 */ {StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonDecay, TwoProtonDecay, StableCluster, AlphaDecay, StableCluster, StableCluster, StableCluster, StableCluster},
250/* Z = 5 */ {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, TwoProtonDecay, ProtonDecay, StableCluster, ProtonDecay, StableCluster, StableCluster, StableCluster},
251/* Z = 6 */ {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, TwoProtonDecay, StableCluster, StableCluster, StableCluster, StableCluster},
252/* Z = 7 */ {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonDecay, ProtonDecay, StableCluster},
253/* Z = 8 */ {StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, StableCluster, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonUnbound, ProtonDecay}
254 };
255
256 /**
257 * Precomputed factor 1.0/A
258 */
259 const G4double ParticleTable::clusterPosFact[maxClusterMass+1] = {0.0, 1.0, 0.5,
260 0.33333, 0.25,
261 0.2, 0.16667,
262 0.14286, 0.125,
263 0.11111, 0.1,
264 0.09091, 0.083333};
265
266 /**
267 * Precomputed factor (1.0/A)^2
268 */
269 const G4double ParticleTable::clusterPosFact2[maxClusterMass+1] = {0.0, 1.0, 0.25,
270 0.11111, 0.0625,
271 0.04, 0.0277778,
272 0.020408, 0.015625,
273 0.012346, 0.01,
274 0.0082645, 0.0069444};
275
276 const G4int ParticleTable::clusterZMin[maxClusterMass+1] = {0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3};
277 const G4int ParticleTable::clusterZMax[maxClusterMass+1] = {0, 0, 1, 2, 3, 3, 5, 5, 6, 6, 7, 7, 8};
278 const G4double ParticleTable::clusterPhaseSpaceCut[maxClusterMass+1] = {0.0, 70000.0, 180000.0,
279 90000.0, 90000.0,
280 128941.0 ,145607.0,
281 161365.0, 176389.0,
282 190798.0, 204681.0,
283 218109.0, 231135.0};
285 const G4double ParticleTable::effectiveNucleonMass2 = 8.8036860777616e5;
289 ParticleTable::theRealNeutronMass + ParticleTable::theRealChargedPiMass
290 + 0.5;
291 const G4double ParticleTable::theINCLProtonSeparationEnergy = 6.83;
292 const G4double ParticleTable::theINCLNeutronSeparationEnergy = ParticleTable::theINCLProtonSeparationEnergy;
293 G4double ParticleTable::protonSeparationEnergy = theINCLProtonSeparationEnergy;
294 G4double ParticleTable::neutronSeparationEnergy = theINCLNeutronSeparationEnergy;
295
296#ifdef INCLXX_IN_GEANT4_MODE
298#else
299 std::vector< std::vector <G4bool> > ParticleTable::massTableMask;
300 std::vector< std::vector <G4double> > ParticleTable::massTable;
301#endif
302
303 void ParticleTable::initialize(Config const * const theConfig /*=0*/) {
304 protonMass = theINCLNucleonMass;
305 neutronMass = theINCLNucleonMass;
306 piPlusMass = theINCLPionMass;
307 piMinusMass = theINCLPionMass;
308 piZeroMass = theINCLPionMass;
309
310#ifndef INCLXX_IN_GEANT4_MODE
311 std::string dataFilePath;
312 if(theConfig)
313 dataFilePath = theConfig->getINCLXXDataFilePath();
314 readRealMasses(dataFilePath);
315#endif
316
317 if(theConfig && theConfig->getUseRealMasses()) {
320 } else {
323 }
324#ifdef INCLXX_IN_GEANT4_MODE
326 theG4IonTable = theG4ParticleTable->GetIonTable();
327 theRealProtonMass = theG4ParticleTable->FindParticle("proton")->GetPDGMass() / MeV;
328 theRealNeutronMass = theG4ParticleTable->FindParticle("neutron")->GetPDGMass() / MeV;
329 theRealChargedPiMass = theG4ParticleTable->FindParticle("pi+")->GetPDGMass() / MeV;
330 theRealPiZeroMass = theG4ParticleTable->FindParticle("pi0")->GetPDGMass() / MeV;
331#endif
332
333 // Initialise the separation-energy function
334 if(!theConfig || theConfig->getSeparationEnergyType()==INCLSeparationEnergy)
336 else if(theConfig->getSeparationEnergyType()==RealSeparationEnergy)
340 else {
341 FATAL("Unrecognized separation-energy type in ParticleTable initialization: " << theConfig->getSeparationEnergyType() << std::endl);
342 std::abort();
343 }
344
345 }
346
348 // Actually this is the 3rd component of isospin (I_z) multiplied by 2!
349 if(t == Proton) {
350 return 1;
351 } else if(t == Neutron) {
352 return -1;
353 } else if(t == PiPlus) {
354 return 2;
355 } else if(t == PiMinus) {
356 return -2;
357 } else if(t == PiZero) {
358 return 0;
359 } else if(t == DeltaPlusPlus) {
360 return 3;
361 } else if(t == DeltaPlus) {
362 return 1;
363 } else if(t == DeltaZero) {
364 return -1;
365 } else if(t == DeltaMinus) {
366 return -3;
367 }
368
369 ERROR("Requested isospin of an unknown particle!");
370 return -10; // Unknown
371 }
372
374 if(s.theType==Composite)
375 return getShortName(s.theA,s.theZ);
376 else
377 return getShortName(s.theType);
378 }
379
381 if(s.theType==Composite)
382 return getName(s.theA,s.theZ);
383 else
384 return getName(s.theType);
385 }
386
387 std::string ParticleTable::getName(const G4int A, const G4int Z) {
388 std::stringstream stream;
389 stream << getElementName(Z) << "-" << A;
390 return stream.str();
391 }
392
393 std::string ParticleTable::getShortName(const G4int A, const G4int Z) {
394 std::stringstream stream;
395 stream << getElementName(Z);
396 if(A>0)
397 stream << A;
398 return stream.str();
399 }
400
402 if(p == G4INCL::Proton) {
403 return std::string("proton");
404 } else if(p == G4INCL::Neutron) {
405 return std::string("neutron");
406 } else if(p == G4INCL::DeltaPlusPlus) {
407 return std::string("delta++");
408 } else if(p == G4INCL::DeltaPlus) {
409 return std::string("delta+");
410 } else if(p == G4INCL::DeltaZero) {
411 return std::string("delta0");
412 } else if(p == G4INCL::DeltaMinus) {
413 return std::string("delta-");
414 } else if(p == G4INCL::PiPlus) {
415 return std::string("pi+");
416 } else if(p == G4INCL::PiZero) {
417 return std::string("pi0");
418 } else if(p == G4INCL::PiMinus) {
419 return std::string("pi-");
420 } else if(p == G4INCL::Composite) {
421 return std::string("composite");
422 }
423 return std::string("unknown");
424 }
425
427 if(p == G4INCL::Proton) {
428 return std::string("p");
429 } else if(p == G4INCL::Neutron) {
430 return std::string("n");
431 } else if(p == G4INCL::DeltaPlusPlus) {
432 return std::string("d++");
433 } else if(p == G4INCL::DeltaPlus) {
434 return std::string("d+");
435 } else if(p == G4INCL::DeltaZero) {
436 return std::string("d0");
437 } else if(p == G4INCL::DeltaMinus) {
438 return std::string("d-");
439 } else if(p == G4INCL::PiPlus) {
440 return std::string("pi+");
441 } else if(p == G4INCL::PiZero) {
442 return std::string("pi0");
443 } else if(p == G4INCL::PiMinus) {
444 return std::string("pi-");
445 } else if(p == G4INCL::Composite) {
446 return std::string("comp");
447 }
448 return std::string("unknown");
449 }
450
452 if(pt == Proton) {
453 return protonMass;
454 } else if(pt == Neutron) {
455 return neutronMass;
456 } else if(pt == PiPlus) {
457 return piPlusMass;
458 } else if(pt == PiMinus) {
459 return piMinusMass;
460 } else if(pt == PiZero) {
461 return piZeroMass;
462 } else {
463 ERROR("ParticleTable::getMass : Unknown particle type." << std::endl);
464 return 0.0;
465 }
466 }
467
469 switch(t) {
470 case Proton:
471 return theRealProtonMass;
472 break;
473 case Neutron:
474 return theRealNeutronMass;
475 break;
476 case PiPlus:
477 case PiMinus:
478 return theRealChargedPiMass;
479 break;
480 case PiZero:
481 return theRealPiZeroMass;
482 break;
483 default:
484 ERROR("Particle::getRealMass : Unknown particle type." << std::endl);
485 return 0.0;
486 break;
487 }
488 }
489
491// assert(A>=0);
492 // For nuclei with Z<0 or Z>A, assume that the exotic charge state is due to pions
493 if(Z<0)
494 return A*neutronMass - Z*getRealMass(PiMinus);
495 else if(Z>A)
496 return A*protonMass + (A-Z)*getRealMass(PiPlus);
497 else if(Z==0)
498 return A*getRealMass(Neutron);
499 else if(A==Z)
500 return A*getRealMass(Proton);
501 else if(A>1) {
502#ifndef INCLXX_IN_GEANT4_MODE
503 if(ParticleTable::hasMassTable(A,Z))
504 return ParticleTable::massTable.at(Z).at(A);
505 else {
506 DEBUG("Real mass unavailable for isotope A=" << A << ", Z=" << Z
507 << ", using Weizsaecker's formula"
508 << std::endl);
509 return getWeizsaeckerMass(A,Z);
510 }
511#else
512 return theG4IonTable->GetNucleusMass(Z,A) / MeV;
513#endif
514 } else
515 return 0.;
516 }
517
519// assert(A>=0);
520 // For nuclei with Z<0 or Z>A, assume that the exotic charge state is due to pions
521 if(Z<0)
522 return A*neutronMass - Z*getINCLMass(PiMinus);
523 else if(Z>A)
524 return A*protonMass + (A-Z)*getINCLMass(PiPlus);
525 else if(A>1)
526 return Z*(protonMass - protonSeparationEnergy) + (A-Z)*(neutronMass - neutronSeparationEnergy);
527 else if(A==1 && Z==0)
528 return getINCLMass(Neutron);
529 else if(A==1 && Z==1)
530 return getINCLMass(Proton);
531 else
532 return 0.;
533 }
534
536// assert(A>0 && Z>=0 && Z<=A);
537 if(A >= 19 || (A < 6 && A >= 2)) {
538 // For large (Woods-Saxon or Modified Harmonic Oscillator) or small
539 // (Gaussian) nuclei, the radius parameter is just the nuclear radius
540 return getRadiusParameter(A,Z);
541 } else if(A < clusterTableASize && Z < clusterTableZSize && A >= 6) {
542 const G4double thisRMS = positionRMS[Z][A];
543 if(thisRMS>0.0)
544 return thisRMS;
545 else {
546 ERROR("ParticleTable::getRadiusParameter : Radius for nucleus A = " << A << " Z = " << Z << " is ==0.0" << std::endl);
547 return 0.0;
548 }
549 } else if(A < 19) {
550 const G4double theRadiusParameter = getRadiusParameter(A, Z);
551 const G4double theDiffusenessParameter = getSurfaceDiffuseness(A, Z);
552 // The formula yields the nuclear RMS radius based on the parameters of
553 // the nuclear-density function
554 return 1.581*theDiffusenessParameter*
555 (2.+5.*theRadiusParameter)/(2.+3.*theRadiusParameter);
556 } else {
557 ERROR("ParticleTable::getNuclearRadius: No radius for nucleus A = " << A << " Z = " << Z << std::endl);
558 return 0.0;
559 }
560 }
561
563// assert(A>0 && Z>=0 && Z<=A);
564 if(A >= 28) {
565 // phenomenological radius fit
566 return (2.745e-4 * A + 1.063) * std::pow(A, 1.0/3.0);
567 } else if(A < 6 && A >= 2) {
568 if(Z<clusterTableZSize) {
569 const G4double thisRMS = positionRMS[Z][A];
570 if(thisRMS>0.0)
571 return thisRMS;
572 else {
573 ERROR("ParticleTable::getRadiusParameter : Radius for nucleus A = " << A << " Z = " << Z << " is ==0.0" << std::endl);
574 return 0.0;
575 }
576 } else {
577 ERROR("ParticleTable::getRadiusParameter : No radius for nucleus A = " << A << " Z = " << Z << std::endl);
578 return 0.0;
579 }
580 } else if(A < 28 && A >= 6) {
581 return mediumRadius[A-1];
582 // return 1.581*mediumDiffuseness[A-1]*(2.+5.*mediumRadius[A-1])/(2.+3.*mediumRadius[A-1]);
583 } else {
584 ERROR("ParticleTable::getRadiusParameter: No radius for nucleus A = " << A << " Z = " << Z << std::endl);
585 return 0.0;
586 }
587 }
588
590 const G4double XFOISA = 8.0;
591 if(A >= 19) {
592 return getNuclearRadius(A,Z) + XFOISA * getSurfaceDiffuseness(A,Z);
593 } else if(A < 19 && A >= 6) {
594 return 5.5 + 0.3 * (G4double(A) - 6.0)/12.0;
595 } else if(A >= 2) {
596 return ParticleTable::getNuclearRadius(A, Z) + 4.5;
597 } else {
598 ERROR("ParticleTable::getMaximumNuclearRadius : No maximum radius for nucleus A = " << A << " Z = " << Z << std::endl);
599 return 0.0;
600 }
601 }
602
603#ifdef INCLXX_IN_GEANT4_MODE
605#else
607#endif // INCLXX_IN_GEANT4_MODE
608
609 if(A >= 28) {
610 return 1.63e-4 * A + 0.510;
611 } else if(A < 28 && A >= 19) {
612 return mediumDiffuseness[A-1];
613 } else if(A < 19 && A >= 6) {
614 return mediumDiffuseness[A-1];
615 } else if(A < 6 && A >= 2) {
616 ERROR("ParticleTable::getSurfaceDiffuseness: was called for A = " << A << " Z = " << Z << std::endl);
617 return 0.0;
618 } else {
619 ERROR("ParticleTable::getSurfaceDiffuseness: No diffuseness for nucleus A = " << A << " Z = " << Z << std::endl);
620 return 0.0;
621 }
622 }
623
625 if(Z<1) {
626 WARN("getElementName called with Z<1" << std::endl);
627 return elementTable[0];
628 } else if(Z<elementTableSize)
629 return elementTable[Z];
630 else
631 return getIUPACElementName(Z);
632 }
633
634#ifndef INCLXX_IN_GEANT4_MODE
635 void ParticleTable::readRealMasses(std::string const &path) {
636 // Clear the existing tables, if any
637 massTableMask.clear();
638 massTable.clear();
639
640 // File name
641 std::string fileName(path + "/walletlifetime.dat");
642 DEBUG("Reading real nuclear masses from file " << fileName << std::endl);
643
644 // Open the file stream
645 std::ifstream massTableIn(fileName.c_str());
646 if(!massTableIn.good()) {
647 FATAL("Cannot open " << fileName << " data file." << std::endl);
648 std::exit(EXIT_FAILURE);
649 return;
650 }
651
652 // Read in the data
653 unsigned int Z, A;
654 const G4double amu = 931.494061; // atomic mass unit in MeV/c^2
655 const G4double eMass = 0.5109988; // electron mass in MeV/c^2
656 G4double excess;
657 massTableIn >> A >> Z >> excess;
658 do {
659 // Dynamically determine the table size
660 if(Z>=massTable.size()) {
661 massTable.resize(Z+1);
662 massTableMask.resize(Z+1);
663 }
664 if(A>=massTable[Z].size()) {
665 massTable[Z].resize(A+1, 0.);
666 massTableMask[Z].resize(A+1, false);
667 }
668
669 massTable.at(Z).at(A) = A*amu + excess - Z*eMass;
670 massTableMask.at(Z).at(A) = true;
671
672 massTableIn >> A >> Z >> excess;
673 } while(massTableIn.good());
674
675 }
676#endif
677
679 std::stringstream elementStream;
680 elementStream << Z;
681 std::string elementName = elementStream.str();
682 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ParticleTable::intToIUPAC);
683 elementName[0] = std::toupper(elementName.at(0));
684 return elementName;
685 }
686
688 // Normalise to lower case
689 std::string elementName(s);
690 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ::tolower);
691 // Return 0 if the element name contains anything but IUPAC digits
692 if(elementName.find_first_not_of(elementIUPACDigits)!=std::string::npos)
693 return 0;
694 std::transform(elementName.begin(), elementName.end(), elementName.begin(), ParticleTable::iupacToInt);
695 std::stringstream elementStream(elementName);
696 G4int Z;
697 elementStream >> Z;
698 return Z;
699 }
700
701}
#define WARN(x)
#define DEBUG(x)
#define FATAL(x)
#define ERROR(x)
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
SeparationEnergyType getSeparationEnergyType() const
Get the separation-energy type.
std::string const & getINCLXXDataFilePath() const
G4bool getUseRealMasses() const
Whether to use real masses.
static const G4double clusterPosFact2[maxClusterMass+1]
static G4double getINCLMass(const G4int A, const G4int Z)
Get INCL nuclear mass (in MeV/c^2)
static NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
static const G4int clusterZMin[maxClusterMass+1]
static const G4double eSquared
Coulomb conversion factor, in MeV*fm.
static G4double getRadiusParameter(const G4int A, const G4int Z)
static void initialize(Config const *const theConfig=0)
Initialize the particle table.
static const G4double effectiveDeltaMass
static SeparationEnergyFn getSeparationEnergy
Static pointer to the separation-energy function.
static ParticleMassFn getTableParticleMass
Static pointer to the mass function for particles.
static const G4double clusterPosFact[maxClusterMass+1]
static const G4int clusterTableZSize
static G4double getNuclearRadius(const G4int A, const G4int Z)
G4double(* NuclearMassFn)(const G4int, const G4int)
static G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2)
static G4IonTable * theG4IonTable
G4double(* ParticleMassFn)(const ParticleType)
static G4double getMaximumNuclearRadius(const G4int A, const G4int Z)
static const G4double effectiveDeltaDecayThreshold
static G4double getSeparationEnergyReal(const ParticleType t, const G4int A, const G4int Z)
Return the real separation energy.
static G4int parseIUPACElement(std::string const &pS)
Parse a IUPAC element name.
static std::string getName(const ParticleType t)
Get the native INCL name of the particle.
G4double(* SeparationEnergyFn)(const ParticleType, const G4int, const G4int)
static const G4int elementTableSize
static const G4double effectiveNucleonMass2
static std::string getIUPACElementName(const G4int Z)
Get the name of an unnamed element from the IUPAC convention.
static G4double getSeparationEnergyRealForLight(const ParticleType t, const G4int A, const G4int Z)
Return the real separation energy only for light nuclei.
static G4int getIsospin(const ParticleType t)
Get the isospin of a particle.
static const G4double effectiveNucleonMass
static const G4double effectivePionMass
static const G4int clusterTableASize
static const G4double clusterPhaseSpaceCut[maxClusterMass+1]
static const G4int clusterZMax[maxClusterMass+1]
static G4double getSeparationEnergyINCL(const ParticleType t, const G4int, const G4int)
Return INCL's default separation energy.
static std::string getShortName(const ParticleType t)
Get the short INCL name of the particle.
static G4double getSurfaceDiffuseness(const G4int A, const G4int Z)
static std::string getElementName(const G4int Z)
Get the name of the element from the atomic number.
static const ClusterDecayType clusterDecayMode[clusterTableZSize][clusterTableASize]
G4double GetNucleusMass(G4int Z, G4int A, G4int L=0) const
Definition: G4IonTable.cc:741
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
static G4ParticleTable * GetParticleTable()
G4IonTable * GetIonTable()
@ INCLSeparationEnergy
@ RealForLightSeparationEnergy