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