source: trunk/source/processes/hadronic/models/neutron_hp/include/G4NeutronHPVector.hh@ 1199

Last change on this file since 1199 was 962, checked in by garnier, 17 years ago

update processes

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