34#define INCLXX_IN_GEANT4_MODE 1
66 G4ThreadLocal Particle *InteractionAvatar::backupPartner = NULL;
67 ThreeVector InteractionAvatar::mbackupPartner;
69 G4ThreadLocal InteractionAvatar *InteractionAvatar::interactionAvatar = 0;
76 violationEFunctor(NULL)
78 interactionAvatar =
this;
85 isPiN((p1->isPion() && p2->isNucleon()) || (p2->isPion() && p1->isNucleon())),
87 violationEFunctor(NULL)
89 interactionAvatar =
this;
100 (*backupPartner) = (*p);
104 INCL_DEBUG(
"setSrcPartner:" << backupPartner->print());
114 delete backupPartner;
117 backupPartner = NULL;
122 (*backupParticle1) = (*particle1);
128 (*backupParticle2) = (*particle2);
171 const short maxIterations=50;
173 if(pos2 < r*r)
return true;
175 while( pos2 >= r*r && iterations<maxIterations )
177 pos *= std::sqrt(r*r*0.9801/pos2);
181 if( iterations < maxIterations)
183 INCL_DEBUG(
"Particle position vector length was : " << p->
getPosition().
mag() <<
", rescaled to: " << pos.mag() <<
'\n');
192 INCL_DEBUG(
"postInteraction: final state: " <<
'\n' << fs->
print() <<
'\n');
207 if ((*i)->isSrcPartner() ==
false){
217 if(((*i)->isPion() || (*i)->isKaon() || (*i)->isAntiKaon()) && (*i)->getPosition().mag() >
theNucleus->getSurfaceRadius(*i)) {
218 (*i)->makeParticipant();
219 (*i)->setOutOfWell();
221 INCL_DEBUG(
"Pion was created outside its potential well." <<
'\n'
229 theNucleus->getStore()->getBook().getAcceptedSrcCollisions() == 1) {
233 if ((*i)->getSrcPair() > 0.) {
242 partnerE = backupPartner->getEnergy() - backupPartner->getPotentialEnergy();
246 if ((*i)->isNucleon())
247 oldTotalEnergy3 += (*i)->getEnergy() - (*i)->getPotentialEnergy();
248 else if ((*i)->isResonance())
249 oldTotalEnergy3 += (*i)->getEnergy() - (*i)->getPotentialEnergy() -
256 << backupPartner->getEnergy() <<
'\n');
263 backupPartner->getEnergy() -
264 backupPartner->getPotentialEnergy()
271 backupPartner->getEnergy() - backupPartner->getPotentialEnergy());
273 INCL_DEBUG(
"check diff. src energies: " << oldTotalEnergy3 <<
" , " << ediff
280 INCL_DEBUG(
"postInteraction before enforceEnergyConservation final state: "
283 << fs->
print() <<
'\n');
285 INCL_DEBUG(
"enforceEnergyConservation finish " << success <<
'\n');
288 INCL_DEBUG(
"Enforcing energy conservation: failed!" <<
'\n');
294 INCL_DEBUG(
"Enforcing energy conservation: failed for SRC"
309 INCL_DEBUG(
"Enforcing energy conservation: success!" <<
'\n');
311 INCL_DEBUG(
"postInteraction after energy conservation: final state: " <<
'\n' << fs->
print() <<
'\n');
315 if((*i)->isDelta() &&
317 INCL_DEBUG(
"Mass of the produced delta below decay threshold; forbidding collision. deltaMass=" <<
318 (*i)->getMass() <<
'\n');
324 INCL_DEBUG(
"Mass of the produced delta below decay threshold for SRC"
344 if (isBlocked && check < 2) {
406 if((*i)->isOutOfWell())
continue;
409 if( !successBringParticlesInside ) {
410 INCL_ERROR(
"Failed to bring particle inside the nucleus!" <<
'\n');
416 std::vector<G4int> newBiasCollisionVector;
418 if(std::fabs(
weight-1.) > 1E-6){
424 (*i)->setBiasCollisionVector(newBiasCollisionVector);
425 if(!(*i)->isOutOfWell()) {
428 G4bool goesBackToSpectator =
false;
429 if((*i)->isNucleon() &&
theNucleus->getStore()->getConfig()->getBackToSpectator()) {
430 G4double threshold = (*i)->getPotentialEnergy();
431 if((*i)->getType()==
Proton)
433 if((*i)->getKineticEnergy() < threshold)
434 goesBackToSpectator =
true;
437 (*i)->thawPropagation();
440 if(goesBackToSpectator) {
441 INCL_DEBUG(
"The following particle goes back to spectator:" <<
'\n'
442 << (*i)->print() <<
'\n');
443 if(!(*i)->isTargetSpectator()) {
444 theNucleus->getStore()->getBook().decrementCascading();
446 (*i)->makeTargetSpectator();
448 if((*i)->isTargetSpectator()) {
449 theNucleus->getStore()->getBook().incrementCascading();
451 (*i)->makeParticipant();
454 (*i)->resetSrcPartner();
457 for(
ParticleIter i=destroyed.begin(), e=destroyed.end(); i!=e; ++i )
458 if(!(*i)->isTargetSpectator())
459 theNucleus->getStore()->getBook().decrementCascading();
466 (*i)->resetSrcPartner();
468 INCL_DEBUG(
"postInteraction end, src energy: "
469 << ediff <<
" , eventnb: " <<
theEventInfo.eventNumber <<
'\n');
475 (*particle1) = (*backupParticle1);
478 (*particle2) = (*backupParticle2);
485 theNucleus->getStore()->getBook().setAcceptedSrcCollisions(0);
490 for (
ParticleIter i = m.begin(), e = m.end(); i != e; ++i) {
491 if ((*i)->getType() == backupPartner->getType() &&
492 (*i)->getSrcPair() == backupPartner->getSrcPair()) {
493 (*i)->setPosition(backupPartner->getPosition());
494 (*i)->setMomentum(backupPartner->getMomentum());
495 (*i)->adjustEnergyFromMomentum();
496 (*i)->resetSrcPartner();
513 theLocalEnergyType =
theNucleus->getStore()->getConfig()->getLocalEnergyPiType();
515 theLocalEnergyType =
theNucleus->getStore()->getConfig()->getLocalEnergyBBType();
517 const G4bool firstAvatar = (
theNucleus->getStore()->getBook().getAcceptedCollisions() == 0);
526 if(manyBodyFinalState)
550 (*violationEFunctor)(theSolution.
x);
552 INCL_DEBUG(
"Couldn't enforce energy conservation after an interaction, root-finding algorithm failed." <<
'\n');
553 theNucleus->getStore()->getBook().incrementEnergyViolationInteraction();
555 delete violationEFunctor;
556 violationEFunctor = NULL;
564 InteractionAvatar::ViolationEMomentumFunctor::ViolationEMomentumFunctor(
Nucleus *
const nucleus,
ParticleList const &modAndCre,
const G4double totalEnergyBeforeInteraction,
ThreeVector const &boost,
const G4bool localE) :
566 finalParticles(modAndCre),
567 initialEnergy(totalEnergyBeforeInteraction),
570 shouldUseLocalEnergy(localE)
574 for(
ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i) {
575 if ((*i)->isSrcPartner() == false){
576 (*i)->boost(boostVector);
578 particleMomenta.push_back((*i)->getMomentum());
582 InteractionAvatar::ViolationEMomentumFunctor::~ViolationEMomentumFunctor() {
583 particleMomenta.clear();
586 G4double InteractionAvatar::ViolationEMomentumFunctor::operator()(
const G4double alpha)
const {
587 scaleParticleMomenta(alpha);
590 for(ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i)
591 deltaE += (*i)->getEnergy() - (*i)->getPotentialEnergy();
592 deltaE -= initialEnergy;
596 void InteractionAvatar::ViolationEMomentumFunctor::scaleParticleMomenta(
const G4double alpha)
const {
598 std::vector<ThreeVector>::const_iterator iP = particleMomenta.begin();
599 for(ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i, ++iP) {
600 (*i)->setMomentum((*iP)*alpha);
601 (*i)->adjustEnergyFromMomentum();
602 if ((*i)->isSrcPartner() ==
false) {
604 (*i)->boost(-boostVector);
607 theNucleus->updatePotentialEnergy(*i);
609 (*i)->setPotentialEnergy(0.);
612 if(shouldUseLocalEnergy && !(*i)->isPion() && !(*i)->isEta() && !(*i)->isOmega() &&
613 !(*i)->isKaon() && !(*i)->isAntiKaon() && !(*i)->isSigma() && !(*i)->isPhoton() && !(*i)->isLambda() && !(*i)->isAntiBaryon() && !(*i)->isSrcPartner()) {
616 G4double locE = KinematicsUtils::getLocalEnergy(theNucleus, *i);
618 G4double deltaLocE = InteractionAvatar::locEAccuracy + 1E3;
619 for(
G4int iterLocE=0;
620 deltaLocE>InteractionAvatar::locEAccuracy && iterLocE<InteractionAvatar::maxIterLocE;
623 (*i)->setEnergy(energy + locE);
624 (*i)->adjustMomentumFromEnergy();
625 theNucleus->updatePotentialEnergy(*i);
626 locE = KinematicsUtils::getLocalEnergy(theNucleus, *i);
627 deltaLocE = std::abs(locE-locEOld);
632 if(shouldUseLocalEnergy && (*i)->isLambda() && theNucleus->getA()>19 && !(*i)->isSrcPartner()) {
635 G4double locE = KinematicsUtils::getLocalEnergy(theNucleus, *i);
637 G4double deltaLocE = InteractionAvatar::locEAccuracy + 1E3;
638 for(
G4int iterLocE=0;
639 deltaLocE>InteractionAvatar::locEAccuracy && iterLocE<InteractionAvatar::maxIterLocE;
642 (*i)->setEnergy(energy + locE);
643 (*i)->adjustMomentumFromEnergy();
644 theNucleus->updatePotentialEnergy(*i);
645 locE = KinematicsUtils::getLocalEnergy(theNucleus, *i);
646 deltaLocE = std::abs(locE-locEOld);
652 void InteractionAvatar::ViolationEMomentumFunctor::cleanUp(
const G4bool success)
const {
654 scaleParticleMomenta(1.);
661 InteractionAvatar::ViolationEEnergyFunctor::ViolationEEnergyFunctor(Nucleus *
const nucleus, Particle *
const aParticle,
const G4double totalEnergyBeforeInteraction,
const G4bool localE) :
662 RootFunctor(0., 1E6),
663 initialEnergy(totalEnergyBeforeInteraction),
665 theParticle(aParticle),
666 theEnergy(theParticle->getEnergy()),
667 theMomentum(theParticle->getMomentum()),
669 shouldUseLocalEnergy(localE)
674 G4double InteractionAvatar::ViolationEEnergyFunctor::operator()(
const G4double alpha)
const {
675 setParticleEnergy(alpha);
676 return theParticle->getEnergy() - theParticle->getPotentialEnergy() - initialEnergy;
679 void InteractionAvatar::ViolationEEnergyFunctor::setParticleEnergy(
const G4double alpha)
const {
689 for(
G4int iterLocE=0;
693 G4double particleEnergy = energyThreshold + locE +
alpha*(theEnergy-energyThreshold);
694 const G4double theMass2 = std::pow(particleEnergy,2.)-theMomentum.mag2();
697 theMass = std::sqrt(theMass2);
700 particleEnergy = energyThreshold;
702 theParticle->setMass(theMass);
703 theParticle->setEnergy(particleEnergy);
705 theNucleus->updatePotentialEnergy(theParticle);
712 deltaLocE = std::abs(locE-locEOld);
717 void InteractionAvatar::ViolationEEnergyFunctor::cleanUp(
const G4bool success)
const {
719 setParticleEnergy(1.);
Simple container for output of event results.
Static root-finder algorithm.
ParticleList & getSrcModifiedParticles()
std::string print() const
ParticleList const & getModifiedParticles() const
void setTotalEnergyBeforeInteraction(G4double E)
void makeNoEnergyConservation()
void addOutgoingParticle(Particle *p)
ParticleList const & getDestroyedParticles() const
G4double getTotalEnergyBeforeInteraction() const
ParticleList const & getCreatedParticles() const
AvatarType getType() const
static const G4int maxIterLocE
Max number of iterations for the determination of the local-energy Q-value.
void restoreParticles() const
Restore the state of both particles.
ParticleList modifiedAndCreated
ParticleList ModifiedAndDestroyed
static InteractionAvatar * Instance()
virtual ~InteractionAvatar()
G4bool enforceEnergyConservation(FinalState *const fs)
Enforce energy conservation.
static void deleteBackupParticles()
Release the memory allocated for the backup particles.
void preInteractionBlocking()
Store the state of the particles before the interaction.
static const G4double locEAccuracy
Target accuracy in the determination of the local-energy Q-value.
void restoreSrcPartner(FinalState *fs)
InteractionAvatar(G4double, G4INCL::Nucleus *, G4INCL::Particle *)
static G4ThreadLocal Particle * backupParticle2
G4bool shouldUseLocalEnergy() const
true if the given avatar should use local energy
void postInteraction(FinalState *)
static G4ThreadLocal Particle * backupParticle1
G4bool bringParticleInside(Particle *const p)
void preInteractionLocalEnergy(Particle *const p)
Apply local-energy transformation, if appropriate.
void setSrcPartner(Particle *p)
G4bool isPhoton() const
Is this a photon?
G4bool isMeson() const
Is this a Meson?
void rpCorrelate()
Make the particle follow a strict r-p correlation.
static void FillINCLBiasVector(G4double newBias)
const G4INCL::ThreeVector & getPosition() const
G4bool isAntiNucleon() const
Is this an antinucleon?
G4double getMass() const
Get the cached particle mass.
static G4ThreadLocal G4int nextBiasedCollisionID
virtual void setPosition(const G4INCL::ThreeVector &position)
G4double total(Particle const *const p1, Particle const *const p2)
G4double energy(const ThreeVector &p, const G4double m)
ThreeVector makeBoostVector(Particle const *const p1, Particle const *const p2)
void transformToLocalEnergyFrame(Nucleus const *const n, Particle *const p)
G4double getLocalEnergy(Nucleus const *const n, Particle *const p)
G4ThreadLocal G4double minDeltaMass2
G4ThreadLocal G4double minDeltaMass
const G4double effectiveNucleonMass
G4bool isBlocked(ParticleList const &p, Nucleus const *const n)
Check Pauli blocking.
G4bool isCDPPBlocked(ParticleList const &p, Nucleus const *const n)
Check CDPP blocking.
Solution solve(RootFunctor const *const f, const G4double x0)
Numerically solve a one-dimensional equation.
ParticleList::const_iterator ParticleIter
@ FirstCollisionLocalEnergy