Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Protected Attributes
G4ScreenedCoulombClassicalKinematics Class Reference

#include <G4ScreenedNuclearRecoil.hh>

Inheritance diagram for G4ScreenedCoulombClassicalKinematics:
G4ScreenedCoulombCrossSectionInfo G4ScreenedCollisionStage

Public Member Functions

 G4ScreenedCoulombClassicalKinematics ()
 
virtual void DoCollisionStep (class G4ScreenedNuclearRecoil *master, const class G4Track &aTrack, const class G4Step &aStep)
 
G4bool DoScreeningComputation (class G4ScreenedNuclearRecoil *master, const G4ScreeningTables *screen, G4double eps, G4double beta)
 
virtual ~G4ScreenedCoulombClassicalKinematics ()
 
- Public Member Functions inherited from G4ScreenedCollisionStage
virtual ~G4ScreenedCollisionStage ()
 

Protected Attributes

c2_const_plugin_function_p
< G4double > & 
phifunc
 
c2_linear_p< G4double > & xovereps
 
G4_c2_ptr diff
 

Additional Inherited Members

Detailed Description

Definition at line 159 of file G4ScreenedNuclearRecoil.hh.

Constructor & Destructor Documentation

G4ScreenedCoulombClassicalKinematics::G4ScreenedCoulombClassicalKinematics ( )

Definition at line 518 of file G4ScreenedNuclearRecoil.cc.

518  :
519 // instantiate all the needed functions statically, so no allocation is done at run time
520 // we will be solving x^2 - x phi(x*au)/eps - beta^2 == 0.0
521 // or, for easier scaling, x'^2 - x' au phi(x')/eps - beta^2 au^2
522 // note that only the last of these gets deleted, since it owns the rest
523 phifunc(c2.const_plugin_function()),
524 xovereps(c2.linear(0., 0., 0.)), // will fill this in with the right slope at run time
525 diff(c2.quadratic(0., 0., 0., 1.)-xovereps*phifunc)
526 {
527 }
c2_const_plugin_function_p< G4double > & phifunc
virtual G4ScreenedCoulombClassicalKinematics::~G4ScreenedCoulombClassicalKinematics ( )
inlinevirtual

Definition at line 169 of file G4ScreenedNuclearRecoil.hh.

169 { }

Member Function Documentation

void G4ScreenedCoulombClassicalKinematics::DoCollisionStep ( class G4ScreenedNuclearRecoil master,
const class G4Track aTrack,
const class G4Step aStep 
)
virtual

Implements G4ScreenedCollisionStage.

Definition at line 609 of file G4ScreenedNuclearRecoil.cc.

References G4CoulombKinematicsInfo::a1, G4CoulombKinematicsInfo::a2, python.hepunit::amu_c2, G4ScreeningTables::au, G4CoulombKinematicsInfo::cosZeta, G4CoulombKinematicsInfo::crossSection, G4ScreenedNuclearRecoil::DepositEnergy(), DoScreeningComputation(), python.hepunit::elm_coupling, python.hepunit::eplus, G4CoulombKinematicsInfo::eRecoil, G4Track::GetDefinition(), G4Track::GetDynamicParticle(), G4ScreenedNuclearRecoil::GetEnableRecoils(), G4ScreenedNuclearRecoil::GetKinematics(), G4DynamicParticle::GetKineticEnergy(), G4ScreenedNuclearRecoil::GetParticleChange(), G4ParticleDefinition::GetPDGCharge(), G4ParticleDefinition::GetPDGMass(), G4ScreenedNuclearRecoil::GetRecoilCutoff(), G4ScreenedCoulombCrossSection::GetScreening(), G4ScreenedNuclearRecoil::GetValidCollision(), G4CoulombKinematicsInfo::impactParameter, G4ParticleChange::ProposeEnergy(), G4CoulombKinematicsInfo::recoilIon, G4ScreenedNuclearRecoil::SetValidCollision(), G4CoulombKinematicsInfo::targetMaterial, and G4ScreeningTables::z1.

