source: trunk/source/processes/hadronic/models/neutron_hp/src/G4NeutronHPVector.cc @ 847

Last change on this file since 847 was 819, checked in by garnier, 16 years ago

import all except CVS

File size: 12.9 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// 070523 bug fix for G4FPE_DEBUG on by A. Howard ( and T. Koi)
31//
32#include "G4NeutronHPVector.hh"
33 
34  // if the ranges do not match, constant extrapolation is used.
35  G4NeutronHPVector & operator + (G4NeutronHPVector & left, G4NeutronHPVector & right)
36  {
37    G4NeutronHPVector * result = new G4NeutronHPVector;
38    G4int j=0;
39    G4double x;
40    G4double y;
41    G4int running = 0;
42    for(G4int i=0; i<left.GetVectorLength(); i++)
43    {
44      while(j<right.GetVectorLength())
45      {
46        if(right.GetX(j)<left.GetX(i)*1.001)
47        {
48          x = right.GetX(j);
49          y = right.GetY(j)+left.GetY(x);
50          result->SetData(running++, x, y);
51          j++;
52        }
53        //else if(std::abs((right.GetX(j)-left.GetX(i))/(left.GetX(i)+right.GetX(j)))>0.001)
54        else if( left.GetX(i)+right.GetX(j) == 0 
55              || std::abs((right.GetX(j)-left.GetX(i))/(left.GetX(i)+right.GetX(j))) > 0.001 )
56        {
57          x = left.GetX(i);
58          y = left.GetY(i)+right.GetY(x);
59          result->SetData(running++, x, y);
60          break;
61        }
62        else
63        {
64          break;
65        }
66      }
67      if(j==right.GetVectorLength())
68      {
69        x = left.GetX(i);
70        y = left.GetY(i)+right.GetY(x);
71        result->SetData(running++, x, y);     
72      }
73    }
74    result->ThinOut(0.02);
75    return *result;
76  }
77
78  G4NeutronHPVector::G4NeutronHPVector()
79  {
80    theData = new G4NeutronHPDataPoint[20]; 
81    nPoints=20;
82    nEntries=0;
83    Verbose=0;
84    theIntegral=0;
85    totalIntegral=-1;
86    isFreed = 0;
87    maxValue = -DBL_MAX;
88    the15percentBorderCash = -DBL_MAX;
89    the50percentBorderCash = -DBL_MAX;
90    label = -DBL_MAX;
91
92  }
93 
94  G4NeutronHPVector::G4NeutronHPVector(G4int n)
95  {
96    nPoints=std::max(n, 20);
97    theData = new G4NeutronHPDataPoint[nPoints]; 
98    nEntries=0;
99    Verbose=0;
100    theIntegral=0;
101    totalIntegral=-1;
102    isFreed = 0;
103    maxValue = -DBL_MAX;
104    the15percentBorderCash = -DBL_MAX;
105    the50percentBorderCash = -DBL_MAX;
106  }
107
108  G4NeutronHPVector::~G4NeutronHPVector()
109  {
110//    if(Verbose==1)G4cout <<"G4NeutronHPVector::~G4NeutronHPVector"<<G4endl;
111      delete [] theData;
112//    if(Verbose==1)G4cout <<"Vector: delete theData"<<G4endl;
113      delete [] theIntegral;
114//    if(Verbose==1)G4cout <<"Vector: delete theIntegral"<<G4endl;
115    isFreed = 1;
116  }
117 
118  G4NeutronHPVector & G4NeutronHPVector:: 
119  operator = (const G4NeutronHPVector & right)
120  {
121    if(&right == this) return *this;
122   
123    G4int i;
124   
125    totalIntegral = right.totalIntegral;
126    if(right.theIntegral!=0) theIntegral = new G4double[right.nEntries];
127    for(i=0; i<right.nEntries; i++)
128    {
129      SetPoint(i, right.GetPoint(i)); // copy theData
130      if(right.theIntegral!=0) theIntegral[i] = right.theIntegral[i];
131    }
132    theManager = right.theManager; 
133    label = right.label;
134 
135    Verbose = right.Verbose;
136    the15percentBorderCash = right.the15percentBorderCash;
137    the50percentBorderCash = right.the50percentBorderCash;
138    theHash = right.theHash;
139   return *this;
140  }
141
142 
143  G4double G4NeutronHPVector::GetXsec(G4double e) 
144  {
145    if(nEntries == 0) return 0;
146    if(!theHash.Prepared()) Hash();
147    G4int min = theHash.GetMinIndex(e);
148    G4int i;
149    for(i=min ; i<nEntries; i++)
150    {
151      //if(theData[i].GetX()>e) break;
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      if ( theData[high].GetX() !=0 
172       &&( theData[high].GetX()-theData[low].GetX())/theData[high].GetX() < 0.000001)
173      {
174        y = theData[low].GetY();
175      }
176      else
177      {
178        y = theInt.Interpolate(theManager.GetScheme(high), e, 
179                               theData[low].GetX(), theData[high].GetX(),
180                               theData[low].GetY(), theData[high].GetY());
181      }
182    }
183    else
184    {
185      y=theData[nEntries-1].GetY();
186    }
187    return y;
188  }
189
190  void G4NeutronHPVector::Dump()
191  {
192    G4cout << nEntries<<G4endl;
193    for(G4int i=0; i<nEntries; i++)
194    {
195      G4cout << theData[i].GetX()<<" ";
196      G4cout << theData[i].GetY()<<" ";
197//      if (i!=1&&i==5*(i/5)) G4cout << G4endl;
198      G4cout << G4endl;
199    }
200    G4cout << G4endl;
201  }
202 
203  void G4NeutronHPVector::Check(G4int i)
204  {
205    if(i>nEntries) throw G4HadronicException(__FILE__, __LINE__, "Skipped some index numbers in G4NeutronHPVector");
206    if(i==nPoints)
207    {
208      nPoints = static_cast<G4int>(1.2*nPoints);
209      G4NeutronHPDataPoint * buff = new G4NeutronHPDataPoint[nPoints];
210      for (G4int j=0; j<nEntries; j++) buff[j] = theData[j];
211      delete [] theData;
212      theData = buff;
213    }
214    if(i==nEntries) nEntries=i+1;
215  }
216
217  void G4NeutronHPVector::
218  Merge(G4InterpolationScheme aScheme, G4double aValue, 
219        G4NeutronHPVector * active, G4NeutronHPVector * passive)
220  { 
221    // interpolate between labels according to aScheme, cut at aValue,
222    // continue in unknown areas by substraction of the last difference.
223   
224    CleanUp();
225    G4int s = 0, n=0, m=0;
226    G4NeutronHPVector * tmp;
227    G4int a = s, p = n, t;
228    while ( a<active->GetVectorLength() )
229    {
230      if(active->GetEnergy(a) <= passive->GetEnergy(p))
231      {
232        G4double xa  = active->GetEnergy(a);
233        G4double yy = theInt.Interpolate(aScheme, aValue, active->GetLabel(), passive->GetLabel(),
234                                                          active->GetXsec(a), passive->GetXsec(xa));
235        SetData(m, xa, yy);
236        theManager.AppendScheme(m, active->GetScheme(a));
237        m++;
238        a++;
239        G4double xp = passive->GetEnergy(p);
240        //if( std::abs(std::abs(xp-xa)/xa)<0.0000001&&a<active->GetVectorLength() )
241        if ( xa != 0 
242          && std::abs(std::abs(xp-xa)/xa) < 0.0000001 
243          && a < active->GetVectorLength() )
244        {
245          p++;
246          tmp = active; t=a;
247          active = passive; a=p;
248          passive = tmp; p=t;
249        }
250      } else {
251        tmp = active; t=a;
252        active = passive; a=p;
253        passive = tmp; p=t;
254      }
255    }
256   
257    G4double deltaX = passive->GetXsec(GetEnergy(m-1)) - GetXsec(m-1);
258    while (p!=passive->GetVectorLength()&&passive->GetEnergy(p)<=aValue)
259    {
260      G4double anX;
261      anX = passive->GetXsec(p)-deltaX;
262      if(anX>0)
263      {
264        //if(std::abs(GetEnergy(m-1)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.0000001)
265        if ( passive->GetEnergy(p) == 0 
266          || std::abs(GetEnergy(m-1)-passive->GetEnergy(p))/passive->GetEnergy(p) > 0.0000001 )
267        {
268          SetData(m, passive->GetEnergy(p), anX);
269          theManager.AppendScheme(m++, passive->GetScheme(p));
270        }
271      }
272      p++;
273    }
274    // Rebuild the Hash;
275    if(theHash.Prepared()) 
276    {
277      ReHash();
278    }
279  }
280   
281  void G4NeutronHPVector::ThinOut(G4double precision)
282  {
283    // anything in there?
284    if(GetVectorLength()==0) return;
285    // make the new vector
286    G4NeutronHPDataPoint * aBuff = new G4NeutronHPDataPoint[nPoints];
287    G4double x, x1, x2, y, y1, y2;
288    G4int count = 0, current = 2, start = 1;
289   
290    // First element always goes and is never tested.
291    aBuff[0] = theData[0];
292   
293    // Find the rest
294    while(current < GetVectorLength())
295    {
296      x1=aBuff[count].GetX();
297      y1=aBuff[count].GetY();
298      x2=theData[current].GetX();
299      y2=theData[current].GetY();
300      for(G4int j=start; j<current; j++)
301      {
302        x = theData[j].GetX();
303        if(x1-x2 == 0) y = (y2+y1)/2.;
304        else y = theInt.Lin(x, x1, x2, y1, y2);
305        if (std::abs(y-theData[j].GetY())>precision*y)
306        {
307          aBuff[++count] = theData[current-1]; // for this one, everything was fine
308          start = current; // the next candidate
309          break;
310        }
311      }
312      current++ ;
313    }
314    // The last one also always goes, and is never tested.
315    aBuff[++count] = theData[GetVectorLength()-1];
316    delete [] theData;
317    theData = aBuff;
318    nEntries = count+1;
319   
320    // Rebuild the Hash;
321    if(theHash.Prepared()) 
322    {
323      ReHash();
324    }
325  }
326
327  G4bool G4NeutronHPVector::IsBlocked(G4double aX)
328  {
329    G4bool result = false;
330    std::vector<G4double>::iterator i;
331    for(i=theBlocked.begin(); i!=theBlocked.end(); i++)
332    {
333      G4double aBlock = *i;
334      if(std::abs(aX-aBlock) < 0.1*MeV)
335      {
336        result = true;
337        theBlocked.erase(i);
338        break;
339      }
340    }
341    return result;
342  }
343
344  G4double G4NeutronHPVector::Sample() // Samples X according to distribution Y
345  {
346    G4double result;
347    G4int j;
348    for(j=0; j<GetVectorLength(); j++)
349    {
350      if(GetY(j)<0) SetY(j, 0);
351    }
352   
353    if(theBuffered.size() !=0 && G4UniformRand()<0.5) 
354    {
355      result = theBuffered[0];
356      theBuffered.erase(theBuffered.begin());
357      if(result < GetX(GetVectorLength()-1) ) return result;
358    }
359    if(GetVectorLength()==1)
360    {
361      result = theData[0].GetX();
362    }
363    else
364    {
365      if(theIntegral==0) { IntegrateAndNormalise(); }
366      do
367      {
368        G4double value, test, baseline;
369        baseline = theData[GetVectorLength()-1].GetX()-theData[0].GetX();
370        G4double rand;
371        do
372        {
373          value = baseline*G4UniformRand();
374          value += theData[0].GetX();
375          test = GetY(value)/maxValue;
376          rand = G4UniformRand();
377        }
378        //while(test<rand);
379        while( test < rand && test > 0 );
380        result = value;
381      }
382      while(IsBlocked(result));
383    }
384    return result;
385  }
386
387  G4double G4NeutronHPVector::Get15percentBorder()
388  {   
389    if(the15percentBorderCash>-DBL_MAX/2.) return the15percentBorderCash;
390    G4double result;
391    if(GetVectorLength()==1)
392    {
393      result = theData[0].GetX();
394      the15percentBorderCash = result;
395    }
396    else
397    {
398      if(theIntegral==0) { IntegrateAndNormalise(); }
399      G4int i;
400      result = theData[GetVectorLength()-1].GetX();
401      for(i=0;i<GetVectorLength();i++)
402      {
403        if(theIntegral[i]/theIntegral[GetVectorLength()-1]>0.15) 
404        {
405          result = theData[std::min(i+1, GetVectorLength()-1)].GetX();
406          the15percentBorderCash = result;
407          break;
408        }
409      }
410      the15percentBorderCash = result;
411    }
412    return result;
413  }
414
415  G4double G4NeutronHPVector::Get50percentBorder()
416  {   
417    if(the50percentBorderCash>-DBL_MAX/2.) return the50percentBorderCash;
418    G4double result;
419    if(GetVectorLength()==1)
420    {
421      result = theData[0].GetX();
422      the50percentBorderCash = result;
423    }
424    else
425    {
426      if(theIntegral==0) { IntegrateAndNormalise(); }
427      G4int i;
428      G4double x = 0.5;
429      result = theData[GetVectorLength()-1].GetX();
430      for(i=0;i<GetVectorLength();i++)
431      {
432        if(theIntegral[i]/theIntegral[GetVectorLength()-1]>x) 
433        {
434          G4int it;
435          it = i;
436          if(it == GetVectorLength()-1)
437          {
438            result = theData[GetVectorLength()-1].GetX();
439          }
440          else
441          {
442            G4double x1, x2, y1, y2;
443            x1 = theIntegral[i-1]/theIntegral[GetVectorLength()-1];
444            x2 = theIntegral[i]/theIntegral[GetVectorLength()-1];
445            y1 = theData[i-1].GetX();
446            y2 = theData[i].GetX();
447            result = theLin.Lin(x, x1, x2, y1, y2);
448          }
449          the50percentBorderCash = result;
450          break;
451        }
452      }
453      the50percentBorderCash = result;
454    }
455    return result;
456  }
Note: See TracBrowser for help on using the repository browser.