source: trunk/source/processes/hadronic/models/neutron_hp/src/G4NeutronHPContAngularPar.cc@ 1199

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

update processes

File size: 18.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// 09-May-06 fix in Sample by T. Koi
31// 080318 Fix Compilation warnings - gcc-4.3.0 by T. Koi
32// (This fix has a real effect to the code.)
33// 080409 Fix div0 error with G4FPE by T. Koi
34// 080612 Fix contribution from Benoit Pirard and Laurent Desorgher (Univ. Bern) #1
35// 080714 Limiting the sum of energy of secondary particles by T. Koi
36// 080801 Fix div0 error wiht G4FPE and memory leak by T. Koi
37// 081024 G4NucleiPropertiesTable:: to G4NucleiProperties::
38//
39
40#include "G4NeutronHPContAngularPar.hh"
41#include "G4NeutronHPLegendreStore.hh"
42#include "G4Gamma.hh"
43#include "G4Electron.hh"
44#include "G4Positron.hh"
45#include "G4Neutron.hh"
46#include "G4Proton.hh"
47#include "G4Deuteron.hh"
48#include "G4Triton.hh"
49#include "G4He3.hh"
50#include "G4Alpha.hh"
51#include "G4NeutronHPVector.hh"
52#include "G4NucleiProperties.hh"
53#include "G4NeutronHPKallbachMannSyst.hh"
54#include "G4ParticleTable.hh"
55
56 void G4NeutronHPContAngularPar::Init(std::ifstream & aDataFile)
57 {
58 aDataFile >> theEnergy >> nEnergies >> nDiscreteEnergies >> nAngularParameters;
59 theEnergy *= eV;
60 theAngular = new G4NeutronHPList [nEnergies];
61 for(G4int i=0; i<nEnergies; i++)
62 {
63 G4double sEnergy;
64 aDataFile >> sEnergy;
65 sEnergy*=eV;
66 theAngular[i].SetLabel(sEnergy);
67 theAngular[i].Init(aDataFile, nAngularParameters, 1.);
68 }
69 }
70
71 G4ReactionProduct *
72 G4NeutronHPContAngularPar::Sample(G4double anEnergy, G4double massCode, G4double /*targetMass*/,
73 G4int angularRep, G4int interpolE )
74 {
75 G4ReactionProduct * result = new G4ReactionProduct;
76 G4int Z = static_cast<G4int>(massCode/1000);
77 G4int A = static_cast<G4int>(massCode-1000*Z);
78 if(massCode==0)
79 {
80 result->SetDefinition(G4Gamma::Gamma());
81 }
82 else if(A==0)
83 {
84 result->SetDefinition(G4Electron::Electron());
85 if(Z==1) result->SetDefinition(G4Positron::Positron());
86 }
87 else if(A==1)
88 {
89 result->SetDefinition(G4Neutron::Neutron());
90 if(Z==1) result->SetDefinition(G4Proton::Proton());
91 }
92 else if(A==2)
93 {
94 result->SetDefinition(G4Deuteron::Deuteron());
95 }
96 else if(A==3)
97 {
98 result->SetDefinition(G4Triton::Triton());
99 if(Z==2) result->SetDefinition(G4He3::He3());
100 }
101 else if(A==4)
102 {
103 result->SetDefinition(G4Alpha::Alpha());
104 if(Z!=2) throw G4HadronicException(__FILE__, __LINE__, "G4NeutronHPContAngularPar: Unknown ion case 1");
105 }
106 else
107 {
108 result->SetDefinition(G4ParticleTable::GetParticleTable()->FindIon(Z,A,0,Z));
109 }
110 G4int i(0);
111 G4int it(0);
112 G4double fsEnergy(0);
113 G4double cosTh(0);
114 if(angularRep==1)
115 {
116// 080612 Fix contribution from Benoit Pirard and Laurent Desorgher (Univ. Bern) #1
117 if (interpolE == 2)
118 {
119
120 //TK080711
121 if ( fresh == true )
122 {
123 remaining_energy = theAngular[0].GetLabel();
124 fresh = false;
125 }
126 //TK080711
127
128 G4double random = G4UniformRand();
129 G4double * running = new G4double[nEnergies+1];
130 running[0]=0;
131
132 for(i=1; i<nEnergies+1; i++)
133 {
134 //TK080711
135 if ( remaining_energy >= theAngular[ i-1 ].GetLabel() )
136 running[i] = running[i-1] + theAngular[i-1].GetValue(0);
137 else
138 running[i] = running[i-1];
139 //TK080711
140 }
141
142 //080730
143 if ( running[ nEnergies ] != 0 )
144 {
145
146 for ( i = 1 ; i < nEnergies+1 ; i++ )
147 {
148 it = i-1;
149 if ( random > running[ i-1 ]/running[ nEnergies ] && random <= running[ i ] / running[ nEnergies ] ) break;
150 }
151 fsEnergy = theAngular[ it ].GetLabel();
152
153 }
154
155 //TK080711
156 if ( i == nEnergies+1 || running[ nEnergies ] == 0 ) fsEnergy = remaining_energy;
157 //TK080711 //080730
158
159 G4NeutronHPLegendreStore theStore(1);
160 theStore.Init(0,fsEnergy,nAngularParameters);
161 for(i=0;i<nAngularParameters;i++)
162 {
163 theStore.SetCoeff(0,i,theAngular[it].GetValue(i));
164 }
165 // use it to sample.
166 cosTh = theStore.SampleMax(fsEnergy);
167
168 //TK080711
169 remaining_energy -= fsEnergy;
170 //TK080711
171
172 //080801b
173 delete[] running;
174 //080801b
175 }
176 else
177 {
178
179 //080714
180 if ( fresh == true )
181 {
182 remaining_energy = theAngular[ nEnergies-1 ].GetLabel();
183 fresh = false;
184 }
185 //080714
186
187
188 G4double random = G4UniformRand();
189 G4double * running = new G4double[nEnergies];
190 running[0]=0;
191 G4double weighted = 0;
192 for(i=1; i<nEnergies; i++)
193 {
194/*
195 if(i!=0)
196 {
197 running[i]=running[i-1];
198 }
199 running[i] += theInt.GetBinIntegral(theManager.GetScheme(i-1),
200 theAngular[i-1].GetLabel(), theAngular[i].GetLabel(),
201 theAngular[i-1].GetValue(0), theAngular[i].GetValue(0));
202 weighted += theInt.GetWeightedBinIntegral(theManager.GetScheme(i-1),
203 theAngular[i-1].GetLabel(), theAngular[i].GetLabel(),
204 theAngular[i-1].GetValue(0), theAngular[i].GetValue(0));
205*/
206
207 running[i]=running[i-1];
208 if ( remaining_energy >= theAngular[i].GetLabel() )
209 {
210 running[i] += theInt.GetBinIntegral(theManager.GetScheme(i-1),
211 theAngular[i-1].GetLabel(), theAngular[i].GetLabel(),
212 theAngular[i-1].GetValue(0), theAngular[i].GetValue(0));
213 weighted += theInt.GetWeightedBinIntegral(theManager.GetScheme(i-1),
214 theAngular[i-1].GetLabel(), theAngular[i].GetLabel(),
215 theAngular[i-1].GetValue(0), theAngular[i].GetValue(0));
216 }
217 }
218 // cash the mean energy in this distribution
219 //080409 TKDB
220 if ( nEnergies == 1 || running[nEnergies-1] == 0 )
221 currentMeanEnergy = 0.0;
222 else
223 {
224 currentMeanEnergy = weighted/running[nEnergies-1];
225 }
226
227 //080409 TKDB
228 if ( nEnergies == 1 ) it = 0;
229
230 //080729
231 if ( running[nEnergies-1] != 0 )
232 {
233 for ( i = 1 ; i < nEnergies ; i++ )
234 {
235 it = i;
236 if ( random < running [ i ] / running [ nEnergies-1 ] ) break;
237 }
238 }
239
240 //080714
241 if ( running [ nEnergies-1 ] == 0 ) it = 0;
242 //080714
243
244 if(it<nDiscreteEnergies||it==0)
245 {
246 if(it == 0)
247 {
248 fsEnergy = theAngular[it].GetLabel();
249 G4NeutronHPLegendreStore theStore(1);
250 theStore.Init(0,fsEnergy,nAngularParameters);
251 for(i=0;i<nAngularParameters;i++)
252 {
253 theStore.SetCoeff(0,i,theAngular[it].GetValue(i));
254 }
255 // use it to sample.
256 cosTh = theStore.SampleMax(fsEnergy);
257 }
258 else
259 {
260 G4double e1, e2;
261 e1 = theAngular[it-1].GetLabel();
262 e2 = theAngular[it].GetLabel();
263 fsEnergy = theInt.Interpolate(theManager.GetInverseScheme(it),
264 random,
265 running[it-1]/running[nEnergies-1],
266 running[it]/running[nEnergies-1],
267 e1, e2);
268 // fill a Legendrestore
269 G4NeutronHPLegendreStore theStore(2);
270 theStore.Init(0,e1,nAngularParameters);
271 theStore.Init(1,e2,nAngularParameters);
272 for(i=0;i<nAngularParameters;i++)
273 {
274 theStore.SetCoeff(0,i,theAngular[it-1].GetValue(i));
275 theStore.SetCoeff(1,i,theAngular[it].GetValue(i));
276 }
277 // use it to sample.
278 theStore.SetManager(theManager);
279 cosTh = theStore.SampleMax(fsEnergy);
280 }
281 }
282 else // continuum contribution
283 {
284 G4double x1 = running[it-1]/running[nEnergies-1];
285 G4double x2 = running[it]/running[nEnergies-1];
286 G4double y1 = theAngular[it-1].GetLabel();
287 G4double y2 = theAngular[it].GetLabel();
288 fsEnergy = theInt.Interpolate(theManager.GetInverseScheme(it),
289 random,x1,x2,y1,y2);
290 G4NeutronHPLegendreStore theStore(2);
291 theStore.Init(0,y1,nAngularParameters);
292 theStore.Init(1,y2,nAngularParameters);
293 theStore.SetManager(theManager);
294 for(i=0;i<nAngularParameters;i++)
295 {
296 theStore.SetCoeff(0,i,theAngular[it-1].GetValue(i));
297 theStore.SetCoeff(1,i,theAngular[it].GetValue(i));
298 }
299 // use it to sample.
300 cosTh = theStore.SampleMax(fsEnergy);
301 }
302 delete [] running;
303
304 //080714
305 remaining_energy -= fsEnergy;
306 //080714
307
308 }
309
310 }
311 else if(angularRep==2)
312 {
313 // first get the energy (already the right for this incoming energy)
314 G4int i;
315 G4double * running = new G4double[nEnergies];
316 running[0]=0;
317 G4double weighted = 0;
318 for(i=1; i<nEnergies; i++)
319 {
320 if(i!=0) running[i]=running[i-1];
321 running[i] += theInt.GetBinIntegral(theManager.GetScheme(i-1),
322 theAngular[i-1].GetLabel(), theAngular[i].GetLabel(),
323 theAngular[i-1].GetValue(0), theAngular[i].GetValue(0));
324 weighted += theInt.GetWeightedBinIntegral(theManager.GetScheme(i-1),
325 theAngular[i-1].GetLabel(), theAngular[i].GetLabel(),
326 theAngular[i-1].GetValue(0), theAngular[i].GetValue(0));
327 }
328 // cash the mean energy in this distribution
329 //080409 TKDB
330 //currentMeanEnergy = weighted/running[nEnergies-1];
331 if ( nEnergies == 1 )
332 currentMeanEnergy = 0.0;
333 else
334 currentMeanEnergy = weighted/running[nEnergies-1];
335
336 G4int it(0);
337 G4double randkal = G4UniformRand();
338 //080409 TKDB
339 //for(i=0; i<nEnergies; i++)
340 for(i=1; i<nEnergies; i++)
341 {
342 it = i;
343 if(randkal<running[i]/running[nEnergies-1]) break;
344 }
345
346 // interpolate the secondary energy.
347 G4double x, x1,x2,y1,y2;
348 if(it==0) it=1;
349 x = randkal*running[nEnergies-1];
350 x1 = running[it-1];
351 x2 = running[it];
352 G4double compoundFraction;
353 // interpolate energy
354 y1 = theAngular[it-1].GetLabel();
355 y2 = theAngular[it].GetLabel();
356 fsEnergy = theInt.Interpolate(theManager.GetInverseScheme(it-1),
357 x, x1,x2,y1,y2);
358 // for theta interpolate the compoundFractions
359 G4double cLow = theAngular[it-1].GetValue(1);
360 G4double cHigh = theAngular[it].GetValue(1);
361 compoundFraction = theInt.Interpolate(theManager.GetScheme(it),
362 fsEnergy, y1, y2, cLow,cHigh);
363 delete [] running;
364
365 // get cosTh
366 G4double incidentEnergy = anEnergy;
367 G4double incidentMass = G4Neutron::Neutron()->GetPDGMass();
368 G4double productEnergy = fsEnergy;
369 G4double productMass = result->GetMass();
370 G4int targetZ = G4int(theTargetCode/1000);
371 G4int targetA = G4int(theTargetCode-1000*targetZ);
372 // To correspond to natural composition (-nat-) data files.
373 if ( targetA == 0 )
374 targetA = int ( theTarget->GetMass()/amu_c2 + 0.5 );
375 G4double targetMass = theTarget->GetMass();
376 G4int residualA = targetA+1-A;
377 G4int residualZ = targetZ-Z;
378 G4double residualMass = residualZ*G4Proton::Proton()->GetPDGMass();
379 residualMass +=(residualA-residualZ)*G4Neutron::Neutron()->GetPDGMass();
380 residualMass -= G4NucleiProperties::GetBindingEnergy( residualA , residualZ );
381 G4NeutronHPKallbachMannSyst theKallbach(compoundFraction,
382 incidentEnergy, incidentMass,
383 productEnergy, productMass,
384 residualMass, residualA, residualZ,
385 targetMass, targetA, targetZ);
386 cosTh = theKallbach.Sample(anEnergy);
387 }
388 else if(angularRep>10&&angularRep<16)
389 {
390 G4double random = G4UniformRand();
391 G4double * running = new G4double[nEnergies];
392 running[0]=0;
393 G4double weighted = 0;
394 for(i=1; i<nEnergies; i++)
395 {
396 if(i!=0) running[i]=running[i-1];
397 running[i] += theInt.GetBinIntegral(theManager.GetScheme(i-1),
398 theAngular[i-1].GetLabel(), theAngular[i].GetLabel(),
399 theAngular[i-1].GetValue(0), theAngular[i].GetValue(0));
400 weighted += theInt.GetWeightedBinIntegral(theManager.GetScheme(i-1),
401 theAngular[i-1].GetLabel(), theAngular[i].GetLabel(),
402 theAngular[i-1].GetValue(0), theAngular[i].GetValue(0));
403 }
404 // cash the mean energy in this distribution
405 //currentMeanEnergy = weighted/running[nEnergies-1];
406 if ( nEnergies == 1 )
407 currentMeanEnergy = 0.0;
408 else
409 currentMeanEnergy = weighted/running[nEnergies-1];
410
411 //080409 TKDB
412 if ( nEnergies == 1 ) it = 0;
413 //for(i=0; i<nEnergies; i++)
414 for(i=1; i<nEnergies; i++)
415 {
416 it = i;
417 if(random<running[i]/running[nEnergies-1]) break;
418 }
419 if(it<nDiscreteEnergies||it==0)
420 {
421 if(it==0)
422 {
423 fsEnergy = theAngular[0].GetLabel();
424 G4NeutronHPVector theStore;
425 G4int aCounter = 0;
426 for(G4int i=1; i<nAngularParameters; i+=2)
427 {
428 theStore.SetX(aCounter, theAngular[0].GetValue(i));
429 theStore.SetY(aCounter, theAngular[0].GetValue(i+1));
430 aCounter++;
431 }
432 G4InterpolationManager aMan;
433 aMan.Init(angularRep-10, nAngularParameters-1);
434 theStore.SetInterpolationManager(aMan);
435 cosTh = theStore.Sample();
436 }
437 else
438 {
439 fsEnergy = theAngular[it].GetLabel();
440 G4NeutronHPVector theStore;
441 G4InterpolationManager aMan;
442 aMan.Init(angularRep-10, nAngularParameters-1);
443 theStore.SetInterpolationManager(aMan); // Store interpolates f(costh)
444 G4InterpolationScheme currentScheme = theManager.GetInverseScheme(it);
445 G4int aCounter = 0;
446 for(G4int i=1; i<nAngularParameters; i+=2)
447 {
448 theStore.SetX(aCounter, theAngular[it].GetValue(i));
449 theStore.SetY(aCounter, theInt.Interpolate(currentScheme,
450 random,
451 running[it-1]/running[nEnergies-1],
452 running[it]/running[nEnergies-1],
453 theAngular[it-1].GetValue(i+1),
454 theAngular[it].GetValue(i+1)));
455 aCounter++;
456 }
457 cosTh = theStore.Sample();
458 }
459 }
460 else
461 {
462 G4double x1 = running[it-1]/running[nEnergies-1];
463 G4double x2 = running[it]/running[nEnergies-1];
464 G4double y1 = theAngular[it-1].GetLabel();
465 G4double y2 = theAngular[it].GetLabel();
466 fsEnergy = theInt.Interpolate(theManager.GetInverseScheme(it),
467 random,x1,x2,y1,y2);
468 G4NeutronHPVector theBuff1;
469 G4NeutronHPVector theBuff2;
470 G4InterpolationManager aMan;
471 aMan.Init(angularRep-10, nAngularParameters-1);
472// theBuff1.SetInterpolationManager(aMan); // Store interpolates f(costh)
473// theBuff2.SetInterpolationManager(aMan); // Store interpolates f(costh)
474 for(i=0; i<nAngularParameters; i++) // i=1 ist wichtig!
475 {
476 theBuff1.SetX(i, theAngular[it-1].GetValue(i));
477 theBuff1.SetY(i, theAngular[it-1].GetValue(i+1));
478 theBuff2.SetX(i, theAngular[it].GetValue(i));
479 theBuff2.SetY(i, theAngular[it].GetValue(i+1));
480 i++;
481 }
482 G4NeutronHPVector theStore;
483 theStore.SetInterpolationManager(aMan); // Store interpolates f(costh)
484 x1 = y1;
485 x2 = y2;
486 G4double x, y;
487 //for(i=0;i<theBuff1.GetVectorLength(); i++);
488 for(i=0;i<theBuff1.GetVectorLength(); i++)
489 {
490 x = theBuff1.GetX(i); // costh binning identical
491 y1 = theBuff1.GetY(i);
492 y2 = theBuff2.GetY(i);
493 y = theInt.Interpolate(theManager.GetScheme(it),
494 fsEnergy, theAngular[it-1].GetLabel(),
495 theAngular[it].GetLabel(), y1, y2);
496 theStore.SetX(i, x);
497 theStore.SetY(i, y);
498 }
499 cosTh = theStore.Sample();
500 }
501 delete [] running;
502 }
503 else
504 {
505 throw G4HadronicException(__FILE__, __LINE__, "G4NeutronHPContAngularPar::Sample: Unknown angular representation");
506 }
507 result->SetKineticEnergy(fsEnergy);
508 G4double phi = twopi*G4UniformRand();
509 G4double theta = std::acos(cosTh);
510 G4double sinth = std::sin(theta);
511 G4double mtot = result->GetTotalMomentum();
512 G4ThreeVector tempVector(mtot*sinth*std::cos(phi), mtot*sinth*std::sin(phi), mtot*std::cos(theta) );
513 result->SetMomentum(tempVector);
514// return the result.
515 return result;
516 }
Note: See TracBrowser for help on using the repository browser.