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