Warning, file /include/Geant4/G4NuclNuclDiffuseElastic.hh was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #ifndef G4NuclNuclDiffuseElastic_h
0042 #define G4NuclNuclDiffuseElastic_h 1
0043
0044 #include <complex>
0045 #include <CLHEP/Units/PhysicalConstants.h>
0046 #include "globals.hh"
0047 #include "G4Integrator.hh"
0048 #include "G4HadronElastic.hh"
0049 #include "G4HadProjectile.hh"
0050 #include "G4Nucleus.hh"
0051
0052 #include "G4Exp.hh"
0053 #include "G4Log.hh"
0054 #include "G4Pow.hh"
0055
0056
0057 class G4ParticleDefinition;
0058 class G4PhysicsTable;
0059 class G4PhysicsLogVector;
0060
0061 class G4NuclNuclDiffuseElastic : public G4HadronElastic
0062 {
0063 public:
0064
0065 G4NuclNuclDiffuseElastic();
0066
0067
0068
0069 virtual ~G4NuclNuclDiffuseElastic();
0070
0071 void Initialise();
0072
0073 void InitialiseOnFly(G4double Z, G4double A);
0074
0075 void BuildAngleTable();
0076
0077 virtual G4double SampleInvariantT(const G4ParticleDefinition* p,
0078 G4double plab,
0079 G4int Z, G4int A);
0080
0081 void SetPlabLowLimit(G4double value);
0082
0083 void SetHEModelLowLimit(G4double value);
0084
0085 void SetQModelLowLimit(G4double value);
0086
0087 void SetLowestEnergyLimit(G4double value);
0088
0089 void SetRecoilKinEnergyLimit(G4double value);
0090
0091 G4double SampleT(const G4ParticleDefinition* aParticle,
0092 G4double p, G4double A);
0093
0094 G4double SampleTableT(const G4ParticleDefinition* aParticle,
0095 G4double p, G4double Z, G4double A);
0096
0097 G4double SampleThetaCMS( const G4ParticleDefinition* aParticle, G4double p, G4double A);
0098
0099 G4double SampleCoulombMuCMS( const G4ParticleDefinition* aParticle, G4double p);
0100
0101 G4double SampleTableThetaCMS(const G4ParticleDefinition* aParticle, G4double p,
0102 G4double Z, G4double A);
0103
0104 G4double GetScatteringAngle(G4int iMomentum, G4int iAngle, G4double position);
0105
0106 G4double SampleThetaLab(const G4HadProjectile* aParticle,
0107 G4double tmass, G4double A);
0108
0109 G4double GetDiffuseElasticXsc( const G4ParticleDefinition* particle,
0110 G4double theta,
0111 G4double momentum,
0112 G4double A );
0113
0114 G4double GetInvElasticXsc( const G4ParticleDefinition* particle,
0115 G4double theta,
0116 G4double momentum,
0117 G4double A, G4double Z );
0118
0119 G4double GetDiffuseElasticSumXsc( const G4ParticleDefinition* particle,
0120 G4double theta,
0121 G4double momentum,
0122 G4double A, G4double Z );
0123
0124 G4double GetInvElasticSumXsc( const G4ParticleDefinition* particle,
0125 G4double tMand,
0126 G4double momentum,
0127 G4double A, G4double Z );
0128
0129 G4double IntegralElasticProb( const G4ParticleDefinition* particle,
0130 G4double theta,
0131 G4double momentum,
0132 G4double A );
0133
0134
0135 G4double GetCoulombElasticXsc( const G4ParticleDefinition* particle,
0136 G4double theta,
0137 G4double momentum,
0138 G4double Z );
0139
0140 G4double GetRutherfordXsc( G4double theta );
0141
0142 G4double GetInvCoulombElasticXsc( const G4ParticleDefinition* particle,
0143 G4double tMand,
0144 G4double momentum,
0145 G4double A, G4double Z );
0146
0147 G4double GetCoulombTotalXsc( const G4ParticleDefinition* particle,
0148 G4double momentum, G4double Z );
0149
0150 G4double GetCoulombIntegralXsc( const G4ParticleDefinition* particle,
0151 G4double momentum, G4double Z,
0152 G4double theta1, G4double theta2 );
0153
0154
0155 G4double CalculateParticleBeta( const G4ParticleDefinition* particle,
0156 G4double momentum );
0157
0158 G4double CalculateZommerfeld( G4double beta, G4double Z1, G4double Z2 );
0159
0160 G4double CalculateAm( G4double momentum, G4double n, G4double Z);
0161
0162 G4double CalculateNuclearRad( G4double A);
0163
0164 G4double ThetaCMStoThetaLab(const G4DynamicParticle* aParticle,
0165 G4double tmass, G4double thetaCMS);
0166
0167 G4double ThetaLabToThetaCMS(const G4DynamicParticle* aParticle,
0168 G4double tmass, G4double thetaLab);
0169
0170 void TestAngleTable(const G4ParticleDefinition* theParticle, G4double partMom,
0171 G4double Z, G4double A);
0172
0173
0174
0175 G4double BesselJzero(G4double z);
0176 G4double BesselJone(G4double z);
0177 G4double DampFactor(G4double z);
0178 G4double BesselOneByArg(G4double z);
0179
0180 G4double GetDiffElasticProb(G4double theta);
0181 G4double GetDiffElasticSumProb(G4double theta);
0182 G4double GetDiffElasticSumProbA(G4double alpha);
0183 G4double GetIntegrandFunction(G4double theta);
0184
0185 G4double GetNuclearRadius(){return fNuclearRadius;};
0186
0187
0188
0189
0190 G4complex GammaLogarithm(G4complex xx);
0191 G4complex GammaLogB2n(G4complex xx);
0192
0193 G4double GetErf(G4double x);
0194
0195 G4double GetCosHaPit2(G4double t){return std::cos(CLHEP::halfpi*t*t);};
0196 G4double GetSinHaPit2(G4double t){return std::sin(CLHEP::halfpi*t*t);};
0197
0198 G4double GetCint(G4double x);
0199 G4double GetSint(G4double x);
0200
0201
0202 G4complex GetErfcComp(G4complex z, G4int nMax);
0203 G4complex GetErfcSer(G4complex z, G4int nMax);
0204 G4complex GetErfcInt(G4complex z);
0205
0206 G4complex GetErfComp(G4complex z, G4int nMax);
0207 G4complex GetErfSer(G4complex z, G4int nMax);
0208
0209 G4double GetExpCos(G4double x);
0210 G4double GetExpSin(G4double x);
0211 G4complex GetErfInt(G4complex z);
0212
0213 G4double GetLegendrePol(G4int n, G4double x);
0214
0215 G4complex TestErfcComp(G4complex z, G4int nMax);
0216 G4complex TestErfcSer(G4complex z, G4int nMax);
0217 G4complex TestErfcInt(G4complex z);
0218
0219 G4complex CoulombAmplitude(G4double theta);
0220 G4double CoulombAmplitudeMod2(G4double theta);
0221
0222 void CalculateCoulombPhaseZero();
0223 G4double CalculateCoulombPhase(G4int n);
0224 void CalculateRutherfordAnglePar();
0225
0226 G4double ProfileNear(G4double theta);
0227 G4double ProfileFar(G4double theta);
0228 G4double Profile(G4double theta);
0229
0230 G4complex PhaseNear(G4double theta);
0231 G4complex PhaseFar(G4double theta);
0232
0233 G4complex GammaLess(G4double theta);
0234 G4complex GammaMore(G4double theta);
0235
0236 G4complex AmplitudeNear(G4double theta);
0237 G4complex AmplitudeFar(G4double theta);
0238
0239 G4complex Amplitude(G4double theta);
0240 G4double AmplitudeMod2(G4double theta);
0241
0242 G4complex AmplitudeSim(G4double theta);
0243 G4double AmplitudeSimMod2(G4double theta);
0244
0245 G4double GetRatioSim(G4double theta);
0246 G4double GetRatioGen(G4double theta);
0247
0248 G4double GetFresnelDiffuseXsc(G4double theta);
0249 G4double GetFresnelIntegrandXsc(G4double alpha);
0250
0251
0252 G4complex AmplitudeGla(G4double theta);
0253 G4double AmplitudeGlaMod2(G4double theta);
0254
0255 G4complex AmplitudeGG(G4double theta);
0256 G4double AmplitudeGGMod2(G4double theta);
0257
0258 void InitParameters(const G4ParticleDefinition* theParticle,
0259 G4double partMom, G4double Z, G4double A);
0260
0261 void InitDynParameters(const G4ParticleDefinition* theParticle,
0262 G4double partMom);
0263
0264 void InitParametersGla(const G4DynamicParticle* aParticle,
0265 G4double partMom, G4double Z, G4double A);
0266
0267 G4double GetHadronNucleonXscNS( G4ParticleDefinition* pParticle,
0268 G4double pTkin,
0269 G4ParticleDefinition* tParticle);
0270
0271 G4double CalcMandelstamS( const G4double mp , const G4double mt ,
0272 const G4double Plab );
0273
0274 G4double GetProfileLambda(){return fProfileLambda;};
0275
0276 inline void SetProfileLambda(G4double pl) {fProfileLambda = pl;};
0277 inline void SetProfileDelta(G4double pd) {fProfileDelta = pd;};
0278 inline void SetProfileAlpha(G4double pa){fProfileAlpha = pa;};
0279 inline void SetCofLambda(G4double pa){fCofLambda = pa;};
0280
0281 inline void SetCofAlpha(G4double pa){fCofAlpha = pa;};
0282 inline void SetCofAlphaMax(G4double pa){fCofAlphaMax = pa;};
0283 inline void SetCofAlphaCoulomb(G4double pa){fCofAlphaCoulomb = pa;};
0284
0285 inline void SetCofDelta(G4double pa){fCofDelta = pa;};
0286 inline void SetCofPhase(G4double pa){fCofPhase = pa;};
0287 inline void SetCofFar(G4double pa){fCofFar = pa;};
0288 inline void SetEtaRatio(G4double pa){fEtaRatio = pa;};
0289 inline void SetMaxL(G4int l){fMaxL = l;};
0290 inline void SetNuclearRadiusCof(G4double r){fNuclearRadiusCof = r;};
0291
0292 inline G4double GetCofAlphaMax(){return fCofAlphaMax;};
0293 inline G4double GetCofAlphaCoulomb(){return fCofAlphaCoulomb;};
0294
0295 private:
0296
0297 G4ParticleDefinition* theProton;
0298 G4ParticleDefinition* theNeutron;
0299 G4ParticleDefinition* theDeuteron;
0300 G4ParticleDefinition* theAlpha;
0301
0302 const G4ParticleDefinition* thePionPlus;
0303 const G4ParticleDefinition* thePionMinus;
0304
0305 G4double lowEnergyRecoilLimit;
0306 G4double lowEnergyLimitHE;
0307 G4double lowEnergyLimitQ;
0308 G4double lowestEnergyLimit;
0309 G4double plabLowLimit;
0310
0311 G4int fEnergyBin;
0312 G4int fAngleBin;
0313
0314 G4PhysicsLogVector* fEnergyVector;
0315 G4PhysicsTable* fAngleTable;
0316 std::vector<G4PhysicsTable*> fAngleBank;
0317
0318 std::vector<G4double> fElementNumberVector;
0319 std::vector<G4String> fElementNameVector;
0320
0321 const G4ParticleDefinition* fParticle;
0322
0323 G4double fWaveVector;
0324 G4double fAtomicWeight;
0325 G4double fAtomicNumber;
0326
0327 G4double fNuclearRadius1;
0328 G4double fNuclearRadius2;
0329 G4double fNuclearRadius;
0330 G4double fNuclearRadiusSquare;
0331 G4double fNuclearRadiusCof;
0332
0333 G4double fBeta;
0334 G4double fZommerfeld;
0335 G4double fRutherfordRatio;
0336 G4double fAm;
0337 G4bool fAddCoulomb;
0338
0339 G4double fCoulombPhase0;
0340 G4double fHalfRutThetaTg;
0341 G4double fHalfRutThetaTg2;
0342 G4double fRutherfordTheta;
0343
0344 G4double fProfileLambda;
0345 G4double fProfileDelta;
0346 G4double fProfileAlpha;
0347
0348 G4double fCofLambda;
0349 G4double fCofAlpha;
0350 G4double fCofDelta;
0351 G4double fCofPhase;
0352 G4double fCofFar;
0353
0354 G4double fCofAlphaMax;
0355 G4double fCofAlphaCoulomb;
0356
0357 G4int fMaxL;
0358 G4double fSumSigma;
0359 G4double fEtaRatio;
0360
0361 G4double fReZ;
0362 G4double fCoulombMuC;
0363
0364 };
0365
0366
0367 inline void G4NuclNuclDiffuseElastic::SetRecoilKinEnergyLimit(G4double value)
0368 {
0369 lowEnergyRecoilLimit = value;
0370 }
0371
0372 inline void G4NuclNuclDiffuseElastic::SetPlabLowLimit(G4double value)
0373 {
0374 plabLowLimit = value;
0375 }
0376
0377 inline void G4NuclNuclDiffuseElastic::SetHEModelLowLimit(G4double value)
0378 {
0379 lowEnergyLimitHE = value;
0380 }
0381
0382 inline void G4NuclNuclDiffuseElastic::SetQModelLowLimit(G4double value)
0383 {
0384 lowEnergyLimitQ = value;
0385 }
0386
0387 inline void G4NuclNuclDiffuseElastic::SetLowestEnergyLimit(G4double value)
0388 {
0389 lowestEnergyLimit = value;
0390 }
0391
0392
0393
0394
0395
0396 inline G4double G4NuclNuclDiffuseElastic::DampFactor(G4double x)
0397 {
0398 G4double df;
0399 G4double f2 = 2., f3 = 6., f4 = 24.;
0400
0401
0402
0403 if( std::fabs(x) < 0.01 )
0404 {
0405 df = 1./(1. + x/f2 + x*x/f3 + x*x*x/f4);
0406 }
0407 else
0408 {
0409 df = x/std::sinh(x);
0410 }
0411 return df;
0412 }
0413
0414
0415
0416
0417
0418
0419 inline G4double G4NuclNuclDiffuseElastic::BesselOneByArg(G4double x)
0420 {
0421 G4double x2, result;
0422
0423 if( std::fabs(x) < 0.01 )
0424 {
0425 x *= 0.5;
0426 x2 = x*x;
0427 result = 2. - x2 + x2*x2/6.;
0428 }
0429 else
0430 {
0431 result = BesselJone(x)/x;
0432 }
0433 return result;
0434 }
0435
0436
0437
0438
0439
0440 inline G4double
0441 G4NuclNuclDiffuseElastic::CalculateParticleBeta(const G4ParticleDefinition* particle,
0442 G4double momentum)
0443 {
0444 G4double mass = particle->GetPDGMass();
0445 G4double a = momentum/mass;
0446 fBeta = a/std::sqrt(1+a*a);
0447
0448 return fBeta;
0449 }
0450
0451
0452
0453
0454
0455 inline G4double
0456 G4NuclNuclDiffuseElastic::CalculateZommerfeld(G4double beta, G4double Z1, G4double Z2 )
0457 {
0458 fZommerfeld = CLHEP::fine_structure_const*Z1*Z2/beta;
0459
0460 return fZommerfeld;
0461 }
0462
0463
0464
0465
0466
0467 inline G4double
0468 G4NuclNuclDiffuseElastic::CalculateAm( G4double momentum, G4double n, G4double Z)
0469 {
0470 G4double k = momentum/CLHEP::hbarc;
0471 G4double ch = 1.13 + 3.76*n*n;
0472 G4double zn = 1.77*k*(1.0/G4Pow::GetInstance()->A13(Z))*CLHEP::Bohr_radius;
0473 G4double zn2 = zn*zn;
0474 fAm = ch/zn2;
0475
0476 return fAm;
0477 }
0478
0479
0480
0481
0482
0483 inline G4double G4NuclNuclDiffuseElastic::CalculateNuclearRad( G4double A)
0484 {
0485 G4double r0 = 1.*CLHEP::fermi, radius;
0486
0487
0488 r0 *= fNuclearRadiusCof;
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505 radius = r0*G4Pow::GetInstance()->A13(A);
0506
0507 return radius;
0508 }
0509
0510
0511
0512
0513
0514 inline G4double G4NuclNuclDiffuseElastic::GetCoulombElasticXsc( const G4ParticleDefinition* particle,
0515 G4double theta,
0516 G4double momentum,
0517 G4double Z )
0518 {
0519 G4double sinHalfTheta = std::sin(0.5*theta);
0520 G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
0521 G4double beta = CalculateParticleBeta( particle, momentum);
0522 G4double z = particle->GetPDGCharge();
0523 G4double n = CalculateZommerfeld( beta, z, Z );
0524 G4double am = CalculateAm( momentum, n, Z);
0525 G4double k = momentum/CLHEP::hbarc;
0526 G4double ch = 0.5*n/k;
0527 G4double ch2 = ch*ch;
0528 G4double xsc = ch2/((sinHalfTheta2+am)*(sinHalfTheta2+am));
0529
0530 return xsc;
0531 }
0532
0533
0534
0535
0536
0537 inline G4double G4NuclNuclDiffuseElastic::GetRutherfordXsc(G4double theta)
0538 {
0539 G4double sinHalfTheta = std::sin(0.5*theta);
0540 G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
0541
0542 G4double ch2 = fRutherfordRatio*fRutherfordRatio;
0543
0544 G4double xsc = ch2/(sinHalfTheta2+fAm)/(sinHalfTheta2+fAm);
0545
0546 return xsc;
0547 }
0548
0549
0550
0551
0552
0553 inline G4double G4NuclNuclDiffuseElastic::GetCoulombTotalXsc( const G4ParticleDefinition* particle,
0554 G4double momentum, G4double Z )
0555 {
0556 G4double beta = CalculateParticleBeta( particle, momentum);
0557 G4cout<<"beta = "<<beta<<G4endl;
0558 G4double z = particle->GetPDGCharge();
0559 G4double n = CalculateZommerfeld( beta, z, Z );
0560 G4cout<<"fZomerfeld = "<<n<<G4endl;
0561 G4double am = CalculateAm( momentum, n, Z);
0562 G4cout<<"cof Am = "<<am<<G4endl;
0563 G4double k = momentum/CLHEP::hbarc;
0564 G4cout<<"k = "<<k*CLHEP::fermi<<" 1/fermi"<<G4endl;
0565 G4cout<<"k*Bohr_radius = "<<k*CLHEP::Bohr_radius<<G4endl;
0566 G4double ch = n/k;
0567 G4double ch2 = ch*ch;
0568 G4double xsc = ch2*CLHEP::pi/(am +am*am);
0569
0570 return xsc;
0571 }
0572
0573
0574
0575
0576
0577
0578 inline G4double
0579 G4NuclNuclDiffuseElastic::GetCoulombIntegralXsc(const G4ParticleDefinition* particle,
0580 G4double momentum, G4double Z,
0581 G4double theta1, G4double theta2 )
0582 {
0583 G4double c1 = std::cos(theta1);
0584
0585 G4double c2 = std::cos(theta2);
0586
0587 G4double beta = CalculateParticleBeta( particle, momentum);
0588
0589 G4double z = particle->GetPDGCharge();
0590 G4double n = CalculateZommerfeld( beta, z, Z );
0591
0592 G4double am = CalculateAm( momentum, n, Z);
0593
0594 G4double k = momentum/CLHEP::hbarc;
0595
0596
0597 G4double ch = n/k;
0598 G4double ch2 = ch*ch;
0599 am *= 2.;
0600 G4double xsc = ch2*CLHEP::twopi*(c1-c2)/((1 - c1 + am)*(1 - c2 + am));
0601
0602 return xsc;
0603 }
0604
0605
0606
0607
0608
0609
0610 inline G4complex G4NuclNuclDiffuseElastic::GammaLogB2n(G4complex z)
0611 {
0612 G4complex z1 = 12.*z;
0613 G4complex z2 = z*z;
0614 G4complex z3 = z2*z;
0615 G4complex z5 = z2*z3;
0616 G4complex z7 = z2*z5;
0617
0618 z3 *= 360.;
0619 z5 *= 1260.;
0620 z7 *= 1680.;
0621
0622 G4complex result = (z-0.5)*std::log(z)-z+0.5*G4Log(CLHEP::twopi);
0623 result += 1./z1 - 1./z3 +1./z5 -1./z7;
0624 return result;
0625 }
0626
0627
0628
0629
0630
0631 inline G4double G4NuclNuclDiffuseElastic::GetErf(G4double x)
0632 {
0633 G4double t, z, tmp, result;
0634
0635 z = std::fabs(x);
0636 t = 1.0/(1.0+0.5*z);
0637
0638 tmp = t*std::exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
0639 t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
0640 t*(-0.82215223+t*0.17087277)))))))));
0641
0642 if( x >= 0.) result = 1. - tmp;
0643 else result = 1. + tmp;
0644
0645 return result;
0646 }
0647
0648
0649
0650
0651
0652 inline G4complex G4NuclNuclDiffuseElastic::GetErfcComp(G4complex z, G4int nMax)
0653 {
0654 G4complex erfcz = 1. - GetErfComp( z, nMax);
0655 return erfcz;
0656 }
0657
0658
0659
0660
0661
0662 inline G4complex G4NuclNuclDiffuseElastic::GetErfcSer(G4complex z, G4int nMax)
0663 {
0664 G4complex erfcz = 1. - GetErfSer( z, nMax);
0665 return erfcz;
0666 }
0667
0668
0669
0670
0671
0672 inline G4complex G4NuclNuclDiffuseElastic::GetErfcInt(G4complex z)
0673 {
0674 G4complex erfcz = 1. - GetErfInt( z);
0675 return erfcz;
0676 }
0677
0678
0679
0680
0681
0682
0683 inline G4complex G4NuclNuclDiffuseElastic::TestErfcComp(G4complex z, G4int nMax)
0684 {
0685 G4complex miz = G4complex( z.imag(), -z.real() );
0686 G4complex erfcz = 1. - GetErfComp( miz, nMax);
0687 G4complex w = std::exp(-z*z)*erfcz;
0688 return w;
0689 }
0690
0691
0692
0693
0694
0695 inline G4complex G4NuclNuclDiffuseElastic::TestErfcSer(G4complex z, G4int nMax)
0696 {
0697 G4complex miz = G4complex( z.imag(), -z.real() );
0698 G4complex erfcz = 1. - GetErfSer( miz, nMax);
0699 G4complex w = std::exp(-z*z)*erfcz;
0700 return w;
0701 }
0702
0703
0704
0705
0706
0707 inline G4complex G4NuclNuclDiffuseElastic::TestErfcInt(G4complex z)
0708 {
0709 G4complex miz = G4complex( z.imag(), -z.real() );
0710 G4complex erfcz = 1. - GetErfInt( miz);
0711 G4complex w = std::exp(-z*z)*erfcz;
0712 return w;
0713 }
0714
0715
0716
0717
0718
0719 inline G4complex G4NuclNuclDiffuseElastic::GetErfSer(G4complex z, G4int nMax)
0720 {
0721 G4int n;
0722 G4double a =1., b = 1., tmp;
0723 G4complex sum = z, d = z;
0724
0725 for( n = 1; n <= nMax; n++)
0726 {
0727 a *= 2.;
0728 b *= 2.*n +1.;
0729 d *= z*z;
0730
0731 tmp = a/b;
0732
0733 sum += tmp*d;
0734 }
0735 sum *= 2.*std::exp(-z*z)/std::sqrt(CLHEP::pi);
0736
0737 return sum;
0738 }
0739
0740
0741
0742 inline G4double G4NuclNuclDiffuseElastic::GetExpCos(G4double x)
0743 {
0744 G4double result;
0745
0746 result = G4Exp(x*x-fReZ*fReZ);
0747 result *= std::cos(2.*x*fReZ);
0748 return result;
0749 }
0750
0751
0752
0753 inline G4double G4NuclNuclDiffuseElastic::GetExpSin(G4double x)
0754 {
0755 G4double result;
0756
0757 result = G4Exp(x*x-fReZ*fReZ);
0758 result *= std::sin(2.*x*fReZ);
0759 return result;
0760 }
0761
0762
0763
0764
0765
0766
0767 inline G4double G4NuclNuclDiffuseElastic::GetCint(G4double x)
0768 {
0769 G4double out;
0770
0771 G4Integrator<G4NuclNuclDiffuseElastic,G4double(G4NuclNuclDiffuseElastic::*)(G4double)> integral;
0772
0773 out= integral.Legendre96(this,&G4NuclNuclDiffuseElastic::GetCosHaPit2, 0., x );
0774
0775 return out;
0776 }
0777
0778
0779
0780
0781
0782 inline G4double G4NuclNuclDiffuseElastic::GetSint(G4double x)
0783 {
0784 G4Integrator<G4NuclNuclDiffuseElastic,G4double(G4NuclNuclDiffuseElastic::*)(G4double)> integral;
0785
0786 G4double out =
0787 integral.Legendre96(this,&G4NuclNuclDiffuseElastic::GetSinHaPit2, 0., x );
0788
0789 return out;
0790 }
0791
0792
0793
0794
0795
0796
0797 inline G4complex G4NuclNuclDiffuseElastic::CoulombAmplitude(G4double theta)
0798 {
0799 G4complex ca;
0800
0801 G4double sinHalfTheta = std::sin(0.5*theta);
0802 G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
0803 sinHalfTheta2 += fAm;
0804
0805 G4double order = 2.*fCoulombPhase0 - fZommerfeld*G4Log(sinHalfTheta2);
0806 G4complex z = G4complex(0., order);
0807 ca = std::exp(z);
0808
0809 ca *= -fZommerfeld/(2.*fWaveVector*sinHalfTheta2);
0810
0811 return ca;
0812 }
0813
0814
0815
0816
0817
0818 inline G4double G4NuclNuclDiffuseElastic::CoulombAmplitudeMod2(G4double theta)
0819 {
0820 G4complex ca = CoulombAmplitude(theta);
0821 G4double out = ca.real()*ca.real() + ca.imag()*ca.imag();
0822
0823 return out;
0824 }
0825
0826
0827
0828
0829
0830
0831 inline void G4NuclNuclDiffuseElastic::CalculateCoulombPhaseZero()
0832 {
0833 G4complex z = G4complex(1,fZommerfeld);
0834
0835 G4complex gammalog = GammaLogB2n(z);
0836 fCoulombPhase0 = gammalog.imag();
0837 }
0838
0839
0840
0841
0842
0843
0844 inline G4double G4NuclNuclDiffuseElastic::CalculateCoulombPhase(G4int n)
0845 {
0846 G4complex z = G4complex(1. + n, fZommerfeld);
0847
0848 G4complex gammalog = GammaLogB2n(z);
0849 return gammalog.imag();
0850 }
0851
0852
0853
0854
0855
0856
0857
0858 inline void G4NuclNuclDiffuseElastic::CalculateRutherfordAnglePar()
0859 {
0860 fHalfRutThetaTg = fZommerfeld/fProfileLambda;
0861 fRutherfordTheta = 2.*std::atan(fHalfRutThetaTg);
0862 fHalfRutThetaTg2 = fHalfRutThetaTg*fHalfRutThetaTg;
0863
0864
0865 }
0866
0867
0868
0869
0870
0871 inline G4double G4NuclNuclDiffuseElastic::ProfileNear(G4double theta)
0872 {
0873 G4double dTheta = fRutherfordTheta - theta;
0874 G4double result = 0., argument = 0.;
0875
0876 if(std::abs(dTheta) < 0.001) result = fProfileAlpha*fProfileDelta;
0877 else
0878 {
0879 argument = fProfileDelta*dTheta;
0880 result = CLHEP::pi*argument*G4Exp(fProfileAlpha*argument);
0881 result /= std::sinh(CLHEP::pi*argument);
0882 result -= 1.;
0883 result /= dTheta;
0884 }
0885 return result;
0886 }
0887
0888
0889
0890
0891
0892 inline G4double G4NuclNuclDiffuseElastic::ProfileFar(G4double theta)
0893 {
0894 G4double dTheta = fRutherfordTheta + theta;
0895 G4double argument = fProfileDelta*dTheta;
0896
0897 G4double result = CLHEP::pi*argument*G4Exp(fProfileAlpha*argument);
0898 result /= std::sinh(CLHEP::pi*argument);
0899 result /= dTheta;
0900
0901 return result;
0902 }
0903
0904
0905
0906
0907
0908 inline G4double G4NuclNuclDiffuseElastic::Profile(G4double theta)
0909 {
0910 G4double dTheta = fRutherfordTheta - theta;
0911 G4double result = 0., argument = 0.;
0912
0913 if(std::abs(dTheta) < 0.001) result = 1.;
0914 else
0915 {
0916 argument = fProfileDelta*dTheta;
0917 result = CLHEP::pi*argument;
0918 result /= std::sinh(result);
0919 }
0920 return result;
0921 }
0922
0923
0924
0925
0926
0927 inline G4complex G4NuclNuclDiffuseElastic::PhaseNear(G4double theta)
0928 {
0929 G4double twosigma = 2.*fCoulombPhase0;
0930 twosigma -= fZommerfeld*G4Log(fHalfRutThetaTg2/(1.+fHalfRutThetaTg2));
0931 twosigma += fRutherfordTheta*fZommerfeld/fHalfRutThetaTg - CLHEP::halfpi;
0932 twosigma -= fProfileLambda*theta - 0.25*CLHEP::pi;
0933
0934 twosigma *= fCofPhase;
0935
0936 G4complex z = G4complex(0., twosigma);
0937
0938 return std::exp(z);
0939 }
0940
0941
0942
0943
0944
0945 inline G4complex G4NuclNuclDiffuseElastic::PhaseFar(G4double theta)
0946 {
0947 G4double twosigma = 2.*fCoulombPhase0;
0948 twosigma -= fZommerfeld*G4Log(fHalfRutThetaTg2/(1.+fHalfRutThetaTg2));
0949 twosigma += fRutherfordTheta*fZommerfeld/fHalfRutThetaTg - CLHEP::halfpi;
0950 twosigma += fProfileLambda*theta - 0.25*CLHEP::pi;
0951
0952 twosigma *= fCofPhase;
0953
0954 G4complex z = G4complex(0., twosigma);
0955
0956 return std::exp(z);
0957 }
0958
0959
0960
0961
0962
0963
0964 inline G4complex G4NuclNuclDiffuseElastic::AmplitudeFar(G4double theta)
0965 {
0966 G4double kappa = std::sqrt(0.5*fProfileLambda/std::sin(theta)/CLHEP::pi);
0967 G4complex out = G4complex(kappa/fWaveVector,0.);
0968 out *= ProfileFar(theta);
0969 out *= PhaseFar(theta);
0970 return out;
0971 }
0972
0973
0974
0975
0976
0977
0978 inline G4complex G4NuclNuclDiffuseElastic::Amplitude(G4double theta)
0979 {
0980
0981 G4complex out = AmplitudeNear(theta) + fCofFar*AmplitudeFar(theta);
0982
0983
0984 return out;
0985 }
0986
0987
0988
0989
0990
0991 inline G4double G4NuclNuclDiffuseElastic::AmplitudeMod2(G4double theta)
0992 {
0993 G4complex out = Amplitude(theta);
0994 G4double mod2 = out.real()*out.real() + out.imag()*out.imag();
0995 return mod2;
0996 }
0997
0998
0999
1000
1001
1002
1003 inline G4double G4NuclNuclDiffuseElastic::GetRatioSim(G4double theta)
1004 {
1005 G4double sinThetaR = 2.*fHalfRutThetaTg/(1. + fHalfRutThetaTg2);
1006 G4double dTheta = 0.5*(theta - fRutherfordTheta);
1007 G4double sindTheta = std::sin(dTheta);
1008
1009 G4double order = std::sqrt(fProfileLambda/sinThetaR/CLHEP::pi)*2.*sindTheta;
1010
1011 G4double cosFresnel = 0.5 - GetCint(order);
1012 G4double sinFresnel = 0.5 - GetSint(order);
1013
1014 G4double out = 0.5*( cosFresnel*cosFresnel + sinFresnel*sinFresnel );
1015
1016 return out;
1017 }
1018
1019
1020
1021
1022
1023 inline G4double G4NuclNuclDiffuseElastic::GetFresnelDiffuseXsc(G4double theta)
1024 {
1025 G4double ratio = GetRatioGen(theta);
1026 G4double ruthXsc = GetRutherfordXsc(theta);
1027 G4double xsc = ratio*ruthXsc;
1028 return xsc;
1029 }
1030
1031
1032
1033
1034
1035 inline G4double G4NuclNuclDiffuseElastic::GetFresnelIntegrandXsc(G4double alpha)
1036 {
1037 G4double theta = std::sqrt(alpha);
1038 G4double xsc = GetFresnelDiffuseXsc(theta);
1039 return xsc;
1040 }
1041
1042
1043
1044
1045
1046 inline G4double G4NuclNuclDiffuseElastic::AmplitudeSimMod2(G4double theta)
1047 {
1048 G4complex out = AmplitudeSim(theta);
1049 G4double mod2 = out.real()*out.real() + out.imag()*out.imag();
1050 return mod2;
1051 }
1052
1053
1054
1055
1056
1057
1058 inline G4double G4NuclNuclDiffuseElastic::AmplitudeGlaMod2(G4double theta)
1059 {
1060 G4complex out = AmplitudeGla(theta);
1061 G4double mod2 = out.real()*out.real() + out.imag()*out.imag();
1062 return mod2;
1063 }
1064
1065
1066
1067
1068
1069 inline G4double G4NuclNuclDiffuseElastic::AmplitudeGGMod2(G4double theta)
1070 {
1071 G4complex out = AmplitudeGG(theta);
1072 G4double mod2 = out.real()*out.real() + out.imag()*out.imag();
1073 return mod2;
1074 }
1075
1076
1077
1078
1079
1080 inline G4double G4NuclNuclDiffuseElastic::CalcMandelstamS( const G4double mp ,
1081 const G4double mt ,
1082 const G4double Plab )
1083 {
1084 G4double Elab = std::sqrt ( mp * mp + Plab * Plab );
1085 G4double sMand = mp*mp + mt*mt + 2*Elab*mt ;
1086
1087 return sMand;
1088 }
1089
1090
1091
1092 #endif