// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // // // Physics model class G4NuclNuclDiffuseElastic // // // G4 Model: optical diffuse elastic scattering with 4-momentum balance // // 24-May-07 V. Grichine // #include "G4NuclNuclDiffuseElastic.hh" #include "G4ParticleTable.hh" #include "G4ParticleDefinition.hh" #include "G4IonTable.hh" #include "G4NucleiProperties.hh" #include "Randomize.hh" #include "G4Integrator.hh" #include "globals.hh" #include "G4PhysicalConstants.hh" #include "G4SystemOfUnits.hh" #include "G4Proton.hh" #include "G4Neutron.hh" #include "G4Deuteron.hh" #include "G4Alpha.hh" #include "G4PionPlus.hh" #include "G4PionMinus.hh" #include "G4Element.hh" #include "G4ElementTable.hh" #include "G4NistManager.hh" #include "G4PhysicsTable.hh" #include "G4PhysicsLogVector.hh" #include "G4PhysicsFreeVector.hh" #include "G4HadronicParameters.hh" ///////////////////////////////////////////////////////////////////////// // // Test Constructor. Just to check xsc G4NuclNuclDiffuseElastic::G4NuclNuclDiffuseElastic() : G4HadronElastic("NNDiffuseElastic"), fParticle(0) { SetMinEnergy( 50*MeV ); SetMaxEnergy( G4HadronicParameters::Instance()->GetMaxEnergy() ); verboseLevel = 0; lowEnergyRecoilLimit = 100.*keV; lowEnergyLimitQ = 0.0*GeV; lowEnergyLimitHE = 0.0*GeV; lowestEnergyLimit= 0.0*keV; plabLowLimit = 20.0*MeV; theProton = G4Proton::Proton(); theNeutron = G4Neutron::Neutron(); theDeuteron = G4Deuteron::Deuteron(); theAlpha = G4Alpha::Alpha(); thePionPlus = G4PionPlus::PionPlus(); thePionMinus= G4PionMinus::PionMinus(); fEnergyBin = 300; // Increased from the original 200 to have no wider log-energy-bins up to 10 PeV fAngleBin = 200; fEnergyVector = new G4PhysicsLogVector( theMinEnergy, theMaxEnergy, fEnergyBin ); fAngleTable = 0; fParticle = 0; fWaveVector = 0.; fAtomicWeight = 0.; fAtomicNumber = 0.; fNuclearRadius = 0.; fBeta = 0.; fZommerfeld = 0.; fAm = 0.; fAddCoulomb = false; // Ranges of angle table relative to current Rutherford (Coulomb grazing) angle // Empirical parameters fCofAlphaMax = 1.5; fCofAlphaCoulomb = 0.5; fProfileDelta = 1.; fProfileAlpha = 0.5; fCofLambda = 1.0; fCofDelta = 0.04; fCofAlpha = 0.095; fNuclearRadius1 = fNuclearRadius2 = fNuclearRadiusSquare = fRutherfordRatio = fCoulombPhase0 = fHalfRutThetaTg = fHalfRutThetaTg2 = fRutherfordTheta = fProfileLambda = fCofPhase = fCofFar = fSumSigma = fEtaRatio = fReZ = 0.0; fMaxL = 0; fNuclearRadiusCof = 1.0; fCoulombMuC = 0.0; } ////////////////////////////////////////////////////////////////////////////// // // Destructor G4NuclNuclDiffuseElastic::~G4NuclNuclDiffuseElastic() { if ( fEnergyVector ) { delete fEnergyVector; fEnergyVector = 0; } for ( std::vector::iterator it = fAngleBank.begin(); it != fAngleBank.end(); ++it ) { if ( (*it) ) (*it)->clearAndDestroy(); delete *it; *it = 0; } fAngleTable = 0; } ////////////////////////////////////////////////////////////////////////////// // // Initialisation for given particle using element table of application void G4NuclNuclDiffuseElastic::Initialise() { // fEnergyVector = new G4PhysicsLogVector( theMinEnergy, theMaxEnergy, fEnergyBin ); const G4ElementTable* theElementTable = G4Element::GetElementTable(); std::size_t jEl, numOfEl = G4Element::GetNumberOfElements(); // projectile radius G4double A1 = G4double( fParticle->GetBaryonNumber() ); G4double R1 = CalculateNuclearRad(A1); for(jEl = 0 ; jEl < numOfEl; ++jEl) // application element loop { fAtomicNumber = (*theElementTable)[jEl]->GetZ(); // atomic number fAtomicWeight = G4NistManager::Instance()->GetAtomicMassAmu( static_cast< G4int >( fAtomicNumber ) ); fNuclearRadius = CalculateNuclearRad(fAtomicWeight); fNuclearRadius += R1; if(verboseLevel > 0) { G4cout<<"G4NuclNuclDiffuseElastic::Initialise() the element: " <<(*theElementTable)[jEl]->GetName()<GetName()); BuildAngleTable(); fAngleBank.push_back(fAngleTable); } } //////////////////////////////////////////////////////////////////////////// // // return differential elastic cross section d(sigma)/d(omega) G4double G4NuclNuclDiffuseElastic::GetDiffuseElasticXsc( const G4ParticleDefinition* particle, G4double theta, G4double momentum, G4double A ) { fParticle = particle; fWaveVector = momentum/hbarc; fAtomicWeight = A; fAddCoulomb = false; fNuclearRadius = CalculateNuclearRad(A); G4double sigma = fNuclearRadius*fNuclearRadius*GetDiffElasticProb(theta); return sigma; } //////////////////////////////////////////////////////////////////////////// // // return invariant differential elastic cross section d(sigma)/d(tMand) G4double G4NuclNuclDiffuseElastic::GetInvElasticXsc( const G4ParticleDefinition* particle, G4double tMand, G4double plab, G4double A, G4double Z ) { G4double m1 = particle->GetPDGMass(); G4LorentzVector lv1(0.,0.,plab,std::sqrt(plab*plab+m1*m1)); G4int iZ = static_cast(Z+0.5); G4int iA = static_cast(A+0.5); G4ParticleDefinition * theDef = 0; if (iZ == 1 && iA == 1) theDef = theProton; else if (iZ == 1 && iA == 2) theDef = theDeuteron; else if (iZ == 1 && iA == 3) theDef = G4Triton::Triton(); else if (iZ == 2 && iA == 3) theDef = G4He3::He3(); else if (iZ == 2 && iA == 4) theDef = theAlpha; else theDef = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(iZ,iA,0); G4double tmass = theDef->GetPDGMass(); G4LorentzVector lv(0.0,0.0,0.0,tmass); lv += lv1; G4ThreeVector bst = lv.boostVector(); lv1.boost(-bst); G4ThreeVector p1 = lv1.vect(); G4double ptot = p1.mag(); G4double ptot2 = ptot*ptot; G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2; if( cost >= 1.0 ) cost = 1.0; else if( cost <= -1.0) cost = -1.0; G4double thetaCMS = std::acos(cost); G4double sigma = GetDiffuseElasticXsc( particle, thetaCMS, ptot, A); sigma *= pi/ptot2; return sigma; } //////////////////////////////////////////////////////////////////////////// // // return differential elastic cross section d(sigma)/d(omega) with Coulomb // correction G4double G4NuclNuclDiffuseElastic::GetDiffuseElasticSumXsc( const G4ParticleDefinition* particle, G4double theta, G4double momentum, G4double A, G4double Z ) { fParticle = particle; fWaveVector = momentum/hbarc; fAtomicWeight = A; fAtomicNumber = Z; fNuclearRadius = CalculateNuclearRad(A); fAddCoulomb = false; G4double z = particle->GetPDGCharge(); G4double kRt = fWaveVector*fNuclearRadius*theta; G4double kRtC = 1.9; if( z && (kRt > kRtC) ) { fAddCoulomb = true; fBeta = CalculateParticleBeta( particle, momentum); fZommerfeld = CalculateZommerfeld( fBeta, z, fAtomicNumber); fAm = CalculateAm( momentum, fZommerfeld, fAtomicNumber); } G4double sigma = fNuclearRadius*fNuclearRadius*GetDiffElasticSumProb(theta); return sigma; } //////////////////////////////////////////////////////////////////////////// // // return invariant differential elastic cross section d(sigma)/d(tMand) with Coulomb // correction G4double G4NuclNuclDiffuseElastic::GetInvElasticSumXsc( const G4ParticleDefinition* particle, G4double tMand, G4double plab, G4double A, G4double Z ) { G4double m1 = particle->GetPDGMass(); G4LorentzVector lv1(0.,0.,plab,std::sqrt(plab*plab+m1*m1)); G4int iZ = static_cast(Z+0.5); G4int iA = static_cast(A+0.5); G4ParticleDefinition* theDef = 0; if (iZ == 1 && iA == 1) theDef = theProton; else if (iZ == 1 && iA == 2) theDef = theDeuteron; else if (iZ == 1 && iA == 3) theDef = G4Triton::Triton(); else if (iZ == 2 && iA == 3) theDef = G4He3::He3(); else if (iZ == 2 && iA == 4) theDef = theAlpha; else theDef = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(iZ,iA,0); G4double tmass = theDef->GetPDGMass(); G4LorentzVector lv(0.0,0.0,0.0,tmass); lv += lv1; G4ThreeVector bst = lv.boostVector(); lv1.boost(-bst); G4ThreeVector p1 = lv1.vect(); G4double ptot = p1.mag(); G4double ptot2 = ptot*ptot; G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2; if( cost >= 1.0 ) cost = 1.0; else if( cost <= -1.0) cost = -1.0; G4double thetaCMS = std::acos(cost); G4double sigma = GetDiffuseElasticSumXsc( particle, thetaCMS, ptot, A, Z ); sigma *= pi/ptot2; return sigma; } //////////////////////////////////////////////////////////////////////////// // // return invariant differential elastic cross section d(sigma)/d(tMand) with Coulomb // correction G4double G4NuclNuclDiffuseElastic::GetInvCoulombElasticXsc( const G4ParticleDefinition* particle, G4double tMand, G4double plab, G4double A, G4double Z ) { G4double m1 = particle->GetPDGMass(); G4LorentzVector lv1(0.,0.,plab,std::sqrt(plab*plab+m1*m1)); G4int iZ = static_cast(Z+0.5); G4int iA = static_cast(A+0.5); G4ParticleDefinition * theDef = 0; if (iZ == 1 && iA == 1) theDef = theProton; else if (iZ == 1 && iA == 2) theDef = theDeuteron; else if (iZ == 1 && iA == 3) theDef = G4Triton::Triton(); else if (iZ == 2 && iA == 3) theDef = G4He3::He3(); else if (iZ == 2 && iA == 4) theDef = theAlpha; else theDef = G4ParticleTable::GetParticleTable()->GetIonTable()->GetIon(iZ,iA,0); G4double tmass = theDef->GetPDGMass(); G4LorentzVector lv(0.0,0.0,0.0,tmass); lv += lv1; G4ThreeVector bst = lv.boostVector(); lv1.boost(-bst); G4ThreeVector p1 = lv1.vect(); G4double ptot = p1.mag(); G4double ptot2 = ptot*ptot; G4double cost = 1 - 0.5*std::fabs(tMand)/ptot2; if( cost >= 1.0 ) cost = 1.0; else if( cost <= -1.0) cost = -1.0; G4double thetaCMS = std::acos(cost); G4double sigma = GetCoulombElasticXsc( particle, thetaCMS, ptot, Z ); sigma *= pi/ptot2; return sigma; } //////////////////////////////////////////////////////////////////////////// // // return differential elastic probability d(probability)/d(omega) G4double G4NuclNuclDiffuseElastic::GetDiffElasticProb( // G4ParticleDefinition* particle, G4double theta // G4double momentum, // G4double A ) { G4double sigma, bzero, bzero2, bonebyarg, bonebyarg2, damp, damp2; G4double delta, diffuse, gamma; G4double e1, e2, bone, bone2; // G4double wavek = momentum/hbarc; // wave vector // G4double r0 = 1.08*fermi; // G4double rad = r0*G4Pow::GetInstance()->A13(A); G4double kr = fWaveVector*fNuclearRadius; // wavek*rad; G4double kr2 = kr*kr; G4double krt = kr*theta; bzero = BesselJzero(krt); bzero2 = bzero*bzero; bone = BesselJone(krt); bone2 = bone*bone; bonebyarg = BesselOneByArg(krt); bonebyarg2 = bonebyarg*bonebyarg; // VI - Coverity complains /* if (fParticle == theProton) { diffuse = 0.63*fermi; gamma = 0.3*fermi; delta = 0.1*fermi*fermi; e1 = 0.3*fermi; e2 = 0.35*fermi; } else // as proton, if were not defined { */ diffuse = 0.63*fermi; gamma = 0.3*fermi; delta = 0.1*fermi*fermi; e1 = 0.3*fermi; e2 = 0.35*fermi; //} G4double lambda = 15.; // 15 ok // G4double kgamma = fWaveVector*gamma; // wavek*delta; G4double kgamma = lambda*(1.-G4Exp(-fWaveVector*gamma/lambda)); // wavek*delta; G4double kgamma2 = kgamma*kgamma; // G4double dk2t = delta*fWaveVector*fWaveVector*theta; // delta*wavek*wavek*theta; // G4double dk2t2 = dk2t*dk2t; // G4double pikdt = pi*fWaveVector*diffuse*theta;// pi*wavek*diffuse*theta; G4double pikdt = lambda*(1.-G4Exp(-pi*fWaveVector*diffuse*theta/lambda)); // wavek*delta; damp = DampFactor(pikdt); damp2 = damp*damp; G4double mode2k2 = (e1*e1+e2*e2)*fWaveVector*fWaveVector; G4double e2dk3t = -2.*e2*delta*fWaveVector*fWaveVector*fWaveVector*theta; sigma = kgamma2; // sigma += dk2t2; sigma *= bzero2; sigma += mode2k2*bone2 + e2dk3t*bzero*bone; sigma += kr2*bonebyarg2; sigma *= damp2; // *rad*rad; return sigma; } //////////////////////////////////////////////////////////////////////////// // // return differential elastic probability d(probability)/d(omega) with // Coulomb correction G4double G4NuclNuclDiffuseElastic::GetDiffElasticSumProb( // G4ParticleDefinition* particle, G4double theta // G4double momentum, // G4double A ) { G4double sigma, bzero, bzero2, bonebyarg, bonebyarg2, damp, damp2; G4double delta, diffuse, gamma; G4double e1, e2, bone, bone2; // G4double wavek = momentum/hbarc; // wave vector // G4double r0 = 1.08*fermi; // G4double rad = r0*G4Pow::GetInstance()->A13(A); G4double kr = fWaveVector*fNuclearRadius; // wavek*rad; G4double kr2 = kr*kr; G4double krt = kr*theta; bzero = BesselJzero(krt); bzero2 = bzero*bzero; bone = BesselJone(krt); bone2 = bone*bone; bonebyarg = BesselOneByArg(krt); bonebyarg2 = bonebyarg*bonebyarg; if (fParticle == theProton) { diffuse = 0.63*fermi; // diffuse = 0.6*fermi; gamma = 0.3*fermi; delta = 0.1*fermi*fermi; e1 = 0.3*fermi; e2 = 0.35*fermi; } else // as proton, if were not defined { diffuse = 0.63*fermi; gamma = 0.3*fermi; delta = 0.1*fermi*fermi; e1 = 0.3*fermi; e2 = 0.35*fermi; } G4double lambda = 15.; // 15 ok // G4double kgamma = fWaveVector*gamma; // wavek*delta; G4double kgamma = lambda*(1.-G4Exp(-fWaveVector*gamma/lambda)); // wavek*delta; // G4cout<<"kgamma = "< integral; fAngleTable = new G4PhysicsTable(fEnergyBin); for( i = 0; i < fEnergyBin; i++) { kinE = fEnergyVector->GetLowEdgeEnergy(i); // G4cout< pi) alphaMax = pi; // VI: Coverity complain //alphaMax = pi2; alphaCoulomb = fRutherfordTheta*fCofAlphaCoulomb; // G4cout<<"alphaCoulomb = "<1) { G4cout <<" t= " << t << " tmax= " << tmax << " ptot= " << ptot << G4endl; } // Sampling of angles in CM system G4double phi = G4UniformRand()*twopi; G4double cost = 1. - 2.0*t/tmax; G4double sint; if( cost >= 1.0 ) { cost = 1.0; sint = 0.0; } else if( cost <= -1.0) { cost = -1.0; sint = 0.0; } else { sint = std::sqrt((1.0-cost)*(1.0+cost)); } if (verboseLevel>1) { G4cout << "cos(t)=" << cost << " std::sin(t)=" << sint << G4endl; } G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost); v1 *= ptot; G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),std::sqrt(ptot*ptot + m1*m1)); nlv1.boost(bst); G4ThreeVector np1 = nlv1.vect(); // G4double theta = std::acos( np1.z()/np1.mag() ); // degree; G4double theta = np1.theta(); return theta; } //////////////////////////////////////////////////////////////////////////// // // Return scattering angle in lab system (target at rest) knowing theta in CMS G4double G4NuclNuclDiffuseElastic::ThetaCMStoThetaLab( const G4DynamicParticle* aParticle, G4double tmass, G4double thetaCMS) { const G4ParticleDefinition* theParticle = aParticle->GetDefinition(); G4double m1 = theParticle->GetPDGMass(); // G4double plab = aParticle->GetTotalMomentum(); G4LorentzVector lv1 = aParticle->Get4Momentum(); G4LorentzVector lv(0.0,0.0,0.0,tmass); lv += lv1; G4ThreeVector bst = lv.boostVector(); lv1.boost(-bst); G4ThreeVector p1 = lv1.vect(); G4double ptot = p1.mag(); G4double phi = G4UniformRand()*twopi; G4double cost = std::cos(thetaCMS); G4double sint; if( cost >= 1.0 ) { cost = 1.0; sint = 0.0; } else if( cost <= -1.0) { cost = -1.0; sint = 0.0; } else { sint = std::sqrt((1.0-cost)*(1.0+cost)); } if (verboseLevel>1) { G4cout << "cos(tcms)=" << cost << " std::sin(tcms)=" << sint << G4endl; } G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost); v1 *= ptot; G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),std::sqrt(ptot*ptot + m1*m1)); nlv1.boost(bst); G4ThreeVector np1 = nlv1.vect(); G4double thetaLab = np1.theta(); return thetaLab; } //////////////////////////////////////////////////////////////////////////// // // Return scattering angle in CMS system (target at rest) knowing theta in Lab G4double G4NuclNuclDiffuseElastic::ThetaLabToThetaCMS( const G4DynamicParticle* aParticle, G4double tmass, G4double thetaLab) { const G4ParticleDefinition* theParticle = aParticle->GetDefinition(); G4double m1 = theParticle->GetPDGMass(); G4double plab = aParticle->GetTotalMomentum(); G4LorentzVector lv1 = aParticle->Get4Momentum(); G4LorentzVector lv(0.0,0.0,0.0,tmass); lv += lv1; G4ThreeVector bst = lv.boostVector(); // lv1.boost(-bst); // G4ThreeVector p1 = lv1.vect(); // G4double ptot = p1.mag(); G4double phi = G4UniformRand()*twopi; G4double cost = std::cos(thetaLab); G4double sint; if( cost >= 1.0 ) { cost = 1.0; sint = 0.0; } else if( cost <= -1.0) { cost = -1.0; sint = 0.0; } else { sint = std::sqrt((1.0-cost)*(1.0+cost)); } if (verboseLevel>1) { G4cout << "cos(tlab)=" << cost << " std::sin(tlab)=" << sint << G4endl; } G4ThreeVector v1(sint*std::cos(phi),sint*std::sin(phi),cost); v1 *= plab; G4LorentzVector nlv1(v1.x(),v1.y(),v1.z(),std::sqrt(plab*plab + m1*m1)); nlv1.boost(-bst); G4ThreeVector np1 = nlv1.vect(); G4double thetaCMS = np1.theta(); return thetaCMS; } /////////////////////////////////////////////////////////////////////////////// // // Test for given particle and element table of momentum, angle probability. // For the moment in lab system. void G4NuclNuclDiffuseElastic::TestAngleTable(const G4ParticleDefinition* theParticle, G4double partMom, G4double Z, G4double A) { fAtomicNumber = Z; // atomic number fAtomicWeight = A; // number of nucleons fNuclearRadius = CalculateNuclearRad(fAtomicWeight); G4cout<<"G4NuclNuclDiffuseElastic::TestAngleTable() init the element with Z = " <PutValue( j-1 , alpha1, sumL10 ); // alpha2 } fAngleTable->insertAt(i,angleVector); fAngleBank.push_back(fAngleTable); /* // Integral over all angle range - Bad accuracy !!! sumL10 = integral.Legendre10(this, &G4NuclNuclDiffuseElastic::GetIntegrandFunction, 0., alpha2); sumL96 = integral.Legendre96(this, &G4NuclNuclDiffuseElastic::GetIntegrandFunction, 0., alpha2); sumAG = integral.AdaptiveGauss(this, &G4NuclNuclDiffuseElastic::GetIntegrandFunction, 0., alpha2,epsilon); G4cout< integral; outRe = integral.Legendre96(this,&G4NuclNuclDiffuseElastic::GetExpSin, 0., y ); outIm = integral.Legendre96(this,&G4NuclNuclDiffuseElastic::GetExpCos, 0., y ); outRe *= 2./std::sqrt(CLHEP::pi); outIm *= 2./std::sqrt(CLHEP::pi); outRe += GetErf(x); return G4complex(outRe, outIm); } ///////////////////////////////////////////////////////////////// // // G4complex G4NuclNuclDiffuseElastic::GammaLess(G4double theta) { G4double sinThetaR = 2.*fHalfRutThetaTg/(1. + fHalfRutThetaTg2); G4double cosHalfThetaR2 = 1./(1. + fHalfRutThetaTg2); G4double u = std::sqrt(0.5*fProfileLambda/sinThetaR); G4double kappa = u/std::sqrt(CLHEP::pi); G4double dTheta = theta - fRutherfordTheta; u *= dTheta; G4double u2 = u*u; G4double u2m2p3 = u2*2./3.; G4complex im = G4complex(0.,1.); G4complex order = G4complex(u,u); order /= std::sqrt(2.); G4complex gamma = CLHEP::pi*kappa*GetErfcInt(-order)*std::exp(im*(u*u+0.25*CLHEP::pi)); G4complex a0 = 0.5*(1. + 4.*(1.+im*u2)*cosHalfThetaR2/3.)/sinThetaR; G4complex a1 = 0.5*(1. + 2.*(1.+im*u2m2p3)*cosHalfThetaR2)/sinThetaR; G4complex out = gamma*(1. - a1*dTheta) - a0; return out; } ///////////////////////////////////////////////////////////////// // // G4complex G4NuclNuclDiffuseElastic::GammaMore(G4double theta) { G4double sinThetaR = 2.*fHalfRutThetaTg/(1. + fHalfRutThetaTg2); G4double cosHalfThetaR2 = 1./(1. + fHalfRutThetaTg2); G4double u = std::sqrt(0.5*fProfileLambda/sinThetaR); G4double kappa = u/std::sqrt(CLHEP::pi); G4double dTheta = theta - fRutherfordTheta; u *= dTheta; G4double u2 = u*u; G4double u2m2p3 = u2*2./3.; G4complex im = G4complex(0.,1.); G4complex order = G4complex(u,u); order /= std::sqrt(2.); G4complex gamma = CLHEP::pi*kappa*GetErfcInt(order)*std::exp(im*(u*u+0.25*CLHEP::pi)); G4complex a0 = 0.5*(1. + 4.*(1.+im*u2)*cosHalfThetaR2/3.)/sinThetaR; G4complex a1 = 0.5*(1. + 2.*(1.+im*u2m2p3)*cosHalfThetaR2)/sinThetaR; G4complex out = -gamma*(1. - a1*dTheta) - a0; return out; } ///////////////////////////////////////////////////////////////// // // G4complex G4NuclNuclDiffuseElastic::AmplitudeNear(G4double theta) { G4double kappa = std::sqrt(0.5*fProfileLambda/std::sin(theta)/CLHEP::pi); G4complex out = G4complex(kappa/fWaveVector,0.); out *= PhaseNear(theta); if( theta <= fRutherfordTheta ) { out *= GammaLess(theta) + ProfileNear(theta); // out *= GammaMore(theta) + ProfileNear(theta); out += CoulombAmplitude(theta); } else { out *= GammaMore(theta) + ProfileNear(theta); // out *= GammaLess(theta) + ProfileNear(theta); } return out; } ///////////////////////////////////////////////////////////////// // // G4complex G4NuclNuclDiffuseElastic::AmplitudeSim(G4double theta) { G4double sinThetaR = 2.*fHalfRutThetaTg/(1. + fHalfRutThetaTg2); G4double dTheta = 0.5*(theta - fRutherfordTheta); G4double sindTheta = std::sin(dTheta); G4double persqrt2 = std::sqrt(0.5); G4complex order = G4complex(persqrt2,persqrt2); order *= std::sqrt(0.5*fProfileLambda/sinThetaR)*2.*sindTheta; // order *= std::sqrt(0.5*fProfileLambda/sinThetaR)*2.*dTheta; G4complex out; if ( theta <= fRutherfordTheta ) { out = 1. - 0.5*GetErfcInt(-order)*ProfileNear(theta); } else { out = 0.5*GetErfcInt(order)*ProfileNear(theta); } out *= CoulombAmplitude(theta); return out; } ///////////////////////////////////////////////////////////////// // // G4complex G4NuclNuclDiffuseElastic::AmplitudeGla(G4double theta) { G4int n; G4double T12b, b, b2; // cosTheta = std::cos(theta); G4complex out = G4complex(0.,0.), shiftC, shiftN; G4complex im = G4complex(0.,1.); for( n = 0; n < fMaxL; n++) { shiftC = std::exp( im*2.*CalculateCoulombPhase(n) ); // b = ( fZommerfeld + std::sqrt( fZommerfeld*fZommerfeld + n*(n+1) ) )/fWaveVector; b = ( std::sqrt( G4double(n*(n+1)) ) )/fWaveVector; b2 = b*b; T12b = fSumSigma*G4Exp(-b2/fNuclearRadiusSquare)/CLHEP::pi/fNuclearRadiusSquare; shiftN = std::exp( -0.5*(1.-im*fEtaRatio)*T12b ) - 1.; out += (2.*n+1.)*shiftC*shiftN*GetLegendrePol(n, theta); } out /= 2.*im*fWaveVector; out += CoulombAmplitude(theta); return out; } ///////////////////////////////////////////////////////////////// // // G4complex G4NuclNuclDiffuseElastic::AmplitudeGG(G4double theta) { G4int n; G4double T12b, a, aTemp, b2, sinThetaH = std::sin(0.5*theta); G4double sinThetaH2 = sinThetaH*sinThetaH; G4complex out = G4complex(0.,0.); G4complex im = G4complex(0.,1.); a = -fSumSigma/CLHEP::twopi/fNuclearRadiusSquare; b2 = fWaveVector*fWaveVector*fNuclearRadiusSquare*sinThetaH2; aTemp = a; for( n = 1; n < fMaxL; n++) { T12b = aTemp*G4Exp(-b2/n)/n; aTemp *= a; out += T12b; G4cout<<"out = "<GetBaryonNumber() ); fNuclearRadius1 = CalculateNuclearRad(A1); // fNuclearRadius = std::sqrt(fNuclearRadius1*fNuclearRadius1+fNuclearRadius2*fNuclearRadius2); fNuclearRadius = fNuclearRadius1 + fNuclearRadius2; G4double a = 0.; G4double z = theParticle->GetPDGCharge(); G4double m1 = theParticle->GetPDGMass(); fWaveVector = partMom/CLHEP::hbarc; G4double lambda = fCofLambda*fWaveVector*fNuclearRadius; G4cout<<"kR = "<GetPDGMass(); G4double proj_mass = pParticle->GetPDGMass(); G4double proj_energy = proj_mass + pTkin; G4double proj_momentum = std::sqrt(pTkin*(pTkin+2*proj_mass)); G4double sMand = CalcMandelstamS ( proj_mass , targ_mass , proj_momentum ); sMand /= CLHEP::GeV*CLHEP::GeV; // in GeV for parametrisation proj_momentum /= CLHEP::GeV; proj_energy /= CLHEP::GeV; proj_mass /= CLHEP::GeV; G4double logS = G4Log(sMand); // General PDG fit constants // fEtaRatio=Re[f(0)]/Im[f(0)] if( proj_momentum >= 1.2 ) { fEtaRatio = 0.13*(logS - 5.8579332)*G4Pow::GetInstance()->powA(sMand,-0.18); } else if( proj_momentum >= 0.6 ) { fEtaRatio = -75.5*(G4Pow::GetInstance()->powA(proj_momentum,0.25)-0.95)/ (G4Pow::GetInstance()->powA(3*proj_momentum,2.2)+1); } else { fEtaRatio = 15.5*proj_momentum/(27*proj_momentum*proj_momentum*proj_momentum+2); } G4cout<<"fEtaRatio = "<= 10. ) // high energy: pp = nn = np // if( proj_momentum >= 2.) { //Delta = 1.; //if( proj_energy < 40. ) Delta = 0.916+0.0021*proj_energy; //AR-12Aug2016 if( proj_momentum >= 10.) { B0 = 7.5; A0 = 100. - B0*G4Log(3.0e7); xsection = A0 + B0*G4Log(proj_energy) - 11 + 103*G4Pow::GetInstance()->powA(2*0.93827*proj_energy + proj_mass*proj_mass+ 0.93827*0.93827,-0.165); // mb } } else // low energy pp = nn != np { if(pParticle == tParticle) // pp or nn // nn to be pp { if( proj_momentum < 0.73 ) { hnXsc = 23 + 50*( G4Pow::GetInstance()->powA( G4Log(0.73/proj_momentum), 3.5 ) ); } else if( proj_momentum < 1.05 ) { hnXsc = 23 + 40*(G4Log(proj_momentum/0.73))* (G4Log(proj_momentum/0.73)); } else // if( proj_momentum < 10. ) { hnXsc = 39.0 + 75*(proj_momentum - 1.2)/(G4Pow::GetInstance()->powA(proj_momentum,3.0) + 0.15); } xsection = hnXsc; } else // pn to be np { if( proj_momentum < 0.8 ) { hpXsc = 33+30*G4Pow::GetInstance()->powA(G4Log(proj_momentum/1.3),4.0); } else if( proj_momentum < 1.4 ) { hpXsc = 33+30*G4Pow::GetInstance()->powA(G4Log(proj_momentum/0.95),2.0); } else // if( proj_momentum < 10. ) { hpXsc = 33.3+ 20.8*(G4Pow::GetInstance()->powA(proj_momentum,2.0)-1.35)/ (G4Pow::GetInstance()->powA(proj_momentum,2.50)+0.95); } xsection = hpXsc; } } xsection *= CLHEP::millibarn; // parametrised in mb G4cout<<"xsection = "<