93  "G4ScreenedNuclearRecoil.cc,v 1.57 2008/05/07 11:51:26 marcus Exp GEANT4 tag ";
 
  135 const G4double G4ScreenedCoulombCrossSection::massmap[nMassMapElements+1]={
 
  136   0, 1.007940, 4.002602, 6.941000, 9.012182, 10.811000, 12.010700, 
 
  137   14.006700, 15.999400, 18.998403, 20.179700, 22.989770, 24.305000, 26.981538, 
 
  139   30.973761, 32.065000, 35.453000, 39.948000, 39.098300, 40.078000, 44.955910, 
 
  141   50.941500, 51.996100, 54.938049, 55.845000, 58.933200, 58.693400, 63.546000, 
 
  143   69.723000, 72.640000, 74.921600, 78.960000, 79.904000, 83.798000, 85.467800, 
 
  145   88.905850, 91.224000, 92.906380, 95.940000, 98.000000, 101.070000, 102.905500,
 
  147   107.868200, 112.411000, 114.818000, 118.710000, 121.760000, 127.600000, 
 
  148   126.904470, 131.293000, 
 
  149   132.905450, 137.327000, 138.905500, 140.116000, 140.907650, 144.240000, 
 
  150   145.000000, 150.360000, 
 
  151   151.964000, 157.250000, 158.925340, 162.500000, 164.930320, 167.259000, 
 
  152   168.934210, 173.040000, 
 
  153   174.967000, 178.490000, 180.947900, 183.840000, 186.207000, 190.230000, 
 
  154   192.217000, 195.078000, 
 
  155   196.966550, 200.590000, 204.383300, 207.200000, 208.980380, 209.000000, 
 
  156   210.000000, 222.000000, 
 
  157   223.000000, 226.000000, 227.000000, 232.038100, 231.035880, 238.028910, 
 
  158   237.000000, 244.000000, 
 
  159   243.000000, 247.000000, 247.000000, 251.000000, 252.000000, 257.000000, 
 
  160   258.000000, 259.000000, 
 
  161   262.000000, 261.000000, 262.000000, 266.000000, 264.000000, 277.000000, 
 
  162   268.000000, 281.000000, 
 
  163   272.000000, 285.000000, 282.500000, 289.000000, 287.500000, 292.000000};
 
  178         if (nMatElements == 1)
 
  180                 element= (*elementVector)[0];
 
  189                 for (
G4int k=0 ; k < nMatElements ; k++ )
 
  191                         nsum+=atomDensities[k];
 
  192                         element= (*elementVector)[k];
 
  193                         if (nsum >= random) 
break;
 
  212             for(
G4int i=0; i<nIsotopes; i++) {
 
  215               if(asum >= random) 
break;
 
  219             N=(
G4int)std::floor(element->
GetN()+0.5);
 
  227                 for(i=0; i<nIsotopes; i++) {
 
  229                         N=(*isoV)[i]->GetN();
 
  230                         if(asum >= random) 
break;
 
  237         ParticleCache::iterator 
p=
targetMap.find(Z*1000+N);
 
  249         const G4int nmfpvals=200;
 
  251         std::vector<G4double> evals(nmfpvals), mfpvals(nmfpvals);
 
  255         if (materialTable == 0) { 
return; }
 
  261         for (
G4int matidx=0; matidx < nMaterials; matidx++) {
 
  273           for (
G4int kel=0 ; kel < nMatElements ; kel++ )
 
  275                         element=elementVector[kel];
 
  278                         if(!kel || ifunc.
xmin() > emin) emin=ifunc.
xmin();
 
  287           for (
G4int i=1; i<nmfpvals-1; i++) evals[i]=emin*std::exp(logint*i);
 
  292           for (
G4int eidx=0; eidx < nmfpvals; eidx++) mfpvals[eidx] = 0.0; 
 
  296           for (
G4int kel=0 ; kel < nMatElements ; kel++ )
 
  298               element=elementVector[kel];
 
  301               G4double ndens = atomDensities[kel]; 
 
  304               for (
G4int eidx=0; eidx < nmfpvals; eidx++) {
 
  305                 mfpvals[eidx] += ndens*sigma(evals[eidx]);
 
  310           for (
G4int eidx=0; eidx < nmfpvals; eidx++) {
 
  311             mfpvals[eidx] = 1.0/mfpvals[eidx];
 
  315                               mfpvals,
true,0,
true,0);
 
  325         screeningKey(ScreeningKey),
 
  326         generateRecoils(GenerateRecoils), avoidReactions(1), 
 
  327         recoilCutoff(RecoilCutoff), physicsCutoff(PhysicsCutoff),
 
  328         hardeningFraction(0.0), hardeningFactor(1.0),
 
  329         externalCrossSectionConstructor(0),
 
  351   std::map<G4int, G4ScreenedCoulombCrossSection*>::iterator xt=
 
  401                                           std::pow(a1,1.0/3.0)) + 1.4)*
fermi);
 
  440         std::map<G4int, G4ScreenedCoulombCrossSection*>::iterator xh=
 
  448         } 
