00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "G4NeutronHPorLEInelasticData.hh"
00035 #include "G4SystemOfUnits.hh"
00036 #include "G4Neutron.hh"
00037 #include "G4ElementTable.hh"
00038 #include "G4NeutronHPData.hh"
00039
00040 #include "G4PhysicsVector.hh"
00041
00042 G4NeutronHPorLEInelasticData::G4NeutronHPorLEInelasticData()
00043 {
00044 SetMinKinEnergy( 0*MeV );
00045 SetMaxKinEnergy( 20*MeV );
00046
00047 ke_cache = 0.0;
00048 xs_cache = 0.0;
00049 element_cache = NULL;
00050 material_cache = NULL;
00051
00052 }
00053
00054 G4NeutronHPorLEInelasticData::~G4NeutronHPorLEInelasticData()
00055 {
00056
00057 }
00058
00059 G4bool G4NeutronHPorLEInelasticData::IsIsoApplicable( const G4DynamicParticle* dp ,
00060 G4int , G4int ,
00061 const G4Element* element ,
00062 const G4Material* )
00063 {
00064 G4double eKin = dp->GetKineticEnergy();
00065 if ( eKin > GetMaxKinEnergy()
00066 || eKin < GetMinKinEnergy()
00067 || dp->GetDefinition() != G4Neutron::Neutron() ) return false;
00068 if ( unavailable_elements->find( element->GetName() ) != unavailable_elements->end() ) return false;
00069
00070 return true;
00071 }
00072
00073 G4double G4NeutronHPorLEInelasticData::GetIsoCrossSection( const G4DynamicParticle* dp ,
00074 G4int , G4int ,
00075 const G4Isotope* ,
00076 const G4Element* element ,
00077 const G4Material* material )
00078 {
00079 if ( dp->GetKineticEnergy() == ke_cache && element == element_cache && material == material_cache ) return xs_cache;
00080
00081 ke_cache = dp->GetKineticEnergy();
00082 element_cache = element;
00083 material_cache = material;
00084 G4double xs = GetCrossSection( dp , element , material->GetTemperature() );
00085 xs_cache = xs;
00086 return xs;
00087
00088 }
00089
00090 G4NeutronHPorLEInelasticData::G4NeutronHPorLEInelasticData( G4NeutronHPChannelList* pChannel , std::set< G4String >* pSet )
00091 :G4VCrossSectionDataSet("NeutronHPorLEInelasticXS")
00092 {
00093 theInelasticChannel = pChannel;
00094 unavailable_elements = pSet;
00095
00096
00097 SetMinKinEnergy( 0*MeV );
00098 SetMaxKinEnergy( 20*MeV );
00099
00100 ke_cache = 0.0;
00101 xs_cache = 0.0;
00102 element_cache = NULL;
00103 material_cache = NULL;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #include "G4NeutronHPInelasticData.hh"
00118 #include "G4LPhysicsFreeVector.hh"
00119
00120
00121 void G4NeutronHPorLEInelasticData::BuildPhysicsTable( const G4ParticleDefinition& aP )
00122 {
00123 if( &aP!=G4Neutron::Neutron() )
00124 throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!");
00125
00126 size_t numberOfElements = G4Element::GetNumberOfElements();
00127 theCrossSections = new G4PhysicsTable( numberOfElements );
00128
00129 static const G4ElementTable *theElementTable = G4Element::GetElementTable();
00130 for ( size_t i=0 ; i < numberOfElements; ++i )
00131 {
00132 G4PhysicsVector* thePhysVec = new G4LPhysicsFreeVector(0, 0, 0);
00133
00134 if ( unavailable_elements->find( (*theElementTable)[i]->GetName() ) == unavailable_elements->end() )
00135 {
00136
00137 G4NeutronHPElementData* theElementData = new G4NeutronHPElementData();
00138 theElementData->Init( (*theElementTable)[i] );
00139
00140 G4NeutronHPVector* theHPVector = theElementData->GetData( (G4NeutronHPInelasticData*)this );
00141
00142 G4int len = theHPVector->GetVectorLength();
00143
00144 if ( len!=0 )
00145 {
00146 G4double emin = theHPVector->GetX(0);
00147 G4double emax = theHPVector->GetX(len-1);
00148
00149 G4LPhysicsFreeVector* aPhysVector= new G4LPhysicsFreeVector ( len , emin , emax );
00150 for ( G4int ii=0; ii<len; ii++ )
00151 {
00152 aPhysVector->PutValues( ii , theHPVector->GetX(ii) , theHPVector->GetY(ii) );
00153 }
00154 delete thePhysVec;
00155 thePhysVec = aPhysVector;
00156 }
00157
00158
00159
00160
00161 }
00162
00163 theCrossSections->push_back(thePhysVec);
00164 }
00165 }
00166
00167
00168
00169 void G4NeutronHPorLEInelasticData::DumpPhysicsTable(const G4ParticleDefinition& aP)
00170 {
00171 if(&aP!=G4Neutron::Neutron())
00172 throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!");
00173
00174 }
00175
00176
00177
00178 #include "G4Nucleus.hh"
00179 #include "G4NucleiProperties.hh"
00180 #include "G4Neutron.hh"
00181 #include "G4Electron.hh"
00182
00183 G4double G4NeutronHPorLEInelasticData::
00184 GetCrossSection(const G4DynamicParticle* aP, const G4Element*anE, G4double aT)
00185 {
00186
00187
00188 G4double result = 0;
00189
00190 G4int index = anE->GetIndex();
00191
00192
00193 G4double eKinetic = aP->GetKineticEnergy();
00194 G4ReactionProduct theNeutron( aP->GetDefinition() );
00195 theNeutron.SetMomentum( aP->GetMomentum() );
00196 theNeutron.SetKineticEnergy( eKinetic );
00197
00198
00199 G4Nucleus aNuc;
00200 G4double eps = 0.0001;
00201 G4double theA = anE->GetN();
00202 G4double theZ = anE->GetZ();
00203 G4double eleMass;
00204 eleMass = ( G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theA+eps), static_cast<G4int>(theZ+eps))
00205 ) / G4Neutron::Neutron()->GetPDGMass();
00206
00207 G4ReactionProduct boosted;
00208 G4double aXsection;
00209
00210
00211 G4int counter = 0;
00212 G4double buffer = 0;
00213 G4int size = G4int(std::max(10., aT/60*kelvin));
00214 G4ThreeVector neutronVelocity = 1./G4Neutron::Neutron()->GetPDGMass()*theNeutron.GetMomentum();
00215 G4double neutronVMag = neutronVelocity.mag();
00216 while(counter == 0 || std::abs(buffer-result/std::max(1,counter)) > 0.03*buffer)
00217 {
00218 if(counter) buffer = result/counter;
00219 while (counter<size)
00220 {
00221 counter ++;
00222 G4ReactionProduct aThermalNuc = aNuc.GetThermalNucleus(eleMass, aT);
00223 boosted.Lorentz(theNeutron, aThermalNuc);
00224 G4double theEkin = boosted.GetKineticEnergy();
00225
00226 aXsection = theInelasticChannel[index].GetXsec( theEkin );
00227
00228 G4ThreeVector targetVelocity = 1./aThermalNuc.GetMass()*aThermalNuc.GetMomentum();
00229 aXsection *= (targetVelocity-neutronVelocity).mag()/neutronVMag;
00230 result += aXsection;
00231 }
00232 size += size;
00233 }
00234 result /= counter;
00235
00236 return result*barn;
00237 }