Geant4  10.01.p01
G4NeutronHPVector.hh
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 // 070606 fix with Valgrind by T. Koi
27 // 080409 Fix div0 error with G4FPE by T. Koi
28 // 080811 Comment out unused method SetBlocked and SetBuffered
29 // Add required cleaning up in CleanUp by T. Koi
30 //
31 #ifndef G4NeutronHPVector_h
32 #define G4NeutronHPVector_h 1
33 
34 #include "G4NeutronHPDataPoint.hh"
35 #include "G4PhysicsVector.hh"
37 #include "Randomize.hh"
38 #include "G4ios.hh"
39 #include <fstream>
42 #include "G4NeutronHPHash.hh"
43 #include "G4Threading.hh"
44 #include <cmath>
45 #include <vector>
46 
47 
48 #if defined WIN32-VC
49  #include <float.h>
50 #endif
51 
53 {
56 
57  public:
58 
60 
62 
64 
66 
67  inline void SetVerbose(G4int ff)
68  {
69  Verbose = ff;
70  }
71 
72  inline void Times(G4double factor)
73  {
74  G4int i;
75  for(i=0; i<nEntries; i++)
76  {
77  theData[i].SetY(theData[i].GetY()*factor);
78  }
79  if(theIntegral!=0)
80  {
81  theIntegral[i] *= factor;
82  }
83  }
84 
85  inline void SetPoint(G4int i, const G4NeutronHPDataPoint & it)
86  {
87  G4double x = it.GetX();
88  G4double y = it.GetY();
89  SetData(i, x, y);
90  }
91 
92  inline void SetData(G4int i, G4double x, G4double y)
93  {
94 // G4cout <<"G4NeutronHPVector::SetData called"<<nPoints<<" "<<nEntries<<G4endl;
95  Check(i);
96  if(y>maxValue) maxValue=y;
97  theData[i].SetData(x, y);
98  }
99  inline void SetX(G4int i, G4double e)
100  {
101  Check(i);
102  theData[i].SetX(e);
103  }
104  inline void SetEnergy(G4int i, G4double e)
105  {
106  Check(i);
107  theData[i].SetX(e);
108  }
109  inline void SetY(G4int i, G4double x)
110  {
111  Check(i);
112  if(x>maxValue) maxValue=x;
113  theData[i].SetY(x);
114  }
115  inline void SetXsec(G4int i, G4double x)
116  {
117  Check(i);
118  if(x>maxValue) maxValue=x;
119  theData[i].SetY(x);
120  }
121  inline G4double GetEnergy(G4int i) const { return theData[i].GetX(); }
122  inline G4double GetXsec(G4int i) { return theData[i].GetY(); }
123  inline G4double GetX(G4int i) const
124  {
125  if (i<0) i=0;
126  if(i>=GetVectorLength()) i=GetVectorLength()-1;
127  return theData[i].GetX();
128  }
129  inline const G4NeutronHPDataPoint & GetPoint(G4int i) const { return theData[i]; }
130 
131  void Hash()
132  {
133  G4int i;
134  G4double x, y;
135  for(i=0 ; i<nEntries; i++)
136  {
137  if(0 == (i+1)%10)
138  {
139  x = GetX(i);
140  y = GetY(i);
141  theHash.SetData(i, x, y);
142  }
143  }
144  }
145 
146  void ReHash()
147  {
148  theHash.Clear();
149  Hash();
150  }
151 
154  {
155  G4int i;
156  for(i=min ; i<nEntries; i++)
157  {
158  if(theData[i].GetX()>e) break;
159  }
160  G4int low = i-1;
161  G4int high = i;
162  if(i==0)
163  {
164  low = 0;
165  high = 1;
166  }
167  else if(i==nEntries)
168  {
169  low = nEntries-2;
170  high = nEntries-1;
171  }
172  G4double y;
173  if(e<theData[nEntries-1].GetX())
174  {
175  // Protect against doubled-up x values
176  if( (theData[high].GetX()-theData[low].GetX())/theData[high].GetX() < 0.000001)
177  {
178  y = theData[low].GetY();
179  }
180  else
181  {
182  y = theInt.Interpolate(theManager.GetScheme(high), e,
183  theData[low].GetX(), theData[high].GetX(),
184  theData[low].GetY(), theData[high].GetY());
185  }
186  }
187  else
188  {
189  y=theData[nEntries-1].GetY();
190  }
191  return y;
192  }
193 
194  inline G4double GetY(G4double x) {return GetXsec(x);}
195  inline G4int GetVectorLength() const {return nEntries;}
196 
197  inline G4double GetY(G4int i)
198  {
199  if (i<0) i=0;
200  if(i>=GetVectorLength()) i=GetVectorLength()-1;
201  return theData[i].GetY();
202  }
203 
204  inline G4double GetY(G4int i) const
205  {
206  if (i<0) i=0;
207  if(i>=GetVectorLength()) i=GetVectorLength()-1;
208  return theData[i].GetY();
209  }
210  void Dump();
211 
212  inline void InitInterpolation(std::istream & aDataFile)
213  {
214  theManager.Init(aDataFile);
215  }
216 
217  void Init(std::istream & aDataFile, G4int total, G4double ux=1., G4double uy=1.)
218  {
219  G4double x,y;
220  for (G4int i=0;i<total;i++)
221  {
222  aDataFile >> x >> y;
223  x*=ux;
224  y*=uy;
225  SetData(i,x,y);
226  if(0 == nEntries%10)
227  {
228  theHash.SetData(nEntries-1, x, y);
229  }
230  }
231  }
232 
233  void Init(std::istream & aDataFile,G4double ux=1., G4double uy=1.)
234  {
235  G4int total;
236  aDataFile >> total;
237  if(theData!=0) delete [] theData;
239  nPoints=total;
240  nEntries=0;
241  theManager.Init(aDataFile);
242  Init(aDataFile, total, ux, uy);
243  }
244 
245  void ThinOut(G4double precision);
246 
247  inline void SetLabel(G4double aLabel)
248  {
249  label = aLabel;
250  }
251 
253  {
254  return label;
255  }
256 
257  inline void CleanUp()
258  {
259  nEntries=0;
261  maxValue = -DBL_MAX;
262  theHash.Clear();
263 //080811 TK DB
264  delete[] theIntegral;
265  theIntegral = NULL;
266  }
267 
268  // merges the vectors active and passive into *this
270  {
271  CleanUp();
272  G4int s_tmp = 0, n=0, m_tmp=0;
273  G4NeutronHPVector * tmp;
274  G4int a = s_tmp, p = n, t;
275  while (a<active->GetVectorLength()&&p<passive->GetVectorLength())
276  {
277  if(active->GetEnergy(a) <= passive->GetEnergy(p))
278  {
279  G4double xa = active->GetEnergy(a);
280  G4double yy = active->GetXsec(a);
281  SetData(m_tmp, xa, yy);
282  theManager.AppendScheme(m_tmp, active->GetScheme(a));
283  m_tmp++;
284  a++;
285  G4double xp = passive->GetEnergy(p);
286 
287 //080409 TKDB
288  //if( std::abs(std::abs(xp-xa)/xa)<0.001 ) p++;
289  if ( !( xa == 0 ) && std::abs(std::abs(xp-xa)/xa)<0.001 ) p++;
290  } else {
291  tmp = active;
292  t=a;
293  active = passive;
294  a=p;
295  passive = tmp;
296  p=t;
297  }
298  }
299  while (a!=active->GetVectorLength())
300  {
301  SetData(m_tmp, active->GetEnergy(a), active->GetXsec(a));
302  theManager.AppendScheme(m_tmp++, active->GetScheme(a));
303  a++;
304  }
305  while (p!=passive->GetVectorLength())
306  {
307  if(std::abs(GetEnergy(m_tmp-1)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.001)
308  //if(std::abs(GetEnergy(m)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.001)
309  {
310  SetData(m_tmp, passive->GetEnergy(p), passive->GetXsec(p));
311  theManager.AppendScheme(m_tmp++, active->GetScheme(p));
312  }
313  p++;
314  }
315  }
316 
317  void Merge(G4InterpolationScheme aScheme, G4double aValue,
319 
320  G4double SampleLin() // Samples X according to distribution Y, linear int
321  {
322  G4double result;
324  if(GetVectorLength()==1)
325  {
326  result = theData[0].GetX();
327  }
328  else
329  {
330  G4int i;
331  G4double rand = G4UniformRand();
332 
333  // this was replaced
334 // for(i=1;i<GetVectorLength();i++)
335 // {
336 // if(rand<theIntegral[i]/theIntegral[GetVectorLength()-1]) break;
337 // }
338 
339 // by this (begin)
340  for(i=GetVectorLength()-1; i>=0 ;i--)
341  {
342  if(rand>theIntegral[i]/theIntegral[GetVectorLength()-1]) break;
343  }
344  if(i!=GetVectorLength()-1) i++;
345 // until this (end)
346 
347  G4double x1, x2, y1, y2;
348  y1 = theData[i-1].GetX();
349  x1 = theIntegral[i-1];
350  y2 = theData[i].GetX();
351  x2 = theIntegral[i];
352  if(std::abs((y2-y1)/y2)<0.0000001) // not really necessary, since the case is excluded by construction
353  {
354  y1 = theData[i-2].GetX();
355  x1 = theIntegral[i-2];
356  }
357  result = theLin.Lin(rand, x1, x2, y1, y2);
358  }
359  return result;
360  }
361 
362  G4double Sample(); // Samples X according to distribution Y
363 
365  {
366  return theIntegral;
367  }
368 
369  inline void IntegrateAndNormalise()
370  {
371  G4int i;
372  if(theIntegral!=0) return;
374  if(nEntries == 1)
375  {
376  theIntegral[0] = 1;
377  return;
378  }
379  theIntegral[0] = 0;
380  G4double sum = 0;
381  G4double x1 = 0;
382  G4double x0 = 0;
383  for(i=1;i<GetVectorLength();i++)
384  {
385  x1 = theData[i].GetX();
386  x0 = theData[i-1].GetX();
387  if (std::abs(x1-x0) > std::abs(x1*0.0000001) )
388  {
389  //********************************************************************
390  //EMendoza -> the interpolation scheme is not always lin-lin
391  /*
392  sum+= 0.5*(theData[i].GetY()+theData[i-1].GetY())*
393  (x1-x0);
394  */
395  //********************************************************************
397  G4double y0 = theData[i-1].GetY();
398  G4double y1 = theData[i].GetY();
399  G4double integ=theInt.GetBinIntegral(aScheme,x0,x1,y0,y1);
400 #if defined WIN32-VC
401  if(!_finite(integ)){integ=0;}
402 #elif defined __IBMCPP__
403  if(isinf(integ)||isnan(integ)){integ=0;}
404 #else
405  if(std::isinf(integ)||std::isnan(integ)){integ=0;}
406 #endif
407  sum+=integ;
408  //********************************************************************
409  }
410  theIntegral[i] = sum;
411  }
413  for(i=1;i<GetVectorLength();i++)
414  {
415  theIntegral[i]/=total;
416  }
417  }
418 
419  inline void Integrate()
420  {
421  G4int i;
422  if(nEntries == 1)
423  {
424  totalIntegral = 0;
425  return;
426  }
427  G4double sum = 0;
428  for(i=1;i<GetVectorLength();i++)
429  {
430  if(std::abs((theData[i].GetX()-theData[i-1].GetX())/theData[i].GetX())>0.0000001)
431  {
432  G4double x1 = theData[i-1].GetX();
433  G4double x2 = theData[i].GetX();
434  G4double y1 = theData[i-1].GetY();
435  G4double y2 = theData[i].GetY();
437  if(aScheme==LINLIN||aScheme==CLINLIN||aScheme==ULINLIN)
438  {
439  sum+= 0.5*(y2+y1)*(x2-x1);
440  }
441  else if(aScheme==LINLOG||aScheme==CLINLOG||aScheme==ULINLOG)
442  {
443  G4double a = y1;
444  G4double b = (y2-y1)/(std::log(x2)-std::log(x1));
445  sum+= (a-b)*(x2-x1) + b*(x2*std::log(x2)-x1*std::log(x1));
446  }
447  else if(aScheme==LOGLIN||aScheme==CLOGLIN||aScheme==ULOGLIN)
448  {
449  G4double a = std::log(y1);
450  G4double b = (std::log(y2)-std::log(y1))/(x2-x1);
451  sum += (std::exp(a)/b)*(std::exp(b*x2)-std::exp(b*x1));
452  }
453  else if(aScheme==HISTO||aScheme==CHISTO||aScheme==UHISTO)
454  {
455  sum+= y1*(x2-x1);
456  }
457  else if(aScheme==LOGLOG||aScheme==CLOGLOG||aScheme==ULOGLOG)
458  {
459  G4double a = std::log(y1);
460  G4double b = (std::log(y2)-std::log(y1))/(std::log(x2)-std::log(x1));
461  sum += (std::exp(a)/(b+1))*(std::pow(x2,b+1)-std::pow(x1,b+1));
462  }
463  else
464  {
465  throw G4HadronicException(__FILE__, __LINE__, "Unknown interpolation scheme in G4NeutronHPVector::Integrate");
466  }
467 
468  }
469  }
470  totalIntegral = sum;
471  }
472 
473  inline G4double GetIntegral() // linear interpolation; use with care
474  {
475  if(totalIntegral<-0.5) Integrate();
476  return totalIntegral;
477  }
478 
479  inline void SetInterpolationManager(const G4InterpolationManager & aManager)
480  {
481  theManager = aManager;
482  }
483 
485  {
486  return theManager;
487  }
488 
490  {
491  theManager = aMan;
492  }
493 
494  inline void SetScheme(G4int aPoint, const G4InterpolationScheme & aScheme)
495  {
496  theManager.AppendScheme(aPoint, aScheme);
497  }
498 
500  {
501  return theManager.GetScheme(anIndex);
502  }
503 
505  {
506  G4double result;
507  G4double running = 0;
508  G4double weighted = 0;
509  for(G4int i=1; i<nEntries; i++)
510  {
511  running += theInt.GetBinIntegral(theManager.GetScheme(i-1),
512  theData[i-1].GetX(), theData[i].GetX(),
513  theData[i-1].GetY(), theData[i].GetY());
515  theData[i-1].GetX(), theData[i].GetX(),
516  theData[i-1].GetY(), theData[i].GetY());
517  }
518  result = weighted / running;
519  return result;
520  }
521 
522 /*
523  void Block(G4double aX)
524  {
525  theBlocked.push_back(aX);
526  }
527 
528  void Buffer(G4double aX)
529  {
530  theBuffered.push_back(aX);
531  }
532 */
533 
534  std::vector<G4double> GetBlocked() {return theBlocked;}
535  std::vector<G4double> GetBuffered() {return theBuffered;}
536 
537 // void SetBlocked(const std::vector<G4double> &aBlocked) {theBlocked = aBlocked;}
538 // void SetBuffered(const std::vector<G4double> &aBuffer) {theBuffered = aBuffer;}
539 
542 
543  private:
544 
545  void Check(G4int i);
546 
548 
549  private:
550 
552 
553  private:
554 
556 
558  G4InterpolationManager theManager; // knows how to interpolate the data.
563 
566  // debug only
568 
571 
572  std::vector<G4double> theBlocked;
573  std::vector<G4double> theBuffered;
576 
577 };
578 
579 #endif
void SetEnergy(G4int i, G4double e)
G4double GetEnergy(G4int i) const
void SetLabel(G4double aLabel)
G4double Get50percentBorder()
G4double GetY(G4double x)
G4int GetVectorLength() const
void SetInterpolationManager(const G4InterpolationManager &aManager)
G4double GetY(G4int i)
void SetPoint(G4int i, const G4NeutronHPDataPoint &it)
void Init(G4int aScheme, G4int aRange)
void ThinOut(G4double precision)
void SetData(G4double e, G4double x)
G4NeutronHPHash theHash
void Merge(G4NeutronHPVector *active, G4NeutronHPVector *passive)
void Init(std::istream &aDataFile, G4int total, G4double ux=1., G4double uy=1.)
std::vector< G4double > theBlocked
void Times(G4double factor)
G4double GetX(G4int i) const
G4double a
Definition: TRTMaterials.hh:39
void SetData(G4int i, G4double x, G4double y)
G4NeutronHPInterpolator theInt
int G4int
Definition: G4Types.hh:78
G4double Interpolate(G4InterpolationScheme aScheme, G4double x, G4double x1, G4double x2, G4double y1, G4double y2) const
void InitInterpolation(std::istream &aDataFile)
G4bool IsBlocked(G4double aX)
void SetVerbose(G4int ff)
G4InterpolationScheme GetScheme(G4int anIndex)
void SetData(G4int index, G4double x, G4double y)
void AppendScheme(G4int aPoint, const G4InterpolationScheme &aScheme)
void SetY(G4int i, G4double x)
G4double GetWeightedBinIntegral(const G4InterpolationScheme &aScheme, const G4double x1, const G4double x2, const G4double y1, const G4double y2)
#define G4UniformRand()
Definition: Randomize.hh:95
G4double Get15percentBorder()
const G4InterpolationManager & GetInterpolationManager() const
bool G4bool
Definition: G4Types.hh:79
G4InterpolationScheme GetScheme(G4int index) const
G4double GetBinIntegral(const G4InterpolationScheme &aScheme, const G4double x1, const G4double x2, const G4double y1, const G4double y2)
G4double GetXsec(G4double e, G4int min)
friend G4NeutronHPVector & operator+(G4NeutronHPVector &left, G4NeutronHPVector &right)
void SetX(G4int i, G4double e)
const G4int n
G4InterpolationManager theManager
std::vector< G4double > GetBlocked()
void SetXsec(G4int i, G4double x)
void SetScheme(G4int aPoint, const G4InterpolationScheme &aScheme)
G4double GetY(G4int i) const
std::vector< G4double > GetBuffered()
static const G4double factor
G4InterpolationScheme
G4double total(Particle const *const p1, Particle const *const p2)
G4double GetXsec(G4int i)
const G4NeutronHPDataPoint & GetPoint(G4int i) const
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4NeutronHPInterpolator theLin
G4double Lin(G4double x, G4double x1, G4double x2, G4double y1, G4double y2)
double G4double
Definition: G4Types.hh:76
std::vector< G4double > theBuffered
G4NeutronHPVector & operator=(const G4NeutronHPVector &right)
#define DBL_MAX
Definition: templates.hh:83
void Init(std::istream &aDataFile, G4double ux=1., G4double uy=1.)
G4NeutronHPDataPoint * theData
void SetInterpolationManager(G4InterpolationManager &aMan)