Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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// INCL++ revision: v5.1.8
34//
35#define INCLXX_IN_GEANT4_MODE 1
36
37#include "globals.hh"
38
39/** \file G4INCLCoulombNonRelativistic.cc
40 * \brief Class for non-relativistic Coulomb distortion.
41 *
42 * \date 14 February 2011
43 * \author Davide Mancusi
44 */
45
47#include "G4INCLGlobals.hh"
48
49namespace G4INCL {
50
52 // No distortion for neutral particles
53 if(p->getZ()!=0) {
54 const G4bool success = coulombDeviation(p, n);
55 if(!success) // transparent
56 return NULL;
57 }
58
59 // Rely on the CoulombNone slave to compute the straight-line intersection
60 // and actually bring the particle to the surface of the nucleus
61 return theCoulombNoneSlave.bringToSurface(p,n);
62 }
63
65 // Neutral clusters?!
66// assert(c->getZ()>0);
67
68 // Perform the actual Coulomb deviation
69 const G4bool success = coulombDeviation(c, n);
70 if(!success) {
71 return IAvatarList();
72 }
73
74 // Rely on the CoulombNone slave to compute the straight-line intersection
75 // and actually bring the particle to the surface of the nucleus
76 return theCoulombNoneSlave.bringToSurface(c,n);
77 }
78
80 Nucleus const * const nucleus) const {
81
82 for(ParticleIter particle=pL.begin(); particle!=pL.end(); ++particle) {
83
84 const G4int Z = (*particle)->getZ();
85 if(Z == 0) continue;
86
87 const G4double tcos=1.-0.000001;
88
89 const G4double et1 = PhysicalConstants::eSquared * nucleus->getZ();
90 const G4double transmissionRadius =
91 nucleus->getDensity()->getTransmissionRadius(*particle);
92
93 const ThreeVector position = (*particle)->getPosition();
94 ThreeVector momentum = (*particle)->getMomentum();
95 const G4double r = position.mag();
96 const G4double p = momentum.mag();
97 const G4double cosTheta = position.dot(momentum)/(r*p);
98 if(cosTheta < 0.999999) {
99 const G4double sinTheta = std::sqrt(1.-cosTheta*cosTheta);
100 const G4double eta = et1 * Z / (*particle)->getKineticEnergy();
101 if(eta > transmissionRadius-0.0001) {
102 // If below the Coulomb barrier, radial emission:
103 momentum = position * (p/r);
104 (*particle)->setMomentum(momentum);
105 } else {
106 const G4double b0 = 0.5 * (eta + std::sqrt(eta*eta +
107 4. * std::pow(transmissionRadius*sinTheta,2)
108 * (1.-eta/transmissionRadius)));
109 const G4double bInf = std::sqrt(b0*(b0-eta));
110 const G4double thr = std::atan(eta/(2.*bInf));
111 G4double uTemp = (1.-b0/transmissionRadius) * std::sin(thr) +
112 b0/transmissionRadius;
113 if(uTemp>tcos) uTemp=tcos;
114 const G4double thd = std::acos(cosTheta)-Math::piOverTwo + thr +
115 std::acos(uTemp);
116 const G4double c1 = std::sin(thd)*cosTheta/sinTheta + std::cos(thd);
117 const G4double c2 = -p*std::sin(thd)/(r*sinTheta);
118 const ThreeVector newMomentum = momentum*c1 + position*c2;
119 (*particle)->setMomentum(newMomentum);
120 }
121 }
122 }
123 }
124
126 Nucleus const * const n) const {
127 G4double theMaxImpactParameter = maxImpactParameterParticle(p, kinE, n);
128 if(theMaxImpactParameter <= 0.)
129 return 0.;
130 if(p.theType == Composite)
131 theMaxImpactParameter += 2.*ParticleTable::getNuclearRadius(p.theA, p.theZ);
132 return theMaxImpactParameter;
133 }
134
135 G4double CoulombNonRelativistic::maxImpactParameterParticle(ParticleSpecies const &p, const G4double kinE,
136 Nucleus const * const n) const {
137 const G4double theMinimumDistance = minimumDistance(p, kinE, n);
138 const G4double rMax = n->getCoulombRadius(p);
139 const G4double theMaxImpactParameterSquared = rMax*(rMax-theMinimumDistance);
140 if(theMaxImpactParameterSquared<=0.)
141 return 0.;
142 G4double theMaxImpactParameter = std::sqrt(theMaxImpactParameterSquared);
143 return theMaxImpactParameter;
144 }
145
146 G4bool CoulombNonRelativistic::coulombDeviation(Particle * const p, Nucleus const * const n) const {
147 // Determine the rotation angle and the new impact parameter
148 ThreeVector positionTransverse = p->getTransversePosition();
149 const G4double impactParameter = positionTransverse.mag();
150
151 // Some useful variables
152 const G4double theMinimumDistance = minimumDistance(p, n);
153 // deltaTheta2 = (pi - Rutherford scattering angle)/2
154 const G4double deltaTheta2 = std::atan(2.*impactParameter/theMinimumDistance);
155 const G4double eccentricity = 1./std::cos(deltaTheta2);
156
157 G4double newImpactParameter, alpha; // Parameters that must be determined by the deviation
158
159 ParticleSpecies aSpecies = p->getSpecies();
160 G4double kineticEnergy = p->getKineticEnergy();
161 // Note that in the following call to maxImpactParameter we are not
162 // interested in the size of the cluster. This is why we call
163 // maxImpactParameterParticle.
164 if(impactParameter>maxImpactParameterParticle(aSpecies, kineticEnergy, n)) {
165 // This should happen only for composite particles, whose trajectory can
166 // geometrically miss the nucleus but still trigger a cascade because of
167 // the finite extension of the projectile.
168 // In this case, the sphere radius is the minimum distance of approach
169 // and the kinematics is very simple.
170 newImpactParameter = 0.5 * theMinimumDistance * (1.+eccentricity); // the minimum distance of approach
171 alpha = Math::piOverTwo - deltaTheta2; // half the Rutherford scattering angle
172 } else {
173 // The particle trajectory intersects the Coulomb sphere
174
175 // Compute the entrance angle
176 const G4double radius = n->getCoulombRadius(p->getSpecies());
177 G4double argument = -(1. + 2.*impactParameter*impactParameter/(radius*theMinimumDistance))
178 / eccentricity;
179 const G4double thetaIn = Math::twoPi - std::acos(argument) - deltaTheta2;
180
181 // Velocity angle at the entrance point
182 alpha = std::atan((1+std::cos(thetaIn))
183 / (std::sqrt(eccentricity*eccentricity-1.) - std::sin(thetaIn)));
184 // New impact parameter
185 newImpactParameter = radius * std::sin(thetaIn - alpha);
186 }
187
188 // Modify the impact parameter of the particle
189 positionTransverse *= newImpactParameter/positionTransverse.mag();
190 const ThreeVector theNewPosition = p->getLongitudinalPosition() + positionTransverse;
191 p->setPosition(theNewPosition);
192
193 // Determine the rotation axis for the incoming particle
194 const ThreeVector &momentum = p->getMomentum();
195 ThreeVector rotationAxis = momentum.vector(positionTransverse);
196 const G4double axisLength = rotationAxis.mag();
197 // Apply the rotation
198 if(axisLength>1E-20) {
199 rotationAxis /= axisLength;
200 p->rotate(alpha, rotationAxis);
201 }
202
203 return true;
204 }
205
206}
Class for non-relativistic Coulomb distortion.
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
void distortOut(ParticleList const &pL, Nucleus const *const n) const
Modify the momenta of the outgoing particles.
G4double maxImpactParameter(ParticleSpecies const &p, const G4double kinE, Nucleus const *const n) const
Return the maximum impact parameter for Coulomb-distorted trajectories.
ParticleEntryAvatar * bringToSurface(Particle *const p, Nucleus *const n) const
Modify the momentum of the particle and position it on the surface of the nucleus.
ParticleEntryAvatar * bringToSurface(Particle *const p, Nucleus *const n) const
Position the particle on the surface of the nucleus.
G4double getTransmissionRadius(Particle const *const p) const
The radius used for calculating the transmission coefficient.
NuclearDensity * getDensity() const
Getter for theDensity.
static G4double getNuclearRadius(const G4int A, const G4int Z)
G4int getZ() const
Returns the charge number.
G4double mag() const
const G4double twoPi
const G4double piOverTwo
const G4double eSquared
Coulomb conversion factor [MeV*fm].
std::list< IAvatar * > IAvatarList
std::list< G4INCL::Particle * > ParticleList
std::list< G4INCL::Particle * >::const_iterator ParticleIter