#include <G4INCLProjectileRemnant.hh>
Inheritance diagram for G4INCL::ProjectileRemnant:
Public Member Functions | |
ProjectileRemnant (ParticleSpecies const species, const G4double kineticEnergy) | |
~ProjectileRemnant () | |
void | reset () |
Reset the projectile remnant to the state at the beginning of the cascade. | |
void | removeParticle (Particle *const p, const G4double theProjectileCorrection) |
Remove a nucleon from the projectile remnant. | |
ParticleList | addDynamicalSpectators (ParticleList pL) |
Add back dynamical spectators to the projectile remnant. | |
ParticleList | addMostDynamicalSpectators (ParticleList pL) |
Add back dynamical spectators to the projectile remnant. | |
void | deleteStoredComponents () |
Clear the stored projectile components and delete the particles. | |
void | clearStoredComponents () |
Clear the stored projectile components. | |
void | clearEnergyLevels () |
Clear the stored energy levels. | |
G4double | computeExcitationEnergy (const long exceptID) const |
Compute the excitation energy. | |
EnergyLevels | getPresentEnergyLevels (const long exceptID) const |
void | storeComponents () |
Store the projectile components. | |
G4int | getNumberStoredComponents () const |
Get the number of the stored components. | |
void | storeEnergyLevels () |
Store the energy levels. |
Definition at line 59 of file G4INCLProjectileRemnant.hh.
G4INCL::ProjectileRemnant::ProjectileRemnant | ( | ParticleSpecies const | species, | |
const G4double | kineticEnergy | |||
) | [inline] |
Definition at line 65 of file G4INCLProjectileRemnant.hh.
References G4INCL::Cluster::boost(), G4INCL::Cluster::freezeInternalMotion(), G4INCL::Particle::getMass(), G4INCL::Cluster::initializeParticles(), G4INCL::Cluster::internalBoostToCM(), G4INCL::Cluster::makeProjectileSpectator(), G4INCL::Cluster::putParticlesOffShell(), G4INCL::Particle::setTableMass(), and storeEnergyLevels().
00066 : Cluster(species.theZ, species.theA) { 00067 00068 // Use the table mass 00069 setTableMass(); 00070 00071 // Set the kinematics 00072 const G4double projectileMass = getMass(); 00073 const G4double energy = kineticEnergy + projectileMass; 00074 const G4double momentumZ = std::sqrt(energy*energy - projectileMass*projectileMass); 00075 00076 // Initialise the particles 00077 initializeParticles(); 00078 internalBoostToCM(); 00079 putParticlesOffShell(); 00080 00081 // Store the energy levels of the ProjectileRemnant (used to compute its 00082 // excitation energy) 00083 storeEnergyLevels(); 00084 00085 // Boost the whole thing 00086 const ThreeVector aBoostVector = ThreeVector(0.0, 0.0, momentumZ / energy); 00087 boost(-aBoostVector); 00088 00089 // Freeze the internal motion of the particles 00090 freezeInternalMotion(); 00091 00092 // Set as projectile spectator 00093 makeProjectileSpectator(); 00094 }
G4INCL::ProjectileRemnant::~ProjectileRemnant | ( | ) | [inline] |
Definition at line 96 of file G4INCLProjectileRemnant.hh.
References clearEnergyLevels(), and deleteStoredComponents().
00096 { 00097 deleteStoredComponents(); 00098 clearEnergyLevels(); 00099 }
ParticleList G4INCL::ProjectileRemnant::addDynamicalSpectators | ( | ParticleList | pL | ) |
Add back dynamical spectators to the projectile remnant.
Try to add the dynamical spectators back to the projectile remnant. Refuse to do so if this leads to a negative projectile excitation energy.
Return a list of rejected dynamical spectators.
Definition at line 123 of file G4INCLProjectileRemnant.cc.
00123 { 00124 // Try as hard as possible to add back all the dynamical spectators. 00125 // Don't add spectators that lead to negative excitation energies, but 00126 // iterate over the spectators as many times as possible, until 00127 // absolutely sure that all of them were rejected. 00128 unsigned int accepted; 00129 do { 00130 accepted = 0; 00131 ParticleList toBeAdded = pL; 00132 for(ParticleIter p=toBeAdded.begin(); p!=toBeAdded.end(); ++p) { 00133 G4bool isAccepted = addDynamicalSpectator(*p); 00134 if(isAccepted) { 00135 pL.remove(*p); 00136 accepted++; 00137 } 00138 } 00139 } while(accepted > 0); 00140 return pL; 00141 }
ParticleList G4INCL::ProjectileRemnant::addMostDynamicalSpectators | ( | ParticleList | pL | ) |
Add back dynamical spectators to the projectile remnant.
Try as hard as possible to add back all the dynamical spectators. Don't add spectators that lead to negative excitation energies. Start by adding all of them, and repeatedly remove the most troublesome one until the excitation energy becomes non-negative.
Return a list of rejected dynamical spectators.
Definition at line 143 of file G4INCLProjectileRemnant.cc.
References G4INCL::ParticleTable::getTableMass, G4INCL::ThreeVector::getZ(), G4INCL::ThreeVector::mag2(), G4INCL::Cluster::particles, G4INCL::Particle::theA, G4INCL::Particle::theEnergy, G4INCL::Particle::theMomentum, and G4INCL::Particle::theZ.
00143 { 00144 // Try as hard as possible to add back all the dynamical spectators. 00145 // Don't add spectators that lead to negative excitation energies. Start by 00146 // adding all of them, and repeatedly remove the most troublesome one until 00147 // the excitation energy becomes non-negative. 00148 00149 // Put all the spectators in the projectile 00150 ThreeVector theNewMomentum = theMomentum; 00151 G4double theNewEnergy = theEnergy; 00152 G4int theNewA = theA; 00153 G4int theNewZ = theZ; 00154 for(ParticleIter p=pL.begin(); p!=pL.end(); ++p) { 00155 // assert((*p)->isNucleon()); 00156 // Add the initial (off-shell) momentum and energy to the projectile remnant 00157 theNewMomentum += getStoredMomentum(*p); 00158 theNewEnergy += (*p)->getEnergy(); 00159 theNewA += (*p)->getA(); 00160 theNewZ += (*p)->getZ(); 00161 } 00162 00163 // Check that the excitation energy of the new projectile remnant is non-negative 00164 const G4double theNewMass = ParticleTable::getTableMass(theNewA,theNewZ); 00165 const G4double theNewInvariantMassSquared = theNewEnergy*theNewEnergy-theNewMomentum.mag2(); 00166 00167 G4bool positiveExcitationEnergy = false; 00168 if(theNewInvariantMassSquared>=0.) { 00169 const G4double theNewInvariantMass = std::sqrt(theNewInvariantMassSquared); 00170 positiveExcitationEnergy = (theNewInvariantMass-theNewMass>-1.e-5); 00171 } 00172 00173 // Keep removing nucleons from the projectile remnant until we achieve a 00174 // non-negative excitation energy. 00175 ParticleList rejected; 00176 while(!positiveExcitationEnergy && !pL.empty()) { 00177 G4double maxExcitationEnergy = -1.E30; 00178 ParticleList::iterator best = pL.end(); 00179 ThreeVector bestMomentum; 00180 G4double bestEnergy = -1.; 00181 G4int bestA = -1, bestZ = -1; 00182 for(ParticleList::iterator p=pL.begin(); p!=pL.end(); ++p) { 00183 // Subtract the initial (off-shell) momentum and energy from the new 00184 // projectile remnant 00185 const ThreeVector theNewerMomentum = theNewMomentum - getStoredMomentum(*p); 00186 const G4double theNewerEnergy = theNewEnergy - (*p)->getEnergy(); 00187 const G4int theNewerA = theNewA - (*p)->getA(); 00188 const G4int theNewerZ = theNewZ - (*p)->getZ(); 00189 00190 const G4double theNewerMass = ParticleTable::getTableMass(theNewerA,theNewerZ); 00191 const G4double theNewerInvariantMassSquared = theNewerEnergy*theNewerEnergy-theNewerMomentum.mag2(); 00192 00193 if(theNewerInvariantMassSquared>=-1.e-5) { 00194 const G4double theNewerInvariantMass = std::sqrt(std::max(0.,theNewerInvariantMassSquared)); 00195 const G4double theNewerExcitationEnergy = theNewerInvariantMass-theNewerMass; 00196 // Pick the nucleon that maximises the excitation energy of the 00197 // ProjectileRemnant 00198 if(theNewerExcitationEnergy>maxExcitationEnergy) { 00199 best = p; 00200 maxExcitationEnergy = theNewerExcitationEnergy; 00201 bestMomentum = theNewerMomentum; 00202 bestEnergy = theNewerEnergy; 00203 bestA = theNewerA; 00204 bestZ = theNewerZ; 00205 } 00206 } 00207 } 00208 00209 // If we couldn't even calculate the excitation energy, fail miserably 00210 if(best==pL.end()) 00211 return pL; 00212 00213 rejected.push_back(*best); 00214 pL.erase(best); 00215 theNewMomentum = bestMomentum; 00216 theNewEnergy = bestEnergy; 00217 theNewA = bestA; 00218 theNewZ = bestZ; 00219 00220 if(maxExcitationEnergy>0.) { 00221 // Stop here 00222 positiveExcitationEnergy = true; 00223 } 00224 } 00225 00226 // Add the accepted participants to the projectile remnant 00227 for(ParticleIter p=pL.begin(); p!=pL.end(); ++p) { 00228 particles.push_back(*p); 00229 } 00230 theA = theNewA; 00231 theZ = theNewZ; 00232 theMomentum = theNewMomentum; 00233 theEnergy = theNewEnergy; 00234 00235 return rejected; 00236 }
void G4INCL::ProjectileRemnant::clearEnergyLevels | ( | ) | [inline] |
Clear the stored energy levels.
Definition at line 145 of file G4INCLProjectileRemnant.hh.
Referenced by ~ProjectileRemnant().
void G4INCL::ProjectileRemnant::clearStoredComponents | ( | ) | [inline] |
Clear the stored projectile components.
Definition at line 140 of file G4INCLProjectileRemnant.hh.
Referenced by deleteStoredComponents().
G4double G4INCL::ProjectileRemnant::computeExcitationEnergy | ( | const long | exceptID | ) | const |
Compute the excitation energy.
Compute the excitation energy of the projectile-like remnant as the difference between the initial and the present configuration. This follows the algorithm proposed by A. Boudard in INCL4.2-HI, as implemented in Geant4.
Definition at line 268 of file G4INCLProjectileRemnant.cc.
References getPresentEnergyLevels(), and G4INCL::Particle::theA.
Referenced by G4INCL::ParticleEntryChannel::getFinalState().
00268 { 00269 // The ground-state energy is the sum of the A smallest initial projectile 00270 // energies. 00271 // For the last nucleon, return 0 so that the algorithm will just put it on 00272 // shell. 00273 if(theA==1) 00274 return 0.; 00275 00276 const G4double groundState = theGroundStateEnergies.at(theA-2); 00277 00278 // Compute the sum of the presently occupied energy levels 00279 const EnergyLevels theEnergyLevels = getPresentEnergyLevels(exceptID); 00280 const G4double excitedState = std::accumulate( 00281 theEnergyLevels.begin(), 00282 theEnergyLevels.end(), 00283 0.); 00284 00285 return excitedState-groundState; 00286 }
void G4INCL::ProjectileRemnant::deleteStoredComponents | ( | ) | [inline] |
Clear the stored projectile components and delete the particles.
Definition at line 133 of file G4INCLProjectileRemnant.hh.
References clearStoredComponents().
Referenced by ~ProjectileRemnant().
00133 { 00134 for(std::map<long,Particle*>::const_iterator p=storedComponents.begin(); p!=storedComponents.end(); ++p) 00135 delete p->second; 00136 clearStoredComponents(); 00137 }
G4int G4INCL::ProjectileRemnant::getNumberStoredComponents | ( | ) | const [inline] |
Get the number of the stored components.
Definition at line 183 of file G4INCLProjectileRemnant.hh.
Referenced by G4INCL::Nucleus::finalizeProjectileRemnant().
EnergyLevels G4INCL::ProjectileRemnant::getPresentEnergyLevels | ( | const long | exceptID | ) | const [inline] |
Definition at line 161 of file G4INCLProjectileRemnant.hh.
References G4INCL::Cluster::particles.
Referenced by computeExcitationEnergy().
00161 { 00162 EnergyLevels theEnergyLevels; 00163 for(ParticleIter p=particles.begin(); p!=particles.end(); ++p) { 00164 if((*p)->getID()!=exceptID) { 00165 EnergyLevelMap::const_iterator i = theInitialEnergyLevels.find((*p)->getID()); 00166 // assert(i!=theInitialEnergyLevels.end()); 00167 theEnergyLevels.push_back(i->second); 00168 } 00169 } 00170 // assert(theEnergyLevels.size()==particles.size()-1); 00171 return theEnergyLevels; 00172 }
void G4INCL::ProjectileRemnant::removeParticle | ( | Particle *const | p, | |
const G4double | theProjectileCorrection | |||
) |
Remove a nucleon from the projectile remnant.
p | particle to be removed | |
theProjectileCorrection | correction to be given to the projectile total energy |
Definition at line 78 of file G4INCLProjectileRemnant.cc.
References DEBUG, G4INCL::Particle::getA(), G4INCL::Particle::getEnergy(), G4INCL::Particle::getMomentum(), G4INCL::Particle::getZ(), G4INCL::Cluster::particles, G4INCL::Cluster::print(), G4INCL::Particle::print(), G4INCL::Cluster::removeParticle(), G4INCL::Particle::theA, G4INCL::Particle::theEnergy, G4INCL::Particle::theMomentum, and G4INCL::Particle::theZ.
Referenced by G4INCL::ParticleEntryChannel::getFinalState().
00078 { 00079 // assert(p->isNucleon()); 00080 00081 DEBUG("The following Particle is about to be removed from the ProjectileRemnant:" 00082 << std::endl << p->print() 00083 << "theProjectileCorrection=" << theProjectileCorrection << std::endl); 00084 // Update A, Z, momentum and energy of the projectile remnant 00085 theA -= p->getA(); 00086 theZ -= p->getZ(); 00087 00088 ThreeVector const &oldMomentum = p->getMomentum(); 00089 const G4double oldEnergy = p->getEnergy(); 00090 Cluster::removeParticle(p); 00091 00092 #if !defined(NDEBUG) && !defined(INCLXX_IN_GEANT4_MODE) 00093 ThreeVector theTotalMomentum; 00094 G4double theTotalEnergy = 0.; 00095 const G4double theThreshold = 0.1; 00096 #endif 00097 00098 if(getA()>0) { // if there are any particles left 00099 // assert((unsigned int)getA()==particles.size()); 00100 00101 const G4double theProjectileCorrectionPerNucleon = theProjectileCorrection / particles.size(); 00102 00103 // Update the kinematics of the components 00104 for(ParticleIter i=particles.begin(); i!=particles.end(); ++i) { 00105 (*i)->setEnergy((*i)->getEnergy() + theProjectileCorrectionPerNucleon); 00106 (*i)->setMass((*i)->getInvariantMass()); 00107 #if !defined(NDEBUG) && !defined(INCLXX_IN_GEANT4_MODE) 00108 theTotalMomentum += (*i)->getMomentum(); 00109 theTotalEnergy += (*i)->getEnergy(); 00110 #endif 00111 } 00112 } 00113 00114 theMomentum -= oldMomentum; 00115 theEnergy -= oldEnergy - theProjectileCorrection; 00116 00117 // assert(std::abs((theTotalMomentum-theMomentum).mag())<theThreshold); 00118 // assert(std::abs(theTotalEnergy-theEnergy)<theThreshold); 00119 DEBUG("After Particle removal, the ProjectileRemnant looks like this:" 00120 << std::endl << print()); 00121 }
void G4INCL::ProjectileRemnant::reset | ( | ) |
Reset the projectile remnant to the state at the beginning of the cascade.
Definition at line 54 of file G4INCLProjectileRemnant.cc.
References G4INCL::Cluster::addParticle(), DEBUG, G4INCL::Cluster::deleteParticles(), G4INCL::Particle::nCollisions, G4INCL::Particle::Particle(), G4INCL::Cluster::print(), G4INCL::Particle::setTableMass(), G4INCL::Particle::theA, G4INCL::Particle::theEnergy, G4INCL::Particle::theMomentum, G4INCL::Particle::thePosition, G4INCL::Particle::thePotentialEnergy, and G4INCL::Particle::theZ.
00054 { 00055 deleteParticles(); 00056 thePosition = ThreeVector(); 00057 theMomentum = ThreeVector(); 00058 theEnergy = 0.0; 00059 thePotentialEnergy = 0.0; 00060 theA = 0; 00061 theZ = 0; 00062 nCollisions = 0; 00063 00064 for(std::map<long, Particle*>::const_iterator i=storedComponents.begin(); i!=storedComponents.end(); ++i) { 00065 Particle *p = new Particle(*(i->second)); 00066 EnergyLevelMap::iterator energyIter = theInitialEnergyLevels.find(i->first); 00067 // assert(energyIter!=theInitialEnergyLevels.end()); 00068 const G4double energyLevel = energyIter->second; 00069 theInitialEnergyLevels.erase(energyIter); 00070 theInitialEnergyLevels[p->getID()] = energyLevel; 00071 addParticle(p); 00072 } 00073 thePosition /= theA; 00074 setTableMass(); 00075 DEBUG("ProjectileRemnant object was reset:" << std::endl << print()); 00076 }
void G4INCL::ProjectileRemnant::storeComponents | ( | ) | [inline] |
Store the projectile components.
Definition at line 175 of file G4INCLProjectileRemnant.hh.
References G4INCL::Particle::Particle(), and G4INCL::Cluster::particles.
00175 { 00176 for(ParticleIter p=particles.begin(); p!=particles.end(); ++p) { 00177 // Store the particles (needed for forced CN) 00178 storedComponents[(*p)->getID()]=new Particle(**p); 00179 } 00180 }
void G4INCL::ProjectileRemnant::storeEnergyLevels | ( | ) | [inline] |
Store the energy levels.
Definition at line 188 of file G4INCLProjectileRemnant.hh.
References G4INCL::Cluster::particles.
Referenced by ProjectileRemnant().
00188 { 00189 EnergyLevels energies; 00190 00191 for(ParticleIter p=particles.begin(); p!=particles.end(); ++p) { 00192 const G4double theCMEnergy = (*p)->getEnergy(); 00193 // Store the CM energy in the EnergyLevels map 00194 theInitialEnergyLevels[(*p)->getID()] = theCMEnergy; 00195 energies.push_back(theCMEnergy); 00196 } 00197 00198 std::sort(energies.begin(), energies.end()); 00199 // assert(energies.size()==(unsigned int)theA); 00200 theGroundStateEnergies.resize(energies.size()); 00201 // Compute the partial sums of the CM energies -- they are our reference 00202 // ground-state energies for any number of nucleons 00203 std::partial_sum(energies.begin(), energies.end(), theGroundStateEnergies.begin()); 00204 }