34#define INCLXX_IN_GEANT4_MODE 1
55 namespace ClusterDecay {
60 void twoBodyDecay(Cluster *
const c,
ClusterDecayType theDecayMode, ParticleList *decayProducts) {
61 Particle *decayParticle = 0;
62 const ThreeVector mom(0.0, 0.0, 0.0);
63 const ThreeVector pos = c->getPosition();
66 switch(theDecayMode) {
68 decayParticle =
new Particle(
Proton, mom, pos);
71 decayParticle =
new Particle(
Neutron, mom, pos);
74 decayParticle =
new Cluster(2,4,0,
false);
77 decayParticle =
new Particle(
Lambda, mom, pos);
80 INCL_ERROR(
"Unrecognized cluster-decay mode in two-body decay: " << theDecayMode <<
'\n'
84 decayParticle->makeParticipant();
85 decayParticle->setNumberOfDecays(1);
86 decayParticle->setPosition(c->getPosition());
87 decayParticle->setEmissionTime(c->getEmissionTime());
88 decayParticle->setRealMass();
91#ifdef INCLXX_IN_GEANT4_MODE
92 if ((c->getZ() == 1) && (c->getA() == 2) && (c->getS() == -1)) {
94 if (c->getEnergy() < 2053.952)
95 c->setMomentum(c->getMomentum() * 0.) ;
97 c->setMomentum(c->getMomentum() / (std::sqrt(c->getMomentum().mag2())/std::sqrt(c->getMomentum().mag2() - 2053.952*2053.952))) ;
101 const ThreeVector velocity = -c->boostVector();
104 const G4int daughterZ = c->getZ() - decayParticle->getZ();
105 const G4int daughterA = c->getA() - decayParticle->getA();
106 const G4int daughterS = c->getS() - decayParticle->getS();
113 c->setMass(daughterMass);
114 c->setExcitationEnergy(0.);
117 const G4double decayMass = decayParticle->getMass();
120 if(motherMass-daughterMass-decayMass>0.)
123 c->setMomentum(momentum);
124 c->adjustEnergyFromMomentum();
125 decayParticle->setMomentum(-momentum);
126 decayParticle->adjustEnergyFromMomentum();
129 decayParticle->boost(velocity);
133 decayProducts->push_back(decayParticle);
137 void threeBodyDecay(Cluster *
const c,
ClusterDecayType theDecayMode, ParticleList *decayProducts) {
138 Particle *decayParticle1 = 0;
139 Particle *decayParticle2 = 0;
140 const ThreeVector mom(0.0, 0.0, 0.0);
141 const ThreeVector pos = c->getPosition();
144 switch(theDecayMode) {
146 decayParticle1 =
new Particle(
Proton, mom, pos);
147 decayParticle2 =
new Particle(
Proton, mom, pos);
150 decayParticle1 =
new Particle(
Neutron, mom, pos);
151 decayParticle2 =
new Particle(
Neutron, mom, pos);
154 INCL_ERROR(
"Unrecognized cluster-decay mode in three-body decay: " << theDecayMode <<
'\n'
158 decayParticle1->makeParticipant();
159 decayParticle2->makeParticipant();
160 decayParticle1->setNumberOfDecays(1);
161 decayParticle2->setNumberOfDecays(1);
162 decayParticle1->setRealMass();
163 decayParticle2->setRealMass();
166 const G4double motherMass = c->getMass();
167 const ThreeVector velocity = -c->boostVector();
170 const G4int decayZ1 = decayParticle1->getZ();
171 const G4int decayA1 = decayParticle1->getA();
172 const G4int decayS1 = decayParticle1->getS();
173 const G4int decayZ2 = decayParticle2->getZ();
174 const G4int decayA2 = decayParticle2->getA();
175 const G4int decayS2 = decayParticle2->getS();
176 const G4int decayZ = decayZ1 + decayZ2;
177 const G4int decayA = decayA1 + decayA2;
178 const G4int decayS = decayS1 + decayS2;
179 const G4int daughterZ = c->getZ() - decayZ;
180 const G4int daughterA = c->getA() - decayA;
181 const G4int daughterS = c->getS() - decayS;
182 const G4double decayMass1 = decayParticle1->getMass();
183 const G4double decayMass2 = decayParticle2->getMass();
187 G4double qValue = motherMass - daughterMass - decayMass1 - decayMass2;
195 const G4double decayMass = decayMass1 + decayMass2 + qValueB;
203 c->setMass(daughterMass);
204 c->setExcitationEnergy(0.);
209 c->setMomentum(momentumA);
210 c->adjustEnergyFromMomentum();
211 const ThreeVector decayBoostVector = momentumA/std::sqrt(decayMass*decayMass + momentumA.mag2());
218 decayParticle1->setMomentum(momentumB);
219 decayParticle2->setMomentum(-momentumB);
220 decayParticle1->adjustEnergyFromMomentum();
221 decayParticle2->adjustEnergyFromMomentum();
224 decayParticle1->boost(decayBoostVector);
225 decayParticle2->boost(decayBoostVector);
228 decayParticle1->boost(velocity);
229 decayParticle2->boost(velocity);
233 decayProducts->push_back(decayParticle1);
234 decayProducts->push_back(decayParticle2);
237#ifdef INCL_DO_NOT_COMPILE
250 void phaseSpaceDecayLegacy(Cluster *
const c,
ClusterDecayType theDecayMode, ParticleList *decayProducts) {
251 const G4int theA = c->getA();
252 const G4int theZ = c->getZ();
254 const ThreeVector mom(0.0, 0.0, 0.0);
255 const ThreeVector pos = c->getPosition();
259 switch(theDecayMode) {
269 INCL_ERROR(
"Unrecognized cluster-decay mode in phase-space decay: " << theDecayMode <<
'\n'
276 G4int finalDaughterZ, finalDaughterA;
282 finalDaughterZ -= theZStep;
295 const G4int nSplits = theA-finalDaughterA;
298 G4double availableEnergy = c->getMass() - finalDaughterMass - nSplits*ejectileMass;
300 if(availableEnergy<0.)
305 G4double eMax = finalDaughterMass + availableEnergy;
306 G4double eMin = finalDaughterMass - ejectileMass;
307 for(
G4int iSplit=0; iSplit<nSplits; ++iSplit) {
308 eMax += ejectileMass;
309 eMin += ejectileMass;
315 std::vector<G4double> theCMMomenta;
316 std::vector<G4double> invariantMasses;
331 if(nTries++>maxTries) {
332 INCL_WARN(
"Phase-space decay exceeded the maximum number of rejections (" << maxTries
333 <<
"). Z=" << theZ <<
", A=" << theA <<
", E*=" << c->getExcitationEnergy()
334 <<
", availableEnergy=" << availableEnergy
335 <<
", nSplits=" << nSplits
341 std::vector<G4double> randomNumbers;
342 for(
G4int iSplit=0; iSplit<nSplits-1; ++iSplit)
344 std::sort(randomNumbers.begin(), randomNumbers.end());
347 invariantMasses.clear();
348 invariantMasses.push_back(finalDaughterMass);
349 for(
G4int iSplit=0; iSplit<nSplits-1; ++iSplit)
350 invariantMasses.push_back(finalDaughterMass + (iSplit+1)*ejectileMass + randomNumbers.at(iSplit)*availableEnergy);
351 invariantMasses.push_back(c->getMass());
354 theCMMomenta.clear();
355 for(
G4int iSplit=0; iSplit<nSplits; ++iSplit) {
356 G4double motherMass = invariantMasses.at(nSplits-iSplit);
357 const G4double daughterMass = invariantMasses.at(nSplits-iSplit-1);
360 if(motherMass-daughterMass-ejectileMass>0.)
362 theCMMomenta.push_back(pCM);
367 for(
G4int iSplit=0; iSplit<nSplits; ++iSplit) {
368 ThreeVector
const velocity = -c->boostVector();
370#if !defined(NDEBUG) && !defined(INCLXX_IN_GEANT4_MODE)
371 const G4double motherMass = c->getMass();
373 c->setA(c->getA() - 1);
374 c->setZ(c->getZ() - theZStep);
375 c->setMass(invariantMasses.at(nSplits-iSplit-1));
377 Particle *ejectile =
new Particle(theEjectileType, mom, pos);
378 ejectile->setRealMass();
381 ThreeVector momentum;
383 c->setMomentum(momentum);
384 c->adjustEnergyFromMomentum();
385 ejectile->setMomentum(-momentum);
386 ejectile->adjustEnergyFromMomentum();
390 ejectile->boost(velocity);
393 decayProducts->push_back(ejectile);
396 c->setExcitationEnergy(0.);
405 void phaseSpaceDecay(Cluster *
const c,
ClusterDecayType theDecayMode, ParticleList *decayProducts) {
406 const G4int theA = c->getA();
407 const G4int theZ = c->getZ();
408 const G4int theL = (-1)*(c->getS());
409 const ThreeVector mom(0.0, 0.0, 0.0);
410 const ThreeVector pos = c->getPosition();
415 switch(theDecayMode) {
426 if(theZ==0) theEjectileType =
Neutron;
427 else theEjectileType =
Proton;
430 INCL_ERROR(
"Unrecognized cluster-decay mode in phase-space decay: " << theDecayMode <<
'\n'
437 G4int finalDaughterZ, finalDaughterA, finalDaughterL;
444 finalDaughterZ -= theZStep;
464 const G4int nLambda = theL-finalDaughterL;
465 const G4int nSplits = theA-finalDaughterA-nLambda;
467 const G4double availableEnergy = c->getMass();
470 const ThreeVector boostVector = - c->boostVector();
473 ParticleList products;
474 c->setA(finalDaughterA);
475 c->setZ(finalDaughterZ);
476 c->setS((-1)*finalDaughterL);
478 c->setMomentum(ThreeVector());
479 c->adjustEnergyFromMomentum();
480 products.push_back(c);
482 for(
G4int j=0; j<nLambda; ++j) {
483 Particle *ejectile =
new Particle(
Lambda, mom, pos);
484 ejectile->setRealMass();
485 products.push_back(ejectile);
487 for(
G4int i=0; i<nSplits; ++i) {
488 Particle *ejectile =
new Particle(theEjectileType, mom, pos);
489 ejectile->setRealMass();
490 products.push_back(ejectile);
494 products.boost(boostVector);
497 ParticleList::iterator productsIter = products.begin();
498 std::advance(productsIter, 1);
499 decayProducts->insert(decayProducts->end(), productsIter, products.end());
501 c->setExcitationEnergy(0.);
509 void recursiveDecay(Cluster *
const c, ParticleList *decayProducts) {
510 const G4int Z = c->getZ();
511 const G4int A = c->getA();
512 const G4int S = c->getS();
514 if(c->getExcitationEnergy()<0.)
515 c->setExcitationEnergy(0.);
520 switch(theDecayMode) {
522 INCL_ERROR(
"Unrecognized cluster-decay mode: " << theDecayMode <<
'\n'
535 twoBodyDecay(c, theDecayMode, decayProducts);
540 threeBodyDecay(c, theDecayMode, decayProducts);
546 phaseSpaceDecay(c, theDecayMode, decayProducts);
552 recursiveDecay(c,decayProducts);
557 INCL_DEBUG(
"Cluster is outside the decay-mode table." << c->print() <<
'\n');
559 INCL_DEBUG(
"Z==A, will decompose it in free protons." <<
'\n');
562 INCL_DEBUG(
"Z==0, will decompose it in free neutrons." <<
'\n');
590 {
StableCluster,
StableCluster,
NeutronDecay,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound},
591 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
NeutronDecay,
TwoNeutronDecay,
NeutronDecay,
TwoNeutronDecay,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound},
592 {
StableCluster,
StableCluster,
ProtonDecay,
StableCluster,
StableCluster,
NeutronDecay,
StableCluster,
NeutronDecay,
StableCluster,
NeutronDecay,
TwoNeutronDecay,
NeutronUnbound,
NeutronUnbound},
593 {
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
ProtonDecay,
ProtonDecay,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
NeutronDecay,
StableCluster,
NeutronDecay},
594 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
ProtonDecay,
TwoProtonDecay,
StableCluster,
AlphaDecay,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
595 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
TwoProtonDecay,
ProtonDecay,
StableCluster,
ProtonDecay,
StableCluster,
StableCluster,
StableCluster},
596 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
ProtonUnbound,
TwoProtonDecay,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
597 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
ProtonUnbound,
ProtonUnbound,
ProtonDecay,
ProtonDecay,
StableCluster},
598 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
ProtonUnbound,
ProtonUnbound,
ProtonUnbound,
ProtonDecay}
602 {
StableCluster,
StableCluster,
NeutronDecay,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound},
603 {
StableCluster,
StableCluster,
LambdaDecay,
StableCluster,
StableCluster,
NeutronDecay,
StableCluster,
StableCluster,
StableCluster,
NeutronDecay,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound},
604 {
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
NeutronDecay,
StableCluster,
NeutronUnbound},
605 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonDecay,
ProtonDecay,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
606 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
607 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
ProtonDecay,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
608 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
609 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
ProtonDecay,
ProtonDecay,
ProtonDecay},
610 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
ProtonUnbound,
ProtonUnbound}
614 {
StableCluster,
StableCluster,
LambdaDecay,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound},
615 {
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
StableCluster,
StableCluster,
NeutronDecay,
StableCluster,
StableCluster,
StableCluster,
NeutronDecay,
NeutronUnbound,
NeutronUnbound},
616 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
617 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonDecay,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
618 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
619 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
620 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
StableCluster,
StableCluster,
StableCluster},
621 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
ProtonDecay,
ProtonDecay},
622 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
ProtonUnbound}
626 {
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound,
LambdaUnbound},
627 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
628 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
629 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonDecay,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
630 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
StableCluster,
StableCluster,
StableCluster,
StableCluster},
631 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
StableCluster,
StableCluster,
StableCluster},
632 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
StableCluster,
StableCluster},
633 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound,
ProtonDecay},
634 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
LambdaUnbound,
ProtonUnbound}
639 recursiveDecay(c, &decayProducts);
648 else if(c->
getS()==-1)
655 return decayProducts;
G4double S(G4double temp)
Static class for carrying out cluster decays.
G4int getS() const
Returns the strangeness number.
G4int getZ() const
Returns the charge number.
std::vector< G4int > getBiasCollisionVector() const
Get the vector list of biased vertices on the particle path.
void setType(ParticleType t)
void setRealMass()
Set the mass of the Particle to its real mass.
G4int getA() const
Returns the baryon number.
G4ThreadLocal ClusterDecayType clusterDecayMode[ParticleTable::clusterTableSSize][ParticleTable::clusterTableZSize][ParticleTable::clusterTableASize]
Table for cluster decays.
ParticleList decay(Cluster *const c)
Carries out a cluster decay.
G4bool isStable(Cluster const *const c)
True if the cluster is stable.
G4double momentumInCM(Particle const *const p1, Particle const *const p2)
gives the momentum in the CM frame of two particles.
const G4int clusterTableZSize
G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2)
const G4int clusterTableSSize
const G4int clusterTableASize
void generate(const G4double sqrtS, ParticleList &particles)
Generate an event in the CM system.
ThreeVector normVector(G4double norm=1.)
ParticleList::const_iterator ParticleIter