Geant4  10.03.p03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ScreenedCoulombClassicalKinematics Class Reference

#include <G4ScreenedNuclearRecoil.hh>

Inheritance diagram for G4ScreenedCoulombClassicalKinematics:
Collaboration diagram for G4ScreenedCoulombClassicalKinematics:

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 173 of file G4ScreenedNuclearRecoil.hh.

Constructor & Destructor Documentation

G4ScreenedCoulombClassicalKinematics::G4ScreenedCoulombClassicalKinematics ( )

Definition at line 579 of file G4ScreenedNuclearRecoil.cc.

579  :
580 // instantiate all the needed functions statically, so no allocation is
581 // done at run time
582 // we will be solving x^2 - x phi(x*au)/eps - beta^2 == 0.0
583 // or, for easier scaling, x'^2 - x' au phi(x')/eps - beta^2 au^2
584 // note that only the last of these gets deleted, since it owns the rest
585  phifunc(c2.const_plugin_function()),
586  xovereps(c2.linear(0., 0., 0.)),
587  // will fill this in with the right slope at run time
588  diff(c2.quadratic(0., 0., 0., 1.)-xovereps*phifunc)
589 {
590 }
static c2_factory< G4double > c2
c2_const_plugin_function_p< G4double > & phifunc
virtual G4ScreenedCoulombClassicalKinematics::~G4ScreenedCoulombClassicalKinematics ( )
inlinevirtual

Definition at line 184 of file G4ScreenedNuclearRecoil.hh.

184 { }

Member Function Documentation

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

Implements G4ScreenedCollisionStage.

Definition at line 692 of file G4ScreenedNuclearRecoil.cc.

694  {
695 
696  if(!master->GetValidCollision()) return;
697 
698  G4ParticleChange &aParticleChange=master->GetParticleChange();
699  G4CoulombKinematicsInfo &kin=master->GetKinematics();
700 
701  const G4DynamicParticle* incidentParticle = aTrack.GetDynamicParticle();
702  G4ParticleDefinition *baseParticle=aTrack.GetDefinition();
703 
704  G4double incidentEnergy = incidentParticle->GetKineticEnergy();
705 
706  // this adjustment to a1 gives the right results for soft
707  // (constant gamma)
708  // relativistic collisions. Hard collisions are wrong anyway, since the
709  // Coulombic and hadronic terms interfere and cannot be added.
710  G4double gamma=(1.0+incidentEnergy/baseParticle->GetPDGMass());
711  G4double a1=kin.a1*gamma; // relativistic gamma correction
712 
713  G4ParticleDefinition *recoilIon=kin.recoilIon;
714  G4double A=recoilIon->GetPDGMass()/amu_c2;
715  G4int Z=(G4int)((recoilIon->GetPDGCharge()/eplus)+0.5);
716 
717  G4double Ec = incidentEnergy*(A/(A+a1));
718  // energy in CM frame (non-relativistic!)
719  const G4ScreeningTables *screen=kin.crossSection->GetScreening(Z);
720  G4double au=screen->au; // screening length
721 
722  G4double beta = kin.impactParameter/au;
723  // dimensionless impact parameter
724  G4double eps = Ec/(screen->z1*Z*elm_coupling/au);
725  // dimensionless energy
726 
727  G4bool ok=DoScreeningComputation(master, screen, eps, beta);
728  if(!ok) {
729  master->SetValidCollision(0); // flag bad collision
730  return; // just bail out without setting valid flag
731  }
732 
733  G4double eRecoil=4*incidentEnergy*a1*A*kin.cosZeta*kin.cosZeta
734  /((a1+A)*(a1+A));
735  kin.eRecoil=eRecoil;
736 
737  if(incidentEnergy-eRecoil < master->GetRecoilCutoff()*a1) {
738  aParticleChange.ProposeEnergy(0.0);
739  master->DepositEnergy(int(screen->z1), a1, kin.targetMaterial,
740  incidentEnergy-eRecoil);
741  }
742 
743  if(master->GetEnableRecoils() &&
744  eRecoil > master->GetRecoilCutoff() * kin.a2) {
745  kin.recoilIon=recoilIon;
746  } else {
747  kin.recoilIon=0; // this flags no recoil to be generated
748  master->DepositEnergy(Z, A, kin.targetMaterial, eRecoil) ;
749  }
750 }
G4double GetKineticEnergy() const
G4ParticleDefinition * recoilIon
tuple elm_coupling
Definition: hepunit.py:286
static const G4double eps
int G4int
Definition: G4Types.hh:78
double A(double temperature)
G4ScreenedCoulombCrossSection * crossSection
bool G4bool
Definition: G4Types.hh:79
static constexpr double eplus
Definition: G4SIunits.hh:199
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)

Here is the call graph for this function:

G4bool G4ScreenedCoulombClassicalKinematics::DoScreeningComputation ( class G4ScreenedNuclearRecoil master,
const G4ScreeningTables screen,
G4double  eps,
G4double  beta 
)

Definition at line 592 of file G4ScreenedNuclearRecoil.cc.

