Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/particle_hp/src/G4ParticleHPLegendreStore.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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)
 31 // #3
 32 //
 33 // P. Arce, June-2014 Conversion neutron_hp to particle_hp
 34 //
 35 #include "G4ParticleHPLegendreStore.hh"
 36 
 37 #include "G4ParticleHPFastLegendre.hh"
 38 #include "G4ParticleHPInterpolator.hh"
 39 #include "G4ParticleHPVector.hh"
 40 #include "Randomize.hh"
 41 
 42 #include <iostream>
 43 
 44 // 080612TK contribution from Benoit Pirard and Laurent Desorgher (Univ. Bern) #3
 45 G4double G4ParticleHPLegendreStore::SampleDiscreteTwoBody(G4double anEnergy)
 46 {
 47   G4double result = 0.;
 48 
 49   G4int i0;
 50   G4int low(0), high(0);
 51   G4ParticleHPFastLegendre theLeg;
 52   for (i0 = 0; i0 < nEnergy; i0++) {
 53     high = i0;
 54     if (theCoeff[i0].GetEnergy() > anEnergy) break;
 55   }
 56   low = std::max(0, high - 1);
 57   G4ParticleHPInterpolator theInt;
 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;
 66   max2 = 0;
 67   G4int l, m_tmp;
 68   for (i0 = 0; i0 < 601; i0++) {
 69     costh = G4double(i0 - 300) / 300.;
 70     try01 = 0.5;
 71     for (m_tmp = 0; m_tmp < theCoeff[low].GetNumberOfPoly(); m_tmp++) {
 72       l = m_tmp + 1;
 73       try01 += (2. * l + 1) / 2. * theCoeff[low].GetCoeff(m_tmp) * theLeg.Evaluate(l, costh);
 74     }
 75     if (try01 > max1) max1 = try01;
 76     try02 = 0.5;
 77     for (m_tmp = 0; m_tmp < theCoeff[high].GetNumberOfPoly(); m_tmp++) {
 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   G4int icounter = 0;
 88   G4int icounter_max = 1024;
 89   do {
 90     icounter++;
 91     if (icounter > icounter_max) {
 92       G4cout << "Loop-counter exceeded the threshold value at " << __LINE__ << "th line of "
 93              << __FILE__ << "." << G4endl;
 94       break;
 95     }
 96     v1 = 0.5;
 97     v2 = 0.5;
 98     result = 2. * G4UniformRand() - 1.;
 99     for (m_tmp = 0; m_tmp < theCoeff[low].GetNumberOfPoly(); m_tmp++) {
100       l = m_tmp + 1;
101       G4double legend = theLeg.Evaluate(l, result);  // @@@ done to avoid optimization error on SUN
102       v1 += (2. * l + 1) / 2. * theCoeff[low].GetCoeff(m_tmp) * legend;
103     }
104     for (m_tmp = 0; m_tmp < theCoeff[high].GetNumberOfPoly(); m_tmp++) {
105       l = m_tmp + 1;
106       G4double legend = theLeg.Evaluate(l, result);  // @@@ done to avoid optimization error on SUN
107       v2 += (2. * l + 1) / 2. * theCoeff[high].GetCoeff(m_tmp) * legend;
108     }
109     // v1 = std::max(0.,v1); // Workaround in case one of the distributions is fully non-physical.
110     // v2 = std::max(0.,v2);
111     value = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, v1, v2);
112     random = G4UniformRand();
113     if (0 >= theNorm) break;  // Workaround for negative cross-section values. @@@@ 31 May 2000
114   } while (random > value / theNorm);  // Loop checking, 11.05.2015, T. Koi
115 
116   return result;
117 }
118 
119 G4double G4ParticleHPLegendreStore::SampleMax(G4double anEnergy)
120 {
121   G4double result = 0.;
122 
123   G4int i0;
124   G4int low(0), high(0);
125   G4ParticleHPFastLegendre theLeg;
126   for (i0 = 0; i0 < nEnergy; i0++) {
127     high = i0;
128     if (theCoeff[i0].GetEnergy() > anEnergy) break;
129   }
130   low = std::max(0, high - 1);
131   G4ParticleHPInterpolator theInt;
132   G4double x, x1, x2;
133   x = anEnergy;
134   x1 = theCoeff[low].GetEnergy();
135   x2 = theCoeff[high].GetEnergy();
136   G4double theNorm = 0;
137   G4double try01 = 0, try02 = 0;
138   G4double max1, max2, costh;
139   max1 = 0;
140   max2 = 0;
141   G4int l;
142   for (i0 = 0; i0 < 601; i0++) {
143     costh = G4double(i0 - 300) / 300.;
144     try01 = 0;
145     for (l = 0; l < theCoeff[low].GetNumberOfPoly(); l++) {
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       try02 += (2. * l + 1) / 2. * theCoeff[high].GetCoeff(l) * theLeg.Evaluate(l, costh);
152     }
153     if (try02 > max2) max2 = try02;
154   }
155   theNorm = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, max1, max2);
156 
157   G4double value, random;
158   G4double v1, v2;
159   G4int icounter = 0;
160   G4int icounter_max = 1024;
161   do {
162     icounter++;
163     if (icounter > icounter_max) {
164       G4cout << "Loop-counter exceeded the threshold value at " << __LINE__ << "th line of "
165              << __FILE__ << "." << G4endl;
166       break;
167     }
168     v1 = 0;
169     v2 = 0;
170     result = 2. * G4UniformRand() - 1.;
171     for (l = 0; l < theCoeff[low].GetNumberOfPoly(); l++) {
172       G4double legend = theLeg.Evaluate(l, result);  // @@@ done to avoid optimization error on SUN
173       v1 += (2. * l + 1) / 2. * theCoeff[low].GetCoeff(l) * legend;
174     }
175     for (l = 0; l < theCoeff[high].GetNumberOfPoly(); l++) {
176       G4double legend = theLeg.Evaluate(l, result);  // @@@ done to avoid optimization error on SUN
177       v2 += (2. * l + 1) / 2. * theCoeff[high].GetCoeff(l) * legend;
178     }
179     v1 = std::max(0., v1);  // Workaround in case one of the distributions is fully non-physical.
180     v2 = std::max(0., v2);
181     value = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, v1, v2);
182     random = G4UniformRand();
183     if (0 >= theNorm) break;  // Workaround for negative cross-section values. @@@@ 31 May 2000
184   } while (random > value / theNorm);  // Loop checking, 11.05.2015, T. Koi
185   return result;
186 }
187 
188 G4double G4ParticleHPLegendreStore::SampleElastic(G4double anEnergy)
189 {
190   G4double result = 0.;
191 
192   G4int i0;
193   G4int low(0), high(0);
194   G4ParticleHPFastLegendre theLeg;
195   for (i0 = 0; i0 < nEnergy; i0++) {
196     high = i0;
197     if (theCoeff[i0].GetEnergy() > anEnergy) break;
198   }
199   low = std::max(0, high - 1);
200   G4ParticleHPInterpolator 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     try01 += (2. * l + 1) / 2. * theCoeff[low].GetCoeff(l) * theLeg.Evaluate(l, -1.);
211     try11 += (2. * l + 1) / 2. * theCoeff[low].GetCoeff(l) * theLeg.Evaluate(l, +1.);
212   }
213   for (l = 0; l < theCoeff[high].GetNumberOfPoly(); l++) {
214     try02 += (2. * l + 1) / 2. * theCoeff[high].GetCoeff(l) * theLeg.Evaluate(l, -1.);
215     try12 += (2. * l + 1) / 2. * theCoeff[high].GetCoeff(l) * theLeg.Evaluate(l, +1.);
216   }
217   try1 = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, try01, try02);
218   try2 = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, try11, try12);
219   theNorm = std::max(try1, try2);
220 
221   G4double value, random;
222   G4double v1, v2;
223   G4int icounter = 0;
224   G4int icounter_max = 1024;
225   do {
226     icounter++;
227     if (icounter > icounter_max) {
228       G4cout << "Loop-counter exceeded the threshold value at " << __LINE__ << "th line of "
229              << __FILE__ << "." << G4endl;
230       break;
231     }
232     v1 = 0;
233     v2 = 0;
234     result = 2. * G4UniformRand() - 1.;
235     for (l = 0; l < theCoeff[low].GetNumberOfPoly(); l++) {
236       G4double legend = theLeg.Evaluate(l, result);  // @@@ done to avoid optimization error on SUN
237       v1 += (2. * l + 1) / 2. * theCoeff[low].GetCoeff(l) * legend;
238     }
239     for (l = 0; l < theCoeff[high].GetNumberOfPoly(); l++) {
240       G4double legend = theLeg.Evaluate(l, result);  // @@@ done to avoid optimization error on SUN
241       v2 += (2. * l + 1) / 2. * theCoeff[high].GetCoeff(l) * legend;
242     }
243     value = theInt.Interpolate(theManager.GetScheme(high), x, x1, x2, v1, v2);
244     random = G4UniformRand();
245   } while (random > value / theNorm);  // Loop checking, 11.05.2015, T. Koi
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     //     G4cout <<"theCoeff["<<i0<<"].GetEnergy() = "<<theCoeff[i0].GetEnergy()<<G4endl;
257     high = i0;
258     if (theCoeff[i0].GetEnergy() > energy) break;
259   }
260   low = std::max(0, high - 1);
261   //  G4cout << "G4ParticleHPLegendreStore::Sample high, low: "<<high<<", "<<low<<G4endl;
262   G4ParticleHPVector theBuffer;
263   G4ParticleHPInterpolator theInt;
264   G4double x1, x2, y1, y2, y;
265   x1 = theCoeff[low].GetEnergy();
266   x2 = theCoeff[high].GetEnergy();
267   //  G4cout << "the xes "<<x1<<" "<<x2<<G4endl;
268   G4double costh = 0;
269   for (i0 = 0; i0 < 601; i0++) {
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     it = i0;
281     if (rand < theBuffer.GetY(i0) / theBuffer.GetY(600)) break;
282     //    G4cout <<"sampling now "<<i0<<" "
283     //         << theBuffer.GetY(i0)<<" "
284     //         << theBuffer.GetY(600)<<" "
285     //         << rand<<" "
286     //         << theBuffer.GetY(i0)/theBuffer.GetY(600)<<G4endl;;
287   }
288   if (it == 601) it = 600;
289   //  G4cout << "G4ParticleHPLegendreStore::Sample it "<<rand<<" "<<it<<G4endl;
290   G4double norm = theBuffer.GetY(600);
291   if (norm == 0) return -DBL_MAX;
292   x1 = theBuffer.GetY(it) / norm;
293   x2 = theBuffer.GetY(it - 1) / norm;
294   y1 = theBuffer.GetX(it);
295   y2 = theBuffer.GetX(it - 1);
296   //  G4cout << "G4ParticleHPLegendreStore::Sample x y "<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<G4endl;
297   return theInt.Interpolate(theManager.GetScheme(high), rand, x1, x2, y1, y2);
298 }
299 
300 G4double
301 G4ParticleHPLegendreStore::Integrate(G4int k,
302                                      G4double costh)  // still in interpolation; not used anymore
303 {
304   G4double result = 0.;
305   G4ParticleHPFastLegendre theLeg;
306   //  G4cout <<"the COEFFS "<<k<<" ";
307   //  G4cout <<theCoeff[k].GetNumberOfPoly()<<" ";
308   for (G4int l = 0; l < theCoeff[k].GetNumberOfPoly(); l++) {
309     result += theCoeff[k].GetCoeff(l) * theLeg.Integrate(l, costh);
310     //    G4cout << theCoeff[k].GetCoeff(l)<<" ";
311   }
312   //  G4cout <<G4endl;
313   return result;
314 }
315