Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ParticleHPVector.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//
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"
39#include "G4Log.hh"
41#include "G4ParticleHPHash.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
57{
59
60 public:
62
64
66
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
149 {
150 G4int i;
151 for (i = min; i < nEntries; i++) {
152 if (theData[i].GetX() > e) break;
153 }
154 G4int low = i - 1;
155 G4int high = i;
156 if (i == 0) {
157 low = 0;
158 high = 1;
159 }
160 else if (i == nEntries) {
161 low = nEntries - 2;
162 high = nEntries - 1;
163 }
164 G4double y;
165 if (e < theData[nEntries - 1].GetX()) {
166 // Protect against doubled-up x values
167 if ((theData[high].GetX() - theData[low].GetX()) / theData[high].GetX() < 0.000001) {
168 y = theData[low].GetY();
169 }
170 else {
171 y = theInt.Interpolate(theManager.GetScheme(high), e, theData[low].GetX(),
172 theData[high].GetX(), theData[low].GetY(), theData[high].GetY());
173 }
174 }
175 else {
176 y = theData[nEntries - 1].GetY();
177 }
178 return y;
179 }
180
181 inline G4double GetY(G4double x) { return GetXsec(x); }
182 inline G4int GetVectorLength() const { return nEntries; }
183
185 {
186 if (i < 0) i = 0;
187 if (i >= GetVectorLength()) i = GetVectorLength() - 1;
188 return theData[i].GetY();
189 }
190
191 inline G4double GetY(G4int i) const
192 {
193 if (i < 0) i = 0;
194 if (i >= GetVectorLength()) i = GetVectorLength() - 1;
195 return theData[i].GetY();
196 }
197 void Dump();
198
199 inline void InitInterpolation(std::istream& aDataFile) { theManager.Init(aDataFile); }
200
201 void Init(std::istream& aDataFile, G4int total, G4double ux = 1., G4double uy = 1.)
202 {
203 G4double x, y;
204 for (G4int i = 0; i < total; i++) {
205 aDataFile >> x >> y;
206 x *= ux;
207 y *= uy;
208 SetData(i, x, y);
209 if (0 == nEntries % 10) {
210 theHash.SetData(nEntries - 1, x, y);
211 }
212 }
213 }
214
215 void Init(std::istream& aDataFile, G4double ux = 1., G4double uy = 1.)
216 {
217 G4int total;
218 aDataFile >> total;
219 delete[] theData;
220 theData = new G4ParticleHPDataPoint[total];
221 nPoints = total;
222 nEntries = 0;
223 theManager.Init(aDataFile);
224 Init(aDataFile, total, ux, uy);
225 }
226
227 void ThinOut(G4double precision);
228
229 inline void SetLabel(G4double aLabel) { label = aLabel; }
230
231 inline G4double GetLabel() { return label; }
232
233 inline void CleanUp()
234 {
235 nEntries = 0;
236 theManager.CleanUp();
237 maxValue = -DBL_MAX;
238 theHash.Clear();
239 // 080811 TK DB
240 delete[] theIntegral;
241 theIntegral = nullptr;
242 }
243
244 // merges the vectors active and passive into *this
245 inline void Merge(G4ParticleHPVector* active, G4ParticleHPVector* passive)
246 {
247 CleanUp();
248 G4int s_tmp = 0, n = 0, m_tmp = 0;
250 G4int a = s_tmp, p = n, t;
251 while (a < active->GetVectorLength()
252 && p < passive->GetVectorLength()) // Loop checking, 11.05.2015, T. Koi
253 {
254 if (active->GetEnergy(a) <= passive->GetEnergy(p)) {
255 G4double xa = active->GetEnergy(a);
256 G4double yy = active->GetXsec(a);
257 SetData(m_tmp, xa, yy);
258 theManager.AppendScheme(m_tmp, active->GetScheme(a));
259 m_tmp++;
260 a++;
261 G4double xp = passive->GetEnergy(p);
262
263 // 080409 TKDB
264 // if( std::abs(std::abs(xp-xa)/xa)<0.001 ) p++;
265 if (!(xa == 0) && std::abs(std::abs(xp - xa) / xa) < 0.001) p++;
266 }
267 else {
268 tmp = active;
269 t = a;
270 active = passive;
271 a = p;
272 passive = tmp;
273 p = t;
274 }
275 }
276 while (a != active->GetVectorLength()) // Loop checking, 11.05.2015, T. Koi
277 {
278 SetData(m_tmp, active->GetEnergy(a), active->GetXsec(a));
279 theManager.AppendScheme(m_tmp++, active->GetScheme(a));
280 a++;
281 }
282 while (p != passive->GetVectorLength()) // Loop checking, 11.05.2015, T. Koi
283 {
284 if (std::abs(GetEnergy(m_tmp - 1) - passive->GetEnergy(p)) / passive->GetEnergy(p) > 0.001)
285 // if(std::abs(GetEnergy(m)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.001)
286 {
287 SetData(m_tmp, passive->GetEnergy(p), passive->GetXsec(p));
288 theManager.AppendScheme(m_tmp++, active->GetScheme(p));
289 }
290 p++;
291 }
292 }
293
294 void Merge(G4InterpolationScheme aScheme, G4double aValue, G4ParticleHPVector* active,
295 G4ParticleHPVector* passive);
296
297 G4double SampleLin() // Samples X according to distribution Y, linear int
298 {
299 G4double result;
300 if (theIntegral == nullptr) IntegrateAndNormalise();
301 if (GetVectorLength() == 1) {
302 result = theData[0].GetX();
303 }
304 else {
305 G4int i;
306 G4double rand = G4UniformRand();
307
308 // this was replaced
309 // for(i=1;i<GetVectorLength();i++)
310 // {
311 // if(rand<theIntegral[i]/theIntegral[GetVectorLength()-1]) break;
312 // }
313
314 // by this (begin)
315 for (i = GetVectorLength() - 1; i >= 0; i--) {
316 if (rand > theIntegral[i] / theIntegral[GetVectorLength() - 1]) break;
317 }
318 if (i != GetVectorLength() - 1) i++;
319 // until this (end)
320
321 G4double x1, x2, y1, y2;
322 y1 = theData[i - 1].GetX();
323 x1 = theIntegral[i - 1];
324 y2 = theData[i].GetX();
325 x2 = theIntegral[i];
326 if (std::abs((y2 - y1) / y2)
327 < 0.0000001) // not really necessary, since the case is excluded by construction
328 {
329 y1 = theData[i - 2].GetX();
330 x1 = theIntegral[i - 2];
331 }
332 result = theLin.Lin(rand, x1, x2, y1, y2);
333 }
334 return result;
335 }
336
337 G4double Sample(); // Samples X according to distribution Y
338
339 G4double* Debug() { return theIntegral; }
340
342 {
343 G4int i;
344 if (theIntegral != nullptr) return;
345 theIntegral = new G4double[nEntries];
346 if (nEntries == 1) {
347 theIntegral[0] = 1;
348 return;
349 }
350 theIntegral[0] = 0;
351 G4double sum = 0;
352 G4double x1 = 0;
353 G4double x0 = 0;
354 for (i = 1; i < GetVectorLength(); i++) {
355 x1 = theData[i].GetX();
356 x0 = theData[i - 1].GetX();
357 if (std::abs(x1 - x0) > std::abs(x1 * 0.0000001)) {
358 //********************************************************************
359 // EMendoza -> the interpolation scheme is not always lin-lin
360 /*
361 sum+= 0.5*(theData[i].GetY()+theData[i-1].GetY())*
362 (x1-x0);
363 */
364 //********************************************************************
365 G4InterpolationScheme aScheme = theManager.GetScheme(i);
366 G4double y0 = theData[i - 1].GetY();
367 G4double y1 = theData[i].GetY();
368 G4double integ = theInt.GetBinIntegral(aScheme, x0, x1, y0, y1);
369#if defined WIN32 - VC
370 if (!_finite(integ)) {
371 integ = 0;
372 }
373#elif defined __IBMCPP__
374 if (isinf(integ) || isnan(integ)) {
375 integ = 0;
376 }
377#else
378 if (std::isinf(integ) || std::isnan(integ)) {
379 integ = 0;
380 }
381#endif
382 sum += integ;
383 //********************************************************************
384 }
385 theIntegral[i] = sum;
386 }
387 G4double total = theIntegral[GetVectorLength() - 1];
388 for (i = 1; i < GetVectorLength(); i++) {
389 theIntegral[i] /= total;
390 }
391 }
392
393 inline void Integrate()
394 {
395 G4int i;
396 if (nEntries == 1) {
397 totalIntegral = 0;
398 return;
399 }
400 G4double sum = 0;
401 for (i = 1; i < GetVectorLength(); i++) {
402 if (std::abs((theData[i].GetX() - theData[i - 1].GetX()) / theData[i].GetX()) > 0.0000001) {
403 G4double x1 = theData[i - 1].GetX();
404 G4double x2 = theData[i].GetX();
405 G4double y1 = theData[i - 1].GetY();
406 G4double y2 = theData[i].GetY();
407 G4InterpolationScheme aScheme = theManager.GetScheme(i);
408 if (aScheme == LINLIN || aScheme == CLINLIN || aScheme == ULINLIN) {
409 sum += 0.5 * (y2 + y1) * (x2 - x1);
410 }
411 else if (aScheme == LINLOG || aScheme == CLINLOG || aScheme == ULINLOG) {
412 G4double a = y1;
413 G4double b = (y2 - y1) / (G4Log(x2) - G4Log(x1));
414 sum += (a - b) * (x2 - x1) + b * (x2 * G4Log(x2) - x1 * G4Log(x1));
415 }
416 else if (aScheme == LOGLIN || aScheme == CLOGLIN || aScheme == ULOGLIN) {
417 G4double a = G4Log(y1);
418 G4double b = (G4Log(y2) - G4Log(y1)) / (x2 - x1);
419 sum += (G4Exp(a) / b) * (G4Exp(b * x2) - G4Exp(b * x1));
420 }
421 else if (aScheme == HISTO || aScheme == CHISTO || aScheme == UHISTO) {
422 sum += y1 * (x2 - x1);
423 }
424 else if (aScheme == LOGLOG || aScheme == CLOGLOG || aScheme == ULOGLOG) {
425 G4double a = G4Log(y1);
426 G4double b = (G4Log(y2) - G4Log(y1)) / (G4Log(x2) - G4Log(x1));
427 sum +=
428 (G4Exp(a) / (b + 1))
429 * (G4Pow::GetInstance()->powA(x2, b + 1) - G4Pow::GetInstance()->powA(x1, b + 1));
430 }
431 else {
433 __FILE__, __LINE__, "Unknown interpolation scheme in G4ParticleHPVector::Integrate");
434 }
435 }
436 }
437 totalIntegral = sum;
438 }
439
440 inline G4double GetIntegral() // linear interpolation; use with care
441 {
442 if (totalIntegral < -0.5) Integrate();
443 return totalIntegral;
444 }
445
447 {
448 theManager = aManager;
449 }
450
451 inline const G4InterpolationManager& GetInterpolationManager() const { return theManager; }
452
453 inline void SetInterpolationManager(G4InterpolationManager& aMan) { theManager = aMan; }
454
455 inline void SetScheme(G4int aPoint, const G4InterpolationScheme& aScheme)
456 {
457 theManager.AppendScheme(aPoint, aScheme);
458 }
459
460 inline G4InterpolationScheme GetScheme(G4int anIndex) { return theManager.GetScheme(anIndex); }
461
463 {
464 G4double result;
465 G4double running = 0;
466 G4double weighted = 0;
467 for (G4int i = 1; i < nEntries; i++) {
468 running +=
469 theInt.GetBinIntegral(theManager.GetScheme(i - 1), theData[i - 1].GetX(),
470 theData[i].GetX(), theData[i - 1].GetY(), theData[i].GetY());
471 weighted += theInt.GetWeightedBinIntegral(theManager.GetScheme(i - 1),
472 theData[i - 1].GetX(), theData[i].GetX(),
473 theData[i - 1].GetY(), theData[i].GetY());
474 }
475 result = weighted / running;
476 return result;
477 }
478
479 // Finds maximum cross section between two values of kinetic energy
480 G4double GetMaxY(G4double emin, G4double emax);
481
482 /*
483 void Block(G4double aX)
484 {
485 theBlocked.push_back(aX);
486 }
487
488 void Buffer(G4double aX)
489 {
490 theBuffered.push_back(aX);
491 }
492 */
493
494 std::vector<G4double> GetBlocked() { return theBlocked; }
495 std::vector<G4double> GetBuffered() { return theBuffered; }
496
497 // void SetBlocked(const std::vector<G4double> &aBlocked) {theBlocked = aBlocked;}
498 // void SetBuffered(const std::vector<G4double> &aBuffer) {theBuffered = aBuffer;}
499
502
503 private:
504 void Check(G4int i);
505
506 G4bool IsBlocked(G4double aX);
507
508 private:
510
511 private:
512 G4double totalIntegral;
513
514 G4ParticleHPDataPoint* theData; // the data
515 G4InterpolationManager theManager; // knows how to interpolate the data.
516 G4double* theIntegral;
517 G4int nEntries;
518 G4int nPoints;
519 G4double label;
520
522 G4int Verbose;
523 // debug only
524 G4int isFreed;
525
526 G4ParticleHPHash theHash;
527 G4double maxValue;
528
529 std::vector<G4double> theBlocked;
530 std::vector<G4double> theBuffered;
531 G4double the15percentBorderCash;
532 G4double the50percentBorderCash;
533};
534
535#endif
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
Definition G4Exp.hh:180
G4InterpolationScheme
G4double G4Log(G4double x)
Definition G4Log.hh:227
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4UniformRand()
Definition Randomize.hh:52
void AppendScheme(G4int aPoint, const G4InterpolationScheme &aScheme)
void Init(G4int aScheme, G4int aRange)
G4InterpolationScheme GetScheme(G4int index) const
void SetData(G4double e, G4double x)
void SetData(G4int index, G4double x, G4double y)
G4double Interpolate(G4InterpolationScheme aScheme, G4double x, G4double x1, G4double x2, G4double y1, G4double y2) const
G4double GetWeightedBinIntegral(const G4InterpolationScheme &aScheme, const G4double x1, const G4double x2, const G4double y1, const G4double y2)
G4double Lin(G4double x, G4double x1, G4double x2, G4double y1, G4double y2)
G4double GetBinIntegral(const G4InterpolationScheme &aScheme, const G4double x1, const G4double x2, const G4double y1, const G4double y2)
G4InterpolationScheme GetScheme(G4int anIndex)
void SetY(G4int i, G4double x)
G4ParticleHPVector & operator=(const G4ParticleHPVector &right)
const G4ParticleHPDataPoint & GetPoint(G4int i) const
void SetX(G4int i, G4double e)
void SetScheme(G4int aPoint, const G4InterpolationScheme &aScheme)
void SetData(G4int i, G4double x, G4double y)
void Times(G4double factor)
friend G4ParticleHPVector & operator+(G4ParticleHPVector &left, G4ParticleHPVector &right)
G4double GetXsec(G4int i)
const G4InterpolationManager & GetInterpolationManager() const
std::vector< G4double > GetBuffered()
G4double GetMaxY(G4double emin, G4double emax)
G4double GetXsec(G4double e, G4int min)
void ThinOut(G4double precision)
G4double GetY(G4int i) const
void SetXsec(G4int i, G4double x)
void SetLabel(G4double aLabel)
G4double GetY(G4int i)
void SetInterpolationManager(const G4InterpolationManager &aManager)
void Init(std::istream &aDataFile, G4double ux=1., G4double uy=1.)
G4double GetY(G4double x)
G4double GetEnergy(G4int i) const
G4double GetX(G4int i) const
void Merge(G4ParticleHPVector *active, G4ParticleHPVector *passive)
void SetEnergy(G4int i, G4double e)
void Init(std::istream &aDataFile, G4int total, G4double ux=1., G4double uy=1.)
G4int GetVectorLength() const
std::vector< G4double > GetBlocked()
void SetPoint(G4int i, const G4ParticleHPDataPoint &it)
void SetVerbose(G4int ff)
void InitInterpolation(std::istream &aDataFile)
void SetInterpolationManager(G4InterpolationManager &aMan)
static G4Pow * GetInstance()
Definition G4Pow.cc:41
G4double powA(G4double A, G4double y) const
Definition G4Pow.hh:230
#define DBL_MAX
Definition templates.hh:62