42 #ifndef G4NuclNuclDiffuseElastic_h
43 #define G4NuclNuclDiffuseElastic_h 1
77 void BuildAngleTable();
88 void SetHEModelLowLimit(
G4double value);
90 void SetQModelLowLimit(
G4double value);
92 void SetLowestEnergyLimit(
G4double value);
94 void SetRecoilKinEnergyLimit(
G4double value);
229 void CalculateCoulombPhaseZero();
231 void CalculateRutherfordAnglePar();
325 std::vector<G4PhysicsTable*> fAngleBank;
327 std::vector<G4double> fElementNumberVector;
328 std::vector<G4String> fElementNameVector;
377 lowEnergyRecoilLimit =
value;
382 plabLowLimit =
value;
387 lowEnergyLimitHE =
value;
392 lowEnergyLimitQ =
value;
397 lowestEnergyLimit =
value;
408 G4double modvalue, value2, fact1, fact2, arg, shift, bessel;
410 modvalue = fabs(value);
414 value2 = value*
value;
416 fact1 = 57568490574.0 + value2*(-13362590354.0
417 + value2*( 651619640.7
418 + value2*(-11214424.18
419 + value2*( 77392.33017
420 + value2*(-184.9052456 ) ) ) ) );
422 fact2 = 57568490411.0 + value2*( 1029532985.0
423 + value2*( 9494680.718
424 + value2*(59272.64853
425 + value2*(267.8532712
426 + value2*1.0 ) ) ) );
428 bessel = fact1/fact2;
436 shift = modvalue-0.785398164;
438 fact1 = 1.0 + value2*(-0.1098628627e-2
439 + value2*(0.2734510407e-4
440 + value2*(-0.2073370639e-5
441 + value2*0.2093887211e-6 ) ) );
443 fact2 = -0.1562499995e-1 + value2*(0.1430488765e-3
444 + value2*(-0.6911147651e-5
445 + value2*(0.7621095161e-6
446 - value2*0.934945152e-7 ) ) );
448 bessel = sqrt(0.636619772/modvalue)*(cos(shift)*fact1 - arg*sin(shift)*fact2 );
460 G4double modvalue, value2, fact1, fact2, arg, shift, bessel;
462 modvalue = fabs(value);
464 if ( modvalue < 8.0 )
466 value2 = value*
value;
468 fact1 = value*(72362614232.0 + value2*(-7895059235.0
469 + value2*( 242396853.1
470 + value2*(-2972611.439
471 + value2*( 15704.48260
472 + value2*(-30.16036606 ) ) ) ) ) );
474 fact2 = 144725228442.0 + value2*(2300535178.0
475 + value2*(18583304.74
476 + value2*(99447.43394
477 + value2*(376.9991397
478 + value2*1.0 ) ) ) );
479 bessel = fact1/fact2;
487 shift = modvalue - 2.356194491;
489 fact1 = 1.0 + value2*( 0.183105e-2
490 + value2*(-0.3516396496e-4
491 + value2*(0.2457520174e-5
492 + value2*(-0.240337019e-6 ) ) ) );
494 fact2 = 0.04687499995 + value2*(-0.2002690873e-3
495 + value2*( 0.8449199096e-5
496 + value2*(-0.88228987e-6
497 + value2*0.105787412e-6 ) ) );
499 bessel = sqrt( 0.636619772/modvalue)*(cos(shift)*fact1 - arg*sin(shift)*fact2);
501 if (value < 0.0) bessel = -bessel;
517 if( std::fabs(x) < 0.01 )
519 df = 1./(1. + x/f2 + x*x/
f3 + x*x*x/
f4);
537 if( std::fabs(x) < 0.01 )
541 result = 2. - x2 + x2*x2/6.;
545 result = BesselJone(x)/
x;
559 fBeta = a/std::sqrt(1+a*a);
570 fZommerfeld = CLHEP::fine_structure_const*Z1*Z2/beta;
583 G4double zn = 1.77*k*std::pow(Z,-1./3.)*CLHEP::Bohr_radius;
596 G4double r0 = 1.*CLHEP::fermi, radius;
599 r0 *= fNuclearRadiusCof;
616 radius = r0*std::pow(A, 1./3.);
630 G4double sinHalfTheta = std::sin(0.5*theta);
631 G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
632 G4double beta = CalculateParticleBeta( particle, momentum);
634 G4double n = CalculateZommerfeld( beta, z, Z );
635 G4double am = CalculateAm( momentum, n, Z);
639 G4double xsc = ch2/(sinHalfTheta2+am)/(sinHalfTheta2+am);
650 G4double sinHalfTheta = std::sin(0.5*theta);
651 G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
653 G4double ch2 = fRutherfordRatio*fRutherfordRatio;
655 G4double xsc = ch2/(sinHalfTheta2+fAm)/(sinHalfTheta2+fAm);
668 G4double beta = CalculateParticleBeta( particle, momentum);
671 G4double n = CalculateZommerfeld( beta, z, Z );
673 G4double am = CalculateAm( momentum, n, Z);
677 G4cout<<
"k*Bohr_radius = "<<k*CLHEP::Bohr_radius<<
G4endl;
680 G4double xsc = ch2*CLHEP::pi/(am +am*am);
698 G4double beta = CalculateParticleBeta( particle, momentum);
701 G4double n = CalculateZommerfeld( beta, z, Z );
703 G4double am = CalculateAm( momentum, n, Z);
711 G4double xsc = ch2*CLHEP::twopi*(c1-c2);
712 xsc /= (1 - c1 + am)*(1 - c2 + am);
724 static G4double cof[6] = { 76.18009172947146, -86.50532032941677,
725 24.01409824083091, -1.231739572450155,
726 0.1208650973866179e-2, -0.5395239384953e-5 } ;
730 tmp -= (z + 0.5) * std::log(tmp);
733 for ( j = 0; j <= 5; j++ )
738 return -tmp + std::log(2.5066282746310005*ser);
758 G4complex result = (z-0.5)*std::log(z)-z+0.5*std::log(CLHEP::twopi);
759 result += 1./z1 - 1./z3 +1./z5 -1./z7;
774 tmp = t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+
775 t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+
776 t*(-0.82215223+t*0.17087277)))))))));
778 if( x >= 0.) result = 1. -
tmp;
779 else result = 1. +
tmp;
790 G4complex erfcz = 1. - GetErfComp( z, nMax);
800 G4complex erfcz = 1. - GetErfSer( z, nMax);
819 if ( n < 0 ) legPol = 0.;
820 else if( n == 0 ) legPol = 1.;
821 else if( n == 1 ) legPol =
x;
822 else if( n == 2 ) legPol = (3.*x*x-1.)/2.;
823 else if( n == 3 ) legPol = (5.*x*x*x-3.*
x)/2.;
824 else if( n == 4 ) legPol = (35.*x*x*x*x-30.*x*x+3.)/8.;
825 else if( n == 5 ) legPol = (63.*x*x*x*x*x-70.*x*x*x+15.*
x)/8.;
826 else if( n == 6 ) legPol = (231.*x*x*x*x*x*x-315.*x*x*x*x+105.*x*x-5.)/16.;
831 legPol = std::sqrt( 2./(n*CLHEP::pi*std::sin(theta+epsilon)) )*std::sin( (n+0.5)*theta+0.25*CLHEP::pi );
845 G4complex erfcz = 1. - GetErfComp( miz, nMax);
857 G4complex erfcz = 1. - GetErfSer( miz, nMax);
881 G4double n2, cofn, shny, chny, fn, gn;
892 G4double cof1 = std::exp(-x*x)/CLHEP::pi;
900 for( n = 1; n <= nMax; n++)
904 cofn = std::exp(-0.5*n2)/(n2+twox2);
906 chny = std::cosh(n*y);
907 shny = std::sinh(n*y);
909 fn = twox - twoxcos2xy*chny + n*sin2xy*shny;
910 gn = twoxsin2xy*chny + n*cos2xy*shny;
921 if(std::abs(x) < 0.0001)
928 outRe += GetErf(x) + cof1*(1-cos2xy)/twox;
929 outIm += cof1*sin2xy/twox;
944 for( n = 1; n <= nMax; n++)
954 sum *= 2.*std::exp(-z*z)/std::sqrt(CLHEP::pi);
965 result = std::exp(x*x-fReZ*fReZ);
966 result *= std::cos(2.*x*fReZ);
976 result = std::exp(x*x-fReZ*fReZ);
977 result *= std::sin(2.*x*fReZ);
1000 outRe *= 2./sqrt(CLHEP::pi);
1001 outIm *= 2./sqrt(CLHEP::pi);
1047 G4double sinHalfTheta = std::sin(0.5*theta);
1048 G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
1049 sinHalfTheta2 += fAm;
1051 G4double order = 2.*fCoulombPhase0 - fZommerfeld*std::log(sinHalfTheta2);
1055 ca *= -fZommerfeld/(2.*fWaveVector*sinHalfTheta2);
1067 G4double out = ca.real()*ca.real() + ca.imag()*ca.imag();
1082 fCoulombPhase0 = gammalog.imag();
1095 return gammalog.imag();
1106 fHalfRutThetaTg = fZommerfeld/fProfileLambda;
1107 fRutherfordTheta = 2.*std::atan(fHalfRutThetaTg);
1108 fHalfRutThetaTg2 = fHalfRutThetaTg*fHalfRutThetaTg;
1119 G4double dTheta = fRutherfordTheta - theta;
1120 G4double result = 0., argument = 0.;
1122 if(std::abs(dTheta) < 0.001) result = fProfileAlpha*fProfileDelta;
1125 argument = fProfileDelta*dTheta;
1126 result = CLHEP::pi*argument*std::exp(fProfileAlpha*argument);
1127 result /= std::sinh(CLHEP::pi*argument);
1140 G4double dTheta = fRutherfordTheta + theta;
1141 G4double argument = fProfileDelta*dTheta;
1143 G4double result = CLHEP::pi*argument*std::exp(fProfileAlpha*argument);
1144 result /= std::sinh(CLHEP::pi*argument);
1156 G4double dTheta = fRutherfordTheta - theta;
1157 G4double result = 0., argument = 0.;
1159 if(std::abs(dTheta) < 0.001) result = 1.;
1162 argument = fProfileDelta*dTheta;
1163 result = CLHEP::pi*argument;
1164 result /= std::sinh(CLHEP::pi*argument);
1175 G4double twosigma = 2.*fCoulombPhase0;
1176 twosigma -= fZommerfeld*std::log(fHalfRutThetaTg2/(1.+fHalfRutThetaTg2));
1177 twosigma += fRutherfordTheta*fZommerfeld/fHalfRutThetaTg - CLHEP::halfpi;
1178 twosigma -= fProfileLambda*theta - 0.25*CLHEP::pi;
1180 twosigma *= fCofPhase;
1193 G4double twosigma = 2.*fCoulombPhase0;
1194 twosigma -= fZommerfeld*std::log(fHalfRutThetaTg2/(1.+fHalfRutThetaTg2));
1195 twosigma += fRutherfordTheta*fZommerfeld/fHalfRutThetaTg - CLHEP::halfpi;
1196 twosigma += fProfileLambda*theta - 0.25*CLHEP::pi;
1198 twosigma *= fCofPhase;
1212 G4double sinThetaR = 2.*fHalfRutThetaTg/(1. + fHalfRutThetaTg2);
1213 G4double cosHalfThetaR2 = 1./(1. + fHalfRutThetaTg2);
1215 G4double u = std::sqrt(0.5*fProfileLambda/sinThetaR);
1216 G4double kappa = u/std::sqrt(CLHEP::pi);
1217 G4double dTheta = theta - fRutherfordTheta;
1224 order /= std::sqrt(2.);
1226 G4complex gamma = CLHEP::pi*kappa*GetErfcInt(-order)*std::exp(im*(u*u+0.25*CLHEP::pi));
1227 G4complex a0 = 0.5*(1. + 4.*(1.+im*u2)*cosHalfThetaR2/3.)/sinThetaR;
1228 G4complex a1 = 0.5*(1. + 2.*(1.+im*u2m2p3)*cosHalfThetaR2)/sinThetaR;
1229 G4complex out = gamma*(1. - a1*dTheta) - a0;
1240 G4double sinThetaR = 2.*fHalfRutThetaTg/(1. + fHalfRutThetaTg2);
1241 G4double cosHalfThetaR2 = 1./(1. + fHalfRutThetaTg2);
1243 G4double u = std::sqrt(0.5*fProfileLambda/sinThetaR);
1244 G4double kappa = u/std::sqrt(CLHEP::pi);
1245 G4double dTheta = theta - fRutherfordTheta;
1252 order /= std::sqrt(2.);
1253 G4complex gamma = CLHEP::pi*kappa*GetErfcInt(order)*std::exp(im*(u*u+0.25*CLHEP::pi));
1254 G4complex a0 = 0.5*(1. + 4.*(1.+im*u2)*cosHalfThetaR2/3.)/sinThetaR;
1255 G4complex a1 = 0.5*(1. + 2.*(1.+im*u2m2p3)*cosHalfThetaR2)/sinThetaR;
1256 G4complex out = -gamma*(1. - a1*dTheta) - a0;
1267 G4double kappa = std::sqrt(0.5*fProfileLambda/std::sin(theta)/CLHEP::pi);
1270 out *= PhaseNear(theta);
1272 if( theta <= fRutherfordTheta )
1274 out *= GammaLess(theta) + ProfileNear(theta);
1276 out += CoulombAmplitude(theta);
1280 out *= GammaMore(theta) + ProfileNear(theta);
1292 G4double kappa = std::sqrt(0.5*fProfileLambda/std::sin(theta)/CLHEP::pi);
1294 out *= ProfileFar(theta);
1295 out *= PhaseFar(theta);
1307 G4complex out = AmplitudeNear(theta) + fCofFar*AmplitudeFar(theta);
1320 G4double mod2 = out.real()*out.real() + out.imag()*out.imag();
1330 G4double sinThetaR = 2.*fHalfRutThetaTg/(1. + fHalfRutThetaTg2);
1331 G4double dTheta = 0.5*(theta - fRutherfordTheta);
1332 G4double sindTheta = std::sin(dTheta);
1333 G4double persqrt2 = std::sqrt(0.5);
1336 order *= std::sqrt(0.5*fProfileLambda/sinThetaR)*2.*sindTheta;
1341 if ( theta <= fRutherfordTheta )
1343 out = 1. - 0.5*GetErfcInt(-order)*ProfileNear(theta);
1347 out = 0.5*GetErfcInt(order)*ProfileNear(theta);
1350 out *= CoulombAmplitude(theta);
1361 G4double sinThetaR = 2.*fHalfRutThetaTg/(1. + fHalfRutThetaTg2);
1362 G4double dTheta = 0.5*(theta - fRutherfordTheta);
1363 G4double sindTheta = std::sin(dTheta);
1365 G4double order = std::sqrt(fProfileLambda/sinThetaR/CLHEP::pi)*2.*sindTheta;
1367 G4double cosFresnel = 0.5 - GetCint(order);
1368 G4double sinFresnel = 0.5 - GetSint(order);
1370 G4double out = 0.5*( cosFresnel*cosFresnel + sinFresnel*sinFresnel );
1381 G4double sinThetaR = 2.*fHalfRutThetaTg/(1. + fHalfRutThetaTg2);
1382 G4double dTheta = 0.5*(theta - fRutherfordTheta);
1383 G4double sindTheta = std::sin(dTheta);
1388 G4double order = std::sqrt(fProfileLambda/sinThetaR/CLHEP::pi)*2.*sindTheta;
1390 order = std::abs(order);
1393 G4double cosFresnel = GetCint(order);
1394 G4double sinFresnel = GetSint(order);
1398 if ( theta <= fRutherfordTheta )
1400 out = 1. + 0.5*( (0.5-cosFresnel)*(0.5-cosFresnel)+(0.5-sinFresnel)*(0.5-sinFresnel) )*prof2;
1401 out += ( cosFresnel + sinFresnel - 1. )*prof;
1405 out = 0.5*( (0.5-cosFresnel)*(0.5-cosFresnel)+(0.5-sinFresnel)*(0.5-sinFresnel) )*prof2;
1417 G4double ratio = GetRatioGen(theta);
1418 G4double ruthXsc = GetRutherfordXsc(theta);
1430 G4double xsc = GetFresnelDiffuseXsc(theta);
1443 G4double mod2 = out.real()*out.real() + out.imag()*out.imag();
1458 for( n = 0; n < fMaxL; n++)
1460 shiftC = std::exp( im*2.*CalculateCoulombPhase(n) );
1462 b = ( std::sqrt(
G4double(n*(n+1)) ) )/fWaveVector;
1464 T12b = fSumSigma*std::exp(-b2/fNuclearRadiusSquare)/CLHEP::pi/fNuclearRadiusSquare;
1465 shiftN = std::exp( -0.5*(1.-im*fEtaRatio)*T12b ) - 1.;
1466 out += (2.*n+1.)*shiftC*shiftN*GetLegendrePol(n, theta);
1468 out /= 2.*im*fWaveVector;
1469 out += CoulombAmplitude(theta);
1480 G4double mod2 = out.real()*out.real() + out.imag()*out.imag();
1492 G4double T12b,
a, aTemp, b2, sinThetaH = std::sin(0.5*theta);
1493 G4double sinThetaH2 = sinThetaH*sinThetaH;
1497 a = -fSumSigma/CLHEP::twopi/fNuclearRadiusSquare;
1498 b2 = fWaveVector*fWaveVector*fNuclearRadiusSquare*sinThetaH2;
1502 for( n = 1; n < fMaxL; n++)
1504 T12b = aTemp*std::exp(-b2/n)/
n;
1509 out *= -4.*im*fWaveVector/CLHEP::pi;
1510 out += CoulombAmplitude(theta);
1521 G4double mod2 = out.real()*out.real() + out.imag()*out.imag();
1537 fNuclearRadius2 = CalculateNuclearRad(fAtomicWeight);
1539 fNuclearRadius1 = CalculateNuclearRad(A1);
1541 fNuclearRadius = fNuclearRadius1 + fNuclearRadius2;
1547 fWaveVector = partMom/CLHEP::hbarc;
1555 fBeta = a/std::sqrt(1+a*a);
1556 fZommerfeld = CalculateZommerfeld( fBeta, z, fAtomicNumber);
1557 fRutherfordRatio = fZommerfeld/fWaveVector;
1558 fAm = CalculateAm( partMom, fZommerfeld, fAtomicNumber);
1563 fProfileDelta = fCofDelta*fProfileLambda;
1564 fProfileAlpha = fCofAlpha*fProfileLambda;
1566 CalculateCoulombPhaseZero();
1567 CalculateRutherfordAnglePar();
1583 fWaveVector = partMom/CLHEP::hbarc;
1590 fBeta = a/std::sqrt(1+a*a);
1591 fZommerfeld = CalculateZommerfeld( fBeta, z, fAtomicNumber);
1592 fRutherfordRatio = fZommerfeld/fWaveVector;
1593 fAm = CalculateAm( partMom, fZommerfeld, fAtomicNumber);
1596 fProfileDelta = fCofDelta*fProfileLambda;
1597 fProfileAlpha = fCofAlpha*fProfileLambda;
1599 CalculateCoulombPhaseZero();
1600 CalculateRutherfordAnglePar();
1617 fNuclearRadius2 = CalculateNuclearRad(fAtomicWeight);
1619 fNuclearRadius1 = CalculateNuclearRad(A1);
1620 fNuclearRadiusSquare = fNuclearRadius1*fNuclearRadius1+fNuclearRadius2*fNuclearRadius2;
1627 fWaveVector = partMom/CLHEP::hbarc;
1630 if( pN < 0. ) pN = 0.;
1633 if( tN < 0. ) tN = 0.;
1639 fSumSigma = (Z*z+pN*tN)*GetHadronNucleonXscNS(theProton, pTkin, theProton) +
1640 (z*tN+pN*
Z)*GetHadronNucleonXscNS(theProton, pTkin, theNeutron);
1642 G4cout<<
"fSumSigma = "<<fSumSigma/CLHEP::millibarn<<
" mb"<<
G4endl;
1643 G4cout<<
"pi*R2 = "<<CLHEP::pi*fNuclearRadiusSquare/CLHEP::millibarn<<
" mb"<<
G4endl;
1644 kR12 = fWaveVector*std::sqrt(fNuclearRadiusSquare);
1646 fMaxL = (
G4int(kR12)+1)*4;
1652 fBeta = a/std::sqrt(1+a*a);
1653 fZommerfeld = CalculateZommerfeld( fBeta, z, fAtomicNumber);
1654 fAm = CalculateAm( partMom, fZommerfeld, fAtomicNumber);
1657 CalculateCoulombPhaseZero();
1683 G4double proj_energy = proj_mass + pTkin;
1684 G4double proj_momentum = std::sqrt(pTkin*(pTkin+2*proj_mass));
1686 G4double sMand = CalcMandelstamS ( proj_mass , targ_mass , proj_momentum );
1688 sMand /= CLHEP::GeV*CLHEP::GeV;
1689 proj_momentum /= CLHEP::GeV;
1690 proj_energy /= CLHEP::GeV;
1691 proj_mass /= CLHEP::GeV;
1699 if( proj_momentum >= 1.2 )
1701 fEtaRatio = 0.13*(logS - 5.8579332)*std::pow(sMand,-0.18);
1703 else if( proj_momentum >= 0.6 )
1705 fEtaRatio = -75.5*(std::pow(proj_momentum,0.25)-0.95)/
1706 (std::pow(3*proj_momentum,2.2)+1);
1710 fEtaRatio = 15.5*proj_momentum/(27*proj_momentum*proj_momentum*proj_momentum+2);
1716 if( proj_momentum >= 10. )
1723 if( proj_momentum >= 10.)
1726 A0 = 100. - B0*std::log(3.0e7);
1728 xsection = A0 + B0*std::log(proj_energy) - 11
1729 + 103*std::pow(2*0.93827*proj_energy + proj_mass*proj_mass+
1730 0.93827*0.93827,-0.165);
1735 if(pParticle == tParticle)
1737 if( proj_momentum < 0.73 )
1739 hnXsc = 23 + 50*( std::pow( std::log(0.73/proj_momentum), 3.5 ) );
1741 else if( proj_momentum < 1.05 )
1743 hnXsc = 23 + 40*(std::log(proj_momentum/0.73))*
1744 (std::log(proj_momentum/0.73));
1749 75*(proj_momentum - 1.2)/(std::pow(proj_momentum,3.0) + 0.15);
1755 if( proj_momentum < 0.8 )
1757 hpXsc = 33+30*std::pow(std::log(proj_momentum/1.3),4.0);
1759 else if( proj_momentum < 1.4 )
1761 hpXsc = 33+30*std::pow(std::log(proj_momentum/0.95),2.0);
1766 20.8*(std::pow(proj_momentum,2.0)-1.35)/
1767 (std::pow(proj_momentum,2.50)+0.95);
1772 xsection *= CLHEP::millibarn;
1773 G4cout<<
"xsection = "<<xsection/CLHEP::millibarn<<
" mb"<<
G4endl;
1785 G4double Elab = std::sqrt ( mp * mp + Plab * Plab );
1786 G4double sMand = mp*mp + mt*mt + 2*Elab*mt ;