34#define INCLXX_IN_GEANT4_MODE 1
70 :theNucleus(0), maximumTime(70.0), currentTime(0.0),
71 hadronizationTime(hTime),
73 theLocalEnergyType(localEnergyType),
74 theLocalEnergyDeltaType(localEnergyDeltaType)
92 if(theNucleus->getAnnihilationType()!=
Def)
95 return shootComposite(projectileSpecies, kineticEnergy, impactParameter, phi);
108 theNucleus->setParticleNucleusCollision();
113 G4double energy = kineticEnergy + projectileMass;
114 G4double momentumZ = std::sqrt(energy*energy - projectileMass*projectileMass);
126 std::vector<G4double> energies;
127 std::vector<G4double> projections;
130 for(
ParticleIter pit = fslist.begin(), e = fslist.end(); pit!=e; ++pit){
131 energies.push_back((*pit)->getKineticEnergy());
132 ab = (*pit)->boostVector();
133 cd = (*pit)->getPosition();
134 projections.push_back(ab.dot(cd));
137 temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
138 TLab = *max_element(energies.begin(), energies.end());
142 temfin *= (5.8E4-TLab)/5.6E4;
144 maximumTime = temfin;
147 const G4double rMax = theNucleus->getUniverseRadius();
149 const G4double maxMesonVelocityProjection = *max_element(energies.begin(), energies.end());
150 const G4double traversalTime = distance / maxMesonVelocityProjection;
151 if(maximumTime < traversalTime)
152 maximumTime = traversalTime;
153 INCL_DEBUG(
"Cascade stopping time is " << maximumTime <<
'\n');
160 theNucleus->setInitialEnergy(pb->
getEnergy()
164 theNucleus->setInitialEnergy(pb->
getEnergy()
169 for(
ParticleIter p = fslist.begin(), e = fslist.end(); p!=e; ++p){
170 (*p)->makeProjectileSpectator();
179 theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
192 std::vector<double> energies;
193 std::vector<double> projections;
196 for(
ParticleIter pit = fslist.begin(), e = fslist.end(); pit!=e; ++pit){
197 energies.push_back((*pit)->getKineticEnergy());
198 ab = (*pit)->boostVector();
199 cd = (*pit)->getPosition();
200 projections.push_back(ab.dot(cd));
203 temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
204 TLab = *max_element(energies.begin(), energies.end());
208 temfin *= (5.8E4-TLab)/5.6E4;
210 maximumTime = temfin;
213 const G4double rMax = theNucleus->getUniverseRadius();
215 const G4double maxMesonVelocityProjection = *max_element(energies.begin(), energies.end());
216 const G4double traversalTime = distance / maxMesonVelocityProjection;
217 if(maximumTime < traversalTime)
218 maximumTime = traversalTime;
219 INCL_DEBUG(
"Cascade stopping time is " << maximumTime <<
'\n');
226 theNucleus->setInitialEnergy(pb->
getEnergy()
230 theNucleus->setInitialEnergy(pb->
getEnergy()
235 for(
ParticleIter p = fslist.begin(), e = fslist.end(); p!=e; ++p){
236 (*p)->makeProjectileSpectator();
245 theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
255 theNucleus->setParticleNucleusCollision();
260 G4double energy = kineticEnergy + projectileMass;
261 G4double momentumZ = std::sqrt(energy*energy - projectileMass*projectileMass);
268 temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
271 temfin = 29.8 * std::pow(theNucleus->getA(), 0.16);
277 temfin *= (5.8E4-TLab)/5.6E4;
279 maximumTime = temfin;
282 const G4double rMax = theNucleus->getUniverseRadius();
285 const G4double traversalTime = distance / projectileVelocity;
286 if(maximumTime < traversalTime)
287 maximumTime = traversalTime;
288 INCL_DEBUG(
"Cascade stopping time is " << maximumTime <<
'\n');
297 INCL_DEBUG(
"impactParameter>CoulombDistortion::maxImpactParameter" <<
'\n');
303 impactParameter * std::sin(phi),
310 theNucleus->setInitialEnergy(p->
getEnergy()
325 theNucleus->getStore()->addParticleEntryAvatar(theEntryAvatar);
335 theNucleus->setNucleusNucleusCollision();
342 maximumTime = 29.8 * std::pow(theNucleus->getA(), 0.16);
353 INCL_ERROR(
"a non-composite try to go through shootComposite : " << species.
theType <<
'\n');
355 const G4double rMax = theNucleus->getUniverseRadius();
356 const G4double distance = 2.*rMax + 2.725*rms;
358 const G4double traversalTime = distance / projectileVelocity;
359 if(maximumTime < traversalTime)
360 maximumTime = traversalTime;
361 INCL_DEBUG(
"Cascade stopping time is " << maximumTime <<
'\n');
367 INCL_DEBUG(
"impactParameter>CoulombDistortion::maxImpactParameter" <<
'\n');
374 impactParameter * std::sin(phi),
380 theNucleus->setIncomingMomentum(pr->
getMomentum());
381 theNucleus->setInitialEnergy(pr->
getEnergy()
391 if(theAvatarList.empty()) {
392 INCL_DEBUG(
"No ParticleEntryAvatar found, transparent event" <<
'\n');
409 theNucleus->setProjectileRemnant(pr);
412 theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
418 if(theNucleus->getAnnihilationType()==
PType || theNucleus->getAnnihilationType()==
NType){
419 INCL_DEBUG(
"Antideuteron annihilation Model B chosen, Annihilation of one antinucleon " <<
'\n');
420 theNucleus->setParticleNucleusCollision();
429 const G4double energy = kineticEnergy + projectileMass;
430 const G4double momentumZ = std::sqrt(energy*energy - projectileMass*projectileMass);
432 DummyC->
boost(-aBoostVector);
438 for(
ParticleIter i = Antis.begin(), e=Antis.end();i!=e;++i){
449 Config const *theConfig=theNucleus->getStore()->getConfig();
451 INCL_DEBUG(
"Annihilation of the Antineutron " <<
'\n');
460 std::vector<G4double> energies;
461 std::vector<G4double> projections;
463 for(
ParticleIter pit = fslist.begin(), e = fslist.end(); pit!=e; ++pit){
464 energies.push_back((*pit)->getKineticEnergy());
465 ab = (*pit)->boostVector();
466 cd = (*pit)->getPosition();
467 projections.push_back(ab.dot(cd));
469 temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
470 TLab = *max_element(energies.begin(), energies.end());
472 temfin *= (5.8E4-TLab)/5.6E4;
473 maximumTime = temfin;
475 const G4double rMax = theNucleus->getUniverseRadius();
477 const G4double maxMesonVelocityProjection = *max_element(energies.begin(), energies.end());
478 const G4double traversalTime = distance / maxMesonVelocityProjection;
479 if(maximumTime < traversalTime)
480 maximumTime = traversalTime;
481 INCL_DEBUG(
"Cascade stopping time is " << maximumTime <<
'\n');
485 theNucleus->setIncomingMomentum(pb->
getMomentum());
495 for(
ParticleIter p = fslist.begin(), e = fslist.end(); p!=e; ++p){
496 (*p)->makeProjectileSpectator();
506 theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
510 theNucleus->getStore()->addParticleEntryAvatar(theEntryAvatar);
514 INCL_DEBUG(
"Antiproton is transparent, not entering the nucleus " <<
'\n');
516 theNucleus->getStore()->addToMissed(pb);
523 INCL_DEBUG(
"Annihilation of the Antiproton " <<
'\n');
532 std::vector<G4double> energies;
533 std::vector<G4double> projections;
535 for(
ParticleIter pit = fslist.begin(), e = fslist.end(); pit!=e; ++pit){
536 energies.push_back((*pit)->getKineticEnergy());
537 ab = (*pit)->boostVector();
538 cd = (*pit)->getPosition();
539 projections.push_back(ab.dot(cd));
541 temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
542 TLab = *max_element(energies.begin(), energies.end());
544 temfin *= (5.8E4-TLab)/5.6E4;
545 maximumTime = temfin;
547 const G4double rMax = theNucleus->getUniverseRadius();
549 const G4double maxMesonVelocityProjection = *max_element(energies.begin(), energies.end());
550 const G4double traversalTime = distance / maxMesonVelocityProjection;
551 if(maximumTime < traversalTime)
552 maximumTime = traversalTime;
553 INCL_DEBUG(
"Cascade stopping time is " << maximumTime <<
'\n');
559 theNucleus->setIncomingMomentum(nb->
getMomentum());
569 for(
ParticleIter p = fslist.begin(), e = fslist.end(); p!=e; ++p){
570 (*p)->makeProjectileSpectator();
580 theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
584 theNucleus->getStore()->addParticleEntryAvatar(theEntryAvatar);
588 INCL_DEBUG(
"Antineutron is transparent, not entering the nucleus " <<
'\n');
589 theNucleus->setIncomingAngularMomentum(
ThreeVector(0.,0.,0.));
590 theNucleus->setIncomingMomentum(
ThreeVector(0.,0.,0.));
592 theNucleus->getStore()->addToMissed(nb);
599 theNucleus->setNucleusNucleusCollision();
601 maximumTime = 29.8 * std::pow(theNucleus->getA(), 0.16);
604 INCL_DEBUG(
"Antideuteron annihilation Model A chosen, Annihilation of Antideuteron as a whole" <<
'\n');
610 std::vector<G4double> energies;
611 std::vector<G4double> projections;
614 for(
ParticleIter pit = fslist.begin(), e = fslist.end(); pit!=e; ++pit){
615 energies.push_back((*pit)->getKineticEnergy());
616 ab = (*pit)->boostVector();
617 cd = (*pit)->getPosition();
618 projections.push_back(ab.dot(cd));
621 temfin = 30.18 * std::pow(theNucleus->getA(), 0.17);
622 TLab = *max_element(energies.begin(), energies.end());
626 temfin *= (5.8E4-TLab)/5.6E4;
628 maximumTime = temfin;
631 const G4double rMax = theNucleus->getUniverseRadius();
633 const G4double maxMesonVelocityProjection = *max_element(energies.begin(), energies.end());
634 const G4double traversalTime = distance / maxMesonVelocityProjection;
635 if(maximumTime < traversalTime)
636 maximumTime = traversalTime;
637 INCL_DEBUG(
"Cascade stopping time is " << maximumTime <<
'\n');
649 for(
ParticleIter p = fslist.begin(), e = fslist.end(); p!=e; ++p){
650 (*p)->makeProjectileSpectator();
659 theNucleus->getStore()->addParticleEntryAvatars(theAvatarList);
680 theNucleus = nucleus;
685 if(anAvatar) theNucleus->getStore()->add(anAvatar);
701 G4double minDistOfApproachSquared = 0.0;
703 if(t>maximumTime || t<currentTime+hadronizationTime)
return NULL;
710 theNucleus->getStore()->getBook().getAcceptedCollisions()==0) ||
714 theNucleus->getStore()->getBook().getAcceptedCollisions()==0) ||
719 if(p1HasLocalEnergy) {
720 backupParticle1 = *p1;
723 *p1 = backupParticle1;
728 if(p2HasLocalEnergy) {
729 backupParticle2 = *p2;
732 *p2 = backupParticle2;
733 if(p1HasLocalEnergy) {
734 *p1 = backupParticle1;
746 if(p1HasLocalEnergy) {
747 *p1 = backupParticle1;
749 if(p2HasLocalEnergy) {
750 *p2 = backupParticle2;
754 if(theNucleus->getStore()->getBook().getAcceptedCollisions()>0
759 if(
Math::tenPi*minDistOfApproachSquared > totalCrossSection)
return NULL;
773 theNucleus->getSurfaceRadius(aParticle)));
775 if(theIntersection.
exists) {
776 time = currentTime + theIntersection.
time;
778 INCL_ERROR(
"Imaginary reflection time for particle: " <<
'\n'
779 << aParticle->
print());
791 Config const *theConfig=theNucleus->getStore()->getConfig();
794 ((particleA->getType()==
antiNeutron) && (particleA->getKineticEnergy() <= particleA->getPotentialEnergy())) ||
796 ((particleA->getType()==
antiProton && particleA->getEnergy() <= particleA->getINCLMass())) ||
798 ((particleA->getType()==
antiNeutron && particleA->getEnergy() <= particleA->getINCLMass())) ||
801 return currentTime + 0.001;
810 (*minDistOfApproach) = 100000.0;
811 return currentTime + 100000.0;
815 (*minDistOfApproach) = distance.
mag2() + time * t7;
816 return currentTime + time;
822 for(
ParticleIter updated=updatedParticles.begin(), e=updatedParticles.end(); updated!=e; ++updated)
825 for(
ParticleIter particle=particles.begin(), end=particles.end(); particle!=end; ++particle)
831 if(updatedParticles.
contains(*particle))
continue;
840 for(
ParticleIter p1=particles.begin(), e=particles.end(); p1!=e; ++p1) {
842 for(
ParticleIter p2 = p1 + 1; p2 != particles.end(); ++p2) {
850 const G4bool haveExcept = !except.empty();
853 for(
ParticleIter p1=particles.begin(), e=particles.end(); p1!=e; ++p1)
857 for(++p2; p2 != particles.end(); ++p2)
870 for(
ParticleIter iter=particles.begin(), e=particles.end(); iter!=e; ++iter) {
874 ParticleList const &p = theNucleus->getStore()->getParticles();
879 ParticleList const &particles = theNucleus->getStore()->getParticles();
882 for(
ParticleIter i=particles.begin(), e=particles.end(); i!=e; ++i) {
890#ifdef INCL_REGENERATE_AVATARS
891 void StandardPropagationModel::generateAllAvatarsExceptUpdated(
FinalState const *
const fs) {
894 for(
ParticleIter i=particles.begin(), e=particles.end(); i!=e; ++i) {
900 except.insert(except.end(), entering.begin(), entering.end());
907 for(
ParticleIter i=particles.begin(), e=particles.end(); i!=e; ++i) {
908 if((*i)->isDelta()) {
910 G4double time = currentTime + decayTime;
911 if(time <= maximumTime) {
917 G4double time = currentTime + decayTime;
918 if(time <= maximumTime) {
922 if((*i)->isOmega()) {
924 G4double timeOmega = currentTime + decayTimeOmega;
925 if(timeOmega <= maximumTime) {
937#ifdef INCL_REGENERATE_AVATARS
938#warning "The INCL_REGENERATE_AVATARS code has not been tested in a while. Use it at your peril."
942 theNucleus->getStore()->clearAvatars();
943 theNucleus->getStore()->initialiseParticleAvatarConnections();
944 generateAllAvatarsExceptUpdated(fs);
960 if(created.empty() && entering.empty())
964 updatedParticlesCopy.insert(updatedParticlesCopy.end(), entering.begin(), entering.end());
965 updatedParticlesCopy.insert(updatedParticlesCopy.end(), created.begin(), created.end());
972 G4INCL::IAvatar *theAvatar = theNucleus->getStore()->findSmallestTime();
973 if(theAvatar == 0)
return 0;
976 if(theAvatar->
getTime() < currentTime) {
977 INCL_ERROR(
"Avatar time = " << theAvatar->
getTime() <<
", currentTime = " << currentTime <<
'\n');
979 }
else if(theAvatar->
getTime() > currentTime) {
980 theNucleus->getStore()->timeStep(theAvatar->
getTime() - currentTime);
982 currentTime = theAvatar->
getTime();
983 theNucleus->getStore()->getBook().setCurrentTime(currentTime);
Static class for selecting Coulomb distortion.
Simple class for computing intersections between a straight line and a sphere.
IAvatarList bringMesonStar(ParticleList const &pL, Nucleus *const n)
ParticleList makeMesonStar()
static G4double getCutNNSquared()
void boost(const ThreeVector &aBoostVector)
Boost the cluster with the indicated velocity.
void internalBoostToCM()
Boost to the CM of the component particles.
void removeParticle(Particle *const p)
Remove a particle from the cluster components.
ParticleList const & getParticles() const
virtual void makeProjectileSpectator()
Make all the components projectile spectators, too.
virtual void initializeParticles()
Initialise the NuclearDensity pointer and sample the particles.
G4INCL::ThreeVector getAngularMomentum() const
Get the total angular momentum (orbital + spin).
void setPosition(const ThreeVector &position)
Set the position of the cluster.
G4double getAtrestThreshold() const
Get the pbar at rest annihilation threshold.
G4double getnbAtrestThreshold() const
Get the nbar at rest annihilation threshold.
static G4double computeDecayTime(Particle *p)
ParticleList const & getEnteringParticles() const
ParticleList const & getModifiedParticles() const
FinalStateValidity getValidity() const
ParticleList const & getCreatedParticles() const
IAvatarList bringMesonStar(ParticleList const &pL, Nucleus *const n)
G4bool ProtonIsTheVictim()
ParticleList makeMesonStar()
ThreeVector boostVector() const
G4double getINCLMass() const
Get the INCL particle mass.
virtual G4INCL::ParticleSpecies getSpecies() const
Get the particle species.
G4bool isPhoton() const
Is this a photon?
G4bool isMeson() const
Is this a Meson?
virtual G4INCL::ThreeVector getAngularMomentum() const
G4double getEnergy() const
G4double getPotentialEnergy() const
Get the particle potential energy.
ParticipantType getParticipantType() const
ThreeVector getPropagationVelocity() const
Get the propagation velocity of the particle.
void propagate(G4double step)
G4int getZ() const
Returns the charge number.
const G4INCL::ThreeVector & getPosition() const
G4bool isParticipant() const
G4double getKineticEnergy() const
Get the particle kinetic energy.
G4bool isAntiNucleon() const
Is this an antinucleon?
virtual void makeProjectileSpectator()
const ThreeVector & adjustMomentumFromEnergy()
Rescale the momentum to match the total energy.
G4bool isPion() const
Is this a pion?
void setINCLMass()
Set the mass of the Particle to its table mass.
const G4INCL::ThreeVector & getMomentum() const
G4INCL::ParticleType getType() const
G4bool isResonance() const
Is it a resonance?
void setEnergy(G4double energy)
std::string print() const
ThreeVector getTransversePosition() const
Transverse component of the position w.r.t. the momentum.
G4double getMass() const
Get the cached particle mass.
virtual void setPosition(const G4INCL::ThreeVector &position)
void setTableMass()
Set the mass of the Particle to its table mass.
G4int getA() const
Returns the baryon number.
ParticleList makeMesonStar()
IAvatarList bringMesonStar(ParticleList const &pL, Nucleus *const n)
G4bool ProtonIsTheVictim()
static G4double computeDecayTime(Particle *p)
void storeComponents()
Store the projectile components.
static G4double computeDecayTime(Particle *p)
virtual ~StandardPropagationModel()
G4double getReflectionTime(G4INCL::Particle const *const aParticle)
Get the reflection time.
G4INCL::IAvatar * propagate(FinalState const *const fs)
G4double getTime(G4INCL::Particle const *const particleA, G4INCL::Particle const *const particleB, G4double *minDistOfApproach) const
void generateCollisions(const ParticleList &particles)
Generate and register collisions among particles in a list, except between those in another list.
G4double shootAtrest(ParticleType const t, const G4double kineticEnergy)
StandardPropagationModel(LocalEnergyType localEnergyType, LocalEnergyType localEnergyDeltaType, const G4double hTime=0.0)
void setStoppingTime(G4double)
void registerAvatar(G4INCL::IAvatar *anAvatar)
G4double getStoppingTime()
void updateAvatars(const ParticleList &particles)
void generateAllAvatars()
(Re)Generate all possible avatars.
G4double shoot(ParticleSpecies const &projectileSpecies, const G4double kineticEnergy, const G4double impactParameter, const G4double phi)
IAvatar * generateBinaryCollisionAvatar(Particle *const p1, Particle *const p2)
Generate a two-particle avatar.
G4double shootCompositeAtrest(ParticleSpecies const &s, const G4double kineticEnergy)
G4INCL::Nucleus * getNucleus()
void generateUpdatedCollisions(const ParticleList &updatedParticles, const ParticleList &particles)
Generate and register collisions between a list of updated particles and all the other particles.
G4double shootComposite(ParticleSpecies const &s, const G4double kineticEnergy, const G4double impactParameter, const G4double phi)
G4double getCurrentTime()
void generateDecays(const ParticleList &particles)
Generate decays for particles that can decay.
void setNucleus(G4INCL::Nucleus *nucleus)
G4double shootParticle(ParticleType const t, const G4double kineticEnergy, const G4double impactParameter, const G4double phi)
ParticleList const & getParticles() const
G4double dot(const ThreeVector &v) const
G4bool contains(const T &t) const
ParticleEntryAvatar * bringToSurfaceAbar(Particle *p, Nucleus *const n)
ParticleEntryAvatar * bringToSurface(Particle *p, Nucleus *const n)
Modify the momentum of an incoming particle and position it on the surface of the nucleus.
G4double maxImpactParameter(ParticleSpecies const &p, const G4double kinE, Nucleus const *const n)
Return the maximum impact parameter for Coulomb-distorted trajectories.
G4double total(Particle const *const p1, Particle const *const p2)
Intersection getLaterTrajectoryIntersection(const ThreeVector &x0, const ThreeVector &p, const G4double r)
Compute the second intersection of a straight particle trajectory with a sphere.
G4double squareTotalEnergyInCM(Particle const *const p1, Particle const *const p2)
void transformToLocalEnergyFrame(Nucleus const *const n, Particle *const p)
G4ThreadLocal NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
G4ThreadLocal ParticleMassFn getTableParticleMass
Static pointer to the mass function for particles.
G4double getLargestNuclearRadius(const G4int A, const G4int Z)
ParticleList::const_iterator ParticleIter
@ FirstCollisionLocalEnergy
UnorderedVector< IAvatar * > IAvatarList
Intersection-point structure.