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 "G4NeutronHPorLFissionData.hh"
00035 #include "G4SystemOfUnits.hh"
00036 #include "G4Neutron.hh"
00037 #include "G4ElementTable.hh"
00038 #include "G4NeutronHPData.hh"
00039
00040 #include "G4PhysicsVector.hh"
00041
00042
00043 G4NeutronHPorLFissionData::G4NeutronHPorLFissionData()
00044 {
00045 SetMinKinEnergy( 0*MeV );
00046 SetMaxKinEnergy( 20*MeV );
00047
00048 ke_cache = 0.0;
00049 xs_cache = 0.0;
00050 element_cache = NULL;
00051 material_cache = NULL;
00052
00053 }
00054
00055 G4NeutronHPorLFissionData::~G4NeutronHPorLFissionData()
00056 {
00057
00058 }
00059
00060 G4bool G4NeutronHPorLFissionData::IsIsoApplicable( const G4DynamicParticle* dp ,
00061 G4int , G4int ,
00062 const G4Element* element ,
00063 const G4Material* )
00064 {
00065 G4double eKin = dp->GetKineticEnergy();
00066 if ( eKin > GetMaxKinEnergy()
00067 || eKin < GetMinKinEnergy()
00068 || dp->GetDefinition() != G4Neutron::Neutron() ) return false;
00069 if ( unavailable_elements->find( element->GetName() ) != unavailable_elements->end() ) return false;
00070
00071 return true;
00072 }
00073
00074 G4double G4NeutronHPorLFissionData::GetIsoCrossSection( const G4DynamicParticle* dp ,
00075 G4int , G4int ,
00076 const G4Isotope* ,
00077 const G4Element* element ,
00078 const G4Material* material )
00079 {
00080 if ( dp->GetKineticEnergy() == ke_cache && element == element_cache && material == material_cache ) return xs_cache;
00081
00082 ke_cache = dp->GetKineticEnergy();
00083 element_cache = element;
00084 material_cache = material;
00085 G4double xs = GetCrossSection( dp , element , material->GetTemperature() );
00086 xs_cache = xs;
00087 return xs;
00088
00089 }
00090
00091 G4NeutronHPorLFissionData::G4NeutronHPorLFissionData( G4NeutronHPChannel* pChannel , std::set< G4String >* pSet )
00092 :G4VCrossSectionDataSet("NeutronHPorLFissionXS")
00093 {
00094 theFissionChannel = pChannel;
00095 unavailable_elements = pSet;
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
00118
00119 void G4NeutronHPorLFissionData::BuildPhysicsTable( const G4ParticleDefinition& aP )
00120 {
00121 if( &aP!=G4Neutron::Neutron() )
00122 throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!");
00123 }
00124
00125
00126
00127 void G4NeutronHPorLFissionData::DumpPhysicsTable(const G4ParticleDefinition& aP)
00128 {
00129 if(&aP!=G4Neutron::Neutron())
00130 throw G4HadronicException(__FILE__, __LINE__, "Attempt to use NeutronHP data for particles other than neutrons!!!");
00131
00132 }
00133
00134
00135
00136 #include "G4Nucleus.hh"
00137 #include "G4NucleiProperties.hh"
00138 #include "G4Neutron.hh"
00139 #include "G4Electron.hh"
00140
00141 G4double G4NeutronHPorLFissionData::
00142 GetCrossSection(const G4DynamicParticle* aP, const G4Element*anE, G4double aT)
00143 {
00144 G4double result = 0;
00145 if ( anE->GetZ() < 90 ) return result;
00146
00147
00148 G4int index = anE->GetIndex();
00149
00150
00151 G4double eKinetic = aP->GetKineticEnergy();
00152 G4ReactionProduct theNeutron( aP->GetDefinition() );
00153 theNeutron.SetMomentum( aP->GetMomentum() );
00154 theNeutron.SetKineticEnergy( eKinetic );
00155
00156
00157 G4Nucleus aNuc;
00158 G4double eps = 0.0001;
00159 G4double theA = anE->GetN();
00160 G4double theZ = anE->GetZ();
00161 G4double eleMass;
00162 eleMass = ( G4NucleiProperties::GetNuclearMass(static_cast<G4int>(theA+eps), static_cast<G4int>(theZ+eps))
00163 ) / G4Neutron::Neutron()->GetPDGMass();
00164
00165 G4ReactionProduct boosted;
00166 G4double aXsection;
00167
00168
00169 G4int counter = 0;
00170 G4double buffer = 0;
00171 G4int size = G4int(std::max(10., aT/60*kelvin));
00172 G4ThreeVector neutronVelocity = 1./G4Neutron::Neutron()->GetPDGMass()*theNeutron.GetMomentum();
00173 G4double neutronVMag = neutronVelocity.mag();
00174 while(counter == 0 || std::abs(buffer-result/std::max(1,counter)) > 0.03*buffer)
00175 {
00176 if(counter) buffer = result/counter;
00177 while (counter<size)
00178 {
00179 counter ++;
00180 G4ReactionProduct aThermalNuc = aNuc.GetThermalNucleus(eleMass, aT);
00181 boosted.Lorentz(theNeutron, aThermalNuc);
00182 G4double theEkin = boosted.GetKineticEnergy();
00183
00184 aXsection = theFissionChannel[index].GetXsec( theEkin );
00185
00186 G4ThreeVector targetVelocity = 1./aThermalNuc.GetMass()*aThermalNuc.GetMomentum();
00187 aXsection *= (targetVelocity-neutronVelocity).mag()/neutronVMag;
00188 result += aXsection;
00189 }
00190 size += size;
00191 }
00192 result /= counter;
00193 return result;
00194 }