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