source: trunk/source/processes/hadronic/models/neutron_hp/include/G4NeutronHPVector.hh @ 1337

Last change on this file since 1337 was 962, checked in by garnier, 15 years ago

update processes

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