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