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
G4ParticleHPJENDLHEData.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// Class Description
27// Cross-section data set for a high precision (based on JENDL_HE evaluated data
28// libraries) description of elastic scattering 20 MeV ~ 3 GeV;
29// Class Description - End
30
31// 15-Nov-06 First Implementation is done by T. Koi (SLAC/SCCS)
32// P. Arce, June-2014 Conversion neutron_hp to particle_hp
33//
35#include "G4SystemOfUnits.hh"
37#include "G4ElementTable.hh"
38#include "G4ParticleHPData.hh"
39#include "G4Pow.hh"
40
42{
43 G4bool result = true;
44 G4double eKin = aP->GetKineticEnergy();
45 //if(eKin>20*MeV||aP->GetDefinition()!=G4Neutron::Neutron()) result = false;
46 if ( eKin < 20*MeV || 3*GeV < eKin || aP->GetDefinition()!=G4Neutron::Neutron() )
47 {
48 result = false;
49 }
50// Element Check
51 else if ( !(vElement[ anE->GetIndex() ]) ) result = false;
52
53 return result;
54}
55
56
58{
59 for ( std::map< G4int , std::map< G4int , G4PhysicsVector* >* >::iterator itZ = mIsotope.begin();
60 itZ != mIsotope.end(); ++itZ ) {
61 std::map< G4int , G4PhysicsVector* >* pointer_map = itZ->second;
62 if ( pointer_map ) {
63 for ( std::map< G4int , G4PhysicsVector* >::iterator itA = pointer_map->begin();
64 itA != pointer_map->end() ; ++itA ) {
65 G4PhysicsVector* pointerPhysicsVector = itA->second;
66 if ( pointerPhysicsVector ) {
67 delete pointerPhysicsVector;
68 itA->second = NULL;
69 }
70 }
71 delete pointer_map;
72 itZ->second = NULL;
73 }
74 }
75 mIsotope.clear();
76}
77
78
80 : G4VCrossSectionDataSet( "JENDLHE"+reaction+"CrossSection" )
81{
82 reactionName = reaction;
83 BuildPhysicsTable( *pd );
84}
85
86
88{
89}
90
91
93{
94 particleName = aP.GetParticleName();
95
96 G4String baseName = G4FindDataDir( "G4NEUTRONHPDATA" );
97 G4String dirName = baseName+"/JENDL_HE/"+particleName+"/"+reactionName ;
98 G4String aFSType = "/CrossSection/";
99 G4ParticleHPNames theNames;
100
101 G4String filename;
102
103 // Create JENDL_HE data
104 // Create map element or isotope
105
106 std::size_t numberOfElements = G4Element::GetNumberOfElements();
107
108 // make a PhysicsVector for each element
109
110 static G4ThreadLocal G4ElementTable *theElementTable = 0 ; if (!theElementTable) theElementTable= G4Element::GetElementTable();
111 vElement.clear();
112 vElement.resize( numberOfElements );
113 for ( std::size_t i = 0; i < numberOfElements; ++i )
114 {
115 G4Element* theElement = (*theElementTable)[i];
116 vElement[i] = false;
117
118 // isotope
119 G4int nIso = (G4int)(*theElementTable)[i]->GetNumberOfIsotopes();
120 G4int Z = (G4int)(*theElementTable)[i]->GetZ();
121 if ( nIso!=0 )
122 {
123 G4bool found_at_least_one = false;
124 for ( G4int i1 = 0; i1 < nIso; ++i1 )
125 {
126 G4int A = theElement->GetIsotope(i1)->GetN();
127
128 if ( isThisNewIsotope( Z , A ) )
129 {
130 std::stringstream ss;
131 ss << dirName << aFSType << Z << "_" << A << "_" << theNames.GetName( Z-1 );
132 filename = ss.str();
133 std::fstream file;
134 file.open ( filename , std::fstream::in );
135 G4int dummy;
136 file >> dummy;
137 if ( file.good() )
138 {
139 found_at_least_one = true;
140
141 // read the file
142 G4PhysicsVector* aPhysVec = readAFile ( &file );
143 registAPhysicsVector( Z , A , aPhysVec );
144 }
145 else
146 {
147 //G4cout << "No file for "<< reactionType << " Z=" << Z << ", A=" << A << G4endl;
148 }
149 file.close();
150 }
151 else
152 {
153 found_at_least_one = TRUE;
154 }
155 }
156 if ( found_at_least_one ) vElement[i] = true;
157 }
158 else
159 {
160 G4StableIsotopes theStableOnes;
161 G4int first = theStableOnes.GetFirstIsotope( Z );
162 G4bool found_at_least_one = FALSE;
163 for ( G4int i1 = 0; i1 < theStableOnes.GetNumberOfIsotopes( static_cast<G4int>(theElement->GetZ() ) ); i1++)
164 {
165 G4int A = theStableOnes.GetIsotopeNucleonCount( first+i1 );
166 if ( isThisNewIsotope( Z , A ) )
167 {
168
169 std::stringstream ss;
170 ss << dirName << aFSType << Z << "_" << A << "_" << theNames.GetName( Z-1 );
171 filename = ss.str();
172
173 std::fstream file;
174 file.open ( filename , std::fstream::in );
175 G4int dummy;
176 file >> dummy;
177 if ( file.good() )
178 {
179 //G4cout << "Found file for Z=" << Z << ", A=" << A << ", as " << filename << G4endl;
180 found_at_least_one = TRUE;
181 //Read the file
182
183 G4PhysicsVector* aPhysVec = readAFile ( &file );
184
185 //Regist the PhysicsVector
186 registAPhysicsVector( Z , A , aPhysVec );
187 }
188 else
189 {
190 //G4cout << "No file for "<< reactionType << " Z=" << Z << ", A=" << A << G4endl;
191 }
192 file.close();
193 }
194 else
195 {
196 found_at_least_one = TRUE;
197 }
198 }
199
200 if ( found_at_least_one ) vElement[i] = true;
201 }
202 }
203}
204
205
207{
208 if(&aP!=G4Neutron::Neutron())
209 throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!");
210}
211
212
215{
216 // Primary energy >20MeV
217 // Thus not taking into account of Doppler broadening
218 // also not taking into account of Target thermal motions
219
220 G4double result = 0;
221
222 G4double ek = aP->GetKineticEnergy();
223
224 G4int nIso = (G4int)anE->GetNumberOfIsotopes();
225 G4int Z = (G4int)anE->GetZ();
226 if ( nIso!=0 )
227 {
228 for ( G4int i1 = 0; i1 < nIso; ++i1 )
229 {
230 G4int A = anE->GetIsotope(i1)->GetN();
231 G4double frac = anE->GetRelativeAbundanceVector()[ i1 ]; // This case does NOT request "*perCent".
232 result += frac * getXSfromThisIsotope( Z , A , ek );
233 }
234 }
235 else
236 {
237 G4StableIsotopes theStableOnes;
238 G4int first = theStableOnes.GetFirstIsotope( Z );
239 for ( G4int i1 = 0; i1 < theStableOnes.GetNumberOfIsotopes( (G4int)anE->GetZ() ); ++i1)
240 {
241 G4int A = theStableOnes.GetIsotopeNucleonCount( first+i1 );
242 G4double frac = theStableOnes.GetAbundance( first+i1 )*perCent; // This case requests "*perCent".
243 result += frac * getXSfromThisIsotope( Z , A , ek );
244 }
245 }
246 return result;
247}
248
249
250G4PhysicsVector* G4ParticleHPJENDLHEData::readAFile ( std::fstream* file )
251{
252 G4int dummy;
253 G4int len;
254 *file >> dummy;
255 *file >> len;
256
257 std::vector< G4double > v_e;
258 std::vector< G4double > v_xs;
259
260 for ( G4int i = 0 ; i < len ; ++i )
261 {
262 G4double e;
263 G4double xs;
264
265 *file >> e;
266 *file >> xs;
267 // data are written in eV and barn.
268 v_e.push_back( e*eV );
269 v_xs.push_back( xs*barn );
270 }
271
272 G4PhysicsFreeVector* aPhysVec = new G4PhysicsFreeVector( static_cast< std::size_t >( len ) , v_e.front() , v_e.back() );
273
274 for ( G4int i = 0 ; i < len ; ++i )
275 {
276 aPhysVec->PutValues( static_cast< std::size_t >( i ) , v_e[ i ] , v_xs[ i ] );
277 }
278
279 return aPhysVec;
280}
281
282
283G4bool G4ParticleHPJENDLHEData::isThisInMap( G4int z , G4int a )
284{
285 if ( mIsotope.find ( z ) == mIsotope.end() ) return false;
286 if ( mIsotope.find ( z ) -> second->find ( a ) == mIsotope.find ( z ) -> second->end() ) return false;
287 return true;
288}
289
290
291void G4ParticleHPJENDLHEData::registAPhysicsVector( G4int Z , G4int A , G4PhysicsVector* aPhysVec )
292{
293 std::pair< G4int , G4PhysicsVector* > aPair = std::pair < G4int , G4PhysicsVector* > ( A , aPhysVec );
294 auto itm = mIsotope.find ( Z );
295 if ( itm != mIsotope.cend() )
296 {
297 itm->second->insert ( aPair );
298 }
299 else
300 {
301 std::map< G4int , G4PhysicsVector* >* aMap = new std::map< G4int , G4PhysicsVector* >;
302 aMap->insert ( aPair );
303 mIsotope.insert( std::pair< G4int , std::map< G4int , G4PhysicsVector* >* > ( Z , aMap ) );
304 }
305}
306
307
308G4double G4ParticleHPJENDLHEData::getXSfromThisIsotope( G4int Z , G4int A , G4double ek )
309{
310 G4double aXSection = 0.0;
311 G4bool outOfRange;
312
313 G4PhysicsVector* aPhysVec;
314 if ( mIsotope.find ( Z )->second->find ( A ) != mIsotope.find ( Z )->second->end() )
315 {
316 aPhysVec = mIsotope.find ( Z )->second->find ( A )->second;
317 aXSection = aPhysVec->GetValue( ek , outOfRange );
318 }
319 else
320 {
321 // Select closest one in the same Z
322 G4int delta0 = 99; // no mean for 99
323 for ( auto it = mIsotope.find ( Z )->second->cbegin();
324 it!= mIsotope.find ( Z )->second->cend(); ++it )
325 {
326 G4int delta = std::abs( A - it->first );
327 if ( delta < delta0 ) delta0 = delta;
328 }
329
330 // Randomize of selection larger or smaller than A
331 if ( G4UniformRand() < 0.5 ) delta0 *= -1;
332 G4int A1 = A + delta0;
333 if ( mIsotope.find ( Z )->second->find ( A1 ) != mIsotope.find ( Z )->second->cend() )
334 {
335 aPhysVec = mIsotope.find ( Z )->second->find ( A1 )->second;
336 }
337 else
338 {
339 A1 = A - delta0;
340 aPhysVec = mIsotope.find ( Z )->second->find ( A1 )->second;
341 }
342
343 aXSection = aPhysVec->GetValue( ek , outOfRange );
344 // X^(2/3) factor
345 aXSection *= G4Pow::GetInstance()->A23( 1.0*A/ A1 );
346 }
347
348 return aXSection;
349}
std::vector< G4Element * > G4ElementTable
const char * G4FindDataDir(const char *)
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
const G4double A[17]
#define G4UniformRand()
Definition: Randomize.hh:52
G4double GetKineticEnergy() const
static G4ElementTable * GetElementTable()
Definition: G4Element.cc:403
G4double * GetRelativeAbundanceVector() const
Definition: G4Element.hh:167
G4double GetZ() const
Definition: G4Element.hh:131
static size_t GetNumberOfElements()
Definition: G4Element.cc:410
const G4Isotope * GetIsotope(G4int iso) const
Definition: G4Element.hh:170
size_t GetIndex() const
Definition: G4Element.hh:182
size_t GetNumberOfIsotopes() const
Definition: G4Element.hh:159
G4int GetN() const
Definition: G4Isotope.hh:93
static G4Neutron * Neutron()
Definition: G4Neutron.cc:103
const G4String & GetParticleName() const
G4double GetCrossSection(const G4DynamicParticle *, const G4Element *, G4double aT)
G4bool IsApplicable(const G4DynamicParticle *, const G4Element *)
void BuildPhysicsTable(const G4ParticleDefinition &)
void DumpPhysicsTable(const G4ParticleDefinition &)
G4ParticleHPDataUsed GetName(G4int A, G4int Z, G4String base, G4String rest, G4bool &active)
void PutValues(const std::size_t index, const G4double energy, const G4double value)
G4double GetValue(const G4double energy, G4bool &isOutRange) const
static G4Pow * GetInstance()
Definition: G4Pow.cc:41
G4double A23(G4double A) const
Definition: G4Pow.hh:131
G4double GetAbundance(G4int number)
G4int GetFirstIsotope(G4int Z)
G4int GetNumberOfIsotopes(G4int Z)
G4int GetIsotopeNucleonCount(G4int number)
#define TRUE
Definition: globals.hh:41
#define FALSE
Definition: globals.hh:38
#define G4ThreadLocal
Definition: tls.hh:77