Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4NucleiProperties class implementation << 27 // 26 // 28 // Author: V.Lara, October 1998 << 27 // $Id: G4NucleiProperties.cc 69015 2013-04-15 09:46:48Z gcosmo $ 29 // History: << 28 // 30 // - 17.11.1998, H.Kurashige - Migrated into p << 29 // 31 // - 31.03.2009, T.Koi - Migrated to AME03 << 30 // ------------------------------------------------------------ 32 // ------------------------------------------- << 31 // GEANT 4 class header file >> 32 // >> 33 // ------------------------------------------------------------ >> 34 // >> 35 // Hadronic Process: Nuclear De-excitations >> 36 // by V. Lara (Oct 1998) >> 37 // Migrate into particles category by H.Kurashige (17 Nov. 98) >> 38 // Added Shell-Pairing corrections to the Cameron mass >> 39 // excess formula by V.Lara (9 May 99) >> 40 // 090331 Migrate to AME03 by Koi, Tatsumi 33 41 34 #include "G4NucleiProperties.hh" 42 #include "G4NucleiProperties.hh" 35 << 36 #include "G4NucleiPropertiesTableAME12.hh" << 37 #include "G4NucleiPropertiesTheoreticalTable.h << 38 #include "G4ParticleTable.hh" << 39 #include "G4PhysicalConstants.hh" 43 #include "G4PhysicalConstants.hh" 40 #include "G4SystemOfUnits.hh" 44 #include "G4SystemOfUnits.hh" 41 45 42 G4ThreadLocal G4double G4NucleiProperties::mas 46 G4ThreadLocal G4double G4NucleiProperties::mass_proton = -1.; 43 G4ThreadLocal G4double G4NucleiProperties::mas 47 G4ThreadLocal G4double G4NucleiProperties::mass_neutron = -1.; 44 G4ThreadLocal G4double G4NucleiProperties::mas 48 G4ThreadLocal G4double G4NucleiProperties::mass_deuteron = -1.; 45 G4ThreadLocal G4double G4NucleiProperties::mas 49 G4ThreadLocal G4double G4NucleiProperties::mass_triton = -1.; 46 G4ThreadLocal G4double G4NucleiProperties::mas 50 G4ThreadLocal G4double G4NucleiProperties::mass_alpha = -1.; 47 G4ThreadLocal G4double G4NucleiProperties::mas 51 G4ThreadLocal G4double G4NucleiProperties::mass_He3 = -1.; 48 52 49 G4double G4NucleiProperties::GetNuclearMass(co 53 G4double G4NucleiProperties::GetNuclearMass(const G4double A, const G4double Z) 50 { 54 { 51 G4double mass = 0.0; << 55 G4double mass=0.0; 52 56 53 if (std::fabs(A - G4int(A)) > 1.e-10) { 57 if (std::fabs(A - G4int(A)) > 1.e-10) { 54 mass = NuclearMass(A, Z); << 58 mass = NuclearMass(A,Z); 55 } << 59 56 else { << 60 } else { 57 // use mass table 61 // use mass table 58 auto iZ = G4int(Z); << 62 G4int iZ = G4int(Z); 59 auto iA = G4int(A); << 63 G4int iA = G4int(A); 60 mass = GetNuclearMass(iA, iZ); << 64 mass =GetNuclearMass(iA,iZ); 61 } 65 } 62 return mass; << 66 >> 67 return mass; 63 } 68 } 64 69 >> 70 65 G4double G4NucleiProperties::GetNuclearMass(co 71 G4double G4NucleiProperties::GetNuclearMass(const G4int A, const G4int Z) 66 { 72 { 67 if (mass_proton <= 0.0) { << 73 if (mass_proton <= 0.0 ) { 68 const G4ParticleDefinition* nucleus = null << 74 const G4ParticleDefinition * nucleus = 0; 69 nucleus = G4ParticleTable::GetParticleTabl << 75 nucleus = G4ParticleTable::GetParticleTable()->FindParticle("proton"); // proton 70 if (nucleus != nullptr) mass_neutron = nuc << 76 if (nucleus!=0) mass_proton = nucleus->GetPDGMass(); >> 77 nucleus = G4ParticleTable::GetParticleTable()->FindParticle("neutron"); // neutron >> 78 if (nucleus!=0) mass_neutron = nucleus->GetPDGMass(); >> 79 nucleus = G4ParticleTable::GetParticleTable()->FindParticle("deuteron"); // deuteron >> 80 if (nucleus!=0) mass_deuteron = nucleus->GetPDGMass(); >> 81 nucleus = G4ParticleTable::GetParticleTable()->FindParticle("triton"); // triton >> 82 if (nucleus!=0) mass_triton = nucleus->GetPDGMass(); >> 83 nucleus = G4ParticleTable::GetParticleTable()->FindParticle("alpha"); // alpha >> 84 if (nucleus!=0) mass_alpha = nucleus->GetPDGMass(); >> 85 nucleus = G4ParticleTable::GetParticleTable()->FindParticle("He3"); // He3 >> 86 if (nucleus!=0) mass_He3 = nucleus->GetPDGMass(); 71 87 72 nucleus = G4ParticleTable::GetParticleTabl << 73 if (nucleus != nullptr) mass_deuteron = nu << 74 << 75 nucleus = G4ParticleTable::GetParticleTabl << 76 if (nucleus != nullptr) mass_triton = nucl << 77 << 78 nucleus = G4ParticleTable::GetParticleTabl << 79 if (nucleus != nullptr) mass_alpha = nucle << 80 << 81 nucleus = G4ParticleTable::GetParticleTabl << 82 if (nucleus != nullptr) mass_He3 = nucleus << 83 << 84 nucleus = G4ParticleTable::GetParticleTabl << 85 if (nucleus != nullptr) mass_proton = nucl << 86 } 88 } 87 89 88 if (A < 1 || Z < 0 || Z > A) { 90 if (A < 1 || Z < 0 || Z > A) { 89 #ifdef G4VERBOSE 91 #ifdef G4VERBOSE 90 if (G4ParticleTable::GetParticleTable()->G << 92 if (G4ParticleTable::GetParticleTable()->GetVerboseLevel()>0) { 91 G4cout << "G4NucleiProperties::GetNuclea << 93 G4cout << "G4NucleiProperties::GetNuclearMass: Wrong values for A = " << A 92 << G4endl; << 94 << " and Z = " << Z << G4endl; 93 } 95 } 94 #endif << 96 #endif 95 return 0.0; 97 return 0.0; 96 } 98 } 97 << 99 98 G4double mass = -1.; << 100 G4double mass= -1.; 99 if ((Z <= 2)) { << 101 if ( (Z<=2) ) { 100 // light nuclei 102 // light nuclei 101 if ((Z == 1) && (A == 1)) { << 103 if ( (Z==1)&&(A==1) ) { 102 mass = mass_proton; 104 mass = mass_proton; 103 } << 105 } else if ( (Z==0)&&(A==1) ) { 104 else if ((Z == 0) && (A == 1)) { << 105 mass = mass_neutron; 106 mass = mass_neutron; 106 } << 107 } else if ( (Z==1)&&(A==2) ) { 107 else if ((Z == 1) && (A == 2)) { << 108 mass = mass_deuteron; 108 mass = mass_deuteron; 109 } << 109 } else if ( (Z==1)&&(A==3) ) { 110 else if ((Z == 1) && (A == 3)) { << 111 mass = mass_triton; 110 mass = mass_triton; 112 } << 111 } else if ( (Z==2)&&(A==4) ) { 113 else if ((Z == 2) && (A == 4)) { << 114 mass = mass_alpha; 112 mass = mass_alpha; 115 } << 113 } else if ( (Z==2)&&(A==3) ) { 116 else if ((Z == 2) && (A == 3)) { << 117 mass = mass_He3; 114 mass = mass_He3; 118 } 115 } 119 } 116 } 120 << 117 121 if (mass < 0.) { 118 if (mass < 0.) { 122 if (G4NucleiPropertiesTableAME12::IsInTabl << 119 if (G4NucleiPropertiesTableAME03::IsInTable(Z,A)) { 123 // AME table << 120 // AME 03 table 124 mass = G4NucleiPropertiesTableAME12::Get << 121 mass = G4NucleiPropertiesTableAME03::GetNuclearMass(Z,A); 125 } << 122 } else if (G4NucleiPropertiesTheoreticalTable::IsInTable(Z,A)){ 126 else if (G4NucleiPropertiesTheoreticalTabl << 127 // Theoretical table 123 // Theoretical table 128 mass = G4NucleiPropertiesTheoreticalTabl << 124 mass = G4NucleiPropertiesTheoreticalTable::GetNuclearMass(Z,A); 129 } << 125 } else { 130 else if (Z == A) { << 126 mass = NuclearMass(G4double(A),G4double(Z)); 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 << 138 } 127 } 139 } 128 } 140 129 141 if (mass < 0.) mass = 0.0; 130 if (mass < 0.) mass = 0.0; 142 return mass; 131 return mass; 143 } 132 } 144 133 145 G4bool G4NucleiProperties::IsInStableTable(con 134 G4bool G4NucleiProperties::IsInStableTable(const G4double A, const G4double Z) 146 { 135 { 147 auto iA = G4int(A); << 136 G4int iA = G4int(A); 148 auto iZ = G4int(Z); << 137 G4int iZ = G4int(Z); 149 return IsInStableTable(iA, iZ); 138 return IsInStableTable(iA, iZ); 150 } 139 } 151 140 152 G4bool G4NucleiProperties::IsInStableTable(con << 141 G4bool G4NucleiProperties::IsInStableTable(const G4int A, const int Z) 153 { 142 { 154 if (A < 1 || Z < 0 || Z > A) { 143 if (A < 1 || Z < 0 || Z > A) { 155 #ifdef G4VERBOSE 144 #ifdef G4VERBOSE 156 if (G4ParticleTable::GetParticleTable()->G << 145 if (G4ParticleTable::GetParticleTable()->GetVerboseLevel()>0) { 157 G4cout << "G4NucleiProperties::IsInStabl << 146 G4cout << "G4NucleiProperties::IsInStableTable: Wrong values for A = " 158 << " and Z = " << Z << G4endl; << 147 << A << " and Z = " << Z << G4endl; 159 } 148 } 160 #endif << 149 #endif 161 return false; 150 return false; 162 } << 151 } >> 152 >> 153 return G4NucleiPropertiesTableAME03::IsInTable(Z,A); 163 154 164 return G4NucleiPropertiesTableAME12::IsInTab << 165 } 155 } 166 156 167 G4double G4NucleiProperties::GetMassExcess(con 157 G4double G4NucleiProperties::GetMassExcess(const G4double A, const G4double Z) 168 { 158 { 169 auto iA = G4int(A); << 159 G4int iA = G4int(A); 170 auto iZ = G4int(Z); << 160 G4int iZ = G4int(Z); 171 return GetMassExcess(iA, iZ); << 161 return GetMassExcess(iA,iZ); 172 } 162 } 173 163 174 G4double G4NucleiProperties::GetMassExcess(con 164 G4double G4NucleiProperties::GetMassExcess(const G4int A, const G4int Z) 175 { 165 { 176 if (A < 1 || Z < 0 || Z > A) { 166 if (A < 1 || Z < 0 || Z > A) { 177 #ifdef G4VERBOSE 167 #ifdef G4VERBOSE 178 if (G4ParticleTable::GetParticleTable()->G << 168 if (G4ParticleTable::GetParticleTable()->GetVerboseLevel()>0) { 179 G4cout << "G4NucleiProperties::GetMassEx << 169 G4cout << "G4NucleiProperties::GetMassExccess: Wrong values for A = " 180 << G4endl; << 170 << A << " and Z = " << Z << G4endl; 181 } 171 } 182 #endif << 172 #endif 183 return 0.0; 173 return 0.0; 184 } << 174 >> 175 } else { 185 176 186 if (G4NucleiPropertiesTableAME12::IsInTable( << 177 if (G4NucleiPropertiesTableAME03::IsInTable(Z,A)){ 187 // AME table << 178 return G4NucleiPropertiesTableAME03::GetMassExcess(Z,A); 188 return G4NucleiPropertiesTableAME12::GetMa << 179 } else if (G4NucleiPropertiesTheoreticalTable::IsInTable(Z,A)){ 189 } << 180 return G4NucleiPropertiesTheoreticalTable::GetMassExcess(Z,A); 190 if (G4NucleiPropertiesTheoreticalTable::IsIn << 181 } else { 191 return G4NucleiPropertiesTheoreticalTable: << 182 return MassExcess(A,Z); >> 183 } 192 } 184 } 193 return MassExcess(A, Z); << 185 194 } 186 } 195 187 >> 188 196 G4double G4NucleiProperties::GetAtomicMass(con 189 G4double G4NucleiProperties::GetAtomicMass(const G4double A, const G4double Z) 197 { 190 { 198 if (A < 1 || Z < 0 || Z > A) { 191 if (A < 1 || Z < 0 || Z > A) { 199 #ifdef G4VERBOSE 192 #ifdef G4VERBOSE 200 if (G4ParticleTable::GetParticleTable()->G << 193 if (G4ParticleTable::GetParticleTable()->GetVerboseLevel()>0) { 201 G4cout << "G4NucleiProperties::GetAtomic << 194 G4cout << "G4NucleiProperties::GetAtomicMass: Wrong values for A = " 202 << G4endl; << 195 << A << " and Z = " << Z << G4endl; 203 } 196 } 204 #endif << 197 #endif 205 return 0.0; 198 return 0.0; 206 } << 207 if (std::fabs(A - G4int(A)) > 1.e-10) { << 208 return AtomicMass(A, Z); << 209 } << 210 199 211 auto iA = G4int(A); << 200 } else if (std::fabs(A - G4int(A)) > 1.e-10) { 212 auto iZ = G4int(Z); << 201 return AtomicMass(A,Z); 213 if (G4NucleiPropertiesTableAME12::IsInTable( << 202 214 return G4NucleiPropertiesTableAME12::GetAt << 203 } else { 215 } << 204 G4int iA = G4int(A); 216 if (G4NucleiPropertiesTheoreticalTable::IsIn << 205 G4int iZ = G4int(Z); 217 return G4NucleiPropertiesTheoreticalTable: << 206 if (G4NucleiPropertiesTableAME03::IsInTable(iZ,iA)) { >> 207 return G4NucleiPropertiesTableAME03::GetAtomicMass(iZ,iA); >> 208 } else if (G4NucleiPropertiesTheoreticalTable::IsInTable(iZ,iA)){ >> 209 return G4NucleiPropertiesTheoreticalTable::GetAtomicMass(iZ,iA); >> 210 } else { >> 211 return AtomicMass(A,Z); >> 212 } 218 } 213 } 219 return AtomicMass(A, Z); << 220 } 214 } 221 215 222 G4double G4NucleiProperties::GetBindingEnergy( 216 G4double G4NucleiProperties::GetBindingEnergy(const G4double A, const G4double Z) 223 { 217 { 224 auto iA = G4int(A); << 218 G4int iA = G4int(A); 225 auto iZ = G4int(Z); << 219 G4int iZ = G4int(Z); 226 return GetBindingEnergy(iA, iZ); << 220 return GetBindingEnergy(iA,iZ); 227 } 221 } 228 222 229 G4double G4NucleiProperties::GetBindingEnergy( 223 G4double G4NucleiProperties::GetBindingEnergy(const G4int A, const G4int Z) 230 { 224 { 231 if (A < 1 || Z < 0 || Z > A) { 225 if (A < 1 || Z < 0 || Z > A) { 232 #ifdef G4VERBOSE 226 #ifdef G4VERBOSE 233 if (G4ParticleTable::GetParticleTable()->G << 227 if (G4ParticleTable::GetParticleTable()->GetVerboseLevel()>0) { 234 G4cout << "G4NucleiProperties::GetMassEx << 228 G4cout << "G4NucleiProperties::GetMassExccess: Wrong values for A = " 235 << G4endl; << 229 << A << " and Z = " << Z << G4endl; 236 } 230 } 237 #endif 231 #endif 238 return 0.0; 232 return 0.0; 239 } << 240 233 241 if (G4NucleiPropertiesTableAME12::IsInTable( << 234 } else { 242 return G4NucleiPropertiesTableAME12::GetBi << 235 if (G4NucleiPropertiesTableAME03::IsInTable(Z,A)) { 243 } << 236 return G4NucleiPropertiesTableAME03::GetBindingEnergy(Z,A); 244 if (G4NucleiPropertiesTheoreticalTable::IsIn << 237 } else if (G4NucleiPropertiesTheoreticalTable::IsInTable(Z,A)) { 245 return G4NucleiPropertiesTheoreticalTable: << 238 return G4NucleiPropertiesTheoreticalTable::GetBindingEnergy(Z,A); >> 239 }else { >> 240 return BindingEnergy(A,Z); >> 241 } >> 242 246 } 243 } 247 return BindingEnergy(A, Z); << 248 } 244 } 249 245 250 G4double G4NucleiProperties::MassExcess(G4doub << 246 >> 247 G4double G4NucleiProperties::MassExcess(G4double A, G4double Z) 251 { 248 { 252 return GetAtomicMass(A, Z) - A * amu_c2; << 249 return GetAtomicMass(A,Z) - A*amu_c2; 253 } 250 } 254 251 255 G4double G4NucleiProperties::AtomicMass(G4doub << 252 G4double G4NucleiProperties::AtomicMass(G4double A, G4double Z) 256 { 253 { 257 G4double hydrogen_mass_excess; << 254 const G4double hydrogen_mass_excess = G4NucleiPropertiesTableAME03::GetMassExcess(1,1); 258 G4double neutron_mass_excess; << 255 const G4double neutron_mass_excess = G4NucleiPropertiesTableAME03::GetMassExcess(0,1); 259 hydrogen_mass_excess = G4NucleiPropertiesTab << 256 260 neutron_mass_excess = G4NucleiPropertiesTabl << 261 G4double mass = 257 G4double mass = 262 (A - Z) * neutron_mass_excess + Z * hydrog << 258 (A-Z)*neutron_mass_excess + Z*hydrogen_mass_excess - BindingEnergy(A,Z) + A*amu_c2; >> 259 263 return mass; 260 return mass; 264 } 261 } 265 262 266 G4double G4NucleiProperties::NuclearMass(G4dou << 263 G4double G4NucleiProperties::NuclearMass(G4double A, G4double Z) 267 { 264 { 268 if (A < 1 || Z < 0 || Z > A) { 265 if (A < 1 || Z < 0 || Z > A) { 269 #ifdef G4VERBOSE 266 #ifdef G4VERBOSE 270 if (G4ParticleTable::GetParticleTable()->G << 267 if (G4ParticleTable::GetParticleTable()->GetVerboseLevel()>0) { 271 G4cout << "G4NucleiProperties::NuclearMa << 268 G4cout << "G4NucleiProperties::NuclearMass: Wrong values for A = " 272 << G4endl; << 269 << A << " and Z = " << Z << G4endl; 273 } 270 } 274 #endif << 271 #endif 275 return 0.0; 272 return 0.0; 276 } 273 } 277 274 278 G4double mass = AtomicMass(A, Z); << 275 G4double mass = AtomicMass(A,Z); 279 << 276 // atomic mass is converted to nuclear mass according formula in AME03 280 // atomic mass is converted to nuclear mass << 277 mass -= Z*electron_mass_c2; 281 // formula in AME03 and 12 << 278 mass += ( 14.4381*std::pow ( Z , 2.39 ) + 1.55468*1e-6*std::pow ( Z , 5.35 ) )*eV; 282 // << 283 mass -= Z * electron_mass_c2; << 284 mass += (14.4381 * std::pow(Z, 2.39) + 1.554 << 285 279 286 return mass; 280 return mass; 287 } 281 } 288 282 289 G4double G4NucleiProperties::BindingEnergy(G4d << 283 G4double G4NucleiProperties::BindingEnergy(G4double A, G4double Z) 290 { << 284 { 291 // 285 // 292 // Weitzsaecker's Mass formula 286 // Weitzsaecker's Mass formula 293 // 287 // 294 G4int Npairing = G4int(A - Z) % 2; // pairi << 288 G4int Npairing = G4int(A-Z)%2; // pairing 295 G4int Zpairing = G4int(Z) % 2; << 289 G4int Zpairing = G4int(Z)%2; 296 G4double binding = -15.67 * A // nuclear vo << 290 G4double binding = 297 + 17.23 * std::pow(A, 2. << 291 - 15.67*A // nuclear volume 298 + 93.15 * ((A / 2. - Z) * << 292 + 17.23*std::pow(A,2./3.) // surface energy 299 + 0.6984523 * Z * Z * std << 293 + 93.15*((A/2.-Z)*(A/2.-Z))/A // asymmetry 300 if (Npairing == Zpairing) { << 294 + 0.6984523*Z*Z*std::pow(A,-1./3.); // coulomb 301 binding += (Npairing + Zpairing - 1) * 12. << 295 if( Npairing == Zpairing ) binding += (Npairing+Zpairing-1) * 12.0 / std::sqrt(A); // pairing 302 } << 303 296 304 return -binding * MeV; << 297 return -binding*MeV; 305 } 298 } >> 299 306 300