34#define INCLXX_IN_GEANT4_MODE 1
67 particle1(p1), particle2(NULL),
70 violationEFunctor(NULL)
77 particle1(p1), particle2(p2),
78 isPiN((p1->isPion() && p2->isNucleon()) || (p2->isPion() && p1->isNucleon())),
80 violationEFunctor(NULL)
97 (*backupParticle1) = (*particle1);
103 (*backupParticle2) = (*particle2);
146 const short maxIterations=50;
148 if(pos2 < r*r)
return true;
150 while( pos2 >= r*r && iterations<maxIterations )
152 pos *= std::sqrt(r*r*0.9801/pos2);
156 if( iterations < maxIterations)
158 INCL_DEBUG(
"Particle position vector length was : " << p->
getPosition().
mag() <<
", rescaled to: " << pos.mag() <<
'\n');
167 INCL_DEBUG(
"postInteraction: final state: " <<
'\n' << fs->
print() <<
'\n');
185 if(((*i)->isPion() || (*i)->isKaon() || (*i)->isAntiKaon()) && (*i)->getPosition().mag() >
theNucleus->
getSurfaceRadius(*i)) {
186 (*i)->makeParticipant();
187 (*i)->setOutOfWell();
189 INCL_DEBUG(
"Pion was created outside its potential well." <<
'\n'
197 INCL_DEBUG(
"Enforcing energy conservation: failed!" <<
'\n');
212 INCL_DEBUG(
"Enforcing energy conservation: success!" <<
'\n');
214 INCL_DEBUG(
"postInteraction after energy conservation: final state: " <<
'\n' << fs->
print() <<
'\n');
218 if((*i)->isDelta() &&
220 INCL_DEBUG(
"Mass of the produced delta below decay threshold; forbidding collision. deltaMass=" <<
221 (*i)->getMass() <<
'\n');
284 if((*i)->isOutOfWell())
continue;
287 if( !successBringParticlesInside ) {
288 INCL_ERROR(
"Failed to bring particle inside the nucleus!" <<
'\n');
294 std::vector<G4int> newBiasCollisionVector;
296 if(std::fabs(
weight-1.) > 1E-6){
302 (*i)->setBiasCollisionVector(newBiasCollisionVector);
303 if(!(*i)->isOutOfWell()) {
306 G4bool goesBackToSpectator =
false;
308 G4double threshold = (*i)->getPotentialEnergy();
309 if((*i)->getType()==
Proton)
311 if((*i)->getKineticEnergy() < threshold)
312 goesBackToSpectator =
true;
315 (*i)->thawPropagation();
318 if(goesBackToSpectator) {
319 INCL_DEBUG(
"The following particle goes back to spectator:" <<
'\n'
320 << (*i)->print() <<
'\n');
321 if(!(*i)->isTargetSpectator()) {
324 (*i)->makeTargetSpectator();
326 if((*i)->isTargetSpectator()) {
329 (*i)->makeParticipant();
334 for(
ParticleIter i=destroyed.begin(), e=destroyed.end(); i!=e; ++i )
335 if(!(*i)->isTargetSpectator())
341 (*particle1) = (*backupParticle1);
343 (*particle2) = (*backupParticle2);
363 if(manyBodyFinalState)
377 (*violationEFunctor)(theSolution.
x);
379 INCL_DEBUG(
"Couldn't enforce energy conservation after an interaction, root-finding algorithm failed." <<
'\n');
382 delete violationEFunctor;
383 violationEFunctor = NULL;
391 InteractionAvatar::ViolationEMomentumFunctor::ViolationEMomentumFunctor(
Nucleus *
const nucleus,
ParticleList const &modAndCre,
const G4double totalEnergyBeforeInteraction,
ThreeVector const &boost,
const G4bool localE) :
393 finalParticles(modAndCre),
394 initialEnergy(totalEnergyBeforeInteraction),
397 shouldUseLocalEnergy(localE)
401 for(
ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i) {
403 particleMomenta.push_back((*i)->getMomentum());
407 InteractionAvatar::ViolationEMomentumFunctor::~ViolationEMomentumFunctor() {
408 particleMomenta.clear();
411 G4double InteractionAvatar::ViolationEMomentumFunctor::operator()(
const G4double alpha)
const {
412 scaleParticleMomenta(alpha);
415 for(
ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i)
416 deltaE += (*i)->getEnergy() - (*i)->getPotentialEnergy();
417 deltaE -= initialEnergy;
421 void InteractionAvatar::ViolationEMomentumFunctor::scaleParticleMomenta(
const G4double alpha)
const {
423 std::vector<ThreeVector>::const_iterator iP = particleMomenta.begin();
424 for(
ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i, ++iP) {
425 (*i)->setMomentum((*iP)*alpha);
426 (*i)->adjustEnergyFromMomentum();
428 (*i)->boost(-boostVector);
430 theNucleus->updatePotentialEnergy(*i);
432 (*i)->setPotentialEnergy(0.);
435 if(shouldUseLocalEnergy && !(*i)->isPion() && !(*i)->isEta() && !(*i)->isOmega() &&
436 !(*i)->isKaon() && !(*i)->isAntiKaon() && !(*i)->isSigma() && !(*i)->isLambda()) {
442 for(
G4int iterLocE=0;
446 (*i)->setEnergy(energy + locE);
447 (*i)->adjustMomentumFromEnergy();
448 theNucleus->updatePotentialEnergy(*i);
450 deltaLocE = std::abs(locE-locEOld);
455 if(shouldUseLocalEnergy && (*i)->isLambda() && theNucleus->getA()>19) {
461 for(
G4int iterLocE=0;
465 (*i)->setEnergy(energy + locE);
466 (*i)->adjustMomentumFromEnergy();
467 theNucleus->updatePotentialEnergy(*i);
469 deltaLocE = std::abs(locE-locEOld);
475 void InteractionAvatar::ViolationEMomentumFunctor::cleanUp(
const G4bool success)
const {
477 scaleParticleMomenta(1.);
484 InteractionAvatar::ViolationEEnergyFunctor::ViolationEEnergyFunctor(Nucleus *
const nucleus, Particle *
const aParticle,
const G4double totalEnergyBeforeInteraction,
const G4bool localE) :
485 RootFunctor(0., 1E6),
486 initialEnergy(totalEnergyBeforeInteraction),
488 theParticle(aParticle),
489 theEnergy(theParticle->getEnergy()),
490 theMomentum(theParticle->getMomentum()),
492 shouldUseLocalEnergy(localE)
497 G4double InteractionAvatar::ViolationEEnergyFunctor::operator()(
const G4double alpha)
const {
498 setParticleEnergy(alpha);
499 return theParticle->getEnergy() - theParticle->getPotentialEnergy() - initialEnergy;
502 void InteractionAvatar::ViolationEEnergyFunctor::setParticleEnergy(
const G4double alpha)
const {
505 if(shouldUseLocalEnergy) {
512 for(
G4int iterLocE=0;
516 G4double particleEnergy = energyThreshold + locE +
alpha*(theEnergy-energyThreshold);
517 const G4double theMass2 = std::pow(particleEnergy,2.)-theMomentum.mag2();
520 theMass = std::sqrt(theMass2);
523 particleEnergy = energyThreshold;
525 theParticle->setMass(theMass);
526 theParticle->setEnergy(particleEnergy);
528 theNucleus->updatePotentialEnergy(theParticle);
529 if(shouldUseLocalEnergy)
535 deltaLocE = std::abs(locE-locEOld);
540 void InteractionAvatar::ViolationEEnergyFunctor::cleanUp(
const G4bool success)
const {
542 setParticleEnergy(1.);
Static root-finder algorithm.
void decrementCascading()
void incrementEnergyViolationInteraction()
G4int getAcceptedCollisions() const
void incrementCascading()
LocalEnergyType getLocalEnergyPiType() const
Get the type of local energy for pi-N and decay avatars.
G4bool getBackToSpectator() const
Get back-to-spectator.
LocalEnergyType getLocalEnergyBBType() const
Get the type of local energy for N-N avatars.
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
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.
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.
G4double getSurfaceRadius(Particle const *const particle) const
Get the maximum allowed radius for a given particle.
G4double getTransmissionBarrier(Particle const *const p)
Get the transmission barrier.
std::vector< G4int > getParticleListBiasVector() const
void boost(const ThreeVector &b) const
G4bool isMeson() const
Is this a Meson?
G4double getEnergy() const
G4double getPotentialEnergy() const
Get the particle potential energy.
void rpCorrelate()
Make the particle follow a strict r-p correlation.
static void FillINCLBiasVector(G4double newBias)
const G4INCL::ThreeVector & getPosition() const
const G4INCL::ThreeVector & getMomentum() const
G4double getMass() const
Get the cached particle mass.
void boost(const ThreeVector &aBoostVector)
static G4ThreadLocal G4int nextBiasedCollisionID
virtual void setPosition(const G4INCL::ThreeVector &position)
Config const * getConfig()
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
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