Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ParticleHPVector.cc
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// 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// 080808 bug fix in Sample() and GetXsec() by T. Koi
32//
33// P. Arce, June-2014 Conversion neutron_hp to particle_hp
34//
35#include "G4ParticleHPVector.hh"
36
37#include "G4SystemOfUnits.hh"
38#include "G4Threading.hh"
39
40// if the ranges do not match, constant extrapolation is used.
42{
43 auto result = new G4ParticleHPVector;
44 G4int j = 0;
45 G4double x;
46 G4double y;
47 G4int running = 0;
48 for (G4int i = 0; i < left.GetVectorLength(); i++) {
49 while (j < right.GetVectorLength()) // Loop checking, 11.05.2015, T. Koi
50 {
51 if (right.GetX(j) < left.GetX(i) * 1.001) {
52 x = right.GetX(j);
53 y = right.GetY(j) + left.GetY(x);
54 result->SetData(running++, x, y);
55 j++;
56 }
57 // else if(std::abs((right.GetX(j)-left.GetX(i))/(left.GetX(i)+right.GetX(j)))>0.001)
58 else if (left.GetX(i) + right.GetX(j) == 0
59 || std::abs((right.GetX(j) - left.GetX(i)) / (left.GetX(i) + right.GetX(j))) > 0.001)
60 {
61 x = left.GetX(i);
62 y = left.GetY(i) + right.GetY(x);
63 result->SetData(running++, x, y);
64 break;
65 }
66 else {
67 break;
68 }
69 }
70 if (j == right.GetVectorLength()) {
71 x = left.GetX(i);
72 y = left.GetY(i) + right.GetY(x);
73 result->SetData(running++, x, y);
74 }
75 }
76 result->ThinOut(0.02);
77 return *result;
78}
79
81{
82 theData = new G4ParticleHPDataPoint[20];
83 nPoints = 20;
84 nEntries = 0;
85 Verbose = 0;
86 theIntegral = nullptr;
87 totalIntegral = -1;
88 isFreed = 0;
89 maxValue = -DBL_MAX;
90 the15percentBorderCash = -DBL_MAX;
91 the50percentBorderCash = -DBL_MAX;
92 label = -DBL_MAX;
93}
94
96{
97 nPoints = std::max(n, 20);
98 theData = new G4ParticleHPDataPoint[nPoints];
99 nEntries = 0;
100 Verbose = 0;
101 theIntegral = nullptr;
102 totalIntegral = -1;
103 isFreed = 0;
104 maxValue = -DBL_MAX;
105 the15percentBorderCash = -DBL_MAX;
106 the50percentBorderCash = -DBL_MAX;
107 label = -DBL_MAX;
108}
109
111{
112 // if(Verbose==1)G4cout <<"G4ParticleHPVector::~G4ParticleHPVector"<<G4endl;
113 delete[] theData;
114 // if(Verbose==1)G4cout <<"Vector: delete theData"<<G4endl;
115 delete[] theIntegral;
116 // if(Verbose==1)G4cout <<"Vector: delete theIntegral"<<G4endl;
117 theHash.Clear();
118 isFreed = 1;
119}
120
122{
123 if (&right == this) return *this;
124
125 G4int i;
126
127 totalIntegral = right.totalIntegral;
128 if (right.theIntegral != nullptr) theIntegral = new G4double[right.nEntries];
129 for (i = 0; i < right.nEntries; i++) {
130 SetPoint(i, right.GetPoint(i)); // copy theData
131 if (right.theIntegral != nullptr) theIntegral[i] = right.theIntegral[i];
132 }
133 theManager = right.theManager;
134 label = right.label;
135
136 Verbose = right.Verbose;
137 the15percentBorderCash = right.the15percentBorderCash;
138 the50percentBorderCash = right.the50percentBorderCash;
139 theHash = right.theHash;
140 return *this;
141}
142
144{
145 if (nEntries == 0) return 0;
146 // if(!theHash.Prepared()) Hash();
147 if (!theHash.Prepared()) {
149 ;
150 }
151 else {
152 Hash();
153 }
154 }
155 G4int min = theHash.GetMinIndex(e);
156 G4int i;
157 for (i = min; i < nEntries; i++) {
158 // if(theData[i].GetX()>e) break;
159 if (theData[i].GetX() >= e) break;
160 }
161 G4int low = i - 1;
162 G4int high = i;
163 if (i == 0) {
164 low = 0;
165 high = 1;
166 }
167 else if (i == nEntries) {
168 low = nEntries - 2;
169 high = nEntries - 1;
170 }
171 G4double y;
172 if (e < theData[nEntries - 1].GetX()) {
173 // Protect against doubled-up x values
174 // if( (theData[high].GetX()-theData[low].GetX())/theData[high].GetX() < 0.000001)
175 if (theData[high].GetX() != 0
176 // 080808 TKDB
177 //&&( theData[high].GetX()-theData[low].GetX())/theData[high].GetX() < 0.000001)
178 && (std::abs((theData[high].GetX() - theData[low].GetX()) / theData[high].GetX())
179 < 0.000001))
180 {
181 y = theData[low].GetY();
182 }
183 else {
184 y = theInt.Interpolate(theManager.GetScheme(high), e, theData[low].GetX(),
185 theData[high].GetX(), theData[low].GetY(), theData[high].GetY());
186 }
187 }
188 else {
189 y = theData[nEntries - 1].GetY();
190 }
191 return y;
192}
193
195{
196 G4cout << nEntries << G4endl;
197 for (G4int i = 0; i < nEntries; i++) {
198 G4cout << theData[i].GetX() << " ";
199 G4cout << theData[i].GetY() << " ";
200 // if (i!=1&&i==5*(i/5)) G4cout << G4endl;
201 G4cout << G4endl;
202 }
203 G4cout << G4endl;
204}
205
206void G4ParticleHPVector::Check(G4int i)
207{
208 if (i > nEntries)
209 throw G4HadronicException(__FILE__, __LINE__,
210 "Skipped some index numbers in G4ParticleHPVector");
211 if (i == nPoints) {
212 nPoints = static_cast<G4int>(1.2 * nPoints);
213 auto buff = new G4ParticleHPDataPoint[nPoints];
214 for (G4int j = 0; j < nEntries; j++)
215 buff[j] = theData[j];
216 delete[] theData;
217 theData = buff;
218 }
219 if (i == nEntries) nEntries = i + 1;
220}
221
223 G4ParticleHPVector* active, G4ParticleHPVector* passive)
224{
225 // interpolate between labels according to aScheme, cut at aValue,
226 // continue in unknown areas by substraction of the last difference.
227
228 CleanUp();
229 G4int s_tmp = 0, n = 0, m_tmp = 0;
231 G4int a = s_tmp, p = n, t;
232 while (a < active->GetVectorLength()) // Loop checking, 11.05.2015, T. Koi
233 {
234 if (active->GetEnergy(a) <= passive->GetEnergy(p)) {
235 G4double xa = active->GetEnergy(a);
236 G4double yy = theInt.Interpolate(aScheme, aValue, active->GetLabel(), passive->GetLabel(),
237 active->GetXsec(a), passive->GetXsec(xa));
238 SetData(m_tmp, xa, yy);
239 theManager.AppendScheme(m_tmp, active->GetScheme(a));
240 m_tmp++;
241 a++;
242 G4double xp = passive->GetEnergy(p);
243 // if( std::abs(std::abs(xp-xa)/xa)<0.0000001&&a<active->GetVectorLength() )
244 if (xa != 0 && std::abs(std::abs(xp - xa) / xa) < 0.0000001 && a < active->GetVectorLength())
245 {
246 p++;
247 tmp = active;
248 t = a;
249 active = passive;
250 a = p;
251 passive = tmp;
252 p = t;
253 }
254 }
255 else {
256 tmp = active;
257 t = a;
258 active = passive;
259 a = p;
260 passive = tmp;
261 p = t;
262 }
263 }
264
265 G4double deltaX = passive->GetXsec(GetEnergy(m_tmp - 1)) - GetXsec(m_tmp - 1);
266 while (p != passive->GetVectorLength()
267 && passive->GetEnergy(p) <= aValue) // Loop checking, 11.05.2015, T. Koi
268 {
269 G4double anX;
270 anX = passive->GetXsec(p) - deltaX;
271 if (anX > 0) {
272 // if(std::abs(GetEnergy(m-1)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.0000001)
273 if (passive->GetEnergy(p) == 0
274 || std::abs(GetEnergy(m_tmp - 1) - passive->GetEnergy(p)) / passive->GetEnergy(p)
275 > 0.0000001)
276 {
277 SetData(m_tmp, passive->GetEnergy(p), anX);
278 theManager.AppendScheme(m_tmp++, passive->GetScheme(p));
279 }
280 }
281 p++;
282 }
283 // Rebuild the Hash;
284 if (theHash.Prepared()) {
285 ReHash();
286 }
287}
288
290{
291 // anything in there?
292 if (GetVectorLength() == 0) return;
293 // make the new vector
294 auto aBuff = new G4ParticleHPDataPoint[nPoints];
295 G4double x, x1, x2, y, y1, y2;
296 G4int count = 0, current = 2, start = 1;
297
298 // First element always goes and is never tested.
299 aBuff[0] = theData[0];
300
301 // Find the rest
302 while (current < GetVectorLength()) // Loop checking, 11.05.2015, T. Koi
303 {
304 x1 = aBuff[count].GetX();
305 y1 = aBuff[count].GetY();
306 x2 = theData[current].GetX();
307 y2 = theData[current].GetY();
308
309 if (x1 - x2 == 0) {
310 // Following block added for avoiding div 0 error on Release + G4FPE_DEBUG
311 for (G4int j = start; j < current; j++) {
312 y = (y2 + y1) / 2.;
313 if (std::abs(y - theData[j].GetY()) > precision * y) {
314 aBuff[++count] = theData[current - 1]; // for this one, everything was fine
315 start = current; // the next candidate
316 break;
317 }
318 }
319 }
320 else {
321 for (G4int j = start; j < current; j++) {
322 x = theData[j].GetX();
323 if (x1 - x2 == 0)
324 y = (y2 + y1) / 2.;
325 else
326 y = theInt.Lin(x, x1, x2, y1, y2);
327 if (std::abs(y - theData[j].GetY()) > precision * y) {
328 aBuff[++count] = theData[current - 1]; // for this one, everything was fine
329 start = current; // the next candidate
330 break;
331 }
332 }
333 }
334 current++;
335 }
336 // The last one also always goes, and is never tested.
337 aBuff[++count] = theData[GetVectorLength() - 1];
338 delete[] theData;
339 theData = aBuff;
340 nEntries = count + 1;
341
342 // Rebuild the Hash;
343 if (theHash.Prepared()) {
344 ReHash();
345 }
346}
347
348G4bool G4ParticleHPVector::IsBlocked(G4double aX)
349{
350 G4bool result = false;
351 std::vector<G4double>::iterator i;
352 for (i = theBlocked.begin(); i != theBlocked.end(); i++) {
353 G4double aBlock = *i;
354 if (std::abs(aX - aBlock) < 0.1 * MeV) {
355 result = true;
356 theBlocked.erase(i);
357 break;
358 }
359 }
360 return result;
361}
362
363G4double G4ParticleHPVector::Sample() // Samples X according to distribution Y
364{
365 G4double result = 0.;
366 G4int j;
367 for (j = 0; j < GetVectorLength(); j++) {
368 if (GetY(j) < 0) SetY(j, 0);
369 }
370
371 if (!theBuffered.empty() && G4UniformRand() < 0.5) {
372 result = theBuffered[0];
373 theBuffered.erase(theBuffered.begin());
374 if (result < GetX(GetVectorLength() - 1)) return result;
375 }
376 if (GetVectorLength() == 1) {
377 result = theData[0].GetX();
378 }
379 else {
380 if (theIntegral == nullptr) {
382 }
383 G4int icounter = 0;
384 G4int icounter_max = 1024;
385 do {
386 icounter++;
387 if (icounter > icounter_max) {
388 G4cout << "Loop-counter exceeded the threshold value at " << __LINE__ << "th line of "
389 << __FILE__ << "." << G4endl;
390 break;
391 }
392 // 080808
393 /*
394 G4double rand;
395 G4double value, test, baseline;
396 baseline = theData[GetVectorLength()-1].GetX()-theData[0].GetX();
397 do
398 {
399 value = baseline*G4UniformRand();
400 value += theData[0].GetX();
401 test = GetY(value)/maxValue;
402 rand = G4UniformRand();
403 }
404 //while(test<rand);
405 while( test < rand && test > 0 );
406 result = value;
407 */
408 G4double rand;
409 G4double value = 0., test;
410 G4int jcounter = 0;
411 G4int jcounter_max = 1024;
412 do {
413 jcounter++;
414 if (jcounter > jcounter_max) {
415 G4cout << "Loop-counter exceeded the threshold value at " << __LINE__ << "th line of "
416 << __FILE__ << "." << G4endl;
417 break;
418 }
419 rand = G4UniformRand();
420 G4int ibin = -1;
421 for (G4int i = 0; i < GetVectorLength(); i++) {
422 if (rand < theIntegral[i]) {
423 ibin = i;
424 break;
425 }
426 }
427 if (ibin < 0) G4cout << "TKDB 080807 " << rand << G4endl;
428 // result
429 rand = G4UniformRand();
430 G4double x1, x2;
431 if (ibin == 0) {
432 x1 = theData[ibin].GetX();
433 value = x1;
434 break;
435 }
436 x1 = theData[ibin - 1].GetX();
437
438 x2 = theData[ibin].GetX();
439 value = rand * (x2 - x1) + x1;
440 //***********************************************************************
441 /*
442 test = GetY ( value ) / std::max ( GetY( ibin-1 ) , GetY ( ibin ) );
443 */
444 //***********************************************************************
445 // EMendoza - Always linear interpolation:
446 G4double y1 = theData[ibin - 1].GetY();
447 G4double y2 = theData[ibin].GetY();
448 G4double mval = (y2 - y1) / (x2 - x1);
449 G4double bval = y1 - mval * x1;
450 test = (mval * value + bval) / std::max(GetY(ibin - 1), GetY(ibin));
451 //***********************************************************************
452 } while (G4UniformRand() > test); // Loop checking, 11.05.2015, T. Koi
453 result = value;
454 // 080807
455 } while (IsBlocked(result)); // Loop checking, 11.05.2015, T. Koi
456 }
457 return result;
458}
459
461{
462 if (the15percentBorderCash > -DBL_MAX / 2.) return the15percentBorderCash;
463 G4double result;
464 if (GetVectorLength() == 1) {
465 result = theData[0].GetX();
466 the15percentBorderCash = result;
467 }
468 else {
469 if (theIntegral == nullptr) {
471 }
472 G4int i;
473 result = theData[GetVectorLength() - 1].GetX();
474 for (i = 0; i < GetVectorLength(); i++) {
475 if (theIntegral[i] / theIntegral[GetVectorLength() - 1] > 0.15) {
476 result = theData[std::min(i + 1, GetVectorLength() - 1)].GetX();
477 the15percentBorderCash = result;
478 break;
479 }
480 }
481 the15percentBorderCash = result;
482 }
483 return result;
484}
485
487{
488 if (the50percentBorderCash > -DBL_MAX / 2.) return the50percentBorderCash;
489 G4double result;
490 if (GetVectorLength() == 1) {
491 result = theData[0].GetX();
492 the50percentBorderCash = result;
493 }
494 else {
495 if (theIntegral == nullptr) {
497 }
498 G4int i;
499 G4double x = 0.5;
500 result = theData[GetVectorLength() - 1].GetX();
501 for (i = 0; i < GetVectorLength(); i++) {
502 if (theIntegral[i] / theIntegral[GetVectorLength() - 1] > x) {
503 G4int it;
504 it = i;
505 if (it == GetVectorLength() - 1) {
506 result = theData[GetVectorLength() - 1].GetX();
507 }
508 else {
509 G4double x1, x2, y1, y2;
510 x1 = theIntegral[i - 1] / theIntegral[GetVectorLength() - 1];
511 x2 = theIntegral[i] / theIntegral[GetVectorLength() - 1];
512 y1 = theData[i - 1].GetX();
513 y2 = theData[i].GetX();
514 result = theLin.Lin(x, x1, x2, y1, y2);
515 }
516 the50percentBorderCash = result;
517 break;
518 }
519 }
520 the50percentBorderCash = result;
521 }
522 return result;
523}
524
526{
527 G4double xsmax = 0.;
528 if (emin > emax || nEntries == 0) return xsmax;
529 if (emin >= theData[nEntries - 1].GetX()) {
530 xsmax = theData[nEntries - 1].GetY();
531 return xsmax;
532 }
533 if (emax <= theData[0].GetX()) {
534 xsmax = theData[0].GetY();
535 return xsmax;
536 }
537 if (!theHash.Prepared() && !G4Threading::IsWorkerThread()) Hash();
538 // Find the lowest index, low, where x(energy) is higher than emin
539 G4int i = theHash.GetMinIndex(emin);
540 for (; i < nEntries; ++i) {
541 if (theData[i].GetX() >= emin) break;
542 }
543 G4int low = i;
544 // Find the lowest index, high, where x(energy) is higher than emax
545 i = theHash.GetMinIndex(emax);
546 for (; i < nEntries; ++i) {
547 if (theData[i].GetX() >= emax) break;
548 }
549 G4int high = i;
550 xsmax = GetXsec(emin); // Set xsmax as low border
551 // Find the highest cross-section
552 for (i = low; i < high; ++i) {
553 if (xsmax < theData[i].GetY()) xsmax = theData[i].GetY();
554 }
555 // Check if it is smaller than the high border (e.g. as for a monotonic increasing cross-section)
556 G4double highborder = GetXsec(emax);
557 if (xsmax < highborder) xsmax = highborder;
558
559 if (xsmax == 0.) {
560 throw G4HadronicException(__FILE__, __LINE__,
561 "G4ParticleHPVector::GetMaxY : called "
562 "G4Nucleus::GetBiasedThermalNucleus for DBRC, xsmax==0.");
563 }
564
565 return xsmax;
566}
G4InterpolationScheme
G4ParticleHPVector & operator+(G4ParticleHPVector &left, G4ParticleHPVector &right)
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
void AppendScheme(G4int aPoint, const G4InterpolationScheme &aScheme)
G4InterpolationScheme GetScheme(G4int index) const
G4bool Prepared() const
G4int GetMinIndex(G4double e) const
G4double Interpolate(G4InterpolationScheme aScheme, G4double x, G4double x1, G4double x2, G4double y1, G4double y2) const
G4double Lin(G4double x, G4double x1, G4double x2, G4double y1, G4double y2)
G4InterpolationScheme GetScheme(G4int anIndex)
void SetY(G4int i, G4double x)
G4ParticleHPVector & operator=(const G4ParticleHPVector &right)
const G4ParticleHPDataPoint & GetPoint(G4int i) const
void SetData(G4int i, G4double x, G4double y)
G4double GetXsec(G4int i)
G4double GetMaxY(G4double emin, G4double emax)
void ThinOut(G4double precision)
G4double GetY(G4double x)
G4double GetEnergy(G4int i) const
G4double GetX(G4int i) const
void Merge(G4ParticleHPVector *active, G4ParticleHPVector *passive)
G4int GetVectorLength() const
void SetPoint(G4int i, const G4ParticleHPDataPoint &it)
G4bool IsWorkerThread()
#define DBL_MAX
Definition templates.hh:62