Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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//
28// Author: V. Grichine (Vladimir,Grichine@cern.ch)
29//
30//
31// G4 Model: diffuse optical elastic scattering with 4-momentum balance
32//
33// Class Description
34// Final state production model for hadron nuclear elastic scattering;
35// Class Description - End
36//
37//
38// 24.05.07 V. Grichine, first implementation for hadron (no Coulomb) elastic scattering
39// 04.09.07 V. Grichine, implementation for Coulomb elastic scattering
40// 12.06.11 V. Grichine, new interface to G4hadronElastic
41
42#ifndef G4DiffuseElastic_h
43#define G4DiffuseElastic_h 1
44
46#include "globals.hh"
47#include "G4HadronElastic.hh"
48#include "G4HadProjectile.hh"
49#include "G4Nucleus.hh"
50
51#include "G4Pow.hh"
52
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 virtual G4bool IsApplicable(const G4HadProjectile &/*aTrack*/,
73 G4Nucleus & /*targetNucleus*/);
74
75 void Initialise();
76
78
79 void BuildAngleTable();
80
81
82 // G4HadFinalState* ApplyYourself(const G4HadProjectile & aTrack, G4Nucleus & targetNucleus);
83
85 G4double plab,
86 G4int Z, G4int A);
87
89
90 void SetPlabLowLimit(G4double value);
91
92 void SetHEModelLowLimit(G4double value);
93
94 void SetQModelLowLimit(G4double value);
95
97
99
100 G4double SampleT(const G4ParticleDefinition* aParticle,
101 G4double p, G4double A);
102
105
107
110
112
113 G4double SampleThetaLab(const G4HadProjectile* aParticle,
114 G4double tmass, G4double A);
115
117 G4double theta,
118 G4double momentum,
119 G4double A );
120
122 G4double theta,
123 G4double momentum,
124 G4double A, G4double Z );
125
127 G4double theta,
128 G4double momentum,
129 G4double A, G4double Z );
130
132 G4double tMand,
133 G4double momentum,
134 G4double A, G4double Z );
135
137 G4double theta,
138 G4double momentum,
139 G4double A );
140
141
143 G4double theta,
144 G4double momentum,
145 G4double Z );
146
148 G4double tMand,
149 G4double momentum,
150 G4double A, G4double Z );
151
153 G4double momentum, G4double Z );
154
156 G4double momentum, G4double Z,
157 G4double theta1, G4double theta2 );
158
159
161 G4double momentum );
162
164
166
168
170 G4double tmass, G4double thetaCMS);
171
173 G4double tmass, G4double thetaLab);
174
175 void TestAngleTable(const G4ParticleDefinition* theParticle, G4double partMom,
177
178
179
184
189
190
191 G4double GetNuclearRadius(){return fNuclearRadius;};
192
193private:
194
195
196 G4ParticleDefinition* theProton;
197 G4ParticleDefinition* theNeutron;
198 G4ParticleDefinition* theDeuteron;
199 G4ParticleDefinition* theAlpha;
200
201 const G4ParticleDefinition* thePionPlus;
202 const G4ParticleDefinition* thePionMinus;
203
204 G4double lowEnergyRecoilLimit;
205 G4double lowEnergyLimitHE;
206 G4double lowEnergyLimitQ;
207 G4double lowestEnergyLimit;
208 G4double plabLowLimit;
209
210 G4int fEnergyBin;
211 G4int fAngleBin;
212
213 G4PhysicsLogVector* fEnergyVector;
214 G4PhysicsTable* fAngleTable;
215 std::vector<G4PhysicsTable*> fAngleBank;
216
217 std::vector<G4double> fElementNumberVector;
218 std::vector<G4String> fElementNameVector;
219
220 const G4ParticleDefinition* fParticle;
221 G4double fWaveVector;
222 G4double fAtomicWeight;
223 G4double fAtomicNumber;
224 G4double fNuclearRadius;
225 G4double fBeta;
226 G4double fZommerfeld;
227 G4double fAm;
228 G4bool fAddCoulomb;
229
230};
231
233 G4Nucleus & nucleus)
234{
235 if( ( projectile.GetDefinition() == G4Proton::Proton() ||
236 projectile.GetDefinition() == G4Neutron::Neutron() ||
237 projectile.GetDefinition() == G4PionPlus::PionPlus() ||
238 projectile.GetDefinition() == G4PionMinus::PionMinus() ||
239 projectile.GetDefinition() == G4KaonPlus::KaonPlus() ||
240 projectile.GetDefinition() == G4KaonMinus::KaonMinus() ) &&
241
242 nucleus.GetZ_asInt() >= 2 ) return true;
243 else return false;
244}
245
247{
248 lowEnergyRecoilLimit = value;
249}
250
252{
253 plabLowLimit = value;
254}
255
257{
258 lowEnergyLimitHE = value;
259}
260
262{
263 lowEnergyLimitQ = value;
264}
265
267{
268 lowestEnergyLimit = value;
269}
270
271
272/////////////////////////////////////////////////////////////
273//
274// Bessel J0 function based on rational approximation from
275// J.F. Hart, Computer Approximations, New York, Willey 1968, p. 141
276
278{
279 G4double modvalue, value2, fact1, fact2, arg, shift, bessel;
280
281 modvalue = std::fabs(value);
282
283 if ( value < 8.0 && value > -8.0 )
284 {
285 value2 = value*value;
286
287 fact1 = 57568490574.0 + value2*(-13362590354.0
288 + value2*( 651619640.7
289 + value2*(-11214424.18
290 + value2*( 77392.33017
291 + value2*(-184.9052456 ) ) ) ) );
292
293 fact2 = 57568490411.0 + value2*( 1029532985.0
294 + value2*( 9494680.718
295 + value2*(59272.64853
296 + value2*(267.8532712
297 + value2*1.0 ) ) ) );
298
299 bessel = fact1/fact2;
300 }
301 else
302 {
303 arg = 8.0/modvalue;
304
305 value2 = arg*arg;
306
307 shift = modvalue-0.785398164;
308
309 fact1 = 1.0 + value2*(-0.1098628627e-2
310 + value2*(0.2734510407e-4
311 + value2*(-0.2073370639e-5
312 + value2*0.2093887211e-6 ) ) );
313
314 fact2 = -0.1562499995e-1 + value2*(0.1430488765e-3
315 + value2*(-0.6911147651e-5
316 + value2*(0.7621095161e-6
317 - value2*0.934945152e-7 ) ) );
318
319 bessel = std::sqrt(0.636619772/modvalue)*(std::cos(shift)*fact1 - arg*std::sin(shift)*fact2 );
320 }
321 return bessel;
322}
323
324/////////////////////////////////////////////////////////////
325//
326// Bessel J1 function based on rational approximation from
327// J.F. Hart, Computer Approximations, New York, Willey 1968, p. 141
328
330{
331 G4double modvalue, value2, fact1, fact2, arg, shift, bessel;
332
333 modvalue = std::fabs(value);
334
335 if ( modvalue < 8.0 )
336 {
337 value2 = value*value;
338
339 fact1 = value*(72362614232.0 + value2*(-7895059235.0
340 + value2*( 242396853.1
341 + value2*(-2972611.439
342 + value2*( 15704.48260
343 + value2*(-30.16036606 ) ) ) ) ) );
344
345 fact2 = 144725228442.0 + value2*(2300535178.0
346 + value2*(18583304.74
347 + value2*(99447.43394
348 + value2*(376.9991397
349 + value2*1.0 ) ) ) );
350 bessel = fact1/fact2;
351 }
352 else
353 {
354 arg = 8.0/modvalue;
355
356 value2 = arg*arg;
357
358 shift = modvalue - 2.356194491;
359
360 fact1 = 1.0 + value2*( 0.183105e-2
361 + value2*(-0.3516396496e-4
362 + value2*(0.2457520174e-5
363 + value2*(-0.240337019e-6 ) ) ) );
364
365 fact2 = 0.04687499995 + value2*(-0.2002690873e-3
366 + value2*( 0.8449199096e-5
367 + value2*(-0.88228987e-6
368 + value2*0.105787412e-6 ) ) );
369
370 bessel = std::sqrt( 0.636619772/modvalue)*(std::cos(shift)*fact1 - arg*std::sin(shift)*fact2);
371
372 if (value < 0.0) bessel = -bessel;
373 }
374 return bessel;
375}
376
377////////////////////////////////////////////////////////////////////
378//
379// damp factor in diffraction x/sh(x), x was already *pi
380
382{
383 G4double df;
384 G4double f2 = 2., f3 = 6., f4 = 24.; // first factorials
385
386 // x *= pi;
387
388 if( std::fabs(x) < 0.01 )
389 {
390 df = 1./(1. + x/f2 + x*x/f3 + x*x*x/f4);
391 }
392 else
393 {
394 df = x/std::sinh(x);
395 }
396 return df;
397}
398
399
400////////////////////////////////////////////////////////////////////
401//
402// return J1(x)/x with special case for small x
403
405{
406 G4double x2, result;
407
408 if( std::fabs(x) < 0.01 )
409 {
410 x *= 0.5;
411 x2 = x*x;
412 result = 2. - x2 + x2*x2/6.;
413 }
414 else
415 {
416 result = BesselJone(x)/x;
417 }
418 return result;
419}
420
421////////////////////////////////////////////////////////////////////
422//
423// return particle beta
424
426 G4double momentum )
427{
428 G4double mass = particle->GetPDGMass();
429 G4double a = momentum/mass;
430 fBeta = a/std::sqrt(1+a*a);
431
432 return fBeta;
433}
434
435////////////////////////////////////////////////////////////////////
436//
437// return Zommerfeld parameter for Coulomb scattering
438
440{
441 fZommerfeld = CLHEP::fine_structure_const*Z1*Z2/beta;
442
443 return fZommerfeld;
444}
445
446////////////////////////////////////////////////////////////////////
447//
448// return Wentzel correction for Coulomb scattering
449
451{
452 G4double k = momentum/CLHEP::hbarc;
453 G4double ch = 1.13 + 3.76*n*n;
454 G4double zn = 1.77*k*(1.0/G4Pow::GetInstance()->A13(Z))*CLHEP::Bohr_radius;
455 G4double zn2 = zn*zn;
456 fAm = ch/zn2;
457
458 return fAm;
459}
460
461////////////////////////////////////////////////////////////////////
462//
463// calculate nuclear radius for different atomic weights using different approximations
464
466{
467 G4double R, r0, a11, a12, a13, a2, a3;
468
469 a11 = 1.26; // 1.08, 1.16
470 a12 = 1.; // 1.08, 1.16
471 a13 = 1.12; // 1.08, 1.16
472 a2 = 1.1;
473 a3 = 1.;
474
475 // Special rms radii for light nucleii
476
477 if (A < 50.)
478 {
479 if (std::abs(A-1.) < 0.5) return 0.89*CLHEP::fermi; // p
480 else if(std::abs(A-2.) < 0.5) return 2.13*CLHEP::fermi; // d
481 else if( // std::abs(Z-1.) < 0.5 &&
482std::abs(A-3.) < 0.5) return 1.80*CLHEP::fermi; // t
483
484 // else if(std::abs(Z-2.) < 0.5 && std::abs(A-3.) < 0.5) return 1.96CLHEP::fermi; // He3
485 else if( // std::abs(Z-2.) < 0.5 &&
486std::abs(A-4.) < 0.5) return 1.68*CLHEP::fermi; // He4
487
488 else if( // std::abs(Z-3.) < 0.5
489 std::abs(A-7.) < 0.5 ) return 2.40*CLHEP::fermi; // Li7
490 else if( // std::abs(Z-4.) < 0.5
491std::abs(A-9.) < 0.5) return 2.51*CLHEP::fermi; // Be9
492
493 else if( 10. < A && A <= 16. ) r0 = a11*( 1 - (1.0/G4Pow::GetInstance()->A23(A)) )*CLHEP::fermi; // 1.08CLHEP::fermi;
494 else if( 15. < A && A <= 20. ) r0 = a12*( 1 - (1.0/G4Pow::GetInstance()->A23(A)) )*CLHEP::fermi;
495 else if( 20. < A && A <= 30. ) r0 = a13*( 1 - (1.0/G4Pow::GetInstance()->A23(A)) )*CLHEP::fermi;
496 else r0 = a2*CLHEP::fermi;
497
498 R = r0*G4Pow::GetInstance()->A13(A);
499 }
500 else
501 {
502 r0 = a3*CLHEP::fermi;
503
504 R = r0*G4Pow::GetInstance()->powA(A, 0.27);
505 }
506 fNuclearRadius = R;
507 return R;
508 /*
509 G4double r0;
510 if( A < 50. )
511 {
512 if( A > 10. ) r0 = 1.16*( 1 - (1.0/G4Pow::GetInstance()->A23(A)) )*CLHEP::fermi; // 1.08CLHEP::fermi;
513 else r0 = 1.1*CLHEP::fermi;
514 fNuclearRadius = r0*G4Pow::GetInstance()->A13(A);
515 }
516 else
517 {
518 r0 = 1.7*CLHEP::fermi; // 1.7*CLHEP::fermi;
519 fNuclearRadius = r0*G4Pow::GetInstance()->powA(A, 0.27); // 0.27);
520 }
521 return fNuclearRadius;
522 */
523}
524
525////////////////////////////////////////////////////////////////////
526//
527// return Coulomb scattering differential xsc with Wentzel correction
528
530 G4double theta,
531 G4double momentum,
532 G4double Z )
533{
534 G4double sinHalfTheta = std::sin(0.5*theta);
535 G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
536 G4double beta = CalculateParticleBeta( particle, momentum);
537 G4double z = particle->GetPDGCharge();
538 G4double n = CalculateZommerfeld( beta, z, Z );
539 G4double am = CalculateAm( momentum, n, Z);
540 G4double k = momentum/CLHEP::hbarc;
541 G4double ch = 0.5*n/k;
542 G4double ch2 = ch*ch;
543 G4double xsc = ch2/(sinHalfTheta2+am)/(sinHalfTheta2+am);
544
545 return xsc;
546}
547
548
549////////////////////////////////////////////////////////////////////
550//
551// return Coulomb scattering total xsc with Wentzel correction
552
554 G4double momentum, G4double Z )
555{
556 G4double beta = CalculateParticleBeta( particle, momentum);
557 G4cout<<"beta = "<<beta<<G4endl;
558 G4double z = particle->GetPDGCharge();
559 G4double n = CalculateZommerfeld( beta, z, Z );
560 G4cout<<"fZomerfeld = "<<n<<G4endl;
561 G4double am = CalculateAm( momentum, n, Z);
562 G4cout<<"cof Am = "<<am<<G4endl;
563 G4double k = momentum/CLHEP::hbarc;
564 G4cout<<"k = "<<k*CLHEP::fermi<<" 1/fermi"<<G4endl;
565 G4cout<<"k*Bohr_radius = "<<k*CLHEP::Bohr_radius<<G4endl;
566 G4double ch = n/k;
567 G4double ch2 = ch*ch;
568 G4double xsc = ch2*CLHEP::pi/(am +am*am);
569
570 return xsc;
571}
572
573////////////////////////////////////////////////////////////////////
574//
575// return Coulomb scattering xsc with Wentzel correction integrated between
576// theta1 and < theta2
577
579 G4double momentum, G4double Z,
580 G4double theta1, G4double theta2 )
581{
582 G4double c1 = std::cos(theta1);
583 G4cout<<"c1 = "<<c1<<G4endl;
584 G4double c2 = std::cos(theta2);
585 G4cout<<"c2 = "<<c2<<G4endl;
586 G4double beta = CalculateParticleBeta( particle, momentum);
587 // G4cout<<"beta = "<<beta<<G4endl;
588 G4double z = particle->GetPDGCharge();
589 G4double n = CalculateZommerfeld( beta, z, Z );
590 // G4cout<<"fZomerfeld = "<<n<<G4endl;
591 G4double am = CalculateAm( momentum, n, Z);
592 // G4cout<<"cof Am = "<<am<<G4endl;
593 G4double k = momentum/CLHEP::hbarc;
594 // G4cout<<"k = "<<k*CLHEP::fermi<<" 1/fermi"<<G4endl;
595 // G4cout<<"k*Bohr_radius = "<<k*CLHEP::Bohr_radius<<G4endl;
596 G4double ch = n/k;
597 G4double ch2 = ch*ch;
598 am *= 2.;
599 G4double xsc = ch2*CLHEP::twopi*(c1-c2);
600 xsc /= (1 - c1 + am)*(1 - c2 + am);
601
602 return xsc;
603}
604
605#endif
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
const G4int Z[17]
const G4double A[17]
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL 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)
virtual G4bool IsApplicable(const G4HadProjectile &, G4Nucleus &)
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 NeutronTuniform(G4int Z)
const G4ParticleDefinition * GetDefinition() const
static G4KaonMinus * KaonMinus()
Definition: G4KaonMinus.cc:112
static G4KaonPlus * KaonPlus()
Definition: G4KaonPlus.cc:112
static G4Neutron * Neutron()
Definition: G4Neutron.cc:103
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:105
G4double GetPDGCharge() const
static G4PionMinus * PionMinus()
Definition: G4PionMinus.cc:97
static G4PionPlus * PionPlus()
Definition: G4PionPlus.cc:97
static G4Pow * GetInstance()
Definition: G4Pow.cc:41
G4double A13(G4double A) const
Definition: G4Pow.cc:116
G4double powA(G4double A, G4double y) const
Definition: G4Pow.hh:230
G4double A23(G4double A) const
Definition: G4Pow.hh:131
static G4Proton * Proton()
Definition: G4Proton.cc:92