34#define INCLXX_IN_GEANT4_MODE 1
68 particle1(p1), particle2(NULL),
71 violationEFunctor(NULL)
78 particle1(p1), particle2(p2),
79 isPiN((p1->isPion() && p2->isNucleon()) || (p2->isPion() && p1->isNucleon())),
81 violationEFunctor(NULL)
98 (*backupParticle1) = (*particle1);
104 (*backupParticle2) = (*particle2);
147 const short maxIterations=50;
149 if(pos2 < r*r)
return true;
151 while( pos2 >= r*r && iterations<maxIterations )
153 pos *= std::sqrt(r*r*0.9801/pos2);
157 if( iterations < maxIterations)
159 INCL_DEBUG(
"Particle position vector length was : " << p->
getPosition().
mag() <<
", rescaled to: " << pos.mag() <<
'\n');
168 INCL_DEBUG(
"postInteraction: final state: " <<
'\n' << fs->
print() <<
'\n');
186 if(((*i)->isPion() || (*i)->isKaon() || (*i)->isAntiKaon()) && (*i)->getPosition().mag() >
theNucleus->
getSurfaceRadius(*i)) {
187 (*i)->makeParticipant();
188 (*i)->setOutOfWell();
190 INCL_DEBUG(
"Pion was created outside its potential well." <<
'\n'
198 INCL_DEBUG(
"Enforcing energy conservation: failed!" <<
'\n');
213 INCL_DEBUG(
"Enforcing energy conservation: success!" <<
'\n');
215 INCL_DEBUG(
"postInteraction after energy conservation: final state: " <<
'\n' << fs->
print() <<
'\n');
219 if((*i)->isDelta() &&
221 INCL_DEBUG(
"Mass of the produced delta below decay threshold; forbidding collision. deltaMass=" <<
222 (*i)->getMass() <<
'\n');
285 if((*i)->isOutOfWell())
continue;
288 if( !successBringParticlesInside ) {
289 INCL_ERROR(
"Failed to bring particle inside the nucleus!" <<
'\n');
295 std::vector<G4int> newBiasCollisionVector;
297 if(std::fabs(
weight-1.) > 1E-6){
303 (*i)->setBiasCollisionVector(newBiasCollisionVector);
304 if(!(*i)->isOutOfWell()) {
307 G4bool goesBackToSpectator =
false;
309 G4double threshold = (*i)->getPotentialEnergy();
310 if((*i)->getType()==
Proton)
312 if((*i)->getKineticEnergy() < threshold)
313 goesBackToSpectator =
true;
316 (*i)->thawPropagation();
319 if(goesBackToSpectator) {
320 INCL_DEBUG(
"The following particle goes back to spectator:" <<
'\n'
321 << (*i)->print() <<
'\n');
322 if(!(*i)->isTargetSpectator()) {
325 (*i)->makeTargetSpectator();
327 if((*i)->isTargetSpectator()) {
330 (*i)->makeParticipant();
335 for(
ParticleIter i=destroyed.begin(), e=destroyed.end(); i!=e; ++i )
336 if(!(*i)->isTargetSpectator())
342 (*particle1) = (*backupParticle1);
344 (*particle2) = (*backupParticle2);
368 if(manyBodyFinalState)
392 (*violationEFunctor)(theSolution.
x);
394 INCL_DEBUG(
"Couldn't enforce energy conservation after an interaction, root-finding algorithm failed." <<
'\n');
397 delete violationEFunctor;
398 violationEFunctor = NULL;
406 InteractionAvatar::ViolationEMomentumFunctor::ViolationEMomentumFunctor(
Nucleus *
const nucleus,
ParticleList const &modAndCre,
const G4double totalEnergyBeforeInteraction,
ThreeVector const &boost,
const G4bool localE) :
408 finalParticles(modAndCre),
409 initialEnergy(totalEnergyBeforeInteraction),
412 shouldUseLocalEnergy(localE)
416 for(
ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i) {
417 (*i)->boost(boostVector);
418 particleMomenta.push_back((*i)->getMomentum());
422 InteractionAvatar::ViolationEMomentumFunctor::~ViolationEMomentumFunctor() {
423 particleMomenta.clear();
426 G4double InteractionAvatar::ViolationEMomentumFunctor::operator()(
const G4double alpha)
const {
427 scaleParticleMomenta(alpha);
430 for(
ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i)
431 deltaE += (*i)->getEnergy() - (*i)->getPotentialEnergy();
432 deltaE -= initialEnergy;
436 void InteractionAvatar::ViolationEMomentumFunctor::scaleParticleMomenta(
const G4double alpha)
const {
438 std::vector<ThreeVector>::const_iterator iP = particleMomenta.begin();
439 for(
ParticleIter i=finalParticles.begin(), e=finalParticles.end(); i!=e; ++i, ++iP) {
440 (*i)->setMomentum((*iP)*alpha);
441 (*i)->adjustEnergyFromMomentum();
447 (*i)->setPotentialEnergy(0.);
451 !(*i)->isKaon() && !(*i)->isAntiKaon() && !(*i)->isSigma() && !(*i)->isPhoton() && !(*i)->isLambda() && !(*i)->isAntiBaryon()) {
457 for(
G4int iterLocE=0;
461 (*i)->setEnergy(energy + locE);
462 (*i)->adjustMomentumFromEnergy();
465 deltaLocE = std::abs(locE-locEOld);
476 for(
G4int iterLocE=0;
480 (*i)->setEnergy(energy + locE);
481 (*i)->adjustMomentumFromEnergy();
484 deltaLocE = std::abs(locE-locEOld);
490 void InteractionAvatar::ViolationEMomentumFunctor::cleanUp(
const G4bool success)
const {
492 scaleParticleMomenta(1.);
499 InteractionAvatar::ViolationEEnergyFunctor::ViolationEEnergyFunctor(Nucleus *
const nucleus, Particle *
const aParticle,
const G4double totalEnergyBeforeInteraction,
const G4bool localE) :
500 RootFunctor(0., 1E6),
501 initialEnergy(totalEnergyBeforeInteraction),
503 theParticle(aParticle),
504 theEnergy(theParticle->getEnergy()),
505 theMomentum(theParticle->getMomentum()),
512 G4double InteractionAvatar::ViolationEEnergyFunctor::operator()(
const G4double alpha)
const {
513 setParticleEnergy(alpha);
517 void InteractionAvatar::ViolationEEnergyFunctor::setParticleEnergy(
const G4double alpha)
const {
527 for(
G4int iterLocE=0;
531 G4double particleEnergy = energyThreshold + locE +
alpha*(theEnergy-energyThreshold);
532 const G4double theMass2 = std::pow(particleEnergy,2.)-theMomentum.mag2();
535 theMass = std::sqrt(theMass2);
538 particleEnergy = energyThreshold;
540 theParticle->setMass(theMass);
541 theParticle->setEnergy(particleEnergy);
550 deltaLocE = std::abs(locE-locEOld);
555 void InteractionAvatar::ViolationEEnergyFunctor::cleanUp(
const G4bool success)
const {
557 setParticleEnergy(1.);
Static root-finder algorithm.
void decrementCascading()
void incrementEnergyViolationInteraction()
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.
ParticleType getProjectileType() const
Get the projectile type.
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.
void updatePotentialEnergy(Particle *p) const
Update the particle potential energy.
std::vector< G4int > getParticleListBiasVector() const
void boost(const ThreeVector &b) const
G4bool isPhoton() const
Is this a photon?
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
G4bool isAntiNucleon() const
Is this an antinucleon?
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)
G4int getA() const
Returns the baryon number.
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