source: trunk/source/processes/hadronic/models/neutron_hp/src/G4NeutronHPVector.cc@ 830

Last change on this file since 830 was 819, checked in by garnier, 17 years ago

import all except CVS

File size: 12.9 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// 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//
32#include "G4NeutronHPVector.hh"
33
34 // if the ranges do not match, constant extrapolation is used.
35 G4NeutronHPVector & operator + (G4NeutronHPVector & left, G4NeutronHPVector & right)
36 {
37 G4NeutronHPVector * result = new G4NeutronHPVector;
38 G4int j=0;
39 G4double x;
40 G4double y;
41 G4int running = 0;
42 for(G4int i=0; i<left.GetVectorLength(); i++)
43 {
44 while(j<right.GetVectorLength())
45 {
46 if(right.GetX(j)<left.GetX(i)*1.001)
47 {
48 x = right.GetX(j);
49 y = right.GetY(j)+left.GetY(x);
50 result->SetData(running++, x, y);
51 j++;
52 }
53 //else if(std::abs((right.GetX(j)-left.GetX(i))/(left.GetX(i)+right.GetX(j)))>0.001)
54 else if( left.GetX(i)+right.GetX(j) == 0
55 || std::abs((right.GetX(j)-left.GetX(i))/(left.GetX(i)+right.GetX(j))) > 0.001 )
56 {
57 x = left.GetX(i);
58 y = left.GetY(i)+right.GetY(x);
59 result->SetData(running++, x, y);
60 break;
61 }
62 else
63 {
64 break;
65 }
66 }
67 if(j==right.GetVectorLength())
68 {
69 x = left.GetX(i);
70 y = left.GetY(i)+right.GetY(x);
71 result->SetData(running++, x, y);
72 }
73 }
74 result->ThinOut(0.02);
75 return *result;
76 }
77
78 G4NeutronHPVector::G4NeutronHPVector()
79 {
80 theData = new G4NeutronHPDataPoint[20];
81 nPoints=20;
82 nEntries=0;
83 Verbose=0;
84 theIntegral=0;
85 totalIntegral=-1;
86 isFreed = 0;
87 maxValue = -DBL_MAX;
88 the15percentBorderCash = -DBL_MAX;
89 the50percentBorderCash = -DBL_MAX;
90 label = -DBL_MAX;
91
92 }
93
94 G4NeutronHPVector::G4NeutronHPVector(G4int n)
95 {
96 nPoints=std::max(n, 20);
97 theData = new G4NeutronHPDataPoint[nPoints];
98 nEntries=0;
99 Verbose=0;
100 theIntegral=0;
101 totalIntegral=-1;
102 isFreed = 0;
103 maxValue = -DBL_MAX;
104 the15percentBorderCash = -DBL_MAX;
105 the50percentBorderCash = -DBL_MAX;
106 }
107
108 G4NeutronHPVector::~G4NeutronHPVector()
109 {
110// if(Verbose==1)G4cout <<"G4NeutronHPVector::~G4NeutronHPVector"<<G4endl;
111 delete [] theData;
112// if(Verbose==1)G4cout <<"Vector: delete theData"<<G4endl;
113 delete [] theIntegral;
114// if(Verbose==1)G4cout <<"Vector: delete theIntegral"<<G4endl;
115 isFreed = 1;
116 }
117
118 G4NeutronHPVector & G4NeutronHPVector::
119 operator = (const G4NeutronHPVector & right)
120 {
121 if(&right == this) return *this;
122
123 G4int i;
124
125 totalIntegral = right.totalIntegral;
126 if(right.theIntegral!=0) theIntegral = new G4double[right.nEntries];
127 for(i=0; i<right.nEntries; i++)
128 {
129 SetPoint(i, right.GetPoint(i)); // copy theData
130 if(right.theIntegral!=0) theIntegral[i] = right.theIntegral[i];
131 }
132 theManager = right.theManager;
133 label = right.label;
134
135 Verbose = right.Verbose;
136 the15percentBorderCash = right.the15percentBorderCash;
137 the50percentBorderCash = right.the50percentBorderCash;
138 theHash = right.theHash;
139 return *this;
140 }
141
142
143 G4double G4NeutronHPVector::GetXsec(G4double e)
144 {
145 if(nEntries == 0) return 0;
146 if(!theHash.Prepared()) Hash();
147 G4int min = theHash.GetMinIndex(e);
148 G4int i;
149 for(i=min ; i<nEntries; i++)
150 {
151 //if(theData[i].GetX()>e) break;
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 if ( theData[high].GetX() !=0
172 &&( theData[high].GetX()-theData[low].GetX())/theData[high].GetX() < 0.000001)
173 {
174 y = theData[low].GetY();
175 }
176 else
177 {
178 y = theInt.Interpolate(theManager.GetScheme(high), e,
179 theData[low].GetX(), theData[high].GetX(),
180 theData[low].GetY(), theData[high].GetY());
181 }
182 }
183 else
184 {
185 y=theData[nEntries-1].GetY();
186 }
187 return y;
188 }
189
190 void G4NeutronHPVector::Dump()
191 {
192 G4cout << nEntries<<G4endl;
193 for(G4int i=0; i<nEntries; i++)
194 {
195 G4cout << theData[i].GetX()<<" ";
196 G4cout << theData[i].GetY()<<" ";
197// if (i!=1&&i==5*(i/5)) G4cout << G4endl;
198 G4cout << G4endl;
199 }
200 G4cout << G4endl;
201 }
202
203 void G4NeutronHPVector::Check(G4int i)
204 {
205 if(i>nEntries) throw G4HadronicException(__FILE__, __LINE__, "Skipped some index numbers in G4NeutronHPVector");
206 if(i==nPoints)
207 {
208 nPoints = static_cast<G4int>(1.2*nPoints);
209 G4NeutronHPDataPoint * buff = new G4NeutronHPDataPoint[nPoints];
210 for (G4int j=0; j<nEntries; j++) buff[j] = theData[j];
211 delete [] theData;
212 theData = buff;
213 }
214 if(i==nEntries) nEntries=i+1;
215 }
216
217 void G4NeutronHPVector::
218 Merge(G4InterpolationScheme aScheme, G4double aValue,
219 G4NeutronHPVector * active, G4NeutronHPVector * passive)
220 {
221 // interpolate between labels according to aScheme, cut at aValue,
222 // continue in unknown areas by substraction of the last difference.
223
224 CleanUp();
225 G4int s = 0, n=0, m=0;
226 G4NeutronHPVector * tmp;
227 G4int a = s, p = n, t;
228 while ( a<active->GetVectorLength() )
229 {
230 if(active->GetEnergy(a) <= passive->GetEnergy(p))
231 {
232 G4double xa = active->GetEnergy(a);
233 G4double yy = theInt.Interpolate(aScheme, aValue, active->GetLabel(), passive->GetLabel(),
234 active->GetXsec(a), passive->GetXsec(xa));
235 SetData(m, xa, yy);
236 theManager.AppendScheme(m, active->GetScheme(a));
237 m++;
238 a++;
239 G4double xp = passive->GetEnergy(p);
240 //if( std::abs(std::abs(xp-xa)/xa)<0.0000001&&a<active->GetVectorLength() )
241 if ( xa != 0
242 && std::abs(std::abs(xp-xa)/xa) < 0.0000001
243 && a < active->GetVectorLength() )
244 {
245 p++;
246 tmp = active; t=a;
247 active = passive; a=p;
248 passive = tmp; p=t;
249 }
250 } else {
251 tmp = active; t=a;
252 active = passive; a=p;
253 passive = tmp; p=t;
254 }
255 }
256
257 G4double deltaX = passive->GetXsec(GetEnergy(m-1)) - GetXsec(m-1);
258 while (p!=passive->GetVectorLength()&&passive->GetEnergy(p)<=aValue)
259 {
260 G4double anX;
261 anX = passive->GetXsec(p)-deltaX;
262 if(anX>0)
263 {
264 //if(std::abs(GetEnergy(m-1)-passive->GetEnergy(p))/passive->GetEnergy(p)>0.0000001)
265 if ( passive->GetEnergy(p) == 0
266 || std::abs(GetEnergy(m-1)-passive->GetEnergy(p))/passive->GetEnergy(p) > 0.0000001 )
267 {
268 SetData(m, passive->GetEnergy(p), anX);
269 theManager.AppendScheme(m++, passive->GetScheme(p));
270 }
271 }
272 p++;
273 }
274 // Rebuild the Hash;
275 if(theHash.Prepared())
276 {
277 ReHash();
278 }
279 }
280
281 void G4NeutronHPVector::ThinOut(G4double precision)
282 {
283 // anything in there?
284 if(GetVectorLength()==0) return;
285 // make the new vector
286 G4NeutronHPDataPoint * aBuff = new G4NeutronHPDataPoint[nPoints];
287 G4double x, x1, x2, y, y1, y2;
288 G4int count = 0, current = 2, start = 1;
289
290 // First element always goes and is never tested.
291 aBuff[0] = theData[0];
292
293 // Find the rest
294 while(current < GetVectorLength())
295 {
296 x1=aBuff[count].GetX();
297 y1=aBuff[count].GetY();
298 x2=theData[current].GetX();
299 y2=theData[current].GetY();
300 for(G4int j=start; j<current; j++)
301 {
302 x = theData[j].GetX();
303 if(x1-x2 == 0) y = (y2+y1)/2.;
304 else y = theInt.Lin(x, x1, x2, y1, y2);
305 if (std::abs(y-theData[j].GetY())>precision*y)
306 {
307 aBuff[++count] = theData[current-1]; // for this one, everything was fine
308 start = current; // the next candidate
309 break;
310 }
311 }
312 current++ ;
313 }
314 // The last one also always goes, and is never tested.
315 aBuff[++count] = theData[GetVectorLength()-1];
316 delete [] theData;
317 theData = aBuff;
318 nEntries = count+1;
319
320 // Rebuild the Hash;
321 if(theHash.Prepared())
322 {
323 ReHash();
324 }
325 }
326
327 G4bool G4NeutronHPVector::IsBlocked(G4double aX)
328 {
329 G4bool result = false;
330 std::vector<G4double>::iterator i;
331 for(i=theBlocked.begin(); i!=theBlocked.end(); i++)
332 {
333 G4double aBlock = *i;
334 if(std::abs(aX-aBlock) < 0.1*MeV)
335 {
336 result = true;
337 theBlocked.erase(i);
338 break;
339 }
340 }
341 return result;
342 }
343
344 G4double G4NeutronHPVector::Sample() // Samples X according to distribution Y
345 {
346 G4double result;
347 G4int j;
348 for(j=0; j<GetVectorLength(); j++)
349 {
350 if(GetY(j)<0) SetY(j, 0);
351 }
352
353 if(theBuffered.size() !=0 && G4UniformRand()<0.5)
354 {
355 result = theBuffered[0];
356 theBuffered.erase(theBuffered.begin());
357 if(result < GetX(GetVectorLength()-1) ) return result;
358 }
359 if(GetVectorLength()==1)
360 {
361 result = theData[0].GetX();
362 }
363 else
364 {
365 if(theIntegral==0) { IntegrateAndNormalise(); }
366 do
367 {
368 G4double value, test, baseline;
369 baseline = theData[GetVectorLength()-1].GetX()-theData[0].GetX();
370 G4double rand;
371 do
372 {
373 value = baseline*G4UniformRand();
374 value += theData[0].GetX();
375 test = GetY(value)/maxValue;
376 rand = G4UniformRand();
377 }
378 //while(test<rand);
379 while( test < rand && test > 0 );
380 result = value;
381 }
382 while(IsBlocked(result));
383 }
384 return result;
385 }
386
387 G4double G4NeutronHPVector::Get15percentBorder()
388 {
389 if(the15percentBorderCash>-DBL_MAX/2.) return the15percentBorderCash;
390 G4double result;
391 if(GetVectorLength()==1)
392 {
393 result = theData[0].GetX();
394 the15percentBorderCash = result;
395 }
396 else
397 {
398 if(theIntegral==0) { IntegrateAndNormalise(); }
399 G4int i;
400 result = theData[GetVectorLength()-1].GetX();
401 for(i=0;i<GetVectorLength();i++)
402 {
403 if(theIntegral[i]/theIntegral[GetVectorLength()-1]>0.15)
404 {
405 result = theData[std::min(i+1, GetVectorLength()-1)].GetX();
406 the15percentBorderCash = result;
407 break;
408 }
409 }
410 the15percentBorderCash = result;
411 }
412 return result;
413 }
414
415 G4double G4NeutronHPVector::Get50percentBorder()
416 {
417 if(the50percentBorderCash>-DBL_MAX/2.) return the50percentBorderCash;
418 G4double result;
419 if(GetVectorLength()==1)
420 {
421 result = theData[0].GetX();
422 the50percentBorderCash = result;
423 }
424 else
425 {
426 if(theIntegral==0) { IntegrateAndNormalise(); }
427 G4int i;
428 G4double x = 0.5;
429 result = theData[GetVectorLength()-1].GetX();
430 for(i=0;i<GetVectorLength();i++)
431 {
432 if(theIntegral[i]/theIntegral[GetVectorLength()-1]>x)
433 {
434 G4int it;
435 it = i;
436 if(it == GetVectorLength()-1)
437 {
438 result = theData[GetVectorLength()-1].GetX();
439 }
440 else
441 {
442 G4double x1, x2, y1, y2;
443 x1 = theIntegral[i-1]/theIntegral[GetVectorLength()-1];
444 x2 = theIntegral[i]/theIntegral[GetVectorLength()-1];
445 y1 = theData[i-1].GetX();
446 y2 = theData[i].GetX();
447 result = theLin.Lin(x, x1, x2, y1, y2);
448 }
449 the50percentBorderCash = result;
450 break;
451 }
452 }
453 the50percentBorderCash = result;
454 }
455 return result;
456 }
Note: See TracBrowser for help on using the repository browser.