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