source: trunk/source/processes/hadronic/models/neutron_hp/src/G4NeutronHPChannel.cc@ 1036

Last change on this file since 1036 was 962, checked in by garnier, 17 years ago

update processes

File size: 9.1 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// neutron_hp -- source file
27// J.P. Wellisch, Nov-1996
28// A prototype of the low energy neutron transport model.
29//
30// 070523 bug fix for G4FPE_DEBUG on by A. Howard ( and T. Koi)
31// 071031 bug fix T. Koi on behalf of A. Howard
32// 081203 bug fix in Register method by T. Koi
33//
34#include "G4NeutronHPChannel.hh"
35#include "G4NeutronHPFinalState.hh"
36#include "globals.hh"
37#include "G4HadTmpUtil.hh"
38
39 G4double G4NeutronHPChannel::GetXsec(G4double energy)
40 {
41 return std::max(0., theChannelData->GetXsec(energy));
42 }
43
44 G4double G4NeutronHPChannel::GetWeightedXsec(G4double energy, G4int isoNumber)
45 {
46 return theIsotopeWiseData[isoNumber].GetXsec(energy);
47 }
48
49 G4double G4NeutronHPChannel::GetFSCrossSection(G4double energy, G4int isoNumber)
50 {
51 return theFinalStates[isoNumber]->GetXsec(energy);
52 }
53
54 void G4NeutronHPChannel::
55 Init(G4Element * anElement, const G4String dirName, const G4String aFSType)
56 {
57 theFSType = aFSType;
58 Init(anElement, dirName);
59 }
60
61 void G4NeutronHPChannel::Init(G4Element * anElement, const G4String dirName)
62 {
63 theDir = dirName;
64 theElement = anElement;
65 }
66
67 G4bool G4NeutronHPChannel::Register(G4NeutronHPFinalState *theFS)
68 {
69 registerCount++;
70 G4int Z = G4lrint(theElement->GetZ());
71
72 Z = Z-registerCount;
73 if ( registerCount > 5 ) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material"); // for Elastic, Capture, Fission case
74 if ( Z < 1 ) return false;
75/*
76 if(registerCount<5)
77 {
78 Z = Z-registerCount;
79 }
80*/
81 //if(Z=theElement->GetZ()-5) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material");
82 // Bug fix by TK on behalf of AH
83 if ( Z <=theElement->GetZ()-5 ) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material");
84 G4int count = 0;
85 if(registerCount==0) count = theElement->GetNumberOfIsotopes();
86 if(count == 0||registerCount!=0) count +=
87 theStableOnes.GetNumberOfIsotopes(Z);
88 niso = count;
89 delete [] theIsotopeWiseData;
90 theIsotopeWiseData = new G4NeutronHPIsoData [niso];
91 delete [] active;
92 active = new G4bool[niso];
93
94 delete [] theFinalStates;
95 theFinalStates = new G4NeutronHPFinalState * [niso];
96 delete theChannelData;
97 theChannelData = new G4NeutronHPVector;
98 for(G4int i=0; i<niso; i++)
99 {
100 theFinalStates[i] = theFS->New();
101 }
102 count = 0;
103 G4int nIsos = niso;
104 if(theElement->GetNumberOfIsotopes()!=0&&registerCount==0)
105 {
106 for (G4int i1=0; i1<nIsos; i1++)
107 {
108 // G4cout <<" Init: normal case"<<G4endl;
109 G4int A = theElement->GetIsotope(i1)->GetN();
110 G4double frac = theElement->GetRelativeAbundanceVector()[i1]/perCent;
111 theFinalStates[i1]->SetA_Z(A, Z);
112 UpdateData(A, Z, count++, frac);
113 }
114 } else {
115 //G4cout <<" Init: mean case: "
116 // <<theStableOnes.GetNumberOfIsotopes(Z)<<" "
117 // <<Z<<" "<<theElement
118 // << G4endl;
119 G4int first = theStableOnes.GetFirstIsotope(Z);
120 for(G4int i1=0;
121 i1<theStableOnes.GetNumberOfIsotopes(Z);
122 i1++)
123 {
124 G4int A = theStableOnes.GetIsotopeNucleonCount(first+i1);
125 G4double frac = theStableOnes.GetAbundance(first+i1);
126 theFinalStates[i1]->SetA_Z(A, Z);
127 UpdateData(A, Z, count++, frac);
128 }
129 }
130 G4bool result = HasDataInAnyFinalState();
131 return result;
132 }
133
134 void G4NeutronHPChannel::UpdateData(G4int A, G4int Z, G4int index, G4double abundance)
135 {
136 theFinalStates[index]->Init(A, Z, theDir, theFSType);
137 if(!theFinalStates[index]->HasAnyData()) return; // nothing there for exactly this isotope.
138
139 // the above has put the X-sec into the FS
140 theBuffer = 0;
141 if(theFinalStates[index]->HasXsec())
142 {
143 theBuffer = theFinalStates[index]->GetXsec();
144 theBuffer->Times(abundance/100.);
145 theIsotopeWiseData[index].FillChannelData(theBuffer);
146 }
147 else // get data from CrossSection directory
148 {
149 G4String tString = "/CrossSection/";
150 active[index] = theIsotopeWiseData[index].Init(A, Z, abundance, theDir, tString);
151 if(active[index]) theBuffer = theIsotopeWiseData[index].MakeChannelData();
152 }
153 if(theBuffer != 0) Harmonise(theChannelData, theBuffer);
154 }
155
156 void G4NeutronHPChannel::Harmonise(G4NeutronHPVector *& theStore, G4NeutronHPVector * theNew)
157 {
158 G4int s = 0, n=0, m=0;
159 G4NeutronHPVector * theMerge = new G4NeutronHPVector;
160 G4NeutronHPVector * anActive = theStore;
161 G4NeutronHPVector * aPassive = theNew;
162 G4NeutronHPVector * tmp;
163 G4int a = s, p = n, t;
164 while (a<anActive->GetVectorLength()&&p<aPassive->GetVectorLength())
165 {
166 if(anActive->GetEnergy(a) <= aPassive->GetEnergy(p))
167 {
168 G4double xa = anActive->GetEnergy(a);
169 theMerge->SetData(m, xa, anActive->GetXsec(a)+std::max(0., aPassive->GetXsec(xa)) );
170 m++;
171 a++;
172 G4double xp = aPassive->GetEnergy(p);
173 if( std::abs(std::abs(xp-xa)/xa)<0.001 )
174 {
175 p++;
176 }
177 } else {
178 tmp = anActive; t=a;
179 anActive = aPassive; a=p;
180 aPassive = tmp; p=t;
181 }
182 }
183 while (a!=anActive->GetVectorLength())
184 {
185 theMerge->SetData(m++, anActive->GetEnergy(a), anActive->GetXsec(a));
186 a++;
187 }
188 while (p!=aPassive->GetVectorLength())
189 {
190 if(std::abs(theMerge->GetEnergy(std::max(0,m-1))-aPassive->GetEnergy(p))/aPassive->GetEnergy(p)>0.001)
191 theMerge->SetData(m++, aPassive->GetEnergy(p), aPassive->GetXsec(p));
192 p++;
193 }
194 delete theStore;
195 theStore = theMerge;
196 }
197
198#include "G4NeutronHPThermalBoost.hh"
199
200 G4HadFinalState * G4NeutronHPChannel::
201 ApplyYourself(const G4HadProjectile & theTrack, G4int anIsotope)
202 {
203// G4cout << "G4NeutronHPChannel::ApplyYourself+"<<niso<<G4endl;
204 if(anIsotope != -1) return theFinalStates[anIsotope]->ApplyYourself(theTrack);
205 G4double sum=0;
206 G4int it=0;
207 G4double * xsec = new G4double[niso];
208 G4NeutronHPThermalBoost aThermalE;
209 for (G4int i=0; i<niso; i++)
210 {
211 if(theFinalStates[i]->HasAnyData())
212 {
213 xsec[i] = theIsotopeWiseData[i].GetXsec(aThermalE.GetThermalEnergy(theTrack,
214 theFinalStates[i]->GetN(),
215 theFinalStates[i]->GetZ(),
216 theTrack.GetMaterial()->GetTemperature()));
217 sum += xsec[i];
218 }
219 else
220 {
221 xsec[i]=0;
222 }
223 }
224 if(sum == 0)
225 {
226// G4cout << "G4NeutronHPChannel::ApplyYourself theFinalState->Initialize+"<<G4endl;
227// G4cout << "G4NeutronHPChannel::ApplyYourself theFinalState->Initialize-"<<G4endl;
228 it = static_cast<G4int>(niso*G4UniformRand());
229 }
230 else
231 {
232// G4cout << "Are we still here? "<<sum<<G4endl;
233// G4cout << "TESTHP 23 NISO="<<niso<<G4endl;
234 G4double random = G4UniformRand();
235 G4double running=0;
236// G4cout << "G4NeutronHPChannel::ApplyYourself Done the sum"<<niso<<G4endl;
237// G4cout << "TESTHP 24 NISO="<<niso<<G4endl;
238 for (G4int ix=0; ix<niso; ix++)
239 {
240 running += xsec[ix];
241 //if(random<=running/sum)
242 if( sum == 0 || random <= running/sum )
243 {
244 it = ix;
245 break;
246 }
247 }
248 if(it==niso) it--;
249 }
250 delete [] xsec;
251 G4HadFinalState * theFinalState=0;
252 while(theFinalState==0)
253 {
254// G4cout << "TESTHP 24 it="<<it<<G4endl;
255 theFinalState = theFinalStates[it]->ApplyYourself(theTrack);
256 }
257// G4cout <<"THE IMPORTANT RETURN"<<G4endl;
258 return theFinalState;
259 }
260
Note: See TracBrowser for help on using the repository browser.