source: trunk/source/processes/hadronic/models/neutron_hp/src/G4NeutronHPPhotonDist.cc @ 1228

Last change on this file since 1228 was 1055, checked in by garnier, 15 years ago

maj sur la beta de geant 4.9.3

File size: 28.0 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 Try to limit sum of secondary photon energy while keeping distribution shape
31//        in the of nDiscrete = 1 an nPartial = 1. Most case are satisfied.
32//        T. Koi
33// 070606 Add Partial case by T. Koi
34// 070618 fix memory leaking by T. Koi
35// 080801 fix memory leaking by T. Koi
36// 080801 Correcting data disorder which happened when both InitPartial
37//        and InitAnglurar methods was called in a same instance by T. Koi
38// 090514 Fix bug in IC electron emission case
39//        Contribution from Chao Zhang (Chao.Zhang@usd.edu) and Dongming Mei(Dongming.Mei@usd.edu)
40//        But it looks like never cause real effect in G4NDL3.13 (at least Natural elements) TK
41//
42// there is a lot of unused (and undebugged) code in this file. Kept for the moment just in case. @@
43
44#include "G4NeutronHPPhotonDist.hh"
45#include "G4NeutronHPLegendreStore.hh"
46#include "G4Electron.hh"
47#include "G4Poisson.hh"
48
49#include <numeric>
50
51G4bool G4NeutronHPPhotonDist::InitMean(std::ifstream & aDataFile)
52{
53
54  G4bool result = true;
55  if(aDataFile >> repFlag)
56  {
57
58    aDataFile >> targetMass;
59    if(repFlag==1)
60    {
61    // multiplicities
62      aDataFile >> nDiscrete;
63      disType = new G4int[nDiscrete];
64      energy = new G4double[nDiscrete];
65      actualMult = new G4int[nDiscrete];
66      theYield = new G4NeutronHPVector[nDiscrete];
67      for (G4int i=0; i<nDiscrete; i++)
68      {
69        aDataFile >> disType[i]>>energy[i];
70        energy[i]*=eV;
71        theYield[i].Init(aDataFile, eV);
72      }
73    }
74    else if(repFlag == 2)
75    {
76       aDataFile >> theInternalConversionFlag;
77       aDataFile >> theBaseEnergy;
78       theBaseEnergy*=eV;
79       aDataFile >> theInternalConversionFlag;
80       // theInternalConversionFlag == 1 No IC, theInternalConversionFlag == 2 with IC
81       aDataFile >> nGammaEnergies;
82       theLevelEnergies = new G4double[nGammaEnergies];
83       theTransitionProbabilities = new G4double[nGammaEnergies];
84       if(theInternalConversionFlag == 2) thePhotonTransitionFraction = new G4double[nGammaEnergies];
85       for(G4int  ii=0; ii<nGammaEnergies; ii++)
86       {
87         if(theInternalConversionFlag == 1)
88         {
89           aDataFile >> theLevelEnergies[ii] >> theTransitionProbabilities[ii];
90           theLevelEnergies[ii]*=eV;
91         }
92         else if(theInternalConversionFlag == 2)
93         {
94           aDataFile >> theLevelEnergies[ii] >> theTransitionProbabilities[ii] >> thePhotonTransitionFraction[ii];
95           theLevelEnergies[ii]*=eV;
96         }
97         else
98         {
99           throw G4HadronicException(__FILE__, __LINE__, "G4NeutronHPPhotonDist: Unknown conversion flag");
100         }
101      }
102       // Note, that this is equivalent to using the 'Gamma' classes.
103      // throw G4HadronicException(__FILE__, __LINE__, "G4NeutronHPPhotonDist: Transition probability array not sampled for the moment.");
104    }
105    else
106    {
107      G4cout << "Data representation in G4NeutronHPPhotonDist: "<<repFlag<<G4endl;
108      throw G4HadronicException(__FILE__, __LINE__, "G4NeutronHPPhotonDist: This data representation is not implemented.");
109    }
110  }
111  else
112  {
113    result = false;
114  }
115  return result;
116}
117
118void G4NeutronHPPhotonDist::InitAngular(std::ifstream & aDataFile)
119{
120
121  G4int i, ii;
122  //angular distributions
123  aDataFile >> isoFlag;
124  if (isoFlag != 1)
125  {
126if ( repFlag == 2 ) G4cout << "TKDB repFlag == 2 && isoFlag !=1  " << G4endl;
127    aDataFile >> tabulationType >> nDiscrete2 >> nIso;
128//080731
129      if ( theGammas != NULL && nDiscrete2 != nDiscrete ) G4cout << "080731c G4NeutronHPPhotonDist nDiscrete2 != nDiscrete, It looks like something wrong in your NDL files. Please update the latest. If you still have this messages after the update, then please report to Geant4 Hyper News." << G4endl;
130
131      // The order of cross section (InitPartials) and distribution (InitAngular here) data are different, we have to re-coordinate consistent data order.
132      std::vector < G4double > vct_gammas_par; 
133      std::vector < G4double > vct_shells_par; 
134      std::vector < G4int > vct_primary_par; 
135      std::vector < G4int > vct_distype_par; 
136      std::vector < G4NeutronHPVector* > vct_pXS_par;
137      if ( theGammas != NULL ) 
138      {
139         //copy the cross section data
140         for ( i = 0 ; i < nDiscrete ; i++ )
141         {
142            vct_gammas_par.push_back( theGammas[ i ] );
143            vct_shells_par.push_back( theShells[ i ] );
144            vct_primary_par.push_back( isPrimary[ i ] );
145            vct_distype_par.push_back( disType[ i ] );
146            G4NeutronHPVector* hpv = new G4NeutronHPVector;
147            *hpv = thePartialXsec[ i ];
148            vct_pXS_par.push_back( hpv );
149         }
150      }
151     if ( theGammas == NULL ) theGammas = new G4double[nDiscrete2];
152     if ( theShells == NULL ) theShells = new G4double[nDiscrete2];
153//080731
154
155    for (i=0; i< nIso; i++) // isotropic photons
156    {
157       aDataFile >> theGammas[i] >> theShells[i];
158       theGammas[i]*=eV;
159       theShells[i]*=eV;
160    }
161    nNeu = new G4int [nDiscrete2-nIso];
162    if(tabulationType==1)theLegendre=new G4NeutronHPLegendreTable *[nDiscrete2-nIso];
163    if(tabulationType==2)theAngular =new G4NeutronHPAngularP *[nDiscrete2-nIso];
164    for(i=nIso; i< nDiscrete2; i++)
165    {
166      if(tabulationType==1) 
167      {
168        aDataFile >> theGammas[i] >> theShells[i] >> nNeu[i-nIso];
169        theGammas[i]*=eV;
170        theShells[i]*=eV;
171        theLegendre[i-nIso]=new G4NeutronHPLegendreTable[nNeu[i-nIso]];
172        theLegendreManager.Init(aDataFile); 
173        for (ii=0; ii<nNeu[i-nIso]; ii++)
174        {
175          theLegendre[i-nIso][ii].Init(aDataFile);
176        }
177      }
178      else if(tabulationType==2)
179      {
180        aDataFile >> theGammas[i] >> theShells[i] >> nNeu[i-nIso];
181        theGammas[i]*=eV;
182        theShells[i]*=eV;
183        theAngular[i-nIso]=new G4NeutronHPAngularP[nNeu[i-nIso]];
184        for (ii=0; ii<nNeu[i-nIso]; ii++)
185        {
186          theAngular[i-nIso][ii].Init(aDataFile);
187        }
188      }
189      else
190      {
191        G4cout << "tabulation type: tabulationType"<<G4endl;
192        throw G4HadronicException(__FILE__, __LINE__, "cannot deal with this tabulation type for angular distributions.");
193      }
194    }
195//080731
196     if ( vct_gammas_par.size() > 0 ) 
197     {
198        //Reordering cross section data to corrsponding distribution data
199        for ( i = 0 ; i < nDiscrete ; i++ ) 
200        {
201           for ( G4int j = 0 ; j < nDiscrete ; j++ ) 
202           {
203              // Checking gamma and shell to identification
204              if ( theGammas[ i ] == vct_gammas_par [ j ] && theShells [ i ] == vct_shells_par[ j ] )
205              {
206                 isPrimary [ i ] = vct_primary_par [ j ];
207                 disType [ i ] = vct_distype_par [ j ];
208                 thePartialXsec[ i ] = ( *( vct_pXS_par[ j ] ) );
209              }
210           }
211        }
212        //Garbage collection
213        for ( std::vector < G4NeutronHPVector* >::iterator
214           it = vct_pXS_par.begin() ; it != vct_pXS_par.end() ; it++ )
215        {
216           delete *it;
217        }
218     }
219//080731
220  }
221}
222
223
224void G4NeutronHPPhotonDist::InitEnergies(std::ifstream & aDataFile)
225{
226  G4int i, energyDistributionsNeeded = 0;
227  for (i=0; i<nDiscrete; i++)
228  {
229    if( disType[i]==1) energyDistributionsNeeded =1;
230  }
231  if(!energyDistributionsNeeded) return;
232  aDataFile >>  nPartials;
233  distribution = new G4int[nPartials];
234  probs = new G4NeutronHPVector[nPartials];
235  partials = new G4NeutronHPPartial * [nPartials];
236  G4int nen;
237  G4int dummy;
238  for (i=0; i<nPartials; i++)
239  {
240    aDataFile >> dummy;
241    probs[i].Init(aDataFile, eV);
242    aDataFile >> nen;
243    partials[i] = new G4NeutronHPPartial(nen);
244    partials[i]->InitInterpolation(aDataFile);
245    partials[i]->Init(aDataFile);
246  }
247}
248
249void G4NeutronHPPhotonDist::InitPartials(std::ifstream & aDataFile)
250{
251
252  //G4cout << "G4NeutronHPPhotonDist::InitPartials " << G4endl;
253  aDataFile >> nDiscrete >> targetMass;
254  if(nDiscrete != 1)
255  {
256    theTotalXsec.Init(aDataFile, eV);
257  }
258  G4int i;
259  theGammas = new G4double[nDiscrete];
260  theShells = new G4double[nDiscrete];
261  isPrimary = new G4int[nDiscrete];
262  disType = new G4int[nDiscrete];
263  thePartialXsec = new G4NeutronHPVector[nDiscrete];
264  for(i=0; i<nDiscrete; i++)
265  {
266    aDataFile>>theGammas[i]>>theShells[i]>>isPrimary[i]>>disType[i];
267    theGammas[i]*=eV;
268    theShells[i]*=eV;
269    thePartialXsec[i].Init(aDataFile, eV);
270  } 
271
272  //G4cout << "G4NeutronHPPhotonDist::InitPartials Test " << G4endl;
273  //G4cout << "G4NeutronHPPhotonDist::InitPartials nDiscrete " << nDiscrete << G4endl;
274  //G4NeutronHPVector* aHP = new G4NeutronHPVector;
275  //aHP->Check(1);
276}
277
278G4ReactionProductVector * G4NeutronHPPhotonDist::GetPhotons(G4double anEnergy)
279{
280
281  //G4cout << "G4NeutronHPPhotonDist::GetPhotons repFlag " << repFlag << G4endl;
282  // the partial cross-section case is not in this yet. @@@@  << 070601 TK add partial
283  G4int i, ii, iii;
284  G4int nSecondaries = 0;
285  G4ReactionProductVector * thePhotons = new G4ReactionProductVector;
286  if(repFlag==1)
287  {
288    G4double current=0;
289    for(i=0; i<nDiscrete; i++)
290    {
291      current = theYield[i].GetY(anEnergy);
292      actualMult[i] = G4Poisson(current); // max cut-off still missing @@@
293      if(nDiscrete==1&&current<1.0001) 
294      {
295        actualMult[i] = static_cast<G4int>(current);
296        if(current<1) 
297        {
298          actualMult[i] = 0;
299          if(G4UniformRand()<current) actualMult[i] = 1;
300        }
301      }
302      nSecondaries += actualMult[i];
303    }
304    //G4cout << "nSecondaries " << nSecondaries  << " anEnergy " << anEnergy/eV << G4endl;
305    for(i=0;i<nSecondaries;i++)
306    {
307      G4ReactionProduct * theOne = new G4ReactionProduct;
308      theOne->SetDefinition(G4Gamma::Gamma());
309      thePhotons->push_back(theOne);
310    }
311    G4int count=0;
312
313/*
314G4double totalCascadeEnergy = 0.;
315G4double lastCascadeEnergy = 0.;
316G4double eGamm = 0;
317G4int maxEnergyIndex = 0;
318*/
319    //Gcout << "nDiscrete " << nDiscrete << " nPartials " << nPartials << G4endl;
320//3456
321      if ( nDiscrete == 1 && nPartials == 1 ) 
322      {
323         if ( actualMult[ 0 ] > 0 ) 
324         {
325            if ( disType[0] == 1 ) // continuum
326            {
327
328/*
329      for(ii=0; ii< actualMult[0]; ii++)
330      {   
331
332          G4double  sum=0, run=0;
333          for(iii=0; iii<nPartials; iii++) sum+=probs[iii].GetY(anEnergy);
334          G4double random = G4UniformRand();
335          G4int theP = 0;
336          for(iii=0; iii<nPartials; iii++)
337          {
338            run+=probs[iii].GetY(anEnergy);
339            theP = iii;
340            if(random<run/sum) break;
341          }
342          if(theP==nPartials) theP=nPartials-1; // das sortiert J aus.
343          sum=0;
344          G4NeutronHPVector * temp;
345          temp = partials[theP]->GetY(anEnergy); //@@@ look at, seems fishy
346          // Looking for TotalCascdeEnergy or LastMaxEnergy
347          if (ii == 0)
348          {
349            maxEnergyIndex = temp->GetVectorLength()-1;
350            totalCascadeEnergy = temp->GetX(maxEnergyIndex);
351            lastCascadeEnergy = totalCascadeEnergy;
352          }
353          lastCascadeEnergy -= eGamm;
354          if (ii != actualMult[i]-1) eGamm = temp->SampleWithMax(lastCascadeEnergy);
355          else eGamm = lastCascadeEnergy;
356          thePhotons->operator[](count)->SetKineticEnergy(eGamm);
357          delete temp;
358
359     }
360*/
361               G4NeutronHPVector * temp;
362               temp = partials[ 0 ]->GetY(anEnergy); //@@@ look at, seems fishy
363               G4double maximumE = temp->GetX( temp->GetVectorLength()-1 ); // This is an assumption.
364
365               //G4cout << "start " << actualMult[ 0 ] << " maximumE " << maximumE/eV << G4endl;
366
367               std::vector< G4double > photons_e_best( actualMult[ 0 ] , 0.0 );
368               G4double best = DBL_MAX;
369               G4int maxTry = 1000; 
370               for ( G4int j = 0 ; j < maxTry ; j++ )
371               {
372                  std::vector< G4double > photons_e( actualMult[ 0 ] , 0.0 );
373                  for ( std::vector< G4double >::iterator
374                      it = photons_e.begin() ; it < photons_e.end() ; it++ ) 
375                 {
376                     *it = temp->Sample();   
377                 }
378                 if ( std::accumulate( photons_e.begin() , photons_e.end() , 0.0 ) > maximumE ) 
379                 {
380                    if ( std::accumulate( photons_e.begin() , photons_e.end() , 0.0 ) < best )
381                       photons_e_best = photons_e;
382                    continue;
383                 }
384                 else
385                 {
386                    for ( std::vector< G4double >::iterator
387                        it = photons_e.begin() ; it < photons_e.end() ; it++ ) 
388                    {
389                       thePhotons->operator[](count)->SetKineticEnergy( *it );
390                    } 
391                    //G4cout << "OK " << actualMult[0] << " j " << j << " total photons E  "
392                    //          << std::accumulate( photons_e.begin() , photons_e.end() , 0.0 )/eV << " ratio " << std::accumulate( photons_e.begin() , photons_e.end() , 0.0 ) / maximumE
393                    //          << G4endl;
394                   
395                    break;
396                 }
397                 G4cout << "NeutronHPPhotonDist could not find fitted energy set for multiplicity of " <<  actualMult[0] << "." << G4endl; 
398                 G4cout << "NeutronHPPhotonDist will use the best set." << G4endl; 
399                 for ( std::vector< G4double >::iterator
400                     it = photons_e_best.begin() ; it < photons_e_best.end() ; it++ ) 
401                 {
402                     thePhotons->operator[](count)->SetKineticEnergy( *it );
403                 }
404                 //G4cout << "Not Good " << actualMult[0] << " j " << j << " total photons E  "
405                 //       << best/eV << " ratio " << best / maximumE
406                 //       << G4endl;
407               }
408               // TKDB
409               delete temp;
410            }
411            else    // discrete
412            {
413               thePhotons->operator[](count)->SetKineticEnergy(energy[i]);
414            }
415            count++;
416            if(count    > nSecondaries)  throw G4HadronicException(__FILE__, __LINE__, "G4NeutronHPPhotonDist::GetPhotons inconsistancy");
417        }
418         
419      }
420      else
421      {
422    for(i=0; i<nDiscrete; i++)
423    { 
424      for(ii=0; ii< actualMult[i]; ii++)
425      {   
426        if(disType[i]==1) // continuum
427        {
428          G4double  sum=0, run=0;
429          for(iii=0; iii<nPartials; iii++) sum+=probs[iii].GetY(anEnergy);
430          G4double random = G4UniformRand();
431          G4int theP = 0;
432          for(iii=0; iii<nPartials; iii++)
433          {
434            run+=probs[iii].GetY(anEnergy);
435            theP = iii;
436            if(random<run/sum) break;
437          }
438          if(theP==nPartials) theP=nPartials-1; // das sortiert J aus.
439          sum=0; 
440          G4NeutronHPVector * temp;
441          temp = partials[theP]->GetY(anEnergy); //@@@ look at, seems fishy
442          G4double eGamm = temp->Sample();
443          thePhotons->operator[](count)->SetKineticEnergy(eGamm);
444          delete temp;
445        }
446        else // discrete
447        {
448          thePhotons->operator[](count)->SetKineticEnergy(energy[i]);
449        }
450        count++;
451        if(count > nSecondaries)  throw G4HadronicException(__FILE__, __LINE__, "G4NeutronHPPhotonDist::GetPhotons inconsistancy");
452      }
453    }
454      }
455    // now do the angular distributions...
456    if( isoFlag == 1)
457    {
458      for (i=0; i< nSecondaries; i++)
459      {
460        G4double costheta = 2.*G4UniformRand()-1;
461        G4double theta = std::acos(costheta);
462        G4double phi = twopi*G4UniformRand();
463        G4double sinth = std::sin(theta);
464        G4double en = thePhotons->operator[](i)->GetTotalEnergy();
465        G4ThreeVector temp(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
466        thePhotons->operator[](i)->SetMomentum( temp ) ;
467  //      G4cout << "Isotropic distribution in PhotonDist"<<temp<<G4endl;
468      }
469    }
470    else
471    {
472      for(i=0; i<nSecondaries; i++)
473      { 
474        G4double currentEnergy = thePhotons->operator[](i)->GetTotalEnergy();
475        for(ii=0; ii<nDiscrete2; ii++) 
476        {
477          if (std::abs(currentEnergy-theGammas[ii])<0.1*keV) break;
478        }
479        if(ii==nDiscrete2) ii--; // fix for what seems an (file12 vs file 14) inconsistancy found in the ENDF 7N14 data. @@
480        if(ii<nIso)
481        {
482          // isotropic distribution
483          G4double theta = pi*G4UniformRand();
484          G4double phi = twopi*G4UniformRand();
485          G4double sinth = std::sin(theta);
486          G4double en = thePhotons->operator[](i)->GetTotalEnergy();
487          G4ThreeVector tempVector(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
488          thePhotons->operator[](i)->SetMomentum( tempVector ) ;
489        }
490        else if(tabulationType==1)
491        {
492          // legendre polynomials
493          G4int it(0);
494          for (iii=0; iii<nNeu[ii-nIso]; iii++) // find the neutron energy
495          {
496            it = iii;
497            if(theLegendre[ii-nIso][iii].GetEnergy()>anEnergy)
498              break;
499          }
500          G4NeutronHPLegendreStore aStore(2);
501          aStore.SetCoeff(1, &(theLegendre[ii-nIso][it])); 
502          aStore.SetCoeff(0, &(theLegendre[ii-nIso][it-1])); 
503          G4double cosTh = aStore.SampleMax(anEnergy);
504          G4double theta = std::acos(cosTh);
505          G4double phi = twopi*G4UniformRand();
506          G4double sinth = std::sin(theta);
507          G4double en = thePhotons->operator[](i)->GetTotalEnergy();
508          G4ThreeVector tempVector(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
509          thePhotons->operator[](i)->SetMomentum( tempVector ) ;
510        }
511        else
512        {
513          // tabulation of probabilities.
514          G4int it(0);
515          for (iii=0; iii<nNeu[ii-nIso]; iii++) // find the neutron energy
516          {
517            it = iii;
518            if(theAngular[ii-nIso][iii].GetEnergy()>anEnergy)
519              break;
520          }
521          G4double costh = theAngular[ii-nIso][it].GetCosTh(); // no interpolation yet @@
522          G4double theta = std::acos(costh);
523          G4double phi = twopi*G4UniformRand();
524          G4double sinth = std::sin(theta);
525          G4double en = thePhotons->operator[](i)->GetTotalEnergy();
526          G4ThreeVector tmpVector(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*costh );
527          thePhotons->operator[](i)->SetMomentum( tmpVector ) ;
528        }
529      } 
530    } 
531  }
532  else if(repFlag == 2)
533  {
534    G4double * running = new G4double[nGammaEnergies];
535    running[0]=theTransitionProbabilities[0];
536    G4int i;
537    for(i=1; i<nGammaEnergies; i++)
538    {
539      running[i]=running[i-1]+theTransitionProbabilities[i];
540    }
541    G4double random = G4UniformRand();
542    G4int it=0;
543    for(i=0; i<nGammaEnergies; i++)
544    {
545      it = i;
546      if(random < running[i]/running[nGammaEnergies-1]) break;
547    }
548    delete [] running;
549    G4double totalEnergy = theBaseEnergy - theLevelEnergies[it];
550    G4ReactionProduct * theOne = new G4ReactionProduct;
551    theOne->SetDefinition(G4Gamma::Gamma());
552    random = G4UniformRand();
553    if(theInternalConversionFlag==2 && random>thePhotonTransitionFraction[it])
554    {
555      theOne->SetDefinition(G4Electron::Electron());
556      //Bug reported Chao Zhang (Chao.Zhang@usd.edu), Dongming Mei(Dongming.Mei@usd.edu) Feb. 25, 2009
557      //But never enter at least with G4NDL3.13
558      totalEnergy += G4Electron::Electron()->GetPDGMass(); //proposed correction: add this line for electron
559    }
560    theOne->SetTotalEnergy(totalEnergy);
561    if( isoFlag == 1 )
562    {
563      G4double costheta = 2.*G4UniformRand()-1;
564      G4double theta = std::acos(costheta);
565      G4double phi = twopi*G4UniformRand();
566      G4double sinth = std::sin(theta);
567      //Bug reported Chao Zhang (Chao.Zhang@usd.edu), Dongming Mei(Dongming.Mei@usd.edu) Feb. 25, 2009
568      //G4double en = theOne->GetTotalEnergy();
569      G4double en = theOne->GetTotalMomentum();
570      //But never cause real effect at least with G4NDL3.13 TK
571      G4ThreeVector temp(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
572      theOne->SetMomentum( temp ) ;
573    }
574    else
575    {
576      G4double currentEnergy = theOne->GetTotalEnergy();
577      for(ii=0; ii<nDiscrete2; ii++) 
578      {
579        if (std::abs(currentEnergy-theGammas[ii])<0.1*keV) break;
580      }
581      if(ii==nDiscrete2) ii--; // fix for what seems an (file12 vs file 14) inconsistancy found in the ENDF 7N14 data. @@
582      if(ii<nIso)
583      {
584        //Bug reported Chao Zhang (Chao.Zhang@usd.edu), Dongming Mei(Dongming.Mei@usd.edu) Feb. 25, 2009
585        // isotropic distribution
586        //G4double theta = pi*G4UniformRand();
587        G4double theta = std::acos(2.*G4UniformRand()-1.);
588        //But this is alos never cause real effect at least with G4NDL3.13 TK  not repFlag == 2 AND isoFlag != 1
589        G4double phi = twopi*G4UniformRand();
590        G4double sinth = std::sin(theta);
591        //Bug reported Chao Zhang (Chao.Zhang@usd.edu), Dongming Mei(Dongming.Mei@usd.edu) Feb. 25, 2009
592        //G4double en = theOne->GetTotalEnergy();
593        G4double en = theOne->GetTotalMomentum();
594        //But never cause real effect at least with G4NDL3.13 TK
595        G4ThreeVector tempVector(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
596        theOne->SetMomentum( tempVector ) ;
597      }
598      else if(tabulationType==1)
599      {
600        // legendre polynomials
601        G4int it(0);
602        for (iii=0; iii<nNeu[ii-nIso]; iii++) // find the neutron energy
603        {
604          it = iii;
605          if(theLegendre[ii-nIso][iii].GetEnergy()>anEnergy)
606            break;
607        }
608        G4NeutronHPLegendreStore aStore(2);
609        aStore.SetCoeff(1, &(theLegendre[ii-nIso][it])); 
610        aStore.SetCoeff(0, &(theLegendre[ii-nIso][it-1])); 
611        G4double cosTh = aStore.SampleMax(anEnergy);
612        G4double theta = std::acos(cosTh);
613        G4double phi = twopi*G4UniformRand();
614        G4double sinth = std::sin(theta);
615        //Bug reported Chao Zhang (Chao.Zhang@usd.edu), Dongming Mei(Dongming.Mei@usd.edu) Feb. 25, 2009
616        //G4double en = theOne->GetTotalEnergy();
617        G4double en = theOne->GetTotalMomentum();
618        //But never cause real effect at least with G4NDL3.13 TK
619        G4ThreeVector tempVector(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*std::cos(theta) );
620        theOne->SetMomentum( tempVector ) ;
621      }
622      else
623      {
624        // tabulation of probabilities.
625        G4int it(0);
626        for (iii=0; iii<nNeu[ii-nIso]; iii++) // find the neutron energy
627        {
628          it = iii;
629          if(theAngular[ii-nIso][iii].GetEnergy()>anEnergy)
630            break;
631        }
632        G4double costh = theAngular[ii-nIso][it].GetCosTh(); // no interpolation yet @@
633        G4double theta = std::acos(costh);
634        G4double phi = twopi*G4UniformRand();
635        G4double sinth = std::sin(theta);
636        //Bug reported Chao Zhang (Chao.Zhang@usd.edu), Dongming Mei(Dongming.Mei@usd.edu) Feb. 25, 2009
637        //G4double en = theOne->GetTotalEnergy();
638        G4double en = theOne->GetTotalMomentum();
639        //But never cause real effect at least with G4NDL3.13 TK
640        G4ThreeVector tmpVector(en*sinth*std::cos(phi), en*sinth*std::sin(phi), en*costh );
641        theOne->SetMomentum( tmpVector ) ;
642      }
643    }
644    thePhotons->push_back(theOne);
645  }
646  else if( repFlag==0 )
647  {
648
649// TK add
650      if ( thePartialXsec == 0 ) 
651      {
652         //G4cout << "repFlag is 0, but no PartialXsec data" << G4endl;
653         //G4cout << "This is not support yet." << G4endl;
654         return thePhotons;
655      }
656
657// Partial Case
658
659      G4ReactionProduct * theOne = new G4ReactionProduct;
660      theOne->SetDefinition( G4Gamma::Gamma() );
661      thePhotons->push_back( theOne );
662
663// Energy
664
665      //G4cout << "Partial Case nDiscrete " << nDiscrete << G4endl;
666      G4double sum = 0.0; 
667      std::vector < G4double > dif( nDiscrete , 0.0 ); 
668      for ( G4int i = 0 ; i < nDiscrete ; i++ ) 
669      {
670         G4double x = thePartialXsec[ i ].GetXsec( anEnergy );  // x in barn
671         if ( x > 0 ) 
672         {
673            sum += x;   
674         } 
675         dif [ i ] = sum; 
676         //G4cout << "i " << i << ", x " << x << ", dif " << dif [ i ] << G4endl;
677      }
678     
679      G4double rand = G4UniformRand();
680
681      G4int iphoton = 0; 
682      for ( G4int i = 0 ; i < nDiscrete ; i++ ) 
683      {
684         G4double y = rand*sum; 
685         if ( dif [ i ] > y ) 
686         {
687            iphoton = i; 
688            break; 
689         } 
690      }
691      //G4cout << "iphoton " << iphoton << G4endl;
692      //G4cout << "photon energy " << theGammas[ iphoton ] /eV  << G4endl;
693
694// Angle
695      G4double cosTheta = 0.0; // mu
696
697      if ( isoFlag == 1 )
698      {
699
700//       Isotropic Case
701
702         cosTheta = 2.*G4UniformRand()-1;
703
704      }
705      else
706      {
707
708         if ( iphoton < nIso )
709         {
710
711//          still Isotropic
712
713            cosTheta = 2.*G4UniformRand()-1;
714
715         }
716         else
717         {
718
719            //G4cout << "Not Isotropic and isoFlag " << isoFlag  << G4endl;
720            //G4cout << "tabulationType " << tabulationType << G4endl;
721            //G4cout << "nDiscrete2  " << nDiscrete2 << G4endl;
722            //G4cout << "nIso " << nIso << G4endl;
723            //G4cout << "size of nNeu " << nDiscrete2-nIso << G4endl;
724            //G4cout << "nNeu[iphoton-nIso] " << nNeu[iphoton-nIso] << G4endl;
725
726            if ( tabulationType == 1 )
727            {
728//             legendre polynomials
729
730               G4int iangle = 0; 
731               for ( G4int j = 0 ; j < nNeu [ iphoton - nIso ] ; j++ )
732               {
733                  iangle = j;
734                  if ( theLegendre[ iphoton - nIso ][ j ].GetEnergy() > anEnergy ) break;
735               }
736 
737               G4NeutronHPLegendreStore aStore( 2 );
738               aStore.SetCoeff( 1 , &( theLegendre[ iphoton - nIso ][ iangle ] ) ); 
739               aStore.SetCoeff( 0 , &( theLegendre[ iphoton - nIso ][ iangle - 1 ] ) ); 
740
741               cosTheta = aStore.SampleMax( anEnergy );
742
743            }
744            else if ( tabulationType == 2 )
745            {
746       
747//             tabulation of probabilities.
748
749               G4int iangle = 0; 
750               for ( G4int j = 0 ; j < nNeu [ iphoton - nIso ] ; j++ )
751               {
752                  iangle = j;
753                  if ( theAngular[ iphoton - nIso ][ j ].GetEnergy() > anEnergy ) break;
754               }
755
756               cosTheta = theAngular[iphoton-nIso][ iangle ].GetCosTh(); // no interpolation yet @@
757
758            }
759         }
760      }
761     
762// Set
763      G4double phi = twopi*G4UniformRand();
764      G4double theta = std::acos( cosTheta );
765      G4double sinTheta = std::sin( theta );
766
767      G4double photonE = theGammas[ iphoton ];
768      G4ThreeVector direction ( sinTheta*std::cos( phi ) , sinTheta * std::sin( phi ) , cosTheta );
769      G4ThreeVector photonP = photonE * direction;
770      thePhotons->operator[]( 0 )->SetMomentum( photonP ) ;
771   
772  }
773  else
774  {
775    delete thePhotons;
776    thePhotons = 0; // no gamma data available; some work needed @@@@@@@
777  }   
778  return thePhotons;
779}
780
Note: See TracBrowser for help on using the repository browser.