35#define INCLXX_IN_GEANT4_MODE 1
66 particle1(p1), particle2(NULL), isPiN(false)
73 particle1(p1), particle2(p2),
74 isPiN((p1->isPion() && p2->isNucleon()) || (p2->isPion() && p1->isNucleon()))
136 const short maxIterations=50;
138 if(pos2 < r*r)
return true;
140 while( pos2 >= r*r && iterations<maxIterations )
142 pos *= std::sqrt(r*r*0.99/pos2);
146 if( iterations < maxIterations)
148 DEBUG(
"Particle position vector length was : " << p->
getPosition().
mag() <<
", rescaled to: " << pos.
mag() << std::endl);
160 modifiedAndCreated.insert(modifiedAndCreated.end(), created.begin(), created.end());
164 for(
ParticleIter i = modifiedAndCreated.begin(); i != modifiedAndCreated.end(); ++i )
173 for(
ParticleIter i = created.begin(); i != created.end(); ++i )
175 (*i)->makeParticipant();
176 (*i)->setOutOfWell();
178 DEBUG(
"Pion was created outside its potential well." << std::endl
188 DEBUG(
"Enforcing energy conservation: failed!" << std::endl);
194 for(
ParticleIter i = created.begin(); i != created.end(); ++i )
204 DEBUG(
"Enforcing energy conservation: success!" << std::endl);
207 for(
ParticleIter i = modified.begin(); i != modified.end(); ++i )
208 if((*i)->isDelta() &&
210 DEBUG(
"Mass of the produced delta below decay threshold; forbidding collision. deltaMass=" <<
211 (*i)->getMass() << std::endl);
217 for(
ParticleIter j = created.begin(); j != created.end(); ++j )
232 DEBUG(
"Pauli: Blocked!" << std::endl);
238 for(
ParticleIter i = created.begin(); i != created.end(); ++i )
248 DEBUG(
"Pauli: Allowed!" << std::endl);
254 DEBUG(
"CDPP: Blocked!" << std::endl);
260 for(
ParticleIter i = created.begin(); i != created.end(); ++i )
270 DEBUG(
"CDPP: Allowed!" << std::endl);
273 for(
ParticleIter i = modifiedAndCreated.begin(); i != modifiedAndCreated.end(); ++i )
276 if((*i)->isOutOfWell())
continue;
279 if( !successBringParticlesInside ) {
280 ERROR(
"Failed to bring particle inside the nucleus!" << std::endl);
285 for(
ParticleIter i = modifiedAndCreated.begin(); i != modifiedAndCreated.end(); ++i ) {
286 if(!(*i)->isOutOfWell()) {
289 G4bool goesBackToSpectator =
false;
291 G4double threshold = (*i)->getPotentialEnergy();
292 if((*i)->getType()==
Proton)
294 if((*i)->getKineticEnergy() < threshold)
295 goesBackToSpectator =
true;
299 (*i)->thawPropagation();
302 if(goesBackToSpectator) {
303 DEBUG(
"The following particle goes back to spectator:" << std::endl
304 << (*i)->print() << std::endl);
305 if(!(*i)->isTargetSpectator()) {
308 (*i)->makeTargetSpectator();
310 if((*i)->isTargetSpectator()) {
313 (*i)->makeParticipant();
318 for(
ParticleIter i = destroyed.begin(); i != destroyed.end(); ++i )
319 if(!(*i)->isTargetSpectator())
349 if(manyBodyFinalState)
352 Particle const *
const p = modified.front();
357 violationEFunctor =
new ViolationEEnergyFunctor(
theNucleus, fs);
364 (*violationEFunctor)(theSolution.first);
366 WARN(
"Couldn't enforce energy conservation after an interaction, root-finding algorithm failed." << std::endl);
368 delete violationEFunctor;
376 InteractionAvatar::ViolationEMomentumFunctor::ViolationEMomentumFunctor(
Nucleus *
const nucleus,
FinalState const *
const finalState,
ThreeVector const *
const boost,
const G4bool localE) :
378 initialEnergy(finalState->getTotalEnergyBeforeInteraction()),
381 shouldUseLocalEnergy(localE)
386 finalParticles.splice(finalParticles.end(), created);
390 particleMomenta.clear();
391 for(
ParticleIter i=finalParticles.begin(); i!=finalParticles.end(); ++i) {
393 particleMomenta.push_back((*i)->getMomentum());
397 G4double InteractionAvatar::ViolationEMomentumFunctor::operator()(
const G4double alpha)
const {
398 scaleParticleMomenta(alpha);
401 for(
ParticleIter i=finalParticles.begin(); i!=finalParticles.end(); ++i)
402 deltaE += (*i)->getEnergy() - (*i)->getPotentialEnergy();
403 deltaE -= initialEnergy;
407 void InteractionAvatar::ViolationEMomentumFunctor::scaleParticleMomenta(
const G4double alpha)
const {
409 std::list<ThreeVector>::const_iterator iP = particleMomenta.begin();
410 for(
ParticleIter i=finalParticles.begin(); i!=finalParticles.end(); ++i, ++iP) {
411 (*i)->setMomentum((*iP)*alpha);
412 (*i)->adjustEnergyFromMomentum();
413 (*i)->boost(-(*boostVector));
415 theNucleus->updatePotentialEnergy(*i);
417 (*i)->setPotentialEnergy(0.);
419 if(shouldUseLocalEnergy && !(*i)->isPion()) {
421 const G4double energy = (*i)->getEnergy();
425 for(
G4int iterLocE=0;
429 (*i)->setEnergy(energy + locE);
430 (*i)->adjustMomentumFromEnergy();
431 theNucleus->updatePotentialEnergy(*i);
433 deltaLocE = std::abs(locE-locEOld);
439 void InteractionAvatar::ViolationEMomentumFunctor::cleanUp(
const G4bool success)
const {
441 scaleParticleMomenta(1.);
448 InteractionAvatar::ViolationEEnergyFunctor::ViolationEEnergyFunctor(Nucleus *
const nucleus, FinalState
const *
const finalState) :
449 RootFunctor(0., 1E6),
450 initialEnergy(finalState->getTotalEnergyBeforeInteraction()),
452 theParticle(finalState->getModifiedParticles().front()),
453 theEnergy(theParticle->getEnergy()),
454 theMomentum(theParticle->getMomentum()),
455 energyThreshold(KinematicsUtils::energy(theMomentum,ParticleTable::effectiveDeltaDecayThreshold))
462 G4double InteractionAvatar::ViolationEEnergyFunctor::operator()(
const G4double alpha)
const {
463 setParticleEnergy(alpha);
464 return theParticle->getEnergy() - theParticle->getPotentialEnergy() - initialEnergy;
467 void InteractionAvatar::ViolationEEnergyFunctor::setParticleEnergy(
const G4double alpha)
const {
472 for(
G4int iterLocE=0;
476 const G4double particleEnergy = energyThreshold +
alpha*(theEnergy-energyThreshold);
477 const G4double theMass = std::sqrt(std::pow(particleEnergy,2.)-theMomentum.mag2());
478 theParticle->setMass(theMass);
479 theParticle->setEnergy(particleEnergy + locE);
480 theParticle->adjustMomentumFromEnergy();
481 theNucleus->updatePotentialEnergy(theParticle);
483 deltaLocE = std::abs(locE-locEOld);
488 void InteractionAvatar::ViolationEEnergyFunctor::cleanUp(
const G4bool success)
const {
490 setParticleEnergy(1.);
Static root-finder algorithm.
void decrementCascading()
void incrementCascading()
G4bool getBackToSpectator() const
Get back-to-spectator.
static G4double total(Particle const *const p1, Particle const *const p2)
ParticleList const & getModifiedParticles() const
void setTotalEnergyBeforeInteraction(G4double E)
void makeNoEnergyConservation()
void addOutgoingParticle(Particle *p)
ParticleList const & getDestroyedParticles() const
ParticleList const & getCreatedParticles() const
static const G4int maxIterLocE
Max number of iterations for the determination of the local-energy Q-value.
G4double oldParticle1Energy
FinalState * postInteraction(FinalState *)
void restoreParticles() const
Restore the state of both particles.
G4double oldParticle2Energy
G4double oldParticle2Potential
G4double oldParticle2Mass
ThreeVector oldParticle2Position
G4double oldParticle2Helicity
G4INCL::Particle * particle1
ParticleType oldParticle2Type
virtual ~InteractionAvatar()
G4bool enforceEnergyConservation(FinalState *const fs)
Enforce energy conservation.
G4INCL::Particle * particle2
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.
G4double oldParticle1Potential
InteractionAvatar(G4double, G4INCL::Nucleus *, G4INCL::Particle *)
ThreeVector oldParticle2Momentum
G4INCL::Nucleus * theNucleus
ThreeVector oldParticle1Momentum
G4bool shouldUseLocalEnergy() const
true if the given avatar should use local energy
ThreeVector oldParticle1Position
G4double oldParticle1Helicity
G4double oldParticle1Mass
G4bool bringParticleInside(Particle *const p)
void preInteractionLocalEnergy(Particle *const p)
Apply local-energy transformation, if appropriate.
ParticleType oldParticle1Type
static ThreeVector makeBoostVector(Particle const *const p1, Particle const *const p2)
static void transformToLocalEnergyFrame(Nucleus const *const n, Particle *const p)
static G4double getLocalEnergy(Nucleus const *const n, Particle *const p)
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.
static const G4double effectiveDeltaDecayThreshold
void setPotentialEnergy(G4double v)
Set the particle potential energy.
G4double getEnergy() const
G4double getPotentialEnergy() const
Get the particle potential energy.
void setMass(G4double mass)
void setHelicity(G4double h)
const G4INCL::ThreeVector & getPosition() const
G4bool isPion() const
Is this a pion?
const G4INCL::ThreeVector & getMomentum() const
virtual void setMomentum(const G4INCL::ThreeVector &momentum)
G4INCL::ParticleType getType() const
void setEnergy(G4double energy)
void setType(ParticleType t)
G4double getMass() const
Get the cached particle mass.
void boost(const ThreeVector &aBoostVector)
virtual void setPosition(const G4INCL::ThreeVector &position)
static G4bool isBlocked(ParticleList const p, Nucleus const *const n)
Check Pauli blocking.
static G4bool isCDPPBlocked(ParticleList const p, Nucleus const *const n)
Check CDPP blocking.
static std::pair< G4double, G4double > const & getSolution()
Get the solution of the last call to solve().
static G4bool solve(RootFunctor const *const f, const G4double x0)
Numerically solve a one-dimensional equation.
Config const * getConfig()
std::list< G4INCL::Particle * > ParticleList
std::list< G4INCL::Particle * >::const_iterator ParticleIter