G4NeutronHPChannel.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 // neutron_hp -- source file
00027 // J.P. Wellisch, Nov-1996
00028 // A prototype of the low energy neutron transport model.
00029 //
00030 // 070523 bug fix for G4FPE_DEBUG on by A. Howard ( and T. Koi)
00031 // 071031 bug fix T. Koi on behalf of A. Howard 
00032 // 081203 bug fix in Register method by T. Koi
00033 //
00034 #include "G4NeutronHPChannel.hh"
00035 #include "globals.hh"
00036 #include "G4SystemOfUnits.hh"
00037 #include "G4NeutronHPFinalState.hh"
00038 #include "G4HadTmpUtil.hh"
00039 
00040 #include "G4NeutronHPManager.hh"
00041 #include "G4NeutronHPReactionWhiteBoard.hh"
00042 
00043   G4double G4NeutronHPChannel::GetXsec(G4double energy)
00044   {
00045     return std::max(0., theChannelData->GetXsec(energy));
00046   }
00047   
00048   G4double G4NeutronHPChannel::GetWeightedXsec(G4double energy, G4int isoNumber)
00049   {
00050     return theIsotopeWiseData[isoNumber].GetXsec(energy);
00051   }
00052   
00053   G4double G4NeutronHPChannel::GetFSCrossSection(G4double energy, G4int isoNumber)
00054   {
00055     return theFinalStates[isoNumber]->GetXsec(energy);
00056   }
00057   
00058   void G4NeutronHPChannel::
00059   Init(G4Element * anElement, const G4String dirName, const G4String aFSType) 
00060   {
00061     theFSType = aFSType;
00062     Init(anElement, dirName);
00063   }
00064    
00065   void G4NeutronHPChannel::Init(G4Element * anElement, const G4String dirName)  
00066   {
00067     theDir = dirName;
00068     theElement = anElement;
00069   }
00070   
00071   G4bool G4NeutronHPChannel::Register(G4NeutronHPFinalState *theFS)
00072   {
00073     registerCount++;
00074     G4int Z = G4lrint(theElement->GetZ());
00075 
00076     Z = Z-registerCount;
00077     if ( registerCount > 5 ) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material"); // for Elastic, Capture, Fission case 
00078     if ( Z < 1 ) return false; 
00079 /*
00080     if(registerCount<5)
00081     {
00082       Z = Z-registerCount;
00083     }
00084 */
00085     //if(Z=theElement->GetZ()-5) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material");
00086     // Bug fix by TK on behalf of AH
00087     if ( Z <=theElement->GetZ()-5 ) throw G4HadronicException(__FILE__, __LINE__, "Channel: Do not know what to do with this material");
00088     G4int count = 0;
00089     if(registerCount==0) count = theElement->GetNumberOfIsotopes();
00090     if(count == 0||registerCount!=0) count +=
00091          theStableOnes.GetNumberOfIsotopes(Z);
00092     niso = count;
00093     delete [] theIsotopeWiseData;
00094     theIsotopeWiseData = new G4NeutronHPIsoData [niso];
00095     delete [] active;
00096     active = new G4bool[niso];
00097 
00098     delete [] theFinalStates;
00099     theFinalStates = new G4NeutronHPFinalState * [niso];
00100     delete theChannelData;
00101     theChannelData = new G4NeutronHPVector; 
00102     for(G4int i=0; i<niso; i++)
00103     {
00104       theFinalStates[i] = theFS->New();
00105     }
00106     count = 0;
00107     G4int nIsos = niso;
00108     if(theElement->GetNumberOfIsotopes()!=0&&registerCount==0)
00109     {
00110       for (G4int i1=0; i1<nIsos; i1++)
00111       {
00112         // G4cout <<" Init: normal case"<<G4endl;
00113         G4int A = theElement->GetIsotope(i1)->GetN();
00114         G4int M = theElement->GetIsotope(i1)->Getm();
00115         G4double frac = theElement->GetRelativeAbundanceVector()[i1]/perCent;
00116         //theFinalStates[i1]->SetA_Z(A, Z);
00117         //UpdateData(A, Z, count++, frac);
00118         theFinalStates[i1]->SetA_Z(A, Z, M);
00119         UpdateData(A, Z, M, count++, frac);
00120       }
00121     } else {
00122       //G4cout <<" Init: mean case: "
00123       //       <<theStableOnes.GetNumberOfIsotopes(Z)<<" "
00124         //     <<Z<<" "<<theElement
00125         //     << G4endl;
00126       G4int first = theStableOnes.GetFirstIsotope(Z);
00127       for(G4int i1=0; 
00128         i1<theStableOnes.GetNumberOfIsotopes(Z);
00129         i1++)
00130       {
00131         G4int A = theStableOnes.GetIsotopeNucleonCount(first+i1);
00132         G4double frac = theStableOnes.GetAbundance(first+i1);
00133         theFinalStates[i1]->SetA_Z(A, Z);
00134         UpdateData(A, Z, count++, frac);
00135       }
00136     }
00137     G4bool result = HasDataInAnyFinalState();
00138     return result;
00139   }
00140   
00141   //void G4NeutronHPChannel::UpdateData(G4int A, G4int Z, G4int index, G4double abundance)
00142   void G4NeutronHPChannel::UpdateData(G4int A, G4int Z, G4int M, G4int index, G4double abundance)
00143   {
00144     //theFinalStates[index]->Init(A, Z, theDir, theFSType);
00145     theFinalStates[index]->Init(A, Z, M, theDir, theFSType);
00146     if(!theFinalStates[index]->HasAnyData()) return; // nothing there for exactly this isotope.
00147 
00148     // the above has put the X-sec into the FS
00149     theBuffer = 0;
00150     if(theFinalStates[index]->HasXsec())
00151     {
00152       theBuffer = theFinalStates[index]->GetXsec();
00153       theBuffer->Times(abundance/100.);
00154       theIsotopeWiseData[index].FillChannelData(theBuffer);
00155     }
00156     else // get data from CrossSection directory
00157     {
00158       G4String tString = "/CrossSection";
00159       //active[index] = theIsotopeWiseData[index].Init(A, Z, abundance, theDir, tString);
00160       active[index] = theIsotopeWiseData[index].Init(A, Z, M, abundance, theDir, tString);
00161       if(active[index]) theBuffer = theIsotopeWiseData[index].MakeChannelData();
00162     }
00163     if(theBuffer != 0) Harmonise(theChannelData, theBuffer);
00164   }
00165   
00166   void G4NeutronHPChannel::Harmonise(G4NeutronHPVector *& theStore, G4NeutronHPVector * theNew)
00167   {
00168     G4int s_tmp = 0, n=0, m_tmp=0;
00169     G4NeutronHPVector * theMerge = new G4NeutronHPVector;
00170     G4NeutronHPVector * anActive = theStore;
00171     G4NeutronHPVector * aPassive = theNew;
00172     G4NeutronHPVector * tmp;
00173     G4int a = s_tmp, p = n, t;
00174     while (a<anActive->GetVectorLength()&&p<aPassive->GetVectorLength())
00175     {
00176       if(anActive->GetEnergy(a) <= aPassive->GetEnergy(p))
00177       {
00178         G4double xa  = anActive->GetEnergy(a);
00179         theMerge->SetData(m_tmp, xa, anActive->GetXsec(a)+std::max(0., aPassive->GetXsec(xa)) );
00180         m_tmp++;
00181         a++;
00182         G4double xp = aPassive->GetEnergy(p);
00183         if( std::abs(std::abs(xp-xa)/xa)<0.001 )
00184         {
00185           p++;
00186         }
00187       } else {
00188         tmp = anActive; t=a;
00189         anActive = aPassive; a=p;
00190         aPassive = tmp; p=t;
00191       }
00192     }
00193     while (a!=anActive->GetVectorLength())
00194     {
00195       theMerge->SetData(m_tmp++, anActive->GetEnergy(a), anActive->GetXsec(a));
00196       a++;
00197     }
00198     while (p!=aPassive->GetVectorLength())
00199     {
00200       if(std::abs(theMerge->GetEnergy(std::max(0,m_tmp-1))-aPassive->GetEnergy(p))/aPassive->GetEnergy(p)>0.001)
00201         theMerge->SetData(m_tmp++, aPassive->GetEnergy(p), aPassive->GetXsec(p));
00202       p++;
00203     }
00204     delete theStore;
00205     theStore = theMerge;
00206   }
00207 
00208 #include "G4NeutronHPThermalBoost.hh"
00209 
00210   G4HadFinalState * G4NeutronHPChannel::
00211   ApplyYourself(const G4HadProjectile & theTrack, G4int anIsotope)
00212   {
00213 //    G4cout << "G4NeutronHPChannel::ApplyYourself+"<<niso<<G4endl;
00214     if ( anIsotope != -1 ) 
00215     {
00216        //Inelastic Case
00217        //G4cout << "G4NeutronHPChannel Inelastic Case" 
00218        //<< " Z= " << this->GetZ(it) << " A = " << this->GetN(it) << G4endl;
00219        G4NeutronHPManager::GetInstance()->GetReactionWhiteBoard()->SetTargA( (G4int)this->GetN(anIsotope) ); 
00220        G4NeutronHPManager::GetInstance()->GetReactionWhiteBoard()->SetTargZ( (G4int)this->GetZ(anIsotope) ); 
00221        return theFinalStates[anIsotope]->ApplyYourself(theTrack);
00222     }
00223     G4double sum=0;
00224     G4int it=0;
00225     G4double * xsec = new G4double[niso];
00226     G4NeutronHPThermalBoost aThermalE;
00227     for (G4int i=0; i<niso; i++)
00228     {
00229       if(theFinalStates[i]->HasAnyData())
00230       {
00231         xsec[i] = theIsotopeWiseData[i].GetXsec(aThermalE.GetThermalEnergy(theTrack,
00232                                                                            theFinalStates[i]->GetN(),
00233                                                                            theFinalStates[i]->GetZ(),
00234                                                                            theTrack.GetMaterial()->GetTemperature()));
00235         sum += xsec[i];
00236       }
00237       else
00238       {
00239         xsec[i]=0;
00240       }
00241     } 
00242     if(sum == 0) 
00243     {
00244 //      G4cout << "G4NeutronHPChannel::ApplyYourself theFinalState->Initialize+"<<G4endl;
00245 //      G4cout << "G4NeutronHPChannel::ApplyYourself theFinalState->Initialize-"<<G4endl;
00246       it = static_cast<G4int>(niso*G4UniformRand());
00247     }
00248     else
00249     {
00250 //      G4cout << "Are we still here? "<<sum<<G4endl;
00251 //      G4cout << "TESTHP 23 NISO="<<niso<<G4endl;
00252       G4double random = G4UniformRand();
00253       G4double running=0;
00254 //      G4cout << "G4NeutronHPChannel::ApplyYourself Done the sum"<<niso<<G4endl;
00255 //      G4cout << "TESTHP 24 NISO="<<niso<<G4endl;
00256       for (G4int ix=0; ix<niso; ix++)
00257       {
00258         running += xsec[ix];
00259         //if(random<=running/sum) 
00260         if( sum == 0 || random <= running/sum ) 
00261         { 
00262           it = ix;
00263           break;
00264         }
00265       }
00266       if(it==niso) it--;
00267     }
00268     delete [] xsec;
00269     G4HadFinalState * theFinalState=0;
00270     while(theFinalState==0)
00271     {
00272 //    G4cout << "TESTHP 24 it="<<it<<G4endl;
00273       theFinalState = theFinalStates[it]->ApplyYourself(theTrack);
00274     }
00275 //    G4cout <<"THE IMPORTANT RETURN"<<G4endl;
00276       //G4cout << "TK G4NeutronHPChannel Elastic, Capture and Fission Cases " 
00277       //<< " Z= " << this->GetZ(it) << " A = " << this->GetN(it) << G4endl;
00278     G4NeutronHPManager::GetInstance()->GetReactionWhiteBoard()->SetTargA( (G4int)this->GetN(it) ); 
00279     G4NeutronHPManager::GetInstance()->GetReactionWhiteBoard()->SetTargZ( (G4int)this->GetZ(it) ); 
00280     return theFinalState;
00281   }
00282 

Generated on Mon May 27 17:48:59 2013 for Geant4 by  doxygen 1.4.7