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 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);
569 return decayProducts;
std::vector< G4int > getBiasCollisionVector() const
Get the vector list of biased vertices on the particle path.
ParticleList::const_iterator ParticleIter
ParticleList decay(Cluster *const c)
Carries out a cluster decay.
static const G4double pos
ThreeVector normVector(G4double norm=1.)
G4bool isStable(Cluster const *const c)
True if the cluster is stable.
const G4int clusterTableZSize
void generate(const G4double sqrtS, ParticleList &particles)
Generate an event in the CM system.
G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2)
G4double momentumInCM(Particle const *const p1, Particle const *const p2)
gives the momentum in the CM frame of two particles.
const G4int clusterTableASize
double A(double temperature)
G4int getZ() const
Returns the charge number.
void setRealMass()
Set the mass of the Particle to its real mass.
G4int getA() const
Returns the baryon number.
void setType(ParticleType t)
Static class for carrying out cluster decays.
G4ThreadLocal ClusterDecayType clusterDecayMode[ParticleTable::clusterTableZSize][ParticleTable::clusterTableASize]
Table for cluster decays.