source: trunk/source/processes/electromagnetic/standard/src/G4WentzelOKandVIxSection.cc@ 1346

Last change on this file since 1346 was 1340, checked in by garnier, 15 years ago

update ti head

File size: 11.0 KB
Line 
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,v 1.12 2010/11/04 17:30:32 vnivanch Exp $
27// GEANT4 tag $Name: emstand-V09-03-25 $
28//
29// -------------------------------------------------------------------
30//
31// GEANT4 Class file
32//
33//
34// File name: G4WentzelOKandVIxSection
35//
36// Author: V.Ivanchenko
37//
38// Creation date: 09.04.2008 from G4MuMscModel
39//
40// Modifications:
41//
42//
43
44// -------------------------------------------------------------------
45//
46
47//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
48//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
49
50#include "G4WentzelOKandVIxSection.hh"
51#include "Randomize.hh"
52#include "G4Electron.hh"
53#include "G4Positron.hh"
54#include "G4Proton.hh"
55#include "G4LossTableManager.hh"
56
57//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
58
59G4double G4WentzelOKandVIxSection::ScreenRSquare[] = {0.0};
60G4double G4WentzelOKandVIxSection::FormFactor[] = {0.0};
61
62using namespace std;
63
64G4WentzelOKandVIxSection::G4WentzelOKandVIxSection() :
65 numlimit(0.1),
66 nwarnings(0),
67 nwarnlimit(50),
68 alpha2(fine_structure_const*fine_structure_const)
69{
70 fNistManager = G4NistManager::Instance();
71 fG4pow = G4Pow::GetInstance();
72 theElectron = G4Electron::Electron();
73 thePositron = G4Positron::Positron();
74 theProton = G4Proton::Proton();
75 lowEnergyLimit = 1.0*eV;
76 G4double p0 = electron_mass_c2*classic_electr_radius;
77 coeff = twopi*p0*p0;
78 particle = 0;
79
80 // Thomas-Fermi screening radii
81 // Formfactors from A.V. Butkevich et al., NIM A 488 (2002) 282
82
83 if(0.0 == ScreenRSquare[0]) {
84 G4double a0 = electron_mass_c2/0.88534;
85 G4double constn = 6.937e-6/(MeV*MeV);
86
87 ScreenRSquare[0] = alpha2*a0*a0;
88 for(G4int j=1; j<100; ++j) {
89 G4double x = a0*fG4pow->Z13(j);
90 ScreenRSquare[j] = alpha2*x*x;
91 x = fNistManager->GetA27(j);
92 FormFactor[j] = constn*x*x;
93 }
94 }
95 currentMaterial = 0;
96 elecXSRatio = factB = formfactA = screenZ = 0.0;
97 cosTetMaxElec = cosTetMaxNuc = invbeta2 = kinFactor = 1.0;
98
99 Initialise(theElectron, 1.0);
100 SetTargetMass(proton_mass_c2);
101}
102
103//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
104
105G4WentzelOKandVIxSection::~G4WentzelOKandVIxSection()
106{}
107
108//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
109
110void G4WentzelOKandVIxSection::Initialise(const G4ParticleDefinition* p,
111 G4double CosThetaLim)
112{
113 SetupParticle(p);
114 tkin = mom2 = 0.0;
115 ecut = etag = DBL_MAX;
116 targetZ = 0;
117 cosThetaMax = CosThetaLim;
118 G4double a =
119 G4LossTableManager::Instance()->FactorForAngleLimit()*CLHEP::hbarc/CLHEP::fermi;
120 factorA2 = 0.5*a*a;
121 currentMaterial = 0;
122}
123
124//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
125
126void G4WentzelOKandVIxSection::SetupParticle(const G4ParticleDefinition* p)
127{
128 particle = p;
129 mass = particle->GetPDGMass();
130 spin = particle->GetPDGSpin();
131 if(0.0 != spin) { spin = 0.5; }
132 G4double q = std::fabs(particle->GetPDGCharge()/eplus);
133 chargeSquare = q*q;
134 charge3 = chargeSquare*q;
135 tkin = 0.0;
136 currentMaterial = 0;
137}
138
139//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
140
141G4double
142G4WentzelOKandVIxSection::SetupTarget(G4int Z, G4double cut)
143{
144 G4double cosTetMaxNuc2 = cosTetMaxNuc;
145 if(Z != targetZ || tkin != etag) {
146 etag = tkin;
147 targetZ = Z;
148 if(targetZ > 99) { targetZ = 99; }
149 SetTargetMass(fNistManager->GetAtomicMassAmu(targetZ)*amu_c2);
150 kinFactor = coeff*targetZ*chargeSquare*invbeta2/mom2;
151
152 screenZ = ScreenRSquare[targetZ]/mom2;
153 if(Z > 1) {
154 G4double tau = tkin/mass;
155 screenZ *=std::min(Z*invbeta2,
156 (1.13 +3.76*Z*Z*invbeta2*alpha2*std::sqrt(tau/(tau + fG4pow->Z23(Z)))));
157 }
158 if(targetZ == 1 && cosTetMaxNuc < 0.0 && particle == theProton) {
159 cosTetMaxNuc = 0.0;
160 }
161 formfactA = FormFactor[targetZ]*mom2;
162
163 // allowing do not compute scattering off e-
164 cosTetMaxElec = 1.0;
165 if(cut < DBL_MAX) {
166 if(mass < MeV) {
167 if(cosTetMaxNuc < 1.0 && cosTetMaxNuc > 0.0 && tkin < 10*cut) {
168 cosTetMaxNuc2 *= 0.1*tkin/cut;
169 }
170 }
171 ComputeMaxElectronScattering(cut);
172 }
173 }
174 return cosTetMaxNuc2;
175}
176
177//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
178
179G4double
180G4WentzelOKandVIxSection::ComputeTransportCrossSectionPerAtom(G4double cosTMax)
181{
182 G4double xsec = 0.0;
183 if(cosTMax >= 1.0) { return xsec; }
184
185 G4double xSection = 0.0;
186 G4double x = 0;
187 G4double y = 0;
188 G4double x1= 0;
189 G4double x2= 0;
190 G4double xlog = 0.0;
191
192 G4double costm = std::max(cosTMax,cosTetMaxElec);
193 G4double fb = screenZ*factB;
194
195 // scattering off electrons
196 if(costm < 1.0) {
197 x = (1.0 - costm)/screenZ;
198 x1= x/(1 + x);
199 if(x < numlimit) {
200 x2 = 0.5*x*x;
201 y = x2*(1.0 - 1.3333333*x + 3*x2);
202 } else {
203 xlog = log(1.0 + x);
204 y = xlog - x1;
205 }
206
207 if(0.0 < factB) {
208 if(x < numlimit) { y -= fb*x2*x*(0.6666667 - x); }
209 else { y -= fb*(x + x1 - 2*xlog); }
210 }
211
212 if(y < 0.0) {
213 ++nwarnings;
214 if(nwarnings < nwarnlimit) {
215 G4cout << "G4WentzelOKandVIxSection::ComputeTransportCrossSectionPerAtom scattering on e- <0"
216 << G4endl;
217 G4cout << "y= " << y
218 << " e(MeV)= " << tkin << " p(MeV/c)= " << sqrt(mom2)
219 << " Z= " << targetZ << " "
220 << particle->GetParticleName() << G4endl;
221 G4cout << " 1-costm= " << 1.0-costm << " screenZ= " << screenZ
222 << " x= " << x << G4endl;
223 }
224 y = 0.0;
225 }
226 xSection = y;
227 }
228 /*
229 G4cout << "G4WentzelVI:XS per A " << " Z= " << targetZ
230 << " e(MeV)= " << tkin/MeV << " XSel= " << xSection
231 << " cut(MeV)= " << ecut/MeV
232 << " zmaxE= " << (1.0 - cosTetMaxElec)/screenZ
233 << " zmaxN= " << (1.0 - cosThetaMax)/screenZ
234 << " 1-costm= " << 1.0 - cosThetaMax << G4endl;
235 */
236 // scattering off nucleus
237 if(cosTMax < 1.0) {
238 x = (1.0 - cosTMax)/screenZ;
239 x1= x/(1 + x);
240 if(x < numlimit) {
241 x2 = 0.5*x*x;
242 y = x2*(1.0 - 1.3333333*x + 3*x2);
243 } else {
244 xlog = log(1.0 + x);
245 y = xlog - x1;
246 }
247
248 if(0.0 < factB) {
249 if(x < numlimit) { y -= fb*x2*x*(0.6666667 - x); }
250 else { y -= fb*(x + x1 - 2*xlog); }
251 }
252 if(y < 0.0) {
253 ++nwarnings;
254 if(nwarnings < nwarnlimit) {
255 G4cout << "G4WentzelOKandVIxSection::ComputeTransportCrossSectionPerAtom scattering on e- <0"
256 << G4endl;
257 G4cout << "y= " << y
258 << " e(MeV)= " << tkin << " Z= " << targetZ << " "
259 << particle->GetParticleName() << G4endl;
260 G4cout << " formfactA= " << formfactA << " screenZ= " << screenZ
261 << " x= " << " x1= " << x1 <<G4endl;
262 }
263 y = 0.0;
264 }
265 xSection += y*targetZ;
266 }
267 xSection *= kinFactor;
268 /*
269 G4cout << "Z= " << targetZ << " XStot= " << xSection/barn
270 << " screenZ= " << screenZ << " formF= " << formfactA
271 << " for " << particle->GetParticleName()
272 << " m= " << mass << " 1/v= " << sqrt(invbeta2) << " p= " << sqrt(mom2)
273 << " x= " << x
274 << G4endl;
275 */
276 return xSection;
277}
278
279//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
280
281G4ThreeVector
282G4WentzelOKandVIxSection::SampleSingleScattering(G4double cosTMin,
283 G4double cosTMax,
284 G4double elecRatio)
285{
286 G4ThreeVector v(0.0,0.0,1.0);
287
288 G4double formf = formfactA;
289 G4double cost1 = cosTMin;
290 G4double cost2 = cosTMax;
291 if(elecRatio > 0.0) {
292 if(G4UniformRand() <= elecRatio) {
293 formf = 0.0;
294 cost1 = std::max(cost1,cosTetMaxElec);
295 cost2 = std::max(cost2,cosTetMaxElec);
296 }
297 }
298 if(cost1 < cost2) { return v; }
299
300 G4double w1 = 1. - cost1 + screenZ;
301 G4double w2 = 1. - cost2 + screenZ;
302 G4double z1 = w1*w2/(w1 + G4UniformRand()*(w2 - w1)) - screenZ;
303 if(factB > 0.0 || formf > 0.0 || factD > 0.01) {
304 G4double grej = (1. - z1*factB)/
305 ( (1.0 + z1*factD)*(1.0 + formf*z1)*(1.0 + formf*z1) );
306 if( G4UniformRand() > grej ) { return v; }
307 }
308 G4double cost = 1.0 - z1;
309 if(cost > 1.0) { cost = 1.0; }
310 else if(cost < -1.0) { cost =-1.0; }
311 G4double sint = sqrt((1.0 - cost)*(1.0 + cost));
312 //G4cout << "sint= " << sint << G4endl;
313 G4double phi = twopi*G4UniformRand();
314 G4double vx1 = sint*cos(phi);
315 G4double vy1 = sint*sin(phi);
316
317 // only direction is changed
318 v.set(vx1,vy1,cost);
319 return v;
320}
321
322//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
323
324void
325G4WentzelOKandVIxSection::ComputeMaxElectronScattering(G4double cutEnergy)
326{
327 G4double tmax = tkin;
328 if(mass > MeV) {
329 G4double ratio = electron_mass_c2/mass;
330 G4double tau = tkin/mass;
331 tmax = 2.0*electron_mass_c2*tau*(tau + 2.)/
332 (1.0 + 2.0*ratio*(tau + 1.0) + ratio*ratio);
333 cosTetMaxElec = 1.0 - std::min(cutEnergy, tmax)*electron_mass_c2/mom2;
334 } else {
335
336 if(particle == theElectron) { tmax *= 0.5; }
337 G4double t = std::min(cutEnergy, tmax);
338 G4double mom21 = t*(t + 2.0*electron_mass_c2);
339 G4double t1 = tkin - t;
340 //G4cout <<"tkin=" <<tkin<<" tmax= "<<tmax<<" t= "
341 //<<t<< " t1= "<<t1<<" cut= "<<ecut<<G4endl;
342 if(t1 > 0.0) {
343 G4double mom22 = t1*(t1 + 2.0*mass);
344 G4double ctm = (mom2 + mom22 - mom21)*0.5/sqrt(mom2*mom22);
345 if(ctm < 1.0) { cosTetMaxElec = ctm; }
346 //if(ctm < -1.0) { cosTetMaxElec = -1.0;}
347 if(particle == theElectron && cosTetMaxElec < 0.0) { cosTetMaxElec = 0.0; }
348 }
349 }
350}
351
352//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Note: See TracBrowser for help on using the repository browser.