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,
false);
77 INCL_ERROR(
"Unrecognized cluster-decay mode in two-body decay: " << theDecayMode <<
'\n'
81 decayParticle->makeParticipant();
82 decayParticle->setNumberOfDecays(1);
83 decayParticle->setPosition(c->getPosition());
84 decayParticle->setEmissionTime(c->getEmissionTime());
85 decayParticle->setRealMass();
89 const ThreeVector velocity = -c->boostVector();
92 const G4int daughterZ = c->getZ() - decayParticle->getZ();
93 const G4int daughterA = c->getA() - decayParticle->getA();
99 c->setMass(daughterMass);
100 c->setExcitationEnergy(0.);
103 const G4double decayMass = decayParticle->getMass();
106 if(motherMass-daughterMass-decayMass>0.)
109 c->setMomentum(momentum);
110 c->adjustEnergyFromMomentum();
111 decayParticle->setMomentum(-momentum);
112 decayParticle->adjustEnergyFromMomentum();
115 decayParticle->boost(velocity);
119 decayProducts->push_back(decayParticle);
123 void threeBodyDecay(Cluster *
const c,
ClusterDecayType theDecayMode, ParticleList *decayProducts) {
124 Particle *decayParticle1 = 0;
125 Particle *decayParticle2 = 0;
126 const ThreeVector mom(0.0, 0.0, 0.0);
127 const ThreeVector
pos = c->getPosition();
130 switch(theDecayMode) {
132 decayParticle1 =
new Particle(
Proton, mom, pos);
133 decayParticle2 =
new Particle(
Proton, mom, pos);
136 decayParticle1 =
new Particle(
Neutron, mom, pos);
137 decayParticle2 =
new Particle(
Neutron, mom, pos);
140 INCL_ERROR(
"Unrecognized cluster-decay mode in three-body decay: " << theDecayMode <<
'\n'
144 decayParticle1->makeParticipant();
145 decayParticle2->makeParticipant();
146 decayParticle1->setNumberOfDecays(1);
147 decayParticle2->setNumberOfDecays(1);
148 decayParticle1->setRealMass();
149 decayParticle2->setRealMass();
152 const G4double motherMass = c->getMass();
153 const ThreeVector velocity = -c->boostVector();
156 const G4int decayZ1 = decayParticle1->getZ();
157 const G4int decayA1 = decayParticle1->getA();
158 const G4int decayZ2 = decayParticle2->getZ();
159 const G4int decayA2 = decayParticle2->getA();
160 const G4int decayZ = decayZ1 + decayZ2;
161 const G4int decayA = decayA1 + decayA2;
162 const G4int daughterZ = c->getZ() - decayZ;
163 const G4int daughterA = c->getA() - decayA;
164 const G4double decayMass1 = decayParticle1->getMass();
165 const G4double decayMass2 = decayParticle2->getMass();
169 G4double qValue = motherMass - daughterMass - decayMass1 - decayMass2;
177 const G4double decayMass = decayMass1 + decayMass2 + qValueB;
184 c->setMass(daughterMass);
185 c->setExcitationEnergy(0.);
190 c->setMomentum(momentumA);
191 c->adjustEnergyFromMomentum();
192 const ThreeVector decayBoostVector = momentumA/std::sqrt(decayMass*decayMass + momentumA.mag2());
199 decayParticle1->setMomentum(momentumB);
200 decayParticle2->setMomentum(-momentumB);
201 decayParticle1->adjustEnergyFromMomentum();
202 decayParticle2->adjustEnergyFromMomentum();
205 decayParticle1->boost(decayBoostVector);
206 decayParticle2->boost(decayBoostVector);
209 decayParticle1->boost(velocity);
210 decayParticle2->boost(velocity);
214 decayProducts->push_back(decayParticle1);
215 decayProducts->push_back(decayParticle2);
218 #ifdef INCL_DO_NOT_COMPILE
231 void phaseSpaceDecayLegacy(Cluster *
const c,
ClusterDecayType theDecayMode, ParticleList *decayProducts) {
232 const G4int theA = c->getA();
233 const G4int theZ = c->getZ();
234 const ThreeVector mom(0.0, 0.0, 0.0);
235 const ThreeVector
pos = c->getPosition();
239 switch(theDecayMode) {
249 INCL_ERROR(
"Unrecognized cluster-decay mode in phase-space decay: " << theDecayMode <<
'\n'
256 G4int finalDaughterZ, finalDaughterA;
262 finalDaughterZ -= theZStep;
275 const G4int nSplits = theA-finalDaughterA;
278 G4double availableEnergy = c->getMass() - finalDaughterMass - nSplits*ejectileMass;
280 if(availableEnergy<0.)
285 G4double eMax = finalDaughterMass + availableEnergy;
286 G4double eMin = finalDaughterMass - ejectileMass;
287 for(
G4int iSplit=0; iSplit<nSplits; ++iSplit) {
288 eMax += ejectileMass;
289 eMin += ejectileMass;
295 std::vector<G4double> theCMMomenta;
296 std::vector<G4double> invariantMasses;
311 if(nTries++>maxTries) {
312 INCL_WARN(
"Phase-space decay exceeded the maximum number of rejections (" << maxTries
313 <<
"). Z=" << theZ <<
", A=" << theA <<
", E*=" << c->getExcitationEnergy()
314 <<
", availableEnergy=" << availableEnergy
315 <<
", nSplits=" << nSplits
321 std::vector<G4double> randomNumbers;
322 for(
G4int iSplit=0; iSplit<nSplits-1; ++iSplit)
324 std::sort(randomNumbers.begin(), randomNumbers.end());
327 invariantMasses.clear();
328 invariantMasses.push_back(finalDaughterMass);
329 for(
G4int iSplit=0; iSplit<nSplits-1; ++iSplit)
330 invariantMasses.push_back(finalDaughterMass + (iSplit+1)*ejectileMass + randomNumbers.at(iSplit)*availableEnergy);
331 invariantMasses.push_back(c->getMass());
334 theCMMomenta.clear();
335 for(
G4int iSplit=0; iSplit<nSplits; ++iSplit) {
336 G4double motherMass = invariantMasses.at(nSplits-iSplit);
337 const G4double daughterMass = invariantMasses.at(nSplits-iSplit-1);
340 if(motherMass-daughterMass-ejectileMass>0.)
342 theCMMomenta.push_back(pCM);
347 for(
G4int iSplit=0; iSplit<nSplits; ++iSplit) {
348 ThreeVector
const velocity = -c->boostVector();
350 #if !defined(NDEBUG) && !defined(INCLXX_IN_GEANT4_MODE)
351 const G4double motherMass = c->getMass();
353 c->setA(c->getA() - 1);
354 c->setZ(c->getZ() - theZStep);
355 c->setMass(invariantMasses.at(nSplits-iSplit-1));
357 Particle *ejectile =
new Particle(theEjectileType, mom, pos);
358 ejectile->setRealMass();
361 ThreeVector momentum;
363 c->setMomentum(momentum);
364 c->adjustEnergyFromMomentum();
365 ejectile->setMomentum(-momentum);
366 ejectile->adjustEnergyFromMomentum();
370 ejectile->boost(velocity);
373 decayProducts->push_back(ejectile);
376 c->setExcitationEnergy(0.);
378 #endif // INCL_DO_NOT_COMPILE
385 void phaseSpaceDecay(Cluster *
const c,
ClusterDecayType theDecayMode, ParticleList *decayProducts) {
386 const G4int theA = c->getA();
388 const ThreeVector mom(0.0, 0.0, 0.0);
389 const ThreeVector
pos = c->getPosition();
393 switch(theDecayMode) {
403 INCL_ERROR(
"Unrecognized cluster-decay mode in phase-space decay: " << theDecayMode <<
'\n'
410 G4int finalDaughterZ, finalDaughterA;
416 finalDaughterZ -= theZStep;
428 const G4int nSplits = theA-finalDaughterA;
430 const G4double availableEnergy = c->getMass();
433 const ThreeVector boostVector = - c->boostVector();
436 ParticleList products;
437 c->setA(finalDaughterA);
438 c->setZ(finalDaughterZ);
440 c->setMomentum(ThreeVector());
441 c->adjustEnergyFromMomentum();
442 products.push_back(c);
443 for(
G4int i=0; i<nSplits; ++i) {
444 Particle *ejectile =
new Particle(theEjectileType, mom, pos);
445 ejectile->setRealMass();
446 products.push_back(ejectile);
450 products.boost(boostVector);
453 ParticleList::iterator productsIter = products.begin();
454 std::advance(productsIter, 1);
455 decayProducts->insert(decayProducts->end(), productsIter, products.end());
457 c->setExcitationEnergy(0.);
465 void recursiveDecay(Cluster *
const c, ParticleList *decayProducts) {
466 const G4int Z = c->getZ();
467 const G4int A = c->getA();
469 if(c->getExcitationEnergy()<0.)
470 c->setExcitationEnergy(0.);
475 switch(theDecayMode) {
477 INCL_ERROR(
"Unrecognized cluster-decay mode: " << theDecayMode <<
'\n'
489 twoBodyDecay(c, theDecayMode, decayProducts);
494 threeBodyDecay(c, theDecayMode, decayProducts);
499 phaseSpaceDecay(c, theDecayMode, decayProducts);
505 recursiveDecay(c,decayProducts);
510 INCL_DEBUG(
"Cluster is outside the decay-mode table." << c->print() <<
'\n');
512 INCL_DEBUG(
"Z==A, will decompose it in free protons." <<
'\n');
515 INCL_DEBUG(
"Z==0, will decompose it in free neutrons." <<
'\n');
542 {
StableCluster,
StableCluster,
NeutronDecay,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound, NeutronUnbound},
543 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
NeutronDecay,
TwoNeutronDecay,
NeutronDecay,
TwoNeutronDecay,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound,
NeutronUnbound, NeutronUnbound},
544 {
StableCluster,
StableCluster,
ProtonDecay,
StableCluster,
StableCluster,
NeutronDecay,
StableCluster,
NeutronDecay,
StableCluster,
NeutronDecay,
TwoNeutronDecay,
NeutronUnbound, NeutronUnbound},
545 {
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
ProtonDecay,
ProtonDecay,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
NeutronDecay,
StableCluster, NeutronDecay},
546 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
ProtonDecay,
TwoProtonDecay,
StableCluster,
AlphaDecay,
StableCluster,
StableCluster,
StableCluster, StableCluster},
547 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
TwoProtonDecay,
ProtonDecay,
StableCluster,
ProtonDecay,
StableCluster,
StableCluster, StableCluster},
548 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
ProtonUnbound,
TwoProtonDecay,
StableCluster,
StableCluster,
StableCluster, StableCluster},
549 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
ProtonUnbound,
ProtonUnbound,
ProtonDecay,
ProtonDecay, StableCluster},
550 {
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
StableCluster,
ProtonUnbound,
ProtonUnbound,
ProtonUnbound,
ProtonUnbound,
ProtonDecay}
555 recursiveDecay(c, &decayProducts);
567 return decayProducts;
G4int getA() const
Returns the baryon number.
const G4int clusterTableASize
Static class for carrying out cluster decays.
G4ThreadLocal ClusterDecayType clusterDecayMode[ParticleTable::clusterTableZSize][ParticleTable::clusterTableASize]
Table for cluster decays.
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.
ThreeVector normVector(G4double norm=1.)
G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2)
double A(double temperature)
ParticleList decay(Cluster *const c)
Carries out a cluster decay.
G4int getZ() const
Returns the charge number.
void generate(const G4double sqrtS, ParticleList &particles)
Generate an event in the CM system.
void setRealMass()
Set the mass of the Particle to its real mass.
void setType(ParticleType t)
const G4int clusterTableZSize
static const G4double pos