Geant4  10.01.p02
G4WentzelVIRelXSection.cc
Go to the documentation of this file.
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 // $Id: G4WentzelVIRelXSection.cc 85306 2014-10-27 14:17:47Z gcosmo $
27 //
28 // -------------------------------------------------------------------
29 //
30 // GEANT4 Class file
31 //
32 //
33 // File name: G4WentzelVIRelXSection
34 //
35 // Author: V.Ivanchenko
36 //
37 // Creation date: 08.06.2012 from G4WentzelOKandVIxSection
38 //
39 // Modifications:
40 //
41 //
42 
43 // -------------------------------------------------------------------
44 //
45 
46 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
48 
50 #include "G4PhysicalConstants.hh"
51 #include "G4SystemOfUnits.hh"
52 #include "Randomize.hh"
53 #include "G4Electron.hh"
54 #include "G4Positron.hh"
55 #include "G4Proton.hh"
56 #include "G4EmParameters.hh"
57 #include "G4Log.hh"
58 
59 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
60 
63 
64 using namespace std;
65 
67  numlimit(0.1),
68  nwarnings(0),
69  nwarnlimit(50),
70  isCombined(combined),
71  alpha2(fine_structure_const*fine_structure_const)
72 {
78  lowEnergyLimit = 1.0*eV;
79  G4double p0 = electron_mass_c2*classic_electr_radius;
80  coeff = twopi*p0*p0;
81  particle = 0;
82 
83  // Thomas-Fermi screening radii
84  // Formfactors from A.V. Butkevich et al., NIM A 488 (2002) 282
85 
86  if(0.0 == ScreenRSquare[0]) {
87  G4double a0 = electron_mass_c2/0.88534;
88  G4double constn = 6.937e-6/(MeV*MeV);
89 
90  ScreenRSquare[0] = alpha2*a0*a0;
91  for(G4int j=1; j<100; ++j) {
92  G4double x = a0*fG4pow->Z13(j);
93  //ScreenRSquare[j] = 0.5*(1 + exp(-j*j*0.001))*alpha2*x*x;
94  ScreenRSquare[j] = 0.5*alpha2*x*x;
95  x = fNistManager->GetA27(j);
96  FormFactor[j] = constn*x*x;
97  }
98  }
99  currentMaterial = 0;
100  elecXSRatio = factB = factD = formfactA = screenZ = 0.0;
102  cosThetaMax = 1.0;
103 
104  factB1= 0.5*CLHEP::pi*fine_structure_const;
105 
106  Initialise(theElectron, 1.0);
107  targetMass = proton_mass_c2;
108 }
109 
110 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
111 
113 {}
114 
115 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
116 
118  G4double cosThetaLim)
119 {
120  SetupParticle(p);
121  tkin = mom2 = momCM2 = 0.0;
122  ecut = etag = DBL_MAX;
123  targetZ = 0;
124 
125  // cosThetaMax is below 1.0 only when MSC is combined with SS
126  if(isCombined) { cosThetaMax = cosThetaLim; }
127 
129  *CLHEP::hbarc/CLHEP::fermi;
130  factorA2 = 0.5*a*a;
131  currentMaterial = 0;
132 }
133 
134 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
135 
137 {
138  particle = p;
139  mass = particle->GetPDGMass();
140  spin = particle->GetPDGSpin();
141  if(0.0 != spin) { spin = 0.5; }
142  G4double q = std::fabs(particle->GetPDGCharge()/eplus);
143  chargeSquare = q*q;
144  charge3 = chargeSquare*q;
145  tkin = 0.0;
146  currentMaterial = 0;
147  targetZ = 0;
148 }
149 
150 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
151 
152 G4double
154 {
155  G4double cosTetMaxNuc2 = cosTetMaxNuc;
156  if(Z != targetZ || tkin != etag) {
157  etag = tkin;
158  targetZ = Z;
159  if(targetZ > 99) { targetZ = 99; }
161  //G4double tmass2 = targetMass*targetMass;
162  //G4double etot = tkin + mass;
163  //G4double invmass2 = mass*mass + tmass2 + 2*etot*targetMass;
164  //momCM2 = mom2*tmass2/invmass2;
165  //gam0pcmp = (etot + targetMass)*targetMass/invmass2;
166  //pcmp2 = tmass2/invmass2;
167 
169 
171  if(Z > 1) {
172  screenZ *= std::min(Z*1.13,1.13 +3.76*Z*Z*invbeta2*alpha2*chargeSquare);
173  /*
174  if(mass > MeV) {
175  screenZ *= std::min(Z*1.13,1.13 +3.76*Z*Z*invbeta2*alpha2*chargeSquare);
176  } else {
177  G4double tau = tkin/mass;
178  // screenZ *= std::min(Z*invbeta2,
179  screenZ *= std::min(Z*1.13,
180  (1.13 +3.76*Z*Z*invbeta2*alpha2*std::sqrt(tau/(tau + fG4pow->Z23(Z)))));
181  }
182  */
183  }
184  if(targetZ == 1 && cosTetMaxNuc2 < 0.0 && particle == theProton) {
185  cosTetMaxNuc2 = 0.0;
186  }
188 
189  cosTetMaxElec = 1.0;
191  }
192  return cosTetMaxNuc2;
193 }
194 
195 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
196 
197 G4double
199 {
200  G4double xsec = 0.0;
201  if(cosTMax >= 1.0) { return xsec; }
202 
203  G4double xSection = 0.0;
204  G4double x = 0;
205  G4double y = 0;
206  G4double x1= 0;
207  G4double x2= 0;
208  G4double xlog = 0.0;
209 
210  G4double costm = std::max(cosTMax,cosTetMaxElec);
211  G4double fb = screenZ*factB;
212 
213  // scattering off electrons
214  if(costm < 1.0) {
215  x = (1.0 - costm)/screenZ;
216  if(x < numlimit) {
217  x2 = 0.5*x*x;
218  y = x2*(1.0 - 1.3333333*x + 3*x2);
219  if(0.0 < factB) { y -= fb*x2*x*(0.6666667 - x); }
220  } else {
221  x1= x/(1 + x);
222  xlog = G4Log(1.0 + x);
223  y = xlog - x1;
224  if(0.0 < factB) { y -= fb*(x + x1 - 2*xlog); }
225  }
226 
227  if(y < 0.0) {
228  ++nwarnings;
229  if(nwarnings < nwarnlimit) {
230  G4cout << "G4WentzelVIRelXSection::ComputeTransportCrossSectionPerAtom scattering on e- <0"
231  << G4endl;
232  G4cout << "y= " << y
233  << " e(MeV)= " << tkin << " p(MeV/c)= " << sqrt(mom2)
234  << " Z= " << targetZ << " "
236  G4cout << " 1-costm= " << 1.0-costm << " screenZ= " << screenZ
237  << " x= " << x << G4endl;
238  }
239  y = 0.0;
240  }
241  xSection = y;
242  }
243  /*
244  G4cout << "G4WentzelVI:XS per A " << " Z= " << targetZ
245  << " e(MeV)= " << tkin/MeV << " XSel= " << xSection
246  << " cut(MeV)= " << ecut/MeV
247  << " zmaxE= " << (1.0 - cosTetMaxElec)/screenZ
248  << " zmaxN= " << (1.0 - cosThetaMax)/screenZ
249  << " 1-costm= " << 1.0 - cosThetaMax << G4endl;
250  */
251  // scattering off nucleus
252  if(cosTMax < 1.0) {
253  x = (1.0 - cosTMax)/screenZ;
254  if(x < numlimit) {
255  x2 = 0.5*x*x;
256  y = x2*(1.0 - 1.3333333*x + 3*x2);
257  if(0.0 < factB) { y -= fb*x2*x*(0.6666667 - x); }
258  } else {
259  x1= x/(1 + x);
260  xlog = G4Log(1.0 + x);
261  y = xlog - x1;
262  if(0.0 < factB) { y -= fb*(x + x1 - 2*xlog); }
263  }
264 
265  if(y < 0.0) {
266  ++nwarnings;
267  if(nwarnings < nwarnlimit) {
268  G4cout << "G4WentzelVIRelXSection::ComputeTransportCrossSectionPerAtom scattering on e- <0"
269  << G4endl;
270  G4cout << "y= " << y
271  << " e(MeV)= " << tkin << " Z= " << targetZ << " "
273  G4cout << " formfactA= " << formfactA << " screenZ= " << screenZ
274  << " x= " << " x1= " << x1 <<G4endl;
275  }
276  y = 0.0;
277  }
278  xSection += y*targetZ;
279  }
280  xSection *= kinFactor;
281  /*
282  G4cout << "Z= " << targetZ << " XStot= " << xSection/barn
283  << " screenZ= " << screenZ << " formF= " << formfactA
284  << " for " << particle->GetParticleName()
285  << " m= " << mass << " 1/v= " << sqrt(invbeta2) << " p= " << sqrt(mom2)
286  << " x= " << x
287  << G4endl;
288  */
289  return xSection;
290 }
291 
292 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
293 
296  G4double cosTMax,
297  G4double elecRatio)
298 {
299  G4ThreeVector v(0.0,0.0,1.0);
300 
301  G4double formf = formfactA;
302  G4double cost1 = cosTMin;
303  G4double cost2 = cosTMax;
304  if(elecRatio > 0.0) {
305  if(G4UniformRand() <= elecRatio) {
306  formf = 0.0;
307  cost1 = std::max(cost1,cosTetMaxElec);
308  cost2 = std::max(cost2,cosTetMaxElec);
309  }
310  }
311  if(cost1 < cost2) { return v; }
312 
313  G4double w1 = 1. - cost1 + screenZ;
314  G4double w2 = 1. - cost2 + screenZ;
315  G4double z1 = w1*w2/(w1 + G4UniformRand()*(w2 - w1)) - screenZ;
316 
317  //G4double fm = 1.0 + formf*z1/(1.0 + (mass + tkin)*z1/targetMass);
318  G4double fm = 1.0 + formf*z1;
319  //G4double grej = (1. - z1*factB)/( (1.0 + z1*factD)*fm*fm );
320  G4double grej = (1. - z1*factB + factB1*targetZ*sqrt(z1*factB)*(2 - z1))/( (1.0 + z1*factD)*fm*fm );
321  // "false" scattering
322  if( G4UniformRand() > grej ) { return v; }
323  // }
324  G4double cost = 1.0 - z1;
325 
326  if(cost > 1.0) { cost = 1.0; }
327  else if(cost < -1.0) { cost =-1.0; }
328  G4double sint = sqrt((1.0 - cost)*(1.0 + cost));
329  //G4cout << "sint= " << sint << G4endl;
330  G4double phi = twopi*G4UniformRand();
331  G4double vx1 = sint*cos(phi);
332  G4double vy1 = sint*sin(phi);
333 
334  // only direction is changed
335  v.set(vx1,vy1,cost);
336  return v;
337 }
338 
339 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
340 
341 void
343 {
344  if(mass > MeV) {
345  G4double ratio = electron_mass_c2/mass;
346  G4double tau = tkin/mass;
347  G4double tmax = 2.0*electron_mass_c2*tau*(tau + 2.)/
348  (1.0 + 2.0*ratio*(tau + 1.0) + ratio*ratio);
349  //tmax = std::min(tmax, targetZ*targetZ*10*eV);
350  cosTetMaxElec = 1.0 - std::min(cutEnergy, tmax)*electron_mass_c2/mom2;
351  } else {
352 
353  G4double tmax = tkin;
354  if(particle == theElectron) { tmax *= 0.5; }
355  //tmax = std::min(tmax, targetZ*targetZ*10*eV);
356  G4double t = std::min(cutEnergy, tmax);
357  G4double mom21 = t*(t + 2.0*electron_mass_c2);
358  G4double t1 = tkin - t;
359  //G4cout <<"tkin=" <<tkin<<" tmax= "<<tmax<<" t= "
360  //<<t<< " t1= "<<t1<<" cut= "<<ecut<<G4endl;
361  if(t1 > 0.0) {
362  G4double mom22 = t1*(t1 + 2.0*mass);
363  G4double ctm = (mom2 + mom22 - mom21)*0.5/sqrt(mom2*mom22);
364  if(ctm < 1.0) { cosTetMaxElec = ctm; }
365  if(particle == theElectron && cosTetMaxElec < 0.0) { cosTetMaxElec = 0.0; }
366  }
367  }
368 }
369 
370 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
const G4double a0
static G4Pow * GetInstance()
Definition: G4Pow.cc:55
static const double MeV
Definition: G4SIunits.hh:193
static G4double ScreenRSquare[100]
G4ThreeVector SampleSingleScattering(G4double CosThetaMin, G4double CosThetaMax, G4double elecRatio=0.0)
G4WentzelVIRelXSection(G4bool combined=true)
const G4ParticleDefinition * theElectron
CLHEP::Hep3Vector G4ThreeVector
const G4double pi
G4double GetA27(G4int Z)
G4double a
Definition: TRTMaterials.hh:39
G4double ComputeTransportCrossSectionPerAtom(G4double CosThetaMax)
int G4int
Definition: G4Types.hh:78
static G4NistManager * Instance()
const G4String & GetParticleName() const
G4double SetupTarget(G4int Z, G4double cut=DBL_MAX)
const G4ParticleDefinition * theProton
void SetupParticle(const G4ParticleDefinition *)
#define G4UniformRand()
Definition: Randomize.hh:93
G4GLOB_DLL std::ostream G4cout
G4double Z13(G4int Z) const
Definition: G4Pow.hh:127
bool G4bool
Definition: G4Types.hh:79
const G4ParticleDefinition * particle
static G4Proton * Proton()
Definition: G4Proton.cc:93
static G4double FormFactor[100]
void ComputeMaxElectronScattering(G4double cut)
G4double G4Log(G4double x)
Definition: G4Log.hh:230
static const double eV
Definition: G4SIunits.hh:194
static G4Positron * Positron()
Definition: G4Positron.cc:94
const G4double p0
G4double GetPDGMass() const
T max(const T t1, const T t2)
brief Return the largest of the two arguments
static G4EmParameters * Instance()
G4double GetAtomicMassAmu(const G4String &symb) const
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
const G4Material * currentMaterial
G4double GetPDGSpin() const
static G4Electron * Electron()
Definition: G4Electron.cc:94
#define G4endl
Definition: G4ios.hh:61
void Initialise(const G4ParticleDefinition *, G4double CosThetaLim)
double G4double
Definition: G4Types.hh:76
static const double eplus
Definition: G4SIunits.hh:178
G4double GetPDGCharge() const
void SetTargetMass(G4double value)
#define DBL_MAX
Definition: templates.hh:83
static const double fermi
Definition: G4SIunits.hh:93
const G4ParticleDefinition * thePositron
G4double FactorForAngleLimit() const