Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 #define INCLXX_IN_GEANT4_MODE 1
34 
35 #include "globals.hh"
36 
37 #include "G4INCLParticleTable.hh"
39 #include <algorithm>
40 // #include <cassert>
41 #include <cmath>
42 #include <cctype>
43 #include <sstream>
44 #ifdef INCLXX_IN_GEANT4_MODE
45 #include "G4SystemOfUnits.hh"
46 #endif
47 
48 #ifdef INCLXX_IN_GEANT4_MODE
49 #include "G4PhysicalConstants.hh"
50 #include "G4SystemOfUnits.hh"
51 #endif
52 
53 namespace G4INCL {
54 
55  namespace ParticleTable {
56 
57  namespace {
58 
59  /// \brief Static instance of the NaturalIsotopicAbundances class
60  const NaturalIsotopicDistributions *theNaturalIsotopicDistributions = NULL;
61 
62  const G4double theINCLNucleonMass = 938.2796;
63  const G4double theINCLPionMass = 138.0;
64  G4ThreadLocal G4double protonMass = 0.0;
65  G4ThreadLocal G4double neutronMass = 0.0;
66  G4ThreadLocal G4double piPlusMass = 0.0;
67  G4ThreadLocal G4double piMinusMass = 0.0;
68  G4ThreadLocal G4double piZeroMass = 0.0;
69 
70  // Hard-coded values of the real particle masses (MeV/c^2)
71  G4ThreadLocal G4double theRealProtonMass = 938.27203;
72  G4ThreadLocal G4double theRealNeutronMass = 939.56536;
73  G4ThreadLocal G4double theRealChargedPiMass = 139.57018;
74  G4ThreadLocal G4double theRealPiZeroMass = 134.9766;
75 
76  const G4int mediumNucleiTableSize = 30;
77 
78  const G4double mediumDiffuseness[mediumNucleiTableSize] =
79  {0.0,0.0,0.0,0.0,0.0,1.78,1.77,1.77,1.77,1.71,
80  1.69,1.69,1.635,1.730,1.81,1.833,1.798,
81  1.841,0.567,0.571, 0.560,0.549,0.550,0.551,
82  0.580,0.575,0.569,0.537,0.0,0.0};
83  const G4double mediumRadius[mediumNucleiTableSize] =
84  {0.0,0.0,0.0,0.0,0.0,0.334,0.327,0.479,0.631,0.838,
85  0.811,1.07,1.403,1.335,1.25,1.544,1.498,1.513,
86  2.58,2.77, 2.775,2.78,2.88,2.98,3.22,3.03,2.84,
87  3.14,0.0,0.0};
88 
89  const G4double positionRMS[clusterTableZSize][clusterTableASize] = {
90  /* A= 0 1 2 3 4 5 6 7 8 9 10 11 12 */
91  /* Z=0 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0},
92  /* Z=1 */ {-1.0, -1.0, 2.10, 1.80, 1.70, 1.83, 2.60, 2.50, -1.0, -1.0, -1.0, -1.0, -1.0},
93  /* Z=2 */ {-1.0, -1.0, -1.0, 1.80, 1.68, 1.70, 2.60, 2.50, 2.50, 2.50, 2.50, -1.0, -1.0},
94  /* Z=3 */ {-1.0, -1.0, -1.0, -1.0, 1.70, 1.83, 2.56, 2.40, 2.50, 2.50, 2.50, 2.50, 2.50},
95  /* Z=4 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 2.60, 2.50, 2.50, 2.51, 2.50, 2.50, 2.50},
96  /* Z=5 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 2.50, 2.50, 2.50, 2.50, 2.45, 2.40, 2.50},
97  /* Z=6 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 2.50, 2.50, 2.50, 2.50, 2.47},
98  /* Z=7 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 2.50, 2.50, 2.50},
99  /* Z=8 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 2.50}
100  };
101 
102  const G4double momentumRMS[clusterTableZSize][clusterTableASize] = {
103  /* A= 0 1 2 3 4 5 6 7 8 9 10 11 12 */
104  /* Z=0 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0},
105  /* Z=1 */ {-1.0, -1.0, 77.0, 110., 153., 100., 100., 100., -1.0, -1.0, -1.0, -1.0, -1.0},
106  /* Z=2 */ {-1.0, -1.0, -1.0, 110., 153., 100., 100., 100., 100., 100., 100., -1.0, -1.0},
107  /* Z=3 */ {-1.0, -1.0, -1.0, -1.0, 153., 100., 100., 100., 100., 100., 100., 100., 100.},
108  /* Z=4 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 100., 100., 100., 100., 100., 100., 100.},
109  /* Z=5 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 100., 100., 100., 100., 100., 100., 100.},
110  /* Z=6 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 100., 100., 100., 100., 100.},
111  /* Z=7 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 100., 100., 100.},
112  /* Z=8 */ {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 100.}
113  };
114 
115  const G4int elementTableSize = 113; // up to Cn
116 
117  /// \brief Table of chemical element names
118  const std::string elementTable[elementTableSize] = {
119  "",
120  "H",
121  "He",
122  "Li",
123  "Be",
124  "B",
125  "C",
126  "N",
127  "O",
128  "F",
129  "Ne",
130  "Na",
131  "Mg",
132  "Al",
133  "Si",
134  "P",
135  "S",
136  "Cl",
137  "Ar",
138  "K",
139  "Ca",
140  "Sc",
141  "Ti",
142  "V",
143  "Cr",
144  "Mn",
145  "Fe",
146  "Co",
147  "Ni",
148  "Cu",
149  "Zn",
150  "Ga",
151  "Ge",
152  "As",
153  "Se",
154  "Br",
155  "Kr",
156  "Rb",
157  "Sr",
158  "Y",
159  "Zr",
160  "Nb",
161  "Mo",
162  "Tc",
163  "Ru",
164  "Rh",
165  "Pd",
166  "Ag",
167  "Cd",
168  "In",
169  "Sn",
170  "Sb",
171  "Te",
172  "I",
173  "Xe",
174  "Cs",
175  "Ba",
176  "La",
177  "Ce",
178  "Pr",
179  "Nd",
180  "Pm",
181  "Sm",
182  "Eu",
183  "Gd",
184  "Tb",
185  "Dy",
186  "Ho",
187  "Er",
188  "Tm",
189  "Yb",
190  "Lu",
191  "Hf",
192  "Ta",
193  "W",
194  "Re",
195  "Os",
196  "Ir",
197  "Pt",
198  "Au",
199  "Hg",
200  "Tl",
201  "Pb",
202  "Bi",
203  "Po",
204  "At",
205  "Rn",
206  "Fr",
207  "Ra",
208  "Ac",
209  "Th",
210  "Pa",
211  "U",
212  "Np",
213  "Pu",
214  "Am",
215  "Cm",
216  "Bk",
217  "Cf",
218  "Es",
219  "Fm",
220  "Md",
221  "No",
222  "Lr",
223  "Rf",
224  "Db",
225  "Sg",
226  "Bh",
227  "Hs",
228  "Mt",
229  "Ds",
230  "Rg",
231  "Cn"
232  };
233 
234  /// \brief Digit names to compose IUPAC element names
235  const std::string elementIUPACDigits = "nubtqphsoe";
236 
237 #define INCL_DEFAULT_SEPARATION_ENERGY 6.83
238  const G4double theINCLProtonSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
239  const G4double theINCLNeutronSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
240  G4ThreadLocal G4double protonSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
241  G4ThreadLocal G4double neutronSeparationEnergy = INCL_DEFAULT_SEPARATION_ENERGY;
242 #undef INCL_DEFAULT_SEPARATION_ENERGY
243 
244  G4ThreadLocal G4double rpCorrelationCoefficient[UnknownParticle];
245 
246  G4ThreadLocal G4double neutronSkinThickness = 0.0;
247  G4ThreadLocal G4double neutronSkinAdditionalDiffuseness = 0.0;
248 
249 #ifdef INCLXX_IN_GEANT4_MODE
250  G4ThreadLocal G4IonTable *theG4IonTable;
251 #endif
252 
253  /// \brief Transform a IUPAC char to an char representing an integer digit
254  char iupacToInt(char c) {
255  return (char)(((G4int)'0')+elementIUPACDigits.find(c));
256  }
257 
258  /// \brief Transform an integer digit (represented by a char) to a IUPAC char
259  char intToIUPAC(char n) { return elementIUPACDigits.at(n); }
260 
261  /// \brief Get the singleton instance of the natural isotopic distributions
262  const NaturalIsotopicDistributions *getNaturalIsotopicDistributions() {
263  if(!theNaturalIsotopicDistributions)
264  theNaturalIsotopicDistributions = new NaturalIsotopicDistributions;
265  return theNaturalIsotopicDistributions;
266  }
267 
268  } // namespace
269 
270  void initialize(Config const * const theConfig /*=0*/) {
271  protonMass = theINCLNucleonMass;
272  neutronMass = theINCLNucleonMass;
273  piPlusMass = theINCLPionMass;
274  piMinusMass = theINCLPionMass;
275  piZeroMass = theINCLPionMass;
276 
277  if(theConfig && theConfig->getUseRealMasses()) {
280  } else {
283  }
284 
285 #ifndef INCLXX_IN_GEANT4_MODE
286  std::string dataFilePath;
287  if(theConfig)
288  dataFilePath = theConfig->getINCLXXDataFilePath();
290 #endif
291 
292 #ifdef INCLXX_IN_GEANT4_MODE
293  G4ParticleTable *theG4ParticleTable = G4ParticleTable::GetParticleTable();
294  theG4IonTable = theG4ParticleTable->GetIonTable();
295  theRealProtonMass = theG4ParticleTable->FindParticle("proton")->GetPDGMass() / MeV;
296  theRealNeutronMass = theG4ParticleTable->FindParticle("neutron")->GetPDGMass() / MeV;
297  theRealChargedPiMass = theG4ParticleTable->FindParticle("pi+")->GetPDGMass() / MeV;
298  theRealPiZeroMass = theG4ParticleTable->FindParticle("pi0")->GetPDGMass() / MeV;
299 #endif
300 
301  effectiveDeltaDecayThreshold = theRealNeutronMass + theRealChargedPiMass + 0.5;
302 
303  // Initialise the separation-energy function
304  if(!theConfig || theConfig->getSeparationEnergyType()==INCLSeparationEnergy)
306  else if(theConfig->getSeparationEnergyType()==RealSeparationEnergy)
310  else {
311  INCL_FATAL("Unrecognized separation-energy type in ParticleTable initialization: " << theConfig->getSeparationEnergyType() << std::endl);
312  std::abort();
313  return;
314  }
315 
316  // Initialise the Fermi-momentum function
317  if(!theConfig || theConfig->getFermiMomentumType()==ConstantFermiMomentum)
319  else if(theConfig->getFermiMomentumType()==ConstantLightFermiMomentum)
321  else if(theConfig->getFermiMomentumType()==MassDependentFermiMomentum)
323  else {
324  INCL_FATAL("Unrecognized Fermi-momentum type in ParticleTable initialization: " << theConfig->getFermiMomentumType() << std::endl);
325  std::abort();
326  return;
327  }
328 
329  // Initialise the r-p correlation coefficients
330  std::fill(rpCorrelationCoefficient, rpCorrelationCoefficient + UnknownParticle, 1.);
331  if(theConfig) {
332  rpCorrelationCoefficient[Proton] = theConfig->getRPCorrelationCoefficient(Proton);
333  rpCorrelationCoefficient[Neutron] = theConfig->getRPCorrelationCoefficient(Neutron);
334  }
335 
336  // Initialise the neutron-skin parameters
337  if(theConfig) {
338  neutronSkinThickness = theConfig->getNeutronSkinThickness();
339  neutronSkinAdditionalDiffuseness = theConfig->getNeutronSkinAdditionalDiffuseness();
340  }
341 
342  }
343 
345  // Actually this is the 3rd component of isospin (I_z) multiplied by 2!
346  if(t == Proton) {
347  return 1;
348  } else if(t == Neutron) {
349  return -1;
350  } else if(t == PiPlus) {
351  return 2;
352  } else if(t == PiMinus) {
353  return -2;
354  } else if(t == PiZero) {
355  return 0;
356  } else if(t == DeltaPlusPlus) {
357  return 3;
358  } else if(t == DeltaPlus) {
359  return 1;
360  } else if(t == DeltaZero) {
361  return -1;
362  } else if(t == DeltaMinus) {
363  return -3;
364  }
365 
366  INCL_ERROR("Requested isospin of an unknown particle!");
367  return -10; // Unknown
368  }
369 
370  std::string getShortName(const ParticleSpecies &s) {
371  if(s.theType==Composite)
372  return getShortName(s.theA,s.theZ);
373  else
374  return getShortName(s.theType);
375  }
376 
377  std::string getName(const ParticleSpecies &s) {
378  if(s.theType==Composite)
379  return getName(s.theA,s.theZ);
380  else
381  return getName(s.theType);
382  }
383 
384  std::string getName(const G4int A, const G4int Z) {
385  std::stringstream stream;
386  stream << getElementName(Z) << "-" << A;
387  return stream.str();
388  }
389 
390  std::string getShortName(const G4int A, const G4int Z) {
391  std::stringstream stream;
392  stream << getElementName(Z);
393  if(A>0)
394  stream << A;
395  return stream.str();
396  }
397 
398  std::string getName(const ParticleType p) {
399  if(p == G4INCL::Proton) {
400  return std::string("proton");
401  } else if(p == G4INCL::Neutron) {
402  return std::string("neutron");
403  } else if(p == G4INCL::DeltaPlusPlus) {
404  return std::string("delta++");
405  } else if(p == G4INCL::DeltaPlus) {
406  return std::string("delta+");
407  } else if(p == G4INCL::DeltaZero) {
408  return std::string("delta0");
409  } else if(p == G4INCL::DeltaMinus) {
410  return std::string("delta-");
411  } else if(p == G4INCL::PiPlus) {
412  return std::string("pi+");
413  } else if(p == G4INCL::PiZero) {
414  return std::string("pi0");
415  } else if(p == G4INCL::PiMinus) {
416  return std::string("pi-");
417  } else if(p == G4INCL::Composite) {
418  return std::string("composite");
419  }
420  return std::string("unknown");
421  }
422 
423  std::string getShortName(const ParticleType p) {
424  if(p == G4INCL::Proton) {
425  return std::string("p");
426  } else if(p == G4INCL::Neutron) {
427  return std::string("n");
428  } else if(p == G4INCL::DeltaPlusPlus) {
429  return std::string("d++");
430  } else if(p == G4INCL::DeltaPlus) {
431  return std::string("d+");
432  } else if(p == G4INCL::DeltaZero) {
433  return std::string("d0");
434  } else if(p == G4INCL::DeltaMinus) {
435  return std::string("d-");
436  } else if(p == G4INCL::PiPlus) {
437  return std::string("pi+");
438  } else if(p == G4INCL::PiZero) {
439  return std::string("pi0");
440  } else if(p == G4INCL::PiMinus) {
441  return std::string("pi-");
442  } else if(p == G4INCL::Composite) {
443  return std::string("comp");
444  }
445  return std::string("unknown");
446  }
447 
449  if(pt == Proton) {
450  return protonMass;
451  } else if(pt == Neutron) {
452  return neutronMass;
453  } else if(pt == PiPlus) {
454  return piPlusMass;
455  } else if(pt == PiMinus) {
456  return piMinusMass;
457  } else if(pt == PiZero) {
458  return piZeroMass;
459  } else {
460  INCL_ERROR("getMass : Unknown particle type." << std::endl);
461  return 0.0;
462  }
463  }
464 
466  switch(t) {
467  case Proton:
468  return theRealProtonMass;
469  break;
470  case Neutron:
471  return theRealNeutronMass;
472  break;
473  case PiPlus:
474  case PiMinus:
475  return theRealChargedPiMass;
476  break;
477  case PiZero:
478  return theRealPiZeroMass;
479  break;
480  default:
481  INCL_ERROR("Particle::getRealMass : Unknown particle type." << std::endl);
482  return 0.0;
483  break;
484  }
485  }
486 
487  G4double getRealMass(const G4int A, const G4int Z) {
488 // assert(A>=0);
489  // For nuclei with Z<0 or Z>A, assume that the exotic charge state is due to pions
490  if(Z<0)
491  return A*neutronMass - Z*getRealMass(PiMinus);
492  else if(Z>A)
493  return A*protonMass + (A-Z)*getRealMass(PiPlus);
494  else if(Z==0)
495  return A*getRealMass(Neutron);
496  else if(A==Z)
497  return A*getRealMass(Proton);
498  else if(A>1) {
499 #ifndef INCLXX_IN_GEANT4_MODE
500  return ::G4INCL::NuclearMassTable::getMass(A,Z);
501 #else
502  return theG4IonTable->GetNucleusMass(Z,A) / MeV;
503 #endif
504  } else
505  return 0.;
506  }
507 
508  G4double getINCLMass(const G4int A, const G4int Z) {
509 // assert(A>=0);
510  // For nuclei with Z<0 or Z>A, assume that the exotic charge state is due to pions
511  if(Z<0)
512  return A*neutronMass - Z*getINCLMass(PiMinus);
513  else if(Z>A)
514  return A*protonMass + (A-Z)*getINCLMass(PiPlus);
515  else if(A>1)
516  return Z*(protonMass - protonSeparationEnergy) + (A-Z)*(neutronMass - neutronSeparationEnergy);
517  else if(A==1 && Z==0)
518  return getINCLMass(Neutron);
519  else if(A==1 && Z==1)
520  return getINCLMass(Proton);
521  else
522  return 0.;
523  }
524 
525  G4double getTableQValue(const G4int A1, const G4int Z1, const G4int A2, const G4int Z2) {
526  return getTableMass(A1,Z1) + getTableMass(A2,Z2) - getTableMass(A1+A2,Z1+Z2);
527  }
528 
529  G4double getTableQValue(const G4int A1, const G4int Z1, const G4int A2, const G4int Z2, const G4int A3, const G4int Z3) {
530  return getTableMass(A1,Z1) + getTableMass(A2,Z2) - getTableMass(A3,Z3) - getTableMass(A1+A2-A3,Z1+Z2-Z3);
531  }
532 
534  if(p.theType == Composite)
535  return (*getTableMass)(p.theA, p.theZ);
536  else
537  return (*getTableParticleMass)(p.theType);
538  }
539 
541  switch(t) {
542  case Proton:
543  case Neutron:
544  case DeltaPlusPlus:
545  case DeltaPlus:
546  case DeltaZero:
547  case DeltaMinus:
548  return 1;
549  break;
550  case PiPlus:
551  case PiMinus:
552  case PiZero:
553  return 0;
554  break;
555  default:
556  return 0;
557  break;
558  }
559  }
560 
562  switch(t) {
563  case DeltaPlusPlus:
564  return 2;
565  break;
566  case Proton:
567  case DeltaPlus:
568  case PiPlus:
569  return 1;
570  break;
571  case Neutron:
572  case DeltaZero:
573  case PiZero:
574  return 0;
575  break;
576  case DeltaMinus:
577  case PiMinus:
578  return -1;
579  break;
580  default:
581  return 0;
582  break;
583  }
584  }
585 
586  G4double getNuclearRadius(const ParticleType t, const G4int A, const G4int Z) {
587 // assert(A>=0);
588  if(A >= 19 || (A < 6 && A >= 2)) {
589  // For large (Woods-Saxon or Modified Harmonic Oscillator) or small
590  // (Gaussian) nuclei, the radius parameter is just the nuclear radius
591  return getRadiusParameter(t,A,Z);
592  } else if(A < clusterTableASize && Z>=0 && Z < clusterTableZSize && A >= 6) {
593  const G4double thisRMS = positionRMS[Z][A];
594  if(thisRMS>0.0)
595  return thisRMS;
596  else {
597  INCL_DEBUG("getNuclearRadius: Radius for nucleus A = " << A << " Z = " << Z << " is not available" << std::endl
598  << "returning radius for C12");
599  return positionRMS[6][12];
600  }
601  } else if(A < 19) {
602  const G4double theRadiusParameter = getRadiusParameter(t, A, Z);
603  const G4double theDiffusenessParameter = getSurfaceDiffuseness(t, A, Z);
604  // The formula yields the nuclear RMS radius based on the parameters of
605  // the nuclear-density function
606  return 1.581*theDiffusenessParameter*
607  (2.+5.*theRadiusParameter)/(2.+3.*theRadiusParameter);
608  } else {
609  INCL_ERROR("getNuclearRadius: No radius for nucleus A = " << A << " Z = " << Z << std::endl);
610  return 0.0;
611  }
612  }
613 
616  }
617 
618  G4double getRadiusParameter(const ParticleType t, const G4int A, const G4int Z) {
619 // assert(A>0);
620  if(A >= 28) {
621  // phenomenological radius fit
622  G4double r0 = (2.745e-4 * A + 1.063) * std::pow(A, 1.0/3.0);
623  if(t==Neutron)
624  r0 += neutronSkinThickness;
625  return r0;
626  } else if(A < 6 && A >= 2) {
627  if(Z<clusterTableZSize && Z>=0) {
628  const G4double thisRMS = positionRMS[Z][A];
629  if(thisRMS>0.0)
630  return thisRMS;
631  else {
632  INCL_DEBUG("getRadiusParameter: Radius for nucleus A = " << A << " Z = " << Z << " is not available" << std::endl
633  << "returning radius for C12");
634  return positionRMS[6][12];
635  }
636  } else {
637  INCL_DEBUG("getRadiusParameter: Radius for nucleus A = " << A << " Z = " << Z << " is not available" << std::endl
638  << "returning radius for C12");
639  return positionRMS[6][12];
640  }
641  } else if(A < 28 && A >= 6) {
642  return mediumRadius[A-1];
643  // return 1.581*mediumDiffuseness[A-1]*(2.+5.*mediumRadius[A-1])/(2.+3.*mediumRadius[A-1]);
644  } else {
645  INCL_ERROR("getRadiusParameter: No radius for nucleus A = " << A << " Z = " << Z << std::endl);
646  return 0.0;
647  }
648  }
649 
651  const G4double XFOISA = 8.0;
652  if(A >= 19) {
653  return getNuclearRadius(t,A,Z) + XFOISA * getSurfaceDiffuseness(t,A,Z);
654  } else if(A < 19 && A >= 6) {
655  return 5.5 + 0.3 * (G4double(A) - 6.0)/12.0;
656  } else if(A >= 2) {
657  return getNuclearRadius(t, A, Z) + 4.5;
658  } else {
659  INCL_ERROR("getMaximumNuclearRadius : No maximum radius for nucleus A = " << A << " Z = " << Z << std::endl);
660  return 0.0;
661  }
662  }
663 
665  if(A >= 28) {
666  G4double a = 1.63e-4 * A + 0.510;
667  if(t==Neutron)
668  a += neutronSkinAdditionalDiffuseness;
669  return a;
670  } else if(A < 28 && A >= 19) {
671  return mediumDiffuseness[A-1];
672  } else if(A < 19 && A >= 6) {
673  return mediumDiffuseness[A-1];
674  } else if(A < 6 && A >= 2) {
675  INCL_ERROR("getSurfaceDiffuseness: was called for A = " << A << " Z = " << Z << std::endl);
676  return 0.0;
677  } else {
678  INCL_ERROR("getSurfaceDiffuseness: No diffuseness for nucleus A = " << A << " Z = " << Z << std::endl);
679  return 0.0;
680  }
681  }
682 
683  G4double getMomentumRMS(const G4int A, const G4int Z) {
684 // assert(Z>=0 && A>=0 && Z<=A);
686  }
687 
688  G4double getSeparationEnergyINCL(const ParticleType t, const G4int /*A*/, const G4int /*Z*/) {
689  if(t==Proton)
690  return theINCLProtonSeparationEnergy;
691  else if(t==Neutron)
692  return theINCLNeutronSeparationEnergy;
693  else {
694  INCL_ERROR("ParticleTable::getSeparationEnergyINCL : Unknown particle type." << std::endl);
695  return 0.0;
696  }
697  }
698 
700  // Real separation energies for all nuclei
701  if(t==Proton)
702  return (*getTableParticleMass)(Proton) + (*getTableMass)(A-1,Z-1) - (*getTableMass)(A,Z);
703  else if(t==Neutron)
704  return (*getTableParticleMass)(Neutron) + (*getTableMass)(A-1,Z) - (*getTableMass)(A,Z);
705  else {
706  INCL_ERROR("ParticleTable::getSeparationEnergyReal : Unknown particle type." << std::endl);
707  return 0.0;
708  }
709  }
710 
712  // Real separation energies for light nuclei, fixed values for heavy nuclei
714  return getSeparationEnergyReal(t, A, Z);
715  else
716  return getSeparationEnergyINCL(t, A, Z);
717  }
718 
719  G4double getProtonSeparationEnergy() { return protonSeparationEnergy; }
720 
721  G4double getNeutronSeparationEnergy() { return neutronSeparationEnergy; }
722 
723  void setProtonSeparationEnergy(const G4double s) { protonSeparationEnergy = s; }
724 
725  void setNeutronSeparationEnergy(const G4double s) { neutronSeparationEnergy = s; }
726 
727  std::string getElementName(const G4int Z) {
728  if(Z<1) {
729  INCL_WARN("getElementName called with Z<1" << std::endl);
730  return elementTable[0];
731  } else if(Z<elementTableSize)
732  return elementTable[Z];
733  else
734  return getIUPACElementName(Z);
735  }
736 
737  std::string getIUPACElementName(const G4int Z) {
738  std::stringstream elementStream;
739  elementStream << Z;
740  std::string elementName = elementStream.str();
741  std::transform(elementName.begin(), elementName.end(), elementName.begin(), intToIUPAC);
742  elementName[0] = std::toupper(elementName.at(0));
743  return elementName;
744  }
745 
746  G4int parseElement(std::string pS) {
747  // Normalize the element name
748  std::transform(pS.begin(), pS.end(), pS.begin(), ::tolower);
749  pS[0] = ::toupper(pS[0]);
750 
751  const std::string *iter = std::find(elementTable, elementTable+elementTableSize, pS);
752  if(iter != elementTable+elementTableSize)
753  return iter - elementTable;
754  else
756  }
757 
758  G4int parseIUPACElement(std::string const &s) {
759  // Normalise to lower case
760  std::string elementName(s);
761  std::transform(elementName.begin(), elementName.end(), elementName.begin(), ::tolower);
762  // Return 0 if the element name contains anything but IUPAC digits
763  if(elementName.find_first_not_of(elementIUPACDigits)!=std::string::npos)
764  return 0;
765  std::transform(elementName.begin(), elementName.end(), elementName.begin(), iupacToInt);
766  std::stringstream elementStream(elementName);
767  G4int Z;
768  elementStream >> Z;
769  return Z;
770  }
771 
773  return getNaturalIsotopicDistributions()->getIsotopicDistribution(Z);
774  }
775 
777  return getNaturalIsotopicDistributions()->drawRandomIsotope(Z);
778  }
779 
780  G4double getFermiMomentumConstant(const G4int /*A*/, const G4int /*Z*/) {
781  return PhysicalConstants::Pf;
782  }
783 
785 // assert(Z>0 && A>0 && Z<=A);
787  const G4double rms = momentumRMS[Z][A];
788  return ((rms>0.) ? rms : momentumRMS[6][12]) * Math::sqrtFiveThirds;
789  } else
790  return getFermiMomentumConstant(A,Z);
791  }
792 
794 // assert(A>0);
795  static const G4double alphaParam = 259.416; // MeV/c
796  static const G4double betaParam = 152.824; // MeV/c
797  static const G4double gammaParam = 9.5157E-2;
798  return alphaParam - betaParam*std::exp(-gammaParam*((G4double)A));
799  }
800 
802 // assert(t==Proton || t==Neutron);
803  return rpCorrelationCoefficient[t];
804  }
805 
806  G4double getNeutronSkinThickness() { return neutronSkinThickness; }
807 
808  G4double getNeutronSkinAdditionalDiffuseness() { return neutronSkinAdditionalDiffuseness; }
809 
815 
816  } // namespace ParticleTable
817 } // namespace G4INCL
818 
#define INCL_FATAL(x)
const G4double sqrtThreeFifths
G4double(* ParticleMassFn)(const ParticleType)
G4double getSeparationEnergyReal(const ParticleType t, const G4int A, const G4int Z)
Return the real separation energy.
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
G4ThreadLocal ParticleMassFn getTableParticleMass
Static pointer to the mass function for particles.
G4double getNeutronSeparationEnergy()
Getter for neutronSeparationEnergy.
std::string const & getINCLXXDataFilePath() const
G4double getProtonSeparationEnergy()
Getter for protonSeparationEnergy.
const XML_Char * s
const char * p
Definition: xmltok.h:285
G4double getTableQValue(const G4int A1, const G4int Z1, const G4int A2, const G4int Z2)
Get Q-value (in MeV/c^2)
#define INCL_ERROR(x)
G4int getChargeNumber(const ParticleType t)
Get charge number from particle type.
#define INCL_WARN(x)
G4double getNeutronSkinAdditionalDiffuseness() const
Get the neutron-skin additional diffuseness.
G4double(* NuclearMassFn)(const G4int, const G4int)
G4double getFermiMomentumConstant(const G4int, const G4int)
Return the constant value of the Fermi momentum.
#define G4ThreadLocal
Definition: tls.hh:52
int G4int
Definition: G4Types.hh:78
void setProtonSeparationEnergy(const G4double s)
Setter for protonSeparationEnergy.
G4double(* FermiMomentumFn)(const G4int, const G4int)
SeparationEnergyType getSeparationEnergyType() const
Get the separation-energy type.
G4double getNuclearRadius(const ParticleType t, const G4int A, const G4int Z)
G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2)
G4int getMassNumber(const ParticleType t)
Get mass number from particle type.
G4IonTable * GetIonTable() const
G4int parseElement(std::string pS)
Get the name of the element from the atomic number.
Class that stores isotopic abundances for a given element.
std::string getIUPACElementName(const G4int Z)
Get the name of an unnamed element from the IUPAC convention.
G4double getLargestNuclearRadius(const G4int A, const G4int Z)
const G4double sqrtFiveThirds
const G4int n
G4bool getUseRealMasses() const
Whether to use real masses.
G4double(* SeparationEnergyFn)(const ParticleType, const G4int, const G4int)
Functions that encapsulate a mass table.
G4double getSurfaceDiffuseness(const ParticleType t, const G4int A, const G4int Z)
G4double getRadiusParameter(const ParticleType t, const G4int A, const G4int Z)
G4ThreadLocal SeparationEnergyFn getSeparationEnergy
Static pointer to the separation-energy function.
FermiMomentumType getFermiMomentumType() const
Get the Fermi-momentum type.
std::string getElementName(const G4int Z)
Get the name of the element from the atomic number.
G4double getMaximumNuclearRadius(const ParticleType t, const G4int A, const G4int Z)
G4double GetPDGMass() const
static G4ParticleTable * GetParticleTable()
G4double getSeparationEnergyRealForLight(const ParticleType t, const G4int A, const G4int Z)
Return the real separation energy only for light nuclei.
G4double getINCLMass(const G4int A, const G4int Z)
Get INCL nuclear mass (in MeV/c^2)
G4int getIsospin(const ParticleType t)
Get the isospin of a particle.
T max(const T t1, const T t2)
brief Return the largest of the two arguments
G4ThreadLocal NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
const G4double Pf
Fermi momentum [MeV/c].
G4double getNeutronSkinThickness() const
Get the neutron-skin thickness.
G4double getNeutronSkinAdditionalDiffuseness()
Get the value of the additional neutron skin diffuseness.
G4int drawRandomNaturalIsotope(const G4int Z)
G4double getTableSpeciesMass(const ParticleSpecies &p)
G4double getMomentumRMS(const G4int A, const G4int Z)
Return the RMS of the momentum distribution (light clusters)
#define INCL_DEFAULT_SEPARATION_ENERGY
IsotopicDistribution const & getNaturalIsotopicDistribution(const G4int Z)
G4double getRPCorrelationCoefficient(const ParticleType t)
Get the value of the r-p correlation coefficient.
G4int parseIUPACElement(std::string const &pS)
Parse a IUPAC element name.
double G4double
Definition: G4Types.hh:76
G4ThreadLocal G4double effectiveDeltaDecayThreshold
#define INCL_DEBUG(x)
G4double getSeparationEnergyINCL(const ParticleType t, const G4int, const G4int)
Return INCL's default separation energy.
G4double getFermiMomentumMassDependent(const G4int A, const G4int)
Return the value Fermi momentum from a fit.
G4double getRPCorrelationCoefficient(const ParticleType t) const
Get the r-p correlation coefficient.
std::string getShortName(const ParticleType t)
Get the short INCL name of the particle.
void initialize(Config const *const theConfig=0)
Initialize the particle table.
void setNeutronSeparationEnergy(const G4double s)
Setter for protonSeparationEnergy.
G4double getNeutronSkinThickness()
Get the value of the neutron skin thickness.
G4double getFermiMomentumConstantLight(const G4int A, const G4int Z)
Return the constant value of the Fermi momentum - special for light.
std::string getName(const ParticleType t)
Get the native INCL name of the particle.
G4ThreadLocal FermiMomentumFn getFermiMomentum