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

Last change on this file since 830 was 819, checked in by garnier, 17 years ago

import all except CVS

File size: 8.8 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//
33#include "G4NeutronHPChannel.hh"
34#include "G4NeutronHPFinalState.hh"
35#include "globals.hh"
36#include "G4HadTmpUtil.hh"
37
38 G4double G4NeutronHPChannel::GetXsec(G4double energy)
39 {
40 return std::max(0., theChannelData->GetXsec(energy));
41 }
42
43 G4double G4NeutronHPChannel::GetWeightedXsec(G4double energy, G4int isoNumber)
44 {
45 return theIsotopeWiseData[isoNumber].GetXsec(energy);
46 }
47
48 G4double G4NeutronHPChannel::GetFSCrossSection(G4double energy, G4int isoNumber)
49 {
50 return theFinalStates[isoNumber]->GetXsec(energy);
51 }
52
53 void G4NeutronHPChannel::
54 Init(G4Element * anElement, const G4String dirName, const G4String aFSType)
55 {
56 theFSType = aFSType;
57 Init(anElement, dirName);
58 }
59
60 void G4NeutronHPChannel::Init(G4Element * anElement, const G4String dirName)
61 {
62 theDir = dirName;
63 theElement = anElement;
64 }
65
66 G4bool G4NeutronHPChannel::Register(G4NeutronHPFinalState *theFS)
67 {
68 registerCount++;
69 G4int Z = G4lrint(theElement->GetZ());
70 if(registerCount<5)
71 {
72 Z = Z-registerCount;
73 }
74 //if(Z=theElement->GetZ()-5) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material");
75 // Bug fix by TK on behalf of AH
76 if ( Z <=theElement->GetZ()-5 ) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material");
77 G4int count = 0;
78 if(registerCount==0) count = theElement->GetNumberOfIsotopes();
79 if(count == 0||registerCount!=0) count +=
80 theStableOnes.GetNumberOfIsotopes(Z);
81 niso = count;
82 delete [] theIsotopeWiseData;
83 theIsotopeWiseData = new G4NeutronHPIsoData [niso];
84 delete [] active;
85 active = new G4bool[niso];
86 delete [] theFinalStates;
87 theFinalStates = new G4NeutronHPFinalState * [niso];
88 delete theChannelData;
89 theChannelData = new G4NeutronHPVector;
90 for(G4int i=0; i<niso; i++)
91 {
92 theFinalStates[i] = theFS->New();
93 }
94 count = 0;
95 G4int nIsos = niso;
96 if(theElement->GetNumberOfIsotopes()!=0&&registerCount==0)
97 {
98 for (G4int i1=0; i1<nIsos; i1++)
99 {
100 // G4cout <<" Init: normal case"<<G4endl;
101 G4int A = theElement->GetIsotope(i1)->GetN();
102 G4double frac = theElement->GetRelativeAbundanceVector()[i1]/perCent;
103 theFinalStates[i1]->SetA_Z(A, Z);
104 UpdateData(A, Z, count++, frac);
105 }
106 } else {
107 //G4cout <<" Init: mean case: "
108 // <<theStableOnes.GetNumberOfIsotopes(Z)<<" "
109 // <<Z<<" "<<theElement
110 // << G4endl;
111 G4int first = theStableOnes.GetFirstIsotope(Z);
112 for(G4int i1=0;
113 i1<theStableOnes.GetNumberOfIsotopes(Z);
114 i1++)
115 {
116 G4int A = theStableOnes.GetIsotopeNucleonCount(first+i1);
117 G4double frac = theStableOnes.GetAbundance(first+i1);
118 theFinalStates[i1]->SetA_Z(A, Z);
119 UpdateData(A, Z, count++, frac);
120 }
121 }
122 G4bool result = HasDataInAnyFinalState();
123 return result;
124 }
125
126 void G4NeutronHPChannel::UpdateData(G4int A, G4int Z, G4int index, G4double abundance)
127 {
128 theFinalStates[index]->Init(A, Z, theDir, theFSType);
129 if(!theFinalStates[index]->HasAnyData()) return; // nothing there for exactly this isotope.
130
131 // the above has put the X-sec into the FS
132 theBuffer = 0;
133 if(theFinalStates[index]->HasXsec())
134 {
135 theBuffer = theFinalStates[index]->GetXsec();
136 theBuffer->Times(abundance/100.);
137 theIsotopeWiseData[index].FillChannelData(theBuffer);
138 }
139 else // get data from CrossSection directory
140 {
141 G4String tString = "/CrossSection/";
142 active[index] = theIsotopeWiseData[index].Init(A, Z, abundance, theDir, tString);
143 if(active[index]) theBuffer = theIsotopeWiseData[index].MakeChannelData();
144 }
145 if(theBuffer != 0) Harmonise(theChannelData, theBuffer);
146 }
147
148 void G4NeutronHPChannel::Harmonise(G4NeutronHPVector *& theStore, G4NeutronHPVector * theNew)
149 {
150 G4int s = 0, n=0, m=0;
151 G4NeutronHPVector * theMerge = new G4NeutronHPVector;
152 G4NeutronHPVector * anActive = theStore;
153 G4NeutronHPVector * aPassive = theNew;
154 G4NeutronHPVector * tmp;
155 G4int a = s, p = n, t;
156 while (a<anActive->GetVectorLength()&&p<aPassive->GetVectorLength())
157 {
158 if(anActive->GetEnergy(a) <= aPassive->GetEnergy(p))
159 {
160 G4double xa = anActive->GetEnergy(a);
161 theMerge->SetData(m, xa, anActive->GetXsec(a)+std::max(0., aPassive->GetXsec(xa)) );
162 m++;
163 a++;
164 G4double xp = aPassive->GetEnergy(p);
165 if( std::abs(std::abs(xp-xa)/xa)<0.001 )
166 {
167 p++;
168 }
169 } else {
170 tmp = anActive; t=a;
171 anActive = aPassive; a=p;
172 aPassive = tmp; p=t;
173 }
174 }
175 while (a!=anActive->GetVectorLength())
176 {
177 theMerge->SetData(m++, anActive->GetEnergy(a), anActive->GetXsec(a));
178 a++;
179 }
180 while (p!=aPassive->GetVectorLength())
181 {
182 if(std::abs(theMerge->GetEnergy(std::max(0,m-1))-aPassive->GetEnergy(p))/aPassive->GetEnergy(p)>0.001)
183 theMerge->SetData(m++, aPassive->GetEnergy(p), aPassive->GetXsec(p));
184 p++;
185 }
186 delete theStore;
187 theStore = theMerge;
188 }
189
190#include "G4NeutronHPThermalBoost.hh"
191
192 G4HadFinalState * G4NeutronHPChannel::
193 ApplyYourself(const G4HadProjectile & theTrack, G4int anIsotope)
194 {
195// G4cout << "G4NeutronHPChannel::ApplyYourself+"<<niso<<G4endl;
196 if(anIsotope != -1) return theFinalStates[anIsotope]->ApplyYourself(theTrack);
197 G4double sum=0;
198 G4int it=0;
199 G4double * xsec = new G4double[niso];
200 G4NeutronHPThermalBoost aThermalE;
201 for (G4int i=0; i<niso; i++)
202 {
203 if(theFinalStates[i]->HasAnyData())
204 {
205 xsec[i] = theIsotopeWiseData[i].GetXsec(aThermalE.GetThermalEnergy(theTrack,
206 theFinalStates[i]->GetN(),
207 theFinalStates[i]->GetZ(),
208 theTrack.GetMaterial()->GetTemperature()));
209 sum += xsec[i];
210 }
211 else
212 {
213 xsec[i]=0;
214 }
215 }
216 if(sum == 0)
217 {
218// G4cout << "G4NeutronHPChannel::ApplyYourself theFinalState->Initialize+"<<G4endl;
219// G4cout << "G4NeutronHPChannel::ApplyYourself theFinalState->Initialize-"<<G4endl;
220 it = static_cast<G4int>(niso*G4UniformRand());
221 }
222 else
223 {
224// G4cout << "Are we still here? "<<sum<<G4endl;
225// G4cout << "TESTHP 23 NISO="<<niso<<G4endl;
226 G4double random = G4UniformRand();
227 G4double running=0;
228// G4cout << "G4NeutronHPChannel::ApplyYourself Done the sum"<<niso<<G4endl;
229// G4cout << "TESTHP 24 NISO="<<niso<<G4endl;
230 for (G4int ix=0; ix<niso; ix++)
231 {
232 running += xsec[ix];
233 //if(random<=running/sum)
234 if( sum == 0 || random <= running/sum )
235 {
236 it = ix;
237 break;
238 }
239 }
240 if(it==niso) it--;
241 }
242 delete [] xsec;
243 G4HadFinalState * theFinalState=0;
244 while(theFinalState==0)
245 {
246// G4cout << "TESTHP 24 it="<<it<<G4endl;
247 theFinalState = theFinalStates[it]->ApplyYourself(theTrack);
248 }
249// G4cout <<"THE IMPORTANT RETURN"<<G4endl;
250 return theFinalState;
251 }
252
Note: See TracBrowser for help on using the repository browser.