Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4NeutronHPVector.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#include "G4NeutronHPVector.hh"
34#include "G4SystemOfUnits.hh"
35
36 // if the ranges do not match, constant extrapolation is used.
38 {
40 G4int j=0;
41 G4double x;
42 G4double y;
43 G4int running = 0;
44 for(G4int i=0; i<left.GetVectorLength(); i++)
45 {
46 while(j<right.GetVectorLength())
47 {
48 if(right.GetX(j)<left.GetX(i)*1.001)
49 {
50 x = right.GetX(j);
51 y = right.GetY(j)+left.GetY(x);
52 result->SetData(running++, x, y);
53 j++;
54 }
55 //else if(std::abs((right.GetX(j)-left.GetX(i))/(left.GetX(i)+right.GetX(j)))>0.001)
56 else if( left.GetX(i)+right.GetX(j) == 0
57 || std::abs((right.GetX(j)-left.GetX(i))/(left.GetX(i)+right.GetX(j))) > 0.001 )
58 {
59 x = left.GetX(i);
60 y = left.GetY(i)+right.GetY(x);
61 result->SetData(running++, x, y);
62 break;
63 }
64 else
65 {
66 break;
67 }
68 }
69 if(j==right.GetVectorLength())
70 {
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 G4NeutronHPDataPoint[20];
83 nPoints=20;
84 nEntries=0;
85 Verbose=0;
86 theIntegral=0;
87 totalIntegral=-1;
88 isFreed = 0;
89 maxValue = -DBL_MAX;
90 the15percentBorderCash = -DBL_MAX;
91 the50percentBorderCash = -DBL_MAX;
92 label = -DBL_MAX;
93
94 }
95
97 {
98 nPoints=std::max(n, 20);
99 theData = new G4NeutronHPDataPoint[nPoints];
100 nEntries=0;
101 Verbose=0;
102 theIntegral=0;
103 totalIntegral=-1;
104 isFreed = 0;
105 maxValue = -DBL_MAX;
106 the15percentBorderCash = -DBL_MAX;
107 the50percentBorderCash = -DBL_MAX;
108 }
109
111 {
112// if(Verbose==1)G4cout <<"G4NeutronHPVector::~G4NeutronHPVector"<<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 isFreed = 1;
118 }
119
121 operator = (const G4NeutronHPVector & right)
122 {
123 if(&right == this) return *this;
124
125 G4int i;
126
127 totalIntegral = right.totalIntegral;
128 if(right.theIntegral!=0) theIntegral = new G4double[right.nEntries];
129 for(i=0; i<right.nEntries; i++)
130 {
131 SetPoint(i, right.GetPoint(i)); // copy theData
132 if(right.theIntegral!=0) theIntegral[i] = right.theIntegral[i];
133 }
134 theManager = right.theManager;
135 label = right.label;
136
137 Verbose = right.Verbose;
138 the15percentBorderCash = right.the15percentBorderCash;
139 the50percentBorderCash = right.the50percentBorderCash;
140 theHash = right.theHash;
141 return *this;
142 }
143
144
146 {
147 if(nEntries == 0) return 0;
148 if(!theHash.Prepared()) Hash();
149 G4int min = theHash.GetMinIndex(e);
150 G4int i;
151 for(i=min ; i<nEntries; i++)
152 {
153 //if(theData[i].GetX()>e) break;
154 if(theData[i].GetX() >= e) break;
155 }
156 G4int low = i-1;
157 G4int high = i;
158 if(i==0)
159 {
160 low = 0;
161 high = 1;
162 }
163 else if(i==nEntries)
164 {
165 low = nEntries-2;
166 high = nEntries-1;
167 }
168 G4double y;
169 if(e<theData[nEntries-1].GetX())
170 {
171 // Protect against doubled-up x values
172 //if( (theData[high].GetX()-theData[low].GetX())/theData[high].GetX() < 0.000001)
173 if ( theData[high].GetX() !=0
174 //080808 TKDB
175 //&&( theData[high].GetX()-theData[low].GetX())/theData[high].GetX() < 0.000001)
176 &&( std::abs( (theData[high].GetX()-theData[low].GetX())/theData[high].GetX() ) < 0.000001 ) )
177 {
178 y = theData[low].GetY();
179 }
180 else
181 {
182 y = theInt.Interpolate(theManager.GetScheme(high), e,
183 theData[low].GetX(), theData[high].GetX(),
184 theData[low].GetY(), theData[high].GetY());
185 }
186 }
187 else
188 {
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 {
199 G4cout << theData[i].GetX()<<" ";
200 G4cout << theData[i].GetY()<<" ";
201// if (i!=1&&i==5*(i/5)) G4cout << G4endl;
202 G4cout << G4endl;
203 }
204 G4cout << G4endl;
205 }
206
207 void G4NeutronHPVector::Check(G4int i)
208 {
209 if(i>nEntries) throw G4HadronicException(__FILE__, __LINE__, "Skipped some index numbers in G4NeutronHPVector");
210 if(i==nPoints)
211 {
212 nPoints = static_cast<G4int>(1.2*nPoints);
213 G4NeutronHPDataPoint * buff = new G4NeutronHPDataPoint[nPoints];
214 for (G4int j=0; j<nEntries; j++) buff[j] = theData[j];
215 delete [] theData;
216 theData = buff;
217 }
218 if(i==nEntries) nEntries=i+1;
219 }
220
222 Merge(G4InterpolationScheme aScheme, G4double aValue,
223 G4NeutronHPVector * active, G4NeutronHPVector * 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;
230 G4NeutronHPVector * tmp;
231 G4int a = s_tmp, p = n, t;
232 while ( a<active->GetVectorLength() )
233 {
234 if(active->GetEnergy(a) <= passive->GetEnergy(p))
235 {
236 G4double xa = active->GetEnergy(a);
237 G4double yy = theInt.Interpolate(aScheme, aValue, active->GetLabel(), passive->GetLabel(),
238 active->GetXsec(a), passive->GetXsec(xa));
239 SetData(m_tmp, xa, yy);
240 theManager.AppendScheme(m_tmp, active->GetScheme(a));
241 m_tmp++;
242 a++;
243 G4double xp = passive->GetEnergy(p);
244 //if( std::abs(std::abs(xp-xa)/xa)<0.0000001&&a<active->GetVectorLength() )
245 if ( xa != 0
246 && std::abs(std::abs(xp-xa)/xa) < 0.0000001
247 && a < active->GetVectorLength() )
248 {
249 p++;
250 tmp = active; t=a;
251 active = passive; a=p;
252 passive = tmp; p=t;
253 }
254 } else {
255 tmp = active; t=a;
256 active = passive; a=p;
257 passive = tmp; p=t;
258 }
259 }
260
261 G4double deltaX = passive->GetXsec(GetEnergy(m_tmp-1)) - GetXsec(m_tmp-1);
262 while (p!=passive->GetVectorLength()&&passive->GetEnergy(p)<=aValue)
263 {
264 G4double anX;
265 anX = passive->GetXsec(p)-deltaX;
266 if(anX>0)
267 {
268 //if(std::abs(GetEnergy(m-1)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.0000001)
269 if ( passive->GetEnergy(p) == 0
270 || std::abs(GetEnergy(m_tmp-1)-passive->GetEnergy(p))/passive->GetEnergy(p) > 0.0000001 )
271 {
272 SetData(m_tmp, passive->GetEnergy(p), anX);
273 theManager.AppendScheme(m_tmp++, passive->GetScheme(p));
274 }
275 }
276 p++;
277 }
278 // Rebuild the Hash;
279 if(theHash.Prepared())
280 {
281 ReHash();
282 }
283 }
284
286 {
287 // anything in there?
288 if(GetVectorLength()==0) return;
289 // make the new vector
290 G4NeutronHPDataPoint * aBuff = new G4NeutronHPDataPoint[nPoints];
291 G4double x, x1, x2, y, y1, y2;
292 G4int count = 0, current = 2, start = 1;
293
294 // First element always goes and is never tested.
295 aBuff[0] = theData[0];
296
297 // Find the rest
298 while(current < GetVectorLength())
299 {
300 x1=aBuff[count].GetX();
301 y1=aBuff[count].GetY();
302 x2=theData[current].GetX();
303 y2=theData[current].GetY();
304 for(G4int j=start; j<current; j++)
305 {
306 x = theData[j].GetX();
307 if(x1-x2 == 0) y = (y2+y1)/2.;
308 else y = theInt.Lin(x, x1, x2, y1, y2);
309 if (std::abs(y-theData[j].GetY())>precision*y)
310 {
311 aBuff[++count] = theData[current-1]; // for this one, everything was fine
312 start = current; // the next candidate
313 break;
314 }
315 }
316 current++ ;
317 }
318 // The last one also always goes, and is never tested.
319 aBuff[++count] = theData[GetVectorLength()-1];
320 delete [] theData;
321 theData = aBuff;
322 nEntries = count+1;
323
324 // Rebuild the Hash;
325 if(theHash.Prepared())
326 {
327 ReHash();
328 }
329 }
330
331 G4bool G4NeutronHPVector::IsBlocked(G4double aX)
332 {
333 G4bool result = false;
334 std::vector<G4double>::iterator i;
335 for(i=theBlocked.begin(); i!=theBlocked.end(); i++)
336 {
337 G4double aBlock = *i;
338 if(std::abs(aX-aBlock) < 0.1*MeV)
339 {
340 result = true;
341 theBlocked.erase(i);
342 break;
343 }
344 }
345 return result;
346 }
347
348 G4double G4NeutronHPVector::Sample() // Samples X according to distribution Y
349 {
350 G4double result;
351 G4int j;
352 for(j=0; j<GetVectorLength(); j++)
353 {
354 if(GetY(j)<0) SetY(j, 0);
355 }
356
357 if(theBuffered.size() !=0 && G4UniformRand()<0.5)
358 {
359 result = theBuffered[0];
360 theBuffered.erase(theBuffered.begin());
361 if(result < GetX(GetVectorLength()-1) ) return result;
362 }
363 if(GetVectorLength()==1)
364 {
365 result = theData[0].GetX();
366 }
367 else
368 {
369 if(theIntegral==0) { IntegrateAndNormalise(); }
370 do
371 {
372//080808
373/*
374 G4double rand;
375 G4double value, test, baseline;
376 baseline = theData[GetVectorLength()-1].GetX()-theData[0].GetX();
377 do
378 {
379 value = baseline*G4UniformRand();
380 value += theData[0].GetX();
381 test = GetY(value)/maxValue;
382 rand = G4UniformRand();
383 }
384 //while(test<rand);
385 while( test < rand && test > 0 );
386 result = value;
387*/
388 G4double rand;
389 G4double value, test;
390 do
391 {
392 rand = G4UniformRand();
393 G4int ibin = -1;
394 for ( G4int i = 0 ; i < GetVectorLength() ; i++ )
395 {
396 if ( rand < theIntegral[i] )
397 {
398 ibin = i;
399 break;
400 }
401 }
402 if ( ibin < 0 ) G4cout << "TKDB 080807 " << rand << G4endl;
403 // result
404 rand = G4UniformRand();
405 G4double x1, x2;
406 if ( ibin == 0 )
407 {
408 x1 = theData[ ibin ].GetX();
409 value = x1;
410 break;
411 }
412 else
413 {
414 x1 = theData[ ibin-1 ].GetX();
415 }
416
417 x2 = theData[ ibin ].GetX();
418 value = rand * ( x2 - x1 ) + x1;
419 //***********************************************************************
420 /*
421 test = GetY ( value ) / std::max ( GetY( ibin-1 ) , GetY ( ibin ) );
422 */
423 //***********************************************************************
424 //EMendoza - Always linear interpolation:
425 G4double y1=theData[ ibin-1 ].GetY();
426 G4double y2=theData[ ibin ].GetY();
427 G4double mval=(y2-y1)/(x2-x1);
428 G4double bval=y1-mval*x1;
429 test =(mval*value+bval)/std::max ( GetY( ibin-1 ) , GetY ( ibin ) );
430 //***********************************************************************
431 }
432 while ( G4UniformRand() > test );
433 result = value;
434//080807
435 }
436 while(IsBlocked(result));
437 }
438 return result;
439 }
440
442 {
443 if(the15percentBorderCash>-DBL_MAX/2.) return the15percentBorderCash;
444 G4double result;
445 if(GetVectorLength()==1)
446 {
447 result = theData[0].GetX();
448 the15percentBorderCash = result;
449 }
450 else
451 {
452 if(theIntegral==0) { IntegrateAndNormalise(); }
453 G4int i;
454 result = theData[GetVectorLength()-1].GetX();
455 for(i=0;i<GetVectorLength();i++)
456 {
457 if(theIntegral[i]/theIntegral[GetVectorLength()-1]>0.15)
458 {
459 result = theData[std::min(i+1, GetVectorLength()-1)].GetX();
460 the15percentBorderCash = result;
461 break;
462 }
463 }
464 the15percentBorderCash = result;
465 }
466 return result;
467 }
468
470 {
471 if(the50percentBorderCash>-DBL_MAX/2.) return the50percentBorderCash;
472 G4double result;
473 if(GetVectorLength()==1)
474 {
475 result = theData[0].GetX();
476 the50percentBorderCash = result;
477 }
478 else
479 {
480 if(theIntegral==0) { IntegrateAndNormalise(); }
481 G4int i;
482 G4double x = 0.5;
483 result = theData[GetVectorLength()-1].GetX();
484 for(i=0;i<GetVectorLength();i++)
485 {
486 if(theIntegral[i]/theIntegral[GetVectorLength()-1]>x)
487 {
488 G4int it;
489 it = i;
490 if(it == GetVectorLength()-1)
491 {
492 result = theData[GetVectorLength()-1].GetX();
493 }
494 else
495 {
496 G4double x1, x2, y1, y2;
497 x1 = theIntegral[i-1]/theIntegral[GetVectorLength()-1];
498 x2 = theIntegral[i]/theIntegral[GetVectorLength()-1];
499 y1 = theData[i-1].GetX();
500 y2 = theData[i].GetX();
501 result = theLin.Lin(x, x1, x2, y1, y2);
502 }
503 the50percentBorderCash = result;
504 break;
505 }
506 }
507 the50percentBorderCash = result;
508 }
509 return result;
510 }
G4InterpolationScheme
G4NeutronHPVector & operator+(G4NeutronHPVector &left, G4NeutronHPVector &right)
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:53
void AppendScheme(G4int aPoint, const G4InterpolationScheme &aScheme)
G4InterpolationScheme GetScheme(G4int index) const
G4int GetMinIndex(G4double e) const
G4bool Prepared() const
G4double Lin(G4double x, G4double x1, G4double x2, G4double y1, G4double y2)
G4double Interpolate(G4InterpolationScheme aScheme, G4double x, G4double x1, G4double x2, G4double y1, G4double y2) const
void Merge(G4NeutronHPVector *active, G4NeutronHPVector *passive)
G4double Get15percentBorder()
G4InterpolationScheme GetScheme(G4int anIndex)
G4NeutronHPVector & operator=(const G4NeutronHPVector &right)
G4int GetVectorLength() const
G4double GetX(G4int i) const
G4double Get50percentBorder()
G4double GetEnergy(G4int i) const
G4double GetXsec(G4int i)
G4double GetY(G4double x)
void SetPoint(G4int i, const G4NeutronHPDataPoint &it)
void SetData(G4int i, G4double x, G4double y)
const G4NeutronHPDataPoint & GetPoint(G4int i) const
void ThinOut(G4double precision)
void SetY(G4int i, G4double x)
#define DBL_MAX
Definition: templates.hh:83