Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/particle_hp/include/G4ParticleHPVector.hh

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