Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
G4DiffuseElastic.hh
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//
27// $Id$
28//
29// Author: V. Grichine (Vladimir,Grichine@cern.ch)
30//
31//
32// G4 Model: diffuse optical elastic scattering with 4-momentum balance
33//
34// Class Description
35// Final state production model for hadron nuclear elastic scattering;
36// Class Description - End
37//
38//
39// 24.05.07 V. Grichine, first implementation for hadron (no Coulomb) elastic scattering
40// 04.09.07 V. Grichine, implementation for Coulomb elastic scattering
41// 12.06.11 V. Grichine, new interface to G4hadronElastic
42
43#ifndef G4DiffuseElastic_h
44#define G4DiffuseElastic_h 1
45
47#include "globals.hh"
48#include "G4HadronElastic.hh"
49#include "G4HadProjectile.hh"
50#include "G4Nucleus.hh"
51
52using namespace std;
53
55class G4PhysicsTable;
57
58class G4DiffuseElastic : public G4HadronElastic // G4HadronicInteraction
59{
60public:
61
63
64 // G4DiffuseElastic(const G4ParticleDefinition* aParticle);
65
66
67
68
69
70 virtual ~G4DiffuseElastic();
71
72 void Initialise();
73
75
76 void BuildAngleTable();
77
78
79 // G4HadFinalState* ApplyYourself(const G4HadProjectile & aTrack, G4Nucleus & targetNucleus);
80
82 G4double plab,
83 G4int Z, G4int A);
84
85 void SetPlabLowLimit(G4double value);
86
87 void SetHEModelLowLimit(G4double value);
88
89 void SetQModelLowLimit(G4double value);
90
92
94
95 G4double SampleT(const G4ParticleDefinition* aParticle,
96 G4double p, G4double A);
97
99 G4double p, G4double Z, G4double A);
100
102
104 G4double Z, G4double A);
105
107
108 G4double SampleThetaLab(const G4HadProjectile* aParticle,
109 G4double tmass, G4double A);
110
112 G4double theta,
113 G4double momentum,
114 G4double A );
115
117 G4double theta,
118 G4double momentum,
119 G4double A, G4double Z );
120
122 G4double theta,
123 G4double momentum,
124 G4double A, G4double Z );
125
127 G4double tMand,
128 G4double momentum,
129 G4double A, G4double Z );
130
132 G4double theta,
133 G4double momentum,
134 G4double A );
135
136
138 G4double theta,
139 G4double momentum,
140 G4double Z );
141
143 G4double tMand,
144 G4double momentum,
145 G4double A, G4double Z );
146
148 G4double momentum, G4double Z );
149
151 G4double momentum, G4double Z,
152 G4double theta1, G4double theta2 );
153
154
156 G4double momentum );
157
159
161
163
165 G4double tmass, G4double thetaCMS);
166
168 G4double tmass, G4double thetaLab);
169
170 void TestAngleTable(const G4ParticleDefinition* theParticle, G4double partMom,
171 G4double Z, G4double A);
172
173
174
179
184
185
186 G4double GetNuclearRadius(){return fNuclearRadius;};
187
188private:
189
190
191 G4ParticleDefinition* theProton;
192 G4ParticleDefinition* theNeutron;
193 G4ParticleDefinition* theDeuteron;
194 G4ParticleDefinition* theAlpha;
195
196 const G4ParticleDefinition* thePionPlus;
197 const G4ParticleDefinition* thePionMinus;
198
199 G4double lowEnergyRecoilLimit;
200 G4double lowEnergyLimitHE;
201 G4double lowEnergyLimitQ;
202 G4double lowestEnergyLimit;
203 G4double plabLowLimit;
204
205 G4int fEnergyBin;
206 G4int fAngleBin;
207
208 G4PhysicsLogVector* fEnergyVector;
209 G4PhysicsTable* fAngleTable;
210 std::vector<G4PhysicsTable*> fAngleBank;
211
212 std::vector<G4double> fElementNumberVector;
213 std::vector<G4String> fElementNameVector;
214
215 const G4ParticleDefinition* fParticle;
216 G4double fWaveVector;
217 G4double fAtomicWeight;
218 G4double fAtomicNumber;
219 G4double fNuclearRadius;
220 G4double fBeta;
221 G4double fZommerfeld;
222 G4double fAm;
223 G4bool fAddCoulomb;
224
225};
226
227
229{
230 lowEnergyRecoilLimit = value;
231}
232
234{
235 plabLowLimit = value;
236}
237
239{
240 lowEnergyLimitHE = value;
241}
242
244{
245 lowEnergyLimitQ = value;
246}
247
249{
250 lowestEnergyLimit = value;
251}
252
253
254/////////////////////////////////////////////////////////////
255//
256// Bessel J0 function based on rational approximation from
257// J.F. Hart, Computer Approximations, New York, Willey 1968, p. 141
258
260{
261 G4double modvalue, value2, fact1, fact2, arg, shift, bessel;
262
263 modvalue = fabs(value);
264
265 if ( value < 8.0 && value > -8.0 )
266 {
267 value2 = value*value;
268
269 fact1 = 57568490574.0 + value2*(-13362590354.0
270 + value2*( 651619640.7
271 + value2*(-11214424.18
272 + value2*( 77392.33017
273 + value2*(-184.9052456 ) ) ) ) );
274
275 fact2 = 57568490411.0 + value2*( 1029532985.0
276 + value2*( 9494680.718
277 + value2*(59272.64853
278 + value2*(267.8532712
279 + value2*1.0 ) ) ) );
280
281 bessel = fact1/fact2;
282 }
283 else
284 {
285 arg = 8.0/modvalue;
286
287 value2 = arg*arg;
288
289 shift = modvalue-0.785398164;
290
291 fact1 = 1.0 + value2*(-0.1098628627e-2
292 + value2*(0.2734510407e-4
293 + value2*(-0.2073370639e-5
294 + value2*0.2093887211e-6 ) ) );
295
296 fact2 = -0.1562499995e-1 + value2*(0.1430488765e-3
297 + value2*(-0.6911147651e-5
298 + value2*(0.7621095161e-6
299 - value2*0.934945152e-7 ) ) );
300
301 bessel = sqrt(0.636619772/modvalue)*(cos(shift)*fact1 - arg*sin(shift)*fact2 );
302 }
303 return bessel;
304}
305
306/////////////////////////////////////////////////////////////
307//
308// Bessel J1 function based on rational approximation from
309// J.F. Hart, Computer Approximations, New York, Willey 1968, p. 141
310
312{
313 G4double modvalue, value2, fact1, fact2, arg, shift, bessel;
314
315 modvalue = fabs(value);
316
317 if ( modvalue < 8.0 )
318 {
319 value2 = value*value;
320
321 fact1 = value*(72362614232.0 + value2*(-7895059235.0
322 + value2*( 242396853.1
323 + value2*(-2972611.439
324 + value2*( 15704.48260
325 + value2*(-30.16036606 ) ) ) ) ) );
326
327 fact2 = 144725228442.0 + value2*(2300535178.0
328 + value2*(18583304.74
329 + value2*(99447.43394
330 + value2*(376.9991397
331 + value2*1.0 ) ) ) );
332 bessel = fact1/fact2;
333 }
334 else
335 {
336 arg = 8.0/modvalue;
337
338 value2 = arg*arg;
339
340 shift = modvalue - 2.356194491;
341
342 fact1 = 1.0 + value2*( 0.183105e-2
343 + value2*(-0.3516396496e-4
344 + value2*(0.2457520174e-5
345 + value2*(-0.240337019e-6 ) ) ) );
346
347 fact2 = 0.04687499995 + value2*(-0.2002690873e-3
348 + value2*( 0.8449199096e-5
349 + value2*(-0.88228987e-6
350 + value2*0.105787412e-6 ) ) );
351
352 bessel = sqrt( 0.636619772/modvalue)*(cos(shift)*fact1 - arg*sin(shift)*fact2);
353
354 if (value < 0.0) bessel = -bessel;
355 }
356 return bessel;
357}
358
359////////////////////////////////////////////////////////////////////
360//
361// damp factor in diffraction x/sh(x), x was already *pi
362
364{
365 G4double df;
366 G4double f2 = 2., f3 = 6., f4 = 24.; // first factorials
367
368 // x *= pi;
369
370 if( std::fabs(x) < 0.01 )
371 {
372 df = 1./(1. + x/f2 + x*x/f3 + x*x*x/f4);
373 }
374 else
375 {
376 df = x/std::sinh(x);
377 }
378 return df;
379}
380
381
382////////////////////////////////////////////////////////////////////
383//
384// return J1(x)/x with special case for small x
385
387{
388 G4double x2, result;
389
390 if( std::fabs(x) < 0.01 )
391 {
392 x *= 0.5;
393 x2 = x*x;
394 result = 2. - x2 + x2*x2/6.;
395 }
396 else
397 {
398 result = BesselJone(x)/x;
399 }
400 return result;
401}
402
403////////////////////////////////////////////////////////////////////
404//
405// return particle beta
406
408 G4double momentum )
409{
410 G4double mass = particle->GetPDGMass();
411 G4double a = momentum/mass;
412 fBeta = a/std::sqrt(1+a*a);
413
414 return fBeta;
415}
416
417////////////////////////////////////////////////////////////////////
418//
419// return Zommerfeld parameter for Coulomb scattering
420
422{
423 fZommerfeld = CLHEP::fine_structure_const*Z1*Z2/beta;
424
425 return fZommerfeld;
426}
427
428////////////////////////////////////////////////////////////////////
429//
430// return Wentzel correction for Coulomb scattering
431
433{
434 G4double k = momentum/CLHEP::hbarc;
435 G4double ch = 1.13 + 3.76*n*n;
436 G4double zn = 1.77*k*std::pow(Z,-1./3.)*CLHEP::Bohr_radius;
437 G4double zn2 = zn*zn;
438 fAm = ch/zn2;
439
440 return fAm;
441}
442
443////////////////////////////////////////////////////////////////////
444//
445// calculate nuclear radius for different atomic weights using different approximations
446
448{
449 G4double r0;
450
451 if( A < 50. )
452 {
453 if( A > 10. ) r0 = 1.16*( 1 - std::pow(A, -2./3.) )*CLHEP::fermi; // 1.08*fermi;
454 else r0 = 1.1*CLHEP::fermi;
455
456 fNuclearRadius = r0*std::pow(A, 1./3.);
457 }
458 else
459 {
460 r0 = 1.7*CLHEP::fermi; // 1.7*fermi;
461
462 fNuclearRadius = r0*std::pow(A, 0.27); // 0.27);
463 }
464 return fNuclearRadius;
465}
466
467////////////////////////////////////////////////////////////////////
468//
469// return Coulomb scattering differential xsc with Wentzel correction
470
472 G4double theta,
473 G4double momentum,
474 G4double Z )
475{
476 G4double sinHalfTheta = std::sin(0.5*theta);
477 G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
478 G4double beta = CalculateParticleBeta( particle, momentum);
479 G4double z = particle->GetPDGCharge();
480 G4double n = CalculateZommerfeld( beta, z, Z );
481 G4double am = CalculateAm( momentum, n, Z);
482 G4double k = momentum/CLHEP::hbarc;
483 G4double ch = 0.5*n/k;
484 G4double ch2 = ch*ch;
485 G4double xsc = ch2/(sinHalfTheta2+am)/(sinHalfTheta2+am);
486
487 return xsc;
488}
489
490
491////////////////////////////////////////////////////////////////////
492//
493// return Coulomb scattering total xsc with Wentzel correction
494
496 G4double momentum, G4double Z )
497{
498 G4double beta = CalculateParticleBeta( particle, momentum);
499 G4cout<<"beta = "<<beta<<G4endl;
500 G4double z = particle->GetPDGCharge();
501 G4double n = CalculateZommerfeld( beta, z, Z );
502 G4cout<<"fZomerfeld = "<<n<<G4endl;
503 G4double am = CalculateAm( momentum, n, Z);
504 G4cout<<"cof Am = "<<am<<G4endl;
505 G4double k = momentum/CLHEP::hbarc;
506 G4cout<<"k = "<<k*CLHEP::fermi<<" 1/fermi"<<G4endl;
507 G4cout<<"k*Bohr_radius = "<<k*CLHEP::Bohr_radius<<G4endl;
508 G4double ch = n/k;
509 G4double ch2 = ch*ch;
510 G4double xsc = ch2*CLHEP::pi/(am +am*am);
511
512 return xsc;
513}
514
515////////////////////////////////////////////////////////////////////
516//
517// return Coulomb scattering xsc with Wentzel correction integrated between
518// theta1 and < theta2
519
521 G4double momentum, G4double Z,
522 G4double theta1, G4double theta2 )
523{
524 G4double c1 = std::cos(theta1);
525 G4cout<<"c1 = "<<c1<<G4endl;
526 G4double c2 = std::cos(theta2);
527 G4cout<<"c2 = "<<c2<<G4endl;
528 G4double beta = CalculateParticleBeta( particle, momentum);
529 // G4cout<<"beta = "<<beta<<G4endl;
530 G4double z = particle->GetPDGCharge();
531 G4double n = CalculateZommerfeld( beta, z, Z );
532 // G4cout<<"fZomerfeld = "<<n<<G4endl;
533 G4double am = CalculateAm( momentum, n, Z);
534 // G4cout<<"cof Am = "<<am<<G4endl;
535 G4double k = momentum/CLHEP::hbarc;
536 // G4cout<<"k = "<<k*CLHEP::fermi<<" 1/fermi"<<G4endl;
537 // G4cout<<"k*Bohr_radius = "<<k*CLHEP::Bohr_radius<<G4endl;
538 G4double ch = n/k;
539 G4double ch2 = ch*ch;
540 am *= 2.;
541 G4double xsc = ch2*CLHEP::twopi*(c1-c2);
542 xsc /= (1 - c1 + am)*(1 - c2 + am);
543
544 return xsc;
545}
546
547#endif
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
G4double SampleThetaLab(const G4HadProjectile *aParticle, G4double tmass, G4double A)
G4double GetDiffElasticSumProbA(G4double alpha)
G4double BesselOneByArg(G4double z)
G4double GetCoulombElasticXsc(const G4ParticleDefinition *particle, G4double theta, G4double momentum, G4double Z)
G4double CalculateAm(G4double momentum, G4double n, G4double Z)
G4double ThetaCMStoThetaLab(const G4DynamicParticle *aParticle, G4double tmass, G4double thetaCMS)
G4double GetCoulombTotalXsc(const G4ParticleDefinition *particle, G4double momentum, G4double Z)
G4double GetInvElasticXsc(const G4ParticleDefinition *particle, G4double theta, G4double momentum, G4double A, G4double Z)
G4double GetInvCoulombElasticXsc(const G4ParticleDefinition *particle, G4double tMand, G4double momentum, G4double A, G4double Z)
void TestAngleTable(const G4ParticleDefinition *theParticle, G4double partMom, G4double Z, G4double A)
G4double ThetaLabToThetaCMS(const G4DynamicParticle *aParticle, G4double tmass, G4double thetaLab)
G4double GetNuclearRadius()
G4double BesselJzero(G4double z)
G4double SampleThetaCMS(const G4ParticleDefinition *aParticle, G4double p, G4double A)
G4double GetCoulombIntegralXsc(const G4ParticleDefinition *particle, G4double momentum, G4double Z, G4double theta1, G4double theta2)
G4double GetIntegrandFunction(G4double theta)
void SetHEModelLowLimit(G4double value)
G4double DampFactor(G4double z)
void SetQModelLowLimit(G4double value)
G4double SampleTableThetaCMS(const G4ParticleDefinition *aParticle, G4double p, G4double Z, G4double A)
virtual G4double SampleInvariantT(const G4ParticleDefinition *p, G4double plab, G4int Z, G4int A)
void SetLowestEnergyLimit(G4double value)
G4double CalculateParticleBeta(const G4ParticleDefinition *particle, G4double momentum)
G4double GetDiffuseElasticSumXsc(const G4ParticleDefinition *particle, G4double theta, G4double momentum, G4double A, G4double Z)
G4double SampleT(const G4ParticleDefinition *aParticle, G4double p, G4double A)
G4double GetDiffElasticSumProb(G4double theta)
G4double GetDiffElasticProb(G4double theta)
G4double IntegralElasticProb(const G4ParticleDefinition *particle, G4double theta, G4double momentum, G4double A)
G4double CalculateZommerfeld(G4double beta, G4double Z1, G4double Z2)
G4double CalculateNuclearRad(G4double A)
virtual ~G4DiffuseElastic()
void InitialiseOnFly(G4double Z, G4double A)
void SetRecoilKinEnergyLimit(G4double value)
G4double SampleTableT(const G4ParticleDefinition *aParticle, G4double p, G4double Z, G4double A)
G4double BesselJone(G4double z)
G4double GetDiffuseElasticXsc(const G4ParticleDefinition *particle, G4double theta, G4double momentum, G4double A)
G4double GetScatteringAngle(G4int iMomentum, G4int iAngle, G4double position)
void SetPlabLowLimit(G4double value)
G4double GetInvElasticSumXsc(const G4ParticleDefinition *particle, G4double tMand, G4double momentum, G4double A, G4double Z)
G4double GetPDGCharge() const