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