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

Last change on this file since 1340 was 962, checked in by garnier, 15 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.