33 #define INCLXX_IN_GEANT4_MODE 1 
   64     particle1(p1), particle2(NULL), isPiN(false)
 
   71     particle1(p1), particle2(p2),
 
   72     isPiN((p1->isPion() && p2->isNucleon()) || (p2->isPion() && p1->isNucleon()))
 
  134     const short maxIterations=50;
 
  136     if(pos2 < r*r) 
return true;
 
  138     while( pos2 >= r*r && iterations<maxIterations )
 
  140       pos *= std::sqrt(r*r*0.99/pos2);
 
  144     if( iterations < maxIterations)
 
  146       DEBUG(
"Particle position vector length was : " << p->
getPosition().
mag() << 
", rescaled to: " << pos.
mag() << std::endl);
 
  158     modifiedAndCreated.insert(modifiedAndCreated.end(), created.begin(), created.end());
 
  162       for( 
ParticleIter i = modifiedAndCreated.begin(); i != modifiedAndCreated.end(); ++i )
 
  171     for( 
ParticleIter i = created.begin(); i != created.end(); ++i )
 
  173         (*i)->makeParticipant();
 
  174         (*i)->setOutOfWell();
 
  176         DEBUG(
"Pion was created outside its potential well." << std::endl
 
  186       DEBUG(
"Enforcing energy conservation: failed!" << std::endl);
 
  192       for( 
ParticleIter i = created.begin(); i != created.end(); ++i )
 
  202     DEBUG(
"Enforcing energy conservation: success!" << std::endl);
 
  205     for( 
ParticleIter i = modified.begin(); i != modified.end(); ++i )
 
  206       if((*i)->isDelta() &&
 
  208         DEBUG(
"Mass of the produced delta below decay threshold; forbidding collision. deltaMass=" <<
 
  209             (*i)->getMass() << std::endl);
 
  215         for( 
ParticleIter j = created.begin(); j != created.end(); ++j )
 
  230       DEBUG(
"Pauli: Blocked!" << std::endl);
 
  236       for( 
ParticleIter i = created.begin(); i != created.end(); ++i )
 
  246     DEBUG(
"Pauli: Allowed!" << std::endl);
 
  252       DEBUG(
"CDPP: Blocked!" << std::endl);
 
  258       for( 
ParticleIter i = created.begin(); i != created.end(); ++i )
 
  268     DEBUG(
"CDPP: Allowed!" << std::endl);
 
  271     for( 
ParticleIter i = modifiedAndCreated.begin(); i != modifiedAndCreated.end(); ++i )
 
  274       if((*i)->isOutOfWell()) 
continue;
 
  277       if( !successBringParticlesInside ) {
 
  278         ERROR(
"Failed to bring particle inside the nucleus!" << std::endl);
 
  283     for( 
ParticleIter i = modifiedAndCreated.begin(); i != modifiedAndCreated.end(); ++i ) {
 
  284       if(!(*i)->isOutOfWell()) {
 
  287         G4bool goesBackToSpectator = 
false;
 
  289           G4double threshold = (*i)->getPotentialEnergy();
 
  290           if((*i)->getType()==
Proton)
 
  292           if((*i)->getKineticEnergy() < threshold)
 
  293             goesBackToSpectator = 
true;
 
  297         (*i)->thawPropagation();
 
  300         if(goesBackToSpectator) {
 
  301           DEBUG(
"The following particle goes back to spectator:" << std::endl
 
  302               << (*i)->print() << std::endl);
 
  303           if(!(*i)->isTargetSpectator()) {
 
  306           (*i)->makeTargetSpectator();
 
  308           if((*i)->isTargetSpectator()) {
 
  311           (*i)->makeParticipant();
 
  316     for( 
ParticleIter i = destroyed.begin(); i != destroyed.end(); ++i )
 
  317       if(!(*i)->isTargetSpectator())
 
  347     if(manyBodyFinalState)
 
  350       Particle const * 
const p = modified.front();
 
  355       violationEFunctor = 
new ViolationEEnergyFunctor(
theNucleus, fs);
 
  362       (*violationEFunctor)(theSolution.first);
 
  364       WARN(
"Couldn't enforce energy conservation after an interaction, root-finding algorithm failed." << std::endl);
 
  366     delete violationEFunctor;
 
  374   InteractionAvatar::ViolationEMomentumFunctor::ViolationEMomentumFunctor(
Nucleus * 
const nucleus, 
FinalState const * 
const finalState, 
ThreeVector const * 
const boost, 
const G4bool localE) :
 
  376     initialEnergy(finalState->getTotalEnergyBeforeInteraction()),
 
  379     shouldUseLocalEnergy(localE)
 
  384     finalParticles.splice(finalParticles.end(), created);
 
  388     particleMomenta.clear();
 
  389     for(
ParticleIter i=finalParticles.begin(); i!=finalParticles.end(); ++i) {
 
  391       particleMomenta.push_back((*i)->getMomentum());
 
  396     scaleParticleMomenta(alpha);
 
  399     for(
ParticleIter i=finalParticles.begin(); i!=finalParticles.end(); ++i)
 
  400       deltaE += (*i)->getEnergy() - (*i)->getPotentialEnergy();
 
  401     deltaE -= initialEnergy;
 
  405   void InteractionAvatar::ViolationEMomentumFunctor::scaleParticleMomenta(
const G4double alpha)
 const {
 
  407     std::list<ThreeVector>::const_iterator iP = particleMomenta.begin();
 
  408     for(
ParticleIter i=finalParticles.begin(); i!=finalParticles.end(); ++i, ++iP) {
 
  409       (*i)->setMomentum((*iP)*alpha);
 
  410       (*i)->adjustEnergyFromMomentum();
 
  411       (*i)->boost(-(*boostVector));
 
  413         theNucleus->updatePotentialEnergy(*i);
 
  415         (*i)->setPotentialEnergy(0.);
 
  417       if(shouldUseLocalEnergy && !(*i)->isPion()) { 
 
  423         for(
G4int iterLocE=0;
 
  427           (*i)->setEnergy(energy + locE); 
 
  428           (*i)->adjustMomentumFromEnergy();
 
  429           theNucleus->updatePotentialEnergy(*i); 
 
  431           deltaLocE = std::abs(locE-locEOld);
 
  437   void InteractionAvatar::ViolationEMomentumFunctor::cleanUp(
const G4bool success)
 const {
 
  439       scaleParticleMomenta(1.);
 
  446   InteractionAvatar::ViolationEEnergyFunctor::ViolationEEnergyFunctor(Nucleus * 
const nucleus, FinalState 
const * 
const finalState) :
 
  447     RootFunctor(0., 1E6),
 
  448     initialEnergy(finalState->getTotalEnergyBeforeInteraction()),
 
  450     theParticle(finalState->getModifiedParticles().front()),
 
  451     theEnergy(theParticle->getEnergy()),
 
  452     theMomentum(theParticle->getMomentum()),
 
  453     energyThreshold(KinematicsUtils::energy(theMomentum,ParticleTable::effectiveDeltaDecayThreshold))
 
  460   G4double InteractionAvatar::ViolationEEnergyFunctor::operator()(
const G4double alpha)
 const {
 
  461     setParticleEnergy(alpha);
 
  462     return theParticle->getEnergy() - theParticle->getPotentialEnergy() - initialEnergy;
 
  465   void InteractionAvatar::ViolationEEnergyFunctor::setParticleEnergy(
const G4double alpha)
 const {
 
  470     for(
G4int iterLocE=0;
 
  474       const G4double particleEnergy = energyThreshold + alpha*(theEnergy-energyThreshold);
 
  475       const G4double theMass = std::sqrt(std::pow(particleEnergy,2.)-theMomentum.mag2());
 
  476       theParticle->setMass(theMass);
 
  477       theParticle->setEnergy(particleEnergy + locE); 
 
  478       theParticle->adjustMomentumFromEnergy();
 
  479       theNucleus->updatePotentialEnergy(theParticle); 
 
  481       deltaLocE = std::abs(locE-locEOld);
 
  486   void InteractionAvatar::ViolationEEnergyFunctor::cleanUp(
const G4bool success)
 const {
 
  488       setParticleEnergy(1.);