610  {
611 
612  if(!master->GetValidCollision()) return;
613 
614  G4ParticleChange &aParticleChange=master->GetParticleChange();
615  G4CoulombKinematicsInfo &kin=master->GetKinematics();
616 
617  const G4DynamicParticle* incidentParticle = aTrack.GetDynamicParticle();
618  G4ParticleDefinition *baseParticle=aTrack.GetDefinition();
619 
620  G4double incidentEnergy = incidentParticle->GetKineticEnergy();
621 
622  // this adjustment to a1 gives the right results for soft (constant gamma)
623  // relativistic collisions. Hard collisions are wrong anyway, since the
624  // Coulombic and hadronic terms interfere and cannot be added.
625  G4double gamma=(1.0+incidentEnergy/baseParticle->GetPDGMass());
626  G4double a1=kin.a1*gamma; // relativistic gamma correction
627 
628  G4ParticleDefinition *recoilIon=kin.recoilIon;
629  G4double A=recoilIon->GetPDGMass()/amu_c2;
630  G4int Z=(G4int)((recoilIon->GetPDGCharge()/eplus)+0.5);
631 
632  G4double Ec = incidentEnergy*(A/(A+a1)); // energy in CM frame (non-relativistic!)
633  const G4ScreeningTables *screen=kin.crossSection->GetScreening(Z);
634  G4double au=screen->au; // screening length
635 
636  G4double beta = kin.impactParameter/au; // dimensionless impact parameter
637  G4double eps = Ec/(screen->z1*Z*elm_coupling/au); // dimensionless energy
638 
639  G4bool ok=DoScreeningComputation(master, screen, eps, beta);
640  if(!ok) {
641  master->SetValidCollision(0); // flag bad collision
642  return; // just bail out without setting valid flag
643  }
644 
645  G4double eRecoil=4*incidentEnergy*a1*A*kin.cosZeta*kin.cosZeta/((a1+A)*(a1+A));
646  kin.eRecoil=eRecoil;
647 
648  if(incidentEnergy-eRecoil < master->GetRecoilCutoff()*a1) {
649  aParticleChange.ProposeEnergy(0.0);
650  master->DepositEnergy(int(screen->z1), a1, kin.targetMaterial, incidentEnergy-eRecoil);
651  }
652 
653  if(master->GetEnableRecoils() && eRecoil > master->GetRecoilCutoff() * kin.a2) {
654  kin.recoilIon=recoilIon;
655  } else {
656  kin.recoilIon=0; // this flags no recoil to be generated
657  master->DepositEnergy(Z, A, kin.targetMaterial, eRecoil) ;
658  }
659 }
G4double GetKineticEnergy() const
G4ParticleDefinition * recoilIon
tuple elm_coupling
Definition: hepunit.py:286
int G4int
Definition: G4Types.hh:78
G4ScreenedCoulombCrossSection * crossSection
bool G4bool
Definition: G4Types.hh:79
const G4ScreeningTables * GetScreening(G4int Z)
G4double GetPDGMass() const
void ProposeEnergy(G4double finalEnergy)
double G4double
Definition: G4Types.hh:76
float amu_c2
Definition: hepunit.py:277
G4double GetPDGCharge() const
G4bool DoScreeningComputation(class G4ScreenedNuclearRecoil *master, const G4ScreeningTables *screen, G4double eps, G4double beta)
G4bool G4ScreenedCoulombClassicalKinematics::DoScreeningComputation ( class G4ScreenedNuclearRecoil master,
const G4ScreeningTables screen,
G4double  eps,
G4double  beta 
)

Definition at line 529 of file G4ScreenedNuclearRecoil.cc.

References G4CoulombKinematicsInfo::a1, G4CoulombKinematicsInfo::a2, G4ScreeningTables::au, G4ScreenedNuclearRecoil::CheckNuclearCollision(), G4CoulombKinematicsInfo::cosTheta, G4CoulombKinematicsInfo::cosZeta, diff, G4ScreeningTables::EMphiData, c2_function< float_type >::find_root(), G4cout, G4endl, c2_const_ptr< float_type >::get(), G4ScreenedNuclearRecoil::GetKinematics(), G4INCL::Math::min(), phifunc, c2_linear_p< float_type >::reset(), c2_const_plugin_function_p< float_type >::set_function(), G4CoulombKinematicsInfo::sinTheta, G4CoulombKinematicsInfo::sinZeta, c2_plugin_function_p< float_type >::unset_function(), test::x, c2_function< float_type >::xmax(), c2_function< float_type >::xmin(), and xovereps.

Referenced by DoCollisionStep().

