Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/particles/management/src/G4NuclideTable.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 ]

Diff markup

Differences between /particles/management/src/G4NuclideTable.cc (Version 11.3.0) and /particles/management/src/G4NuclideTable.cc (Version 5.2)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 // G4NuclideTable class implementation            
 27 //                                                
 28 // Author: T.Koi, SLAC - 10 October 2013          
 29 // -------------------------------------------    
 30                                                   
 31 #include "G4NuclideTable.hh"                      
 32                                                   
 33 #include "G4NuclideTableMessenger.hh"             
 34 #include "G4PhysicalConstants.hh"                 
 35 #include "G4String.hh"                            
 36 #include "G4SystemOfUnits.hh"                     
 37 #include "G4ios.hh"                               
 38 #include "globals.hh"                             
 39                                                   
 40 #include <fstream>                                
 41 #include <iomanip>                                
 42 #include <sstream>                                
 43                                                   
 44 G4NuclideTable* G4NuclideTable::GetInstance()     
 45 {                                                 
 46   static G4NuclideTable instance;                 
 47   return &instance;                               
 48 }                                                 
 49                                                   
 50 G4NuclideTable* G4NuclideTable::GetNuclideTabl    
 51 {                                                 
 52   return GetInstance();                           
 53 }                                                 
 54                                                   
 55 G4NuclideTable::G4NuclideTable()                  
 56   : G4VIsotopeTable("Isomer"), mean_life_thres    
 57 {                                                 
 58   fMessenger = new G4NuclideTableMessenger(thi    
 59   fIsotopeList = new G4IsotopeList();             
 60   GenerateNuclide();                              
 61 }                                                 
 62                                                   
 63 G4NuclideTable::~G4NuclideTable()                 
 64 {                                                 
 65   for (auto& it : map_pre_load_list) {            
 66     it.second.clear();                            
 67   }                                               
 68   map_pre_load_list.clear();                      
 69                                                   
 70   for (auto& it : map_full_list) {                
 71     it.second.clear();                            
 72   }                                               
 73   map_full_list.clear();                          
 74                                                   
 75   if (fIsotopeList != nullptr) {                  
 76     for (const auto& i : *fIsotopeList) {         
 77       delete i;                                   
 78     }                                             
 79     fIsotopeList->clear();                        
 80     delete fIsotopeList;                          
 81     fIsotopeList = nullptr;                       
 82   }                                               
 83   delete fMessenger;                              
 84 }                                                 
 85                                                   
 86 G4IsotopeProperty* G4NuclideTable::GetIsotope(    
 87                                                   
 88 {                                                 
 89   G4IsotopeProperty* fProperty = nullptr;         
 90                                                   
 91   // At first searching UserDefined               
 92   if (fUserDefinedList != nullptr) {              
 93     for (const auto it : *fUserDefinedList) {     
 94       if (Z == it->GetAtomicNumber() && A == i    
 95         G4double levelE = it->GetEnergy();        
 96         if (levelE - flevelTolerance / 2 <= E     
 97           if (flb == it->GetFloatLevelBase())     
 98             return it;                            
 99           }  // found                             
100         }                                         
101       }                                           
102     }                                             
103   }                                               
104                                                   
105   // Searching pre-load                           
106   // Note: isomer level is properly set only f    
107   //                                              
108   G4int ionCode = 1000 * Z + A;                   
109   auto itf = map_pre_load_list.find(ionCode);     
110                                                   
111   if (itf != map_pre_load_list.cend()) {          
112     auto lower_bound_itr = itf->second.lower_b    
113     G4double levelE = DBL_MAX;                    
114                                                   
115     while (lower_bound_itr != itf->second.cend    
116       levelE = lower_bound_itr->first;            
117       if (levelE - flevelTolerance / 2 <= E &&    
118         if (flb == (lower_bound_itr->second)->    
119           return lower_bound_itr->second;  //     
120         }                                         
121       }                                           
122       else {                                      
123         break;                                    
124       }                                           
125       ++lower_bound_itr;                          
126     }                                             
127   }                                               
128                                                   
129   return fProperty;  // not found                 
130 }                                                 
131                                                   
132 G4double G4NuclideTable::GetTruncationError(G4    
133 {                                                 
134   G4double tolerance = G4NuclideTable::GetInst    
135   return eex - (G4long)(eex / tolerance) * tol    
136 }                                                 
137                                                   
138 G4double G4NuclideTable::Round(G4double eex)      
139 {                                                 
140   G4double tolerance = G4NuclideTable::GetInst    
141   return round(eex / tolerance) * tolerance;      
142 }                                                 
143                                                   
144 G4long G4NuclideTable::Truncate(G4double eex)     
145 {                                                 
146   G4double tolerance = G4NuclideTable::GetInst    
147   return (G4long)(eex / tolerance);               
148 }                                                 
149                                                   
150 G4double G4NuclideTable::Tolerance()              
151 {                                                 
152   return G4NuclideTable::GetInstance()->GetLev    
153 }                                                 
154                                                   
155 G4IsotopeProperty* G4NuclideTable::GetIsotopeB    
156 {                                                 
157   if (lvl == 0) return GetIsotope(Z, A, 0.0);     
158   return nullptr;                                 
159 }                                                 
160                                                   
161 void G4NuclideTable::GenerateNuclide()            
162 {                                                 
163   if (mean_life_threshold < minimum_mean_life_    
164     // Need to update full list                   
165     const char* path = G4FindDataDir("G4ENSDFS    
166                                                   
167     if (path == nullptr) {                        
168       G4Exception("G4NuclideTable", "PART70000    
169                   "G4ENSDFSTATEDATA environmen    
170       return;                                     
171     }                                             
172                                                   
173     std::ifstream ifs;                            
174     G4String filename(path);                      
175     filename += "/ENSDFSTATE.dat";                
176                                                   
177     ifs.open(filename.c_str());                   
178     if (!ifs.good()) {                            
179       G4Exception("G4NuclideTable", "PART70001    
180       return;                                     
181     }                                             
182                                                   
183     G4int ionCode = 0;                            
184     G4int iLevel = 0;                             
185     G4int ionZ;                                   
186     G4int ionA;                                   
187     G4double ionE;                                
188     G4String ionFL;                               
189     G4double ionLife;                             
190     G4int ionJ;                                   
191     G4double ionMu;                               
192                                                   
193     // Lifetimes read from ENSDFSTATE are mean    
194     ifs >> ionZ >> ionA >> ionE >> ionFL >> io    
195                                                   
196     while (ifs.good())  // Loop checking, 09.0    
197     {                                             
198       if (ionCode != 1000 * ionZ + ionA) {        
199         iLevel = 0;                               
200         ionCode = 1000 * ionZ + ionA;             
201       }                                           
202                                                   
203       ionE *= keV;                                
204       G4Ions::G4FloatLevelBase flb = StripFloa    
205       ionLife *= ns;                              
206       ionMu *= (joule / tesla);                   
207                                                   
208       if ((ionE == 0 && flb == G4Ions::G4Float    
209           || (mean_life_threshold <= ionLife &    
210       {                                           
211         if (ionE > 0) ++iLevel;                   
212         if (iLevel > 9) iLevel = 9;               
213                                                   
214         auto fProperty = new G4IsotopeProperty    
215                                                   
216         // Set Isotope Property                   
217         fProperty->SetAtomicNumber(ionZ);         
218         fProperty->SetAtomicMass(ionA);           
219         fProperty->SetIsomerLevel(iLevel);        
220         fProperty->SetEnergy(ionE);               
221         fProperty->SetiSpin(ionJ);                
222         fProperty->SetLifeTime(ionLife);          
223         fProperty->SetDecayTable(nullptr);        
224         fProperty->SetMagneticMoment(ionMu);      
225         fProperty->SetFloatLevelBase(flb);        
226                                                   
227         fIsotopeList->push_back(fProperty);       
228                                                   
229         auto itf = map_full_list.find(ionCode)    
230         if (itf == map_full_list.cend()) {        
231           std::multimap<G4double, G4IsotopePro    
232           itf = (map_full_list.insert(std::pai    
233                    ionCode, aMultiMap)))          
234                   .first;                         
235         }                                         
236         itf->second.insert(std::pair<G4double,    
237       }                                           
238                                                   
239       ifs >> ionZ >> ionA >> ionE >> ionFL >>     
240     }  // End while                               
241                                                   
242     minimum_mean_life_threshold = mean_life_th    
243   }                                               
244                                                   
245   // Clear current map                            
246   for (auto& it : map_pre_load_list) {            
247     it.second.clear();                            
248   }                                               
249   map_pre_load_list.clear();                      
250                                                   
251   // Build map based on current threshold valu    
252   for (const auto& it : map_full_list) {          
253     G4int ionCode = it.first;                     
254     auto itf = map_pre_load_list.find(ionCode)    
255     if (itf == map_pre_load_list.cend()) {        
256       std::multimap<G4double, G4IsotopePropert    
257       itf = (map_pre_load_list.insert(            
258                std::pair<G4int, std::multimap<    
259               .first;                             
260     }                                             
261                                                   
262     G4int iLevel = 0;                             
263     for (const auto& itt : it.second) {           
264       G4double exEnergy = itt.first;              
265       G4double meanLife = itt.second->GetLifeT    
266       if (exEnergy == 0.0 || meanLife > mean_l    
267         if (itt.first != 0.0) ++iLevel;           
268         if (iLevel > 9) iLevel = 9;               
269         itt.second->SetIsomerLevel(iLevel);       
270         itf->second.insert(std::pair<G4double,    
271       }                                           
272     }                                             
273   }                                               
274 }                                                 
275                                                   
276 void G4NuclideTable::AddState(G4int ionZ, G4in    
277                               G4double ionMu)     
278 {                                                 
279   if (G4Threading::IsMasterThread()) {            
280     G4int flbIndex = 0;                           
281     ionE = StripFloatLevelBase(ionE, flbIndex)    
282     AddState(ionZ, ionA, ionE, flbIndex, ionLi    
283   }                                               
284 }                                                 
285                                                   
286 void G4NuclideTable::AddState(G4int ionZ, G4in    
287                               G4double ionLife    
288 {                                                 
289   if (G4Threading::IsMasterThread()) {            
290     if (fUserDefinedList == nullptr) fUserDefi    
291                                                   
292     auto fProperty = new G4IsotopeProperty();     
293                                                   
294     // Set Isotope Property                       
295     fProperty->SetAtomicNumber(ionZ);             
296     fProperty->SetAtomicMass(ionA);               
297     fProperty->SetIsomerLevel(9);                 
298     fProperty->SetEnergy(ionE);                   
299     fProperty->SetiSpin(ionJ);                    
300     fProperty->SetLifeTime(ionLife);              
301     fProperty->SetDecayTable(nullptr);            
302     fProperty->SetMagneticMoment(ionMu);          
303     fProperty->SetFloatLevelBase(flbIndex);       
304                                                   
305     fUserDefinedList->push_back(fProperty);       
306     fIsotopeList->push_back(fProperty);           
307   }                                               
308 }                                                 
309                                                   
310 void G4NuclideTable::AddState(G4int ionZ, G4in    
311                               G4double ionLife    
312 {                                                 
313   if (G4Threading::IsMasterThread()) {            
314     if (fUserDefinedList == nullptr) fUserDefi    
315                                                   
316     auto fProperty = new G4IsotopeProperty();     
317                                                   
318     // Set Isotope Property                       
319     fProperty->SetAtomicNumber(ionZ);             
320     fProperty->SetAtomicMass(ionA);               
321     fProperty->SetIsomerLevel(9);                 
322     fProperty->SetEnergy(ionE);                   
323     fProperty->SetiSpin(ionJ);                    
324     fProperty->SetLifeTime(ionLife);              
325     fProperty->SetDecayTable(nullptr);            
326     fProperty->SetMagneticMoment(ionMu);          
327     fProperty->SetFloatLevelBase(flb);            
328                                                   
329     fUserDefinedList->push_back(fProperty);       
330     fIsotopeList->push_back(fProperty);           
331   }                                               
332 }                                                 
333                                                   
334 void G4NuclideTable::SetThresholdOfHalfLife(G4    
335 {                                                 
336   if (G4Threading::IsMasterThread()) {            
337     mean_life_threshold = t / 0.69314718;         
338     GenerateNuclide();                            
339   }                                               
340 }                                                 
341                                                   
342 // Set the mean life threshold for nuclides       
343 // All nuclides with mean lives greater than t    
344 // for this run                                   
345 void G4NuclideTable::SetMeanLifeThreshold(G4do    
346 {                                                 
347   if (G4Threading::IsMasterThread()) {            
348     mean_life_threshold = t;                      
349     GenerateNuclide();                            
350   }                                               
351 }                                                 
352                                                   
353 G4double G4NuclideTable::StripFloatLevelBase(G    
354 {                                                 
355   G4double rem = std::fmod(E / (1.0E-3 * eV),     
356   flbIndex = G4int(rem);                          
357   return E - rem;                                 
358 }                                                 
359                                                   
360 G4Ions::G4FloatLevelBase G4NuclideTable::Strip    
361 {                                                 
362   if (sFLB.empty() || 2 < sFLB.size()) {          
363     G4String text;                                
364     text += sFLB;                                 
365     text += " is not valid indicator of G4Ions    
366     text += "You may use a wrong version of EN    
367     text += "Please use G4ENSDFSTATE-2.0 or la    
368                                                   
369     G4Exception("G4NuclideTable", "PART70002",    
370   }                                               
371   G4Ions::G4FloatLevelBase flb = noFloat;         
372   if (!(sFLB == "-")) {                           
373     flb = G4Ions::FloatLevelBase(sFLB.back());    
374   }                                               
375   return flb;                                     
376 }                                                 
377