Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/inclxx/incl_physics/src/G4INCLProjectileRemnant.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/hadronic/models/inclxx/incl_physics/src/G4INCLProjectileRemnant.cc (Version 11.3.0) and /processes/hadronic/models/inclxx/incl_physics/src/G4INCLProjectileRemnant.cc (Version 10.0.p1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // INCL++ intra-nuclear cascade model              26 // INCL++ intra-nuclear cascade model
 27 // Alain Boudard, CEA-Saclay, France           <<  27 // Pekka Kaitaniemi, CEA and Helsinki Institute of Physics
 28 // Joseph Cugnon, University of Liege, Belgium <<  28 // Davide Mancusi, CEA
 29 // Jean-Christophe David, CEA-Saclay, France   <<  29 // Alain Boudard, CEA
 30 // Pekka Kaitaniemi, CEA-Saclay, France, and H <<  30 // Sylvie Leray, CEA
 31 // Sylvie Leray, CEA-Saclay, France            <<  31 // Joseph Cugnon, University of Liege
 32 // Davide Mancusi, CEA-Saclay, France          << 
 33 //                                                 32 //
 34 #define INCLXX_IN_GEANT4_MODE 1                    33 #define INCLXX_IN_GEANT4_MODE 1
 35                                                    34 
 36 #include "globals.hh"                              35 #include "globals.hh"
 37                                                    36 
 38 /** \file G4INCLProjectileRemnant.cc               37 /** \file G4INCLProjectileRemnant.cc
 39  * \brief Class for constructing a projectile-     38  * \brief Class for constructing a projectile-like remnant.
 40  *                                                 39  *
 41  * \date 20 March 2012                             40  * \date 20 March 2012
 42  * \author Davide Mancusi                          41  * \author Davide Mancusi
 43  */                                                42  */
 44                                                    43 
 45 #include "G4INCLProjectileRemnant.hh"              44 #include "G4INCLProjectileRemnant.hh"
 46 #include <algorithm>                               45 #include <algorithm>
 47 #include <numeric>                                 46 #include <numeric>
 48                                                    47 
 49 namespace G4INCL {                                 48 namespace G4INCL {
 50                                                    49 
                                                   >>  50   G4int shuffleComponentsHelper(G4int range) {
                                                   >>  51     return (G4int)(Random::shoot1()*range);
                                                   >>  52   }
                                                   >>  53 
 51   void ProjectileRemnant::reset() {                54   void ProjectileRemnant::reset() {
 52     deleteParticles();                             55     deleteParticles();
 53     thePosition = ThreeVector();                   56     thePosition = ThreeVector();
 54     theMomentum = ThreeVector();                   57     theMomentum = ThreeVector();
 55     theEnergy = 0.0;                               58     theEnergy = 0.0;
 56     thePotentialEnergy = 0.0;                      59     thePotentialEnergy = 0.0;
 57     theA = 0;                                      60     theA = 0;
 58     theZ = 0;                                      61     theZ = 0;
 59     nCollisions = 0;                               62     nCollisions = 0;
 60                                                    63 
 61     for(std::map<long, Particle*>::const_itera     64     for(std::map<long, Particle*>::const_iterator i=storedComponents.begin(); i!=storedComponents.end(); ++i) {
 62       Particle *p = new Particle(*(i->second))     65       Particle *p = new Particle(*(i->second));
 63       EnergyLevelMap::iterator energyIter = th     66       EnergyLevelMap::iterator energyIter = theInitialEnergyLevels.find(i->first);
 64 // assert(energyIter!=theInitialEnergyLevels.e     67 // assert(energyIter!=theInitialEnergyLevels.end());
 65       const G4double energyLevel = energyIter-     68       const G4double energyLevel = energyIter->second;
 66       theInitialEnergyLevels.erase(energyIter)     69       theInitialEnergyLevels.erase(energyIter);
 67       theInitialEnergyLevels[p->getID()] = ene     70       theInitialEnergyLevels[p->getID()] = energyLevel;
 68       addParticle(p);                              71       addParticle(p);
 69     }                                              72     }
 70     if(theA>0)                                 <<  73     thePosition /= theA;
 71       thePosition /= theA;                     << 
 72     setTableMass();                                74     setTableMass();
 73     INCL_DEBUG("ProjectileRemnant object was r <<  75     INCL_DEBUG("ProjectileRemnant object was reset:" << std::endl << print());
 74   }                                                76   }
 75                                                    77 
 76   void ProjectileRemnant::removeParticle(Parti     78   void ProjectileRemnant::removeParticle(Particle * const p, const G4double theProjectileCorrection) {
 77 // assert(p->isNucleon() || p->isLambda());    <<  79 // assert(p->isNucleon());
 78                                                    80 
 79     INCL_DEBUG("The following Particle is abou     81     INCL_DEBUG("The following Particle is about to be removed from the ProjectileRemnant:"
 80         << '\n' << p->print()                  <<  82         << std::endl << p->print()
 81         << "theProjectileCorrection=" << thePr <<  83         << "theProjectileCorrection=" << theProjectileCorrection << std::endl);
 82     // Update A, Z, S, momentum, and energy of <<  84     // Update A, Z, momentum and energy of the projectile remnant
 83     theA -= p->getA();                             85     theA -= p->getA();
 84     theZ -= p->getZ();                             86     theZ -= p->getZ();
 85     theS -= p->getS();                         << 
 86                                                    87 
 87     ThreeVector const &oldMomentum = p->getMom     88     ThreeVector const &oldMomentum = p->getMomentum();
 88     const G4double oldEnergy = p->getEnergy();     89     const G4double oldEnergy = p->getEnergy();
 89     Cluster::removeParticle(p);                    90     Cluster::removeParticle(p);
 90                                                    91 
 91 #if !defined(NDEBUG) && !defined(INCLXX_IN_GEA     92 #if !defined(NDEBUG) && !defined(INCLXX_IN_GEANT4_MODE)
 92     ThreeVector theTotalMomentum;                  93     ThreeVector theTotalMomentum;
 93     G4double theTotalEnergy = 0.;                  94     G4double theTotalEnergy = 0.;
 94     const G4double theThreshold = 0.1;             95     const G4double theThreshold = 0.1;
 95 #endif                                             96 #endif
 96                                                    97 
 97     if(getA()>0) { // if there are any particl     98     if(getA()>0) { // if there are any particles left
 98 // assert((unsigned int)getA()==particles.size     99 // assert((unsigned int)getA()==particles.size());
 99                                                   100 
100       const G4double theProjectileCorrectionPe    101       const G4double theProjectileCorrectionPerNucleon = theProjectileCorrection / particles.size();
101                                                   102 
102       // Update the kinematics of the componen    103       // Update the kinematics of the components
103       for(ParticleIter i=particles.begin(), e=    104       for(ParticleIter i=particles.begin(), e=particles.end(); i!=e; ++i) {
104         (*i)->setEnergy((*i)->getEnergy() + th    105         (*i)->setEnergy((*i)->getEnergy() + theProjectileCorrectionPerNucleon);
105         (*i)->setMass((*i)->getInvariantMass()    106         (*i)->setMass((*i)->getInvariantMass());
106 #if !defined(NDEBUG) && !defined(INCLXX_IN_GEA    107 #if !defined(NDEBUG) && !defined(INCLXX_IN_GEANT4_MODE)
107         theTotalMomentum += (*i)->getMomentum(    108         theTotalMomentum += (*i)->getMomentum();
108         theTotalEnergy += (*i)->getEnergy();      109         theTotalEnergy += (*i)->getEnergy();
109 #endif                                            110 #endif
110       }                                           111       }
111     }                                             112     }
112                                                   113 
113     theMomentum -= oldMomentum;                   114     theMomentum -= oldMomentum;
114     theEnergy -= oldEnergy - theProjectileCorr    115     theEnergy -= oldEnergy - theProjectileCorrection;
115                                                   116 
116 // assert(std::abs((theTotalMomentum-theMoment    117 // assert(std::abs((theTotalMomentum-theMomentum).mag())<theThreshold);
117 // assert(std::abs(theTotalEnergy-theEnergy)<t    118 // assert(std::abs(theTotalEnergy-theEnergy)<theThreshold);
118     INCL_DEBUG("After Particle removal, the Pr    119     INCL_DEBUG("After Particle removal, the ProjectileRemnant looks like this:"
119         << '\n' << print());                   << 120         << std::endl << print());
120   }                                               121   }
121                                                   122 
122   ParticleList ProjectileRemnant::addDynamical    123   ParticleList ProjectileRemnant::addDynamicalSpectators(ParticleList pL) {
123     // Try as hard as possible to add back all    124     // Try as hard as possible to add back all the dynamical spectators.
124     // Don't add spectators that lead to negat    125     // Don't add spectators that lead to negative excitation energies, but
125     // iterate over the spectators as many tim    126     // iterate over the spectators as many times as possible, until
126     // absolutely sure that all of them were r    127     // absolutely sure that all of them were rejected.
127     unsigned int accepted;                        128     unsigned int accepted;
128     unsigned long loopCounter = 0;             << 
129     const unsigned long maxLoopCounter = 10000 << 
130     do {                                          129     do {
131       accepted = 0;                               130       accepted = 0;
132       ParticleList toBeAdded = pL;                131       ParticleList toBeAdded = pL;
133       for(ParticleIter p=toBeAdded.begin(), e=    132       for(ParticleIter p=toBeAdded.begin(), e=toBeAdded.end(); p!=e; ++p) {
134         G4bool isAccepted = addDynamicalSpecta    133         G4bool isAccepted = addDynamicalSpectator(*p);
135         if(isAccepted) {                          134         if(isAccepted) {
136           pL.remove(*p);                          135           pL.remove(*p);
137           accepted++;                             136           accepted++;
138         }                                         137         }
139       }                                           138       }
140       ++loopCounter;                           << 139     } while(accepted > 0);
141     } while(loopCounter<maxLoopCounter && acce << 
142     return pL;                                    140     return pL;
143   }                                               141   }
144                                                   142 
145   ParticleList ProjectileRemnant::addAllDynami << 143   ParticleList ProjectileRemnant::addAllDynamicalSpectators(ParticleList pL) {
146     // Put all the spectators in the projectil    144     // Put all the spectators in the projectile
147     ThreeVector theNewMomentum = theMomentum;     145     ThreeVector theNewMomentum = theMomentum;
148     G4double theNewEnergy = theEnergy;            146     G4double theNewEnergy = theEnergy;
149     G4int theNewA = theA;                         147     G4int theNewA = theA;
150     G4int theNewZ = theZ;                         148     G4int theNewZ = theZ;
151     G4int theNewS = theS;                      << 
152     for(ParticleIter p=pL.begin(), e=pL.end();    149     for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p) {
153 // assert((*p)->isNucleonorLambda());          << 150 // assert((*p)->isNucleon());
154       // Add the initial (off-shell) momentum     151       // Add the initial (off-shell) momentum and energy to the projectile remnant
155       theNewMomentum += getStoredMomentum(*p);    152       theNewMomentum += getStoredMomentum(*p);
156       theNewEnergy += (*p)->getEnergy();          153       theNewEnergy += (*p)->getEnergy();
157       theNewA += (*p)->getA();                    154       theNewA += (*p)->getA();
158       theNewZ += (*p)->getZ();                    155       theNewZ += (*p)->getZ();
159       theNewS += (*p)->getS();                 << 
160     }                                             156     }
161                                                   157 
162     // Check that the excitation energy of the    158     // Check that the excitation energy of the new projectile remnant is non-negative
163     const G4double theNewMass = ParticleTable: << 159     const G4double theNewMass = ParticleTable::getTableMass(theNewA,theNewZ);
164     const G4double theNewExcitationEnergy = co    160     const G4double theNewExcitationEnergy = computeExcitationEnergyWith(pL);
165     const G4double theNewEffectiveMass = theNe    161     const G4double theNewEffectiveMass = theNewMass + theNewExcitationEnergy;
166                                                   162 
167     // If this condition is satisfied, there i    163     // If this condition is satisfied, there is no solution. Fall back on the
168     // "most" method                              164     // "most" method
169     if(theNewEnergy<theNewEffectiveMass) {        165     if(theNewEnergy<theNewEffectiveMass) {
170       INCL_WARN("Could not add all the dynamic    166       INCL_WARN("Could not add all the dynamical spectators back into the projectile remnant."
171            << " Falling back to the \"most\" m << 167            << " Falling back to the \"most\" method." << std::endl);
172       return addMostDynamicalSpectators(pL);      168       return addMostDynamicalSpectators(pL);
173     }                                             169     }
174                                                   170 
175     // Add all the participants to the project    171     // Add all the participants to the projectile remnant
176     for(ParticleIter p=pL.begin(), e=pL.end();    172     for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p) {
177       particles.push_back(*p);                    173       particles.push_back(*p);
178     }                                             174     }
179                                                   175 
180     // Rescale the momentum of the projectile     176     // Rescale the momentum of the projectile remnant so that sqrt(s) has the
181     // correct value                              177     // correct value
182     const G4double scalingFactorSquared = (the    178     const G4double scalingFactorSquared = (theNewEnergy*theNewEnergy-theNewEffectiveMass*theNewEffectiveMass)/theNewMomentum.mag2();
183     const G4double scalingFactor = std::sqrt(s    179     const G4double scalingFactor = std::sqrt(scalingFactorSquared);
184     INCL_DEBUG("Scaling factor for the project << 180     INCL_DEBUG("Scaling factor for the projectile-remnant momentum = " << scalingFactor << std::endl);
185                                                   181 
186     theA = theNewA;                               182     theA = theNewA;
187     theZ = theNewZ;                               183     theZ = theNewZ;
188     theS = theNewS;                            << 
189     theMomentum = theNewMomentum * scalingFact    184     theMomentum = theNewMomentum * scalingFactor;
190     theEnergy = theNewEnergy;                     185     theEnergy = theNewEnergy;
191                                                   186 
192     return ParticleList();                        187     return ParticleList();
193   }                                               188   }
194                                                   189 
195   ParticleList ProjectileRemnant::addMostDynam    190   ParticleList ProjectileRemnant::addMostDynamicalSpectators(ParticleList pL) {
196     // Try as hard as possible to add back all    191     // Try as hard as possible to add back all the dynamical spectators.
197     // Don't add spectators that lead to negat    192     // Don't add spectators that lead to negative excitation energies. Start by
198     // adding all of them, and repeatedly remo    193     // adding all of them, and repeatedly remove the most troublesome one until
199     // the excitation energy becomes non-negat    194     // the excitation energy becomes non-negative.
200                                                   195 
201     // Put all the spectators in the projectil    196     // Put all the spectators in the projectile
202     ThreeVector theNewMomentum = theMomentum;     197     ThreeVector theNewMomentum = theMomentum;
203     G4double theNewEnergy = theEnergy;            198     G4double theNewEnergy = theEnergy;
204     G4int theNewA = theA;                         199     G4int theNewA = theA;
205     G4int theNewZ = theZ;                         200     G4int theNewZ = theZ;
206     G4int theNewS = theS;                      << 
207     for(ParticleIter p=pL.begin(), e=pL.end();    201     for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p) {
208 // assert((*p)->isNucleonorLambda());          << 202 // assert((*p)->isNucleon());
209       // Add the initial (off-shell) momentum     203       // Add the initial (off-shell) momentum and energy to the projectile remnant
210       theNewMomentum += getStoredMomentum(*p);    204       theNewMomentum += getStoredMomentum(*p);
211       theNewEnergy += (*p)->getEnergy();          205       theNewEnergy += (*p)->getEnergy();
212       theNewA += (*p)->getA();                    206       theNewA += (*p)->getA();
213       theNewZ += (*p)->getZ();                    207       theNewZ += (*p)->getZ();
214       theNewS += (*p)->getS();                 << 
215     }                                             208     }
216                                                   209 
217     // Check that the excitation energy of the    210     // Check that the excitation energy of the new projectile remnant is non-negative
218     const G4double theNewMass = ParticleTable: << 211     const G4double theNewMass = ParticleTable::getTableMass(theNewA,theNewZ);
219     const G4double theNewInvariantMassSquared     212     const G4double theNewInvariantMassSquared = theNewEnergy*theNewEnergy-theNewMomentum.mag2();
220                                                   213 
221     G4bool positiveExcitationEnergy = false;      214     G4bool positiveExcitationEnergy = false;
222     if(theNewInvariantMassSquared>=0.) {          215     if(theNewInvariantMassSquared>=0.) {
223       const G4double theNewInvariantMass = std    216       const G4double theNewInvariantMass = std::sqrt(theNewInvariantMassSquared);
224       positiveExcitationEnergy = (theNewInvari    217       positiveExcitationEnergy = (theNewInvariantMass-theNewMass>-1.e-5);
225     }                                             218     }
226                                                   219 
227     // Keep removing nucleons from the project    220     // Keep removing nucleons from the projectile remnant until we achieve a
228     // non-negative excitation energy.            221     // non-negative excitation energy.
229     ParticleList rejected;                        222     ParticleList rejected;
230     while(!positiveExcitationEnergy && !pL.emp << 223     while(!positiveExcitationEnergy && !pL.empty()) {
231       G4double maxExcitationEnergy = -1.E30;      224       G4double maxExcitationEnergy = -1.E30;
232       ParticleMutableIter best = pL.end();        225       ParticleMutableIter best = pL.end();
233       ThreeVector bestMomentum;                   226       ThreeVector bestMomentum;
234       G4double bestEnergy = -1.;                  227       G4double bestEnergy = -1.;
235       G4int bestA = -1, bestZ = -1, bestS = 0; << 228       G4int bestA = -1, bestZ = -1;
236       for(ParticleList::iterator p=pL.begin(),    229       for(ParticleList::iterator p=pL.begin(), e=pL.end(); p!=e; ++p) {
237         // Subtract the initial (off-shell) mo    230         // Subtract the initial (off-shell) momentum and energy from the new
238         // projectile remnant                     231         // projectile remnant
239         const ThreeVector theNewerMomentum = t    232         const ThreeVector theNewerMomentum = theNewMomentum - getStoredMomentum(*p);
240         const G4double theNewerEnergy = theNew    233         const G4double theNewerEnergy = theNewEnergy - (*p)->getEnergy();
241         const G4int theNewerA = theNewA - (*p)    234         const G4int theNewerA = theNewA - (*p)->getA();
242         const G4int theNewerZ = theNewZ - (*p)    235         const G4int theNewerZ = theNewZ - (*p)->getZ();
243         const G4int theNewerS = theNewS - (*p) << 
244                                                   236 
245         const G4double theNewerMass = Particle << 237         const G4double theNewerMass = ParticleTable::getTableMass(theNewerA,theNewerZ);
246         const G4double theNewerInvariantMassSq    238         const G4double theNewerInvariantMassSquared = theNewerEnergy*theNewerEnergy-theNewerMomentum.mag2();
247                                                   239 
248         if(theNewerInvariantMassSquared>=-1.e-    240         if(theNewerInvariantMassSquared>=-1.e-5) {
249           const G4double theNewerInvariantMass    241           const G4double theNewerInvariantMass = std::sqrt(std::max(0.,theNewerInvariantMassSquared));
250           const G4double theNewerExcitationEne    242           const G4double theNewerExcitationEnergy = ((theNewerA>1) ? theNewerInvariantMass-theNewerMass : 0.);
251           // Pick the nucleon that maximises t    243           // Pick the nucleon that maximises the excitation energy of the
252           // ProjectileRemnant                    244           // ProjectileRemnant
253           if(theNewerExcitationEnergy>maxExcit    245           if(theNewerExcitationEnergy>maxExcitationEnergy) {
254             best = p;                             246             best = p;
255             maxExcitationEnergy = theNewerExci    247             maxExcitationEnergy = theNewerExcitationEnergy;
256             bestMomentum = theNewerMomentum;      248             bestMomentum = theNewerMomentum;
257             bestEnergy = theNewerEnergy;          249             bestEnergy = theNewerEnergy;
258             bestA = theNewerA;                    250             bestA = theNewerA;
259             bestZ = theNewerZ;                    251             bestZ = theNewerZ;
260             bestS = theNewerS;                 << 
261           }                                       252           }
262         }                                         253         }
263       }                                           254       }
264                                                   255 
265       // If we couldn't even calculate the exc    256       // If we couldn't even calculate the excitation energy, fail miserably
266       if(best==pL.end())                          257       if(best==pL.end())
267         return pL;                                258         return pL;
268                                                   259 
269       rejected.push_back(*best);                  260       rejected.push_back(*best);
270       pL.erase(best);                             261       pL.erase(best);
271       theNewMomentum = bestMomentum;              262       theNewMomentum = bestMomentum;
272       theNewEnergy = bestEnergy;                  263       theNewEnergy = bestEnergy;
273       theNewA = bestA;                            264       theNewA = bestA;
274       theNewZ = bestZ;                            265       theNewZ = bestZ;
275       theNewS = bestS;                         << 
276                                                   266 
277       if(maxExcitationEnergy>0.) {                267       if(maxExcitationEnergy>0.) {
278         // Stop here                              268         // Stop here
279         positiveExcitationEnergy = true;          269         positiveExcitationEnergy = true;
280       }                                           270       }
281     }                                             271     }
282                                                   272 
283     // Add the accepted participants to the pr    273     // Add the accepted participants to the projectile remnant
284     for(ParticleIter p=pL.begin(), e=pL.end();    274     for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p) {
285       particles.push_back(*p);                    275       particles.push_back(*p);
286     }                                             276     }
287     theA = theNewA;                               277     theA = theNewA;
288     theZ = theNewZ;                               278     theZ = theNewZ;
289     theS = theNewS;                            << 
290     theMomentum = theNewMomentum;                 279     theMomentum = theNewMomentum;
291     theEnergy = theNewEnergy;                     280     theEnergy = theNewEnergy;
292                                                   281 
293     return rejected;                              282     return rejected;
294   }                                               283   }
295                                                   284 
296   G4bool ProjectileRemnant::addDynamicalSpecta    285   G4bool ProjectileRemnant::addDynamicalSpectator(Particle * const p) {
297 // assert(p->isNucleon());                        286 // assert(p->isNucleon());
298                                                   287 
299     // Add the initial (off-shell) momentum an    288     // Add the initial (off-shell) momentum and energy to the projectile remnant
300     ThreeVector const &oldMomentum = getStored    289     ThreeVector const &oldMomentum = getStoredMomentum(p);
301     const ThreeVector theNewMomentum = theMome    290     const ThreeVector theNewMomentum = theMomentum + oldMomentum;
302     const G4double oldEnergy = p->getEnergy();    291     const G4double oldEnergy = p->getEnergy();
303     const G4double theNewEnergy = theEnergy +     292     const G4double theNewEnergy = theEnergy + oldEnergy;
304                                                   293 
305     // Check that the excitation energy of the    294     // Check that the excitation energy of the new projectile remnant is non-negative
306     const G4double theNewMass = ParticleTable: << 295     const G4double theNewMass = ParticleTable::getTableMass(theA+p->getA(),theZ+p->getZ());
307     const G4double theNewInvariantMassSquared     296     const G4double theNewInvariantMassSquared = theNewEnergy*theNewEnergy-theNewMomentum.mag2();
308                                                   297 
309     if(theNewInvariantMassSquared<0.)             298     if(theNewInvariantMassSquared<0.)
310       return false;                               299       return false;
311                                                   300 
312     const G4double theNewInvariantMass = std::    301     const G4double theNewInvariantMass = std::sqrt(theNewInvariantMassSquared);
313                                                   302 
314     if(theNewInvariantMass-theNewMass<-1.e-5)     303     if(theNewInvariantMass-theNewMass<-1.e-5)
315       return false; // negative excitation ene    304       return false; // negative excitation energy here
316                                                   305 
317     // Add the spectator to the projectile rem    306     // Add the spectator to the projectile remnant
318     theA += p->getA();                            307     theA += p->getA();
319     theZ += p->getZ();                            308     theZ += p->getZ();
320     theMomentum = theNewMomentum;                 309     theMomentum = theNewMomentum;
321     theEnergy = theNewEnergy;                     310     theEnergy = theNewEnergy;
322     particles.push_back(p);                       311     particles.push_back(p);
323     return true;                                  312     return true;
324   }                                               313   }
325                                                   314 
326   G4double ProjectileRemnant::computeExcitatio    315   G4double ProjectileRemnant::computeExcitationEnergyExcept(const long exceptID) const {
327     const EnergyLevels theEnergyLevels = getPr    316     const EnergyLevels theEnergyLevels = getPresentEnergyLevelsExcept(exceptID);
328     return computeExcitationEnergy(theEnergyLe    317     return computeExcitationEnergy(theEnergyLevels);
329   }                                               318   }
330                                                   319 
331   G4double ProjectileRemnant::computeExcitatio    320   G4double ProjectileRemnant::computeExcitationEnergyWith(const ParticleList &pL) const {
332     const EnergyLevels theEnergyLevels = getPr    321     const EnergyLevels theEnergyLevels = getPresentEnergyLevelsWith(pL);
333     return computeExcitationEnergy(theEnergyLe    322     return computeExcitationEnergy(theEnergyLevels);
334   }                                               323   }
335                                                   324 
336   G4double ProjectileRemnant::computeExcitatio    325   G4double ProjectileRemnant::computeExcitationEnergy(const EnergyLevels &levels) const {
337     // The ground-state energy is the sum of t    326     // The ground-state energy is the sum of the A smallest initial projectile
338     // energies.                                  327     // energies.
339     // For the last nucleon, return 0 so that     328     // For the last nucleon, return 0 so that the algorithm will just put it on
340     // shell.                                     329     // shell.
341     const std::size_t theNewA = levels.size(); << 330     const unsigned theNewA = levels.size();
342 // assert(theNewA>0);                             331 // assert(theNewA>0);
343     if(theNewA==1)                                332     if(theNewA==1)
344       return 0.;                                  333       return 0.;
345                                                   334 
346     const G4double groundState = theGroundStat    335     const G4double groundState = theGroundStateEnergies.at(theNewA-1);
347                                                   336 
348     // Compute the sum of the presently occupi    337     // Compute the sum of the presently occupied energy levels
349     const G4double excitedState = std::accumul    338     const G4double excitedState = std::accumulate(
350         levels.cbegin(),                       << 339         levels.begin(),
351         levels.cend(),                         << 340         levels.end(),
352         0.);                                      341         0.);
353                                                   342 
354     return excitedState-groundState;              343     return excitedState-groundState;
355   }                                               344   }
356                                                   345 
357   ProjectileRemnant::EnergyLevels ProjectileRe    346   ProjectileRemnant::EnergyLevels ProjectileRemnant::getPresentEnergyLevelsExcept(const long exceptID) const {
358     EnergyLevels theEnergyLevels;                 347     EnergyLevels theEnergyLevels;
359     for(ParticleIter p=particles.begin(), e=pa    348     for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
360       if((*p)->getID()!=exceptID) {               349       if((*p)->getID()!=exceptID) {
361         EnergyLevelMap::const_iterator i = the    350         EnergyLevelMap::const_iterator i = theInitialEnergyLevels.find((*p)->getID());
362 // assert(i!=theInitialEnergyLevels.end());       351 // assert(i!=theInitialEnergyLevels.end());
363         theEnergyLevels.push_back(i->second);     352         theEnergyLevels.push_back(i->second);
364       }                                           353       }
365     }                                             354     }
366 // assert(theEnergyLevels.size()==particles.si    355 // assert(theEnergyLevels.size()==particles.size()-1);
367     return theEnergyLevels;                       356     return theEnergyLevels;
368   }                                               357   }
369                                                   358 
370   ProjectileRemnant::EnergyLevels ProjectileRe    359   ProjectileRemnant::EnergyLevels ProjectileRemnant::getPresentEnergyLevelsWith(const ParticleList &pL) const {
371     EnergyLevels theEnergyLevels;                 360     EnergyLevels theEnergyLevels;
372     for(ParticleIter p=particles.begin(), e=pa    361     for(ParticleIter p=particles.begin(), e=particles.end(); p!=e; ++p) {
373       EnergyLevelMap::const_iterator i = theIn    362       EnergyLevelMap::const_iterator i = theInitialEnergyLevels.find((*p)->getID());
374 // assert(i!=theInitialEnergyLevels.end());       363 // assert(i!=theInitialEnergyLevels.end());
375       theEnergyLevels.push_back(i->second);       364       theEnergyLevels.push_back(i->second);
376     }                                             365     }
377     for(ParticleIter p=pL.begin(), e=pL.end();    366     for(ParticleIter p=pL.begin(), e=pL.end(); p!=e; ++p) {
378       EnergyLevelMap::const_iterator i = theIn    367       EnergyLevelMap::const_iterator i = theInitialEnergyLevels.find((*p)->getID());
379 // assert(i!=theInitialEnergyLevels.end());       368 // assert(i!=theInitialEnergyLevels.end());
380       theEnergyLevels.push_back(i->second);       369       theEnergyLevels.push_back(i->second);
381     }                                             370     }
382                                                   371 
383 // assert(theEnergyLevels.size()==particles.si    372 // assert(theEnergyLevels.size()==particles.size()+pL.size());
384     return theEnergyLevels;                       373     return theEnergyLevels;
385   }                                               374   }
386                                                   375 
387 }                                                 376 }
388                                                   377 
389                                                   378