Geant4 11.3.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ParticleHPIsoProbabilityTable_NJOY.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//
27//-------------------------------------------------------------------
28//
29// Geant4 source file
30//
31// File name: G4ParticleHPIsoProbabilityTable_NJOY.cc
32//
33// Authors: Marek Zmeskal (CTU, Czech Technical University in Prague, Czech Republic)
34// Loic Thulliez (CEA France)
35//
36// Creation date: 4 June 2024
37//
38// Description: Class for the probability table of the given isotope
39// and for the given temperature generated with NJOY.
40// It reads the files with probability tables and
41// finds the correct cross-section.
42//
43// Modifications:
44//
45// -------------------------------------------------------------------
46//
47//
48
50#include "G4SystemOfUnits.hh"
51#include "G4DynamicParticle.hh"
52#include "G4ParticleHPVector.hh"
53#include "Randomize.hh"
54#include "G4NucleiProperties.hh"
55#include "G4ReactionProduct.hh"
59#include "G4Nucleus.hh"
60#include "G4Element.hh"
61
62#include <string>
63#include <sstream>
64
65///--------------------------------------------------------------------------------------
70
71///--------------------------------------------------------------------------------------
73
74///--------------------------------------------------------------------------------------
75void G4ParticleHPIsoProbabilityTable_NJOY::Init( G4int theZ, G4int theA, G4int them, G4double theT, const G4String& dirName ) {
76 Z = theZ;
77 A = theA;
78 m = them;
79 T = theT;
80 G4cout << "The NJOY probability tables are being initialized for Z=" << Z << " A=" << A << " and T=" << T << " K." << G4endl;
81 std::string strZ = std::to_string(Z);
82 std::string strA = std::to_string(A);
83 filename = strZ + "_" + strA;
84 if ( m != 0 ) {
85 std::string strm = std::to_string(m);
86 filename += "_m" + strm;
87 }
88 G4String fullPathFileName = dirName + filename + "." + std::to_string( (G4int)(T) ) + ".pt";
89 std::istringstream theData( std::ios::in );
90 G4ParticleHPManager::GetInstance()->GetDataStream( fullPathFileName, theData );
91 if ( theData.good() ) {
92 G4double emin;
93 G4double emax;
94 G4double energy;
95 theData >> emin >> emax;
96 Emin = emin * eV;
97 Emax = emax * eV;
98 theData >> nEnergies >> tableOrder >> lssf_flag;
100 theProbabilities = new std::vector< std::vector< G4double >* >;
101 theElasticData = new std::vector< std::vector< G4double >* >;
102 theCaptureData = new std::vector< std::vector< G4double >* >;
103 theFissionData = new std::vector< std::vector< G4double >* >;
104 G4double probability, total, elastic, capture, fission;
105 for ( G4int i = 0; i < nEnergies; i++ ) {
106 theData >> energy;
107 theEnergies->SetEnergy( i, energy * eV );
108 std::vector< G4double >* vecprob = new std::vector< G4double >;
109 std::vector< G4double >* vecela = new std::vector< G4double >;
110 std::vector< G4double >* veccap = new std::vector< G4double >;
111 std::vector< G4double >* vecfiss = new std::vector< G4double >;
112 for ( G4int j = 0; j < tableOrder; j++ ) {
113 theData >> probability >> total >> elastic >> capture >> fission;
114 vecprob->push_back( probability );
115 vecela->push_back( elastic );
116 veccap->push_back( capture );
117 vecfiss->push_back( fission );
118 }
119 theProbabilities->push_back( vecprob );
120 theElasticData->push_back( vecela );
121 theCaptureData->push_back( veccap );
122 theFissionData->push_back( vecfiss );
123 }
124 G4cout << "Probability tables found and succesfully read from " << Emin / keV << " keV to " << Emax / keV << " keV." << G4endl;
125 } else {
126 G4cout << "No probability tables found for this isotope and temperature, smooth cross section will be used instead." << G4endl;
127 }
128}
129
130///--------------------------------------------------------------------------------------
132 const G4Element* ele, G4double& kineticEnergy, G4double& random_number, std::thread::id& id ) {
133 if ( kineticEnergy == energy_cache[id] ) {
134 if ( MTnumber == 2 ) { // elastic cross section
135 return xsela_cache[id];
136 } else if ( MTnumber == 102 ) { // radiative capture cross section
137 return xscap_cache[id];
138 } else if ( MTnumber == 18 ) { // fission cross section
139 return xsfiss_cache[id];
140 }
141 }
142 energy_cache[id] = kineticEnergy;
143 if ( kineticEnergy < Emin || kineticEnergy > Emax ) {
144 // if the kinetic energy is outside of the URR limits for the given isotope, it finds the smooth cross section
145 G4int indexEl = (G4int)ele->GetIndex();
146 G4int isotopeJ = -1; // index of isotope in the given element
147 for ( G4int j = 0; j < (G4int)ele->GetNumberOfIsotopes(); j++ ) {
148 if ( A == (G4int)ele->GetIsotope(j)->GetN() ) {
149 isotopeJ = j;
150 break;
151 }
152 }
153 G4double frac = ele->GetRelativeAbundanceVector()[isotopeJ];
154 G4double weightedelasticXS;
155 G4double weightedcaptureXS;
156 if ( G4ParticleHPManager::GetInstance()->GetNeglectDoppler() ) {
157 weightedelasticXS = (*G4ParticleHPManager::GetInstance()->GetElasticFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
158 weightedcaptureXS = (*G4ParticleHPManager::GetInstance()->GetCaptureFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
159 } else {
160 weightedelasticXS = this->GetDopplerBroadenedElasticXS( dp, indexEl, isotopeJ );
161 weightedcaptureXS = this->GetDopplerBroadenedCaptureXS( dp, indexEl, isotopeJ );
162 }
163 xsela_cache[id] = weightedelasticXS / frac;
164 xscap_cache[id] = weightedcaptureXS / frac;
165 if ( Z < 88 ) {
166 xsfiss_cache[id] = 0.0;
167 } else {
168 if ( G4ParticleHPManager::GetInstance()->GetNeglectDoppler() ) {
169 G4double weightedfissionXS = (*G4ParticleHPManager::GetInstance()->GetFissionFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
170 xsfiss_cache[id] = weightedfissionXS / frac;
171 } else {
172 G4double weightedfissionXS = this->GetDopplerBroadenedFissionXS( dp, indexEl, isotopeJ );
173 xsfiss_cache[id] = weightedfissionXS / frac;
174 }
175 }
176 } else if ( lssf_flag == 0 ) {
177 G4int indexE = theEnergies->GetEnergyIndex( kineticEnergy );
178 std::vector< G4double >* theProbability1 = theProbabilities->at(indexE - 1);
179 std::vector< G4double >* theProbability2 = theProbabilities->at(indexE);
180 G4double ene1 = theEnergies->GetEnergy(indexE - 1);
181 G4double ene2 = theEnergies->GetEnergy(indexE);
182 G4double rand = random_number;
183 G4int indexP1;
184 G4int indexP2;
185 for ( indexP1 = 0; indexP1 < tableOrder; indexP1++ ) {
186 if ( rand <= theProbability1->at(indexP1) ) break;
187 }
188 for ( indexP2 = 0; indexP2 < tableOrder; indexP2++ ) {
189 if ( rand <= theProbability2->at(indexP2) ) break;
190 }
191 G4double ela1 = theElasticData->at(indexE - 1)->at(indexP1);
192 G4double ela2 = theElasticData->at(indexE)->at(indexP2);
193 G4double cap1 = theCaptureData->at(indexE - 1)->at(indexP1);
194 G4double cap2 = theCaptureData->at(indexE)->at(indexP2);
195 xsela_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, ela1, ela2 ) * barn;
196 xscap_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, cap1, cap2 ) * barn;
197 if ( Z < 88 ) {
198 xsfiss_cache[id] = 0.0;
199 } else {
200 G4double fiss1 = theFissionData->at(indexE - 1)->at(indexP1);
201 G4double fiss2 = theFissionData->at(indexE)->at(indexP2);
202 xsfiss_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, fiss1, fiss2 ) * barn;
203 }
204 } else if ( lssf_flag == 1 ) {
205 G4int indexE = theEnergies->GetEnergyIndex( kineticEnergy );
206 std::vector< G4double >* theProbability1 = theProbabilities->at(indexE - 1);
207 std::vector< G4double >* theProbability2 = theProbabilities->at(indexE);
208 G4double ene1 = theEnergies->GetEnergy(indexE - 1);
209 G4double ene2 = theEnergies->GetEnergy(indexE);
210 G4double rand = random_number;
211 G4int indexP1;
212 G4int indexP2;
213 for ( indexP1 = 0; indexP1 < tableOrder; indexP1++ ) {
214 if ( rand <= theProbability1->at(indexP1) ) break;
215 }
216 for ( indexP2 = 0; indexP2 < tableOrder; indexP2++ ) {
217 if ( rand <= theProbability2->at(indexP2) ) break;
218 }
219 G4int indexEl = (G4int)ele->GetIndex();
220 G4int isotopeJ = -1; // index of isotope in the given element
221 for ( G4int j = 0; j < (G4int)ele->GetNumberOfIsotopes(); j++ ) {
222 if ( A == (G4int)ele->GetIsotope(j)->GetN() ) {
223 isotopeJ = j;
224 break;
225 }
226 }
227 G4double frac = ele->GetRelativeAbundanceVector()[isotopeJ];
228 G4double weightedelasticXS;
229 G4double weightedcaptureXS;
230 if ( G4ParticleHPManager::GetInstance()->GetNeglectDoppler() ) {
231 weightedelasticXS = (*G4ParticleHPManager::GetInstance()->GetElasticFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
232 weightedcaptureXS = (*G4ParticleHPManager::GetInstance()->GetCaptureFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
233 } else {
234 weightedelasticXS = this->GetDopplerBroadenedElasticXS( dp, indexEl, isotopeJ );
235 weightedcaptureXS = this->GetDopplerBroadenedCaptureXS( dp, indexEl, isotopeJ );
236 }
237 G4double ela1 = theElasticData->at(indexE - 1)->at(indexP1);
238 G4double ela2 = theElasticData->at(indexE)->at(indexP2);
239 G4double cap1 = theCaptureData->at(indexE - 1)->at(indexP1);
240 G4double cap2 = theCaptureData->at(indexE)->at(indexP2);
241 G4double elasticXS = weightedelasticXS / frac;
242 G4double captureXS = weightedcaptureXS / frac;
243 xsela_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, ela1, ela2 ) * elasticXS;
244 xscap_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, cap1, cap2 ) * captureXS;
245 if ( Z < 88 ) {
246 xsfiss_cache[id] = 0.0;
247 } else {
248 if ( G4ParticleHPManager::GetInstance()->GetNeglectDoppler() ) {
249 G4double weightedfissionXS = (*G4ParticleHPManager::GetInstance()->GetFissionFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
250 G4double fissionXS = weightedfissionXS / frac;
251 G4double fiss1 = theFissionData->at(indexE - 1)->at(indexP1);
252 G4double fiss2 = theFissionData->at(indexE)->at(indexP2);
253 xsfiss_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, fiss1, fiss2 ) * fissionXS;
254 } else {
255 G4double weightedfissionXS = this->GetDopplerBroadenedFissionXS( dp, indexEl, isotopeJ );
256 G4double fissionXS = weightedfissionXS / frac;
257 G4double fiss1 = theFissionData->at(indexE - 1)->at(indexP1);
258 G4double fiss2 = theFissionData->at(indexE)->at(indexP2);
259 xsfiss_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, fiss1, fiss2 ) * fissionXS;
260 }
261 }
262 }
263 if ( MTnumber == 2 ) { // elastic cross section
264 return xsela_cache[id];
265 } else if ( MTnumber == 102 ) { // radiative capture cross section
266 return xscap_cache[id];
267 } else if ( MTnumber == 18 ) { // fission cross section
268 return xsfiss_cache[id];
269 } else {
270 G4cout << "Reaction was not found, returns 0." << G4endl;
271 return 0;
272 }
273}
274
275///--------------------------------------------------------------------------------------
277 const G4Element* ele, G4double& kineticEnergy, std::map< std::thread::id, G4double >& random_number_cache, std::thread::id& id ) {
278 energy_cache[id] = kineticEnergy;
279 if ( kineticEnergy < Emin || kineticEnergy > Emax ) {
280 // if the kinetic energy is outside of the URR limits for the given isotope, it finds the smooth cross section
281 G4int indexEl = (G4int)ele->GetIndex();
282 G4int isotopeJ = -1; // index of isotope in the given element
283 for ( G4int j = 0; j < (G4int)ele->GetNumberOfIsotopes(); j++ ) {
284 if ( A == (G4int)ele->GetIsotope(j)->GetN() ) {
285 isotopeJ = j;
286 break;
287 }
288 }
289 G4double frac = ele->GetRelativeAbundanceVector()[isotopeJ];
290 G4double weightedelasticXS;
291 G4double weightedcaptureXS;
292 if ( G4ParticleHPManager::GetInstance()->GetNeglectDoppler() ) {
293 weightedelasticXS = (*G4ParticleHPManager::GetInstance()->GetElasticFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
294 weightedcaptureXS = (*G4ParticleHPManager::GetInstance()->GetCaptureFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
295 } else {
296 weightedelasticXS = this->GetDopplerBroadenedElasticXS( dp, indexEl, isotopeJ );
297 weightedcaptureXS = this->GetDopplerBroadenedCaptureXS( dp, indexEl, isotopeJ );
298 }
299 xsela_cache[id] = weightedelasticXS / frac;
300 xscap_cache[id] = weightedcaptureXS / frac;
301 if ( Z < 88 ) {
302 xsfiss_cache[id] = 0.0;
303 } else {
304 if ( G4ParticleHPManager::GetInstance()->GetNeglectDoppler() ) {
305 G4double weightedfissionXS = (*G4ParticleHPManager::GetInstance()->GetFissionFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
306 xsfiss_cache[id] = weightedfissionXS / frac;
307 } else {
308 G4double weightedfissionXS = this->GetDopplerBroadenedFissionXS( dp, indexEl, isotopeJ );
309 xsfiss_cache[id] = weightedfissionXS / frac;
310 }
311 }
312 } else if ( lssf_flag == 0 ) {
313 G4int indexE = theEnergies->GetEnergyIndex(kineticEnergy);
314 std::vector< G4double >* theProbability1 = theProbabilities->at(indexE - 1);
315 std::vector< G4double >* theProbability2 = theProbabilities->at(indexE);
316 G4double ene1 = theEnergies->GetEnergy(indexE - 1);
317 G4double ene2 = theEnergies->GetEnergy(indexE);
318 G4double rand = G4UniformRand();
319 random_number_cache[id] = rand;
320 G4int indexP1;
321 G4int indexP2;
322 for ( indexP1 = 0; indexP1 < tableOrder; indexP1++ ) {
323 if ( rand <= theProbability1->at(indexP1) ) break;
324 }
325 for ( indexP2 = 0; indexP2 < tableOrder; indexP2++ ) {
326 if ( rand <= theProbability2->at(indexP2) ) break;
327 }
328 G4double ela1 = theElasticData->at(indexE - 1)->at(indexP1);
329 G4double ela2 = theElasticData->at(indexE)->at(indexP2);
330 G4double cap1 = theCaptureData->at(indexE - 1)->at(indexP1);
331 G4double cap2 = theCaptureData->at(indexE)->at(indexP2);
332 xsela_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, ela1, ela2 ) * barn;
333 xscap_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, cap1, cap2 ) * barn;
334 if ( Z < 88 ) {
335 xsfiss_cache[id] = 0.0;
336 } else {
337 G4double fiss1 = theFissionData->at(indexE - 1)->at(indexP1);
338 G4double fiss2 = theFissionData->at(indexE)->at(indexP2);
339 xsfiss_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, fiss1, fiss2 ) * barn;
340 }
341 } else if ( lssf_flag == 1 ) {
342 G4int indexE = theEnergies->GetEnergyIndex( kineticEnergy );
343 std::vector< G4double >* theProbability1 = theProbabilities->at(indexE - 1);
344 std::vector< G4double >* theProbability2 = theProbabilities->at(indexE);
345 G4double ene1 = theEnergies->GetEnergy(indexE - 1);
346 G4double ene2 = theEnergies->GetEnergy(indexE);
347 G4double rand = G4UniformRand();
348 random_number_cache[id] = rand;
349 G4int indexP1;
350 G4int indexP2;
351 for ( indexP1 = 0; indexP1 < tableOrder; indexP1++ ) {
352 if ( rand <= theProbability1->at(indexP1) ) break;
353 }
354 for ( indexP2 = 0; indexP2 < tableOrder; indexP2++ ) {
355 if ( rand <= theProbability2->at(indexP2) ) break;
356 }
357 G4int indexEl = (G4int)ele->GetIndex();
358 G4int isotopeJ = -1; // index of isotope in the given element
359 for ( G4int j = 0; j < (G4int)ele->GetNumberOfIsotopes(); j++ ) {
360 if ( A == (G4int)ele->GetIsotope(j)->GetN() ) {
361 isotopeJ = j;
362 break;
363 }
364 }
365 G4double frac = ele->GetRelativeAbundanceVector()[isotopeJ];
366 G4double weightedelasticXS;
367 G4double weightedcaptureXS;
368 if ( G4ParticleHPManager::GetInstance()->GetNeglectDoppler() ) {
369 weightedelasticXS = (*G4ParticleHPManager::GetInstance()->GetElasticFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
370 weightedcaptureXS = (*G4ParticleHPManager::GetInstance()->GetCaptureFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
371 } else {
372 weightedelasticXS = this->GetDopplerBroadenedElasticXS( dp, indexEl, isotopeJ );
373 weightedcaptureXS = this->GetDopplerBroadenedCaptureXS( dp, indexEl, isotopeJ );
374 }
375 G4double ela1 = theElasticData->at(indexE - 1)->at(indexP1);
376 G4double ela2 = theElasticData->at(indexE)->at(indexP2);
377 G4double cap1 = theCaptureData->at(indexE - 1)->at(indexP1);
378 G4double cap2 = theCaptureData->at(indexE)->at(indexP2);
379 G4double elasticXS = weightedelasticXS / frac;
380 G4double captureXS = weightedcaptureXS / frac;
381 xsela_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, ela1, ela2 ) * elasticXS;
382 xscap_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, cap1, cap2 ) * captureXS;
383 if ( Z < 88 ) {
384 xsfiss_cache[id] = 0.0;
385 } else {
386 if ( G4ParticleHPManager::GetInstance()->GetNeglectDoppler() ) {
387 G4double weightedfissionXS = (*G4ParticleHPManager::GetInstance()->GetFissionFinalStates())[indexEl]->GetWeightedXsec( kineticEnergy, isotopeJ );
388 G4double fissionXS = weightedfissionXS / frac;
389 G4double fiss1 = theFissionData->at(indexE - 1)->at(indexP1);
390 G4double fiss2 = theFissionData->at(indexE)->at(indexP2);
391 xsfiss_cache[id] = theInt.Lin(kineticEnergy, ene1, ene2, fiss1, fiss2) * fissionXS;
392 } else {
393 G4double weightedfissionXS = this->GetDopplerBroadenedFissionXS( dp, indexEl, isotopeJ );
394 G4double fissionXS = weightedfissionXS / frac;
395 G4double fiss1 = theFissionData->at(indexE - 1)->at(indexP1);
396 G4double fiss2 = theFissionData->at(indexE)->at(indexP2);
397 xsfiss_cache[id] = theInt.Lin( kineticEnergy, ene1, ene2, fiss1, fiss2 ) * fissionXS;
398 }
399 }
400 }
401 if ( MTnumber == 2 ) { // elastic cross section
402 return xsela_cache[id];
403 } else if ( MTnumber == 102 ) { // radiative capture cross section
404 return xscap_cache[id];
405 } else if ( MTnumber == 18 ) { // fission cross section
406 return xsfiss_cache[id];
407 } else {
408 G4cout << "Reaction was not found, returns 0." << G4endl;
409 return 0;
410 }
411}
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
G4double GetIsoCrossSectionPT(const G4DynamicParticle *, G4int, const G4Element *, G4double &, std::map< std::thread::id, G4double > &, std::thread::id &) override
G4double GetCorrelatedIsoCrossSectionPT(const G4DynamicParticle *, G4int, const G4Element *, G4double &, G4double &, std::thread::id &) override
void Init(G4int, G4int, G4int, G4double, const G4String &) override
std::map< std::thread::id, G4double > xsela_cache
std::map< std::thread::id, G4double > xscap_cache
std::map< std::thread::id, G4double > energy_cache
G4double GetDopplerBroadenedFissionXS(const G4DynamicParticle *, G4int, G4int)
std::vector< std::vector< G4double > * > * theElasticData
std::vector< std::vector< G4double > * > * theFissionData
std::map< std::thread::id, G4double > xsfiss_cache
std::vector< std::vector< G4double > * > * theCaptureData
G4double GetDopplerBroadenedCaptureXS(const G4DynamicParticle *, G4int, G4int)
G4double GetDopplerBroadenedElasticXS(const G4DynamicParticle *, G4int, G4int)
std::vector< std::vector< G4double > * > * theProbabilities
std::vector< G4ParticleHPChannel * > * GetFissionFinalStates() const
std::vector< G4ParticleHPChannel * > * GetElasticFinalStates() const
std::vector< G4ParticleHPChannel * > * GetCaptureFinalStates() const
void GetDataStream(const G4String &, std::istringstream &iss)
static G4ParticleHPManager * GetInstance()