595 {
596  G4double au=screen->au;
597  G4CoulombKinematicsInfo &kin=master->GetKinematics();
598  G4double A=kin.a2;
599  G4double a1=kin.a1;
600 
601  G4double xx0; // first estimate of closest approach
602  if(eps < 5.0) {
603  G4double y=std::log(eps);
604  G4double mlrho4=((((3.517e-4*y+1.401e-2)*y+2.393e-1)*y+2.734)*y+2.220);
605  G4double rho4=std::exp(-mlrho4); // W&M eq. 18
606  G4double bb2=0.5*beta*beta;
607  xx0=std::sqrt(bb2+std::sqrt(bb2*bb2+rho4)); // W&M eq. 17
608  } else {
609  G4double ee=1.0/(2.0*eps);
610  xx0=ee+std::sqrt(ee*ee+beta*beta); // W&M eq. 15 (Rutherford value)
611  if(master->CheckNuclearCollision(A, a1, xx0*au)) return 0;
612  // nuclei too close
613 
614  }
615 
616  // we will be solving x^2 - x phi(x*au)/eps - beta^2 == 0.0
617  // or, for easier scaling, x'^2 - x' au phi(x')/eps - beta^2 au^2
618  xovereps.reset(0., 0.0, au/eps); // slope of x*au/eps term
619  phifunc.set_function(&(screen->EMphiData.get()));
620  // install interpolating table
621  G4double xx1, phip, phip2;
622  G4int root_error;
623  xx1=diff->find_root(phifunc.xmin(), std::min(10*xx0*au,phifunc.xmax()),
624  std::min(xx0*au, phifunc.xmax()), beta*beta*au*au,
625  &root_error, &phip, &phip2)/au;
626 
627  if(root_error) {
628  G4cout << "Screened Coulomb Root Finder Error" << G4endl;
629  G4cout << "au " << au << " A " << A << " a1 " << a1
630  << " xx1 " << xx1 << " eps " << eps
631  << " beta " << beta << G4endl;
632  G4cout << " xmin " << phifunc.xmin() << " xmax "
633  << std::min(10*xx0*au,phifunc.xmax()) ;
634  G4cout << " f(xmin) " << phifunc(phifunc.xmin())
635  << " f(xmax) "
636  << phifunc(std::min(10*xx0*au,phifunc.xmax())) ;
637  G4cout << " xstart " << std::min(xx0*au, phifunc.xmax())
638  << " target " << beta*beta*au*au ;
639  G4cout << G4endl;
640  throw c2_exception("Failed root find");
641  }
642 
643  // phiprime is scaled by one factor of au because phi is evaluated
644  // at (xx0*au),
645  G4double phiprime=phip*au;
646 
647  //lambda0 is from W&M 19
648  G4double lambda0=1.0/std::sqrt(0.5+beta*beta/(2.0*xx1*xx1)
649  -phiprime/(2.0*eps));
650 
651  // compute the 6-term Lobatto integral alpha (per W&M 21, with
652  // different coefficients)
653  // this is probably completely un-needed but gives the highest
654  // quality results,
655  G4double alpha=(1.0+ lambda0)/30.0;
656  G4double xvals[]={0.98302349, 0.84652241, 0.53235309, 0.18347974};
657  G4double weights[]={0.03472124, 0.14769029, 0.23485003, 0.18602489};
658  for(G4int k=0; k<4; k++) {
659  G4double x, ff;
660  x=xx1/xvals[k];
661  ff=1.0/std::sqrt(1.0-phifunc(x*au)/(x*eps)-beta*beta/(x*x));
662  alpha+=weights[k]*ff;
663  }
664 
666  // throws an exception if used without setting again
667 
668  G4double thetac1=pi*beta*alpha/xx1;
669  // complement of CM scattering angle
670  G4double sintheta=std::sin(thetac1); //note sin(pi-theta)=sin(theta)
671  G4double costheta=-std::cos(thetac1); // note cos(pi-theta)=-cos(theta)
672  // G4double psi=std::atan2(sintheta, costheta+a1/A);
673  // lab scattering angle (M&T 3rd eq. 8.69)
674 
675  // numerics note: because we checked above for reasonable values
676  // of beta which give real recoils,
677  // we don't have to look too closely for theta -> 0 here
678  // (which would cause sin(theta)
679  // and 1-cos(theta) to both vanish and make the atan2 ill behaved).
680  G4double zeta=std::atan2(sintheta, 1-costheta);
681  // lab recoil angle (M&T 3rd eq. 8.73)
682  G4double coszeta=std::cos(zeta);
683  G4double sinzeta=std::sin(zeta);
684 
685  kin.sinTheta=sintheta;
686  kin.cosTheta=costheta;
687  kin.sinZeta=sinzeta;
688  kin.cosZeta=coszeta;
689  return 1; // all OK, collision is valid
690 }
static const G4double eps
tuple x
Definition: test.py:50
void set_function(const c2_function< float_type > *f)
Definition: c2_function.hh:930
int G4int
Definition: G4Types.hh:78
c2_const_plugin_function_p< G4double > & phifunc
G4GLOB_DLL std::ostream G4cout
double A(double temperature)
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:735
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
static constexpr double pi
Definition: G4SIunits.hh:75
double G4double
Definition: G4Types.hh:76
static const G4double alpha
float_type xmax() const
Definition: c2_function.hh:390
void unset_function()
clear our function
Definition: c2_function.hh:907
float_type xmin() const
Definition: c2_function.hh:389

Here is the call graph for this function:

Here is the caller graph for this function:

Member Data Documentation

G4_c2_ptr G4ScreenedCoulombClassicalKinematics::diff
protected

Definition at line 190 of file G4ScreenedNuclearRecoil.hh.

c2_const_plugin_function_p<G4double>& G4ScreenedCoulombClassicalKinematics::phifunc
protected

Definition at line 188 of file G4ScreenedNuclearRecoil.hh.

c2_linear_p<G4double>& G4ScreenedCoulombClassicalKinematics::xovereps
protected

Definition at line 189 of file G4ScreenedNuclearRecoil.hh.


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