Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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,[email protected])
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