Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4INCLParticleEntryChannel.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// Alain Boudard, CEA-Saclay, France
28// Joseph Cugnon, University of Liege, Belgium
29// Jean-Christophe David, CEA-Saclay, France
30// Pekka Kaitaniemi, CEA-Saclay, France, and Helsinki Institute of Physics, Finland
31// Sylvie Leray, CEA-Saclay, France
32// Davide Mancusi, CEA-Saclay, France
33//
34#define INCLXX_IN_GEANT4_MODE 1
35
36#include "globals.hh"
37
39#include "G4INCLRootFinder.hh"
40#include "G4INCLIntersection.hh"
41#include <algorithm>
42
43namespace G4INCL {
44
46 :theNucleus(n), theParticle(p)
47 {}
48
50 {}
51
53 // Behaves slightly differency if a third body (the projectile) is present
54 G4bool isNN = theNucleus->isNucleusNucleusCollision();
55
56 /* Corrections to the energy of the entering particle
57 *
58 * In particle-nucleus reactions, the goal of this correction is to satisfy
59 * energy conservation in particle-nucleus reactions using real particle
60 * and nuclear masses.
61 *
62 * In nucleus-nucleus reactions, in addition to the above, the correction
63 * is determined by a model for the excitation energy of the
64 * quasi-projectile (QP). The energy of the entering nucleon is such that
65 * the QP excitation energy, as determined by conservation, is what given
66 * by our model.
67 *
68 * Possible choices for the correction (or, equivalently, for the QP
69 * excitation energy):
70 *
71 * 1. the correction is 0. (same as in particle-nucleus);
72 * 2. the correction is the separation energy of the entering nucleon in
73 * the current QP;
74 * 3. the QP excitation energy is given by A. Boudard's algorithm, as
75 * implemented in INCL4.2-HI/Geant4.
76 * 4. the QP excitation energy vanishes.
77 *
78 * Ideally, the QP excitation energy should always be >=0. Algorithms 1.
79 * and 2. do not guarantee this, although violations to the rule seem to be
80 * more severe for 1. than for 2.. Algorithms 3. and 4., by construction,
81 * yields non-negative QP excitation energies.
82 */
83 G4double theCorrection;
84 if(isNN) {
85// assert(theParticle->isNucleonorLambda()); // Possible hypernucleus projectile of inverse kinematic
86 ProjectileRemnant * const projectileRemnant = theNucleus->getProjectileRemnant();
87// assert(projectileRemnant);
88
89 // No correction (model 1. above)
90 /*
91 theCorrection = theParticle->getEmissionQValueCorrection(
92 theNucleus->getA() + theParticle->getA(),
93 theNucleus->getZ() + theParticle->getZ())
94 + theParticle->getTableMass() - theParticle->getINCLMass();
95 const G4double theProjectileCorrection = 0.;
96 */
97
98 // Correct the energy of the entering particle for the Q-value of the
99 // emission from the projectile (model 2. above)
100 /*
101 theCorrection = theParticle->getTransferQValueCorrection(
102 projectileRemnant->getA(), projectileRemnant->getZ(),
103 theNucleus->getA(), theNucleus->getZ());
104 G4double theProjectileCorrection;
105 if(projectileRemnant->getA()>theParticle->getA()) { // if there are any particles left
106 // Compute the projectile Q-value (to be used as a correction to the
107 // other components of the projectile remnant)
108 theProjectileCorrection = ParticleTable::getTableQValue(
109 projectileRemnant->getA() - theParticle->getA(),
110 projectileRemnant->getZ() - theParticle->getZ(),
111 theParticle->getA(),
112 theParticle->getZ());
113 } else
114 theProjectileCorrection = 0.;
115 */
116
117 // Fix the correction in such a way that the quasi-projectile excitation
118 // energy is given by A. Boudard's INCL4.2-HI model (model 3. above).
119 const G4double theProjectileExcitationEnergy =
120 (projectileRemnant->getA()-theParticle->getA()>1) ?
121 (projectileRemnant->computeExcitationEnergyExcept(theParticle->getID())) :
122 0.;
123 // Set the projectile excitation energy to zero (cold quasi-projectile,
124 // model 4. above).
125 // const G4double theProjectileExcitationEnergy = 0.;
126 // The part that follows is common to model 3. and 4.
127 const G4double theProjectileEffectiveMass =
128 ParticleTable::getTableMass(projectileRemnant->getA() - theParticle->getA(), projectileRemnant->getZ() - theParticle->getZ(), projectileRemnant->getS() - theParticle->getS())
129 + theProjectileExcitationEnergy;
130 const ThreeVector &theProjectileMomentum = projectileRemnant->getMomentum() - theParticle->getMomentum();
131 const G4double theProjectileEnergy = std::sqrt(theProjectileMomentum.mag2() + theProjectileEffectiveMass*theProjectileEffectiveMass);
132 const G4double theProjectileCorrection = theProjectileEnergy - (projectileRemnant->getEnergy() - theParticle->getEnergy());
133 theCorrection = theParticle->getEmissionQValueCorrection(
134 theNucleus->getA() + theParticle->getA(),
135 theNucleus->getZ() + theParticle->getZ(),
136 theNucleus->getS() + theParticle->getS())
137 + theParticle->getTableMass() - theParticle->getINCLMass()
138 + theProjectileCorrection;
139 // end of part common to model 3. and 4.
140
141
142 projectileRemnant->removeParticle(theParticle, theProjectileCorrection);
143 } else {
144 const G4int ACN = theNucleus->getA() + theParticle->getA();
145 const G4int ZCN = theNucleus->getZ() + theParticle->getZ();
146 const G4int SCN = theNucleus->getS() + theParticle->getS();
147 // Correction to the Q-value of the entering particle
148 if(theParticle->isKaon()) theCorrection = theParticle->getEmissionQValueCorrection(ACN,ZCN,theNucleus->getS());
149 else theCorrection = theParticle->getEmissionQValueCorrection(ACN,ZCN,SCN);
150 INCL_DEBUG("The following Particle enters with correction " << theCorrection << '\n'
151 << theParticle->print() << '\n');
152 }
153
154 const G4double energyBefore = theParticle->getEnergy() - theCorrection;
155 G4bool success = particleEnters(theCorrection);
156 fs->addEnteringParticle(theParticle);
157
158 if(!success) {
160 } else if(theParticle->isNucleonorLambda() &&
161 theParticle->getKineticEnergy()<theNucleus->getPotential()->getFermiEnergy(theParticle)) {
162 // If the participant is a nucleon entering below its Fermi energy, force a
163 // compound nucleus
165 } else if(theParticle->isKaon()) theNucleus->setNumberOfKaon(theNucleus->getNumberOfKaon()+1);
166
167 fs->setTotalEnergyBeforeInteraction(energyBefore);
168 }
169
170 G4bool ParticleEntryChannel::particleEnters(const G4double theQValueCorrection) {
171
172 // \todo{this is the place to add refraction}
173
174 theParticle->setINCLMass(); // Will automatically put the particle on shell
175
176 // Add the nuclear potential to the kinetic energy when entering the
177 // nucleus
178
179 class IncomingEFunctor : public RootFunctor {
180 public:
181 IncomingEFunctor(Particle * const p, Nucleus const * const n, const G4double correction) :
182 RootFunctor(0., 1E6),
183 theParticle(p),
184 thePotential(n->getPotential()),
185 theEnergy(theParticle->getEnergy()),
186 theMass(theParticle->getMass()),
187 theQValueCorrection(correction),
188 refraction(n->getStore()->getConfig()->getRefraction()),
189 theMomentumDirection(theParticle->getMomentum())
190 {
191 if(refraction) {
192 const ThreeVector &position = theParticle->getPosition();
193 const G4double r2 = position.mag2();
194 if(r2>0.)
195 normal = - position / std::sqrt(r2);
196 G4double cosIncidenceAngle = theParticle->getCosRPAngle();
197 if(cosIncidenceAngle < -1.)
198 sinIncidenceAnglePOut = 0.;
199 else
200 sinIncidenceAnglePOut = theMomentumDirection.mag()*std::sqrt(1.-cosIncidenceAngle*cosIncidenceAngle);
201 } else {
202 sinIncidenceAnglePOut = 0.;
203 }
204 }
205 ~IncomingEFunctor() {}
206 G4double operator()(const G4double v) const {
207 G4double energyInside = std::max(theMass, theEnergy + v - theQValueCorrection);
208 theParticle->setEnergy(energyInside);
209 theParticle->setPotentialEnergy(v);
210 if(refraction) {
211 // Compute the new direction of the particle momentum
212 const G4double pIn = std::sqrt(energyInside*energyInside-theMass*theMass);
213 const G4double sinRefractionAngle = sinIncidenceAnglePOut/pIn;
214 const G4double cosRefractionAngle = (sinRefractionAngle>1.) ? 0. : std::sqrt(1.-sinRefractionAngle*sinRefractionAngle);
215 const ThreeVector momentumInside = theMomentumDirection - normal * normal.dot(theMomentumDirection) + normal * (pIn * cosRefractionAngle);
216 theParticle->setMomentum(momentumInside);
217 } else {
218 theParticle->setMomentum(theMomentumDirection); // keep the same direction
219 }
220 // Scale the particle momentum
221 theParticle->adjustMomentumFromEnergy();
222 return v - thePotential->computePotentialEnergy(theParticle);
223 }
224 void cleanUp(const G4bool /*success*/) const {}
225 private:
226 Particle *theParticle;
227 NuclearPotential::INuclearPotential const *thePotential;
228 const G4double theEnergy;
229 const G4double theMass;
230 const G4double theQValueCorrection;
231 const G4bool refraction;
232 const ThreeVector theMomentumDirection;
233 ThreeVector normal;
234 G4double sinIncidenceAnglePOut;
235 } theIncomingEFunctor(theParticle,theNucleus,theQValueCorrection);
236
237 G4double v = theNucleus->getPotential()->computePotentialEnergy(theParticle);
238 if(theParticle->getKineticEnergy()+v-theQValueCorrection<0.) { // Particle entering below 0. Die gracefully
239 INCL_DEBUG("Particle " << theParticle->getID() << " is trying to enter below 0" << '\n');
240 return false;
241 }
242 const RootFinder::Solution theSolution = RootFinder::solve(&theIncomingEFunctor, v);
243 if(theSolution.success) { // Apply the solution
244 theIncomingEFunctor(theSolution.x);
245 INCL_DEBUG("Particle successfully entered:\n" << theParticle->print() << '\n');
246 } else {
247 INCL_WARN("Couldn't compute the potential for incoming particle, root-finding algorithm failed." << '\n');
248 }
249 return theSolution.success;
250 }
251
252}
253
Simple class for computing intersections between a straight line and a sphere.
#define INCL_WARN(x)
#define INCL_DEBUG(x)
Static root-finder algorithm.
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
void addEnteringParticle(Particle *p)
void setTotalEnergyBeforeInteraction(G4double E)
virtual G4double computePotentialEnergy(const Particle *const p) const =0
G4double getFermiEnergy(const Particle *const p) const
Return the Fermi energy for a particle.
ProjectileRemnant * getProjectileRemnant() const
Get the projectile remnant.
G4bool isNucleusNucleusCollision() const
Is it a nucleus-nucleus collision?
NuclearPotential::INuclearPotential const * getPotential() const
Getter for thePotential.
ParticleEntryChannel(Nucleus *n, Particle *p)
G4double getINCLMass() const
Get the INCL particle mass.
G4int getS() const
Returns the strangeness number.
G4double getEmissionQValueCorrection(const G4int AParent, const G4int ZParent) const
Computes correction on the emission Q-value.
void setNumberOfKaon(const G4int NK)
G4double getEnergy() const
G4bool isNucleonorLambda() const
Is this a Nucleon or a Lambda?
G4int getZ() const
Returns the charge number.
G4double getKineticEnergy() const
Get the particle kinetic energy.
void setINCLMass()
Set the mass of the Particle to its table mass.
const G4INCL::ThreeVector & getMomentum() const
G4bool isKaon() const
Is this a Kaon?
G4int getNumberOfKaon() const
Number of Kaon inside de nucleus.
virtual G4double getTableMass() const
Get the tabulated particle mass.
std::string print() const
long getID() const
G4int getA() const
Returns the baryon number.
void removeParticle(Particle *const p, const G4double theProjectileCorrection)
Remove a nucleon from the projectile remnant.
G4double computeExcitationEnergyExcept(const long exceptID) const
Compute the excitation energy when a nucleon is removed.
G4double mag2() const
G4ThreadLocal NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
Solution solve(RootFunctor const *const f, const G4double x0)
Numerically solve a one-dimensional equation.