else xs=(*xh).second;
 
  501                 G4double lattice=0.5/std::pow(numberDensity,1.0/3.0); 
 
  504                 G4double sigopi=1.0/(
pi*numberDensity*length);  
 
  516                 if(sigopi < lattice*lattice) { 
 
  537     printf(
"ScreenedNuclear impact reject: length=%.3f P=%.4f limit=%.4f\n",
 
  563         std::vector<G4ScreenedCollisionStage *>::iterator stage=
 
  567                 (*stage)->DoCollisionStep(
this,aTrack, aStep);
 
  585   phifunc(c2.const_plugin_function()),
 
  586   xovereps(c2.linear(0., 0., 0.)), 
 
  588   diff(c2.quadratic(0., 0., 0., 1.)-xovereps*phifunc)
 
  604     G4double mlrho4=((((3.517e-4*y+1.401e-2)*y+2.393e-1)*y+2.734)*y+2.220);
 
  607     xx0=std::sqrt(bb2+std::sqrt(bb2*bb2+rho4)); 
 
  610     xx0=ee+std::sqrt(ee*ee+beta*beta); 
 
  625                       &root_error, &phip, &phip2)/au; 
 
  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;
 
  638                        <<  
" target " <<  beta*beta*au*au ;
 
  648         G4double lambda0=1.0/std::sqrt(0.5+beta*beta/(2.0*xx1*xx1)
 
  649                                        -phiprime/(2.0*eps));
 
  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++) {
 
  661                 ff=1.0/std::sqrt(1.0-
phifunc(x*au)/(x*eps)-beta*beta/(x*x));
 
  662                 alpha+=weights[k]*ff;
 
  670         G4double sintheta=std::sin(thetac1); 
 
  671         G4double costheta=-std::cos(thetac1); 
 
  680         G4double zeta=std::atan2(sintheta, 1-costheta); 
 
  717         G4double Ec = incidentEnergy*(A/(A+a1)); 
 
  737         if(incidentEnergy-eRecoil < master->GetRecoilCutoff()*a1) {
 
  740                                       incidentEnergy-eRecoil);
 
  772         recoilMomentumDirection=
 
  773           recoilMomentumDirection.
rotateUz(incidentDirection);
 
  775           recoilMomentumDirection*std::sqrt(2.0*eRecoil*kin.
a2*
amu_c2);
 
  788                                 recoilMomentumDirection,eRecoil) ;
 
  808   if(nam == 
"GenericIon" || nam == 
"proton"  
  809      || nam == 
"deuteron" || nam == 
"triton"  
  810      || nam == 
"alpha" || nam == 
"He3") {
 
  838         static const size_t ncoef=4;
 
  839         static G4double scales[ncoef]={-3.2, -0.9432, -0.4028, -0.2016};
 
  840         static G4double coefs[ncoef]={0.1818,0.5099,0.2802,0.0281};
 
  843           0.8854*
angstrom*0.529/(std::pow(z1, 0.23)+std::pow(z2,0.23));
 
  844         std::vector<G4double> r(npoints), phi(npoints);
 
  846         for(
size_t i=0; i<npoints; i++) {
 
  847                 G4double rr=(float)i/(
float)(npoints-1);
 
  851                 for(
size_t j=0; j<ncoef; j++) 
 
  852                   sum+=coefs[j]*std::exp(scales[j]*r[i]/au);
 
  858         for(
size_t j=0; j<ncoef; j++) 
 
  859           phiprime0+=scales[j]*coefs[j]*std::exp(scales[j]*r[0]/au);
 
  870         static const size_t ncoef=3;
 
  871         static G4double scales[ncoef]={-6.0, -1.2, -0.3};
 
  872         static G4double coefs[ncoef]={0.10, 0.55, 0.35};
 
  875                                                     +std::pow(z2,0.6667));
 
  876         std::vector<G4double> r(npoints), phi(npoints);
 
  878         for(
size_t i=0; i<npoints; i++) {
 
  879                 G4double rr=(float)i/(
float)(npoints-1);
 
  883                 for(
size_t j=0; j<ncoef; j++) 
 
  884                   sum+=coefs[j]*std::exp(scales[j]*r[i]/au);
 
  890         for(
size_t j=0; j<ncoef; j++) 
 
  891           phiprime0+=scales[j]*coefs[j]*std::exp(scales[j]*r[0]/au);
 
  905                                                     +std::pow(z2,0.6667));
 
  906         std::vector<G4double> r(npoints), phi(npoints);
 
  908         for(
size_t i=0; i<npoints; i++) {
 
  909                 G4double rr=(float)i/(
float)(npoints-1);
 
  915                 G4double phipoly=1+y+0.3344*ysq+0.0485*y*ysq+0.002647*ysq*ysq;
 
  916                 phi[i]=phipoly*std::exp(-y);
 
  921         G4double logphiprime0=(9.67/2.0)*(2*0.3344-1.0); 
 
  923         logphiprime0 *= (1.0/au); 
 
  969 std::vector<G4String> 
 
  971   std::vector<G4String> keys;
 
  973   std::map<std::string, ScreeningFunc>::const_iterator sfunciter=phiMap.begin();
 
  974   for(; sfunciter != phiMap.end(); sfunciter++) 
 
  975     keys.push_back((*sfunciter).first);
 
  988         return mc2*f/(std::sqrt(1.0+f)+1.0); 
 
  992         G4double s2th2=eratio*( (m1+mass2)*(m1+mass2)/(4.0*m1*mass2) );
 
  994         return 2.0*std::asin(sth2);
 
 1001         static const size_t sigLen=200; 
 
 1010         if (materialTable == 0) { 
return; }
 
 1015         for (
G4int im=0; im<nMaterials; im++)
 
 1021             for (
G4int iEl=0; iEl<nMatElements; iEl++)
 
 1023                 G4Element* element = (*elementVector)[iEl];
 
 1031                 std::map<std::string, ScreeningFunc>::iterator sfunciter=
 
 1032                   phiMap.find(screeningKey);
 
 1033                 if(sfunciter==phiMap.end()) {
 
 1035                   ed << 
"No such screening key <"  
 1036                      << screeningKey << 
">"; 
 
 1037                   G4Exception(
"G4NativeScreenedCoulombCrossSection::LoadData",
 
 1048                 st.
z1=z1; st.
m1=a1; st.
z2=
Z; st.
m2=a2; st.
emin=recoilCutoff;
 
 1069                 x0func->set_domain(1e-6*
angstrom/au, 0.9999*screen->
xmax()/au); 
 
 1081                 G4double eratkin=0.9999*(4*a1*a2)/((a1+a2)*(a1+a2)); 
 
 1088                   G4cout << 
"Native Screening: " << screeningKey << 
" "  
 1089                          << z1 << 
" " << a1 << 
" " << 
 
 1090                     Z << 
" " << a2 << 
" " << recoilCutoff << 
G4endl;
 
 1092                 for(
size_t idx=0; idx<sigLen; idx++) {
 
 1093                   G4double ee=std::exp(idx*((l1-l0)/sigLen)+l0);
 
 1102                   c2eps.
reset(0.0, 0.0, eps); 
 
 1116                     x0=x0_solution(2*q-q*q);
 
size_t GetNumberOfIsotopes() const 
 
G4ParticleDefinition * GetDefinition() const 
 
virtual void Initialize(const G4Track &)
 
static c2_factory< G4double > c2
 
G4_c2_const_ptr EMphiData
 
std::vector< G4String > GetScreeningKeys() const 
 
std::vector< G4Isotope * > G4IsotopeVector
 
static lin_log_interpolating_function_p< float_type > & lin_log_interpolating_function()
make a *new object 
 
G4CoulombKinematicsInfo kinematics
 
G4double GetCurrentInteractionLength() const 
the the interaciton length used in the last scattering. 
 
std::vector< G4Element * > G4ElementVector
 
std::ostringstream G4ExceptionDescription
 
void AddStage(G4ScreenedCollisionStage *stage)
 
virtual void LoadData(G4String screeningKey, G4int z1, G4double m1, G4double recoilCutoff)=0
 
G4double GetKineticEnergy() const 
 
G4bool GetValidCollision() const 
 
const G4DynamicParticle * GetDynamicParticle() const 
 
G4double highEnergyLimit
the energy per nucleon above which the MFP is constant 
 
virtual void DoCollisionStep(class G4ScreenedNuclearRecoil *master, const class G4Track &aTrack, const class G4Step &aStep)
 
Definition of the G4ScreenedNuclearRecoil class. 
 
G4ParticleDefinition * recoilIon
 
G4CoulombKinematicsInfo & GetKinematics()
 
G4int GetFirstIsotope(G4int Z)
 
virtual void DumpPhysicsTable(const G4ParticleDefinition &aParticleType)
Export physics tables for persistency. Not Implemented. 
 
G4double GetRecoilCutoff() const 
get the recoil cutoff 
 
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
 
static G4MaterialTable * GetMaterialTable()
 
const G4MaterialCutsCouple * GetMaterialCutsCouple() const 
 
const G4VNIELPartition * NIELPartitionFunction
 
std::vector< G4Material * > G4MaterialTable
 
static const G4double eps
 
virtual G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *)
used internally by Geant4 machinery 
 
void DepositEnergy(G4int z1, G4double a1, const G4Material *material, G4double energy)
take the given energy, and use the material information to partition it into NIEL and ionizing energy...
 
G4ParticleDefinition * GetDefinition() const 
 
void append_function(const c2_function< float_type > &func)
append a new function to the sequence 
 
void BuildMFPTables(void)
 
virtual ~G4NativeScreenedCoulombCrossSection()
 
void set_function(const c2_function< float_type > *f)
 
const G4ElementVector * GetElementVector() const 
 
virtual void BuildPhysicsTable(const G4ParticleDefinition &aParticleType)
Build physics tables in advance. Not Implemented. 
 
const G4String & GetParticleName() const 
 
std::vector< G4ScreenedCollisionStage * > collisionStages
 
G4_c2_function & LJScreening(G4int z1, G4int z2, size_t npoints, G4double rMax, G4double *auval)
 
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
 
const XML_Char const XML_Char * data
 
static constexpr double gram
 
c2_const_plugin_function_p< G4double > & phifunc
 
G4ScreenedCoulombCrossSection * externalCrossSectionConstructor
 
static c2_connector_function_p< float_type > & connector_function(float_type x0, const c2_function< float_type > &f0, float_type x2, const c2_function< float_type > &f2, bool auto_center, float_type y1)
make a *new object 
 
const G4double * GetVecNbOfAtomsPerVolume() const 
 
static G4double thetac(G4double m1, G4double mass2, G4double eratio)
 
G4GLOB_DLL std::ostream G4cout
 
double A(double temperature)
 
G4ScreenedCoulombCrossSection * crossSection
 
void reset(float_type x0, float_type y0, float_type slope)
Change the slope and intercepts after construction. 
 
void ProposeNonIonizingEnergyDeposit(G4double anEnergyPart)
 
static G4double cm_energy(G4double a1, G4double a2, G4double t0)
 
G4double GetHardeningFactor() const 
get the boost factor in use. 
 
std::map< G4int, G4_c2_const_ptr > MFPTables
 
std::map< G4int, G4ScreenedCoulombCrossSection * > crossSectionHandlers
 
const G4ThreeVector & GetMomentumDirection() const 
 
void set_domain(float_type amin, float_type amax)
 
ScreeningMap screeningData
 
Hep3Vector & rotateUz(const Hep3Vector &)
 
static constexpr double eplus
 
virtual ~G4ScreenedCoulombCrossSection()
 
void SetValidCollision(G4bool flag)
 
const G4ScreeningTables * GetScreening(G4int Z)
 
G4ParticleDefinition * SelectRandomUnweightedTarget(const G4MaterialCutsCouple *couple)
 
G4NativeScreenedCoulombCrossSection()
 
G4double * GetRelativeAbundanceVector() const 
 
static G4Proton * Proton()
 
void SetProcessSubType(G4int)
 
void release_for_return()
release the function without destroying it, so it can be returned from a function ...
 
G4double lowEnergyLimit
the energy per nucleon below which the MFP is zero 
 
const G4String & GetParticleType() const 
 
std::map< G4int, G4_c2_const_ptr > sigmaMap
 
G4_c2_function & ZBLScreening(G4int z1, G4int z2, size_t npoints, G4double rMax, G4double *auval)
 
const c2_function< float_type > & get() const 
get a reference to our owned function 
 
G4bool GetEnableRecoils() const 
find out if generation of recoils is enabled. 
 
static size_t GetNumberOfMaterials()
 
const G4String & GetProcessName() const 
 
G4ScreenedNuclearRecoil(const G4String &processName="ScreenedElastic", const G4String &ScreeningKey="zbl", G4bool GenerateRecoils=1, G4double RecoilCutoff=100.0 *eV, G4double PhysicsCutoff=10.0 *eV)
Construct the process and set some physics parameters for it. 
 
virtual G4bool IsApplicable(const G4ParticleDefinition &aParticleType)
test if a prticle of type aParticleType can use this process 
 
static G4IonTable * GetIonTable()
 
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
 
G4int GetNumberOfIsotopes(G4int Z)
 
static const G4double emax
 
the exception class for c2_function operations. 
 
void SetNIELPartitionFunction(const G4VNIELPartition *part)
set the pointer to a class for paritioning energy into NIEL 
 
virtual G4ScreenedCoulombCrossSection * create()=0
 
G4double GetTotNbOfAtomsPerVolume() const 
 
G4bool registerDepositedEnergy
 
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 ...
 
G4IsotopeVector * GetIsotopeVector() const 
 
void SetVerbosity(G4int v)
 
static log_log_interpolating_function_p< float_type > & log_log_interpolating_function()
make a *new object 
 
G4int GetIsotopeNucleonCount(G4int number)
 
G4double GetPDGMass() const 
 
static c2_linear_p< float_type > & linear(float_type x0, float_type y0, float_type slope)
make a *new object 
 
G4double standardmass(G4int z1)
 
T max(const T t1, const T t2)
brief Return the largest of the two arguments 
 
static constexpr double nm
 
G4double energy(const ThreeVector &p, const G4double m)
 
void SetNumberOfSecondaries(G4int totSecondaries)
 
static const char * CVSFileVers()
 
G4_c2_function & LJZBLScreening(G4int z1, G4int z2, size_t npoints, G4double rMax, G4double *auval)
 
const G4Material * targetMaterial
 
virtual ~G4ScreenedNuclearRecoil()
destructor 
 
virtual G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
used internally by Geant4 machinery 
 
G4VParticleChange * pParticleChange
 
a factory of pre-templated c2_function generators 
 
virtual G4bool CheckNuclearCollision(G4double A, G4double A1, G4double apsis)
deterine if the moving particle is within the strong force range of the selected nucleus ...
 
void ProposeEnergy(G4double finalEnergy)
 
T min(const T t1, const T t2)
brief Return the smallest of the two arguments 
 
void AddScreeningFunction(G4String name, ScreeningFunc fn)
 
static c2_inverse_function_p< float_type > & inverse_function(const c2_function< float_type > &source)
make a *new object 
 
void AddSecondary(G4Track *aSecondary)
 
virtual G4ScreenedCoulombCrossSection * GetNewCrossSectionHandler(void)
 
G4double GetEnergy() const 
 
G4double GetHardeningFraction() const 
get the fraction of particles which will have boosted scattering 
 
static constexpr double MeV
 
static constexpr double angstrom
 
static constexpr double pi
 
size_t GetNumberOfElements() const 
 
G4double GetAbundance(G4int number)
 
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
 
virtual void DoCollisionStep(class G4ScreenedNuclearRecoil *master, const class G4Track &aTrack, const class G4Step &aStep)
 
G4int GetVerboseLevel() const 
get the verbosity. 
 
G4_c2_function &(* ScreeningFunc)(G4int z1, G4int z2, size_t nPoints, G4double rMax, G4double *au)
 
class G4ParticleChange & GetParticleChange()
get the pointer to our ParticleChange object. for internal use, primarily. 
 
static constexpr double fermi
 
G4ScreenedCoulombClassicalKinematics()
 
c2_linear_p< G4double > & xovereps
 
G4double GetPDGCharge() const 
 
static const G4double alpha
 
G4bool DoScreeningComputation(class G4ScreenedNuclearRecoil *master, const G4ScreeningTables *screen, G4double eps, G4double beta)
 
G4_c2_function & MoliereScreening(G4int z1, G4int z2, size_t npoints, G4double rMax, G4double *auval)
 
void ResetTables()
clear precomputed screening tables 
 
A process which handles screened Coulomb collisions between nuclei. 
 
virtual void LoadData(G4String screeningKey, G4int z1, G4double m1, G4double recoilCutoff)
 
G4int GetProcessSubType() const 
 
static constexpr double mole
 
virtual G4double PartitionNIEL(G4int z1, G4double a1, const G4Material *material, G4double energy) const =0
 
void unset_function()
clear our function 
 
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
 
create a c2_function which is a piecewise assembly of other c2_functions.The functions must have incr...
 
G4ThreeVector GetMomentum() const 
 
const G4Material * GetMaterial() const 
 
G4double processMaxEnergy
the energy per nucleon beyond which the cross section is zero, to cross over to G4MSC ...
 
static c2_piecewise_function_p< float_type > & piecewise_function()
make a *new object 
 
std::map< G4int, G4ScreenedCoulombCrossSection * > & GetCrossSectionHandlers()
 
Provides a factory class to avoid an infinite number of template.