82 lowEnergyRecoilLimit = 100.*keV;
83 lowEnergyLimitQ = 0.0*GeV;
84 lowEnergyLimitHE = 0.0*GeV;
85 lowestEnergyLimit = 0.0*keV;
86 plabLowLimit = 20.0*MeV;
121 delete fEnergyVector;
124 for ( std::vector<G4PhysicsTable*>::iterator it = fAngleBank.begin();
125 it != fAngleBank.end(); ++it )
127 if ( (*it) ) (*it)->clearAndDestroy();
148 for( jEl = 0; jEl < numOfEl; ++jEl)
150 fAtomicNumber = (*theElementTable)[jEl]->GetZ();
156 G4cout<<
"G4DiffuseElastic::Initialise() the element: "
157 <<(*theElementTable)[jEl]->GetName()<<
G4endl;
159 fElementNumberVector.push_back(fAtomicNumber);
160 fElementNameVector.push_back((*theElementTable)[jEl]->GetName());
163 fAngleBank.push_back(fAngleTable);
178 fParticle = particle;
179 fWaveVector = momentum/hbarc;
206 if (iZ == 1 && iA == 1) theDef = theProton;
207 else if (iZ == 1 && iA == 2) theDef = theDeuteron;
209 else if (iZ == 2 && iA == 3) theDef =
G4He3::He3();
210 else if (iZ == 2 && iA == 4) theDef = theAlpha;
224 G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2;
226 if( cost >= 1.0 ) cost = 1.0;
227 else if( cost <= -1.0) cost = -1.0;
229 G4double thetaCMS = std::acos(cost);
249 fParticle = particle;
250 fWaveVector = momentum/hbarc;
258 G4double kRt = fWaveVector*fNuclearRadius*theta;
261 if( z && (kRt > kRtC) )
266 fAm =
CalculateAm( momentum, fZommerfeld, fAtomicNumber);
293 if (iZ == 1 && iA == 1) theDef = theProton;
294 else if (iZ == 1 && iA == 2) theDef = theDeuteron;
296 else if (iZ == 2 && iA == 3) theDef =
G4He3::He3();
297 else if (iZ == 2 && iA == 4) theDef = theAlpha;
311 G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2;
313 if( cost >= 1.0 ) cost = 1.0;
314 else if( cost <= -1.0) cost = -1.0;
316 G4double thetaCMS = std::acos(cost);
343 if (iZ == 1 && iA == 1) theDef = theProton;
344 else if (iZ == 1 && iA == 2) theDef = theDeuteron;
346 else if (iZ == 2 && iA == 3) theDef =
G4He3::He3();
347 else if (iZ == 2 && iA == 4) theDef = theAlpha;
361 G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2;
363 if( cost >= 1.0 ) cost = 1.0;
364 else if( cost <= -1.0) cost = -1.0;
366 G4double thetaCMS = std::acos(cost);
386 G4double sigma, bzero, bzero2, bonebyarg, bonebyarg2, damp, damp2;
394 if (fParticle == theProton)
396 diffuse = 0.63*fermi;
398 delta = 0.1*fermi*fermi;
402 else if (fParticle == theNeutron)
404 diffuse = 0.63*fermi;
406 diffuse *= k0/fWaveVector;
409 delta = 0.1*fermi*fermi;
415 diffuse = 0.63*fermi;
417 delta = 0.1*fermi*fermi;
421 G4double kr = fWaveVector*fNuclearRadius;
426 bzero2 = bzero*bzero;
430 bonebyarg2 = bonebyarg*bonebyarg;
436 G4double kgamma = lambda*(1.-
G4Exp(-fWaveVector*gamma/lambda));
443 G4double pikdt = lambda*(1.-
G4Exp(-pi*fWaveVector*diffuse*theta/lambda));
448 G4double mode2k2 = (e1*e1+e2*e2)*fWaveVector*fWaveVector;
449 G4double e2dk3t = -2.*e2*delta*fWaveVector*fWaveVector*fWaveVector*theta;
455 sigma += mode2k2*bone2 + e2dk3t*bzero*bone;
456 sigma += kr2*bonebyarg2;
474 G4double sigma, bzero, bzero2, bonebyarg, bonebyarg2, damp, damp2;
482 G4double kr = fWaveVector*fNuclearRadius;
487 bzero2 = bzero*bzero;
491 bonebyarg2 = bonebyarg*bonebyarg;
493 if (fParticle == theProton)
495 diffuse = 0.63*fermi;
498 delta = 0.1*fermi*fermi;
502 else if (fParticle == theNeutron)
504 diffuse = 0.63*fermi;
507 diffuse *= k0/fWaveVector;
509 delta = 0.1*fermi*fermi;
515 diffuse = 0.63*fermi;
517 delta = 0.1*fermi*fermi;
523 G4double kgamma = lambda*(1.-
G4Exp(-fWaveVector*gamma/lambda));
529 G4double sinHalfTheta = std::sin(0.5*theta);
530 G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
532 kgamma += 0.5*fZommerfeld/kr/(sinHalfTheta2+fAm);
543 G4double pikdt = lambda*(1.-
G4Exp(-pi*fWaveVector*diffuse*theta/lambda));
550 G4double mode2k2 = (e1*e1+e2*e2)*fWaveVector*fWaveVector;
551 G4double e2dk3t = -2.*e2*delta*fWaveVector*fWaveVector*fWaveVector*theta;
556 sigma += mode2k2*bone2;
557 sigma += e2dk3t*bzero*bone;
560 sigma += kr2*bonebyarg2;
578 theta = std::sqrt(alpha);
582 G4double sigma, bzero, bzero2, bonebyarg, bonebyarg2, damp, damp2;
590 G4double kr = fWaveVector*fNuclearRadius;
595 bzero2 = bzero*bzero;
599 bonebyarg2 = bonebyarg*bonebyarg;
601 if ( fParticle == theProton )
603 diffuse = 0.63*fermi;
606 delta = 0.1*fermi*fermi;
610 else if ( fParticle == theNeutron )
612 diffuse = 0.63*fermi;
617 delta = 0.1*fermi*fermi;
623 diffuse = 0.63*fermi;
625 delta = 0.1*fermi*fermi;
631 G4double kgamma = lambda*(1.-
G4Exp(-fWaveVector*gamma/lambda));
638 G4double sinHalfTheta2 = sinHalfTheta*sinHalfTheta;
640 kgamma += 0.5*fZommerfeld/kr/(sinHalfTheta2+fAm);
650 G4double pikdt = lambda*(1. -
G4Exp( -pi*fWaveVector*diffuse*theta/lambda ) );
657 G4double mode2k2 = ( e1*e1 + e2*e2 )*fWaveVector*fWaveVector;
658 G4double e2dk3t = -2.*e2*delta*fWaveVector*fWaveVector*fWaveVector*theta;
663 sigma += mode2k2*bone2;
664 sigma += e2dk3t*bzero*bone;
667 sigma += kr2*bonebyarg2;
702 fParticle = particle;
703 fWaveVector = momentum/hbarc;
724 G4double t = 2*p*p*( 1 - std::cos(theta) );
738 G4double norm, result, theta1, theta2, thetaMax, sum = 0.;
740 fParticle = particle;
741 fWaveVector = momentum/hbarc;
746 thetaMax = 10.174/fWaveVector/fNuclearRadius;
748 if (thetaMax > pi) thetaMax = pi;
757 for(i = 1; i <= iMax; i++)
759 theta1 = (i-1)*thetaMax/iMax;
760 theta2 = i*thetaMax/iMax;
765 result = 0.5*(theta1 + theta2);
769 if (i > iMax ) result = 0.5*(theta1 + theta2);
773 result += G4RandGauss::shoot(0.,sigma);
775 if(result < 0.) result = 0.;
776 if(result > thetaMax) result = thetaMax;
790 fParticle = aParticle;
792 G4double totElab = std::sqrt(m1*m1+p*p);
804 if( aParticle == theNeutron)
807 G4double pCMS2 = momentumCMS*momentumCMS;
808 G4double Tkin = std::sqrt(pCMS2+m1*m1)-m1;
843 G4double t = 2*p*p*( 1 - std::cos(std::sqrt(alpha)) );
858 G4int iMomentum, iAngle;
862 for(iElement = 0; iElement < fElementNumberVector.size(); iElement++)
864 if( std::fabs(Z - fElementNumberVector[iElement]) < 0.5)
break;
866 if ( iElement == fElementNumberVector.size() )
878 fAngleTable = fAngleBank[iElement];
880 G4double kinE = std::sqrt(momentum*momentum + m1*m1) - m1;
882 for( iMomentum = 0; iMomentum < fEnergyBin; iMomentum++)
884 if( kinE < fEnergyVector->GetLowEdgeEnergy(iMomentum) )
break;
886 if ( iMomentum >= fEnergyBin ) iMomentum = fEnergyBin-1;
887 if ( iMomentum < 0 ) iMomentum = 0;
891 if (iMomentum == fEnergyBin -1 || iMomentum == 0 )
897 for(iAngle = 0; iAngle < fAngleBin-1; iAngle++)
899 if(
position > (*(*fAngleTable)(iMomentum))(iAngle) )
break;
901 if (iAngle >= fAngleBin-1) iAngle = fAngleBin-2;
916 for(iAngle = 0; iAngle < fAngleBin-1; iAngle++)
919 if(
position > (*(*fAngleTable)(iMomentum))(iAngle) )
break;
921 if (iAngle >= fAngleBin-1) iAngle = fAngleBin-2;
938 for(iAngle = 0; iAngle < fAngleBin-1; iAngle++)
941 if(
position > (*(*fAngleTable)(iMomentum))(iAngle) )
break;
943 if (iAngle >= fAngleBin-1) iAngle = fAngleBin-2;
957 randAngle = W1*theta1 + W2*theta2;
965 if(randAngle < 0.) randAngle = 0.;
983 G4cout<<
"G4DiffuseElastic::InitialiseOnFly() the element with Z = "
986 fElementNumberVector.push_back(fAtomicNumber);
990 fAngleBank.push_back(fAngleTable);
1004 G4double alpha1, alpha2, alphaMax, alphaCoulomb, delta = 0., sum = 0.;
1010 for( i = 0; i < fEnergyBin; i++)
1013 partMom = std::sqrt( kinE*(kinE + 2*m1) );
1015 fWaveVector = partMom/hbarc;
1017 G4double kR = fWaveVector*fNuclearRadius;
1024 alphaMax = kRmax*kRmax/kR2;
1034 if ( alphaMax >= CLHEP::pi*CLHEP::pi ) alphaMax = CLHEP::pi*CLHEP::pi;
1036 alphaCoulomb = kRcoul*kRcoul/kR2;
1041 fBeta = a/std::sqrt(1+a*a);
1043 fAm =
CalculateAm( partMom, fZommerfeld, fAtomicNumber);
1049 G4double delth = alphaMax/fAngleBin;
1057 for(j = fAngleBin-1; j >= 1; j--)
1065 alpha1 = delth*(j-1);
1067 alpha2 = alpha1 + delth;
1070 if( ( alpha1 < alphaCoulomb ) && z ) fAddCoulomb =
false;
1077 angleVector->
PutValue( j-1 , alpha1, sum );
1080 fAngleTable->insertAt(i, angleVector);
1095 G4double x1, x2, y1, y2, randAngle;
1099 randAngle = (*fAngleTable)(iMomentum)->GetLowEdgeEnergy(iAngle);
1104 if ( iAngle >=
G4int((*fAngleTable)(iMomentum)->GetVectorLength()) )
1106 iAngle = (*fAngleTable)(iMomentum)->GetVectorLength() - 1;
1108 y1 = (*(*fAngleTable)(iMomentum))(iAngle-1);
1109 y2 = (*(*fAngleTable)(iMomentum))(iAngle);
1111 x1 = (*fAngleTable)(iMomentum)->GetLowEdgeEnergy(iAngle-1);
1112 x2 = (*fAngleTable)(iMomentum)->GetLowEdgeEnergy(iAngle);
1114 if ( x1 == x2 ) randAngle = x2;
1117 if ( y1 == y2 ) randAngle = x1 + ( x2 - x1 )*
G4UniformRand();
1120 randAngle = x1 + (
position - y1 )*( x2 - x1 )/( y2 - y1 );
1159 t =
SampleT( theParticle, ptot,
A);
1162 if(!(t < 0.0 || t >= 0.0))
1166 G4cout <<
"G4DiffuseElastic:WARNING: A = " <<
A
1167 <<
" mom(GeV)= " << plab/GeV
1168 <<
" S-wave will be sampled"
1175 G4cout <<
" t= " << t <<
" tmax= " << tmax
1176 <<
" ptot= " << ptot <<
G4endl;
1189 else if( cost <= -1.0)
1196 sint = std::sqrt((1.0-cost)*(1.0+cost));
1200 G4cout <<
"cos(t)=" << cost <<
" std::sin(t)=" << sint <<
G4endl;
1202 G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost);
1243 G4double cost = std::cos(thetaCMS);
1251 else if( cost <= -1.0)
1258 sint = std::sqrt((1.0-cost)*(1.0+cost));
1262 G4cout <<
"cos(tcms)=" << cost <<
" std::sin(tcms)=" << sint <<
G4endl;
1264 G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost);
1303 G4double cost = std::cos(thetaLab);
1311 else if( cost <= -1.0)
1318 sint = std::sqrt((1.0-cost)*(1.0+cost));
1322 G4cout <<
"cos(tlab)=" << cost <<
" std::sin(tlab)=" << sint <<
G4endl;
1324 G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost);
1352 G4cout<<
"G4DiffuseElastic::TestAngleTable() init the element with Z = "
1355 fElementNumberVector.push_back(fAtomicNumber);
1362 G4double alpha1=0., alpha2=0., alphaMax=0., alphaCoulomb=0.;
1363 G4double deltaL10 = 0., deltaL96 = 0., deltaAG = 0.;
1364 G4double sumL10 = 0.,sumL96 = 0.,sumAG = 0.;
1371 fWaveVector = partMom/hbarc;
1373 G4double kR = fWaveVector*fNuclearRadius;
1378 alphaMax = kRmax*kRmax/kR2;
1380 if (alphaMax > 4.) alphaMax = 4.;
1382 alphaCoulomb = kRcoul*kRcoul/kR2;
1387 fBeta = a/std::sqrt(1+a*a);
1389 fAm =
CalculateAm( partMom, fZommerfeld, fAtomicNumber);
1396 fAddCoulomb =
false;
1398 for(j = 1; j < fAngleBin; j++)
1403 alpha1 = alphaMax*(j-1)/fAngleBin;
1404 alpha2 = alphaMax*( j )/fAngleBin;
1406 if( ( alpha2 > alphaCoulomb ) && z ) fAddCoulomb =
true;
1420 G4cout<<alpha1<<
"\t"<<std::sqrt(alpha1)/degree<<
"\t"
1421 <<sumL10<<
"\t"<<sumL96<<
"\t"<<sumAG<<
G4endl;
1423 angleVector->
PutValue( j-1 , alpha1, sumL10 );
1425 fAngleTable->insertAt(i,angleVector);
1426 fAngleBank.push_back(fAngleTable);
double epsilon(double density, double temperature)
double A(double temperature)
std::vector< G4Element * > G4ElementTable
G4double G4Exp(G4double initial_x)
Exponential Function double precision.
G4GLOB_DLL std::ostream G4cout
Hep3Vector boostVector() const
HepLorentzVector & boost(double, double, double)
static G4Deuteron * Deuteron()
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 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 BesselJzero(G4double z)
G4double SampleThetaCMS(const G4ParticleDefinition *aParticle, G4double p, G4double A)
G4double GetIntegrandFunction(G4double theta)
G4double DampFactor(G4double z)
G4double SampleTableThetaCMS(const G4ParticleDefinition *aParticle, G4double p, G4double Z, G4double A)
virtual G4double SampleInvariantT(const G4ParticleDefinition *p, G4double plab, G4int Z, G4int A)
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)
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)
G4double GetInvElasticSumXsc(const G4ParticleDefinition *particle, G4double tMand, G4double momentum, G4double A, G4double Z)
G4double NeutronTuniform(G4int Z)
G4ParticleDefinition * GetDefinition() const
G4LorentzVector Get4Momentum() const
G4double GetTotalMomentum() const
static G4ElementTable * GetElementTable()
static size_t GetNumberOfElements()
G4double GetTotalMomentum() const
const G4ParticleDefinition * GetDefinition() const
const G4LorentzVector & Get4Momentum() const
void SetMinEnergy(G4double anEnergy)
void SetMaxEnergy(const G4double anEnergy)
G4double GetMaxEnergy() const
static G4HadronicParameters * Instance()
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
static G4Neutron * Neutron()
static G4NistManager * Instance()
G4double GetAtomicMassAmu(const G4String &symb) const
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4double GetPDGMass() const
G4double GetPDGCharge() const
G4IonTable * GetIonTable() const
static G4ParticleTable * GetParticleTable()
void PutValue(std::size_t index, G4double energy, G4double dValue)
G4double GetLowEdgeEnergy(std::size_t binNumber) const
static G4PionMinus * PionMinus()
static G4PionPlus * PionPlus()
static G4Proton * Proton()
static G4Triton * Triton()