Geant4  10.00.p03
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 
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 
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 
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 
254  G4ThreadLocal G4double constantFermiMomentum = PhysicalConstants::Pf;
255 
257  char iupacToInt(char c) {
258  return (char)(((G4int)'0')+elementIUPACDigits.find(c));
259  }
260 
262  char intToIUPAC(char n) { return elementIUPACDigits.at(n); }
263 
265  const NaturalIsotopicDistributions *getNaturalIsotopicDistributions() {
266  if(!theNaturalIsotopicDistributions)
267  theNaturalIsotopicDistributions = new NaturalIsotopicDistributions;
268  return theNaturalIsotopicDistributions;
269  }
270 
271  } // namespace
272 
273  void initialize(Config const * const theConfig /*=0*/) {
274  protonMass = theINCLNucleonMass;
275  neutronMass = theINCLNucleonMass;
276  piPlusMass = theINCLPionMass;
277  piMinusMass = theINCLPionMass;
278  piZeroMass = theINCLPionMass;
279 
280  if(theConfig && theConfig->getUseRealMasses()) {
283  } else {
286  }
287 
288 #ifndef INCLXX_IN_GEANT4_MODE
289  std::string dataFilePath;
290  if(theConfig)
291  dataFilePath = theConfig->getINCLXXDataFilePath();
293 #endif
294 
295 #ifdef INCLXX_IN_GEANT4_MODE
296  G4ParticleTable *theG4ParticleTable = G4ParticleTable::GetParticleTable();
297  theG4IonTable = theG4ParticleTable->GetIonTable();
298  theRealProtonMass = theG4ParticleTable->FindParticle("proton")->GetPDGMass() / MeV;
299  theRealNeutronMass = theG4ParticleTable->FindParticle("neutron")->GetPDGMass() / MeV;
300  theRealChargedPiMass = theG4ParticleTable->FindParticle("pi+")->GetPDGMass() / MeV;
301  theRealPiZeroMass = theG4ParticleTable->FindParticle("pi0")->GetPDGMass() / MeV;
302 #endif
303 
304  effectiveDeltaDecayThreshold = theRealNeutronMass + theRealChargedPiMass + 0.5;
305 
306  // Initialise the separation-energy function
307  if(!theConfig || theConfig->getSeparationEnergyType()==INCLSeparationEnergy)
309  else if(theConfig->getSeparationEnergyType()==RealSeparationEnergy)
313  else {
314  INCL_FATAL("Unrecognized separation-energy type in ParticleTable initialization: " << theConfig->getSeparationEnergyType() << std::endl);
315  std::abort();
316  return;
317  }
318 
319  // Initialise the Fermi-momentum function
320  if(!theConfig || theConfig->getFermiMomentumType()==ConstantFermiMomentum) {
322  if(theConfig) {
323  const G4double aFermiMomentum = theConfig->getFermiMomentum();
324  if(aFermiMomentum>0.)
325  constantFermiMomentum = aFermiMomentum;
326  else
327  constantFermiMomentum = PhysicalConstants::Pf;
328  } else {
329  constantFermiMomentum = PhysicalConstants::Pf;
330  }
331  } else if(theConfig->getFermiMomentumType()==ConstantLightFermiMomentum)
333  else if(theConfig->getFermiMomentumType()==MassDependentFermiMomentum)
335  else {
336  INCL_FATAL("Unrecognized Fermi-momentum type in ParticleTable initialization: " << theConfig->getFermiMomentumType() << std::endl);
337  std::abort();
338  return;
339  }
340 
341  // Initialise the r-p correlation coefficients
342  std::fill(rpCorrelationCoefficient, rpCorrelationCoefficient + UnknownParticle, 1.);
343  if(theConfig) {
344  rpCorrelationCoefficient[Proton] = theConfig->getRPCorrelationCoefficient(Proton);
345  rpCorrelationCoefficient[Neutron] = theConfig->getRPCorrelationCoefficient(Neutron);
346  }
347 
348  // Initialise the neutron-skin parameters
349  if(theConfig) {
350  neutronSkinThickness = theConfig->getNeutronSkinThickness();
351  neutronSkinAdditionalDiffuseness = theConfig->getNeutronSkinAdditionalDiffuseness();
352  }
353 
354  }
355 
357  // Actually this is the 3rd component of isospin (I_z) multiplied by 2!
358  if(t == Proton) {
359  return 1;
360  } else if(t == Neutron) {
361  return -1;
362  } else if(t == PiPlus) {
363  return 2;
364  } else if(t == PiMinus) {
365  return -2;
366  } else if(t == PiZero) {
367  return 0;
368  } else if(t == DeltaPlusPlus) {
369  return 3;
370  } else if(t == DeltaPlus) {
371  return 1;
372  } else if(t == DeltaZero) {
373  return -1;
374  } else if(t == DeltaMinus) {
375  return -3;
376  }
377 
378  INCL_ERROR("Requested isospin of an unknown particle!");
379  return -10; // Unknown
380  }
381 
382  std::string getShortName(const ParticleSpecies &s) {
383  if(s.theType==Composite)
384  return getShortName(s.theA,s.theZ);
385  else
386  return getShortName(s.theType);
387  }
388 
389  std::string getName(const ParticleSpecies &s) {
390  if(s.theType==Composite)
391  return getName(s.theA,s.theZ);
392  else
393  return getName(s.theType);
394  }
395 
396  std::string getName(const G4int A, const G4int Z) {
397  std::stringstream stream;
398  stream << getElementName(Z) << "-" << A;
399  return stream.str();
400  }
401 
402  std::string getShortName(const G4int A, const G4int Z) {
403  std::stringstream stream;
404  stream << getElementName(Z);
405  if(A>0)
406  stream << A;
407  return stream.str();
408  }
409 
410  std::string getName(const ParticleType p) {
411  if(p == G4INCL::Proton) {
412  return std::string("proton");
413  } else if(p == G4INCL::Neutron) {
414  return std::string("neutron");
415  } else if(p == G4INCL::DeltaPlusPlus) {
416  return std::string("delta++");
417  } else if(p == G4INCL::DeltaPlus) {
418  return std::string("delta+");
419  } else if(p == G4INCL::DeltaZero) {
420  return std::string("delta0");
421  } else if(p == G4INCL::DeltaMinus) {
422  return std::string("delta-");
423  } else if(p == G4INCL::PiPlus) {
424  return std::string("pi+");
425  } else if(p == G4INCL::PiZero) {
426  return std::string("pi0");
427  } else if(p == G4INCL::PiMinus) {
428  return std::string("pi-");
429  } else if(p == G4INCL::Composite) {
430  return std::string("composite");
431  }
432  return std::string("unknown");
433  }
434 
435  std::string getShortName(const ParticleType p) {
436  if(p == G4INCL::Proton) {
437  return std::string("p");
438  } else if(p == G4INCL::Neutron) {
439  return std::string("n");
440  } else if(p == G4INCL::DeltaPlusPlus) {
441  return std::string("d++");
442  } else if(p == G4INCL::DeltaPlus) {
443  return std::string("d+");
444  } else if(p == G4INCL::DeltaZero) {
445  return std::string("d0");
446  } else if(p == G4INCL::DeltaMinus) {
447  return std::string("d-");
448  } else if(p == G4INCL::PiPlus) {
449  return std::string("pi+");
450  } else if(p == G4INCL::PiZero) {
451  return std::string("pi0");
452  } else if(p == G4INCL::PiMinus) {
453  return std::string("pi-");
454  } else if(p == G4INCL::Composite) {
455  return std::string("comp");
456  }
457  return std::string("unknown");
458  }
459 
461  if(pt == Proton) {
462  return protonMass;
463  } else if(pt == Neutron) {
464  return neutronMass;
465  } else if(pt == PiPlus) {
466  return piPlusMass;
467  } else if(pt == PiMinus) {
468  return piMinusMass;
469  } else if(pt == PiZero) {
470  return piZeroMass;
471  } else {
472  INCL_ERROR("getMass : Unknown particle type." << std::endl);
473  return 0.0;
474  }
475  }
476 
478  switch(t) {
479  case Proton:
480  return theRealProtonMass;
481  break;
482  case Neutron:
483  return theRealNeutronMass;
484  break;
485  case PiPlus:
486  case PiMinus:
487  return theRealChargedPiMass;
488  break;
489  case PiZero:
490  return theRealPiZeroMass;
491  break;
492  default:
493  INCL_ERROR("Particle::getRealMass : Unknown particle type." << std::endl);
494  return 0.0;
495  break;
496  }
497  }
498 
499  G4double getRealMass(const G4int A, const G4int Z) {
500 // assert(A>=0);
501  // For nuclei with Z<0 or Z>A, assume that the exotic charge state is due to pions
502  if(Z<0)
503  return A*neutronMass - Z*getRealMass(PiMinus);
504  else if(Z>A)
505  return A*protonMass + (A-Z)*getRealMass(PiPlus);
506  else if(Z==0)
507  return A*getRealMass(Neutron);
508  else if(A==Z)
509  return A*getRealMass(Proton);
510  else if(A>1) {
511 #ifndef INCLXX_IN_GEANT4_MODE
512  return ::G4INCL::NuclearMassTable::getMass(A,Z);
513 #else
514  return theG4IonTable->GetNucleusMass(Z,A) / MeV;
515 #endif
516  } else
517  return 0.;
518  }
519 
520  G4double getINCLMass(const G4int A, const G4int Z) {
521 // assert(A>=0);
522  // For nuclei with Z<0 or Z>A, assume that the exotic charge state is due to pions
523  if(Z<0)
524  return A*neutronMass - Z*getINCLMass(PiMinus);
525  else if(Z>A)
526  return A*protonMass + (A-Z)*getINCLMass(PiPlus);
527  else if(A>1)
528  return Z*(protonMass - protonSeparationEnergy) + (A-Z)*(neutronMass - neutronSeparationEnergy);
529  else if(A==1 && Z==0)
530  return getINCLMass(Neutron);
531  else if(A==1 && Z==1)
532  return getINCLMass(Proton);
533  else
534  return 0.;
535  }
536 
537  G4double getTableQValue(const G4int A1, const G4int Z1, const G4int A2, const G4int Z2) {
538  return getTableMass(A1,Z1) + getTableMass(A2,Z2) - getTableMass(A1+A2,Z1+Z2);
539  }
540 
541  G4double getTableQValue(const G4int A1, const G4int Z1, const G4int A2, const G4int Z2, const G4int A3, const G4int Z3) {
542  return getTableMass(A1,Z1) + getTableMass(A2,Z2) - getTableMass(A3,Z3) - getTableMass(A1+A2-A3,Z1+Z2-Z3);
543  }
544 
546  if(p.theType == Composite)
547  return (*getTableMass)(p.theA, p.theZ);
548  else
549  return (*getTableParticleMass)(p.theType);
550  }
551 
553  switch(t) {
554  case Proton:
555  case Neutron:
556  case DeltaPlusPlus:
557  case DeltaPlus:
558  case DeltaZero:
559  case DeltaMinus:
560  return 1;
561  break;
562  case PiPlus:
563  case PiMinus:
564  case PiZero:
565  return 0;
566  break;
567  default:
568  return 0;
569  break;
570  }
571  }
572 
574  switch(t) {
575  case DeltaPlusPlus:
576  return 2;
577  break;
578  case Proton:
579  case DeltaPlus:
580  case PiPlus:
581  return 1;
582  break;
583  case Neutron:
584  case DeltaZero:
585  case PiZero:
586  return 0;
587  break;
588  case DeltaMinus:
589  case PiMinus:
590  return -1;
591  break;
592  default:
593  return 0;
594  break;
595  }
596  }
597 
598  G4double getNuclearRadius(const ParticleType t, const G4int A, const G4int Z) {
599 // assert(A>=0);
600  if(A >= 19 || (A < 6 && A >= 2)) {
601  // For large (Woods-Saxon or Modified Harmonic Oscillator) or small
602  // (Gaussian) nuclei, the radius parameter is just the nuclear radius
603  return getRadiusParameter(t,A,Z);
604  } else if(A < clusterTableASize && Z>=0 && Z < clusterTableZSize && A >= 6) {
605  const G4double thisRMS = positionRMS[Z][A];
606  if(thisRMS>0.0)
607  return thisRMS;
608  else {
609  INCL_DEBUG("getNuclearRadius: Radius for nucleus A = " << A << " Z = " << Z << " is not available" << std::endl
610  << "returning radius for C12");
611  return positionRMS[6][12];
612  }
613  } else if(A < 19) {
614  const G4double theRadiusParameter = getRadiusParameter(t, A, Z);
615  const G4double theDiffusenessParameter = getSurfaceDiffuseness(t, A, Z);
616  // The formula yields the nuclear RMS radius based on the parameters of
617  // the nuclear-density function
618  return 1.581*theDiffusenessParameter*
619  (2.+5.*theRadiusParameter)/(2.+3.*theRadiusParameter);
620  } else {
621  INCL_ERROR("getNuclearRadius: No radius for nucleus A = " << A << " Z = " << Z << std::endl);
622  return 0.0;
623  }
624  }
625 
628  }
629 
631 // assert(A>0);
632  if(A >= 28) {
633  // phenomenological radius fit
634  G4double r0 = (2.745e-4 * A + 1.063) * std::pow(A, 1.0/3.0);
635  if(t==Neutron)
636  r0 += neutronSkinThickness;
637  return r0;
638  } else if(A < 6 && A >= 2) {
639  if(Z<clusterTableZSize && Z>=0) {
640  const G4double thisRMS = positionRMS[Z][A];
641  if(thisRMS>0.0)
642  return thisRMS;
643  else {
644  INCL_DEBUG("getRadiusParameter: Radius for nucleus A = " << A << " Z = " << Z << " is not available" << std::endl
645  << "returning radius for C12");
646  return positionRMS[6][12];
647  }
648  } else {
649  INCL_DEBUG("getRadiusParameter: Radius for nucleus A = " << A << " Z = " << Z << " is not available" << std::endl
650  << "returning radius for C12");
651  return positionRMS[6][12];
652  }
653  } else if(A < 28 && A >= 6) {
654  return mediumRadius[A-1];
655  // return 1.581*mediumDiffuseness[A-1]*(2.+5.*mediumRadius[A-1])/(2.+3.*mediumRadius[A-1]);
656  } else {
657  INCL_ERROR("getRadiusParameter: No radius for nucleus A = " << A << " Z = " << Z << std::endl);
658  return 0.0;
659  }
660  }
661 
663  const G4double XFOISA = 8.0;
664  if(A >= 19) {
665  return getNuclearRadius(t,A,Z) + XFOISA * getSurfaceDiffuseness(t,A,Z);
666  } else if(A < 19 && A >= 6) {
667  return 5.5 + 0.3 * (G4double(A) - 6.0)/12.0;
668  } else if(A >= 2) {
669  return getNuclearRadius(t, A, Z) + 4.5;
670  } else {
671  INCL_ERROR("getMaximumNuclearRadius : No maximum radius for nucleus A = " << A << " Z = " << Z << std::endl);
672  return 0.0;
673  }
674  }
675 
677  if(A >= 28) {
678  G4double a = 1.63e-4 * A + 0.510;
679  if(t==Neutron)
680  a += neutronSkinAdditionalDiffuseness;
681  return a;
682  } else if(A < 28 && A >= 19) {
683  return mediumDiffuseness[A-1];
684  } else if(A < 19 && A >= 6) {
685  return mediumDiffuseness[A-1];
686  } else if(A < 6 && A >= 2) {
687  INCL_ERROR("getSurfaceDiffuseness: was called for A = " << A << " Z = " << Z << std::endl);
688  return 0.0;
689  } else {
690  INCL_ERROR("getSurfaceDiffuseness: No diffuseness for nucleus A = " << A << " Z = " << Z << std::endl);
691  return 0.0;
692  }
693  }
694 
695  G4double getMomentumRMS(const G4int A, const G4int Z) {
696 // assert(Z>=0 && A>=0 && Z<=A);
698  }
699 
700  G4double getSeparationEnergyINCL(const ParticleType t, const G4int /*A*/, const G4int /*Z*/) {
701  if(t==Proton)
702  return theINCLProtonSeparationEnergy;
703  else if(t==Neutron)
704  return theINCLNeutronSeparationEnergy;
705  else {
706  INCL_ERROR("ParticleTable::getSeparationEnergyINCL : Unknown particle type." << std::endl);
707  return 0.0;
708  }
709  }
710 
712  // Real separation energies for all nuclei
713  if(t==Proton)
714  return (*getTableParticleMass)(Proton) + (*getTableMass)(A-1,Z-1) - (*getTableMass)(A,Z);
715  else if(t==Neutron)
716  return (*getTableParticleMass)(Neutron) + (*getTableMass)(A-1,Z) - (*getTableMass)(A,Z);
717  else {
718  INCL_ERROR("ParticleTable::getSeparationEnergyReal : Unknown particle type." << std::endl);
719  return 0.0;
720  }
721  }
722 
724  // Real separation energies for light nuclei, fixed values for heavy nuclei
726  return getSeparationEnergyReal(t, A, Z);
727  else
728  return getSeparationEnergyINCL(t, A, Z);
729  }
730 
731  G4double getProtonSeparationEnergy() { return protonSeparationEnergy; }
732 
733  G4double getNeutronSeparationEnergy() { return neutronSeparationEnergy; }
734 
735  void setProtonSeparationEnergy(const G4double s) { protonSeparationEnergy = s; }
736 
737  void setNeutronSeparationEnergy(const G4double s) { neutronSeparationEnergy = s; }
738 
739  std::string getElementName(const G4int Z) {
740  if(Z<1) {
741  INCL_WARN("getElementName called with Z<1" << std::endl);
742  return elementTable[0];
743  } else if(Z<elementTableSize)
744  return elementTable[Z];
745  else
746  return getIUPACElementName(Z);
747  }
748 
749  std::string getIUPACElementName(const G4int Z) {
750  std::stringstream elementStream;
751  elementStream << Z;
752  std::string elementName = elementStream.str();
753  std::transform(elementName.begin(), elementName.end(), elementName.begin(), intToIUPAC);
754  elementName[0] = std::toupper(elementName.at(0));
755  return elementName;
756  }
757 
758  G4int parseElement(std::string pS) {
759  // Normalize the element name
760  std::transform(pS.begin(), pS.end(), pS.begin(), ::tolower);
761  pS[0] = ::toupper(pS[0]);
762 
763  const std::string *iter = std::find(elementTable, elementTable+elementTableSize, pS);
764  if(iter != elementTable+elementTableSize)
765  return iter - elementTable;
766  else
768  }
769 
770  G4int parseIUPACElement(std::string const &s) {
771  // Normalise to lower case
772  std::string elementName(s);
773  std::transform(elementName.begin(), elementName.end(), elementName.begin(), ::tolower);
774  // Return 0 if the element name contains anything but IUPAC digits
775  if(elementName.find_first_not_of(elementIUPACDigits)!=std::string::npos)
776  return 0;
777  std::transform(elementName.begin(), elementName.end(), elementName.begin(), iupacToInt);
778  std::stringstream elementStream(elementName);
779  G4int Z;
780  elementStream >> Z;
781  return Z;
782  }
783 
785  return getNaturalIsotopicDistributions()->getIsotopicDistribution(Z);
786  }
787 
789  return getNaturalIsotopicDistributions()->drawRandomIsotope(Z);
790  }
791 
792  G4double getFermiMomentumConstant(const G4int /*A*/, const G4int /*Z*/) {
793  return constantFermiMomentum;
794  }
795 
797 // assert(Z>0 && A>0 && Z<=A);
799  const G4double rms = momentumRMS[Z][A];
800  return ((rms>0.) ? rms : momentumRMS[6][12]) * Math::sqrtFiveThirds;
801  } else
802  return getFermiMomentumConstant(A,Z);
803  }
804 
806 // assert(A>0);
807  static const G4double alphaParam = 259.416; // MeV/c
808  static const G4double betaParam = 152.824; // MeV/c
809  static const G4double gammaParam = 9.5157E-2;
810  return alphaParam - betaParam*std::exp(-gammaParam*((G4double)A));
811  }
812 
814 // assert(t==Proton || t==Neutron);
815  return rpCorrelationCoefficient[t];
816  }
817 
818  G4double getNeutronSkinThickness() { return neutronSkinThickness; }
819 
820  G4double getNeutronSkinAdditionalDiffuseness() { return neutronSkinAdditionalDiffuseness; }
821 
827 
828  } // namespace ParticleTable
829 } // namespace G4INCL
830 
#define INCL_FATAL(x)
The INCL configuration object.
Definition: G4INCLConfig.hh:67
const G4double sqrtThreeFifths
static const double MeV
Definition: G4SIunits.hh:193
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.
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 getFermiMomentum() const
Get the Fermi momentum.
G4double a
Definition: TRTMaterials.hh:39
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)
static const double s
Definition: G4SIunits.hh:150
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.
static const G4double A[nN]
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