88 "G4ScreenedNuclearRecoil.cc,v 1.57 2008/05/07 11:51:26 marcus Exp GEANT4 tag ";
131 const G4double G4ScreenedCoulombCrossSection::massmap[nMassMapElements+1]={
132 0, 1.007940, 4.002602, 6.941000, 9.012182, 10.811000, 12.010700,
133 14.006700, 15.999400, 18.998403, 20.179700, 22.989770, 24.305000, 26.981538, 28.085500,
134 30.973761, 32.065000, 35.453000, 39.948000, 39.098300, 40.078000, 44.955910, 47.867000,
135 50.941500, 51.996100, 54.938049, 55.845000, 58.933200, 58.693400, 63.546000, 65.409000,
136 69.723000, 72.640000, 74.921600, 78.960000, 79.904000, 83.798000, 85.467800, 87.620000,
137 88.905850, 91.224000, 92.906380, 95.940000, 98.000000, 101.070000, 102.905500, 106.420000,
138 107.868200, 112.411000, 114.818000, 118.710000, 121.760000, 127.600000, 126.904470, 131.293000,
139 132.905450, 137.327000, 138.905500, 140.116000, 140.907650, 144.240000, 145.000000, 150.360000,
140 151.964000, 157.250000, 158.925340, 162.500000, 164.930320, 167.259000, 168.934210, 173.040000,
141 174.967000, 178.490000, 180.947900, 183.840000, 186.207000, 190.230000, 192.217000, 195.078000,
142 196.966550, 200.590000, 204.383300, 207.200000, 208.980380, 209.000000, 210.000000, 222.000000,
143 223.000000, 226.000000, 227.000000, 232.038100, 231.035880, 238.028910, 237.000000, 244.000000,
144 243.000000, 247.000000, 247.000000, 251.000000, 252.000000, 257.000000, 258.000000, 259.000000,
145 262.000000, 261.000000, 262.000000, 266.000000, 264.000000, 277.000000, 268.000000, 281.000000,
146 272.000000, 285.000000, 282.500000, 289.000000, 287.500000, 292.000000};
158 if (nMatElements == 1)
160 element= (*elementVector)[0];
169 for (
G4int k=0 ; k < nMatElements ; k++ )
171 nsum+=atomDensities[k];
172 element= (*elementVector)[k];
173 if (nsum >= random)
break;
190 for(
G4int i=0; i<nIsotopes; i++) {
193 if(asum >= random)
break;
197 N=(
G4int)std::floor(element->
GetN()+0.5);
205 for(i=0; i<nIsotopes; i++) {
207 N=(*isoV)[i]->GetN();
208 if(asum >= random)
break;
214 ParticleCache::iterator
p=
targetMap.find(Z*1000+N);
226 const G4int nmfpvals=200;
228 std::vector<G4double> evals(nmfpvals), mfpvals(nmfpvals);
232 if (materialTable == 0) {
return; }
237 for (
G4int matidx=0; matidx < nMaterials; matidx++) {
247 for (
G4int kel=0 ; kel < nMatElements ; kel++ )
249 element=elementVector[kel];
252 if(!kel || ifunc.
xmin() > emin) emin=ifunc.
xmin();
253 if(!kel || ifunc.
xmax() < emax) emax=ifunc.
xmax();
256 G4double logint=std::log(emax/emin) / (nmfpvals-1) ;
259 for (
G4int i=1; i<nmfpvals-1; i++) evals[i]=emin*std::exp(logint*i);
264 for (
G4int eidx=0; eidx < nmfpvals; eidx++) mfpvals[eidx] = 0.0;
267 for (
G4int kel=0 ; kel < nMatElements ; kel++ )
269 element=elementVector[kel];
272 G4double ndens = atomDensities[kel];
274 for (
G4int eidx=0; eidx < nmfpvals; eidx++) {
275 mfpvals[eidx] += ndens*sigma(evals[eidx]);
280 for (
G4int eidx=0; eidx < nmfpvals; eidx++) {
281 mfpvals[eidx] = 1.0/mfpvals[eidx];
294 screeningKey(ScreeningKey),
295 generateRecoils(GenerateRecoils), avoidReactions(1),
296 recoilCutoff(RecoilCutoff), physicsCutoff(PhysicsCutoff),
297 hardeningFraction(0.0), hardeningFactor(1.0),
298 externalCrossSectionConstructor(0),
361 return avoidReactions && (apsis < (1.1*(std::pow(A,1.0/3.0)+std::pow(a1,1.0/3.0)) + 1.4)*
fermi);
395 std::map<G4int, G4ScreenedCoulombCrossSection*>::iterator xh=
403 }
else xs=(*xh).second;
450 G4double lattice=0.5/std::pow(numberDensity,1.0/3.0);
452 G4double sigopi=1.0/(CLHEP::pi*numberDensity*length);
459 if(sigopi < lattice*lattice) {
479 printf(
"ScreenedNuclear impact reject: length=%.3f P=%.4f limit=%.4f\n",
504 std::vector<G4ScreenedCollisionStage *>::iterator stage=
collisionStages.begin();
507 (*stage)->DoCollisionStep(
this,aTrack, aStep);
523 phifunc(c2.const_plugin_function()),
524 xovereps(c2.linear(0., 0., 0.)),
525 diff(c2.quadratic(0., 0., 0., 1.)-xovereps*phifunc)
540 G4double mlrho4=((((3.517e-4*y+1.401e-2)*y+2.393e-1)*y+2.734)*y+2.220);
543 xx0=std::sqrt(bb2+std::sqrt(bb2*bb2+rho4));
546 xx0=ee+std::sqrt(ee*ee+beta*beta);
561 G4cout <<
"Screened Coulomb Root Finder Error" <<
G4endl;
562 G4cout <<
"au " << au <<
" A " << A <<
" a1 " << a1 <<
" xx1 " << xx1 <<
" eps " << eps <<
" beta " << beta <<
G4endl;
565 G4cout <<
" xstart " <<
std::min(xx0*au, phifunc.xmax()) <<
" target " << beta*beta*au*au ;
574 G4double lambda0=1.0/std::sqrt(0.5+beta*beta/(2.0*xx1*xx1)-phiprime/(2.0*eps));
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++) {
584 ff=1.0/std::sqrt(1.0-
phifunc(x*au)/(x*eps)-beta*beta/(x*x));
585 alpha+=weights[k]*
ff;
590 G4double thetac1=CLHEP::pi*beta*alpha/xx1;
591 G4double sintheta=std::sin(thetac1);
592 G4double costheta=-std::cos(thetac1);
598 G4double zeta=std::atan2(sintheta, 1-costheta);
632 G4double Ec = incidentEnergy*(A/(A+a1));
648 if(incidentEnergy-eRecoil < master->GetRecoilCutoff()*a1) {
679 recoilMomentumDirection=recoilMomentumDirection.
rotateUz(incidentDirection);
690 recoilMomentumDirection,eRecoil) ;
710 if(nam ==
"GenericIon" || nam ==
"proton"
711 || nam ==
"deuteron" || nam ==
"triton" || nam ==
"alpha" || nam ==
"He3") {
737 static const size_t ncoef=4;
738 static G4double scales[ncoef]={-3.2, -0.9432, -0.4028, -0.2016};
739 static G4double coefs[ncoef]={0.1818,0.5099,0.2802,0.0281};
742 std::vector<G4double>
r(npoints), phi(npoints);
744 for(
size_t i=0; i<npoints; i++) {
745 G4double rr=(float)i/(
float)(npoints-1);
748 for(
size_t j=0; j<ncoef; j++) sum+=coefs[j]*std::exp(scales[j]*
r[i]/au);
754 for(
size_t j=0; j<ncoef; j++) phiprime0+=scales[j]*coefs[j]*std::exp(scales[j]*
r[0]/au);
763 static const size_t ncoef=3;
764 static G4double scales[ncoef]={-6.0, -1.2, -0.3};
765 static G4double coefs[ncoef]={0.10, 0.55, 0.35};
767 G4double au=0.8853*0.529*
angstrom/std::sqrt(std::pow(z1, 0.6667)+std::pow(z2,0.6667));
768 std::vector<G4double>
r(npoints), phi(npoints);
770 for(
size_t i=0; i<npoints; i++) {
771 G4double rr=(float)i/(
float)(npoints-1);
774 for(
size_t j=0; j<ncoef; j++) sum+=coefs[j]*std::exp(scales[j]*
r[i]/au);
780 for(
size_t j=0; j<ncoef; j++) phiprime0+=scales[j]*coefs[j]*std::exp(scales[j]*
r[0]/au);
791 G4double au=0.8853*0.529*
angstrom/std::sqrt(std::pow(z1, 0.6667)+std::pow(z2,0.6667));
792 std::vector<G4double>
r(npoints), phi(npoints);
794 for(
size_t i=0; i<npoints; i++) {
795 G4double rr=(float)i/(
float)(npoints-1);
800 G4double phipoly=1+y+0.3344*ysq+0.0485*y*ysq+0.002647*ysq*ysq;
801 phi[i]=phipoly*std::exp(-y);
806 G4double logphiprime0=(9.67/2.0)*(2*0.3344-1.0);
807 logphiprime0 *= (1.0/au);
850 std::vector<G4String> keys;
852 std::map<std::string, ScreeningFunc>::const_iterator sfunciter=phiMap.begin();
853 for(; sfunciter != phiMap.end(); sfunciter++) keys.push_back((*sfunciter).first);
865 return mc2*f/(std::sqrt(1.0+f)+1.0);
869 G4double s2th2=eratio*( (m1+mass2)*(m1+mass2)/(4.0*m1*mass2) );
871 return 2.0*std::asin(sth2);
876 static const size_t sigLen=200;
883 if (materialTable == 0) {
return; }
888 for (
G4int im=0; im<nMaterials; im++)
894 for (
G4int iEl=0; iEl<nMatElements; iEl++)
896 G4Element* element = (*elementVector)[iEl];
903 std::map<std::string, ScreeningFunc>::iterator sfunciter=phiMap.find(screeningKey);
904 if(sfunciter==phiMap.end()) {
905 G4cout <<
"no such screening key " << screeningKey <<
G4endl;
928 x0func->set_domain(1e-6*
angstrom/au, 0.9999*screen->
xmax()/au);
936 G4double eratkin=0.9999*(4*a1*a2)/((a1+a2)*(a1+a2));
942 G4cout <<
"Native Screening: " << screeningKey <<
" " << z1 <<
" " << a1 <<
" " <<
943 Z <<
" " << a2 <<
" " << recoilCutoff <<
G4endl;
945 for(
size_t idx=0; idx<sigLen; idx++) {
946 G4double ee=std::exp(idx*((l1-l0)/sigLen)+l0);
949 G4double theta=thetac(gamma*a1, a2, eratio);
951 G4double eps=cm_energy(a1, a2, ee)/escale;
952 c2eps.
reset(0.0, 0.0, eps);
962 x0=x0_solution(2*q-q*q);
966 G4double betasquared=x0*x0 - x0*phiau(x0)/eps;
size_t GetNumberOfIsotopes() const
G4ParticleDefinition * GetDefinition() const
virtual void Initialize(const G4Track &)
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
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)
G4ParticleDefinition * GetIon(G4int atomicNumber, G4int atomicMass, G4double excitationEnergy)
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
static G4MaterialTable * GetMaterialTable()
G4ScreenedNuclearRecoil(const G4String &processName="ScreenedElastic", const G4String &ScreeningKey="zbl", G4bool GenerateRecoils=1, G4double RecoilCutoff=100.0 *CLHEP::eV, G4double PhysicsCutoff=10.0 *CLHEP::eV)
Construct the process and set some physics parameters for it.
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
const G4VNIELPartition * NIELPartitionFunction
std::vector< G4Material * > G4MaterialTable
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)
fill the container with a new function, or clear it with a null pointer
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)
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
G4GLOB_DLL std::ostream G4cout
G4ScreenedCoulombCrossSection * crossSection
void reset(float_type x0, float_type y0, float_type slope)
Change the slope and intercepts after construction.
void ProposeNonIonizingEnergyDeposit(G4double anEnergyPart)
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)
set the domain for this function.
ScreeningMap screeningData
Hep3Vector & rotateUz(const Hep3Vector &)
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
virtual G4bool IsApplicable(const G4ParticleDefinition &aParticleType)
test if a prticle of type aParticleType can use this process
G4int GetNumberOfIsotopes(G4int Z)
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 G4ParticleTable * GetParticleTable()
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
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
size_t GetNumberOfElements() const
G4double GetAbundance(G4int number)
printf("%d Experimental points found\n", nlines)
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.
G4ScreenedCoulombClassicalKinematics()
c2_linear_p< G4double > & xovereps
G4double GetPDGCharge() const
G4bool DoScreeningComputation(class G4ScreenedNuclearRecoil *master, const G4ScreeningTables *screen, G4double eps, G4double beta)
float_type xmax() const
return the upper bound of the domain for this function as set by set_domain()
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
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 &)
float_type xmin() const
return the lower bound of the domain for this function as set by set_domain()
const XML_Char const XML_Char * data
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.