Ignore:
Timestamp:
Apr 6, 2009, 12:21:12 PM (15 years ago)
Author:
garnier
Message:

update processes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/processes/electromagnetic/standard/src/G4CoulombScatteringModel.cc

    r819 r961  
    2424// ********************************************************************
    2525//
    26 // $Id: G4CoulombScatteringModel.cc,v 1.29 2007/11/09 11:45:45 vnivanch Exp $
    27 // GEANT4 tag $Name: geant4-09-01-patch-02 $
     26// $Id: G4CoulombScatteringModel.cc,v 1.37 2008/07/31 13:11:34 vnivanch Exp $
     27// GEANT4 tag $Name: geant4-09-02-ref-02 $
    2828//
    2929// -------------------------------------------------------------------
     
    4444// 19.10.06 V.Ivanchenko use inheritance from G4eCoulombScatteringModel
    4545// 09.10.07 V.Ivanchenko reorganized methods, add cut dependence in scattering off e-
     46// 09.06.08 V.Ivanchenko SelectIsotope is moved to the base class
    4647//
    4748// Class Description:
     
    5556#include "Randomize.hh"
    5657#include "G4ParticleChangeForGamma.hh"
    57 #include "G4NistManager.hh"
    5858#include "G4ParticleTable.hh"
    5959#include "G4IonTable.hh"
     
    6464using namespace std;
    6565
    66 G4CoulombScatteringModel::G4CoulombScatteringModel(
    67   G4double thetaMin, G4double thetaMax, G4bool build,
    68   G4double tlim, const G4String& nam)
    69   : G4eCoulombScatteringModel(thetaMin,thetaMax,build,tlim,nam)
    70 {
    71   theMatManager    = G4NistManager::Instance();
    72   theParticleTable = G4ParticleTable::GetParticleTable();
    73 }
     66G4CoulombScatteringModel::G4CoulombScatteringModel(const G4String& nam)
     67  : G4eCoulombScatteringModel(nam)
     68{}
    7469
    7570//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
     
    8479                                G4double kinEnergy,
    8580                                G4double Z,
    86                                 G4double A,
     81                                G4double,
    8782                                G4double cutEnergy,
    8883                                G4double)
    8984{
    90   if(p == particle && kinEnergy == tkin && Z == targetZ &&
    91      A == targetA && cutEnergy == ecut) return nucXSection;
    92 
    93   // Lab system
    94   G4double ekin = std::max(keV, kinEnergy);
    95   nucXSection = ComputeElectronXSectionPerAtom(p,ekin,Z,A,cutEnergy);
     85  SetupParticle(p);
     86  G4double ekin = std::max(lowEnergyLimit, kinEnergy);
     87  SetupKinematic(ekin, cutEnergy);
     88
     89  // save lab system kinematics
     90  G4double xtkin = tkin;
     91  G4double xmom2 = mom2;
     92  G4double xinvb = invbeta2;
    9693
    9794  // CM system
    9895  G4int iz      = G4int(Z);
    99   G4double m1   = theMatManager->GetAtomicMassAmu(iz)*amu_c2;
     96  G4double m2   = fNistManager->GetAtomicMassAmu(iz)*amu_c2;
    10097  G4double etot = tkin + mass;
    10198  G4double ptot = sqrt(mom2);
    102   G4double bet  = ptot/(etot + m1);
    103   G4double gam  = 1.0/sqrt((1.0 - bet)*(1.0 + bet));
    104   G4double momCM= gam*(ptot - bet*etot);
    105 
    106   //  G4cout << "ptot= " << ptot << " etot= " << etot << " beta= "
    107   //     << bet << " gam= " << gam << " Z= " << Z << " A= " << A << G4endl;
    108   // G4cout << " CM. mom= " << momCM  << " m= " << m
    109   // << " m1= " << m1 << " iz= " << iz <<G4endl;
    110 
    111   G4double momCM2 = momCM*momCM;
    112   cosTetMaxNuc = std::max(cosThetaMax, 1.0 - 0.5*q2Limit/momCM2);
    113   if(1.5 > targetA && p == theProton && cosTetMaxNuc < 0.0) cosTetMaxNuc = 0.0;
    114   //G4cout << " ctmax= " << cosTetMaxNuc
    115   //<< " ctmin= " << cosThetaMin << G4endl; 
    116 
    117   // Cross section in CM system
    118   if(cosTetMaxNuc < cosThetaMin) {
    119     G4double effmass = mass*m1/(mass + m1);
    120     G4double x1 = 1.0 - cosThetaMin;
    121     G4double x2 = 1.0 - cosTetMaxNuc;
    122     G4double z1 = x1 + screenZ;
    123     G4double z2 = x2 + screenZ;
    124     G4double d  = 1.0/formfactA;
    125     G4double zn1= x1 + d;
    126     G4double zn2= x2 + d;
    127     nucXSection += coeff*Z*Z*chargeSquare*(1.0 +  effmass*effmass/momCM2)
    128       *(1./z1 - 1./z2 + 1./zn1 - 1./zn2 +
    129         2.0*formfactA*std::log(z1*zn2/(z2*zn1)))/momCM2;
    130     //G4cout << "XS: x1= " << x1 << " x2= " << x2
    131     //<< " cross= " << cross << G4endl;
    132     //G4cout << "momCM2= " << momCM2 << " invbeta2= " << invbeta2
    133     //       << " coeff= " << coeff << G4endl;
    134   }
    135   if(nucXSection < 0.0) nucXSection = 0.0;
    136   return nucXSection;
    137 }
    138 
    139 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
    140 
    141 G4double G4CoulombScatteringModel::SelectIsotope(const G4Element* elm)
    142 {
    143   G4double N = elm->GetN();
    144   G4int ni   = elm->GetNumberOfIsotopes();
    145   if(ni > 0) {
    146     G4double* ab = elm->GetRelativeAbundanceVector();
    147     G4double x = G4UniformRand();
    148     G4int idx;
    149     for(idx=0; idx<ni; idx++) {
    150       x -= ab[idx];
    151       if (x <= 0.0) break;
    152     }
    153     if(idx >= ni) {
    154       G4cout << "G4CoulombScatteringModel::SelectIsotope WARNING: "
    155              << "abandance vector for"
    156              << elm->GetName() << " is not normalised to unit" << G4endl;
    157     } else {
    158       N = G4double(elm->GetIsotope(idx)->GetN());
    159     }
    160   }
    161   return N;
     99
     100  G4double m12  = mass*mass;
     101  G4double momCM= ptot*m2/sqrt(m12 + m2*m2 + 2.0*etot*m2);
     102
     103  mom2 = momCM*momCM;
     104  tkin = sqrt(mom2 + m12) - mass;
     105  invbeta2 = 1.0 +  m12/mom2;
     106
     107  SetupTarget(Z, tkin);
     108
     109  G4double xsec = CrossSectionPerAtom();
     110
     111  // restore Lab system kinematics
     112  tkin = xtkin;
     113  mom2 = xmom2;
     114  invbeta2 = xinvb;
     115
     116  return xsec;
    162117}
    163118
     
    169124                               const G4DynamicParticle* dp,
    170125                               G4double cutEnergy,
    171                                G4double maxEnergy)
     126                               G4double)
    172127{
    173   const G4Material* aMaterial = couple->GetMaterial();
    174   const G4ParticleDefinition* p = dp->GetDefinition();
    175128  G4double kinEnergy = dp->GetKineticEnergy();
    176 
    177   // Select isotope and setup
    178   SetupParticle(p);
    179   const G4Element* elm =
    180     SelectRandomAtom(aMaterial,p,kinEnergy,cutEnergy,maxEnergy);
    181   G4double Z  = elm->GetZ();
    182   G4double A  = SelectIsotope(elm);
     129  if(kinEnergy <= DBL_MIN) return;
     130  DefineMaterial(couple);
     131  SetupParticle(dp->GetDefinition());
     132  G4double ekin = std::max(lowEnergyLimit, kinEnergy);
     133  SetupKinematic(ekin, cutEnergy);
     134
     135  // Choose nucleus
     136  currentElement = SelectRandomAtom(couple,particle,ekin,ecut,tkin);
     137
     138  G4double Z  = currentElement->GetZ();
    183139  G4int iz    = G4int(Z);
    184   G4int ia    = G4int(A + 0.5);
    185 
    186   G4double cross =
    187     ComputeCrossSectionPerAtom(p,kinEnergy,Z,A,cutEnergy,maxEnergy);
    188 
    189   G4double costm = cosTetMaxNuc;
    190   G4double formf = formfactA;
    191   if(G4UniformRand()*cross < elecXSection) {
    192     costm = cosTetMaxElec;
    193     formf = 0.0;
    194   }
    195 
    196   //  G4cout << "SampleSec: Ekin= " << kinEnergy << " m1= " << m1
    197   // << " Z= "<< Z << " A= " <<A<< G4endl;
    198 
    199   if(costm >= cosThetaMin) return;
    200 
    201   // kinematics in CM system
    202   G4double m1   = theParticleTable->GetIonTable()->GetNucleusMass(iz, ia);
    203   G4double etot = kinEnergy + mass;
     140  G4int ia    = SelectIsotopeNumber(currentElement);
     141  G4double m2 = theParticleTable->GetIonTable()->GetNucleusMass(iz, ia);
     142
     143  // CM system
     144  G4double etot = tkin + mass;
    204145  G4double ptot = sqrt(mom2);
    205   G4double bet  = ptot/(etot + m1);
     146
     147  G4double momCM= ptot*m2/sqrt(mass*mass + m2*m2 + 2.0*etot*m2);
     148  mom2 = momCM*momCM;
     149  G4double m12 = mass*mass;
     150  G4double eCM = sqrt(mom2 + m12);
     151
     152  // a correction for heavy projectile
     153  G4double fm = m2/(mass + m2);
     154  invbeta2 = 1.0 +  m12*fm*fm/mom2;
     155
     156  // sample scattering angle in CM system
     157  SetupTarget(Z, eCM - mass);
     158
     159  G4double cost = SampleCosineTheta();
     160  G4double z1   = 1.0 - cost;
     161  if(z1 < 0.0) return;
     162
     163  G4double sint = sqrt(z1*(1.0 + cost));
     164  G4double phi  = twopi * G4UniformRand();
     165
     166  // kinematics in the Lab system
     167  G4double bet  = ptot/(etot + m2);
    206168  G4double gam  = 1.0/sqrt((1.0 - bet)*(1.0 + bet));
    207   G4double pCM  = gam*(ptot - bet*etot);
    208   G4double eCM  = gam*(etot - bet*ptot);
    209 
    210   G4double x1 = 1. - cosThetaMin + screenZ;
    211   G4double x2 = 1. - costm;
    212   G4double x3 = cosThetaMin - costm;
    213 
    214   G4double grej,  z, z1;
    215   do {
    216     z  = G4UniformRand()*x3;
    217     z1 = (x1*x2 - screenZ*z)/(x1 + z);
    218     if(z1 < 0.0) z1 = 0.0;
    219     else if(z1 > 2.0) z1 = 2.0;
    220     grej = 1.0/(1.0 + formf*z1);
    221   } while ( G4UniformRand() > grej*grej ); 
    222  
    223   G4double cost = 1.0 - z1;
    224   G4double sint= sqrt(z1*(2.0 - z1));
    225 
    226   G4double phi = twopi * G4UniformRand();
    227 
    228   // projectile after scattering
    229   G4double pzCM = pCM*cost;
    230   G4ThreeVector v1(pCM*cos(phi)*sint,pCM*sin(phi)*sint,gam*(pzCM + bet*eCM));
     169  G4double pzCM = momCM*cost;
     170
     171  G4ThreeVector v1(momCM*cos(phi)*sint,momCM*sin(phi)*sint,gam*(pzCM + bet*eCM));
    231172  G4ThreeVector dir = dp->GetMomentumDirection();
    232173  G4ThreeVector newDirection = v1.unit();
    233174  newDirection.rotateUz(dir);   
    234175  fParticleChange->ProposeMomentumDirection(newDirection);   
     176
    235177  G4double elab = gam*(eCM + bet*pzCM);
    236   G4double ekin = elab - mass;
     178  ekin = elab - mass;
    237179  if(ekin < 0.0) ekin = 0.0;
    238   G4double plab = sqrt(ekin*(ekin + 2.0*mass));
    239180  fParticleChange->SetProposedKineticEnergy(ekin);
    240181
    241182  // recoil
    242183  G4double erec = kinEnergy - ekin;
    243   if(erec > Z*aMaterial->GetIonisation()->GetMeanExcitationEnergy()) {
     184  G4double th =
     185    std::min(recoilThreshold,
     186             Z*currentElement->GetIonisation()->GetMeanExcitationEnergy());
     187
     188  if(erec > th) {
    244189    G4ParticleDefinition* ion = theParticleTable->FindIon(iz, ia, 0, iz);
     190    G4double plab = sqrt(ekin*(ekin + 2.0*mass));
    245191    G4ThreeVector p2 = (ptot*dir - plab*newDirection).unit();
    246192    G4DynamicParticle* newdp  = new G4DynamicParticle(ion, p2, erec);
Note: See TracChangeset for help on using the changeset viewer.