Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4ParticleHPThermalScatteringData.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// Thermal Neutron Scattering
27// Koi, Tatsumi (SCCS/SLAC)
28//
29// Class Description
30// Cross Sections for a high precision (based on evaluated data
31// libraries) description of themal neutron scattering below 4 eV;
32// Based on Thermal neutron scattering files
33// from the evaluated nuclear data files ENDF/B-VI, Release2
34// To be used in your physics list in case you need this physics.
35// In this case you want to register an object of this class with
36// the corresponding process.
37// Class Description - End
38
39// 15-Nov-06 First implementation is done by T. Koi (SLAC/SCCS)
40// 070625 implement clearCurrentXSData to fix memory leaking by T. Koi
41// P. Arce, June-2014 Conversion neutron_hp to particle_hp
42//
43
44#include <list>
45#include <algorithm>
46
49
50#include "G4SystemOfUnits.hh"
51#include "G4Neutron.hh"
52#include "G4ElementTable.hh"
53
54#include "G4Threading.hh"
55
57:G4VCrossSectionDataSet("NeutronHPThermalScatteringData")
58,coherent(nullptr)
59,incoherent(nullptr)
60,inelastic(nullptr)
61{
62 // Upper limit of neutron energy
63 emax = 4*eV;
64 SetMinKinEnergy( 0*MeV );
65 SetMaxKinEnergy( emax );
66
67 ke_cache = 0.0;
68 xs_cache = 0.0;
69 element_cache = nullptr;
70 material_cache = nullptr;
71
72 indexOfThermalElement.clear();
73
75}
76
78{
79 clearCurrentXSData();
80
81 delete names;
82}
83
85 G4int /*Z*/ , G4int /*A*/ ,
86 const G4Element* element ,
87 const G4Material* material )
88{
89 G4double eKin = dp->GetKineticEnergy();
90 if ( eKin > 4.0*eV //GetMaxKinEnergy()
91 || eKin < 0 //GetMinKinEnergy()
92 || dp->GetDefinition() != G4Neutron::Neutron() ) return false;
93
94 if ( dic.find( std::pair < const G4Material* , const G4Element* > ( (G4Material*)NULL , element ) ) != dic.end()
95 || dic.find( std::pair < const G4Material* , const G4Element* > ( material , element ) ) != dic.end() ) return true;
96
97 return false;
98}
99
101 G4int /*Z*/ , G4int /*A*/ ,
102 const G4Isotope* /*iso*/ ,
103 const G4Element* element ,
104 const G4Material* material )
105{
106 ke_cache = dp->GetKineticEnergy();
107 element_cache = element;
108 material_cache = material;
109 G4double xs = GetCrossSection( dp , element , material );
110 xs_cache = xs;
111 return xs;
112}
113
114void G4ParticleHPThermalScatteringData::clearCurrentXSData()
115{
116 if ( coherent != nullptr )
117 {
118 for (auto it=coherent->cbegin() ; it!=coherent->cend(); ++it)
119 {
120 if ( it->second != nullptr )
121 {
122 for (auto itt=it->second->cbegin(); itt!=it->second->cend(); ++itt)
123 {
124 delete itt->second;
125 }
126 }
127 delete it->second;
128 }
129 coherent->clear();
130 }
131
132 if ( incoherent != nullptr )
133 {
134 for (auto it=incoherent->cbegin(); it!=incoherent->cend() ; ++it)
135 {
136 if ( it->second != nullptr )
137 {
138 for (auto itt=it->second->cbegin(); itt!=it->second->cend(); ++itt)
139 {
140 delete itt->second;
141 }
142 }
143 delete it->second;
144 }
145 incoherent->clear();
146 }
147
148 if ( inelastic != nullptr )
149 {
150 for (auto it=inelastic->cbegin(); it!=inelastic->cend(); ++it)
151 {
152 if ( it->second != nullptr )
153 {
154 for (auto itt=it->second->cbegin(); itt!=it->second->cend(); ++itt)
155 {
156 delete itt->second;
157 }
158 }
159 delete it->second;
160 }
161 inelastic->clear();
162 }
163
164}
165
166
168{
169 G4bool result = false;
170
171 G4double eKin = aP->GetKineticEnergy();
172 // Check energy
173 if ( eKin < emax )
174 {
175 // Check Particle Species
176 if ( aP->GetDefinition() == G4Neutron::Neutron() )
177 {
178 // anEle is one of Thermal elements
179 G4int ie = (G4int) anEle->GetIndex();
180 for (auto it = indexOfThermalElement.cbegin();
181 it != indexOfThermalElement.cend() ; ++it)
182 {
183 if ( ie == *it ) return true;
184 }
185 }
186 }
187
188 return result;
189}
190
191
193{
194
195 if ( &aP != G4Neutron::Neutron() )
196 throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!");
197
198 //std::map < std::pair < G4Material* , const G4Element* > , G4int > dic;
199 //
200 dic.clear();
201 if ( G4Threading::IsMasterThread() ) clearCurrentXSData();
202
203 std::map < G4String , G4int > co_dic;
204
205 //Searching Nist Materials
206 static G4ThreadLocal G4MaterialTable* theMaterialTable = nullptr;
207 if (!theMaterialTable) theMaterialTable= G4Material::GetMaterialTable();
208 std::size_t numberOfMaterials = G4Material::GetNumberOfMaterials();
209 for ( std::size_t i = 0 ; i < numberOfMaterials ; ++i )
210 {
211 G4Material* material = (*theMaterialTable)[i];
212 G4int numberOfElements = (G4int)material->GetNumberOfElements();
213 for ( G4int j = 0 ; j < numberOfElements ; ++j )
214 {
215 const G4Element* element = material->GetElement(j);
216 if ( names->IsThisThermalElement ( material->GetName() , element->GetName() ) )
217 {
218 G4int ts_ID_of_this_geometry;
219 G4String ts_ndl_name = names->GetTS_NDL_Name( material->GetName() , element->GetName() );
220 if ( co_dic.find ( ts_ndl_name ) != co_dic.cend() )
221 {
222 ts_ID_of_this_geometry = co_dic.find ( ts_ndl_name ) -> second;
223 }
224 else
225 {
226 ts_ID_of_this_geometry = (G4int)co_dic.size();
227 co_dic.insert ( std::pair< G4String , G4int >( ts_ndl_name , ts_ID_of_this_geometry ) );
228 }
229
230 dic.insert( std::pair < std::pair < G4Material* , const G4Element* > , G4int > ( std::pair < G4Material* , const G4Element* > ( material , element ) , ts_ID_of_this_geometry ) );
231 }
232 }
233 }
234
235 //Searching TS Elements
236 static G4ThreadLocal G4ElementTable* theElementTable = nullptr;
237 if (!theElementTable) theElementTable= G4Element::GetElementTable();
238 std::size_t numberOfElements = G4Element::GetNumberOfElements();
239
240 for ( std::size_t i = 0 ; i < numberOfElements ; ++i )
241 {
242 const G4Element* element = (*theElementTable)[i];
243 if ( names->IsThisThermalElement ( element->GetName() ) )
244 {
245 if ( names->IsThisThermalElement ( element->GetName() ) )
246 {
247 G4int ts_ID_of_this_geometry;
248 G4String ts_ndl_name = names->GetTS_NDL_Name( element->GetName() );
249 if ( co_dic.find ( ts_ndl_name ) != co_dic.cend() )
250 {
251 ts_ID_of_this_geometry = co_dic.find ( ts_ndl_name ) -> second;
252 }
253 else
254 {
255 ts_ID_of_this_geometry = (G4int)co_dic.size();
256 co_dic.insert ( std::pair< G4String , G4int >( ts_ndl_name , ts_ID_of_this_geometry ) );
257 }
258
259 dic.insert( std::pair < std::pair < const G4Material* , const G4Element* > , G4int > ( std::pair < const G4Material* , const G4Element* > ( (G4Material*)NULL , element ) , ts_ID_of_this_geometry ) );
260 }
261 }
262 }
263
264 G4cout << G4endl;
265 G4cout << "Neutron HP Thermal Scattering Data: Following material-element pairs and/or elements are registered." << G4endl;
266 for ( auto it = dic.cbegin() ; it != dic.cend() ; ++it )
267 {
268 if ( it->first.first != nullptr )
269 {
270 G4cout << "Material " << it->first.first->GetName() << " - Element "
271 << it->first.second->GetName()
272 << ", internal thermal scattering id " << it->second << G4endl;
273 }
274 else
275 {
276 G4cout << "Element " << it->first.second->GetName()
277 << ", internal thermal scattering id " << it->second << G4endl;
278 }
279 }
280 G4cout << G4endl;
281
283
284 coherent = hpmanager->GetThermalScatteringCoherentCrossSections();
285 incoherent = hpmanager->GetThermalScatteringIncoherentCrossSections();
286 inelastic = hpmanager->GetThermalScatteringInelasticCrossSections();
287
289 {
290 if ( coherent == nullptr )
291 coherent = new std::map< G4int , std::map< G4double , G4ParticleHPVector* >* >;
292 if ( incoherent == nullptr )
293 incoherent = new std::map< G4int , std::map< G4double , G4ParticleHPVector* >* >;
294 if ( inelastic == nullptr )
295 inelastic = new std::map< G4int , std::map< G4double , G4ParticleHPVector* >* >;
296
297 // Read Cross Section Data files
298
299 G4String dirName;
300 if ( !G4FindDataDir( "G4NEUTRONHPDATA" ) )
301 throw G4HadronicException(__FILE__, __LINE__, "Please setenv G4NEUTRONHPDATA to point to the neutron cross-section files.");
302 G4String baseName = G4FindDataDir( "G4NEUTRONHPDATA" );
303
304 dirName = baseName + "/ThermalScattering";
305
306 G4String ndl_filename;
307 G4String full_name;
308
309 for ( auto it = co_dic.cbegin() ; it != co_dic.cend() ; ++it )
310 {
311 ndl_filename = it->first;
312 G4int ts_ID = it->second;
313
314 // Coherent
315 full_name = dirName + "/Coherent/CrossSection/" + ndl_filename;
316 auto coh_amapTemp_EnergyCross = readData( full_name );
317 coherent->insert ( std::pair < G4int , std::map< G4double , G4ParticleHPVector* >* > ( ts_ID , coh_amapTemp_EnergyCross ) );
318
319 // Incoherent
320 full_name = dirName + "/Incoherent/CrossSection/" + ndl_filename;
321 auto incoh_amapTemp_EnergyCross = readData( full_name );
322 incoherent->insert ( std::pair < G4int , std::map< G4double , G4ParticleHPVector* >* > ( ts_ID , incoh_amapTemp_EnergyCross ) );
323
324 // Inelastic
325 full_name = dirName + "/Inelastic/CrossSection/" + ndl_filename;
326 auto inela_amapTemp_EnergyCross = readData( full_name );
327 inelastic->insert ( std::pair < G4int , std::map< G4double , G4ParticleHPVector* >* > ( ts_ID , inela_amapTemp_EnergyCross ) );
328 }
332 }
333}
334
335
336std::map< G4double , G4ParticleHPVector* >*
337G4ParticleHPThermalScatteringData::readData ( G4String full_name )
338{
339 auto aData = new std::map< G4double , G4ParticleHPVector* >;
340
341 std::istringstream theChannel;
342 G4ParticleHPManager::GetInstance()->GetDataStream(full_name,theChannel);
343
344 G4int dummy;
345 while ( theChannel >> dummy ) // MF // Loop checking, 11.05.2015, T. Koi
346 {
347 theChannel >> dummy; // MT
348 G4double temp;
349 theChannel >> temp;
350 G4ParticleHPVector* anEnergyCross = new G4ParticleHPVector;
351 G4int nData;
352 theChannel >> nData;
353 anEnergyCross->Init ( theChannel , nData , eV , barn );
354 aData->insert ( std::pair < G4double , G4ParticleHPVector* > ( temp , anEnergyCross ) );
355 }
356
357 return aData;
358}
359
360
362{
363 if( &aP != G4Neutron::Neutron() )
364 throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!");
365}
366
367
369{
370 G4double result = 0;
371
372 G4int ts_id =getTS_ID( aM , anE );
373
374 if ( ts_id == -1 ) return result;
375
376 G4double aT = aM->GetTemperature();
377
378 G4double Xcoh = GetX ( aP , aT , coherent->find(ts_id)->second );
379 G4double Xincoh = GetX ( aP , aT , incoherent->find(ts_id)->second );
380 G4double Xinela = GetX ( aP , aT , inelastic->find(ts_id)->second );
381
382 result = Xcoh + Xincoh + Xinela;
383
384 return result;
385}
386
387
389{
390 G4double result = 0;
391 G4int ts_id = getTS_ID( aM , anE );
392 G4double aT = aM->GetTemperature();
393 result = GetX ( aP , aT , inelastic->find( ts_id )->second );
394 return result;
395}
396
398{
399 G4double result = 0;
400 G4int ts_id = getTS_ID( aM , anE );
401 G4double aT = aM->GetTemperature();
402 result = GetX ( aP , aT , coherent->find( ts_id )->second );
403 return result;
404}
405
407{
408 G4double result = 0;
409 G4int ts_id = getTS_ID( aM , anE );
410 G4double aT = aM->GetTemperature();
411 result = GetX ( aP , aT , incoherent->find( ts_id )->second );
412 return result;
413}
414
415G4int G4ParticleHPThermalScatteringData::getTS_ID ( const G4Material* material , const G4Element* element )
416{
417 G4int result = -1;
418 if ( dic.find( std::pair < const G4Material* , const G4Element* > ( (G4Material*)NULL , element ) ) != dic.end() )
419 return dic.find( std::pair < const G4Material* , const G4Element* > ( (G4Material*)NULL , element ) )->second;
420 if ( dic.find( std::pair < const G4Material* , const G4Element* > ( material , element ) ) != dic.end() )
421 return dic.find( std::pair < const G4Material* , const G4Element* > ( material , element ) )->second;
422 return result;
423}
424
425G4double G4ParticleHPThermalScatteringData::GetX ( const G4DynamicParticle* aP, G4double aT , std::map < G4double , G4ParticleHPVector* >* amapTemp_EnergyCross )
426{
427 G4double result = 0;
428 if ( amapTemp_EnergyCross->size() == 0 ) return result;
429
430 G4double eKinetic = aP->GetKineticEnergy();
431
432 if ( amapTemp_EnergyCross->size() == 1 ) {
433 if ( std::fabs ( aT - amapTemp_EnergyCross->cbegin()->first ) / amapTemp_EnergyCross->begin()->first > 0.1 ) {
434 G4cout << "G4ParticleHPThermalScatteringData:: The temperature of material ("
435 << aT/kelvin << "K) is different more than 10% from temperature of thermal scattering file expected ("
436 << amapTemp_EnergyCross->begin()->first << "K). Result may not be reliable."
437 << G4endl;
438 }
439 result = amapTemp_EnergyCross->begin()->second->GetXsec ( eKinetic );
440 return result;
441 }
442
443 auto it = amapTemp_EnergyCross->cbegin();
444 for (it=amapTemp_EnergyCross->cbegin(); it!=amapTemp_EnergyCross->cend(); ++it)
445 {
446 if ( aT < it->first ) break;
447 }
448 if ( it == amapTemp_EnergyCross->cbegin() ) {
449 ++it; // lower than the first
450 } else if ( it == amapTemp_EnergyCross->cend() ) {
451 --it; // upper than the last
452 }
453
454 G4double TH = it->first;
455 G4double XH = it->second->GetXsec ( eKinetic );
456
457 if ( it != amapTemp_EnergyCross->cbegin() ) --it;
458 G4double TL = it->first;
459 G4double XL = it->second->GetXsec ( eKinetic );
460
461 if ( TH == TL )
462 throw G4HadronicException(__FILE__, __LINE__, "Thermal Scattering Data Error!");
463
464 G4double T = aT;
465 G4double X = ( XH - XL ) / ( TH - TL ) * ( T - TL ) + XL;
466 result = X;
467
468 return result;
469}
470
471
473{
474 names->AddThermalElement( nameG4Element , filename );
475}
476
478{
479 outFile << "High Precision cross data based on thermal scattering data in evaluated nuclear data libraries for neutrons below 5eV on specific materials\n" ;
480}
std::vector< G4Element * > G4ElementTable
const char * G4FindDataDir(const char *)
std::vector< G4Material * > G4MaterialTable
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4ElementTable * GetElementTable()
Definition: G4Element.cc:403
static size_t GetNumberOfElements()
Definition: G4Element.cc:410
size_t GetIndex() const
Definition: G4Element.hh:182
const G4String & GetName() const
Definition: G4Element.hh:127
static size_t GetNumberOfMaterials()
Definition: G4Material.cc:684
G4double GetTemperature() const
Definition: G4Material.hh:177
const G4Element * GetElement(G4int iel) const
Definition: G4Material.hh:197
size_t GetNumberOfElements() const
Definition: G4Material.hh:181
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:677
const G4String & GetName() const
Definition: G4Material.hh:172
static G4Neutron * Neutron()
Definition: G4Neutron.cc:103
void RegisterThermalScatteringIncoherentCrossSections(std::map< G4int, std::map< G4double, G4ParticleHPVector * > * > *val)
std::map< G4int, std::map< G4double, G4ParticleHPVector * > * > * GetThermalScatteringCoherentCrossSections()
std::map< G4int, std::map< G4double, G4ParticleHPVector * > * > * GetThermalScatteringInelasticCrossSections()
void RegisterThermalScatteringCoherentCrossSections(std::map< G4int, std::map< G4double, G4ParticleHPVector * > * > *val)
std::map< G4int, std::map< G4double, G4ParticleHPVector * > * > * GetThermalScatteringIncoherentCrossSections()
static G4ParticleHPManager * GetInstance()
void GetDataStream(G4String, std::istringstream &iss)
void RegisterThermalScatteringInelasticCrossSections(std::map< G4int, std::map< G4double, G4ParticleHPVector * > * > *val)
G4double GetCrossSection(const G4DynamicParticle *, const G4Element *, const G4Material *)
G4double GetIncoherentCrossSection(const G4DynamicParticle *, const G4Element *, const G4Material *)
void BuildPhysicsTable(const G4ParticleDefinition &)
G4double GetIsoCrossSection(const G4DynamicParticle *, G4int, G4int, const G4Isotope *, const G4Element *, const G4Material *)
G4double GetCoherentCrossSection(const G4DynamicParticle *, const G4Element *, const G4Material *)
void DumpPhysicsTable(const G4ParticleDefinition &)
G4double GetInelasticCrossSection(const G4DynamicParticle *, const G4Element *, const G4Material *)
virtual void CrossSectionDescription(std::ostream &) const
G4bool IsApplicable(const G4DynamicParticle *, const G4Element *)
G4bool IsIsoApplicable(const G4DynamicParticle *, G4int, G4int, const G4Element *, const G4Material *)
void Init(std::istream &aDataFile, G4int total, G4double ux=1., G4double uy=1.)
void SetMaxKinEnergy(G4double value)
void SetMinKinEnergy(G4double value)
G4bool IsMasterThread()
Definition: G4Threading.cc:124
#define G4ThreadLocal
Definition: tls.hh:77