Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // Class Description 26 // Class Description 27 // Cross-section data set for a high precision 27 // Cross-section data set for a high precision (based on JENDL_HE evaluated data 28 // libraries) description of elastic scatterin 28 // libraries) description of elastic scattering 20 MeV ~ 3 GeV; 29 // Class Description - End 29 // Class Description - End 30 30 31 // 15-Nov-06 First Implementation is done by T 31 // 15-Nov-06 First Implementation is done by T. Koi (SLAC/SCCS) 32 // P. Arce, June-2014 Conversion neutron_hp to 32 // P. Arce, June-2014 Conversion neutron_hp to particle_hp 33 // 33 // 34 #include "G4ParticleHPJENDLHEData.hh" 34 #include "G4ParticleHPJENDLHEData.hh" 35 << 35 #include "G4SystemOfUnits.hh" >> 36 #include "G4PhysicsFreeVector.hh" 36 #include "G4ElementTable.hh" 37 #include "G4ElementTable.hh" 37 #include "G4ParticleHPData.hh" 38 #include "G4ParticleHPData.hh" 38 #include "G4PhysicsFreeVector.hh" << 39 #include "G4Pow.hh" 39 #include "G4Pow.hh" 40 #include "G4SystemOfUnits.hh" << 41 40 42 G4bool G4ParticleHPJENDLHEData::IsApplicable(c << 41 G4bool G4ParticleHPJENDLHEData::IsApplicable(const G4DynamicParticle*aP, const G4Element* anE) 43 { 42 { 44 G4bool result = true; << 45 G4double eKin = aP->GetKineticEnergy(); << 46 // if(eKin>20*MeV||aP->GetDefinition()!=G4Ne << 47 if (eKin < 20 * MeV || 3 * GeV < eKin || aP- << 48 result = false; << 49 } << 50 // Element Check << 51 else if (!(vElement[anE->GetIndex()])) << 52 result = false; << 53 43 54 return result; << 44 G4bool result = true; >> 45 G4double eKin = aP->GetKineticEnergy(); >> 46 //if(eKin>20*MeV||aP->GetDefinition()!=G4Neutron::Neutron()) result = false; >> 47 if ( eKin < 20*MeV || 3*GeV < eKin || aP->GetDefinition()!=G4Neutron::Neutron() ) >> 48 { >> 49 result = false; >> 50 } >> 51 // Element Check >> 52 else if ( !(vElement[ anE->GetIndex() ]) ) result = false; >> 53 >> 54 return result; >> 55 55 } 56 } 56 57 >> 58 >> 59 57 G4ParticleHPJENDLHEData::G4ParticleHPJENDLHEDa 60 G4ParticleHPJENDLHEData::G4ParticleHPJENDLHEData() 58 { 61 { 59 for (auto& itZ : mIsotope) { << 62 for ( std::map< G4int , std::map< G4int , G4PhysicsVector* >* >::iterator itZ = mIsotope.begin(); 60 std::map<G4int, G4PhysicsVector*>* pointer << 63 itZ != mIsotope.end(); ++itZ ) { 61 if (pointer_map != nullptr) { << 64 std::map< G4int , G4PhysicsVector* >* pointer_map = itZ->second; 62 for (auto& itA : *pointer_map) { << 65 if ( pointer_map ) { 63 G4PhysicsVector* pointerPhysicsVector << 66 for ( std::map< G4int , G4PhysicsVector* >::iterator itA = pointer_map->begin(); 64 if (pointerPhysicsVector != nullptr) { << 67 itA != pointer_map->end() ; ++itA ) { >> 68 G4PhysicsVector* pointerPhysicsVector = itA->second; >> 69 if ( pointerPhysicsVector ) { 65 delete pointerPhysicsVector; 70 delete pointerPhysicsVector; 66 itA.second = NULL; << 71 itA->second = NULL; 67 } 72 } 68 } 73 } 69 delete pointer_map; 74 delete pointer_map; 70 itZ.second = NULL; << 75 itZ->second = NULL; 71 } 76 } 72 } 77 } 73 mIsotope.clear(); 78 mIsotope.clear(); 74 } 79 } >> 80 75 81 76 G4ParticleHPJENDLHEData::G4ParticleHPJENDLHEDa << 82 77 : G4VCrossSectionDataSet("JENDLHE" + reactio << 83 G4ParticleHPJENDLHEData::G4ParticleHPJENDLHEData( G4String reaction , G4ParticleDefinition* pd ) >> 84 :G4VCrossSectionDataSet( "JENDLHE"+reaction+"CrossSection" ) 78 { 85 { 79 reactionName = reaction; << 86 reactionName = reaction; 80 BuildPhysicsTable(*pd); << 87 BuildPhysicsTable( *pd ); 81 } 88 } 82 89 83 G4ParticleHPJENDLHEData::~G4ParticleHPJENDLHED << 84 90 85 void G4ParticleHPJENDLHEData::BuildPhysicsTabl << 91 86 { << 92 G4ParticleHPJENDLHEData::~G4ParticleHPJENDLHEData() 87 particleName = aP.GetParticleName(); << 93 { 88 << 94 ; 89 const G4String& baseName = G4FindDataDir("G4 << 95 //delete theCrossSections; 90 const G4String& dirName = baseName + "/JENDL << 91 const G4String& aFSType = "/CrossSection/"; << 92 G4ParticleHPNames theNames; << 93 << 94 G4String filename; << 95 << 96 // Create JENDL_HE data << 97 // Create map element or isotope << 98 << 99 std::size_t numberOfElements = G4Element::Ge << 100 << 101 // make a PhysicsVector for each element << 102 << 103 auto theElementTable = G4Element::GetElement << 104 vElement.clear(); << 105 vElement.resize(numberOfElements); << 106 for (std::size_t i = 0; i < numberOfElements << 107 G4Element* theElement = (*theElementTable) << 108 vElement[i] = false; << 109 << 110 // isotope << 111 auto nIso = (G4int)(*theElementTable)[i]-> << 112 auto Z = (G4int)(*theElementTable)[i]->Get << 113 for (G4int i1 = 0; i1 < nIso; ++i1) { << 114 G4int A = theElement->GetIsotope(i1)->Ge << 115 << 116 if (isThisNewIsotope(Z, A)) { << 117 std::stringstream ss; << 118 ss << dirName << aFSType << Z << "_" << A << << 119 filename = ss.str(); << 120 std::fstream file; << 121 file.open(filename, std::fstream::in); << 122 G4int dummy; << 123 file >> dummy; << 124 if (file.good()) { << 125 vElement[i] = true; << 126 << 127 // read the file << 128 G4PhysicsVector* aPhysVec = readAFile(&fil << 129 registAPhysicsVector(Z, A, aPhysVec); << 130 } << 131 file.close(); << 132 } << 133 } << 134 } << 135 } 96 } >> 97 136 98 137 void G4ParticleHPJENDLHEData::DumpPhysicsTable << 138 {} << 139 99 140 G4double G4ParticleHPJENDLHEData::GetCrossSect << 100 void G4ParticleHPJENDLHEData::BuildPhysicsTable( const G4ParticleDefinition& aP ) 141 << 142 { 101 { 143 // Primary energy >20MeV << 102 144 // Thus not taking into account of Doppler b << 103 // if ( &aP != G4Neutron::Neutron() ) 145 // also not taking into account of Target th << 104 // throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!"); 146 << 105 particleName = aP.GetParticleName(); 147 G4double result = 0; << 106 148 << 107 G4String baseName = std::getenv( "G4NEUTRONHPDATA" ); 149 G4double ek = aP->GetKineticEnergy(); << 108 G4String dirName = baseName+"/JENDL_HE/"+particleName+"/"+reactionName ; 150 << 109 G4String aFSType = "/CrossSection/"; 151 auto nIso = (G4int)anE->GetNumberOfIsotopes( << 110 G4ParticleHPNames theNames; 152 auto Z = (G4int)anE->GetZ(); << 111 153 for (G4int i1 = 0; i1 < nIso; ++i1) { << 112 G4String filename; 154 G4int A = anE->GetIsotope(i1)->GetN(); << 113 155 G4double frac = anE->GetRelativeAbundanceV << 114 // Create JENDL_HE data 156 // This case does NOT request "*perCent". << 115 // Create map element or isotope 157 result += frac * getXSfromThisIsotope(Z, A << 116 158 } << 117 size_t numberOfElements = G4Element::GetNumberOfElements(); 159 return result; << 118 //theCrossSections = new G4PhysicsTable( numberOfElements ); >> 119 >> 120 // make a PhysicsVector for each element >> 121 >> 122 static G4ThreadLocal G4ElementTable *theElementTable = 0 ; if (!theElementTable) theElementTable= G4Element::GetElementTable(); >> 123 vElement.clear(); >> 124 vElement.resize( numberOfElements ); >> 125 for ( size_t i = 0; i < numberOfElements; ++i ) >> 126 { >> 127 >> 128 G4Element* theElement = (*theElementTable)[i]; >> 129 vElement[i] = false; >> 130 >> 131 // isotope >> 132 G4int nIso = (*theElementTable)[i]->GetNumberOfIsotopes(); >> 133 G4int Z = static_cast<G4int> ((*theElementTable)[i]->GetZ()); >> 134 if ( nIso!=0 ) >> 135 { >> 136 G4bool found_at_least_one = false; >> 137 for ( G4int i1 = 0; i1 < nIso; i1++ ) >> 138 { >> 139 G4int A = theElement->GetIsotope(i1)->GetN(); >> 140 >> 141 if ( isThisNewIsotope( Z , A ) ) >> 142 { >> 143 >> 144 std::stringstream ss; >> 145 ss << dirName << aFSType << Z << "_" << A << "_" << theNames.GetName( Z-1 ); >> 146 filename = ss.str(); >> 147 std::fstream file; >> 148 file.open ( filename , std::fstream::in ); >> 149 G4int dummy; >> 150 file >> dummy; >> 151 if ( file.good() ) >> 152 { >> 153 >> 154 //G4cout << "Found file for Z=" << Z << ", A=" << A << ", as " << filename << G4endl; >> 155 found_at_least_one = true; >> 156 >> 157 // read the file >> 158 G4PhysicsVector* aPhysVec = readAFile ( &file ); >> 159 >> 160 //Regist >> 161 >> 162 registAPhysicsVector( Z , A , aPhysVec ); >> 163 >> 164 } >> 165 else >> 166 { >> 167 //G4cout << "No file for "<< reactionType << " Z=" << Z << ", A=" << A << G4endl; >> 168 } >> 169 >> 170 file.close(); >> 171 >> 172 } >> 173 else >> 174 { >> 175 found_at_least_one = TRUE; >> 176 } >> 177 } >> 178 >> 179 if ( found_at_least_one ) vElement[i] = true; >> 180 >> 181 } >> 182 else >> 183 { >> 184 G4StableIsotopes theStableOnes; >> 185 G4int first = theStableOnes.GetFirstIsotope( Z ); >> 186 G4bool found_at_least_one = FALSE; >> 187 for ( G4int i1 = 0; i1 < theStableOnes.GetNumberOfIsotopes( static_cast<G4int>(theElement->GetZ() ) ); i1++) >> 188 { >> 189 G4int A = theStableOnes.GetIsotopeNucleonCount( first+i1 ); >> 190 >> 191 if ( isThisNewIsotope( Z , A ) ) >> 192 { >> 193 >> 194 std::stringstream ss; >> 195 ss << dirName << aFSType << Z << "_" << A << "_" << theNames.GetName( Z-1 ); >> 196 filename = ss.str(); >> 197 >> 198 std::fstream file; >> 199 file.open ( filename , std::fstream::in ); >> 200 G4int dummy; >> 201 file >> dummy; >> 202 if ( file.good() ) >> 203 { >> 204 //G4cout << "Found file for Z=" << Z << ", A=" << A << ", as " << filename << G4endl; >> 205 found_at_least_one = TRUE; >> 206 //Read the file >> 207 >> 208 G4PhysicsVector* aPhysVec = readAFile ( &file ); >> 209 >> 210 //Regist the PhysicsVector >> 211 registAPhysicsVector( Z , A , aPhysVec ); >> 212 >> 213 } >> 214 else >> 215 { >> 216 //G4cout << "No file for "<< reactionType << " Z=" << Z << ", A=" << A << G4endl; >> 217 } >> 218 >> 219 file.close(); >> 220 } >> 221 else >> 222 { >> 223 found_at_least_one = TRUE; >> 224 } >> 225 } >> 226 >> 227 if ( found_at_least_one ) vElement[i] = true; >> 228 >> 229 } >> 230 >> 231 } >> 232 160 } 233 } 161 234 162 G4PhysicsVector* G4ParticleHPJENDLHEData::read << 235 >> 236 >> 237 void G4ParticleHPJENDLHEData::DumpPhysicsTable(const G4ParticleDefinition& aP) 163 { 238 { 164 G4int dummy; << 239 if(&aP!=G4Neutron::Neutron()) 165 G4int len; << 240 throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!"); 166 *file >> dummy; << 241 // G4cout << "G4ParticleHPJENDLHEData::DumpPhysicsTable still to be implemented"<<G4endl; 167 *file >> len; << 242 } 168 243 169 std::vector<G4double> v_e; << 170 std::vector<G4double> v_xs; << 171 244 172 for (G4int i = 0; i < len; ++i) { << 173 G4double e; << 174 G4double xs; << 175 245 176 *file >> e; << 246 G4double G4ParticleHPJENDLHEData:: 177 *file >> xs; << 247 GetCrossSection(const G4DynamicParticle* aP, const G4Element*anE, G4double ) 178 // data are written in eV and barn. << 248 // aTemp 179 v_e.push_back(e * eV); << 249 { 180 v_xs.push_back(xs * barn); << 181 } << 182 250 183 auto aPhysVec = new G4PhysicsFreeVector(stat << 251 // Primary energy >20MeV >> 252 // Thus >> 253 // Not take account of Doppler broadening >> 254 // also >> 255 // Not take account of Target thermal motions >> 256 >> 257 G4double result = 0; >> 258 >> 259 G4double ek = aP->GetKineticEnergy(); >> 260 >> 261 G4int nIso = anE->GetNumberOfIsotopes(); >> 262 G4int Z = static_cast<G4int> ( anE->GetZ() ); >> 263 if ( nIso!=0 ) >> 264 { >> 265 for ( G4int i1 = 0; i1 < nIso; i1++ ) >> 266 { 184 267 185 for (G4int i = 0; i < len; ++i) { << 268 G4int A = anE->GetIsotope(i1)->GetN(); 186 aPhysVec->PutValues(static_cast<std::size_ << 269 G4double frac = anE->GetRelativeAbundanceVector()[ i1 ]; // This case do NOT request "*perCent". 187 } << 270 >> 271 result += frac * getXSfromThisIsotope( Z , A , ek ); >> 272 //G4cout << reactionType << " XS in barn " << Z << " " << A << " " << frac << " " << getXSfromThisIsotope( Z , A , ek )/barn << G4endl; >> 273 >> 274 } >> 275 } >> 276 else >> 277 { >> 278 >> 279 G4StableIsotopes theStableOnes; >> 280 G4int first = theStableOnes.GetFirstIsotope( Z ); >> 281 for ( G4int i1 = 0; i1 < theStableOnes.GetNumberOfIsotopes( static_cast<G4int>(anE->GetZ() ) ); i1++) >> 282 { >> 283 >> 284 G4int A = theStableOnes.GetIsotopeNucleonCount( first+i1 ); >> 285 G4double frac = theStableOnes.GetAbundance( first+i1 )*perCent; // This case request "*perCent". >> 286 >> 287 result += frac * getXSfromThisIsotope( Z , A , ek ); >> 288 //G4cout << reactionType << " XS in barn " << Z << " " << A << " " << frac << " " << getXSfromThisIsotope( Z , A , ek )/barn << G4endl; >> 289 >> 290 } >> 291 } >> 292 return result; 188 293 189 return aPhysVec; << 190 } 294 } 191 295 192 G4bool G4ParticleHPJENDLHEData::isThisInMap(G4 << 296 >> 297 >> 298 G4PhysicsVector* G4ParticleHPJENDLHEData::readAFile ( std::fstream* file ) 193 { 299 { 194 if (mIsotope.find(z) == mIsotope.end()) retu << 300 195 if (mIsotope.find(z)->second->find(a) == mIs << 301 G4int dummy; 196 return true; << 302 G4int len; >> 303 *file >> dummy; >> 304 *file >> len; >> 305 >> 306 std::vector< G4double > v_e; >> 307 std::vector< G4double > v_xs; >> 308 >> 309 for ( G4int i = 0 ; i < len ; i++ ) >> 310 { >> 311 G4double e; >> 312 G4double xs; >> 313 >> 314 *file >> e; >> 315 *file >> xs; >> 316 // data are written in eV and barn. >> 317 v_e.push_back( e*eV ); >> 318 v_xs.push_back( xs*barn ); >> 319 } >> 320 >> 321 G4PhysicsFreeVector* aPhysVec = new G4PhysicsFreeVector( static_cast< size_t >( len ) , v_e.front() , v_e.back() ); >> 322 >> 323 for ( G4int i = 0 ; i < len ; i++ ) >> 324 { >> 325 aPhysVec->PutValues( static_cast< size_t >( i ) , v_e[ i ] , v_xs[ i ] ); >> 326 } >> 327 >> 328 return aPhysVec; 197 } 329 } 198 330 199 void G4ParticleHPJENDLHEData::registAPhysicsVe << 331 >> 332 >> 333 G4bool G4ParticleHPJENDLHEData::isThisInMap( G4int z , G4int a ) 200 { 334 { 201 std::pair<G4int, G4PhysicsVector*> aPair = s << 335 if ( mIsotope.find ( z ) == mIsotope.end() ) return false; 202 auto itm = mIsotope.find(Z); << 336 if ( mIsotope.find ( z ) -> second->find ( a ) == mIsotope.find ( z ) -> second->end() ) return false; 203 if (itm != mIsotope.cend()) { << 337 return true; 204 itm->second->insert(aPair); << 205 } << 206 else { << 207 auto aMap = new std::map<G4int, G4PhysicsV << 208 aMap->insert(aPair); << 209 mIsotope.insert(std::pair<G4int, std::map< << 210 } << 211 } 338 } 212 339 213 G4double G4ParticleHPJENDLHEData::getXSfromThi << 340 >> 341 >> 342 void G4ParticleHPJENDLHEData::registAPhysicsVector( G4int Z , G4int A , G4PhysicsVector* aPhysVec ) 214 { 343 { 215 G4double aXSection = 0.0; << 216 344 217 G4PhysicsVector* aPhysVec; << 345 std::pair< G4int , G4PhysicsVector* > aPair = std::pair < G4int , G4PhysicsVector* > ( A , aPhysVec ); 218 if (mIsotope.find(Z)->second->find(A) != mIs << 346 219 aPhysVec = mIsotope.find(Z)->second->find( << 347 std::map < G4int , std::map< G4int , G4PhysicsVector* >* >::iterator itm; 220 aXSection = aPhysVec->Value(ek); << 348 itm = mIsotope.find ( Z ); 221 } << 349 if ( itm != mIsotope.end() ) 222 else { << 350 { 223 // Select closest one in the same Z << 351 itm->second->insert ( aPair ); 224 G4int delta0 = 99; // no mean for 99 << 352 } 225 for (auto it = mIsotope.find(Z)->second->c << 353 else 226 { 354 { 227 G4int delta = std::abs(A - it->first); << 355 std::map< G4int , G4PhysicsVector* >* aMap = new std::map< G4int , G4PhysicsVector* >; 228 if (delta < delta0) delta0 = delta; << 356 aMap->insert ( aPair ); >> 357 mIsotope.insert( std::pair< G4int , std::map< G4int , G4PhysicsVector* >* > ( Z , aMap ) ); 229 } 358 } 230 359 231 // Randomize of selection larger or smalle << 360 } 232 if (G4UniformRand() < 0.5) delta0 *= -1; << 233 G4int A1 = A + delta0; << 234 if (mIsotope.find(Z)->second->find(A1) != << 235 aPhysVec = mIsotope.find(Z)->second->fin << 236 } << 237 else { << 238 A1 = A - delta0; << 239 aPhysVec = mIsotope.find(Z)->second->fin << 240 } << 241 361 242 aXSection = aPhysVec->Value(ek); << 243 // X^(2/3) factor << 244 aXSection *= G4Pow::GetInstance()->A23(1.0 << 245 } << 246 362 247 return aXSection; << 363 >> 364 G4double G4ParticleHPJENDLHEData::getXSfromThisIsotope( G4int Z , G4int A , G4double ek ) >> 365 { >> 366 >> 367 G4double aXSection = 0.0; >> 368 G4bool outOfRange; >> 369 >> 370 G4PhysicsVector* aPhysVec; >> 371 if ( mIsotope.find ( Z )->second->find ( A ) != mIsotope.find ( Z )->second->end() ) >> 372 { >> 373 >> 374 aPhysVec = mIsotope.find ( Z )->second->find ( A )->second; >> 375 aXSection = aPhysVec->GetValue( ek , outOfRange ); >> 376 >> 377 } >> 378 else >> 379 { >> 380 >> 381 //Select closest one in the same Z >> 382 std::map < G4int , G4PhysicsVector* >::iterator it; >> 383 G4int delta0 = 99; // no mean for 99 >> 384 for ( it = mIsotope.find ( Z )->second->begin() ; it != mIsotope.find ( Z )->second->end() ; it++ ) >> 385 { >> 386 G4int delta = std::abs( A - it->first ); >> 387 if ( delta < delta0 ) delta0 = delta; >> 388 } >> 389 >> 390 // Randomize of selection larger or smaller than A >> 391 if ( G4UniformRand() < 0.5 ) delta0 *= -1; >> 392 G4int A1 = A + delta0; >> 393 if ( mIsotope.find ( Z )->second->find ( A1 ) != mIsotope.find ( Z )->second->end() ) >> 394 { >> 395 aPhysVec = mIsotope.find ( Z )->second->find ( A1 )->second; >> 396 } >> 397 else >> 398 { >> 399 A1 = A - delta0; >> 400 aPhysVec = mIsotope.find ( Z )->second->find ( A1 )->second; >> 401 } >> 402 >> 403 aXSection = aPhysVec->GetValue( ek , outOfRange ); >> 404 // X^(2/3) factor >> 405 //aXSection *= std::pow ( 1.0*A/ A1 , 2.0 / 3.0 ); >> 406 aXSection *= G4Pow::GetInstance()->A23( 1.0*A/ A1 ); >> 407 >> 408 } >> 409 >> 410 return aXSection; 248 } 411 } 249 412