G4PenelopeIonisationXSHandler.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 // $Id$
00027 //
00028 // Author: Luciano Pandola
00029 //
00030 // History:
00031 // --------
00032 // 08 Mar 2012   L Pandola    First complete implementation
00033 //
00034 
00035 #include "G4PenelopeIonisationXSHandler.hh"
00036 #include "G4PhysicalConstants.hh"
00037 #include "G4SystemOfUnits.hh"
00038 #include "G4ParticleDefinition.hh"
00039 #include "G4Electron.hh"
00040 #include "G4Positron.hh"
00041 #include "G4PenelopeOscillatorManager.hh"
00042 #include "G4PenelopeOscillator.hh"
00043 #include "G4PenelopeCrossSection.hh"
00044 #include "G4PhysicsFreeVector.hh"
00045 #include "G4PhysicsLogVector.hh" 
00046 
00047 G4PenelopeIonisationXSHandler::G4PenelopeIonisationXSHandler(size_t nb)
00048   :XSTableElectron(0),XSTablePositron(0),
00049    theDeltaTable(0),energyGrid(0)
00050 {
00051   nBins = nb;
00052   G4double LowEnergyLimit = 100.0*eV;
00053   G4double HighEnergyLimit = 100.0*GeV;
00054   oscManager = G4PenelopeOscillatorManager::GetOscillatorManager();
00055   XSTableElectron = new 
00056     std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>;
00057   XSTablePositron = new 
00058     std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>;
00059 
00060   theDeltaTable = new std::map<const G4Material*,G4PhysicsFreeVector*>;
00061   energyGrid = new G4PhysicsLogVector(LowEnergyLimit,
00062                                       HighEnergyLimit, 
00063                                       nBins-1); //one hidden bin is added
00064 
00065   verboseLevel = 0;
00066 }
00067 
00068 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
00069  
00070 G4PenelopeIonisationXSHandler::~G4PenelopeIonisationXSHandler()
00071 {
00072   std::map< std::pair<const G4Material*,G4double>, G4PenelopeCrossSection*>::iterator i;
00073   if (XSTableElectron)
00074     {
00075       for (i=XSTableElectron->begin(); i != XSTableElectron->end(); i++)
00076         {
00077           G4PenelopeCrossSection* tab = i->second;
00078           delete tab;
00079         }
00080       delete XSTableElectron;
00081       XSTableElectron = 0;
00082     }
00083 
00084   if (XSTablePositron)
00085     {
00086       for (i=XSTablePositron->begin(); i != XSTablePositron->end(); i++)
00087         {
00088           G4PenelopeCrossSection* tab = i->second;
00089           delete tab;
00090         }
00091       delete XSTablePositron;
00092       XSTablePositron = 0;
00093     }
00094 
00095   std::map<const G4Material*,G4PhysicsFreeVector*>::iterator k;
00096   if (theDeltaTable)
00097     {
00098       for (k=theDeltaTable->begin();k!=theDeltaTable->end();k++)        
00099         delete k->second;
00100       delete theDeltaTable;
00101       theDeltaTable = 0;
00102     }
00103     
00104   if (energyGrid)
00105     delete energyGrid;
00106 
00107   if (verboseLevel > 2)
00108     G4cout << "G4PenelopeIonisationXSHandler. Tables have been cleared" 
00109            << G4endl;
00110 }
00111 
00112 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
00113 
00114 G4PenelopeCrossSection* 
00115 G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple(const G4ParticleDefinition* part,
00116                                                                 const G4Material* mat,
00117                                                                 G4double cut)
00118 {
00119   if (part != G4Electron::Electron() && part != G4Positron::Positron())
00120     {
00121       G4ExceptionDescription ed;
00122       ed << "Invalid particle: " << part->GetParticleName() << G4endl;
00123       G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
00124                   "em0001",FatalException,ed);
00125       return NULL;
00126     }
00127 
00128   if (part == G4Electron::Electron())
00129     {
00130       if (!XSTableElectron)
00131         {
00132           G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
00133                       "em0028",FatalException,  
00134                       "The Cross Section Table for e- was not initialized correctly!");
00135           return NULL;
00136         }
00137       std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
00138       if (XSTableElectron->count(theKey)) //table already built 
00139         return XSTableElectron->find(theKey)->second;
00140       else
00141         {
00142           BuildXSTable(mat,cut,part);
00143           if (XSTableElectron->count(theKey)) //now it should be ok!
00144             return XSTableElectron->find(theKey)->second;
00145           else
00146             {
00147               G4ExceptionDescription ed;
00148               ed << "Unable to build e- table for " << mat->GetName() << G4endl;
00149               G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
00150                           "em0029",FatalException,ed);     
00151             }
00152         }
00153     }
00154 
00155   if (part == G4Positron::Positron())
00156     {
00157       if (!XSTablePositron)
00158         {
00159           G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
00160                       "em0028",FatalException,  
00161                       "The Cross Section Table for e+ was not initialized correctly!");
00162           return NULL;
00163         }
00164       std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
00165       if (XSTablePositron->count(theKey)) //table already built 
00166         return XSTablePositron->find(theKey)->second;
00167       else
00168         {
00169           BuildXSTable(mat,cut,part);
00170           if (XSTablePositron->count(theKey)) //now it should be ok!
00171             return XSTablePositron->find(theKey)->second;
00172           else
00173             {
00174               G4ExceptionDescription ed;
00175               ed << "Unable to build e+ table for " << mat->GetName() << G4endl;
00176               G4Exception("G4PenelopeIonisationXSHandler::GetCrossSectionTableForCouple()",
00177                           "em0029",FatalException,ed);             
00178             }
00179         }
00180     }
00181   return NULL;
00182 }
00183 
00184 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
00185 
00186 void G4PenelopeIonisationXSHandler::BuildXSTable(const G4Material* mat,G4double cut,
00187                                              const G4ParticleDefinition* part)
00188 {
00189   //
00190   //This method fills the G4PenelopeCrossSection containers for electrons or positrons
00191   //and for the given material/cut couple. The calculation is done as sum over the 
00192   //individual shells.
00193   //Equivalent of subroutines EINaT and PINaT of Penelope
00194   //
00195   if (verboseLevel > 2)
00196     {
00197       G4cout << "G4PenelopeIonisationXSHandler: going to build cross section table " << G4endl;
00198       G4cout << "for " << part->GetParticleName() << " in " << mat->GetName() << G4endl;
00199     }
00200 
00201   //Tables have been already created (checked by GetCrossSectionTableForCouple)
00202   G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableIonisation(mat);
00203   size_t numberOfOscillators = theTable->size();
00204 
00205   if (energyGrid->GetVectorLength() != nBins) 
00206     {
00207       G4ExceptionDescription ed;
00208       ed << "Energy Grid looks not initialized" << G4endl;
00209       ed << nBins << " " << energyGrid->GetVectorLength() << G4endl;
00210       G4Exception("G4PenelopeIonisationXSHandler::BuildXSTable()",
00211                   "em2030",FatalException,ed);
00212     }
00213 
00214   G4PenelopeCrossSection* XSEntry = new G4PenelopeCrossSection(nBins,numberOfOscillators);
00215  
00216   //loop on the energy grid
00217   for (size_t bin=0;bin<nBins;bin++)
00218     {
00219        G4double energy = energyGrid->GetLowEdgeEnergy(bin);
00220        G4double XH0=0, XH1=0, XH2=0;
00221        G4double XS0=0, XS1=0, XS2=0;
00222    
00223        //oscillator loop
00224        for (size_t iosc=0;iosc<numberOfOscillators;iosc++)
00225          {
00226            G4DataVector* tempStorage = 0;
00227 
00228            G4PenelopeOscillator* theOsc = (*theTable)[iosc];
00229            G4double delta = GetDensityCorrection(mat,energy);
00230            if (part == G4Electron::Electron())       
00231              tempStorage = ComputeShellCrossSectionsElectron(theOsc,energy,cut,delta);
00232            else if (part == G4Positron::Positron())
00233              tempStorage = ComputeShellCrossSectionsPositron(theOsc,energy,cut,delta);
00234            //check results are all right
00235            if (!tempStorage)
00236              {
00237                G4ExceptionDescription ed;
00238                ed << "Problem in calculating the shell XS for shell # " 
00239                   << iosc << G4endl;
00240                G4Exception("G4PenelopeIonisationXSHandler::BuildXSTable()",
00241                            "em2031",FatalException,ed);                    
00242                delete XSEntry;
00243                return;
00244              }
00245            if (tempStorage->size() != 6)
00246              {
00247                G4ExceptionDescription ed;
00248                ed << "Problem in calculating the shell XS " << G4endl;
00249                ed << "Result has dimension " << tempStorage->size() << " instead of 6" << G4endl;
00250                G4Exception("G4PenelopeIonisationXSHandler::BuildXSTable()",
00251                            "em2031",FatalException,ed); 
00252              }
00253            G4double stre = theOsc->GetOscillatorStrength();
00254 
00255            XH0 += stre*(*tempStorage)[0];
00256            XH1 += stre*(*tempStorage)[1];
00257            XH2 += stre*(*tempStorage)[2];
00258            XS0 += stre*(*tempStorage)[3];
00259            XS1 += stre*(*tempStorage)[4];
00260            XS2 += stre*(*tempStorage)[5];
00261            XSEntry->AddShellCrossSectionPoint(bin,iosc,energy,stre*(*tempStorage)[0]);
00262            if (tempStorage)
00263              {
00264                delete tempStorage;
00265                tempStorage = 0;
00266              }
00267          }       
00268        XSEntry->AddCrossSectionPoint(bin,energy,XH0,XH1,XH2,XS0,XS1,XS2);
00269     }
00270 
00271   //Insert in the appropriate table
00272   std::pair<const G4Material*,G4double> theKey = std::make_pair(mat,cut);
00273   if (part == G4Electron::Electron())      
00274     XSTableElectron->insert(std::make_pair(theKey,XSEntry));
00275   else if (part == G4Positron::Positron())
00276     XSTablePositron->insert(std::make_pair(theKey,XSEntry));
00277   else
00278     delete XSEntry;
00279   
00280   return;
00281 }
00282 
00283 
00284 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
00285 
00286 G4double G4PenelopeIonisationXSHandler::GetDensityCorrection(const G4Material* mat,
00287                                                          G4double energy)
00288 {
00289   G4double result = 0;
00290   if (!theDeltaTable)
00291     {
00292       G4Exception("G4PenelopeIonisationXSHandler::GetDensityCorrection()",
00293                   "em2032",FatalException,
00294                   "Delta Table not initialized. Was Initialise() run?");
00295       return 0;
00296     }
00297   if (energy <= 0*eV)
00298     {
00299       G4cout << "G4PenelopeIonisationXSHandler::GetDensityCorrection()" << G4endl;
00300       G4cout << "Invalid energy " << energy/eV << " eV " << G4endl;
00301       return 0;
00302     }
00303   G4double logene = std::log(energy);
00304 
00305   //check if the material has been built
00306   if (!(theDeltaTable->count(mat)))
00307     BuildDeltaTable(mat);
00308 
00309   if (theDeltaTable->count(mat))
00310     {
00311       G4PhysicsFreeVector* vec = theDeltaTable->find(mat)->second;
00312       result = vec->Value(logene); //the table has delta vs. ln(E)      
00313     }
00314   else
00315     {
00316       G4ExceptionDescription ed;      
00317       ed << "Unable to build table for " << mat->GetName() << G4endl;
00318       G4Exception("G4PenelopeIonisationXSHandler::GetDensityCorrection()",
00319                   "em2033",FatalException,ed);
00320     }
00321 
00322   return result;
00323 }
00324 
00325 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
00326 
00327 void G4PenelopeIonisationXSHandler::BuildDeltaTable(const G4Material* mat)
00328 {
00329   G4PenelopeOscillatorTable* theTable = oscManager->GetOscillatorTableIonisation(mat);
00330   G4double plasmaSq = oscManager->GetPlasmaEnergySquared(mat);
00331   G4double totalZ = oscManager->GetTotalZ(mat);
00332   size_t numberOfOscillators = theTable->size();
00333 
00334   if (energyGrid->GetVectorLength() != nBins) 
00335     {
00336       G4ExceptionDescription ed;
00337       ed << "Energy Grid for Delta table looks not initialized" << G4endl;
00338       ed << nBins << " " << energyGrid->GetVectorLength() << G4endl;
00339       G4Exception("G4PenelopeIonisationXSHandler::BuildDeltaTable()",
00340                   "em2030",FatalException,ed);
00341     }
00342 
00343   G4PhysicsFreeVector* theVector = new G4PhysicsFreeVector(nBins);
00344 
00345   //loop on the energy grid
00346   for (size_t bin=0;bin<nBins;bin++)
00347     {
00348       G4double delta = 0.;
00349       G4double energy = energyGrid->GetLowEdgeEnergy(bin);
00350 
00351       //Here calculate delta
00352       G4double gam = 1.0+(energy/electron_mass_c2);
00353       G4double gamSq = gam*gam;
00354 
00355       G4double TST = totalZ/(gamSq*plasmaSq);
00356       G4double wl2 = 0;
00357       G4double fdel = 0;
00358 
00359       //loop on oscillators
00360       for (size_t i=0;i<numberOfOscillators;i++)
00361         {
00362           G4PenelopeOscillator* theOsc = (*theTable)[i];
00363           G4double wri = theOsc->GetResonanceEnergy();
00364           fdel += theOsc->GetOscillatorStrength()/(wri*wri+wl2);
00365         }      
00366       if (fdel >= TST) //if fdel < TST, delta = 0
00367         {
00368           //get last oscillator
00369           G4PenelopeOscillator* theOsc = (*theTable)[numberOfOscillators-1]; 
00370           wl2 = theOsc->GetResonanceEnergy()*theOsc->GetResonanceEnergy();
00371           
00372           //First iteration
00373           G4bool loopAgain = false;
00374           do
00375             {
00376               loopAgain = false;
00377               wl2 += wl2;
00378               fdel = 0.;
00379               for (size_t i=0;i<numberOfOscillators;i++)
00380                 {
00381                   G4PenelopeOscillator* theOscLocal1 = (*theTable)[i];
00382                   G4double wri = theOscLocal1->GetResonanceEnergy();
00383                   fdel += theOscLocal1->GetOscillatorStrength()/(wri*wri+wl2);
00384                 }
00385               if (fdel > TST)
00386                 loopAgain = true;
00387             }while(loopAgain);
00388 
00389           G4double wl2l = 0;
00390           G4double wl2u = wl2;
00391           //second iteration
00392           do
00393             {        
00394               loopAgain = false;
00395               wl2 = 0.5*(wl2l+wl2u);
00396               fdel = 0;
00397               for (size_t i=0;i<numberOfOscillators;i++)
00398                 {
00399                   G4PenelopeOscillator* theOscLocal2 = (*theTable)[i];
00400                   G4double wri = theOscLocal2->GetResonanceEnergy();
00401                   fdel += theOscLocal2->GetOscillatorStrength()/(wri*wri+wl2);
00402                 }
00403               if (fdel > TST)
00404                 wl2l = wl2;
00405               else
00406                 wl2u = wl2;
00407               if ((wl2u-wl2l)>1e-12*wl2)
00408                 loopAgain = true;
00409             }while(loopAgain);
00410           
00411           //Eventually get density correction
00412           delta = 0.;
00413           for (size_t i=0;i<numberOfOscillators;i++)
00414             {
00415               G4PenelopeOscillator* theOscLocal3 = (*theTable)[i];
00416               G4double wri = theOscLocal3->GetResonanceEnergy();
00417               delta += theOscLocal3->GetOscillatorStrength()*
00418                 std::log(1.0+(wl2/(wri*wri)));               
00419             }
00420           delta = (delta/totalZ)-wl2/(gamSq*plasmaSq);
00421         }
00422       energy = std::max(1e-9*eV,energy); //prevents log(0)
00423       theVector->PutValue(bin,std::log(energy),delta);
00424     }
00425   theDeltaTable->insert(std::make_pair(mat,theVector));
00426   return;
00427 }
00428                                                         
00429 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
00430 G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsElectron(G4PenelopeOscillator* theOsc,
00431                                                                                   G4double energy,
00432                                                                                   G4double cut,
00433                                                                                   G4double delta)
00434 {
00435   //
00436   //This method calculates the hard and soft cross sections (H0-H1-H2-S0-S1-S2) for 
00437   //the given oscillator/cut and at the given energy.
00438   //It returns a G4DataVector* with 6 entries (H0-H1-H2-S0-S1-S2)
00439   //Equivalent of subroutines EINaT1 of Penelope
00440   //
00441   // Results are _per target electron_
00442   //
00443   G4DataVector* result = new G4DataVector();
00444   for (size_t i=0;i<6;i++)
00445     result->push_back(0.);
00446   G4double ionEnergy = theOsc->GetIonisationEnergy();
00447   
00448   //return a set of zero's if the energy it too low to excite the current oscillator
00449   if (energy < ionEnergy)
00450     return result;
00451 
00452   G4double H0=0.,H1=0.,H2=0.;
00453   G4double S0=0.,S1=0.,S2=0.;
00454 
00455   //Define useful constants to be used in the calculation
00456   G4double gamma = 1.0+energy/electron_mass_c2;
00457   G4double gammaSq = gamma*gamma;
00458   G4double beta = (gammaSq-1.0)/gammaSq;
00459   G4double pielr2 = pi*classic_electr_radius*classic_electr_radius; //pi*re^2
00460   G4double constant = pielr2*2.0*electron_mass_c2/beta;
00461   G4double XHDT0 = std::log(gammaSq)-beta;
00462 
00463   G4double cpSq = energy*(energy+2.0*electron_mass_c2);
00464   G4double cp = std::sqrt(cpSq);
00465   G4double amol = (energy/(energy+electron_mass_c2))*(energy/(energy+electron_mass_c2));
00466 
00467   //
00468   // Distant interactions
00469   //
00470   G4double resEne = theOsc->GetResonanceEnergy();
00471   G4double cutoffEne = theOsc->GetCutoffRecoilResonantEnergy();
00472   if (energy > resEne)
00473     {
00474       G4double cp1Sq = (energy-resEne)*(energy-resEne+2.0*electron_mass_c2);
00475       G4double cp1 = std::sqrt(cp1Sq);
00476       
00477       //Distant longitudinal interactions
00478       G4double QM = 0;
00479       if (resEne > 1e-6*energy)
00480         QM = std::sqrt((cp-cp1)*(cp-cp1)+electron_mass_c2*electron_mass_c2)-electron_mass_c2;
00481       else
00482         {
00483           QM = resEne*resEne/(beta*2.0*electron_mass_c2);
00484           QM = QM*(1.0-0.5*QM/electron_mass_c2);
00485         }
00486       G4double SDL1 = 0;
00487       if (QM < cutoffEne)
00488         SDL1 = std::log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
00489       
00490       //Distant transverse interactions
00491       if (SDL1)
00492         {
00493           G4double SDT1 = std::max(XHDT0-delta,0.0);
00494           G4double SD1 = SDL1+SDT1;
00495           if (cut > resEne)
00496             {
00497               S1 = SD1; //XS1
00498               S0 = SD1/resEne; //XS0
00499               S2 = SD1*resEne; //XS2
00500             }
00501           else
00502             {
00503               H1 = SD1; //XH1
00504               H0 = SD1/resEne; //XH0
00505               H2 = SD1*resEne; //XH2
00506             }
00507         }
00508     }
00509   //
00510   // Close collisions (Moller's cross section)
00511   //
00512   G4double wl = std::max(cut,cutoffEne);
00513   G4double ee = energy + ionEnergy;
00514   G4double wu = 0.5*ee;
00515   if (wl < wu-(1e-5*eV))
00516     {
00517       H0 += (1.0/(ee-wu)) - (1.0/(ee-wl)) - (1.0/wu) + (1.0/wl) + 
00518         (1.0-amol)*std::log(((ee-wu)*wl)/((ee-wl)*wu))/ee + 
00519         amol*(wu-wl)/(ee*ee);
00520       H1 += std::log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) + 
00521         (2.0-amol)*std::log((ee-wu)/(ee-wl)) + 
00522         amol*(wu*wu-wl*wl)/(2.0*ee*ee);
00523       H2 += (2.0-amol)*(wu-wl)+(wu*(2.0*ee-wu)/(ee-wu)) - 
00524         (wl*(2.0*ee-wl)/(ee-wl)) + 
00525         (3.0-amol)*ee*std::log((ee-wu)/(ee-wl)) +       
00526         amol*(wu*wu*wu-wl*wl*wl)/(3.0*ee*ee);
00527       wu = wl;
00528     }
00529   wl = cutoffEne;
00530   
00531   if (wl > wu-(1e-5*eV))
00532     {
00533       (*result)[0] = constant*H0;
00534       (*result)[1] = constant*H1;
00535       (*result)[2] = constant*H2;
00536       (*result)[3] = constant*S0;
00537       (*result)[4] = constant*S1;
00538       (*result)[5] = constant*S2;
00539       return result;
00540     }
00541 
00542   S0 += (1.0/(ee-wu))-(1.0/(ee-wl)) - (1.0/wu) + (1.0/wl) + 
00543     (1.0-amol)*std::log(((ee-wu)*wl)/((ee-wl)*wu))/ee +
00544     amol*(wu-wl)/(ee*ee);
00545   S1 += std::log(wu/wl)+(ee/(ee-wu))-(ee/(ee-wl)) + 
00546     (2.0-amol)*std::log((ee-wu)/(ee-wl)) + 
00547     amol*(wu*wu-wl*wl)/(2.0*ee*ee);
00548   S2 += (2.0-amol)*(wu-wl)+(wu*(2.0*ee-wu)/(ee-wu)) - 
00549     (wl*(2.0*ee-wl)/(ee-wl)) + 
00550     (3.0-amol)*ee*std::log((ee-wu)/(ee-wl)) + 
00551     amol*(wu*wu*wu-wl*wl*wl)/(3.0*ee*ee);
00552 
00553   (*result)[0] = constant*H0;
00554   (*result)[1] = constant*H1;
00555   (*result)[2] = constant*H2;
00556   (*result)[3] = constant*S0;
00557   (*result)[4] = constant*S1;
00558   (*result)[5] = constant*S2;
00559   return result;
00560 }
00561 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
00562 G4DataVector* G4PenelopeIonisationXSHandler::ComputeShellCrossSectionsPositron(G4PenelopeOscillator* theOsc,
00563                                                                                   G4double energy,
00564                                                                                   G4double cut,
00565                                                                                   G4double delta)
00566 {
00567   //
00568   //This method calculates the hard and soft cross sections (H0-H1-H2-S0-S1-S2) for 
00569   //the given oscillator/cut and at the given energy.
00570   //It returns a G4DataVector* with 6 entries (H0-H1-H2-S0-S1-S2)
00571   //Equivalent of subroutines PINaT1 of Penelope
00572   //
00573   // Results are _per target electron_
00574   //
00575   G4DataVector* result = new G4DataVector();
00576   for (size_t i=0;i<6;i++)
00577     result->push_back(0.);
00578   G4double ionEnergy = theOsc->GetIonisationEnergy();
00579   
00580   //return a set of zero's if the energy it too low to excite the current oscillator
00581   if (energy < ionEnergy)
00582     return result;
00583 
00584   G4double H0=0.,H1=0.,H2=0.;
00585   G4double S0=0.,S1=0.,S2=0.;
00586 
00587   //Define useful constants to be used in the calculation
00588   G4double gamma = 1.0+energy/electron_mass_c2;
00589   G4double gammaSq = gamma*gamma;
00590   G4double beta = (gammaSq-1.0)/gammaSq;
00591   G4double pielr2 = pi*classic_electr_radius*classic_electr_radius; //pi*re^2
00592   G4double constant = pielr2*2.0*electron_mass_c2/beta;
00593   G4double XHDT0 = std::log(gammaSq)-beta;
00594 
00595   G4double cpSq = energy*(energy+2.0*electron_mass_c2);
00596   G4double cp = std::sqrt(cpSq);
00597   G4double amol = (energy/(energy+electron_mass_c2))*(energy/(energy+electron_mass_c2));
00598   G4double g12 = (gamma+1.0)*(gamma+1.0);
00599   //Bhabha coefficients
00600   G4double bha1 = amol*(2.0*g12-1.0)/(gammaSq-1.0);
00601   G4double bha2 = amol*(3.0+1.0/g12);
00602   G4double bha3 = amol*2.0*gamma*(gamma-1.0)/g12;
00603   G4double bha4 = amol*(gamma-1.0)*(gamma-1.0)/g12;
00604 
00605   //
00606   // Distant interactions
00607   //
00608   G4double resEne = theOsc->GetResonanceEnergy();
00609   G4double cutoffEne = theOsc->GetCutoffRecoilResonantEnergy();
00610   if (energy > resEne)
00611     {
00612       G4double cp1Sq = (energy-resEne)*(energy-resEne+2.0*electron_mass_c2);
00613       G4double cp1 = std::sqrt(cp1Sq);
00614       
00615       //Distant longitudinal interactions
00616       G4double QM = 0;
00617       if (resEne > 1e-6*energy)
00618         QM = std::sqrt((cp-cp1)*(cp-cp1)+electron_mass_c2*electron_mass_c2)-electron_mass_c2;
00619       else
00620         {
00621           QM = resEne*resEne/(beta*2.0*electron_mass_c2);
00622           QM = QM*(1.0-0.5*QM/electron_mass_c2);
00623         }
00624       G4double SDL1 = 0;
00625       if (QM < cutoffEne)
00626         SDL1 = std::log(cutoffEne*(QM+2.0*electron_mass_c2)/(QM*(cutoffEne+2.0*electron_mass_c2)));
00627       
00628       //Distant transverse interactions
00629       if (SDL1)
00630         {
00631           G4double SDT1 = std::max(XHDT0-delta,0.0);
00632           G4double SD1 = SDL1+SDT1;
00633           if (cut > resEne)
00634             {
00635               S1 = SD1; //XS1
00636               S0 = SD1/resEne; //XS0
00637               S2 = SD1*resEne; //XS2
00638             }
00639           else
00640             {
00641               H1 = SD1; //XH1
00642               H0 = SD1/resEne; //XH0
00643               H2 = SD1*resEne; //XH2
00644             }
00645         }
00646     }
00647 
00648   //
00649   // Close collisions (Bhabha's cross section)
00650   //
00651   G4double wl = std::max(cut,cutoffEne);
00652   G4double wu = energy; 
00653   G4double energySq = energy*energy;
00654   if (wl < wu-(1e-5*eV))
00655     {
00656       G4double wlSq = wl*wl;
00657       G4double wuSq = wu*wu;
00658       H0 += (1.0/wl) - (1.0/wu)- bha1*std::log(wu/wl)/energy  
00659         + bha2*(wu-wl)/energySq  
00660         - bha3*(wuSq-wlSq)/(2.0*energySq*energy)
00661         + bha4*(wuSq*wu-wlSq*wl)/(3.0*energySq*energySq);
00662       H1 += std::log(wu/wl) - bha1*(wu-wl)/energy
00663         + bha2*(wuSq-wlSq)/(2.0*energySq)
00664         - bha3*(wuSq*wu-wlSq*wl)/(3.0*energySq*energy)
00665         + bha4*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energySq);
00666       H2 += wu - wl - bha1*(wuSq-wlSq)/(2.0*energy)
00667         + bha2*(wuSq*wu-wlSq*wl)/(3.0*energySq)
00668         - bha3*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energy)
00669         + bha4*(wuSq*wuSq*wu-wlSq*wlSq*wl)/(5.0*energySq*energySq);
00670       wu = wl;
00671     }
00672   wl = cutoffEne;
00673   
00674   if (wl > wu-(1e-5*eV))
00675     {
00676       (*result)[0] = constant*H0;
00677       (*result)[1] = constant*H1;
00678       (*result)[2] = constant*H2;
00679       (*result)[3] = constant*S0;
00680       (*result)[4] = constant*S1;
00681       (*result)[5] = constant*S2;
00682       return result;
00683     }
00684 
00685   G4double wlSq = wl*wl;
00686   G4double wuSq = wu*wu;
00687 
00688   S0 += (1.0/wl) - (1.0/wu) - bha1*std::log(wu/wl)/energy 
00689     + bha2*(wu-wl)/energySq  
00690     - bha3*(wuSq-wlSq)/(2.0*energySq*energy)
00691     + bha4*(wuSq*wu-wlSq*wl)/(3.0*energySq*energySq);
00692 
00693   S1 += std::log(wu/wl) - bha1*(wu-wl)/energy
00694     + bha2*(wuSq-wlSq)/(2.0*energySq)
00695     - bha3*(wuSq*wu-wlSq*wl)/(3.0*energySq*energy)
00696     + bha4*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energySq);
00697 
00698   S2 += wu - wl - bha1*(wuSq-wlSq)/(2.0*energy)
00699     + bha2*(wuSq*wu-wlSq*wl)/(3.0*energySq)
00700     - bha3*(wuSq*wuSq-wlSq*wlSq)/(4.0*energySq*energy)
00701     + bha4*(wuSq*wuSq*wu-wlSq*wlSq*wl)/(5.0*energySq*energySq);
00702 
00703  (*result)[0] = constant*H0;
00704  (*result)[1] = constant*H1;
00705  (*result)[2] = constant*H2;
00706  (*result)[3] = constant*S0;
00707  (*result)[4] = constant*S1;
00708  (*result)[5] = constant*S2;
00709 
00710  return result;
00711 }

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