34#define INCLXX_IN_GEANT4_MODE 1
45#ifndef G4INCLNucleus_hh
46#define G4INCLNucleus_hh 1
72 :
Cluster(charge,mass,strangess,true),
73 theInitialZ(charge), theInitialA(mass), theInitialS(strangess),
74 theNpInitial(0), theNnInitial(0),
76 theNSpInitial(0), theNSzInitial(0), theNSmInitial(0),
77 theNpionplusInitial(0), theNpionminusInitial(0),
78 theNkaonplusInitial(0), theNkaonminusInitial(0),
79 theNantiprotonInitial(0),theNantineutronInitial(0),
80 initialInternalEnergy(0.), srcInternalEnergy(0.),
81 incomingAngularMomentum(0.,0.,0.), incomingMomentum(0.,0.,0.),
82 initialCenterOfMass(0.,0.,0.),
86 theUniverseRadius(universeRadius),
87 isNucleusNucleus(false),
88 theProjectileRemnant(NULL),
101 pionPotential =
true;
120 if(theUniverseRadius<0)
121 theUniverseRadius = theDensity->getMaximumRadius();
122 theStore =
new Store(conf);
144 delete theProjectileRemnant;
145 theProjectileRemnant = NULL;
167 for(
ParticleIter iter=created.begin(), e=created.end(); iter!=e; ++iter) {
168 theStore->add((*iter));
169 if(!(*iter)->isOutOfWell()) {
170 totalEnergy += (*iter)->getEnergy() - (*iter)->getPotentialEnergy();
175 for(
ParticleIter iter=deleted.begin(), e=deleted.end(); iter!=e; ++iter) {
176 theStore->particleHasBeenDestroyed(*iter);
180 for(
ParticleIter iter=modified.begin(), e=modified.end(); iter!=e; ++iter) {
181 theStore->particleHasBeenUpdated(*iter);
182 totalEnergy += (*iter)->getEnergy() - (*iter)->getPotentialEnergy();
186 for(
ParticleIter iter=out.begin(), e=out.end(); iter!=e; ++iter) {
187 if((*iter)->isCluster()) {
190#ifdef INCLXX_IN_GEANT4_MODE
195 for(
ParticleIter in=components.begin(), end=components.end(); in!=end; ++in)
196 theStore->particleHasBeenEjected(*in);
198 theStore->particleHasBeenEjected(*iter);
200 totalEnergy += (*iter)->getEnergy();
201 theA -= (*iter)->getA();
202 theZ -= (*iter)->getZ();
203 theS -= (*iter)->getS();
204 theStore->addToOutgoing(*iter);
205 (*iter)->setEmissionTime(theStore->getBook().getCurrentTime());
209 for(
ParticleIter iter=entering.begin(), e=entering.end(); iter!=e; ++iter) {
211 totalEnergy += (*iter)->getEnergy() - (*iter)->getPotentialEnergy();
215 theStore->removeScheduledAvatars();
217 INCL_DEBUG(
"A Particle is entering below the Fermi sea:" <<
'\n' << finalstate->
print() <<
'\n');
220 for(
ParticleIter iter=entering.begin(), e=entering.end(); iter!=e; ++iter) {
227 INCL_ERROR(
"Energy nonconservation! Energy at the beginning of the event = "
229 <<
" and after interaction = "
230 << totalEnergy <<
'\n'
231 << finalstate->
print());
236 INCL_WARN(
"Useless Nucleus::propagateParticles -method called." <<
'\n');
242 for(
ParticleIter p=inside.begin(), e=inside.end(); p!=e; ++p) {
243 if((*p)->isNucleon())
244 totalEnergy += (*p)->getKineticEnergy() - (*p)->getPotentialEnergy();
245 else if((*p)->isResonance())
247 else if((*p)->isHyperon())
253 totalEnergy += (*p)->getEnergy() - (*p)->getPotentialEnergy();
264 computeOneNucleonRecoilKinematics();
271 theSpin = incomingAngularMomentum;
273 ParticleList const &outgoing = theStore->getOutgoingParticles();
274 for(
ParticleIter p=outgoing.begin(), e=outgoing.end(); p!=e; ++p) {
276 theSpin -= (*p)->getAngularMomentum();
278 if(theProjectileRemnant) {
279 theMomentum -= theProjectileRemnant->getMomentum();
280 theSpin -= theProjectileRemnant->getAngularMomentum();
296 for(
ParticleIter p=inside.begin(), e=inside.end(); p!=e; ++p) {
297 const G4double mass = (*p)->getMass();
298 cm += (*p)->getPosition() * mass;
309 return totalEnergy - initialInternalEnergy - separationEnergies;
317 std::stringstream ss;
318 ss <<
"Particles in the nucleus:" <<
'\n'
319 <<
"Inside:" <<
'\n';
322 for(
ParticleIter p=inside.begin(), e=inside.end(); p!=e; ++p) {
323 ss <<
"index = " <<
counter <<
'\n'
327 ss <<
"Outgoing:" <<
'\n';
328 ParticleList const &outgoing = theStore->getOutgoingParticles();
329 for(
ParticleIter p=outgoing.begin(), e=outgoing.end(); p!=e; ++p)
337 std::cout <<
"restoreSrcPartner: " << particle->
print() << std::endl;
338 std::cout <<
"restoreSrcPartner: " << m.print() << std::endl;
343 std::cout <<
"restoreSrcPartner bis: " << particle->
print() << std::endl;
347 ParticleList const &out = theStore->getOutgoingParticles();
349 for(
ParticleIter i=out.begin(), e=out.end(); i!=e; ++i) {
350 if((*i)->isDelta()) deltas.push_back((*i));
352 if(deltas.empty())
return false;
354 for(
ParticleIter i=deltas.begin(), e=deltas.end(); i!=e; ++i) {
355 INCL_DEBUG(
"Decay outgoing delta particle:" <<
'\n'
356 << (*i)->print() <<
'\n');
358 const G4double deltaMass = (*i)->getMass();
363 (*i)->setEnergy((*i)->getMass());
373 nucleon->getTableMass(),
374 pion->getTableMass());
376 newMomentum *= decayMomentum / newMomentum.
mag();
378 pion->setTableMass();
379 pion->setMomentum(newMomentum);
380 pion->adjustEnergyFromMomentum();
381 pion->setEmissionTime(nucleon->getEmissionTime());
383 pion->setBiasCollisionVector(nucleon->getBiasCollisionVector());
385 nucleon->setTableMass();
386 nucleon->setMomentum(-newMomentum);
387 nucleon->adjustEnergyFromMomentum();
388 nucleon->boost(beta);
390 theStore->addToOutgoing(pion);
408 if(thePotential->hasPionPotential() && !unphysicalRemnant)
414 for(
ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
415 if((*i)->isDelta()) deltas.push_back((*i));
418 for(
ParticleIter i=deltas.begin(), e=deltas.end(); i!=e; ++i) {
419 INCL_DEBUG(
"Decay inside delta particle:" <<
'\n'
420 << (*i)->print() <<
'\n');
426 if(unphysicalRemnant) {
427 INCL_WARN(
"Forcing delta decay inside an unphysical remnant (A=" <<
theA
428 <<
", Z=" <<
theZ <<
"). Might lead to energy-violation warnings."
447 if(unphysicalRemnant) {
448 INCL_DEBUG(
"Remnant is unphysical: Z=" <<
theZ <<
", A=" <<
theA <<
", emitting all the pions" <<
'\n');
461 if(unphysicalRemnant){
463 INCL_WARN(
"Remnant is unphysical: Z=" <<
theZ <<
", A=" <<
theA <<
", too much strange particles? -> all emit" <<
'\n');
474 for(
ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i){
475 if((*i)->isSigma() || (*i)->isAntiKaon()) stranges.push_back((*i));
476 else if((*i)->isNucleon() && (*i)->getZ() == 1) protons.push_back((*i));
477 else if((*i)->isNucleon() && (*i)->getZ() == 0) neutrons.push_back((*i));
480 if((stranges.size() > protons.size()) || (stranges.size() > neutrons.size())){
481 INCL_WARN(
"Remnant is unphysical: Nproton=" << protons.size() <<
", Nneutron=" << neutrons.size() <<
", Strange particles : " << stranges.size() <<
'\n');
489 for(
ParticleIter i=stranges.begin(), e=stranges.end(); i!=e; ++i) {
490 INCL_DEBUG(
"Absorbe inside strange particles:" <<
'\n'
491 << (*i)->print() <<
'\n');
494 decay =
new DecayAvatar((*protonIter), (*i), 0.0,
this,
true);
498 decay =
new DecayAvatar((*neutronIter), (*i), 0.0,
this,
true);
501 else if(
Random::shoot()*(protons.size() + neutrons.size()) < protons.size()){
502 decay =
new DecayAvatar((*protonIter), (*i), 0.0,
this,
true);
506 decay =
new DecayAvatar((*neutronIter), (*i), 0.0,
this,
true);
519 ParticleList const &out = theStore->getOutgoingParticles();
521 for(
ParticleIter i=out.begin(), e=out.end(); i!=e; ++i) {
525 if(pionResonances.empty())
return false;
527 for(
ParticleIter i=pionResonances.begin(), e=pionResonances.end(); i!=e; ++i) {
528 INCL_DEBUG(
"Decay outgoing pionResonances particle:" <<
'\n'
529 << (*i)->print() <<
'\n');
531 const G4double pionResonanceMass = (*i)->getMass();
536 (*i)->setEnergy((*i)->getMass());
544 Particle *
const theCreatedParticle1 = created.front();
546 if (created.size() == 1) {
551 newMomentum *= decayMomentum / newMomentum.
mag();
557 theCreatedParticle1->
boost(beta);
563 theModifiedParticle->
boost(beta);
565 theStore->addToOutgoing(theCreatedParticle1);
567 else if (created.size() == 2) {
568 Particle *
const theCreatedParticle2 = created.back();
570 theCreatedParticle1->
boost(beta);
573 theCreatedParticle2->
boost(beta);
576 theModifiedParticle->
boost(beta);
578 theStore->addToOutgoing(theCreatedParticle1);
579 theStore->addToOutgoing(theCreatedParticle2);
582 INCL_ERROR(
"Wrong number (< 2) of created particles during the decay of a pion resonance");
592 ParticleList const &out = theStore->getOutgoingParticles();
594 for(
ParticleIter i=out.begin(), e=out.end(); i!=e; ++i) {
597 if(neutralsigma.empty())
return false;
599 for(
ParticleIter i=neutralsigma.begin(), e=neutralsigma.end(); i!=e; ++i) {
600 INCL_DEBUG(
"Decay outgoing neutral sigma:" <<
'\n'
601 << (*i)->print() <<
'\n');
603 const G4double neutralsigmaMass = (*i)->getMass();
608 (*i)->setEnergy((*i)->getMass());
616 Particle *
const theCreatedParticle = created.front();
618 if (created.size() == 1) {
623 newMomentum *= decayMomentum / newMomentum.
mag();
628 theCreatedParticle->
boost(beta);
634 theModifiedParticle->
boost(beta);
636 theStore->addToOutgoing(theCreatedParticle);
639 INCL_ERROR(
"Wrong number (!= 1) of created particles during the decay of a sigma zero");
649 ParticleList const &out = theStore->getOutgoingParticles();
651 for(
ParticleIter i=out.begin(), e=out.end(); i!=e; ++i) {
652 if((*i)->getType() ==
KZero || (*i)->getType() ==
KZeroBar) neutralkaon.push_back((*i));
654 if(neutralkaon.empty())
return false;
656 for(
ParticleIter i=neutralkaon.begin(), e=neutralkaon.end(); i!=e; ++i) {
657 INCL_DEBUG(
"Transform outgoing neutral kaon:" <<
'\n'
658 << (*i)->print() <<
'\n');
672 ParticleList const &out = theStore->getOutgoingParticles();
674 for(
ParticleIter i=out.begin(), e=out.end(); i!=e; ++i) {
675 if((*i)->isCluster()) clusters.push_back((*i));
677 if(clusters.empty())
return false;
679 for(
ParticleIter i=clusters.begin(), e=clusters.end(); i!=e; ++i) {
682#ifdef INCLXX_IN_GEANT4_MODE
688 for(
ParticleIter j=decayProducts.begin(), end=decayProducts.end(); j!=end; ++j){
690 theStore->addToOutgoing(*j);
702 for(
ParticleIter j=decayProducts.begin(), e=decayProducts.end(); j!=e; ++j){
704 theStore->addToOutgoing(*j);
715 INCL_WARN(
"Forcing emissions of all pions in the nucleus." <<
'\n');
718 const G4double tinyPionEnergy = 0.1;
723 for(
ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i) {
726 INCL_DEBUG(
"Forcing emission of the following particle: "
727 << thePion->
print() <<
'\n');
733 if(kineticEnergyOutside > 0.0)
740 toEject.push_back(thePion);
743 for(
ParticleIter i=toEject.begin(), e=toEject.end(); i!=e; ++i) {
744 theStore->particleHasBeenEjected(*i);
745 theStore->addToOutgoing(*i);
756 INCL_DEBUG(
"Forcing emissions of all strange particles in the nucleus." <<
'\n');
764 for(
ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i) {
765 if((*i)->isSigma() || (*i)->isAntiKaon()) {
767 INCL_DEBUG(
"Forcing emission of the following particle: "
768 << theParticle->
print() <<
'\n');
774 if(kineticEnergyOutside > 0.0)
783 toEject.push_back(theParticle);
786 for(
ParticleIter i=toEject.begin(), e=toEject.end(); i!=e; ++i) {
787 theStore->particleHasBeenEjected(*i);
788 theStore->addToOutgoing(*i);
799 INCL_DEBUG(
"Forcing emissions of all Lambda in the nucleus." <<
'\n');
807 for(
ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i) {
808 if((*i)->isLambda()) {
810 INCL_DEBUG(
"Forcing emission of the following particle: "
811 << theLambda->
print() <<
'\n');
817 if(kineticEnergyOutside > 0.0)
825 toEject.push_back(theLambda);
828 for(
ParticleIter i=toEject.begin(), e=toEject.end(); i!=e; ++i) {
829 theStore->particleHasBeenEjected(*i);
830 theStore->addToOutgoing(*i);
833 return (
G4int)toEject.size();
842 INCL_DEBUG(
"Forcing emissions of all antiLambda in the nucleus." <<
'\n');
850 for(
ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i) {
851 if((*i)->isAntiLambda()) {
852 Particle *
const theAntiLambda = *i;
853 INCL_DEBUG(
"Forcing emission of the following particle: "
854 << theAntiLambda->
print() <<
'\n');
860 if(kineticEnergyOutside > 0.0)
868 toEject.push_back(theAntiLambda);
871 for(
ParticleIter i=toEject.begin(), e=toEject.end(); i!=e; ++i) {
872 theStore->particleHasBeenEjected(*i);
873 theStore->addToOutgoing(*i);
876 return (
G4int)toEject.size();
885 INCL_DEBUG(
"Forcing emissions of all Kaon in the nucleus." <<
'\n');
893 for(
ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i) {
896 INCL_DEBUG(
"Forcing emission of the following particle: "
897 << theKaon->
print() <<
'\n');
903 if(kineticEnergyOutside > 0.0)
911 toEject.push_back(theKaon);
914 for(
ParticleIter i=toEject.begin(), e=toEject.end(); i!=e; ++i) {
915 theStore->particleHasBeenEjected(*i);
916 theStore->addToOutgoing(*i);
920 return toEject.size() != 0;
926 INCL_DEBUG(
"Forcing annihilation of all Antinucleons and emission of all produced mesons in the nucleus." <<
'\n' );
935 for(
ParticleIter i=inside.begin(), e=inside.end(); i!=e; ++i)
936 if((*i)->isAntiNucleon()) antinucleons.push_back((*i));
939 for(
ParticleIter i=antinucleons.begin(), e=antinucleons.end(); i!=e; ++i) {
940 Particle * theAnnihilated =
nullptr;
944 for (
ParticleIter pnuc=inside.begin(), enuc=inside.end(); pnuc!=enuc;++pnuc){
945 if ((*pnuc)->isNucleon()){
946 temp_dist = ((*pnuc)->getPosition() - (*i)->getPosition()).mag();
947 if(temp_dist < dist_NbarNuc){
948 dist_NbarNuc = temp_dist;
949 theAnnihilated = (*pnuc);
954 INCL_DEBUG(
"Forcing collision of the following particle :" <<
'\n' << (*i)->print() <<
'\n' << theAnnihilated->
print() <<
'\n' );
955 theNewZ = theNewZ - (theAnnihilated->
getZ() + ((*i)->getZ()));
959 INCL_DEBUG(
"Forcing Emission of the resulting particle of the forced annihilation" <<
'\n');
961 for(
ParticleIter outs=modifiedparts.begin(), eouts=modifiedparts.end();outs!=eouts;outs++){
962 toEject.push_back((*outs));
965 if(created.size() !=0){
966 for(
ParticleIter out=created.begin(),eout=created.end();out!=eout;out++){
967 toEject.push_back((*out));
975 for(
ParticleIter iEject=toEject.begin(),eEject=toEject.end();iEject!=eEject;iEject++){
976 (*iEject)->setEmissionTime(theStore->getBook().getCurrentTime());
978 G4double kineticEnergyOutside = (*iEject)->getKineticEnergy() - (*iEject)->getPotentialEnergy() + theQValueCorrection;
979 (*iEject)->setTableMass();
980 if(kineticEnergyOutside > 0.0)
981 (*iEject)->setEnergy((*iEject)->getMass() + kineticEnergyOutside);
983 (*iEject)->setEnergy((*iEject)->getMass() + tinyEnergy);
984 (*iEject)->adjustMomentumFromEnergy();
985 (*iEject)->setPotentialEnergy(0.);
986 theStore->particleHasBeenEjected(*iEject);
987 theStore->addToOutgoing(*iEject);
996 Book const &theBook = theStore->getBook();
1000 if(nEventCollisions==0 && nEventDecays==0 && nEventClusters==0)
1007 void Nucleus::computeOneNucleonRecoilKinematics() {
1029 for(
ParticleIter j=created.begin(), e=created.end(); j!=e; ++j)
1037 if(outgoing.size() == 2) {
1039 INCL_DEBUG(
"Two particles in the outgoing channel, applying exact two-body kinematics" <<
'\n');
1043 Particle *p1 = outgoing.front(), *p2 = outgoing.back();
1044 const ThreeVector aBoostVector = incomingMomentum / initialEnergy;
1046 p1->boost(aBoostVector);
1047 const G4double sqrts = std::sqrt(initialEnergy*initialEnergy - incomingMomentum.
mag2());
1049 const G4double scale = pcm/(p1->getMomentum().mag());
1051 p1->setMomentum(p1->getMomentum()*scale);
1052 p2->setMomentum(-p1->getMomentum());
1053 p1->adjustEnergyFromMomentum();
1054 p2->adjustEnergyFromMomentum();
1056 p1->boost(-aBoostVector);
1057 p2->boost(-aBoostVector);
1061 INCL_DEBUG(
"Trying to adjust final-state momenta to achieve energy and momentum conservation" <<
'\n');
1063 const G4int maxIterations=8;
1065 G4double val=1.E+100, oldVal=1.E+100, oldOldVal=1.E+100, oldOldOldVal;
1066 ThreeVector totalMomentum, deltaP;
1067 std::vector<ThreeVector> minMomenta;
1070 minMomenta.reserve(outgoing.size());
1073 totalMomentum.setX(0.0);
1074 totalMomentum.setY(0.0);
1075 totalMomentum.setZ(0.0);
1076 for(
ParticleIter i=outgoing.begin(), e=outgoing.end(); i!=e; ++i)
1077 totalMomentum += (*i)->getMomentum();
1081 for(
ParticleIter i=outgoing.begin(), e=outgoing.end(); i!=e; ++i)
1082 totalEnergy += (*i)->getEnergy();
1085 for(
G4int iterations=0; iterations < maxIterations; ++iterations) {
1088 oldOldOldVal = oldOldVal;
1092 if(iterations%2 == 0) {
1095 deltaP = incomingMomentum - totalMomentum;
1097 for(
ParticleIter i=outgoing.begin(), e=outgoing.end(); i!=e; ++i)
1098 pOldTot += (*i)->getMomentum().mag();
1099 for(
ParticleIter i=outgoing.begin(), e=outgoing.end(); i!=e; ++i) {
1100 const ThreeVector mom = (*i)->getMomentum();
1101 (*i)->setMomentum(mom + deltaP*mom.mag()/pOldTot);
1102 (*i)->adjustEnergyFromMomentum();
1107 energyScale = initialEnergy/totalEnergy;
1108 for(
ParticleIter i=outgoing.begin(), e=outgoing.end(); i!=e; ++i) {
1109 const ThreeVector mom = (*i)->getMomentum();
1110 G4double pScale = ((*i)->getEnergy()*energyScale - std::pow((*i)->getMass(),2))/mom.mag2();
1112 (*i)->setEnergy((*i)->getEnergy()*energyScale);
1113 (*i)->adjustMomentumFromEnergy();
1119 totalMomentum.setX(0.0);
1120 totalMomentum.setY(0.0);
1121 totalMomentum.setZ(0.0);
1123 for(
ParticleIter i=outgoing.begin(), e=outgoing.end(); i!=e; ++i) {
1124 totalMomentum += (*i)->getMomentum();
1125 totalEnergy += (*i)->getEnergy();
1129 val = std::pow(totalEnergy - initialEnergy,2) +
1130 0.25*(totalMomentum - incomingMomentum).mag2();
1131 INCL_DEBUG(
"Merit function: val=" << val <<
", oldVal=" << oldVal <<
", oldOldVal=" << oldOldVal <<
", oldOldOldVal=" << oldOldOldVal <<
'\n');
1135 INCL_DEBUG(
"New minimum found, storing the particle momenta" <<
'\n');
1137 for(
ParticleIter i=outgoing.begin(), e=outgoing.end(); i!=e; ++i)
1138 minMomenta.push_back((*i)->getMomentum());
1142 if(val > oldOldVal && oldVal > oldOldOldVal) {
1143 INCL_DEBUG(
"Search is diverging, breaking out of the iteration loop: val=" << val <<
", oldVal=" << oldVal <<
", oldOldVal=" << oldOldVal <<
", oldOldOldVal=" << oldOldOldVal <<
'\n');
1153 std::vector<ThreeVector>::const_iterator v = minMomenta.begin();
1154 for(
ParticleIter i=outgoing.begin(), e=outgoing.end(); i!=e; ++i, ++v) {
1155 (*i)->setMomentum(*v);
1156 (*i)->adjustEnergyFromMomentum();
1166 G4bool isNucleonAbsorption =
false;
1167 G4bool isPionAbsorption =
false;
1173 isPionAbsorption =
true;
1184 if(outgoingParticles.size() == 0 &&
1187 isNucleonAbsorption =
true;
1194 for(
ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i ) {
1197 if(isPionAbsorption) {
1198 if((*i)->isPion()) {
1199 isPionAbsorption =
false;
1205#ifdef INCLXX_IN_GEANT4_MODE
1215 eventInfo->
EKin[eventInfo->
nParticles] = (*i)->getKineticEnergy();
1223#ifdef INCLXX_IN_GEANT4_MODE
1227 eventInfo->
history.push_back(
"");
1247 if(theProjectileRemnant && (theProjectileRemnant->getA()>0 || theProjectileRemnant->getA()<0)) {
1248#ifdef INCLXX_IN_GEANT4_MODE
1257 G4double eStar = theProjectileRemnant->getExcitationEnergy();
1258 if(std::abs(eStar)<1E-10)
1262 INCL_WARN(
"Negative excitation energy in projectile-like remnant! EStarRem = " << eventInfo->
EStarRem[eventInfo->
nRemnants] <<
'\n');
1264 const ThreeVector &spin = theProjectileRemnant->getSpin();
1270 eventInfo->
EKinRem[eventInfo->
nRemnants] = theProjectileRemnant->getKineticEnergy();
1271 const ThreeVector &mom = theProjectileRemnant->getMomentum();
1285#ifdef INCLXX_IN_GEANT4_MODE
1318 Book const &theBook = theStore->getBook();
1341 INCL_DEBUG(
"theEventInfo " << theEventInfo.
Zt <<
" " << theEventInfo.
At <<
'\n');
1342 theBalance.
Z = theEventInfo.
Zp + theEventInfo.
Zt;
1343 theBalance.
A = theEventInfo.
Ap + theEventInfo.
At;
1344 theBalance.
S = theEventInfo.
Sp + theEventInfo.
St;
1345 INCL_DEBUG(
"theBalance Z and A " << theBalance.
Z <<
" " << theBalance.
A <<
'\n');
1350 ParticleList const &outgoingParticles = theStore->getOutgoingParticles();
1351 for(
ParticleIter i=outgoingParticles.begin(), e=outgoingParticles.end(); i!=e; ++i ) {
1352 theBalance.
Z -= (*i)->getZ();
1353 theBalance.
A -= (*i)->getA();
1354 theBalance.
S -= (*i)->getS();
1357 theBalance.
energy -= (*i)->getEnergy();
1358 theBalance.
momentum -= (*i)->getMomentum();
1362 if(theProjectileRemnant && (theProjectileRemnant->getA()>0 || theProjectileRemnant->getA()<0)) {
1363 theBalance.
Z -= theProjectileRemnant->getZ();
1364 theBalance.
A -= theProjectileRemnant->getA();
1365 theBalance.
S -= theProjectileRemnant->getS();
1366 if(theProjectileRemnant->getA()>0)
1367 theBalance.
energy -=
ParticleTable::getTableMass(theProjectileRemnant->getA(),theProjectileRemnant->getZ(),theProjectileRemnant->getS()) + theProjectileRemnant->getExcitationEnergy();
1368 else if(theProjectileRemnant->getA()<0)
1369 theBalance.
energy -=
ParticleTable::getTableMass(-(theProjectileRemnant->getA()),-(theProjectileRemnant->getZ()),theProjectileRemnant->getS()) + theProjectileRemnant->getExcitationEnergy();
1370 theBalance.
energy -= theProjectileRemnant->getKineticEnergy();
1371 theBalance.
momentum -= theProjectileRemnant->getMomentum();
1375 ParticleList const & missedParticles = theStore->getMissedParticles();
1376 for(
ParticleIter i=missedParticles.begin(), e=missedParticles.end(); i!=e;++i){
1377 theBalance.
Z -= (*i)->getZ();
1378 theBalance.
A -= (*i)->getA();
1379 theBalance.
S -= (*i)->getS();
1380 theBalance.
energy -= (*i)->getEnergy();
1386 theBalance.
Z -=
getZ();
1387 theBalance.
A -=
getA();
1388 theBalance.
S -=
getS();
1395 Book const &theBook = theStore->getBook();
1398 INCL_DEBUG(
"excitation energy negative and afterrecoil "
1400 <<
" eventNumber=" << theEventInfo.
eventNumber <<
" "
1402 INCL_DEBUG(
"excitation energy negative and afterrecoil "
1404 <<
" " << initialEnergy <<
'\n');
1409 <<
" and afterrecoil 1 , kinetic energy ="
1421 setSpin(incomingAngularMomentum);
1428 const G4int prA = theProjectileRemnant->getA();
1429 if(prA>=1 || prA<=-1) {
1431 const G4double aMass = theProjectileRemnant->getInvariantMass();
1432 theProjectileRemnant->setMass(aMass);
1442 theProjectileRemnant->setExcitationEnergy(anExcitationEnergy);
1448 theProjectileRemnant->setEmissionTime(anEmissionTime);
Static class for carrying out cluster decays.
Simple class implementing De Jong's spin model for nucleus-nucleus collisions.
#define INCL_DATABLOCK(x)
G4int getAcceptedDecays() const
G4int getSrcPairs() const
G4double getFirstCollisionXSec() const
G4double getFirstCollisionTime() const
G4int getAvatars(AvatarType type) const
G4double getFirstCollisionSpectatorMomentum() const
G4double getCurrentTime() const
G4int getAcceptedCollisions() const
G4double getFirstCollisionSpectatorPosition() const
G4int getBlockedCollisions() const
G4int getAcceptedSrcCollisions() const
G4bool getFirstCollisionIsElastic() const
G4int getEnergyViolationInteraction() const
G4int getBlockedDecays() const
G4int getEmittedClusters() const
ThreeVector const & getSpin() const
Get the spin of the nucleus.
ParticleList const & getParticles() const
void setSpin(const ThreeVector &j)
Set the spin of the nucleus.
virtual void initializeParticles()
Initialise the NuclearDensity pointer and sample the particles.
ParticleSampler * theParticleSampler
Cluster(const G4int Z, const G4int A, const G4int S, const G4bool createParticleSampler=true)
Standard Cluster constructor.
virtual G4double getTableMass() const
Get the real particle mass.
G4double theExcitationEnergy
G4bool getPionPotential() const
Do we want the pion potential?
PotentialType getPotentialType() const
Get the type of the potential for nucleons.
ParticleList const & getOutgoingParticles() const
ParticleList const & getEnteringParticles() const
std::string print() const
ParticleList const & getModifiedParticles() const
FinalStateValidity getValidity() const
ParticleList const & getDestroyedParticles() const
G4double getTotalEnergyBeforeInteraction() const
ParticleList const & getCreatedParticles() const
FinalState * getFinalState()
G4int emitInsideAntilambda()
Force emission of all Antilambda.
G4bool decayOutgoingNeutralKaon()
Force the transformation of outgoing Neutral Kaon into propation eigenstate.
G4double computeSeparationEnergyBalance() const
Outgoing - incoming separation energies.
void fillEventInfo(EventInfo *eventInfo)
G4bool decayMe()
Force the phase-space decay of the Nucleus.
G4double computeTotalEnergy() const
Compute the current total energy.
G4bool decayInsideDeltas()
Force the decay of deltas inside the nucleus.
void computeRecoilKinematics()
Compute the recoil momentum and spin of the nucleus.
void finalizeProjectileRemnant(const G4double emissionTime)
Finalise the projectile remnant.
G4bool emitInsideKaon()
Force emission of all Kaon inside the nucleus.
G4bool isEventTransparent() const
Is the event transparent?
void applyFinalState(FinalState *)
void setAType(AnnihilationType type)
void insertParticle(Particle *p)
Insert a new particle (e.g. a projectile) in the nucleus.
G4double getSrcInternalEnergy() const
Nucleus(G4int mass, G4int charge, G4int strangess, Config const *const conf, const G4double universeRadius=-1., AnnihilationType AType=Def)
void emitInsideStrangeParticles()
Force emission of all strange particles inside the nucleus.
void deleteProjectileRemnant()
Delete the projectile remnant.
G4bool decayOutgoingPionResonances(G4double timeThreshold)
Force the decay of outgoing PionResonances (eta/omega).
G4bool emitInsideAnnihilationProducts()
Force emission of all Antinucleon inside the nucleus.
void useFusionKinematics()
Adjust the kinematics for complete-fusion events.
AnnihilationType getAType() const
G4double getInitialInternalEnergy() const
const ThreeVector & getIncomingMomentum() const
Get the incoming momentum vector.
void emitInsidePions()
Force emission of all pions inside the nucleus.
G4double getInitialEnergy() const
Get the initial energy.
void restoreSrcPartner(Particle *particle, ThreeVector m)
ThreeVector computeCenterOfMass() const
Compute the current center-of-mass position.
G4bool decayOutgoingClusters()
Force the decay of unstable outgoing clusters.
G4double getExcitationEnergy() const
Get the excitation energy of the nucleus.
G4int emitInsideLambda()
Force emission of all Lambda (desexitation code with strangeness not implanted yet).
void propagateParticles(G4double step)
G4bool decayInsideStrangeParticles()
Force the transformation of strange particles into a Lambda;.
ConservationBalance getConservationBalance(EventInfo const &theEventInfo, const G4bool afterRecoil) const
Compute charge, mass, energy and momentum balance.
void initializeParticles()
G4bool hasRemnant() const
Does the nucleus give a cascade remnant?
void updatePotentialEnergy(Particle *p) const
Update the particle potential energy.
G4double computeExcitationEnergy() const
Compute the current excitation energy.
G4bool decayOutgoingDeltas()
Force the decay of outgoing deltas.
G4bool decayOutgoingSigmaZero(G4double timeThreshold)
Force the decay of outgoing Neutral Sigma.
G4int getPDGCode() const
Set a PDG Code (MONTE CARLO PARTICLE NUMBERING).
void setPotentialEnergy(G4double v)
Set the particle potential energy.
G4int getS() const
Returns the strangeness number.
G4double getEmissionQValueCorrection(const G4int AParent, const G4int ZParent) const
Computes correction on the emission Q-value.
G4INCL::ThreeVector theMomentum
void setBiasCollisionVector(std::vector< G4int > BiasCollisionVector)
Set the vector list of biased vertices on the particle path.
G4double getPotentialEnergy() const
Get the particle potential energy.
void setMass(G4double mass)
G4int getZ() const
Returns the charge number.
G4double getKineticEnergy() const
Get the particle kinetic energy.
G4int theNKaon
The number of Kaons inside the nucleus (update during the cascade).
std::vector< G4int > getBiasCollisionVector() const
Get the vector list of biased vertices on the particle path.
void setEmissionTime(G4double t)
G4double adjustEnergyFromMomentum()
Recompute the energy to match the momentum.
static G4double getTotalBias()
General bias vector function.
const ThreeVector & adjustMomentumFromEnergy()
Rescale the momentum to match the total energy.
const G4INCL::ThreeVector & getMomentum() const
virtual void setMomentum(const G4INCL::ThreeVector &momentum)
virtual G4double getTableMass() const
Get the tabulated particle mass.
void setEnergy(G4double energy)
std::string print() const
G4double getMass() const
Get the cached particle mass.
void boost(const ThreeVector &aBoostVector)
void setTableMass()
Set the mass of the Particle to its table mass.
G4bool isDelta() const
Is it a Delta?
G4int getA() const
Returns the baryon number.
G4INCL::ThreeVector thePosition
ParticleList const & getOutgoingParticles() const
void addToOutgoing(Particle *p)
add the particle to the outgoing particle list.
void particleHasBeenEjected(Particle *const)
ParticleList const & getParticles() const
ParticleList decay(Cluster *const c)
Carries out a cluster decay.
G4double momentumInCM(Particle const *const p1, Particle const *const p2)
gives the momentum in the CM frame of two particles.
G4double toDegrees(G4double radians)
NuclearDensity const * createDensity(const G4int A, const G4int Z, const G4int S)
INuclearPotential const * createPotential(const PotentialType type, const G4int theA, const G4int theZ, const G4bool pionPotential)
Create an INuclearPotential object.
G4ThreadLocal NuclearMassFn getTableMass
Static pointer to the mass function for nuclei.
G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2).
void setNeutronSeparationEnergy(const G4double s)
Setter for protonSeparationEnergy.
const G4double effectiveNucleonMass
void setProtonSeparationEnergy(const G4double s)
Setter for protonSeparationEnergy.
G4double getWidth(const ParticleType t)
Get particle width (in s).
const G4double hc
[MeV*fm]
ParticleList::const_iterator ParticleIter
Bool_t pionAbsorption
True if the event is a pion absorption.
Short_t S[maxSizeParticles]
Particle strangeness number.
Int_t nCollisionAvatars
Number of collision avatars.
Short_t origin[maxSizeParticles]
Origin of the particle.
Short_t At
Mass number of the target nucleus.
Short_t Zp
Charge number of the projectile nucleus.
Int_t parentResonancePDGCode[maxSizeParticles]
Particle's parent resonance PDG code.
Int_t nDecays
Number of accepted Delta decays.
Int_t projectileType
Projectile particle type.
Short_t nCascadeParticles
Number of cascade particles.
Short_t nRemnants
Number of remnants.
Float_t theta[maxSizeParticles]
Particle momentum polar angle [radians].
Short_t A[maxSizeParticles]
Particle mass number.
Float_t EKinRem[maxSizeRemnants]
Remnant kinetic energy [MeV].
Float_t firstCollisionSpectatorMomentum
Momentum of the spectator on the first collision (fm).
Int_t parentResonanceID[maxSizeParticles]
Particle's parent resonance unique ID identifier.
Float_t jzRem[maxSizeRemnants]
Remnant angular momentum, z component [ ].
Bool_t nucleonAbsorption
True if the event is a nucleon absorption.
Float_t emissionTime[maxSizeParticles]
Emission time [fm/c].
Float_t EStarRem[maxSizeRemnants]
Remnant excitation energy [MeV].
Short_t St
Strangeness number of the target nucleus.
Int_t nEnergyViolationInteraction
Number of attempted collisions/decays for which the energy-conservation algorithm failed to find a so...
Float_t phi[maxSizeParticles]
Particle momentum azimuthal angle [radians].
Int_t nSrcPairs
Number of src pairs.
Short_t Ap
Mass number of the projectile nucleus.
Int_t nReflectionAvatars
Number of reflection avatars.
Int_t nSrcCollisions
Number of accepted SRC collisions.
Float_t firstCollisionSpectatorPosition
Position of the spectator on the first collision (fm).
Short_t Z[maxSizeParticles]
Particle charge number.
Bool_t forcedCompoundNucleus
True if the event is a forced CN.
Float_t JRem[maxSizeRemnants]
Remnant spin [ ].
Float_t thetaRem[maxSizeRemnants]
Remnant momentum polar angle [radians].
std::vector< std::string > history
History of the particle.
Short_t Sp
Strangeness number of the projectile nucleus.
Float_t EKin[maxSizeParticles]
Particle kinetic energy [MeV].
Short_t nParticles
Number of particles in the final state.
Float_t jxRem[maxSizeRemnants]
Remnant angular momentum, x component [ ].
Int_t nBlockedDecays
Number of decays blocked by Pauli or CDPP.
Float_t px[maxSizeParticles]
Particle momentum, x component [MeV/c].
Float_t ParticleBias[maxSizeParticles]
Particle weight due to the bias.
Short_t SRem[maxSizeRemnants]
Remnant strangeness number.
Float_t pxRem[maxSizeRemnants]
Remnant momentum, x component [MeV/c].
Float_t pyRem[maxSizeRemnants]
Remnant momentum, y component [MeV/c].
Float_t firstCollisionTime
Time of the first collision [fm/c].
Short_t Zt
Charge number of the target nucleus.
Float_t phiRem[maxSizeRemnants]
Remnant momentum azimuthal angle [radians].
Float_t pzRem[maxSizeRemnants]
Remnant momentum, z component [MeV/c].
static G4ThreadLocal Int_t eventNumber
Number of the event.
Float_t pz[maxSizeParticles]
Particle momentum, z component [MeV/c].
Int_t nCollisions
Number of accepted two-body collisions.
Int_t PDGCode[maxSizeParticles]
PDG numbering of the particles.
Int_t nBlockedCollisions
Number of two-body collisions blocked by Pauli or CDPP.
Float_t jyRem[maxSizeRemnants]
Remnant angular momentum, y component [ ].
Float_t py[maxSizeParticles]
Particle momentum, y component [MeV/c].
Bool_t firstCollisionIsElastic
True if the first collision was elastic.
Short_t ARem[maxSizeRemnants]
Remnant mass number.
Short_t ZRem[maxSizeRemnants]
Remnant charge number.
Float_t firstCollisionXSec
Cross section of the first collision (mb).
Int_t nDecayAvatars
Number of decay avatars.
Struct for conservation laws.