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 // neutron_hp -- source file 26 // neutron_hp -- source file 27 // J.P. Wellisch, Nov-1996 27 // J.P. Wellisch, Nov-1996 28 // A prototype of the low energy neutron trans 28 // A prototype of the low energy neutron transport model. 29 // 29 // 30 // 070523 add neglecting doppler broadening on 30 // 070523 add neglecting doppler broadening on the fly. T. Koi 31 // 070613 fix memory leaking by T. Koi 31 // 070613 fix memory leaking by T. Koi 32 // 071002 enable cross section dump by T. Koi 32 // 071002 enable cross section dump by T. Koi 33 // 080428 change checking point of "neglecting << 33 // 080428 change checking point of "neglecting doppler broadening" flag 34 // from GetCrossSection to BuildPhysics 34 // from GetCrossSection to BuildPhysicsTable by T. Koi 35 // 081024 G4NucleiPropertiesTable:: to G4Nucle 35 // 081024 G4NucleiPropertiesTable:: to G4NucleiProperties:: 36 // 36 // 37 // P. Arce, June-2014 Conversion neutron_hp to 37 // P. Arce, June-2014 Conversion neutron_hp to particle_hp 38 // 38 // 39 #include "G4ParticleHPElasticData.hh" 39 #include "G4ParticleHPElasticData.hh" 40 << 40 #include "G4ParticleHPManager.hh" 41 #include "G4Electron.hh" << 41 #include "G4PhysicalConstants.hh" 42 #include "G4ElementTable.hh" << 42 #include "G4SystemOfUnits.hh" 43 #include "G4HadronicParameters.hh" << 44 #include "G4Neutron.hh" 43 #include "G4Neutron.hh" 45 #include "G4NucleiProperties.hh" << 44 #include "G4ElementTable.hh" 46 #include "G4Nucleus.hh" << 47 #include "G4ParticleHPData.hh" 45 #include "G4ParticleHPData.hh" 48 #include "G4ParticleHPManager.hh" 46 #include "G4ParticleHPManager.hh" 49 #include "G4PhysicalConstants.hh" << 47 #include "G4HadronicParameters.hh" 50 #include "G4Pow.hh" 48 #include "G4Pow.hh" 51 #include "G4SystemOfUnits.hh" << 52 49 53 G4ParticleHPElasticData::G4ParticleHPElasticDa << 50 G4ParticleHPElasticData::G4ParticleHPElasticData() >> 51 :G4VCrossSectionDataSet("NeutronHPElasticXS") 54 { 52 { 55 SetMinKinEnergy(0 * MeV); << 53 SetMinKinEnergy( 0*MeV ); 56 SetMaxKinEnergy(20 * MeV); << 54 SetMaxKinEnergy( 20*MeV ); 57 55 58 theCrossSections = nullptr; << 56 theCrossSections = 0; 59 instanceOfWorker = false; << 57 onFlightDB = true; 60 if (G4Threading::IsWorkerThread()) { << 58 instanceOfWorker = false; 61 instanceOfWorker = true; << 59 if ( G4Threading::IsWorkerThread() ) { 62 } << 60 instanceOfWorker = true; 63 element_cache = nullptr; << 61 } 64 material_cache = nullptr; << 62 element_cache = NULL; 65 ke_cache = 0.0; << 63 material_cache = NULL; 66 xs_cache = 0.0; << 64 ke_cache = 0.0; 67 // BuildPhysicsTable( *G4Neutron::Neutron() << 65 xs_cache = 0.0; >> 66 // BuildPhysicsTable( *G4Neutron::Neutron() ); 68 } 67 } 69 << 68 70 G4ParticleHPElasticData::~G4ParticleHPElasticD 69 G4ParticleHPElasticData::~G4ParticleHPElasticData() 71 { 70 { 72 if (theCrossSections != nullptr && !instance << 71 if ( theCrossSections != NULL && instanceOfWorker != true ) { 73 theCrossSections->clearAndDestroy(); << 72 theCrossSections->clearAndDestroy(); 74 delete theCrossSections; << 73 delete theCrossSections; 75 theCrossSections = nullptr; << 74 theCrossSections = NULL; 76 } << 75 } >> 76 } >> 77 >> 78 G4bool G4ParticleHPElasticData::IsIsoApplicable( const G4DynamicParticle* dp , >> 79 G4int /*Z*/ , G4int /*A*/ , >> 80 const G4Element* /*elm*/ , >> 81 const G4Material* /*mat*/ ) >> 82 { >> 83 >> 84 G4double eKin = dp->GetKineticEnergy(); >> 85 if ( eKin > GetMaxKinEnergy() >> 86 || eKin < GetMinKinEnergy() >> 87 || dp->GetDefinition() != G4Neutron::Neutron() ) return false; >> 88 >> 89 return true; >> 90 } >> 91 >> 92 G4double G4ParticleHPElasticData::GetIsoCrossSection( const G4DynamicParticle* dp , >> 93 G4int /*Z*/ , G4int /*A*/ , >> 94 const G4Isotope* /*iso*/ , >> 95 const G4Element* element , >> 96 const G4Material* material ) >> 97 { >> 98 if ( dp->GetKineticEnergy() == ke_cache && element == element_cache && material == material_cache ) return xs_cache; >> 99 >> 100 ke_cache = dp->GetKineticEnergy(); >> 101 element_cache = element; >> 102 material_cache = material; >> 103 G4double xs = GetCrossSection( dp , element , material->GetTemperature() ); >> 104 xs_cache = xs; >> 105 return xs; 77 } 106 } 78 107 79 G4bool G4ParticleHPElasticData::IsIsoApplicabl << 108 /* 80 << 109 G4bool G4ParticleHPElasticData::IsApplicable(const G4DynamicParticle*aP, const G4Element*) 81 << 110 { 82 { << 111 G4bool result = true; 83 G4double eKin = dp->GetKineticEnergy(); << 112 G4double eKin = aP->GetKineticEnergy(); 84 return eKin <= GetMaxKinEnergy() && eKin >= << 113 if(eKin>20*MeV||aP->GetDefinition()!=G4Neutron::Neutron()) result = false; 85 && dp->GetDefinition() == G4Neutron:: << 114 return result; 86 } << 87 << 88 G4double G4ParticleHPElasticData::GetIsoCrossS << 89 << 90 << 91 << 92 { << 93 if (dp->GetKineticEnergy() == ke_cache && el << 94 return xs_cache; << 95 << 96 ke_cache = dp->GetKineticEnergy(); << 97 element_cache = element; << 98 material_cache = material; << 99 G4double xs = GetCrossSection(dp, element, m << 100 xs_cache = xs; << 101 return xs; << 102 } 115 } >> 116 */ 103 117 104 void G4ParticleHPElasticData::BuildPhysicsTabl 118 void G4ParticleHPElasticData::BuildPhysicsTable(const G4ParticleDefinition& aP) 105 { 119 { 106 if (&aP != G4Neutron::Neutron()) << 107 throw G4HadronicException(__FILE__, __LINE << 108 "Attempt to use << 109 << 110 if (G4Threading::IsWorkerThread()) { << 111 theCrossSections = G4ParticleHPManager::Ge << 112 return; << 113 } << 114 120 115 std::size_t numberOfElements = G4Element::Ge << 121 if(&aP!=G4Neutron::Neutron()) 116 // TKDB << 122 throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!"); 117 // if ( theCrossSections == 0 ) theCrossSect << 123 118 if (theCrossSections == nullptr) << 124 //080428 119 theCrossSections = new G4PhysicsTable(numb << 125 if ( G4ParticleHPManager::GetInstance()->GetNeglectDoppler() ) 120 else << 126 { 121 theCrossSections->clearAndDestroy(); << 127 onFlightDB = false; >> 128 #ifdef G4VERBOSE >> 129 if ( G4HadronicParameters::Instance()->GetVerboseLevel() > 0 ) { >> 130 G4cout << "Find a flag of \"G4NEUTRONHP_NEGLECT_DOPPLER\"." << G4endl; >> 131 G4cout << "On the fly Doppler broadening will be neglect in the cross section calculation of elastic scattering of neutrons (<20MeV)." << G4endl; >> 132 } >> 133 #endif >> 134 } >> 135 >> 136 if ( G4Threading::IsWorkerThread() ) { >> 137 theCrossSections = G4ParticleHPManager::GetInstance()->GetElasticCrossSections(); >> 138 return; >> 139 } >> 140 >> 141 size_t numberOfElements = G4Element::GetNumberOfElements(); >> 142 // TKDB >> 143 //if ( theCrossSections == 0 ) theCrossSections = new G4PhysicsTable( numberOfElements ); >> 144 if ( theCrossSections == NULL ) >> 145 theCrossSections = new G4PhysicsTable( numberOfElements ); >> 146 else >> 147 theCrossSections->clearAndDestroy(); 122 148 123 // make a PhysicsVector for each element 149 // make a PhysicsVector for each element 124 150 125 auto theElementTable = G4Element::GetElement << 151 static G4ThreadLocal G4ElementTable *theElementTable = 0 ; if (!theElementTable) theElementTable= G4Element::GetElementTable(); 126 for (std::size_t i = 0; i < numberOfElements << 152 for( size_t i=0; i<numberOfElements; ++i ) 127 G4PhysicsVector* physVec = G4ParticleHPDat << 153 { 128 ->MakePhysics << 154 G4PhysicsVector* physVec = G4ParticleHPData:: >> 155 Instance(G4Neutron::Neutron())->MakePhysicsVector((*theElementTable)[i], this); 129 theCrossSections->push_back(physVec); 156 theCrossSections->push_back(physVec); 130 } 157 } 131 158 132 G4ParticleHPManager::GetInstance()->Register << 159 G4ParticleHPManager::GetInstance()->RegisterElasticCrossSections(theCrossSections); 133 } 160 } 134 161 135 void G4ParticleHPElasticData::DumpPhysicsTable << 162 void G4ParticleHPElasticData::DumpPhysicsTable(const G4ParticleDefinition& aP) 136 { 163 { 137 #ifdef G4VERBOSE << 164 if(&aP!=G4Neutron::Neutron()) 138 if (G4HadronicParameters::Instance()->GetVer << 165 throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!"); >> 166 >> 167 #ifdef G4VERBOSE >> 168 if ( G4HadronicParameters::Instance()->GetVerboseLevel() == 0 ) return; >> 169 >> 170 // >> 171 // Dump element based cross section >> 172 // range 10e-5 eV to 20 MeV >> 173 // 10 point per decade >> 174 // in barn >> 175 // >> 176 >> 177 G4cout << G4endl; >> 178 G4cout << G4endl; >> 179 G4cout << "Elastic Cross Section of Neutron HP"<< G4endl; >> 180 G4cout << "(Pointwise cross-section at 0 Kelvin.)" << G4endl; >> 181 G4cout << G4endl; >> 182 G4cout << "Name of Element" << G4endl; >> 183 G4cout << "Energy[eV] XS[barn]" << G4endl; >> 184 G4cout << G4endl; >> 185 >> 186 size_t numberOfElements = G4Element::GetNumberOfElements(); >> 187 static G4ThreadLocal G4ElementTable *theElementTable = 0 ; if (!theElementTable) theElementTable= G4Element::GetElementTable(); >> 188 >> 189 for ( size_t i = 0 ; i < numberOfElements ; ++i ) >> 190 { >> 191 >> 192 G4cout << (*theElementTable)[i]->GetName() << G4endl; >> 193 >> 194 G4int ie = 0; >> 195 >> 196 for ( ie = 0 ; ie < 130 ; ie++ ) >> 197 { >> 198 G4double eKinetic = 1.0e-5 * G4Pow::GetInstance()->powA ( 10.0 , ie/10.0 ) *eV; >> 199 G4bool outOfRange = false; >> 200 >> 201 if ( eKinetic < 20*MeV ) >> 202 { >> 203 G4cout << eKinetic/eV << " " << (*((*theCrossSections)(i))).GetValue(eKinetic, outOfRange)/barn << G4endl; >> 204 } 139 205 140 // << 141 // Dump element based cross section << 142 // range 10e-5 eV to 20 MeV << 143 // 10 point per decade << 144 // in barn << 145 // << 146 << 147 G4cout << G4endl; << 148 G4cout << G4endl; << 149 G4cout << "Elastic Cross Section of Neutron << 150 G4cout << "(Pointwise cross-section at 0 Kel << 151 G4cout << G4endl; << 152 G4cout << "Name of Element" << G4endl; << 153 G4cout << "Energy[eV] XS[barn]" << G4endl; << 154 G4cout << G4endl; << 155 << 156 std::size_t numberOfElements = G4Element::Ge << 157 auto theElementTable = G4Element::GetElement << 158 << 159 for (std::size_t i = 0; i < numberOfElements << 160 G4cout << (*theElementTable)[i]->GetName() << 161 G4int ie = 0; << 162 << 163 for (ie = 0; ie < 130; ++ie) { << 164 G4double eKinetic = 1.0e-5 * G4Pow::GetI << 165 G4bool outOfRange = false; << 166 << 167 if (eKinetic < 20 * MeV) { << 168 G4cout << eKinetic / eV << " " << 169 << (*((*theCrossSections)(i))). << 170 } 206 } 171 } << 207 172 G4cout << G4endl; << 208 G4cout << G4endl; 173 } << 209 } 174 #endif << 210 >> 211 //G4cout << "G4ParticleHPElasticData::DumpPhysicsTable still to be implemented"<<G4endl; >> 212 #endif 175 } 213 } 176 214 177 G4double G4ParticleHPElasticData::GetCrossSect << 215 #include "G4Nucleus.hh" 178 << 216 #include "G4NucleiProperties.hh" >> 217 #include "G4Neutron.hh" >> 218 #include "G4Electron.hh" >> 219 >> 220 G4double G4ParticleHPElasticData:: >> 221 GetCrossSection(const G4DynamicParticle* aP, const G4Element*anE, G4double aT) 179 { 222 { 180 G4double result = 0; 223 G4double result = 0; 181 G4bool outOfRange; 224 G4bool outOfRange; 182 auto index = (G4int)anE->GetIndex(); << 225 G4int index = anE->GetIndex(); 183 226 184 // prepare neutron 227 // prepare neutron 185 G4double eKinetic = aP->GetKineticEnergy(); 228 G4double eKinetic = aP->GetKineticEnergy(); 186 229 187 if (G4ParticleHPManager::GetInstance()->GetN << 230 if ( !onFlightDB ) 188 // NEGLECT_DOPPLER_B. << 231 { 189 G4double factor = 1.0; << 232 //NEGLECT_DOPPLER_B. 190 if (eKinetic < aT * k_Boltzmann) { << 233 G4double factor = 1.0; 191 // below 0.1 eV neutrons << 234 if ( eKinetic < aT * k_Boltzmann ) 192 // Have to do some, but now just igonre. << 235 { 193 // Will take care after performance chec << 236 // below 0.1 eV neutrons 194 // factor = factor * targetV; << 237 // Have to do some, but now just igonre. 195 } << 238 // Will take care after performance check. 196 return ((*((*theCrossSections)(index))).Ge << 239 // factor = factor * targetV; >> 240 } >> 241 return ( (*((*theCrossSections)(index))).GetValue(eKinetic, outOfRange) )* factor; 197 } 242 } 198 243 199 G4ReactionProduct theNeutron(aP->GetDefiniti << 244 G4ReactionProduct theNeutron( aP->GetDefinition() ); 200 theNeutron.SetMomentum(aP->GetMomentum()); << 245 theNeutron.SetMomentum( aP->GetMomentum() ); 201 theNeutron.SetKineticEnergy(eKinetic); << 246 theNeutron.SetKineticEnergy( eKinetic ); 202 247 203 // prepare thermal nucleus 248 // prepare thermal nucleus 204 G4Nucleus aNuc; 249 G4Nucleus aNuc; 205 G4double eps = 0.0001; 250 G4double eps = 0.0001; 206 G4double theA = anE->GetN(); 251 G4double theA = anE->GetN(); 207 G4double theZ = anE->GetZ(); 252 G4double theZ = anE->GetZ(); 208 G4double eleMass; << 253 G4double eleMass; 209 254 210 eleMass = (G4NucleiProperties::GetNuclearMas << 211 / G4Neutron::Neutron()->GetPDGMass << 212 255 >> 256 eleMass = ( G4NucleiProperties::GetNuclearMass( static_cast<G4int>(theA+eps) , static_cast<G4int>(theZ+eps) ) >> 257 ) / G4Neutron::Neutron()->GetPDGMass(); >> 258 213 G4ReactionProduct boosted; 259 G4ReactionProduct boosted; 214 G4double aXsection; 260 G4double aXsection; 215 << 261 216 // MC integration loop 262 // MC integration loop 217 G4int counter = 0; 263 G4int counter = 0; 218 G4double buffer = 0; 264 G4double buffer = 0; 219 G4int size = G4int(std::max(10., aT / 60 * k << 265 G4int size = G4int(std::max(10., aT/60*kelvin)); 220 G4ThreeVector neutronVelocity = << 266 G4ThreeVector neutronVelocity = 1./G4Neutron::Neutron()->GetPDGMass()*theNeutron.GetMomentum(); 221 1. / G4Neutron::Neutron()->GetPDGMass() * << 222 G4double neutronVMag = neutronVelocity.mag() 267 G4double neutronVMag = neutronVelocity.mag(); 223 268 224 while (counter == 0 << 269 while(counter == 0 || std::abs(buffer-result/std::max(1,counter)) > 0.03*buffer) // Loop checking, 11.05.2015, T. Koi 225 || std::abs(buffer - result / std::ma << 226 > 0.03 * buffer) // Loop checki << 227 { 270 { 228 if (counter != 0) buffer = result / counte << 271 if(counter) buffer = result/counter; 229 while (counter < size) // Loop checking, << 272 while (counter<size) // Loop checking, 11.05.2015, T. Koi 230 { 273 { 231 counter++; << 274 counter ++; 232 G4ReactionProduct aThermalNuc = aNuc.Get 275 G4ReactionProduct aThermalNuc = aNuc.GetThermalNucleus(eleMass, aT); 233 boosted.Lorentz(theNeutron, aThermalNuc) 276 boosted.Lorentz(theNeutron, aThermalNuc); 234 G4double theEkin = boosted.GetKineticEne 277 G4double theEkin = boosted.GetKineticEnergy(); 235 aXsection = (*((*theCrossSections)(index 278 aXsection = (*((*theCrossSections)(index))).GetValue(theEkin, outOfRange); 236 // velocity correction. 279 // velocity correction. 237 G4ThreeVector targetVelocity = 1. / aThe << 280 G4ThreeVector targetVelocity = 1./aThermalNuc.GetMass()*aThermalNuc.GetMomentum(); 238 aXsection *= (targetVelocity - neutronVe << 281 aXsection *= (targetVelocity-neutronVelocity).mag()/neutronVMag; 239 result += aXsection; 282 result += aXsection; 240 } 283 } 241 size += size; 284 size += size; 242 } 285 } 243 result /= counter; 286 result /= counter; 244 /* << 287 /* 245 // Checking impact of G4NEUTRONHP_NEGLECT << 288 // Checking impact of G4NEUTRONHP_NEGLECT_DOPPLER 246 G4cout << " result " << result << " " << 289 G4cout << " result " << result << " " 247 << (*((*theCrossSections)(index))). << 290 << (*((*theCrossSections)(index))).GetValue(eKinetic, outOfRange) << " " 248 << (*((*theCrossSections)(index))). << 291 << (*((*theCrossSections)(index))).GetValue(eKinetic, outOfRange) /result << G4endl; 249 */ << 292 */ 250 return result; 293 return result; 251 } 294 } 252 295 253 G4int G4ParticleHPElasticData::GetVerboseLevel << 296 G4int G4ParticleHPElasticData:: >> 297 GetVerboseLevel() const 254 { 298 { 255 return G4ParticleHPManager::GetInstance()->G << 299 return G4ParticleHPManager::GetInstance()->GetVerboseLevel(); 256 } 300 } 257 301 258 void G4ParticleHPElasticData::SetVerboseLevel( << 302 void G4ParticleHPElasticData:: >> 303 SetVerboseLevel( G4int newValue ) 259 { 304 { 260 G4ParticleHPManager::GetInstance()->SetVerbo << 305 G4ParticleHPManager::GetInstance()->SetVerboseLevel(newValue); 261 } 306 } 262 << 263 void G4ParticleHPElasticData::CrossSectionDesc 307 void G4ParticleHPElasticData::CrossSectionDescription(std::ostream& outFile) const 264 { 308 { 265 outFile << "High Precision cross data based << 309 outFile << "High Precision cross data based on Evaluated Nuclear Data Files (ENDF) for elastic reaction of neutrons below 20MeV\n" ; 266 "reaction of neutrons below 20MeV << 267 } 310 } 268 311