source: trunk/source/processes/hadronic/models/neutron_hp/src/G4NeutronHPLegendreStore.cc@ 1199

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

update processes

File size: 10.4 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// 080612 SampleDiscreteTwoBody contribution from Benoit Pirard and Laurent Desorgher (Univ. Bern) #3
31//
32#include "G4NeutronHPLegendreStore.hh"
33#include "G4NeutronHPVector.hh"
34#include "G4NeutronHPInterpolator.hh"
35#include "G4NeutronHPFastLegendre.hh"
36#include "Randomize.hh"
37#include <iostream>
38
39
40
41//080612TK contribution from Benoit Pirard and Laurent Desorgher (Univ. Bern) #3
42G4double G4NeutronHPLegendreStore::SampleDiscreteTwoBody (G4double anEnergy)
43{
44 G4double result;
45
46 G4int i0;
47 G4int low(0), high(0);
48 G4NeutronHPFastLegendre theLeg;
49 for (i0=0; i0<nEnergy; i0++)
50 {
51 high = i0;
52 if(theCoeff[i0].GetEnergy()>anEnergy) break;
53 }
54 low = std::max(0, high-1);
55 G4NeutronHPInterpolator theInt;
56 G4double x, x1, x2;
57 x = anEnergy;
58 x1 = theCoeff[low].GetEnergy();
59 x2 = theCoeff[high].GetEnergy();
60 G4double theNorm = 0;
61 G4double try01=0, try02=0;
62 G4double max1, max2, costh;
63 max1 = 0; max2 = 0;
64 G4int l,m;
65 for(i0=0; i0<601; i0++)
66 {
67 costh = G4double(i0-300)/300.;
68 try01 = 0.5;
69 for(m=0; m<theCoeff[low].GetNumberOfPoly() ; m++)
70 {
71 l=m+1;
72 try01 += (2.*l+1)/2.*theCoeff[low].GetCoeff(m)*theLeg.Evaluate(l, costh);
73 }
74 if(try01>max1) max1=try01;
75 try02 = 0.5;
76 for(m=0; m<theCoeff[high].GetNumberOfPoly() ; m++)
77 {
78 l=m+1;
79 try02 += (2.*l+1)/2.*theCoeff[high].GetCoeff(m)*theLeg.Evaluate(l, costh);
80 }
81 if(try02>max2) max2=try02;
82 }
83 theNorm = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, max1, max2);
84
85 G4double value, random;
86 G4double v1, v2;
87 do
88 {
89 v1 = 0.5;
90 v2 = 0.5;
91 result = 2.*G4UniformRand()-1.;
92 for(m=0; m<theCoeff[low].GetNumberOfPoly() ; m++)
93 {
94 l=m+1;
95 G4double legend = theLeg.Evaluate(l, result); // @@@ done to avoid optimization error on SUN
96 v1 += (2.*l+1)/2.*theCoeff[low].GetCoeff(m)*legend;
97 }
98 for(m=0; m<theCoeff[high].GetNumberOfPoly() ; m++)
99 {
100 l=m+1;
101 G4double legend = theLeg.Evaluate(l, result); // @@@ done to avoid optimization error on SUN
102 v2 += (2.*l+1)/2.*theCoeff[high].GetCoeff(m)*legend;
103 }
104 // v1 = std::max(0.,v1); // Workaround in case one of the distributions is fully non-physical.
105 // v2 = std::max(0.,v2);
106 value = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, v1, v2);
107 random = G4UniformRand();
108 if(0>=theNorm) break; // Workaround for negative cross-section values. @@@@ 31 May 2000
109 }
110 while(random>value/theNorm);
111
112 return result;
113}
114
115
116
117G4double G4NeutronHPLegendreStore::SampleMax (G4double anEnergy)
118{
119 G4double result;
120
121 G4int i0;
122 G4int low(0), high(0);
123 G4NeutronHPFastLegendre theLeg;
124 for (i0=0; i0<nEnergy; i0++)
125 {
126 high = i0;
127 if(theCoeff[i0].GetEnergy()>anEnergy) break;
128 }
129 low = std::max(0, high-1);
130 G4NeutronHPInterpolator theInt;
131 G4double x, x1, x2;
132 x = anEnergy;
133 x1 = theCoeff[low].GetEnergy();
134 x2 = theCoeff[high].GetEnergy();
135 G4double theNorm = 0;
136 G4double try01=0, try02=0;
137 G4double max1, max2, costh;
138 max1 = 0; max2 = 0;
139 G4int l;
140 for(i0=0; i0<601; i0++)
141 {
142 costh = G4double(i0-300)/300.;
143 try01 = 0;
144 for(l=0; l<theCoeff[low].GetNumberOfPoly() ; l++)
145 {
146 try01 += (2.*l+1)/2.*theCoeff[low].GetCoeff(l)*theLeg.Evaluate(l, costh);
147 }
148 if(try01>max1) max1=try01;
149 try02 = 0;
150 for(l=0; l<theCoeff[high].GetNumberOfPoly() ; l++)
151 {
152 try02 += (2.*l+1)/2.*theCoeff[high].GetCoeff(l)*theLeg.Evaluate(l, costh);
153 }
154 if(try02>max2) max2=try02;
155 }
156 theNorm = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, max1, max2);
157
158 G4double value, random;
159 G4double v1, v2;
160 do
161 {
162 v1 = 0;
163 v2 = 0;
164 result = 2.*G4UniformRand()-1.;
165 for(l=0; l<theCoeff[low].GetNumberOfPoly() ; l++)
166 {
167 G4double legend = theLeg.Evaluate(l, result); // @@@ done to avoid optimization error on SUN
168 v1 += (2.*l+1)/2.*theCoeff[low].GetCoeff(l)*legend;
169 }
170 for(l=0; l<theCoeff[high].GetNumberOfPoly() ; l++)
171 {
172 G4double legend = theLeg.Evaluate(l, result); // @@@ done to avoid optimization error on SUN
173 v2 += (2.*l+1)/2.*theCoeff[high].GetCoeff(l)*legend;
174 }
175 v1 = std::max(0.,v1); // Workaround in case one of the distributions is fully non-physical.
176 v2 = std::max(0.,v2);
177 value = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, v1, v2);
178 random = G4UniformRand();
179 if(0>=theNorm) break; // Workaround for negative cross-section values. @@@@ 31 May 2000
180 }
181 while(random>value/theNorm);
182
183 return result;
184}
185
186
187G4double G4NeutronHPLegendreStore::SampleElastic (G4double anEnergy)
188{
189 G4double result;
190
191 G4int i0;
192 G4int low(0), high(0);
193 G4NeutronHPFastLegendre theLeg;
194 for (i0=0; i0<nEnergy; i0++)
195 {
196 high = i0;
197 if(theCoeff[i0].GetEnergy()>anEnergy) break;
198 }
199 low = std::max(0, high-1);
200 G4NeutronHPInterpolator theInt;
201 G4double x, x1, x2;
202 x = anEnergy;
203 x1 = theCoeff[low].GetEnergy();
204 x2 = theCoeff[high].GetEnergy();
205 G4double theNorm = 0;
206 G4double try01=0, try02=0, try11=0, try12=0;
207 G4double try1, try2;
208 G4int l;
209 for(l=0; l<theCoeff[low].GetNumberOfPoly(); l++)
210 {
211 try01 += (2.*l+1)/2.*theCoeff[low].GetCoeff(l)*theLeg.Evaluate(l, -1.);
212 try11 += (2.*l+1)/2.*theCoeff[low].GetCoeff(l)*theLeg.Evaluate(l, +1.);
213 }
214 for(l=0; l<theCoeff[high].GetNumberOfPoly(); l++)
215 {
216 try02 += (2.*l+1)/2.*theCoeff[high].GetCoeff(l)*theLeg.Evaluate(l, -1.);
217 try12 += (2.*l+1)/2.*theCoeff[high].GetCoeff(l)*theLeg.Evaluate(l, +1.);
218 }
219 try1 = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, try01, try02);
220 try2 = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, try11, try12);
221 theNorm = std::max(try1, try2);
222
223 G4double value, random;
224 G4double v1, v2;
225 do
226 {
227 v1 = 0;
228 v2 = 0;
229 result = 2.*G4UniformRand()-1.;
230 for(l=0; l<theCoeff[low].GetNumberOfPoly() ; l++)
231 {
232 G4double legend = theLeg.Evaluate(l, result); // @@@ done to avoid optimization error on SUN
233 v1 += (2.*l+1)/2.*theCoeff[low].GetCoeff(l)*legend;
234 }
235 for(l=0; l<theCoeff[high].GetNumberOfPoly() ; l++)
236 {
237 G4double legend = theLeg.Evaluate(l, result); // @@@ done to avoid optimization error on SUN
238 v2 += (2.*l+1)/2.*theCoeff[high].GetCoeff(l)*legend;
239 }
240 value = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, v1, v2);
241 random = G4UniformRand();
242 }
243 while(random>value/theNorm);
244
245 return result;
246}
247
248G4double G4NeutronHPLegendreStore::Sample (G4double energy) // still in interpolation; do not use
249{
250 G4int i0;
251 G4int low(0), high(0);
252// G4cout << "G4NeutronHPLegendreStore::Sample "<<energy<<" "<<energy<<" "<<nEnergy<<G4endl;
253 for (i0=0; i0<nEnergy; i0++)
254 {
255// G4cout <<"theCoeff["<<i0<<"].GetEnergy() = "<<theCoeff[i0].GetEnergy()<<G4endl;
256 high = i0;
257 if(theCoeff[i0].GetEnergy()>energy) break;
258 }
259 low = std::max(0, high-1);
260// G4cout << "G4NeutronHPLegendreStore::Sample high, low: "<<high<<", "<<low<<G4endl;
261 G4NeutronHPVector theBuffer;
262 G4NeutronHPInterpolator theInt;
263 G4double x1, x2, y1, y2, y;
264 x1 = theCoeff[low].GetEnergy();
265 x2 = theCoeff[high].GetEnergy();
266// G4cout << "the xes "<<x1<<" "<<x2<<G4endl;
267 G4double costh=0;
268 for(i0=0; i0<601; i0++)
269 {
270 costh = G4double(i0-300)/300.;
271 y1 = Integrate(low, costh);
272 y2 = Integrate(high, costh);
273 y = theInt.Interpolate(theManager.GetScheme(high), energy, x1, x2, y1, y2);
274 theBuffer.SetData(i0, costh, y);
275// G4cout << "Integration "<<low<<" "<<costh<<" "<<y1<<" "<<y2<<" "<<y<<G4endl;
276 }
277 G4double rand = G4UniformRand();
278 G4int it;
279 for (i0=1; i0<601; i0++)
280 {
281 it = i0;
282 if(rand < theBuffer.GetY(i0)/theBuffer.GetY(600)) break;
283// G4cout <<"sampling now "<<i0<<" "
284// << theBuffer.GetY(i0)<<" "
285// << theBuffer.GetY(600)<<" "
286// << rand<<" "
287// << theBuffer.GetY(i0)/theBuffer.GetY(600)<<G4endl;;
288 }
289 if(it==601) it=600;
290// G4cout << "G4NeutronHPLegendreStore::Sample it "<<rand<<" "<<it<<G4endl;
291 G4double norm = theBuffer.GetY(600);
292 if(norm==0) return -DBL_MAX;
293 x1 = theBuffer.GetY(it)/norm;
294 x2 = theBuffer.GetY(it-1)/norm;
295 y1 = theBuffer.GetX(it);
296 y2 = theBuffer.GetX(it-1);
297// G4cout << "G4NeutronHPLegendreStore::Sample x y "<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<G4endl;
298 return theInt.Interpolate(theManager.GetScheme(high), rand, x1, x2, y1, y2);
299}
300
301G4double G4NeutronHPLegendreStore::Integrate(G4int k, G4double costh) // still in interpolation; not used anymore
302{
303 G4double result=0;
304 G4NeutronHPFastLegendre theLeg;
305// G4cout <<"the COEFFS "<<k<<" ";
306// G4cout <<theCoeff[k].GetNumberOfPoly()<<" ";
307 for(G4int l=0; l<theCoeff[k].GetNumberOfPoly() ; l++)
308 {
309 result += theCoeff[k].GetCoeff(l)*theLeg.Integrate(l, costh);
310// G4cout << theCoeff[k].GetCoeff(l)<<" ";
311 }
312// G4cout <<G4endl;
313 return result;
314}
Note: See TracBrowser for help on using the repository browser.