// // ******************************************************************** // * 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. * // ******************************************************************** // // $Id: G4NuclNuclDiffuseElastic.cc,v 1.2 2009/04/10 13:22:25 grichine Exp $ // GEANT4 tag $Name: geant4-09-04-beta-01 $ // // // 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 "Randomize.hh" #include "G4Integrator.hh" #include "globals.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 "G4PhysicsTable.hh" #include "G4PhysicsLogVector.hh" #include "G4PhysicsFreeVector.hh" ///////////////////////////////////////////////////////////////////////// // // Test Constructor. Just to check xsc G4NuclNuclDiffuseElastic::G4NuclNuclDiffuseElastic() : G4HadronicInteraction(), fParticle(0) { SetMinEnergy( 0.01*GeV ); SetMaxEnergy( 1.*TeV ); 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 = 200; 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; fProfileDelta = 1.; fProfileAlpha = 0.5; } ////////////////////////////////////////////////////////////////////////// // // Constructor with initialisation G4NuclNuclDiffuseElastic::G4NuclNuclDiffuseElastic(const G4ParticleDefinition* aParticle) : G4HadronicInteraction(), fParticle(aParticle) { SetMinEnergy( 0.01*GeV ); SetMaxEnergy( 1.*TeV ); 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 = 200; // 200; // 100; fAngleBin = 400; // 200; // 100; // fEnergyVector = 0; fEnergyVector = new G4PhysicsLogVector( theMinEnergy, theMaxEnergy, fEnergyBin ); fAngleTable = 0; fParticle = aParticle; fWaveVector = 0.; fAtomicWeight = 0.; fAtomicNumber = 0.; fNuclearRadius = 0.; fBeta = 0.; fZommerfeld = 0.; fAm = 0.; fAddCoulomb = false; // Initialise(); } ////////////////////////////////////////////////////////////////////////////// // // Destructor G4NuclNuclDiffuseElastic::~G4NuclNuclDiffuseElastic() { if(fEnergyVector) delete fEnergyVector; if( fAngleTable ) { fAngleTable->clearAndDestroy(); delete fAngleTable ; } } ////////////////////////////////////////////////////////////////////////////// // // Initialisation for given particle using element table of application void G4NuclNuclDiffuseElastic::Initialise() { // fEnergyVector = new G4PhysicsLogVector( theMinEnergy, theMaxEnergy, fEnergyBin ); const G4ElementTable* theElementTable = G4Element::GetElementTable(); size_t jEl, numOfEl = G4Element::GetNumberOfElements(); for(jEl = 0 ; jEl < numOfEl; ++jEl) // application element loop { fAtomicNumber = (*theElementTable)[jEl]->GetZ(); // atomic number fAtomicWeight = (*theElementTable)[jEl]->GetN(); // number of nucleons fNuclearRadius = CalculateNuclearRad(fAtomicWeight); if(verboseLevel > 0) { G4cout<<"G4NuclNuclDiffuseElastic::Initialise() the element: " <<(*theElementTable)[jEl]->GetName()<GetName()); BuildAngleTable(); fAngleBank.push_back(fAngleTable); } return; } //////////////////////////////////////////////////////////////////////////////// // // Model analog of DoIt function G4HadFinalState* G4NuclNuclDiffuseElastic::ApplyYourself( const G4HadProjectile& aTrack, G4Nucleus& targetNucleus ) { theParticleChange.Clear(); const G4HadProjectile* aParticle = &aTrack; G4double ekin = aParticle->GetKineticEnergy(); if(ekin <= lowestEnergyLimit) { theParticleChange.SetEnergyChange(ekin); theParticleChange.SetMomentumChange(aTrack.Get4Momentum().vect().unit()); return &theParticleChange; } G4double aTarget = targetNucleus.GetN(); G4double zTarget = targetNucleus.GetZ(); G4double plab = aParticle->GetTotalMomentum(); if (verboseLevel >1) { G4cout << "G4NuclNuclDiffuseElastic::DoIt: Incident particle plab=" << plab/GeV << " GeV/c " << " ekin(MeV) = " << ekin/MeV << " " << aParticle->GetDefinition()->GetParticleName() << G4endl; } // Scattered particle referred to axis of incident particle const G4ParticleDefinition* theParticle = aParticle->GetDefinition(); G4double m1 = theParticle->GetPDGMass(); G4int Z = static_cast(zTarget+0.5); G4int A = static_cast(aTarget+0.5); G4int N = A - Z; G4int projPDG = theParticle->GetPDGEncoding(); if (verboseLevel>1) { G4cout << "G4NuclNuclDiffuseElastic for " << theParticle->GetParticleName() << " PDGcode= " << projPDG << " on nucleus Z= " << Z << " A= " << A << " N= " << N << G4endl; } G4ParticleDefinition * theDef = 0; if(Z == 1 && A == 1) theDef = theProton; else if (Z == 1 && A == 2) theDef = theDeuteron; else if (Z == 1 && A == 3) theDef = G4Triton::Triton(); else if (Z == 2 && A == 3) theDef = G4He3::He3(); else if (Z == 2 && A == 4) theDef = theAlpha; else theDef = G4ParticleTable::GetParticleTable()->FindIon(Z,A,0,Z); G4double m2 = theDef->GetPDGMass(); G4LorentzVector lv1 = aParticle->Get4Momentum(); G4LorentzVector lv(0.0,0.0,0.0,m2); lv += lv1; G4ThreeVector bst = lv.boostVector(); lv1.boost(-bst); G4ThreeVector p1 = lv1.vect(); G4double ptot = p1.mag(); G4double tmax = 4.0*ptot*ptot; G4double t = 0.0; // // Sample t // // t = SampleT( theParticle, ptot, A); t = SampleTableT( theParticle, ptot, Z, A); // use initialised table // NaN finder if(!(t < 0.0 || t >= 0.0)) { if (verboseLevel > 0) { G4cout << "G4NuclNuclDiffuseElastic:WARNING: Z= " << Z << " N= " << N << " pdg= " << projPDG << " mom(GeV)= " << plab/GeV << " S-wave will be sampled" << G4endl; } t = G4UniformRand()*tmax; } if(verboseLevel>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); G4double eFinal = nlv1.e() - m1; if (verboseLevel > 1) { G4cout << "Scattered: " << nlv1<<" m= " << m1 << " ekin(MeV)= " << eFinal << " Proj: 4-mom " << lv1 <GetDefinition()->GetParticleName() << " p(GeV/c)= " << plab << " on " << theDef->GetParticleName() << G4endl; eFinal = 0.0; nlv1.setE(m1); } theParticleChange.SetMomentumChange(nlv1.vect().unit()); theParticleChange.SetEnergyChange(eFinal); G4LorentzVector nlv0 = lv - nlv1; G4double erec = nlv0.e() - m2; if (verboseLevel > 1) { G4cout << "Recoil: " << nlv0<<" m= " << m2 << " ekin(MeV)= " << erec < lowEnergyRecoilLimit) { G4DynamicParticle * aSec = new G4DynamicParticle(theDef, nlv0); theParticleChange.AddSecondary(aSec); } else { if(erec < 0.0) erec = 0.0; theParticleChange.SetLocalEnergyDeposit(erec); } return &theParticleChange; } //////////////////////////////////////////////////////////////////////////// // // 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()->FindIon(iZ,iA,0,iZ); 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()->FindIon(iZ,iA,0,iZ); 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()->FindIon(iZ,iA,0,iZ); 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*std::pow(A, 1./3.); 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; 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 kg = fWaveVector*gamma; // wavek*delta; G4double kg = lambda*(1.-std::exp(-fWaveVector*gamma/lambda)); // wavek*delta; G4double kg2 = kg*kg; // 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.-std::exp(-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 = kg2; // 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*std::pow(A, 1./3.); 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 kg = fWaveVector*gamma; // wavek*delta; G4double kg = lambda*(1.-std::exp(-fWaveVector*gamma/lambda)); // wavek*delta; // G4cout<<"kg = "<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<