Geant4-11
G4ParticleHPThermalScattering.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 (SLAC/SCCS)
28//
29// Class Description:
30//
31// Final State Generators for a high precision (based on evaluated data
32// libraries) description of themal neutron scattering below 4 eV;
33// Based on Thermal neutron scattering files
34// from the evaluated nuclear data files ENDF/B-VI, Release2
35// To be used in your physics list in case you need this physics.
36// In this case you want to register an object of this class with
37// the corresponding process.
38
39
40// 070625 Fix memory leaking at destructor by T. Koi
41// 081201 Fix memory leaking at destructor by T. Koi
42// 100729 Add model name in constructor Problem #1116
43// P. Arce, June-2014 Conversion neutron_hp to particle_hp
44//
50#include "G4SystemOfUnits.hh"
51#include "G4Neutron.hh"
52#include "G4ElementTable.hh"
53#include "G4MaterialTable.hh"
54#include "G4Threading.hh"
55
57 :G4HadronicInteraction("NeutronHPThermalScattering")
58,coherentFSs(nullptr)
59,incoherentFSs(nullptr)
60,inelasticFSs(nullptr)
61{
63
64 SetMinEnergy( 0.*eV );
65 SetMaxEnergy( 4*eV );
67
68 nMaterial = 0;
69 nElement = 0;
70}
71
72
74{
75 delete theHPElastic;
76}
77
78
80 if ( incoherentFSs != nullptr ) {
81 for ( std::map < G4int , std::map < G4double , std::vector < E_isoAng* >* >* >::iterator it = incoherentFSs->begin() ; it != incoherentFSs->end() ; it++ )
82 {
83 std::map < G4double , std::vector < E_isoAng* >* >::iterator itt;
84 for ( itt = it->second->begin() ; itt != it->second->end() ; itt++ )
85 {
86 std::vector< E_isoAng* >::iterator ittt;
87 for ( ittt = itt->second->begin(); ittt != itt->second->end() ; ittt++ )
88 {
89 delete *ittt;
90 }
91 delete itt->second;
92 }
93 delete it->second;
94 }
95 }
96
97 if ( coherentFSs != nullptr ) {
98 for ( std::map < G4int , std::map < G4double , std::vector < std::pair< G4double , G4double >* >* >* >::iterator it = coherentFSs->begin() ; it != coherentFSs->end() ; it++ )
99 {
100 std::map < G4double , std::vector < std::pair< G4double , G4double >* >* >::iterator itt;
101 for ( itt = it->second->begin() ; itt != it->second->end() ; itt++ )
102 {
103 std::vector < std::pair< G4double , G4double >* >::iterator ittt;
104 for ( ittt = itt->second->begin(); ittt != itt->second->end() ; ittt++ )
105 {
106 delete *ittt;
107 }
108 delete itt->second;
109 }
110 delete it->second;
111 }
112 }
113
114 if ( inelasticFSs != nullptr ) {
115 for ( std::map < G4int , std::map < G4double , std::vector < E_P_E_isoAng* >* >* >::iterator it = inelasticFSs->begin() ; it != inelasticFSs->end() ; it++ )
116 {
117 std::map < G4double , std::vector < E_P_E_isoAng* >* >::iterator itt;
118 for ( itt = it->second->begin() ; itt != it->second->end() ; itt++ )
119 {
120 std::vector < E_P_E_isoAng* >::iterator ittt;
121 for ( ittt = itt->second->begin(); ittt != itt->second->end() ; ittt++ )
122 {
123 std::vector < E_isoAng* >::iterator it4;
124 for ( it4 = (*ittt)->vE_isoAngle.begin() ; it4 != (*ittt)->vE_isoAngle.end() ; it4++ )
125 {
126 delete *it4;
127 }
128 delete *ittt;
129 }
130 delete itt->second;
131 }
132 delete it->second;
133 }
134 }
135
136 incoherentFSs = nullptr;
137 coherentFSs = nullptr;
138 inelasticFSs = nullptr;
139}
140
141
144 theHPElastic->BuildPhysicsTable( particle );
145}
146
147
148std::map < G4double , std::vector < std::pair< G4double , G4double >* >* >* G4ParticleHPThermalScattering::readACoherentFSDATA( G4String name )
149{
150
151 std::map < G4double , std::vector < std::pair< G4double , G4double >* >* >* aCoherentFSDATA = new std::map < G4double , std::vector < std::pair< G4double , G4double >* >* >;
152
153 //std::ifstream theChannel( name.c_str() );
154 std::istringstream theChannel(std::ios::in);
156
157 std::vector< G4double > vBraggE;
158
159 G4int dummy;
160 while ( theChannel >> dummy ) // MF // Loop checking, 11.05.2015, T. Koi
161 {
162 theChannel >> dummy; // MT
163 G4double temp;
164 theChannel >> temp;
165 std::vector < std::pair< G4double , G4double >* >* anBragE_P = new std::vector < std::pair< G4double , G4double >* >;
166
167 G4int n;
168 theChannel >> n;
169 for ( G4int i = 0 ; i < n ; i++ )
170 {
171 G4double Ei;
172 G4double Pi;
173 if ( aCoherentFSDATA->size() == 0 )
174 {
175 theChannel >> Ei;
176 vBraggE.push_back( Ei );
177 }
178 else
179 {
180 Ei = vBraggE[ i ];
181 }
182 theChannel >> Pi;
183 anBragE_P->push_back ( new std::pair < G4double , G4double > ( Ei , Pi ) );
184 //G4cout << "Coherent Elastic " << Ei << " " << Pi << G4endl;
185 }
186 aCoherentFSDATA->insert ( std::pair < G4double , std::vector < std::pair< G4double , G4double >* >* > ( temp , anBragE_P ) );
187 }
188
189 return aCoherentFSDATA;
190}
191
192
193std::map < G4double , std::vector < E_P_E_isoAng* >* >* G4ParticleHPThermalScattering::readAnInelasticFSDATA ( G4String name )
194{
195 std::map < G4double , std::vector < E_P_E_isoAng* >* >* anT_E_P_E_isoAng = new std::map < G4double , std::vector < E_P_E_isoAng* >* >;
196
197 //std::ifstream theChannel( name.c_str() );
198 std::istringstream theChannel(std::ios::in);
200
201 G4int dummy;
202 while ( theChannel >> dummy ) // MF // Loop checking, 11.05.2015, T. Koi
203 {
204 theChannel >> dummy; // MT
205 G4double temp;
206 theChannel >> temp;
207 std::vector < E_P_E_isoAng* >* vE_P_E_isoAng = new std::vector < E_P_E_isoAng* >;
208 G4int n;
209 theChannel >> n;
210 for ( G4int i = 0 ; i < n ; i++ )
211 {
212 vE_P_E_isoAng->push_back ( readAnE_P_E_isoAng ( &theChannel ) );
213 }
214 anT_E_P_E_isoAng->insert ( std::pair < G4double , std::vector < E_P_E_isoAng* >* > ( temp , vE_P_E_isoAng ) );
215 }
216 //theChannel.close();
217
218 return anT_E_P_E_isoAng;
219}
220
221
223{
224 E_P_E_isoAng* aData = new E_P_E_isoAng;
225
226 G4double dummy;
228 G4int nep , nl;
229 *file >> dummy;
230 *file >> energy;
231 aData->energy = energy*eV;
232 *file >> dummy;
233 *file >> dummy;
234 *file >> nep;
235 *file >> nl;
236 aData->n = nep/nl;
237 for ( G4int i = 0 ; i < aData->n ; i++ )
238 {
239 G4double prob;
240 E_isoAng* anE_isoAng = new E_isoAng;
241 aData->vE_isoAngle.push_back( anE_isoAng );
242 *file >> energy;
243 anE_isoAng->energy = energy*eV;
244 anE_isoAng->n = nl - 2;
245 anE_isoAng->isoAngle.resize( anE_isoAng->n );
246 *file >> prob;
247 aData->prob.push_back( prob );
248 //G4cout << "G4ParticleHPThermalScattering inelastic " << energy/eV << " " << i << " " << prob << " " << aData->prob[ i ] << G4endl;
249 for ( G4int j = 0 ; j < anE_isoAng->n ; j++ )
250 {
251 G4double x;
252 *file >> x;
253 anE_isoAng->isoAngle[j] = x ;
254 //G4cout << "G4ParticleHPThermalScattering inelastic " << x << anE_isoAng->isoAngle[j] << G4endl;
255 }
256 }
257
258 // Calcuate sum_of_provXdEs
259 G4double total = 0;
260 aData->secondary_energy_cdf.push_back(0.);
261 for ( G4int i = 0 ; i < aData->n - 1 ; i++ )
262 {
263 G4double E_L = aData->vE_isoAngle[i]->energy/eV;
264 G4double E_H = aData->vE_isoAngle[i+1]->energy/eV;
265 G4double dE = E_H - E_L;
266 G4double pdf = (aData->prob[i] + aData->prob[i+1] )/2. * dE;
267 total += ( pdf );
268 aData->secondary_energy_cdf.push_back( total );
269 aData->secondary_energy_pdf.push_back( pdf );
270 aData->secondary_energy_value.push_back( E_L );
271 }
272
273 aData->sum_of_probXdEs = total;
274
275 // Normalize CDF
277 for ( G4int i = 0; i < aData->secondary_energy_cdf_size; ++i )
278 {
279 aData->secondary_energy_cdf[i] /= total;
280 }
281
282 return aData;
283}
284
285
286std::map < G4double , std::vector < E_isoAng* >* >* G4ParticleHPThermalScattering::readAnIncoherentFSDATA ( G4String name )
287{
288 std::map < G4double , std::vector < E_isoAng* >* >* T_E = new std::map < G4double , std::vector < E_isoAng* >* >;
289
290 //std::ifstream theChannel( name.c_str() );
291 std::istringstream theChannel(std::ios::in);
293
294 G4int dummy;
295 while ( theChannel >> dummy ) // MF // Loop checking, 11.05.2015, T. Koi
296 {
297 theChannel >> dummy; // MT
298 G4double temp;
299 theChannel >> temp;
300 std::vector < E_isoAng* >* vE_isoAng = new std::vector < E_isoAng* >;
301 G4int n;
302 theChannel >> n;
303 for ( G4int i = 0 ; i < n ; i++ )
304 vE_isoAng->push_back ( readAnE_isoAng( &theChannel ) );
305 T_E->insert ( std::pair < G4double , std::vector < E_isoAng* >* > ( temp , vE_isoAng ) );
306 }
307 //theChannel.close();
308
309 return T_E;
310}
311
312
314{
315 E_isoAng* aData = new E_isoAng;
316
317 G4double dummy;
319 G4int n;
320 *file >> dummy;
321 *file >> energy;
322 *file >> dummy;
323 *file >> dummy;
324 *file >> n;
325 *file >> dummy;
326 aData->energy = energy*eV;
327 aData->n = n-2;
328 aData->isoAngle.resize( n );
329
330 *file >> dummy;
331 *file >> dummy;
332 for ( G4int i = 0 ; i < aData->n ; i++ )
333 *file >> aData->isoAngle[i];
334
335 return aData;
336}
337
338
340{
341
342// Select Element > Reaction >
343
344 const G4Material * theMaterial = aTrack.GetMaterial();
345 G4double aTemp = theMaterial->GetTemperature();
346 G4int n = theMaterial->GetNumberOfElements();
347
348 G4bool findThermalElement = false;
349 G4int ielement;
350 const G4Element* theElement = nullptr;
351 for ( G4int i = 0; i < n ; i++ )
352 {
353 theElement = theMaterial->GetElement(i);
354 //Select target element
355 if ( aNucleus.GetZ_asInt() == (G4int)(theElement->GetZ() + 0.5 ) )
356 {
357 //Check Applicability of Thermal Scattering
358 if ( getTS_ID( nullptr , theElement ) != -1 )
359 {
360 ielement = getTS_ID( nullptr , theElement );
361 findThermalElement = true;
362 break;
363 }
364 else if ( getTS_ID( theMaterial , theElement ) != -1 )
365 {
366 ielement = getTS_ID( theMaterial , theElement );
367 findThermalElement = true;
368 break;
369 }
370 }
371 }
372
373 if ( findThermalElement == true )
374 {
375
376// Select Reaction (Inelastic, coherent, incoherent)
377 const G4ParticleDefinition* pd = aTrack.GetDefinition();
378 G4DynamicParticle* dp = new G4DynamicParticle ( pd , aTrack.Get4Momentum() );
379 G4double total = theXSection->GetCrossSection( dp , theElement , theMaterial );
380 G4double inelastic = theXSection->GetInelasticCrossSection( dp , theElement , theMaterial );
381
382
383 G4double random = G4UniformRand();
384 if ( random <= inelastic/total )
385 {
386 // Inelastic
387
388 // T_L and T_H
389 std::map < G4double , std::vector< E_P_E_isoAng* >* >::iterator it;
390 std::vector<G4double> v_temp;
391 v_temp.clear();
392 for ( it = inelasticFSs->find( ielement )->second->begin() ; it != inelasticFSs->find( ielement )->second->end() ; it++ )
393 {
394 v_temp.push_back( it->first );
395 }
396
397// T_L T_H
398 std::pair < G4double , G4double > tempLH = find_LH ( aTemp , &v_temp );
399//
400// For T_L aNEP_EPM_TL and T_H aNEP_EPM_TH
401//
402 std::vector< E_P_E_isoAng* >* vNEP_EPM_TL = 0;
403 std::vector< E_P_E_isoAng* >* vNEP_EPM_TH = 0;
404
405 if ( tempLH.first != 0.0 && tempLH.second != 0.0 )
406 {
407 vNEP_EPM_TL = inelasticFSs->find( ielement )->second->find ( tempLH.first/kelvin )->second;
408 vNEP_EPM_TH = inelasticFSs->find( ielement )->second->find ( tempLH.second/kelvin )->second;
409 }
410 else if ( tempLH.first == 0.0 )
411 {
412 std::map < G4double , std::vector< E_P_E_isoAng* >* >::iterator itm;
413 itm = inelasticFSs->find( ielement )->second->begin();
414 vNEP_EPM_TL = itm->second;
415 itm++;
416 vNEP_EPM_TH = itm->second;
417 tempLH.first = tempLH.second;
418 tempLH.second = itm->first;
419 }
420 else if ( tempLH.second == 0.0 )
421 {
422 std::map < G4double , std::vector< E_P_E_isoAng* >* >::iterator itm;
423 itm = inelasticFSs->find( ielement )->second->end();
424 itm--;
425 vNEP_EPM_TH = itm->second;
426 itm--;
427 vNEP_EPM_TL = itm->second;
428 tempLH.second = tempLH.first;
429 tempLH.first = itm->first;
430 }
431
432 G4double sE=0., mu=1.0;
433
434 // New Geant4 method - Stochastic temperature interpolation of the final state
435 // (continuous temperature interpolation was used previously)
436 std::pair< G4double , G4double > secondaryParam;
437 G4double rand_temp = G4UniformRand();
438 if ( rand_temp < (aTemp-tempLH.first)/(tempLH.second - tempLH.first) )
439 secondaryParam = sample_inelastic_E_mu( aTrack.GetKineticEnergy() , vNEP_EPM_TH );
440 else
441 secondaryParam = sample_inelastic_E_mu( aTrack.GetKineticEnergy() , vNEP_EPM_TL );
442
443 sE = secondaryParam.first;
444 mu = secondaryParam.second;
445
446 //set
449 G4double sint= std::sqrt ( 1 - mu*mu );
450 theParticleChange.SetMomentumChange( sint*std::cos(phi), sint*std::sin(phi), mu );
451
452 }
453 else if ( random <= ( inelastic + theXSection->GetCoherentCrossSection( dp , theElement , theMaterial ) ) / total )
454 {
455 // Coherent Elastic
456
457 G4double E = aTrack.GetKineticEnergy();
458
459 // T_L and T_H
460 std::map < G4double , std::vector< std::pair< G4double , G4double >* >* >::iterator it;
461 std::vector<G4double> v_temp;
462 v_temp.clear();
463 for ( it = coherentFSs->find( ielement )->second->begin() ; it != coherentFSs->find( ielement )->second->end() ; it++ )
464 {
465 v_temp.push_back( it->first );
466 }
467
468// T_L T_H
469 std::pair < G4double , G4double > tempLH = find_LH ( aTemp , &v_temp );
470//
471//
472// For T_L anEPM_TL and T_H anEPM_TH
473//
474 std::vector< std::pair< G4double , G4double >* >* pvE_p_TL = nullptr;
475 std::vector< std::pair< G4double , G4double >* >* pvE_p_TH = nullptr;
476
477 if ( tempLH.first != 0.0 && tempLH.second != 0.0 )
478 {
479 pvE_p_TL = coherentFSs->find( ielement )->second->find ( tempLH.first/kelvin )->second;
480 pvE_p_TH = coherentFSs->find( ielement )->second->find ( tempLH.first/kelvin )->second;
481 }
482 else if ( tempLH.first == 0.0 )
483 {
484 pvE_p_TL = coherentFSs->find( ielement )->second->find ( v_temp[ 0 ] )->second;
485 pvE_p_TH = coherentFSs->find( ielement )->second->find ( v_temp[ 1 ] )->second;
486 tempLH.first = tempLH.second;
487 tempLH.second = v_temp[ 1 ];
488 }
489 else if ( tempLH.second == 0.0 )
490 {
491 pvE_p_TH = coherentFSs->find( ielement )->second->find ( v_temp.back() )->second;
492 std::vector< G4double >::iterator itv;
493 itv = v_temp.end();
494 itv--;
495 itv--;
496 pvE_p_TL = coherentFSs->find( ielement )->second->find ( *itv )->second;
497 tempLH.second = tempLH.first;
498 tempLH.first = *itv;
499 }
500 else
501 {
502 //tempLH.first == 0.0 && tempLH.second
503 throw G4HadronicException(__FILE__, __LINE__, "A problem is found in Thermal Scattering Data! Unexpected temperature values in data");
504 }
505
506 std::vector< G4double > vE_T;
507 std::vector< G4double > vp_T;
508
509 G4int n1 = pvE_p_TL->size();
510
511 // New Geant4 method - Stochastic interpolation of the final state
512 std::vector< std::pair< G4double , G4double >* >* pvE_p_T_sampled;
513 G4double rand_temp = G4UniformRand();
514 if ( rand_temp < (aTemp-tempLH.first)/(tempLH.second - tempLH.first) )
515 pvE_p_T_sampled = pvE_p_TH;
516 else
517 pvE_p_T_sampled = pvE_p_TL;
518
519 //171005 fix bug, contribution from H.N. TRAN@CEA
520 for ( G4int i=0 ; i < n1 ; i++ )
521 {
522 vE_T.push_back ( (*pvE_p_T_sampled)[i]->first );
523 vp_T.push_back ( (*pvE_p_T_sampled)[i]->second );
524 }
525
526 G4int j = 0;
527 for ( G4int i = 1 ; i < n1 ; i++ )
528 {
529 if ( E/eV < vE_T[ i ] )
530 {
531 j = i-1;
532 break;
533 }
534 }
535
536 G4double rand_for_mu = G4UniformRand();
537
538 G4int k = 0;
539 for ( G4int i = 0 ; i <= j ; i++ )
540 {
541 G4double Pi = vp_T[ i ] / vp_T[ j ];
542 if ( rand_for_mu < Pi )
543 {
544 k = i;
545 break;
546 }
547 }
548
549 G4double Ei = vE_T[ k ];
550
551 G4double mu = 1 - 2 * Ei / (E/eV) ;
552 //111102
553 if ( mu < -1.0 ) mu = -1.0;
554 //G4cout << "E= " << E/eV << ", Ei= " << Ei << ", mu= " << mu << G4endl;
555
558 G4double sint= std::sqrt ( 1 - mu*mu );
559 theParticleChange.SetMomentumChange( sint*std::cos(phi), sint*std::sin(phi), mu );
560
561 }
562 else
563 {
564 // InCoherent Elastic
565
566 // T_L and T_H
567 std::map < G4double , std::vector < E_isoAng* >* >::iterator it;
568 std::vector<G4double> v_temp;
569 v_temp.clear();
570 for ( it = incoherentFSs->find( ielement )->second->begin() ; it != incoherentFSs->find( ielement )->second->end() ; it++ )
571 {
572 v_temp.push_back( it->first );
573 }
574
575// T_L T_H
576 std::pair < G4double , G4double > tempLH = find_LH ( aTemp , &v_temp );
577
578//
579// For T_L anEPM_TL and T_H anEPM_TH
580//
581
582 E_isoAng anEPM_TL_E;
583 E_isoAng anEPM_TH_E;
584
585 if ( tempLH.first != 0.0 && tempLH.second != 0.0 ) {
586 //Interpolate TL and TH
587 anEPM_TL_E = create_E_isoAng_from_energy ( aTrack.GetKineticEnergy() , incoherentFSs->find( ielement )->second->find ( tempLH.first/kelvin )->second );
588 anEPM_TH_E = create_E_isoAng_from_energy ( aTrack.GetKineticEnergy() , incoherentFSs->find( ielement )->second->find ( tempLH.second/kelvin )->second );
589 } else if ( tempLH.first == 0.0 ) {
590 //Extrapolate T0 and T1
591 anEPM_TL_E = create_E_isoAng_from_energy ( aTrack.GetKineticEnergy() , incoherentFSs->find( ielement )->second->find ( v_temp[ 0 ] )->second );
592 anEPM_TH_E = create_E_isoAng_from_energy ( aTrack.GetKineticEnergy() , incoherentFSs->find( ielement )->second->find ( v_temp[ 1 ] )->second );
593 tempLH.first = tempLH.second;
594 tempLH.second = v_temp[ 1 ];
595 } else if ( tempLH.second == 0.0 ) {
596 //Extrapolate Tmax-1 and Tmax
597 anEPM_TH_E = create_E_isoAng_from_energy ( aTrack.GetKineticEnergy() , incoherentFSs->find( ielement )->second->find ( v_temp.back() )->second );
598 std::vector< G4double >::iterator itv;
599 itv = v_temp.end();
600 itv--;
601 itv--;
602 anEPM_TL_E = create_E_isoAng_from_energy ( aTrack.GetKineticEnergy() , incoherentFSs->find( ielement )->second->find ( *itv )->second );
603 tempLH.second = tempLH.first;
604 tempLH.first = *itv;
605 }
606
607 // E_isoAng for aTemp and aTrack.GetKineticEnergy()
608 G4double mu=1.0;
609
610 // New Geant4 method - Stochastic interpolation of the final state
611 E_isoAng anEPM_T_E_sampled;
612 G4double rand_temp = G4UniformRand();
613 if ( rand_temp < (aTemp-tempLH.first)/(tempLH.second - tempLH.first) )
614 anEPM_T_E_sampled = anEPM_TH_E;
615 else
616 anEPM_T_E_sampled = anEPM_TL_E;
617
618 mu = getMu ( &anEPM_T_E_sampled );
619
620 // Set Final State
621 theParticleChange.SetEnergyChange( aTrack.GetKineticEnergy() ); // No energy change in Elastic
623 G4double sint= std::sqrt ( 1 - mu*mu );
624 theParticleChange.SetMomentumChange( sint*std::cos(phi), sint*std::sin(phi), mu );
625
626 }
627 delete dp;
628
629 return &theParticleChange;
630
631 }
632 else
633 {
634 // Not thermal element
635 // Neutron HP will handle
636 return theHPElastic -> ApplyYourself( aTrack, aNucleus, 1); // L. Thulliez 2021/05/04 (CEA-Saclay)
637 }
638
639}
640
641
642//**********************************************************
643// Geant4 new algorithm
644//**********************************************************
645
646//--------------------------------------------------
647// New method added by L. Thulliez 2021 (CEA-Saclay)
648//--------------------------------------------------
649std::pair< G4double , G4int> G4ParticleHPThermalScattering::
650sample_inelastic_E( G4double rndm1, G4double rndm2, E_P_E_isoAng* anE_P_E_isoAng )
651{
652 G4int i=0;
653 G4double sE_value=0;
654
655 for ( ; i < anE_P_E_isoAng->secondary_energy_cdf_size-1 ; ++i )
656 {
657 if ( rndm1 >= anE_P_E_isoAng->secondary_energy_cdf[i] &&
658 rndm1 < anE_P_E_isoAng->secondary_energy_cdf[i+1] )
659 {
660 G4double sE_value_i = anE_P_E_isoAng->secondary_energy_value[i];
661 G4double sE_pdf_i = anE_P_E_isoAng->secondary_energy_pdf[i];
662 G4double sE_value_i1 = anE_P_E_isoAng->secondary_energy_value[i+1];
663 G4double sE_pdf_i1 = anE_P_E_isoAng->secondary_energy_pdf[i+1];
664
665 G4double lambda = 0;
666 G4double alpha = (sE_pdf_i1 - sE_pdf_i) / (sE_pdf_i1 + sE_pdf_i);
667 G4double rndm = rndm1;
668
669 if ( std::fabs(alpha) < 1E-8 )
670 {
671 lambda = rndm2;
672 }
673 else
674 {
675 G4double beta = 2 * sE_pdf_i / (sE_pdf_i1 + sE_pdf_i);
676 rndm = rndm2;
677 G4double gamma = -rndm;
678 G4double delta = beta*beta - 4*alpha*gamma;
679
680 if ( delta < 0 && std::fabs(delta) < 1.E-8 ) delta = 0;
681
682 lambda = -beta + std::sqrt(delta);
683 lambda = lambda/(2 * alpha);
684
685 if ( lambda > 1 ) lambda = 1;
686 else if ( lambda < 0 ) lambda = 0;
687 }
688
689 sE_value = sE_value_i + lambda * (sE_value_i1 - sE_value_i);
690
691 break;
692 }
693 }
694
695 return std::pair< G4double , G4int >( sE_value , i );
696}
697
698
699//--------------------------------------------------
700// New method added by L. Thulliez 2021 (CEA-Saclay)
701//--------------------------------------------------
702std::pair< G4double , G4double > G4ParticleHPThermalScattering::
703sample_inelastic_E_mu( G4double pE , std::vector< E_P_E_isoAng* >* vNEP_EPM )
704{
705 // Sample primary energy bin
706 std::map< G4double , G4int > map_energy;
707 map_energy.clear();
708 std::vector< G4double > v_energy;
709 v_energy.clear();
710 std::vector< E_P_E_isoAng* >::iterator itv;
711 G4int i = 0;
712 for ( itv = vNEP_EPM->begin(); itv != vNEP_EPM->end(); ++itv )
713 {
714 v_energy.push_back( (*itv)->energy );
715 map_energy.insert( std::pair< G4double , G4int >( (*itv)->energy , i ) );
716 i++;
717 }
718
719 std::pair< G4double , G4double > energyLH = find_LH( pE , &v_energy );
720
721 std::vector< E_P_E_isoAng* > pE_P_E_isoAng_limit(2, nullptr);
722
723 if ( energyLH.first != 0.0 && energyLH.second != 0.0 )
724 {
725 pE_P_E_isoAng_limit[0] = (*vNEP_EPM)[ map_energy.find ( energyLH.first )->second ];
726 pE_P_E_isoAng_limit[1] = (*vNEP_EPM)[ map_energy.find ( energyLH.second )->second ];
727 }
728 else if ( energyLH.first == 0.0 )
729 {
730 pE_P_E_isoAng_limit[0] = (*vNEP_EPM)[ 0 ];
731 pE_P_E_isoAng_limit[1] = (*vNEP_EPM)[ 1 ];
732 }
733 if ( energyLH.second == 0.0 )
734 {
735 pE_P_E_isoAng_limit[1] = (*vNEP_EPM).back();
736 itv = vNEP_EPM->end();
737 itv--;
738 itv--;
739 pE_P_E_isoAng_limit[0] = *itv;
740 }
741
742 // Compute interpolation factor of the incident neutron energy
743 G4double factor = (energyLH.second - pE) / (energyLH.second - energyLH.first);
744
745 if ( (energyLH.second - pE) <= 0. && std::fabs(pE/energyLH.second - 1) < 1E-11 ) factor = 0.;
746 if ( (energyLH.first - pE) >= 0. && std::fabs(energyLH.first / pE - 1) < 1E-11 ) factor = 1.;
747
748 G4double rndm1 = G4UniformRand();
749 G4double rndm2 = G4UniformRand();
750
751 // Sample secondary neutron energy
752 std::pair< G4double , G4int > sE_lower = sample_inelastic_E( rndm1, rndm2, pE_P_E_isoAng_limit[0] );
753 std::pair< G4double , G4int > sE_upper = sample_inelastic_E( rndm1, rndm2, pE_P_E_isoAng_limit[1] );
754 G4double sE = factor * sE_lower.first + (1 - factor) * sE_upper.first;
755 sE = sE * eV;
756
757 // Sample cosine knowing the secondary neutron energy
758 rndm1 = G4UniformRand();
759 rndm2 = G4UniformRand();
760 G4double mu_lower = getMu( rndm1, rndm2, pE_P_E_isoAng_limit[0]->vE_isoAngle[sE_lower.second] );
761 G4double mu_upper = getMu( rndm1, rndm2, pE_P_E_isoAng_limit[1]->vE_isoAngle[sE_upper.second] );
762 G4double mu = factor * mu_lower + (1 - factor) * mu_upper;
763
764 return std::pair< G4double , G4double >( sE , mu );
765}
766
767
768//--------------------------------------------------
769// New method added by L. Thulliez 2021 (CEA-Saclay)
770//--------------------------------------------------
772{
773 G4double result = 0.0;
774
775 G4int in = int ( rndm1 * ( (*anEPM).n ) );
776
777 if ( in != 0 )
778 {
779 G4double mu_l = (*anEPM).isoAngle[ in-1 ];
780 G4double mu_h = (*anEPM).isoAngle[ in ];
781 result = ( mu_h - mu_l ) * ( rndm1*((*anEPM).n) - in ) + mu_l;
782 }
783 else
784 {
785 G4double x = rndm1 * (*anEPM).n;
786 G4double ratio = 0.5;
787 if ( x <= ratio )
788 {
789 G4double mu_l = -1;
790 G4double mu_h = (*anEPM).isoAngle[ 0 ];
791 result = ( mu_h - mu_l ) * rndm2 + mu_l;
792 }
793 else
794 {
795 G4double mu_l = (*anEPM).isoAngle[ (*anEPM).n - 1 ];
796 G4double mu_h = 1;
797 result = ( mu_h - mu_l ) * rndm2 + mu_l;
798 }
799 }
800
801 return result;
802}
803
804
805//**********************************************************
806// Geant4 previous algorithm
807//**********************************************************
808
810{
811
812 G4double random = G4UniformRand();
813 G4double result = 0.0;
814
815 G4int in = int ( random * ( (*anEPM).n ) );
816
817 if ( in != 0 )
818 {
819 G4double mu_l = (*anEPM).isoAngle[ in-1 ];
820 G4double mu_h = (*anEPM).isoAngle[ in ];
821 result = ( mu_h - mu_l ) * ( random * ( (*anEPM).n ) - in ) + mu_l;
822 }
823 else
824 {
825 G4double x = random * (*anEPM).n;
826 //Bugzilla 1971
827 G4double ratio = 0.5;
828 G4double xx = G4UniformRand();
829 if ( x <= ratio )
830 {
831 G4double mu_l = -1;
832 G4double mu_h = (*anEPM).isoAngle[ 0 ];
833 result = ( mu_h - mu_l ) * xx + mu_l;
834 }
835 else
836 {
837 G4double mu_l = (*anEPM).isoAngle[ (*anEPM).n - 1 ];
838 G4double mu_h = 1;
839 result = ( mu_h - mu_l ) * xx + mu_l;
840 }
841 }
842 return result;
843}
844
845
846std::pair < G4double , G4double > G4ParticleHPThermalScattering::find_LH ( G4double x , std::vector< G4double >* aVector )
847{
848 G4double LL = 0.0;
849 G4double H = 0.0;
850
851 // v->size() == 1 --> LL=H=v(0)
852 if ( aVector->size() == 1 ) {
853 LL = aVector->front();
854 H = aVector->front();
855 } else {
856 // 1) temp < v(0) -> LL=0.0 H=v(0)
857 // 2) v(i-1) < temp <= v(i) -> LL=v(i-1) H=v(i)
858 // 3) v(imax) < temp -> LL=v(imax) H=0.0
859 for ( std::vector< G4double >::iterator
860 it = aVector->begin() ; it != aVector->end() ; it++ ) {
861 if ( x <= *it ) {
862 H = *it;
863 if ( it != aVector->begin() ) {
864 // 2)
865 it--;
866 LL = *it;
867 } else {
868 // 1)
869 LL = 0.0;
870 }
871 break;
872 }
873 }
874 // 3)
875 if ( H == 0.0 ) LL = aVector->back();
876 }
877
878 return std::pair < G4double , G4double > ( LL , H );
879}
880
881
882G4double G4ParticleHPThermalScattering::get_linear_interpolated ( G4double x , std::pair< G4double , G4double > Low , std::pair< G4double , G4double > High )
883{
884 G4double y=0.0;
885 if ( High.first - Low.first != 0 ) {
886 y = ( High.second - Low.second ) / ( High.first - Low.first ) * ( x - Low.first ) + Low.second;
887 } else {
888 if ( High.second == Low.second ) {
889 y = High.second;
890 } else {
891 G4cout << "G4ParticleHPThermalScattering liner interpolation err!!" << G4endl;
892 }
893 }
894
895 return y;
896}
897
898
901 std::vector<E_isoAng*>* vEPM)
902{
903 E_isoAng anEPM_T_E;
904 std::vector<E_isoAng*>::iterator iv;
905
906 std::vector<G4double> v_e;
907 v_e.clear();
908 for (iv = vEPM->begin(); iv != vEPM->end(); iv++)
909 v_e.push_back( (*iv)->energy );
910
911 std::pair<G4double, G4double> energyLH = find_LH(energy, &v_e);
912 //G4cout << " " << energy/eV << " " << energyLH.first/eV << " " << energyLH.second/eV << G4endl;
913
914 E_isoAng* panEPM_T_EL = 0;
915 E_isoAng* panEPM_T_EH = 0;
916
917 if (energyLH.first != 0.0 && energyLH.second != 0.0) {
918 for (iv = vEPM->begin(); iv != vEPM->end(); iv++) {
919 if (energyLH.first == (*iv)->energy) {
920 panEPM_T_EL = *iv;
921 iv++;
922 panEPM_T_EH = *iv;
923 break;
924 }
925 }
926
927 } else if (energyLH.first == 0.0) {
928 panEPM_T_EL = (*vEPM)[0];
929 panEPM_T_EH = (*vEPM)[1];
930
931 } else if (energyLH.second == 0.0) {
932 panEPM_T_EH = (*vEPM).back();
933 iv = vEPM->end();
934 iv--;
935 iv--;
936 panEPM_T_EL = *iv;
937 }
938
939 if (panEPM_T_EL != 0 && panEPM_T_EH != 0) {
940 //checking isoAng has proper values or not
941 // Inelastic/FS, the first and last entries of *vEPM has all zero values.
942 if ( !(check_E_isoAng(panEPM_T_EL) ) ) panEPM_T_EL = panEPM_T_EH;
943 if ( !(check_E_isoAng(panEPM_T_EH) ) ) panEPM_T_EH = panEPM_T_EL;
944
945 if (panEPM_T_EL->n == panEPM_T_EH->n) {
946 anEPM_T_E.energy = energy;
947 anEPM_T_E.n = panEPM_T_EL->n;
948
949 for (G4int i=0; i < panEPM_T_EL->n; i++) {
951 angle = get_linear_interpolated(energy, std::pair<G4double,G4double>(energyLH.first, panEPM_T_EL->isoAngle[i] ),
952 std::pair<G4double,G4double>(energyLH.second, panEPM_T_EH->isoAngle[i] ) );
953 anEPM_T_E.isoAngle.push_back(angle);
954 }
955
956 } else {
957 G4Exception("G4ParticleHPThermalScattering::create_E_isoAng_from_energy",
958 "NotSupported", JustWarning,
959 "G4ParticleHPThermalScattering does not support yet EL->n != EH->n.");
960 }
961
962 } else {
963 G4Exception("G4ParticleHPThermalScattering::create_E_isoAng_from_energy",
964 "HAD_THERM_000", FatalException,
965 "Pointer panEPM_T_EL or panEPM_T_EH is zero");
966 }
967
968 return anEPM_T_E;
969}
970
971
973{
974 G4double secondary_energy = 0.0;
975
976 G4int n = anE_P_E_isoAng->n;
977 G4double sum_p = 0.0; // sum_p_H
978 G4double sum_p_L = 0.0;
979
980 G4double total=0.0;
981
982/*
983 delete for speed up
984 for ( G4int i = 0 ; i < n-1 ; i++ )
985 {
986 G4double E_L = anE_P_E_isoAng->vE_isoAngle[i]->energy/eV;
987 G4double E_H = anE_P_E_isoAng->vE_isoAngle[i+1]->energy/eV;
988 G4double dE = E_H - E_L;
989 total += ( ( anE_P_E_isoAng->prob[i] ) * dE );
990 }
991
992 if ( std::abs( total - anE_P_E_isoAng->sum_of_probXdEs ) > 1.0e-14 ) G4cout << total - anE_P_E_isoAng->sum_of_probXdEs << G4endl;
993*/
994 total = anE_P_E_isoAng->sum_of_probXdEs;
995
996 for ( G4int i = 0 ; i < n-1 ; i++ )
997 {
998 G4double E_L = anE_P_E_isoAng->vE_isoAngle[i]->energy/eV;
999 G4double E_H = anE_P_E_isoAng->vE_isoAngle[i+1]->energy/eV;
1000 G4double dE = E_H - E_L;
1001 sum_p += ( ( anE_P_E_isoAng->prob[i] ) * dE );
1002
1003 if ( random <= sum_p/total )
1004 {
1005 secondary_energy = get_linear_interpolated ( random , std::pair < G4double , G4double > ( sum_p_L/total , E_L ) , std::pair < G4double , G4double > ( sum_p/total , E_H ) );
1006 secondary_energy = secondary_energy*eV; //need eV
1007 break;
1008 }
1009 sum_p_L = sum_p;
1010 }
1011
1012 return secondary_energy;
1013}
1014
1015
1016std::pair< G4double , E_isoAng > G4ParticleHPThermalScattering::create_sE_and_EPM_from_pE_and_vE_P_E_isoAng ( G4double rand_for_sE , G4double pE , std::vector < E_P_E_isoAng* >* vNEP_EPM )
1017{
1018 std::map< G4double , G4int > map_energy;
1019 map_energy.clear();
1020 std::vector< G4double > v_energy;
1021 v_energy.clear();
1022 std::vector< E_P_E_isoAng* >::iterator itv;
1023 G4int i = 0;
1024 for ( itv = vNEP_EPM->begin(); itv != vNEP_EPM->end(); itv++ )
1025 {
1026 v_energy.push_back( (*itv)->energy );
1027 map_energy.insert( std::pair < G4double , G4int > ( (*itv)->energy , i ) );
1028 i++;
1029 }
1030
1031 std::pair < G4double , G4double > energyLH = find_LH ( pE , &v_energy );
1032
1033 E_P_E_isoAng* pE_P_E_isoAng_EL = 0;
1034 E_P_E_isoAng* pE_P_E_isoAng_EH = 0;
1035
1036 if ( energyLH.first != 0.0 && energyLH.second != 0.0 )
1037 {
1038 pE_P_E_isoAng_EL = (*vNEP_EPM)[ map_energy.find ( energyLH.first )->second ];
1039 pE_P_E_isoAng_EH = (*vNEP_EPM)[ map_energy.find ( energyLH.second )->second ];
1040 }
1041 else if ( energyLH.first == 0.0 )
1042 {
1043 pE_P_E_isoAng_EL = (*vNEP_EPM)[ 0 ];
1044 pE_P_E_isoAng_EH = (*vNEP_EPM)[ 1 ];
1045 }
1046 if ( energyLH.second == 0.0 )
1047 {
1048 pE_P_E_isoAng_EH = (*vNEP_EPM).back();
1049 itv = vNEP_EPM->end();
1050 itv--;
1051 itv--;
1052 pE_P_E_isoAng_EL = *itv;
1053 }
1054
1055 G4double sE;
1056 G4double sE_L;
1057 G4double sE_H;
1058
1059 sE_L = get_secondary_energy_from_E_P_E_isoAng ( rand_for_sE , pE_P_E_isoAng_EL );
1060 sE_H = get_secondary_energy_from_E_P_E_isoAng ( rand_for_sE , pE_P_E_isoAng_EH );
1061
1062 sE = get_linear_interpolated ( pE , std::pair < G4double , G4double > ( energyLH.first , sE_L ) , std::pair < G4double , G4double > ( energyLH.second , sE_H ) );
1063
1064
1065 E_isoAng E_isoAng_L = create_E_isoAng_from_energy ( sE , &(pE_P_E_isoAng_EL->vE_isoAngle) );
1066 E_isoAng E_isoAng_H = create_E_isoAng_from_energy ( sE , &(pE_P_E_isoAng_EH->vE_isoAngle) );
1067
1068 E_isoAng anE_isoAng;
1069 //For defeating warning message from compiler
1070 anE_isoAng.n = 1;
1071 anE_isoAng.energy = sE; //never used
1072 if ( E_isoAng_L.n == E_isoAng_H.n )
1073 {
1074 anE_isoAng.n = E_isoAng_L.n;
1075 for ( G4int j=0 ; j < anE_isoAng.n ; j++ )
1076 {
1078 angle = get_linear_interpolated ( sE , std::pair< G4double , G4double > ( sE_L , E_isoAng_L.isoAngle[ j ] ) , std::pair< G4double , G4double > ( sE_H , E_isoAng_H.isoAngle[ j ] ) );
1079 anE_isoAng.isoAngle.push_back( angle );
1080 }
1081 }
1082 else
1083 {
1084 //G4cout << "Do not Suuport yet." << G4endl;
1085 throw G4HadronicException(__FILE__, __LINE__, "Unexpected values!");
1086 }
1087
1088 return std::pair< G4double , E_isoAng >( sE , anE_isoAng);
1089}
1090
1091
1093{
1094 //Is rebuild of physics table a necessity
1096 return;
1097 } else {
1100 }
1101
1102 dic.clear();
1103 std::map < G4String , G4int > co_dic;
1104
1105 //Searching Nist Materials
1106 static G4ThreadLocal G4MaterialTable* theMaterialTable = 0 ; if (!theMaterialTable) theMaterialTable= G4Material::GetMaterialTable();
1107 size_t numberOfMaterials = G4Material::GetNumberOfMaterials();
1108 for ( size_t i = 0 ; i < numberOfMaterials ; i++ )
1109 {
1110 G4Material* material = (*theMaterialTable)[i];
1111 size_t numberOfElements = material->GetNumberOfElements();
1112 for ( size_t j = 0 ; j < numberOfElements ; j++ )
1113 {
1114 const G4Element* element = material->GetElement(j);
1115 if ( names.IsThisThermalElement ( material->GetName() , element->GetName() ) )
1116 {
1117 G4int ts_ID_of_this_geometry;
1118 G4String ts_ndl_name = names.GetTS_NDL_Name( material->GetName() , element->GetName() );
1119 if ( co_dic.find ( ts_ndl_name ) != co_dic.end() )
1120 {
1121 ts_ID_of_this_geometry = co_dic.find ( ts_ndl_name ) -> second;
1122 }
1123 else
1124 {
1125 ts_ID_of_this_geometry = co_dic.size();
1126 co_dic.insert ( std::pair< G4String , G4int >( ts_ndl_name , ts_ID_of_this_geometry ) );
1127 }
1128
1129 //G4cout << "Neutron HP Thermal Scattering: Registering a material-element pair of "
1130 // << material->GetName() << " " << element->GetName()
1131 // << " as internal thermal scattering id of " << ts_ID_of_this_geometry << "." << G4endl;
1132
1133 dic.insert( std::pair < std::pair < G4Material* , const G4Element* > , G4int > ( std::pair < G4Material* , const G4Element* > ( material , element ) , ts_ID_of_this_geometry ) );
1134 }
1135 }
1136 }
1137
1138 //Searching TS Elements
1139 static G4ThreadLocal G4ElementTable* theElementTable = 0 ; if (!theElementTable) theElementTable= G4Element::GetElementTable();
1140 size_t numberOfElements = G4Element::GetNumberOfElements();
1141 //size_t numberOfThermalElements = 0;
1142 for ( size_t i = 0 ; i < numberOfElements ; i++ )
1143 {
1144 const G4Element* element = (*theElementTable)[i];
1145 if ( names.IsThisThermalElement ( element->GetName() ) )
1146 {
1147 if ( names.IsThisThermalElement ( element->GetName() ) )
1148 {
1149 G4int ts_ID_of_this_geometry;
1150 G4String ts_ndl_name = names.GetTS_NDL_Name( element->GetName() );
1151 if ( co_dic.find ( ts_ndl_name ) != co_dic.end() )
1152 {
1153 ts_ID_of_this_geometry = co_dic.find ( ts_ndl_name ) -> second;
1154 }
1155 else
1156 {
1157 ts_ID_of_this_geometry = co_dic.size();
1158 co_dic.insert ( std::pair< G4String , G4int >( ts_ndl_name , ts_ID_of_this_geometry ) );
1159 }
1160
1161 //G4cout << "Neutron HP Thermal Scattering: Registering an element of "
1162 // << material->GetName() << " " << element->GetName()
1163 // << " as internal thermal scattering id of " << ts_ID_of_this_geometry << "." << G4endl;
1164
1165 dic.insert( std::pair < std::pair < const G4Material* , const G4Element* > , G4int > ( std::pair < const G4Material* , const G4Element* > ( (G4Material*)nullptr , element ) , ts_ID_of_this_geometry ) );
1166 }
1167 }
1168 }
1169
1170 G4cout << G4endl;
1171 G4cout << "Neutron HP Thermal Scattering: Following material-element pairs or elements are registered." << G4endl;
1172 for ( std::map < std::pair < const G4Material* , const G4Element* > , G4int >::iterator it = dic.begin() ; it != dic.end() ; it++ )
1173 {
1174 if ( it->first.first != nullptr )
1175 {
1176 G4cout << "Material " << it->first.first->GetName() << " - Element " << it->first.second->GetName() << ", internal thermal scattering id " << it->second << G4endl;
1177 }
1178 else
1179 {
1180 G4cout << "Element " << it->first.second->GetName() << ", internal thermal scattering id " << it->second << G4endl;
1181 }
1182 }
1183 G4cout << G4endl;
1184
1185 // Read Cross Section Data files
1186
1191
1193
1195
1196 if ( coherentFSs == nullptr ) coherentFSs = new std::map < G4int , std::map < G4double , std::vector < std::pair< G4double , G4double >* >* >* >;
1197 if ( incoherentFSs == nullptr ) incoherentFSs = new std::map < G4int , std::map < G4double , std::vector < E_isoAng* >* >* >;
1198 if ( inelasticFSs == nullptr ) inelasticFSs = new std::map < G4int , std::map < G4double , std::vector < E_P_E_isoAng* >* >* >;
1199
1200 G4String dirName;
1201 if ( !std::getenv( "G4NEUTRONHPDATA" ) )
1202 throw G4HadronicException(__FILE__, __LINE__, "Please setenv G4NEUTRONHPDATA to point to the neutron cross-section files.");
1203 dirName = std::getenv( "G4NEUTRONHPDATA" );
1204
1205 //G4String name;
1206
1207 for ( std::map < G4String , G4int >::iterator it = co_dic.begin() ; it != co_dic.end() ; it++ )
1208 {
1209 G4String tsndlName = it->first;
1210 G4int ts_ID = it->second;
1211
1212 // Coherent
1213 G4String fsName = "/ThermalScattering/Coherent/FS/";
1214 G4String fileName = dirName + fsName + tsndlName;
1215 coherentFSs->insert ( std::pair < G4int , std::map < G4double , std::vector < std::pair< G4double , G4double >* >* >* > ( ts_ID , readACoherentFSDATA( fileName ) ) );
1216
1217 // incoherent elastic
1218 fsName = "/ThermalScattering/Incoherent/FS/";
1219 fileName = dirName + fsName + tsndlName;
1220 incoherentFSs->insert ( std::pair < G4int , std::map < G4double , std::vector < E_isoAng* >* >* > ( ts_ID , readAnIncoherentFSDATA( fileName ) ) );
1221
1222 // inelastic
1223 fsName = "/ThermalScattering/Inelastic/FS/";
1224 fileName = dirName + fsName + tsndlName;
1225 inelasticFSs->insert ( std::pair < G4int , std::map < G4double , std::vector < E_P_E_isoAng* >* >* > ( ts_ID , readAnInelasticFSDATA( fileName ) ) );
1226 }
1227
1231 }
1232
1234}
1235
1236
1238{
1239 G4int result = -1;
1240 if ( dic.find( std::pair < const G4Material* , const G4Element* > ( material , element ) ) != dic.end() )
1241 result = dic.find( std::pair < const G4Material* , const G4Element* > ( material , element ) )->second;
1242 return result;
1243}
1244
1245
1246const std::pair<G4double, G4double> G4ParticleHPThermalScattering::GetFatalEnergyCheckLevels() const
1247{
1248 //return std::pair<G4double, G4double>(10*perCent,10*GeV);
1249 return std::pair<G4double, G4double>(10*perCent,DBL_MAX);
1250}
1251
1252
1254{
1255 names.AddThermalElement( nameG4Element , filename );
1256 theXSection->AddUserThermalScatteringFile( nameG4Element , filename );
1258}
1259
1260
1262{
1263 G4bool result=false;
1264
1265 G4int n = anE_IsoAng->n;
1266 G4double sum=0.0;
1267 for ( G4int i = 0 ; i < n ; i++ ) {
1268 sum += anE_IsoAng->isoAngle[ i ];
1269 }
1270 if ( sum != 0.0 ) result = true;
1271
1272 return result;
1273}
1274
1275
1277{
1278 outFile << "High Precision model based on thermal scattering data in\n"
1279 << "evaluated nuclear data libraries for neutrons below 5eV\n"
1280 << "on specific materials\n";
1281}
static const G4int LL[nN]
std::vector< G4Element * > G4ElementTable
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
static const G4double alpha
std::vector< G4Material * > G4MaterialTable
static const G4double dE
static constexpr double kelvin
Definition: G4SIunits.hh:274
static constexpr double perCent
Definition: G4SIunits.hh:325
static constexpr double second
Definition: G4SIunits.hh:137
static constexpr double eV
Definition: G4SIunits.hh:201
static const G4double angle[DIMMOTT]
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
#define G4UniformRand()
Definition: Randomize.hh:52
static G4ElementTable * GetElementTable()
Definition: G4Element.cc:397
G4double GetZ() const
Definition: G4Element.hh:131
static size_t GetNumberOfElements()
Definition: G4Element.cc:404
const G4String & GetName() const
Definition: G4Element.hh:127
void SetEnergyChange(G4double anEnergy)
void SetMomentumChange(const G4ThreeVector &aV)
const G4Material * GetMaterial() const
const G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
const G4LorentzVector & Get4Momentum() const
void SetMinEnergy(G4double anEnergy)
void SetMaxEnergy(const G4double anEnergy)
static size_t GetNumberOfMaterials()
Definition: G4Material.cc:679
G4double GetTemperature() const
Definition: G4Material.hh:178
const G4Element * GetElement(G4int iel) const
Definition: G4Material.hh:198
size_t GetNumberOfElements() const
Definition: G4Material.hh:182
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:672
static G4Neutron * Neutron()
Definition: G4Neutron.cc:103
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:105
void BuildPhysicsTable(const G4ParticleDefinition &)
void RegisterThermalScatteringCoherentFinalStates(std::map< G4int, std::map< G4double, std::vector< std::pair< G4double, G4double > * > * > * > *val)
void RegisterThermalScatteringIncoherentFinalStates(std::map< G4int, std::map< G4double, std::vector< E_isoAng * > * > * > *val)
void RegisterThermalScatteringInelasticFinalStates(std::map< G4int, std::map< G4double, std::vector< E_P_E_isoAng * > * > * > *val)
std::map< G4int, std::map< G4double, std::vector< std::pair< G4double, G4double > * > * > * > * GetThermalScatteringCoherentFinalStates()
static G4ParticleHPManager * GetInstance()
std::map< G4int, std::map< G4double, std::vector< E_isoAng * > * > * > * GetThermalScatteringIncoherentFinalStates()
void GetDataStream(G4String, std::istringstream &iss)
std::map< G4int, std::map< G4double, std::vector< E_P_E_isoAng * > * > * > * GetThermalScatteringInelasticFinalStates()
G4double GetCrossSection(const G4DynamicParticle *, const G4Element *, const G4Material *)
void BuildPhysicsTable(const G4ParticleDefinition &)
G4double GetCoherentCrossSection(const G4DynamicParticle *, const G4Element *, const G4Material *)
G4double GetInelasticCrossSection(const G4DynamicParticle *, const G4Element *, const G4Material *)
std::map< G4double, std::vector< std::pair< G4double, G4double > * > * > * readACoherentFSDATA(G4String)
std::pair< G4double, G4double > find_LH(G4double, std::vector< G4double > *)
G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &aTargetNucleus)
G4int getTS_ID(const G4Material *, const G4Element *)
E_isoAng create_E_isoAng_from_energy(G4double, std::vector< E_isoAng * > *)
void AddUserThermalScatteringFile(G4String, G4String)
std::map< G4double, std::vector< E_isoAng * > * > * readAnIncoherentFSDATA(G4String)
std::pair< G4double, E_isoAng > create_sE_and_EPM_from_pE_and_vE_P_E_isoAng(G4double, G4double, std::vector< E_P_E_isoAng * > *)
E_P_E_isoAng * readAnE_P_E_isoAng(std::istream *)
G4ParticleHPThermalScatteringNames names
std::map< G4int, std::map< G4double, std::vector< std::pair< G4double, G4double > * > * > * > * coherentFSs
virtual void ModelDescription(std::ostream &outFile) const
G4double get_linear_interpolated(G4double, std::pair< G4double, G4double >, std::pair< G4double, G4double >)
std::pair< G4double, G4double > sample_inelastic_E_mu(G4double pE, std::vector< E_P_E_isoAng * > *vNEP_EPM)
std::pair< G4double, G4int > sample_inelastic_E(G4double rndm1, G4double rndm2, E_P_E_isoAng *anE_P_E_isoAng)
std::map< G4int, std::map< G4double, std::vector< E_P_E_isoAng * > * > * > * inelasticFSs
virtual const std::pair< G4double, G4double > GetFatalEnergyCheckLevels() const
std::map< G4int, std::map< G4double, std::vector< E_isoAng * > * > * > * incoherentFSs
std::map< G4double, std::vector< E_P_E_isoAng * > * > * readAnInelasticFSDATA(G4String)
G4double get_secondary_energy_from_E_P_E_isoAng(G4double random, E_P_E_isoAng *anE_P_E_isoAng)
void BuildPhysicsTable(const G4ParticleDefinition &)
std::map< std::pair< const G4Material *, const G4Element * >, G4int > dic
G4ParticleHPThermalScatteringData * theXSection
static constexpr double twopi
Definition: SystemOfUnits.h:56
G4double total(Particle const *const p1, Particle const *const p2)
G4double energy(const ThreeVector &p, const G4double m)
const char * name(G4int ptype)
G4bool IsMasterThread()
Definition: G4Threading.cc:124
string material
Definition: eplot.py:19
std::vector< G4double > prob
std::vector< E_isoAng * > vE_isoAngle
std::vector< G4double > secondary_energy_pdf
std::vector< G4double > secondary_energy_cdf
std::vector< G4double > secondary_energy_value
std::vector< G4double > isoAngle
#define DBL_MAX
Definition: templates.hh:62
#define G4ThreadLocal
Definition: tls.hh:77