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 "G4NeutronHPChannel.hh"
00035 #include "globals.hh"
00036 #include "G4SystemOfUnits.hh"
00037 #include "G4NeutronHPFinalState.hh"
00038 #include "G4HadTmpUtil.hh"
00039
00040 #include "G4NeutronHPManager.hh"
00041 #include "G4NeutronHPReactionWhiteBoard.hh"
00042
00043 G4double G4NeutronHPChannel::GetXsec(G4double energy)
00044 {
00045 return std::max(0., theChannelData->GetXsec(energy));
00046 }
00047
00048 G4double G4NeutronHPChannel::GetWeightedXsec(G4double energy, G4int isoNumber)
00049 {
00050 return theIsotopeWiseData[isoNumber].GetXsec(energy);
00051 }
00052
00053 G4double G4NeutronHPChannel::GetFSCrossSection(G4double energy, G4int isoNumber)
00054 {
00055 return theFinalStates[isoNumber]->GetXsec(energy);
00056 }
00057
00058 void G4NeutronHPChannel::
00059 Init(G4Element * anElement, const G4String dirName, const G4String aFSType)
00060 {
00061 theFSType = aFSType;
00062 Init(anElement, dirName);
00063 }
00064
00065 void G4NeutronHPChannel::Init(G4Element * anElement, const G4String dirName)
00066 {
00067 theDir = dirName;
00068 theElement = anElement;
00069 }
00070
00071 G4bool G4NeutronHPChannel::Register(G4NeutronHPFinalState *theFS)
00072 {
00073 registerCount++;
00074 G4int Z = G4lrint(theElement->GetZ());
00075
00076 Z = Z-registerCount;
00077 if ( registerCount > 5 ) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material");
00078 if ( Z < 1 ) return false;
00079
00080
00081
00082
00083
00084
00085
00086
00087 if ( Z <=theElement->GetZ()-5 ) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material");
00088 G4int count = 0;
00089 if(registerCount==0) count = theElement->GetNumberOfIsotopes();
00090 if(count == 0||registerCount!=0) count +=
00091 theStableOnes.GetNumberOfIsotopes(Z);
00092 niso = count;
00093 delete [] theIsotopeWiseData;
00094 theIsotopeWiseData = new G4NeutronHPIsoData [niso];
00095 delete [] active;
00096 active = new G4bool[niso];
00097
00098 delete [] theFinalStates;
00099 theFinalStates = new G4NeutronHPFinalState * [niso];
00100 delete theChannelData;
00101 theChannelData = new G4NeutronHPVector;
00102 for(G4int i=0; i<niso; i++)
00103 {
00104 theFinalStates[i] = theFS->New();
00105 }
00106 count = 0;
00107 G4int nIsos = niso;
00108 if(theElement->GetNumberOfIsotopes()!=0&®isterCount==0)
00109 {
00110 for (G4int i1=0; i1<nIsos; i1++)
00111 {
00112
00113 G4int A = theElement->GetIsotope(i1)->GetN();
00114 G4int M = theElement->GetIsotope(i1)->Getm();
00115 G4double frac = theElement->GetRelativeAbundanceVector()[i1]/perCent;
00116
00117
00118 theFinalStates[i1]->SetA_Z(A, Z, M);
00119 UpdateData(A, Z, M, count++, frac);
00120 }
00121 } else {
00122
00123
00124
00125
00126 G4int first = theStableOnes.GetFirstIsotope(Z);
00127 for(G4int i1=0;
00128 i1<theStableOnes.GetNumberOfIsotopes(Z);
00129 i1++)
00130 {
00131 G4int A = theStableOnes.GetIsotopeNucleonCount(first+i1);
00132 G4double frac = theStableOnes.GetAbundance(first+i1);
00133 theFinalStates[i1]->SetA_Z(A, Z);
00134 UpdateData(A, Z, count++, frac);
00135 }
00136 }
00137 G4bool result = HasDataInAnyFinalState();
00138 return result;
00139 }
00140
00141
00142 void G4NeutronHPChannel::UpdateData(G4int A, G4int Z, G4int M, G4int index, G4double abundance)
00143 {
00144
00145 theFinalStates[index]->Init(A, Z, M, theDir, theFSType);
00146 if(!theFinalStates[index]->HasAnyData()) return;
00147
00148
00149 theBuffer = 0;
00150 if(theFinalStates[index]->HasXsec())
00151 {
00152 theBuffer = theFinalStates[index]->GetXsec();
00153 theBuffer->Times(abundance/100.);
00154 theIsotopeWiseData[index].FillChannelData(theBuffer);
00155 }
00156 else
00157 {
00158 G4String tString = "/CrossSection";
00159
00160 active[index] = theIsotopeWiseData[index].Init(A, Z, M, abundance, theDir, tString);
00161 if(active[index]) theBuffer = theIsotopeWiseData[index].MakeChannelData();
00162 }
00163 if(theBuffer != 0) Harmonise(theChannelData, theBuffer);
00164 }
00165
00166 void G4NeutronHPChannel::Harmonise(G4NeutronHPVector *& theStore, G4NeutronHPVector * theNew)
00167 {
00168 G4int s_tmp = 0, n=0, m_tmp=0;
00169 G4NeutronHPVector * theMerge = new G4NeutronHPVector;
00170 G4NeutronHPVector * anActive = theStore;
00171 G4NeutronHPVector * aPassive = theNew;
00172 G4NeutronHPVector * tmp;
00173 G4int a = s_tmp, p = n, t;
00174 while (a<anActive->GetVectorLength()&&p<aPassive->GetVectorLength())
00175 {
00176 if(anActive->GetEnergy(a) <= aPassive->GetEnergy(p))
00177 {
00178 G4double xa = anActive->GetEnergy(a);
00179 theMerge->SetData(m_tmp, xa, anActive->GetXsec(a)+std::max(0., aPassive->GetXsec(xa)) );
00180 m_tmp++;
00181 a++;
00182 G4double xp = aPassive->GetEnergy(p);
00183 if( std::abs(std::abs(xp-xa)/xa)<0.001 )
00184 {
00185 p++;
00186 }
00187 } else {
00188 tmp = anActive; t=a;
00189 anActive = aPassive; a=p;
00190 aPassive = tmp; p=t;
00191 }
00192 }
00193 while (a!=anActive->GetVectorLength())
00194 {
00195 theMerge->SetData(m_tmp++, anActive->GetEnergy(a), anActive->GetXsec(a));
00196 a++;
00197 }
00198 while (p!=aPassive->GetVectorLength())
00199 {
00200 if(std::abs(theMerge->GetEnergy(std::max(0,m_tmp-1))-aPassive->GetEnergy(p))/aPassive->GetEnergy(p)>0.001)
00201 theMerge->SetData(m_tmp++, aPassive->GetEnergy(p), aPassive->GetXsec(p));
00202 p++;
00203 }
00204 delete theStore;
00205 theStore = theMerge;
00206 }
00207
00208 #include "G4NeutronHPThermalBoost.hh"
00209
00210 G4HadFinalState * G4NeutronHPChannel::
00211 ApplyYourself(const G4HadProjectile & theTrack, G4int anIsotope)
00212 {
00213
00214 if ( anIsotope != -1 )
00215 {
00216
00217
00218
00219 G4NeutronHPManager::GetInstance()->GetReactionWhiteBoard()->SetTargA( (G4int)this->GetN(anIsotope) );
00220 G4NeutronHPManager::GetInstance()->GetReactionWhiteBoard()->SetTargZ( (G4int)this->GetZ(anIsotope) );
00221 return theFinalStates[anIsotope]->ApplyYourself(theTrack);
00222 }
00223 G4double sum=0;
00224 G4int it=0;
00225 G4double * xsec = new G4double[niso];
00226 G4NeutronHPThermalBoost aThermalE;
00227 for (G4int i=0; i<niso; i++)
00228 {
00229 if(theFinalStates[i]->HasAnyData())
00230 {
00231 xsec[i] = theIsotopeWiseData[i].GetXsec(aThermalE.GetThermalEnergy(theTrack,
00232 theFinalStates[i]->GetN(),
00233 theFinalStates[i]->GetZ(),
00234 theTrack.GetMaterial()->GetTemperature()));
00235 sum += xsec[i];
00236 }
00237 else
00238 {
00239 xsec[i]=0;
00240 }
00241 }
00242 if(sum == 0)
00243 {
00244
00245
00246 it = static_cast<G4int>(niso*G4UniformRand());
00247 }
00248 else
00249 {
00250
00251
00252 G4double random = G4UniformRand();
00253 G4double running=0;
00254
00255
00256 for (G4int ix=0; ix<niso; ix++)
00257 {
00258 running += xsec[ix];
00259
00260 if( sum == 0 || random <= running/sum )
00261 {
00262 it = ix;
00263 break;
00264 }
00265 }
00266 if(it==niso) it--;
00267 }
00268 delete [] xsec;
00269 G4HadFinalState * theFinalState=0;
00270 while(theFinalState==0)
00271 {
00272
00273 theFinalState = theFinalStates[it]->ApplyYourself(theTrack);
00274 }
00275
00276
00277
00278 G4NeutronHPManager::GetInstance()->GetReactionWhiteBoard()->SetTargA( (G4int)this->GetN(it) );
00279 G4NeutronHPManager::GetInstance()->GetReactionWhiteBoard()->SetTargZ( (G4int)this->GetZ(it) );
00280 return theFinalState;
00281 }
00282