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