Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/particles/management/src/G4NucleiProperties.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 // G4NucleiProperties class implementation
 27 //
 28 // Author: V.Lara, October 1998
 29 // History:
 30 // - 17.11.1998, H.Kurashige - Migrated into particles category
 31 // - 31.03.2009, T.Koi - Migrated to AME03
 32 // --------------------------------------------------------------------
 33 
 34 #include "G4NucleiProperties.hh"
 35 
 36 #include "G4NucleiPropertiesTableAME12.hh"
 37 #include "G4NucleiPropertiesTheoreticalTable.hh"
 38 #include "G4ParticleTable.hh"
 39 #include "G4PhysicalConstants.hh"
 40 #include "G4SystemOfUnits.hh"
 41 
 42 G4ThreadLocal G4double G4NucleiProperties::mass_proton = -1.;
 43 G4ThreadLocal G4double G4NucleiProperties::mass_neutron = -1.;
 44 G4ThreadLocal G4double G4NucleiProperties::mass_deuteron = -1.;
 45 G4ThreadLocal G4double G4NucleiProperties::mass_triton = -1.;
 46 G4ThreadLocal G4double G4NucleiProperties::mass_alpha = -1.;
 47 G4ThreadLocal G4double G4NucleiProperties::mass_He3 = -1.;
 48 
 49 G4double G4NucleiProperties::GetNuclearMass(const G4double A, const G4double Z)
 50 {
 51   G4double mass = 0.0;
 52 
 53   if (std::fabs(A - G4int(A)) > 1.e-10) {
 54     mass = NuclearMass(A, Z);
 55   }
 56   else {
 57     // use mass table
 58     auto iZ = G4int(Z);
 59     auto iA = G4int(A);
 60     mass = GetNuclearMass(iA, iZ);
 61   }
 62   return mass;
 63 }
 64 
 65 G4double G4NucleiProperties::GetNuclearMass(const G4int A, const G4int Z)
 66 {
 67   if (mass_proton <= 0.0) {
 68     const G4ParticleDefinition* nucleus = nullptr;
 69     nucleus = G4ParticleTable::GetParticleTable()->FindParticle("neutron");
 70     if (nucleus != nullptr) mass_neutron = nucleus->GetPDGMass();
 71 
 72     nucleus = G4ParticleTable::GetParticleTable()->FindParticle("deuteron");
 73     if (nucleus != nullptr) mass_deuteron = nucleus->GetPDGMass();
 74 
 75     nucleus = G4ParticleTable::GetParticleTable()->FindParticle("triton");
 76     if (nucleus != nullptr) mass_triton = nucleus->GetPDGMass();
 77 
 78     nucleus = G4ParticleTable::GetParticleTable()->FindParticle("alpha");
 79     if (nucleus != nullptr) mass_alpha = nucleus->GetPDGMass();
 80 
 81     nucleus = G4ParticleTable::GetParticleTable()->FindParticle("He3");
 82     if (nucleus != nullptr) mass_He3 = nucleus->GetPDGMass();
 83 
 84     nucleus = G4ParticleTable::GetParticleTable()->FindParticle("proton");
 85     if (nucleus != nullptr) mass_proton = nucleus->GetPDGMass();
 86   }
 87 
 88   if (A < 1 || Z < 0 || Z > A) {
 89 #ifdef G4VERBOSE
 90     if (G4ParticleTable::GetParticleTable()->GetVerboseLevel() > 0) {
 91       G4cout << "G4NucleiProperties::GetNuclearMass: Wrong values for A = " << A << " and Z = " << Z
 92              << G4endl;
 93     }
 94 #endif
 95     return 0.0;
 96   }
 97 
 98   G4double mass = -1.;
 99   if ((Z <= 2)) {
100     // light nuclei
101     if ((Z == 1) && (A == 1)) {
102       mass = mass_proton;
103     }
104     else if ((Z == 0) && (A == 1)) {
105       mass = mass_neutron;
106     }
107     else if ((Z == 1) && (A == 2)) {
108       mass = mass_deuteron;
109     }
110     else if ((Z == 1) && (A == 3)) {
111       mass = mass_triton;
112     }
113     else if ((Z == 2) && (A == 4)) {
114       mass = mass_alpha;
115     }
116     else if ((Z == 2) && (A == 3)) {
117       mass = mass_He3;
118     }
119   }
120 
121   if (mass < 0.) {
122     if (G4NucleiPropertiesTableAME12::IsInTable(Z, A)) {
123       // AME table
124       mass = G4NucleiPropertiesTableAME12::GetNuclearMass(Z, A);
125     }
126     else if (G4NucleiPropertiesTheoreticalTable::IsInTable(Z, A)) {
127       // Theoretical table
128       mass = G4NucleiPropertiesTheoreticalTable::GetNuclearMass(Z, A);
129     }
130     else if (Z == A) {
131       mass = A * mass_proton;
132     }
133     else if (0 == Z) {
134       mass = A * mass_neutron;
135     }
136     else {
137       mass = NuclearMass(G4double(A), G4double(Z));
138     }
139   }
140 
141   if (mass < 0.) mass = 0.0;
142   return mass;
143 }
144 
145 G4bool G4NucleiProperties::IsInStableTable(const G4double A, const G4double Z)
146 {
147   auto iA = G4int(A);
148   auto iZ = G4int(Z);
149   return IsInStableTable(iA, iZ);
150 }
151 
152 G4bool G4NucleiProperties::IsInStableTable(const G4int A, const G4int Z)
153 {
154   if (A < 1 || Z < 0 || Z > A) {
155 #ifdef G4VERBOSE
156     if (G4ParticleTable::GetParticleTable()->GetVerboseLevel() > 0) {
157       G4cout << "G4NucleiProperties::IsInStableTable: Wrong values for A = " << A
158              << " and Z = " << Z << G4endl;
159     }
160 #endif
161     return false;
162   }
163 
164   return G4NucleiPropertiesTableAME12::IsInTable(Z, A);
165 }
166 
167 G4double G4NucleiProperties::GetMassExcess(const G4double A, const G4double Z)
168 {
169   auto iA = G4int(A);
170   auto iZ = G4int(Z);
171   return GetMassExcess(iA, iZ);
172 }
173 
174 G4double G4NucleiProperties::GetMassExcess(const G4int A, const G4int Z)
175 {
176   if (A < 1 || Z < 0 || Z > A) {
177 #ifdef G4VERBOSE
178     if (G4ParticleTable::GetParticleTable()->GetVerboseLevel() > 0) {
179       G4cout << "G4NucleiProperties::GetMassExccess: Wrong values for A = " << A << " and Z = " << Z
180              << G4endl;
181     }
182 #endif
183     return 0.0;
184   }
185 
186   if (G4NucleiPropertiesTableAME12::IsInTable(Z, A)) {
187     // AME table
188     return G4NucleiPropertiesTableAME12::GetMassExcess(Z, A);
189   }
190   if (G4NucleiPropertiesTheoreticalTable::IsInTable(Z, A)) {
191     return G4NucleiPropertiesTheoreticalTable::GetMassExcess(Z, A);
192   }
193   return MassExcess(A, Z);
194 }
195 
196 G4double G4NucleiProperties::GetAtomicMass(const G4double A, const G4double Z)
197 {
198   if (A < 1 || Z < 0 || Z > A) {
199 #ifdef G4VERBOSE
200     if (G4ParticleTable::GetParticleTable()->GetVerboseLevel() > 0) {
201       G4cout << "G4NucleiProperties::GetAtomicMass: Wrong values for A = " << A << " and Z = " << Z
202              << G4endl;
203     }
204 #endif
205     return 0.0;
206   }
207   if (std::fabs(A - G4int(A)) > 1.e-10) {
208     return AtomicMass(A, Z);
209   }
210 
211   auto iA = G4int(A);
212   auto iZ = G4int(Z);
213   if (G4NucleiPropertiesTableAME12::IsInTable(Z, A)) {
214     return G4NucleiPropertiesTableAME12::GetAtomicMass(Z, A);
215   }
216   if (G4NucleiPropertiesTheoreticalTable::IsInTable(iZ, iA)) {
217     return G4NucleiPropertiesTheoreticalTable::GetAtomicMass(iZ, iA);
218   }
219   return AtomicMass(A, Z);
220 }
221 
222 G4double G4NucleiProperties::GetBindingEnergy(const G4double A, const G4double Z)
223 {
224   auto iA = G4int(A);
225   auto iZ = G4int(Z);
226   return GetBindingEnergy(iA, iZ);
227 }
228 
229 G4double G4NucleiProperties::GetBindingEnergy(const G4int A, const G4int Z)
230 {
231   if (A < 1 || Z < 0 || Z > A) {
232 #ifdef G4VERBOSE
233     if (G4ParticleTable::GetParticleTable()->GetVerboseLevel() > 0) {
234       G4cout << "G4NucleiProperties::GetMassExccess: Wrong values for A = " << A << " and Z = " << Z
235              << G4endl;
236     }
237 #endif
238     return 0.0;
239   }
240 
241   if (G4NucleiPropertiesTableAME12::IsInTable(Z, A)) {
242     return G4NucleiPropertiesTableAME12::GetBindingEnergy(Z, A);
243   }
244   if (G4NucleiPropertiesTheoreticalTable::IsInTable(Z, A)) {
245     return G4NucleiPropertiesTheoreticalTable::GetBindingEnergy(Z, A);
246   }
247   return BindingEnergy(A, Z);
248 }
249 
250 G4double G4NucleiProperties::MassExcess(G4double A, G4double Z)
251 {
252   return GetAtomicMass(A, Z) - A * amu_c2;
253 }
254 
255 G4double G4NucleiProperties::AtomicMass(G4double A, G4double Z)
256 {
257   G4double hydrogen_mass_excess;
258   G4double neutron_mass_excess;
259   hydrogen_mass_excess = G4NucleiPropertiesTableAME12::GetMassExcess(1, 1);
260   neutron_mass_excess = G4NucleiPropertiesTableAME12::GetMassExcess(0, 1);
261   G4double mass =
262     (A - Z) * neutron_mass_excess + Z * hydrogen_mass_excess - BindingEnergy(A, Z) + A * amu_c2;
263   return mass;
264 }
265 
266 G4double G4NucleiProperties::NuclearMass(G4double A, G4double Z)
267 {
268   if (A < 1 || Z < 0 || Z > A) {
269 #ifdef G4VERBOSE
270     if (G4ParticleTable::GetParticleTable()->GetVerboseLevel() > 0) {
271       G4cout << "G4NucleiProperties::NuclearMass: Wrong values for A = " << A << " and Z = " << Z
272              << G4endl;
273     }
274 #endif
275     return 0.0;
276   }
277 
278   G4double mass = AtomicMass(A, Z);
279 
280   // atomic mass is converted to nuclear mass according to
281   // formula in  AME03 and 12
282   //
283   mass -= Z * electron_mass_c2;
284   mass += (14.4381 * std::pow(Z, 2.39) + 1.55468 * 1e-6 * std::pow(Z, 5.35)) * eV;
285 
286   return mass;
287 }
288 
289 G4double G4NucleiProperties::BindingEnergy(G4double A, G4double Z)
290 {
291   //
292   // Weitzsaecker's Mass formula
293   //
294   G4int Npairing = G4int(A - Z) % 2;  // pairing
295   G4int Zpairing = G4int(Z) % 2;
296   G4double binding = -15.67 * A  // nuclear volume
297                      + 17.23 * std::pow(A, 2. / 3.)  // surface energy
298                      + 93.15 * ((A / 2. - Z) * (A / 2. - Z)) / A  // asymmetry
299                      + 0.6984523 * Z * Z * std::pow(A, -1. / 3.);  // coulomb
300   if (Npairing == Zpairing) {
301     binding += (Npairing + Zpairing - 1) * 12.0 / std::sqrt(A);  // pairing
302   }
303 
304   return -binding * MeV;
305 }
306