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

Last change on this file since 1340 was 962, checked in by garnier, 15 years ago

update processes

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