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.);