Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4NeutronHPLegendreStore.cc
Go to the documentation of this file.
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//
33#include "G4NeutronHPVector.hh"
36#include "Randomize.hh"
37#include <iostream>
38
39
40
41//080612TK contribution from Benoit Pirard and Laurent Desorgher (Univ. Bern) #3
43{
44 G4double result;
45
46 G4int i0;
47 G4int low(0), high(0);
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);
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_tmp;
65 for(i0=0; i0<601; i0++)
66 {
67 costh = G4double(i0-300)/300.;
68 try01 = 0.5;
69 for(m_tmp=0; m_tmp<theCoeff[low].GetNumberOfPoly() ; m_tmp++)
70 {
71 l=m_tmp+1;
72 try01 += (2.*l+1)/2.*theCoeff[low].GetCoeff(m_tmp)*theLeg.Evaluate(l, costh);
73 }
74 if(try01>max1) max1=try01;
75 try02 = 0.5;
76 for(m_tmp=0; m_tmp<theCoeff[high].GetNumberOfPoly() ; m_tmp++)
77 {
78 l=m_tmp+1;
79 try02 += (2.*l+1)/2.*theCoeff[high].GetCoeff(m_tmp)*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_tmp=0; m_tmp<theCoeff[low].GetNumberOfPoly() ; m_tmp++)
93 {
94 l=m_tmp+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_tmp)*legend;
97 }
98 for(m_tmp=0; m_tmp<theCoeff[high].GetNumberOfPoly() ; m_tmp++)
99 {
100 l=m_tmp+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_tmp)*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
118{
119 G4double result;
120
121 G4int i0;
122 G4int low(0), high(0);
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);
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
188{
189 G4double result;
190
191 G4int i0;
192 G4int low(0), high(0);
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);
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;
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;
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}
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4UniformRand()
Definition: Randomize.hh:53
G4InterpolationScheme GetScheme(G4int index) const
G4double Integrate(G4int l, G4double costh)
G4double Evaluate(G4int l, G4double costh)
G4double Interpolate(G4InterpolationScheme aScheme, G4double x, G4double x1, G4double x2, G4double y1, G4double y2) const
G4double GetCoeff(G4int i, G4int l)
G4double Integrate(G4int k, G4double costh)
G4double SampleMax(G4double energy)
G4double Sample(G4double energy)
G4double SampleDiscreteTwoBody(G4double anEnergy)
G4double SampleElastic(G4double anEnergy)
G4double GetX(G4int i) const
G4double GetY(G4double x)
void SetData(G4int i, G4double x, G4double y)
#define DBL_MAX
Definition: templates.hh:83