531 {
532  G4double au=screen->au;
533  G4CoulombKinematicsInfo &kin=master->GetKinematics();
534  G4double A=kin.a2;
535  G4double a1=kin.a1;
536 
537  G4double xx0; // first estimate of closest approach
538  if(eps < 5.0) {
539  G4double y=std::log(eps);
540  G4double mlrho4=((((3.517e-4*y+1.401e-2)*y+2.393e-1)*y+2.734)*y+2.220);
541  G4double rho4=std::exp(-mlrho4); // W&M eq. 18
542  G4double bb2=0.5*beta*beta;
543  xx0=std::sqrt(bb2+std::sqrt(bb2*bb2+rho4)); // W&M eq. 17
544  } else {
545  G4double ee=1.0/(2.0*eps);
546  xx0=ee+std::sqrt(ee*ee+beta*beta); // W&M eq. 15 (Rutherford value)
547  if(master->CheckNuclearCollision(A, a1, xx0*au)) return 0; // nuclei too close
548 
549  }
550 
551  // we will be solving x^2 - x phi(x*au)/eps - beta^2 == 0.0
552  // or, for easier scaling, x'^2 - x' au phi(x')/eps - beta^2 au^2
553  xovereps.reset(0., 0.0, au/eps); // slope of x*au/eps term
554  phifunc.set_function(&(screen->EMphiData.get())); // install interpolating table
555  G4double xx1, phip, phip2;
556  G4int root_error;
557  xx1=diff->find_root(phifunc.xmin(), std::min(10*xx0*au,phifunc.xmax()),
558  std::min(xx0*au, phifunc.xmax()), beta*beta*au*au, &root_error, &phip, &phip2)/au;
559 
560  if(root_error) {
561  G4cout << "Screened Coulomb Root Finder Error" << G4endl;
562  G4cout << "au " << au << " A " << A << " a1 " << a1 << " xx1 " << xx1 << " eps " << eps << " beta " << beta << G4endl;
563  G4cout << " xmin " << phifunc.xmin() << " xmax " << std::min(10*xx0*au,phifunc.xmax()) ;
564  G4cout << " f(xmin) " << phifunc(phifunc.xmin()) << " f(xmax) " << phifunc(std::min(10*xx0*au,phifunc.xmax())) ;
565  G4cout << " xstart " << std::min(xx0*au, phifunc.xmax()) << " target " << beta*beta*au*au ;
566  G4cout << G4endl;
567  throw c2_exception("Failed root find");
568  }
569 
570  // phiprime is scaled by one factor of au because phi is evaluated at (xx0*au),
571  G4double phiprime=phip*au;
572 
573  //lambda0 is from W&M 19
574  G4double lambda0=1.0/std::sqrt(0.5+beta*beta/(2.0*xx1*xx1)-phiprime/(2.0*eps));
575 
576  //compute the 6-term Lobatto integral alpha (per W&M 21, with different coefficients)
577  // this is probably completely un-needed but gives the highest quality results,
578  G4double alpha=(1.0+ lambda0)/30.0;
579  G4double xvals[]={0.98302349, 0.84652241, 0.53235309, 0.18347974};
580  G4double weights[]={0.03472124, 0.14769029, 0.23485003, 0.18602489};
581  for(G4int k=0; k<4; k++) {
582  G4double x, ff;
583  x=xx1/xvals[k];
584  ff=1.0/std::sqrt(1.0-phifunc(x*au)/(x*eps)-beta*beta/(x*x));
585  alpha+=weights[k]*ff;
586  }
587 
588  phifunc.unset_function(); // throws an exception if used without setting again
589 
590  G4double thetac1=CLHEP::pi*beta*alpha/xx1; // complement of CM scattering angle
591  G4double sintheta=std::sin(thetac1); //note sin(pi-theta)=sin(theta)
592  G4double costheta=-std::cos(thetac1); // note cos(pi-theta)=-cos(theta)
593  // G4double psi=std::atan2(sintheta, costheta+a1/A); // lab scattering angle (M&T 3rd eq. 8.69)
594 
595  // numerics note: because we checked above for reasonable values of beta which give real recoils,
596  // we don't have to look too closely for theta -> 0 here (which would cause sin(theta)
597  // and 1-cos(theta) to both vanish and make the atan2 ill behaved).
598  G4double zeta=std::atan2(sintheta, 1-costheta); // lab recoil angle (M&T 3rd eq. 8.73)
599  G4double coszeta=std::cos(zeta);
600  G4double sinzeta=std::sin(zeta);
601 
602  kin.sinTheta=sintheta;
603  kin.cosTheta=costheta;
604  kin.sinZeta=sinzeta;
605  kin.cosZeta=coszeta;
606  return 1; // all OK, collision is valid
607 }
void set_function(const c2_function< float_type > *f)
fill the container with a new function, or clear it with a null pointer
Definition: c2_function.hh:832
int G4int
Definition: G4Types.hh:78
c2_const_plugin_function_p< G4double > & phifunc
G4GLOB_DLL std::ostream G4cout
void reset(float_type x0, float_type y0, float_type slope)
Change the slope and intercepts after construction.
const c2_function< float_type > & get() const
get a reference to our owned function
Definition: c2_function.hh:614
the exception class for c2_function operations.
Definition: c2_function.hh:65
float_type find_root(float_type lower_bracket, float_type upper_bracket, float_type start, float_type value, int *error=0, float_type *final_yprime=0, float_type *final_yprime2=0) const
solve f(x)==value very efficiently, with explicit knowledge of derivatives of the function ...
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
#define G4endl
Definition: G4ios.hh:61
double G4double
Definition: G4Types.hh:76
float_type xmax() const
return the upper bound of the domain for this function as set by set_domain()
Definition: c2_function.hh:299
void unset_function()
clear our function
Definition: c2_function.hh:808
float_type xmin() const
return the lower bound of the domain for this function as set by set_domain()
Definition: c2_function.hh:297

Field Documentation

G4_c2_ptr G4ScreenedCoulombClassicalKinematics::diff
protected

Definition at line 174 of file G4ScreenedNuclearRecoil.hh.

Referenced by DoScreeningComputation().

c2_const_plugin_function_p<G4double>& G4ScreenedCoulombClassicalKinematics::phifunc
protected

Definition at line 172 of file G4ScreenedNuclearRecoil.hh.

Referenced by DoScreeningComputation().

c2_linear_p<G4double>& G4ScreenedCoulombClassicalKinematics::xovereps
protected

Definition at line 173 of file G4ScreenedNuclearRecoil.hh.

Referenced by DoScreeningComputation().


The documentation for this class was generated from the following files: