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