source: trunk/source/processes/hadronic/models/neutron_hp/src/G4NeutronHPChannel.cc @ 829

Last change on this file since 829 was 819, checked in by garnier, 16 years ago

import all except CVS

File size: 8.8 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// 071031 bug fix T. Koi on behalf of A. Howard
32//
33#include "G4NeutronHPChannel.hh"
34#include "G4NeutronHPFinalState.hh"
35#include "globals.hh"
36#include "G4HadTmpUtil.hh"
37
38  G4double G4NeutronHPChannel::GetXsec(G4double energy)
39  {
40    return std::max(0., theChannelData->GetXsec(energy));
41  }
42 
43  G4double G4NeutronHPChannel::GetWeightedXsec(G4double energy, G4int isoNumber)
44  {
45    return theIsotopeWiseData[isoNumber].GetXsec(energy);
46  }
47 
48  G4double G4NeutronHPChannel::GetFSCrossSection(G4double energy, G4int isoNumber)
49  {
50    return theFinalStates[isoNumber]->GetXsec(energy);
51  }
52 
53  void G4NeutronHPChannel::
54  Init(G4Element * anElement, const G4String dirName, const G4String aFSType) 
55  {
56    theFSType = aFSType;
57    Init(anElement, dirName);
58  }
59   
60  void G4NeutronHPChannel::Init(G4Element * anElement, const G4String dirName) 
61  {
62    theDir = dirName;
63    theElement = anElement;
64  }
65 
66  G4bool G4NeutronHPChannel::Register(G4NeutronHPFinalState *theFS)
67  {
68    registerCount++;
69    G4int Z = G4lrint(theElement->GetZ());
70    if(registerCount<5)
71    {
72      Z = Z-registerCount;
73    }
74    //if(Z=theElement->GetZ()-5) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material");
75    // Bug fix by TK on behalf of AH
76    if ( Z <=theElement->GetZ()-5 ) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material");
77    G4int count = 0;
78    if(registerCount==0) count = theElement->GetNumberOfIsotopes();
79    if(count == 0||registerCount!=0) count +=
80         theStableOnes.GetNumberOfIsotopes(Z);
81    niso = count;
82    delete [] theIsotopeWiseData;
83    theIsotopeWiseData = new G4NeutronHPIsoData [niso];
84    delete [] active;
85    active = new G4bool[niso];
86    delete [] theFinalStates;
87    theFinalStates = new G4NeutronHPFinalState * [niso];
88    delete theChannelData;
89    theChannelData = new G4NeutronHPVector; 
90    for(G4int i=0; i<niso; i++)
91    {
92      theFinalStates[i] = theFS->New();
93    }
94    count = 0;
95    G4int nIsos = niso;
96    if(theElement->GetNumberOfIsotopes()!=0&&registerCount==0)
97    {
98      for (G4int i1=0; i1<nIsos; i1++)
99      {
100        // G4cout <<" Init: normal case"<<G4endl;
101        G4int A = theElement->GetIsotope(i1)->GetN();
102        G4double frac = theElement->GetRelativeAbundanceVector()[i1]/perCent;
103        theFinalStates[i1]->SetA_Z(A, Z);
104        UpdateData(A, Z, count++, frac);
105      }
106    } else {
107      //G4cout <<" Init: mean case: "
108      //       <<theStableOnes.GetNumberOfIsotopes(Z)<<" "
109        //     <<Z<<" "<<theElement
110        //     << G4endl;
111      G4int first = theStableOnes.GetFirstIsotope(Z);
112      for(G4int i1=0; 
113        i1<theStableOnes.GetNumberOfIsotopes(Z);
114        i1++)
115      {
116        G4int A = theStableOnes.GetIsotopeNucleonCount(first+i1);
117        G4double frac = theStableOnes.GetAbundance(first+i1);
118        theFinalStates[i1]->SetA_Z(A, Z);
119        UpdateData(A, Z, count++, frac);
120      }
121    }
122    G4bool result = HasDataInAnyFinalState();
123    return result;
124  }
125 
126  void G4NeutronHPChannel::UpdateData(G4int A, G4int Z, G4int index, G4double abundance)
127  {
128    theFinalStates[index]->Init(A, Z, theDir, theFSType);
129    if(!theFinalStates[index]->HasAnyData()) return; // nothing there for exactly this isotope.
130
131    // the above has put the X-sec into the FS
132    theBuffer = 0;
133    if(theFinalStates[index]->HasXsec())
134    {
135      theBuffer = theFinalStates[index]->GetXsec();
136      theBuffer->Times(abundance/100.);
137      theIsotopeWiseData[index].FillChannelData(theBuffer);
138    }
139    else // get data from CrossSection directory
140    {
141      G4String tString = "/CrossSection/";
142      active[index] = theIsotopeWiseData[index].Init(A, Z, abundance, theDir, tString);
143      if(active[index]) theBuffer = theIsotopeWiseData[index].MakeChannelData();
144    }
145    if(theBuffer != 0) Harmonise(theChannelData, theBuffer);
146  }
147 
148  void G4NeutronHPChannel::Harmonise(G4NeutronHPVector *& theStore, G4NeutronHPVector * theNew)
149  {
150    G4int s = 0, n=0, m=0;
151    G4NeutronHPVector * theMerge = new G4NeutronHPVector;
152    G4NeutronHPVector * anActive = theStore;
153    G4NeutronHPVector * aPassive = theNew;
154    G4NeutronHPVector * tmp;
155    G4int a = s, p = n, t;
156    while (a<anActive->GetVectorLength()&&p<aPassive->GetVectorLength())
157    {
158      if(anActive->GetEnergy(a) <= aPassive->GetEnergy(p))
159      {
160        G4double xa  = anActive->GetEnergy(a);
161        theMerge->SetData(m, xa, anActive->GetXsec(a)+std::max(0., aPassive->GetXsec(xa)) );
162        m++;
163        a++;
164        G4double xp = aPassive->GetEnergy(p);
165        if( std::abs(std::abs(xp-xa)/xa)<0.001 )
166        {
167          p++;
168        }
169      } else {
170        tmp = anActive; t=a;
171        anActive = aPassive; a=p;
172        aPassive = tmp; p=t;
173      }
174    }
175    while (a!=anActive->GetVectorLength())
176    {
177      theMerge->SetData(m++, anActive->GetEnergy(a), anActive->GetXsec(a));
178      a++;
179    }
180    while (p!=aPassive->GetVectorLength())
181    {
182      if(std::abs(theMerge->GetEnergy(std::max(0,m-1))-aPassive->GetEnergy(p))/aPassive->GetEnergy(p)>0.001)
183        theMerge->SetData(m++, aPassive->GetEnergy(p), aPassive->GetXsec(p));
184      p++;
185    }
186    delete theStore;
187    theStore = theMerge;
188  }
189
190#include "G4NeutronHPThermalBoost.hh"
191
192  G4HadFinalState * G4NeutronHPChannel::
193  ApplyYourself(const G4HadProjectile & theTrack, G4int anIsotope)
194  {
195//    G4cout << "G4NeutronHPChannel::ApplyYourself+"<<niso<<G4endl;
196    if(anIsotope != -1) return theFinalStates[anIsotope]->ApplyYourself(theTrack);
197    G4double sum=0;
198    G4int it=0;
199    G4double * xsec = new G4double[niso];
200    G4NeutronHPThermalBoost aThermalE;
201    for (G4int i=0; i<niso; i++)
202    {
203      if(theFinalStates[i]->HasAnyData())
204      {
205        xsec[i] = theIsotopeWiseData[i].GetXsec(aThermalE.GetThermalEnergy(theTrack,
206                                                                           theFinalStates[i]->GetN(),
207                                                                           theFinalStates[i]->GetZ(),
208                                                                           theTrack.GetMaterial()->GetTemperature()));
209        sum += xsec[i];
210      }
211      else
212      {
213        xsec[i]=0;
214      }
215    } 
216    if(sum == 0) 
217    {
218//      G4cout << "G4NeutronHPChannel::ApplyYourself theFinalState->Initialize+"<<G4endl;
219//      G4cout << "G4NeutronHPChannel::ApplyYourself theFinalState->Initialize-"<<G4endl;
220      it = static_cast<G4int>(niso*G4UniformRand());
221    }
222    else
223    {
224//      G4cout << "Are we still here? "<<sum<<G4endl;
225//      G4cout << "TESTHP 23 NISO="<<niso<<G4endl;
226      G4double random = G4UniformRand();
227      G4double running=0;
228//      G4cout << "G4NeutronHPChannel::ApplyYourself Done the sum"<<niso<<G4endl;
229//      G4cout << "TESTHP 24 NISO="<<niso<<G4endl;
230      for (G4int ix=0; ix<niso; ix++)
231      {
232        running += xsec[ix];
233        //if(random<=running/sum)
234        if( sum == 0 || random <= running/sum ) 
235        { 
236          it = ix;
237          break;
238        }
239      }
240      if(it==niso) it--;
241    }
242    delete [] xsec;
243    G4HadFinalState * theFinalState=0;
244    while(theFinalState==0)
245    {
246//    G4cout << "TESTHP 24 it="<<it<<G4endl;
247      theFinalState = theFinalStates[it]->ApplyYourself(theTrack);
248    }
249//    G4cout <<"THE IMPORTANT RETURN"<<G4endl;
250    return theFinalState;
251  }
252
Note: See TracBrowser for help on using the repository browser.