Geant4  10.00.p02
G4INCLCoulombNonRelativistic.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // INCL++ intra-nuclear cascade model
27 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
28 // Davide Mancusi, CEA
29 // Alain Boudard, CEA
30 // Sylvie Leray, CEA
31 // Joseph Cugnon, University of Liege
32 //
33 #define INCLXX_IN_GEANT4_MODE 1
34 
35 #include "globals.hh"
36 
45 #include "G4INCLGlobals.hh"
46 
47 namespace G4INCL {
48 
50  // No distortion for neutral particles
51  if(p->getZ()!=0) {
52  const G4bool success = coulombDeviation(p, n);
53  if(!success) // transparent
54  return NULL;
55  }
56 
57  // Rely on the CoulombNone slave to compute the straight-line intersection
58  // and actually bring the particle to the surface of the nucleus
60  }
61 
63  // Neutral clusters?!
64 // assert(c->getZ()>0);
65 
66  // Perform the actual Coulomb deviation
67  const G4bool success = coulombDeviation(c, n);
68  if(!success) {
69  return IAvatarList();
70  }
71 
72  // Rely on the CoulombNone slave to compute the straight-line intersection
73  // and actually bring the particle to the surface of the nucleus
75  }
76 
78  Nucleus const * const nucleus) const {
79 
80  for(ParticleIter particle=pL.begin(), e=pL.end(); particle!=e; ++particle) {
81 
82  const G4int Z = (*particle)->getZ();
83  if(Z == 0) continue;
84 
85  const G4double tcos=1.-0.000001;
86 
87  const G4double et1 = PhysicalConstants::eSquared * nucleus->getZ();
88  const G4double transmissionRadius =
89  nucleus->getDensity()->getTransmissionRadius(*particle);
90 
91  const ThreeVector position = (*particle)->getPosition();
92  ThreeVector momentum = (*particle)->getMomentum();
93  const G4double r = position.mag();
94  const G4double p = momentum.mag();
95  const G4double cosTheta = position.dot(momentum)/(r*p);
96  if(cosTheta < 0.999999) {
97  const G4double sinTheta = std::sqrt(1.-cosTheta*cosTheta);
98  const G4double eta = et1 * Z / (*particle)->getKineticEnergy();
99  if(eta > transmissionRadius-0.0001) {
100  // If below the Coulomb barrier, radial emission:
101  momentum = position * (p/r);
102  (*particle)->setMomentum(momentum);
103  } else {
104  const G4double b0 = 0.5 * (eta + std::sqrt(eta*eta +
105  4. * std::pow(transmissionRadius*sinTheta,2)
106  * (1.-eta/transmissionRadius)));
107  const G4double bInf = std::sqrt(b0*(b0-eta));
108  const G4double thr = std::atan(eta/(2.*bInf));
109  G4double uTemp = (1.-b0/transmissionRadius) * std::sin(thr) +
110  b0/transmissionRadius;
111  if(uTemp>tcos) uTemp=tcos;
112  const G4double thd = std::acos(cosTheta)-Math::piOverTwo + thr +
113  std::acos(uTemp);
114  const G4double c1 = std::sin(thd)*cosTheta/sinTheta + std::cos(thd);
115  const G4double c2 = -p*std::sin(thd)/(r*sinTheta);
116  const ThreeVector newMomentum = momentum*c1 + position*c2;
117  (*particle)->setMomentum(newMomentum);
118  }
119  }
120  }
121  }
122 
124  Nucleus const * const n) const {
125  const G4double theMinimumDistance = minimumDistance(p, kinE, n);
126  G4double rMax = n->getUniverseRadius();
127  if(p.theType == Composite)
129  const G4double theMaxImpactParameterSquared = rMax*(rMax-theMinimumDistance);
130  if(theMaxImpactParameterSquared<=0.)
131  return 0.;
132  const G4double theMaxImpactParameter = std::sqrt(theMaxImpactParameterSquared);
133  return theMaxImpactParameter;
134  }
135 
137  // Determine the rotation angle and the new impact parameter
138  ThreeVector positionTransverse = p->getTransversePosition();
139  const G4double impactParameterSquared = positionTransverse.mag2();
140  const G4double impactParameter = std::sqrt(impactParameterSquared);
141 
142  // Some useful variables
143  const G4double theMinimumDistance = minimumDistance(p, n);
144  // deltaTheta2 = (pi - Rutherford scattering angle)/2
145  const G4double deltaTheta2 = std::atan(2.*impactParameter/theMinimumDistance);
146  const G4double eccentricity = 1./std::cos(deltaTheta2);
147 
148  G4double newImpactParameter, alpha; // Parameters that must be determined by the deviation
149 
150  const G4double radius = getCoulombRadius(p->getSpecies(), n);
151  const G4double impactParameterTangentSquared = radius*(radius-theMinimumDistance);
152  if(impactParameterSquared >= impactParameterTangentSquared) {
153  // The particle trajectory misses the Coulomb sphere
154  // In this case the new impact parameter is the minimum distance of
155  // approach of the hyperbola
156 // assert(std::abs(1. + 2.*impactParameter*impactParameter/(radius*theMinimumDistance))>=eccentricity);
157  newImpactParameter = 0.5 * theMinimumDistance * (1.+eccentricity); // the minimum distance of approach
158  alpha = Math::piOverTwo - deltaTheta2; // half the Rutherford scattering angle
159  } else {
160  // The particle trajectory intersects the Coulomb sphere
161 
162  // Compute the entrance angle
163  const G4double argument = -(1. + 2.*impactParameter*impactParameter/(radius*theMinimumDistance))
164  / eccentricity;
165 // assert(std::abs(argument)<=1.);
166  const G4double thetaIn = Math::twoPi - std::acos(argument) - deltaTheta2;
167 
168  // Velocity angle at the entrance point
169  alpha = std::atan((1+std::cos(thetaIn))
170  / (std::sqrt(eccentricity*eccentricity-1.) - std::sin(thetaIn)));
171  // New impact parameter
172  newImpactParameter = radius * std::sin(thetaIn - alpha);
173  }
174 
175  // Modify the impact parameter of the particle
176  positionTransverse *= newImpactParameter/positionTransverse.mag();
177  const ThreeVector theNewPosition = p->getLongitudinalPosition() + positionTransverse;
178  p->setPosition(theNewPosition);
179 
180  // Determine the rotation axis for the incoming particle
181  const ThreeVector &momentum = p->getMomentum();
182  ThreeVector rotationAxis = momentum.vector(positionTransverse);
183  const G4double axisLength = rotationAxis.mag();
184  // Apply the rotation
185  if(axisLength>1E-20) {
186  rotationAxis /= axisLength;
187  p->rotate(alpha, rotationAxis);
188  }
189 
190  return true;
191  }
192 
194  if(p.theType == Composite) {
195  const G4int Zp = p.theZ;
196  const G4int Ap = p.theA;
197  const G4int Zt = n->getZ();
198  const G4int At = n->getA();
199  G4double barr, radius = 0.;
200  if(Zp==1 && Ap==2) { // d
201  barr = 0.2565*Math::pow23((G4double)At)-0.78;
202  radius = PhysicalConstants::eSquared*Zp*Zt/barr - 2.5;
203  } else if(Zp==1 && Ap==3) { // t
204  barr = 0.5*(0.5009*Math::pow23((G4double)At)-1.16);
205  radius = PhysicalConstants::eSquared*Zt/barr - 0.5;
206  } else if(Zp==2) { // alpha, He3
207  barr = 0.5939*Math::pow23((G4double)At)-1.64;
208  radius = PhysicalConstants::eSquared*Zp*Zt/barr - 0.5;
209  } else if(Zp>2) {
210  // Coulomb radius from the Shen model
211  const G4double Ap13 = Math::pow13((G4double)Ap);
212  const G4double At13 = Math::pow13((G4double)At);
213  const G4double rp = 1.12*Ap13 - 0.94/Ap13;
214  const G4double rt = 1.12*At13 - 0.94/At13;
215  const G4double someRadius = rp+rt+3.2;
216  const G4double theShenBarrier = PhysicalConstants::eSquared*Zp*Zt/someRadius - rt*rp/(rt+rp);
217  radius = PhysicalConstants::eSquared*Zp*Zt/theShenBarrier;
218  }
219  if(radius<=0.) {
221  INCL_ERROR("Negative Coulomb radius! Using the sum of nuclear radii = " << radius << std::endl);
222  }
223  INCL_DEBUG("Coulomb radius for particle "
224  << ParticleTable::getShortName(p) << " in nucleus A=" << At <<
225  ", Z=" << Zt << ": " << radius << std::endl);
226  return radius;
227  } else
228  return n->getUniverseRadius();
229  }
230 
231 }
G4int getA() const
Returns the baryon number.
ParticleEntryAvatar * bringToSurface(Particle *const p, Nucleus *const n) const
Modify the momentum of the particle and position it on the surface of the nucleus.
static c2_factory< G4double > c2
Class for non-relativistic Coulomb distortion.
const G4double eSquared
Coulomb conversion factor [MeV*fm].
G4double dot(const ThreeVector &v) const
Dot product.
#define INCL_ERROR(x)
const G4INCL::ThreeVector & getMomentum() const
Get the momentum vector.
G4double minimumDistance(ParticleSpecies const &p, const G4double kineticEnergy, Nucleus const *const n) const
Return the minimum distance of approach in a head-on collision (b=0).
Cluster is a particle (inherits from the Particle class) that is actually a collection of elementary ...
int G4int
Definition: G4Types.hh:78
ThreeVector vector(const ThreeVector &v) const
Vector product.
G4double pow23(G4double x)
G4double mag2() const
Get the square of the length.
CoulombNone theCoulombNoneSlave
Internal CoulombNone slave to generate the avatars.
virtual void rotate(const G4double angle, const ThreeVector &axis)
Rotate the particle position and momentum.
G4double maxImpactParameter(ParticleSpecies const &p, const G4double kinE, Nucleus const *const n) const
Return the maximum impact parameter for Coulomb-distorted trajectories.
G4double getLargestNuclearRadius(const G4int A, const G4int Z)
bool G4bool
Definition: G4Types.hh:79
virtual void setPosition(const G4INCL::ThreeVector &position)
G4int getZ() const
Returns the charge number.
G4double getCoulombRadius(ParticleSpecies const &p, Nucleus const *const n) const
Get the Coulomb radius for a given particle.
UnorderedVector< IAvatar * > IAvatarList
const G4double piOverTwo
const G4int n
static const G4double c1
ParticleEntryAvatar * bringToSurface(Particle *const p, Nucleus *const n) const
Position the particle on the surface of the nucleus.
ThreeVector getTransversePosition() const
Transverse component of the position w.r.t.
G4bool coulombDeviation(Particle *const p, Nucleus const *const n) const
Perform Coulomb deviation.
NuclearDensity const * getDensity() const
Getter for theDensity.
int position
Definition: filter.cc:7
const G4double twoPi
virtual G4INCL::ParticleSpecies getSpecies() const
Get the particle species.
G4double getUniverseRadius() const
Getter for theUniverseRadius.
G4double mag() const
Get the length of the vector.
double G4double
Definition: G4Types.hh:76
#define INCL_DEBUG(x)
G4double getTransmissionRadius(Particle const *const p) const
The radius used for calculating the transmission coefficient.
G4double pow13(G4double x)
static const G4double alpha
static const G4double b0
std::string getShortName(const ParticleType t)
Get the short INCL name of the particle.
ThreeVector getLongitudinalPosition() const
Longitudinal component of the position w.r.t.
ParticleList::const_iterator ParticleIter
void distortOut(ParticleList const &pL, Nucleus const *const n) const
Modify the momenta of the outgoing particles.