Geant4-11
Functions
G4INCL::ClusterDecay::anonymous_namespace{G4INCLClusterDecay.cc} Namespace Reference

Functions

void phaseSpaceDecay (Cluster *const c, ClusterDecayType theDecayMode, ParticleList *decayProducts)
 Disassembles unbound nuclei using the phase-space model. More...
 
void recursiveDecay (Cluster *const c, ParticleList *decayProducts)
 Recursively decay clusters. More...
 
void threeBodyDecay (Cluster *const c, ClusterDecayType theDecayMode, ParticleList *decayProducts)
 Carries out three-body decays. More...
 
void twoBodyDecay (Cluster *const c, ClusterDecayType theDecayMode, ParticleList *decayProducts)
 Carries out two-body decays. More...
 

Function Documentation

◆ phaseSpaceDecay()

void G4INCL::ClusterDecay::anonymous_namespace{G4INCLClusterDecay.cc}::phaseSpaceDecay ( Cluster *const  c,
ClusterDecayType  theDecayMode,
ParticleList decayProducts 
)

Disassembles unbound nuclei using the phase-space model.

This implementation uses the Kopylov algorithm, defined in namespace PhaseSpaceGenerator.

Definition at line 405 of file G4INCLClusterDecay.cc.

405 {
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();
411
412 G4int theZStep;
413
414 ParticleType theEjectileType;
415 switch(theDecayMode) {
416 case ProtonUnbound:
417 theZStep = 1;
418 theEjectileType = Proton;
419 break;
420 case NeutronUnbound:
421 theZStep = 0;
422 theEjectileType = Neutron;
423 break;
424 case LambdaUnbound: // Will always completly decay. Append only if theA == 0 and/or theZ == 0
425 theZStep = -99;
426 if(theZ==0) theEjectileType = Neutron;
427 else theEjectileType = Proton;
428 break;
429 default:
430 INCL_ERROR("Unrecognized cluster-decay mode in phase-space decay: " << theDecayMode << '\n'
431 << c->print());
432 return;
433 }
434
435 // Find the daughter cluster (first cluster which is not
436 // proton/neutron-unbound, in the sense of the table)
437 G4int finalDaughterZ, finalDaughterA, finalDaughterL;
438 if(theZ<ParticleTable::clusterTableZSize && theA<ParticleTable::clusterTableASize && theZStep != -99) {
439 finalDaughterZ=theZ;
440 finalDaughterA=theA;
441 finalDaughterL=theL;
442 while(finalDaughterA>0 && clusterDecayMode[finalDaughterL][finalDaughterZ][finalDaughterA]!=StableCluster) { /* Loop modified, 15.01.18, J. Hirtz */
443 finalDaughterA--;
444 finalDaughterZ -= theZStep;
445 }
446 } else {
447 finalDaughterA = 1;
448 if(theDecayMode==ProtonUnbound){
449 finalDaughterZ = 1;
450 finalDaughterL = 0;
451 }
452 else if(theDecayMode==NeutronUnbound){
453 finalDaughterZ = 0;
454 finalDaughterL = 0;
455 }
456 else {
457 finalDaughterZ = 0;
458 finalDaughterL = 1;
459 }
460 }
461// assert(finalDaughterZ<=theZ && finalDaughterA<theA && finalDaughterA>0 && finalDaughterZ>=0 && finalDaughterL>=0);
462
463 // Compute the available decay energy
464 const G4int nLambda = theL-finalDaughterL;
465 const G4int nSplits = theA-finalDaughterA-nLambda;
466 // c->getMass() can possibly contain some excitation energy, too
467 const G4double availableEnergy = c->getMass();
468
469 // Save the boost vector for the cluster
470 const ThreeVector boostVector = - c->boostVector();
471
472 // Create a list of decay products
473 ParticleList products;
474 c->setA(finalDaughterA);
475 c->setZ(finalDaughterZ);
476 c->setS((-1)*finalDaughterL);
477 c->setRealMass();
478 c->setMomentum(ThreeVector());
480 products.push_back(c);
481
482 for(G4int j=0; j<nLambda; ++j) {
483 Particle *ejectile = new Particle(Lambda, mom, pos);
484 ejectile->setRealMass();
485 products.push_back(ejectile);
486 }
487 for(G4int i=0; i<nSplits; ++i) {
488 Particle *ejectile = new Particle(theEjectileType, mom, pos);
489 ejectile->setRealMass();
490 products.push_back(ejectile);
491 }
492
493 PhaseSpaceGenerator::generate(availableEnergy, products);
494 products.boost(boostVector);
495
496 // Copy decay products in the output list (but skip the residue)
497 ParticleList::iterator productsIter = products.begin();
498 std::advance(productsIter, 1);
499 decayProducts->insert(decayProducts->end(), productsIter, products.end());
500
501 c->setExcitationEnergy(0.);
502 }
static const G4double pos
#define INCL_ERROR(x)
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
void setExcitationEnergy(const G4double e)
Set the excitation energy of the cluster.
void setS(const G4int S)
Set the strangess number of the cluster.
void setA(const G4int A)
Set the mass number of the cluster.
void setZ(const G4int Z)
Set the charge number of the cluster.
std::string print() const
ThreeVector boostVector() const
G4int getS() const
Returns the strangeness number.
G4int getZ() const
Returns the charge number.
const G4INCL::ThreeVector & getPosition() const
G4double adjustEnergyFromMomentum()
Recompute the energy to match the momentum.
virtual void setMomentum(const G4INCL::ThreeVector &momentum)
G4double getMass() const
Get the cached particle mass.
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.
void generate(const G4double sqrtS, ParticleList &particles)
Generate an event in the CM system.

References G4INCL::Particle::adjustEnergyFromMomentum(), G4INCL::ParticleList::boost(), G4INCL::Particle::boostVector(), G4INCL::ClusterDecay::clusterDecayMode, G4INCL::ParticleTable::clusterTableASize, G4INCL::ParticleTable::clusterTableZSize, G4INCL::PhaseSpaceGenerator::generate(), G4INCL::Particle::getA(), G4INCL::Particle::getMass(), G4INCL::Particle::getPosition(), G4INCL::Particle::getS(), G4INCL::Particle::getZ(), INCL_ERROR, G4INCL::Lambda, G4INCL::ClusterDecay::LambdaUnbound, G4INCL::Neutron, G4INCL::ClusterDecay::NeutronUnbound, pos, G4INCL::Cluster::print(), G4INCL::Proton, G4INCL::ClusterDecay::ProtonUnbound, G4INCL::Cluster::setA(), G4INCL::Cluster::setExcitationEnergy(), G4INCL::Particle::setMomentum(), G4INCL::Particle::setRealMass(), G4INCL::Cluster::setS(), G4INCL::Cluster::setZ(), and G4INCL::ClusterDecay::StableCluster.

Referenced by recursiveDecay().

◆ recursiveDecay()

void G4INCL::ClusterDecay::anonymous_namespace{G4INCLClusterDecay.cc}::recursiveDecay ( Cluster *const  c,
ParticleList decayProducts 
)

Recursively decay clusters.

Parameters
ccluster that should decay
decayProductsdecay products are appended to the end of this list

Definition at line 509 of file G4INCLClusterDecay.cc.

509 {
510 const G4int Z = c->getZ();
511 const G4int A = c->getA();
512 const G4int S = c->getS();
513// assert(c->getExcitationEnergy()>-1.e-5);
514 if(c->getExcitationEnergy()<0.)
515 c->setExcitationEnergy(0.);
516
518 ClusterDecayType theDecayMode = clusterDecayMode[(S*(-1))][Z][A];
519
520 switch(theDecayMode) {
521 default:
522 INCL_ERROR("Unrecognized cluster-decay mode: " << theDecayMode << '\n'
523 << c->print());
524 return;
525 break;
526 case StableCluster:
527 // For stable clusters, just return
528 return;
529 break;
530 case ProtonDecay:
531 case NeutronDecay:
532 case LambdaDecay:
533 case AlphaDecay:
534 // Two-body decays
535 twoBodyDecay(c, theDecayMode, decayProducts);
536 break;
537 case TwoProtonDecay:
538 case TwoNeutronDecay:
539 // Three-body decays
540 threeBodyDecay(c, theDecayMode, decayProducts);
541 break;
542 case ProtonUnbound:
543 case NeutronUnbound:
544 case LambdaUnbound:
545 // Phase-space decays
546 phaseSpaceDecay(c, theDecayMode, decayProducts);
547 break;
548 }
549
550 // Calls itself recursively in case the produced remnant is still unstable.
551 // Sneaky, isn't it.
552 recursiveDecay(c,decayProducts);
553
554 } else {
555 // The cluster is too large for our decay-mode table. Decompose it only
556 // if Z==0 || Z==A.
557 INCL_DEBUG("Cluster is outside the decay-mode table." << c->print() << '\n');
558 if(Z==A) {
559 INCL_DEBUG("Z==A, will decompose it in free protons." << '\n');
560 phaseSpaceDecay(c, ProtonUnbound, decayProducts);
561 } else if(Z==0) {
562 INCL_DEBUG("Z==0, will decompose it in free neutrons." << '\n');
563 phaseSpaceDecay(c, NeutronUnbound, decayProducts);
564 }
565 }
566 }
G4double S(G4double temp)
#define INCL_DEBUG(x)
const G4int Z[17]
const G4double A[17]
G4double getExcitationEnergy() const
Get the excitation energy of the cluster.
void threeBodyDecay(Cluster *const c, ClusterDecayType theDecayMode, ParticleList *decayProducts)
Carries out three-body decays.
void phaseSpaceDecay(Cluster *const c, ClusterDecayType theDecayMode, ParticleList *decayProducts)
Disassembles unbound nuclei using the phase-space model.
void twoBodyDecay(Cluster *const c, ClusterDecayType theDecayMode, ParticleList *decayProducts)
Carries out two-body decays.
void recursiveDecay(Cluster *const c, ParticleList *decayProducts)
Recursively decay clusters.

References A, G4INCL::ClusterDecay::AlphaDecay, G4INCL::ClusterDecay::clusterDecayMode, G4INCL::ParticleTable::clusterTableASize, G4INCL::ParticleTable::clusterTableSSize, G4INCL::ParticleTable::clusterTableZSize, G4INCL::Particle::getA(), G4INCL::Cluster::getExcitationEnergy(), G4INCL::Particle::getS(), G4INCL::Particle::getZ(), INCL_DEBUG, INCL_ERROR, G4INCL::ClusterDecay::LambdaDecay, G4INCL::ClusterDecay::LambdaUnbound, G4INCL::ClusterDecay::NeutronDecay, G4INCL::ClusterDecay::NeutronUnbound, phaseSpaceDecay(), G4INCL::Cluster::print(), G4INCL::ClusterDecay::ProtonDecay, G4INCL::ClusterDecay::ProtonUnbound, recursiveDecay(), S(), G4INCL::Cluster::setExcitationEnergy(), G4INCL::ClusterDecay::StableCluster, threeBodyDecay(), twoBodyDecay(), G4INCL::ClusterDecay::TwoNeutronDecay, G4INCL::ClusterDecay::TwoProtonDecay, and Z.

Referenced by G4INCL::ClusterDecay::decay(), and recursiveDecay().

◆ threeBodyDecay()

void G4INCL::ClusterDecay::anonymous_namespace{G4INCLClusterDecay.cc}::threeBodyDecay ( Cluster *const  c,
ClusterDecayType  theDecayMode,
ParticleList decayProducts 
)

Carries out three-body decays.

Definition at line 137 of file G4INCLClusterDecay.cc.

137 {
138 Particle *decayParticle1 = 0;
139 Particle *decayParticle2 = 0;
140 const ThreeVector mom(0.0, 0.0, 0.0);
141 const ThreeVector pos = c->getPosition();
142
143 // Create the emitted particles
144 switch(theDecayMode) {
145 case TwoProtonDecay:
146 decayParticle1 = new Particle(Proton, mom, pos);
147 decayParticle2 = new Particle(Proton, mom, pos);
148 break;
149 case TwoNeutronDecay:
150 decayParticle1 = new Particle(Neutron, mom, pos);
151 decayParticle2 = new Particle(Neutron, mom, pos);
152 break;
153 default:
154 INCL_ERROR("Unrecognized cluster-decay mode in three-body decay: " << theDecayMode << '\n'
155 << c->print());
156 return;
157 }
158 decayParticle1->makeParticipant();
159 decayParticle2->makeParticipant();
160 decayParticle1->setNumberOfDecays(1);
161 decayParticle2->setNumberOfDecays(1);
162 decayParticle1->setRealMass();
163 decayParticle2->setRealMass();
164
165 // Save some variables of the mother cluster
166 const G4double motherMass = c->getMass();
167 const ThreeVector velocity = -c->boostVector();
168
169 // Masses and charges of the daughter particle and of the decay products
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();
184 const G4double daughterMass = ParticleTable::getRealMass(daughterA,daughterZ,daughterS);
185
186 // Q-values
187 G4double qValue = motherMass - daughterMass - decayMass1 - decayMass2;
188// assert(qValue > -1e-5); // Q-value should be >0
189 if(qValue<0.)
190 qValue=0.;
191 const G4double qValueB = qValue * Random::shoot();
192
193 // The decay particles behave as if they had more mass until the second
194 // decay
195 const G4double decayMass = decayMass1 + decayMass2 + qValueB;
196
197 /* Stage A: mother --> daughter + (decay1+decay2) */
198
199 // The mother cluster becomes the daughter
200 c->setZ(daughterZ);
201 c->setA(daughterA);
202 c->setS(daughterS);
203 c->setMass(daughterMass);
204 c->setExcitationEnergy(0.);
205
206 // Decay kinematics in the mother rest frame
207 const G4double pCMA = KinematicsUtils::momentumInCM(motherMass, daughterMass, decayMass);
208 const ThreeVector momentumA = Random::normVector(pCMA);
209 c->setMomentum(momentumA);
211 const ThreeVector decayBoostVector = momentumA/std::sqrt(decayMass*decayMass + momentumA.mag2());
212
213 /* Stage B: (decay1+decay2) --> decay1 + decay2 */
214
215 // Decay kinematics in the (decay1+decay2) rest frame
216 const G4double pCMB = KinematicsUtils::momentumInCM(decayMass, decayMass1, decayMass2);
217 const ThreeVector momentumB = Random::normVector(pCMB);
218 decayParticle1->setMomentum(momentumB);
219 decayParticle2->setMomentum(-momentumB);
220 decayParticle1->adjustEnergyFromMomentum();
221 decayParticle2->adjustEnergyFromMomentum();
222
223 // Boost decay1 and decay2 to the Stage-A decay frame
224 decayParticle1->boost(decayBoostVector);
225 decayParticle2->boost(decayBoostVector);
226
227 // Boost all particles to the lab frame
228 decayParticle1->boost(velocity);
229 decayParticle2->boost(velocity);
230 c->boost(velocity);
231
232 // Add the decay particles to the list of decay products
233 decayProducts->push_back(decayParticle1);
234 decayProducts->push_back(decayParticle2);
235 }
void boost(const ThreeVector &aBoostVector)
Boost the cluster with the indicated velocity.
void setMass(G4double mass)
void setNumberOfDecays(G4int n)
Set the number of decays undergone by the particle.
virtual void makeParticipant()
void boost(const ThreeVector &aBoostVector)
G4double mag2() const
ThreeVector shoot(const G4int Ap, const G4int Af)
G4double momentumInCM(Particle const *const p1, Particle const *const p2)
gives the momentum in the CM frame of two particles.
G4double getRealMass(const G4INCL::ParticleType t)
Get particle mass (in MeV/c^2)
ThreeVector normVector(G4double norm=1.)

References G4INCL::Particle::adjustEnergyFromMomentum(), G4INCL::Cluster::boost(), G4INCL::Particle::boost(), G4INCL::Particle::boostVector(), G4INCL::Particle::getA(), G4INCL::Particle::getMass(), G4INCL::Particle::getPosition(), G4INCL::ParticleTable::getRealMass(), G4INCL::Particle::getS(), G4INCL::Particle::getZ(), INCL_ERROR, G4INCL::ThreeVector::mag2(), G4INCL::Particle::makeParticipant(), G4INCL::KinematicsUtils::momentumInCM(), G4INCL::Neutron, G4INCL::Random::normVector(), pos, G4INCL::Cluster::print(), G4INCL::Proton, G4INCL::Cluster::setA(), G4INCL::Cluster::setExcitationEnergy(), G4INCL::Particle::setMass(), G4INCL::Particle::setMomentum(), G4INCL::Particle::setNumberOfDecays(), G4INCL::Particle::setRealMass(), G4INCL::Cluster::setS(), G4INCL::Cluster::setZ(), G4INCL::Random::shoot(), G4INCL::ClusterDecay::TwoNeutronDecay, and G4INCL::ClusterDecay::TwoProtonDecay.

Referenced by recursiveDecay().

◆ twoBodyDecay()

void G4INCL::ClusterDecay::anonymous_namespace{G4INCLClusterDecay.cc}::twoBodyDecay ( Cluster *const  c,
ClusterDecayType  theDecayMode,
ParticleList decayProducts 
)

Carries out two-body decays.

Definition at line 60 of file G4INCLClusterDecay.cc.

60 {
61 Particle *decayParticle = 0;
62 const ThreeVector mom(0.0, 0.0, 0.0);
63 const ThreeVector pos = c->getPosition();
64
65 // Create the emitted particle
66 switch(theDecayMode) {
67 case ProtonDecay:
68 decayParticle = new Particle(Proton, mom, pos);
69 break;
70 case NeutronDecay:
71 decayParticle = new Particle(Neutron, mom, pos);
72 break;
73 case AlphaDecay:
74 decayParticle = new Cluster(2,4,0,false);
75 break;
76 case LambdaDecay:
77 decayParticle = new Particle(Lambda, mom, pos);
78 break;
79 default:
80 INCL_ERROR("Unrecognized cluster-decay mode in two-body decay: " << theDecayMode << '\n'
81 << c->print());
82 return;
83 }
84 decayParticle->makeParticipant();
85 decayParticle->setNumberOfDecays(1);
86 decayParticle->setPosition(c->getPosition());
87 decayParticle->setEmissionTime(c->getEmissionTime());
88 decayParticle->setRealMass();
89
90 // Save some variables of the mother cluster
91#ifdef INCLXX_IN_GEANT4_MODE
92 if ((c->getZ() == 1) && (c->getA() == 2) && (c->getS() == -1)) { // no Mass for A=2,Z=1,S=-1 in Geant4
93 c->setMass(2053.952);
94 if (c->getEnergy() < 2053.952) // Energy can be lower than the sum of p and Lambda masses (2053.952)...
95 c->setMomentum(c->getMomentum() * 0.) ;
96 else
97 c->setMomentum(c->getMomentum() / (std::sqrt(c->getMomentum().mag2())/std::sqrt(c->getMomentum().mag2() - 2053.952*2053.952))) ;
98 }
99#endif
100 G4double motherMass = c->getMass();
101 const ThreeVector velocity = -c->boostVector();
102
103 // Characteristics of the daughter particle
104 const G4int daughterZ = c->getZ() - decayParticle->getZ();
105 const G4int daughterA = c->getA() - decayParticle->getA();
106 const G4int daughterS = c->getS() - decayParticle->getS();
107 const G4double daughterMass = ParticleTable::getRealMass(daughterA,daughterZ,daughterS);
108
109 // The mother cluster becomes the daughter
110 c->setZ(daughterZ);
111 c->setA(daughterA);
112 c->setS(daughterS);
113 c->setMass(daughterMass);
114 c->setExcitationEnergy(0.);
115
116 // Decay kinematics in the mother rest frame
117 const G4double decayMass = decayParticle->getMass();
118// assert(motherMass-daughterMass-decayMass>-1.e-5); // Q-value should be >0
119 G4double pCM = 0.;
120 if(motherMass-daughterMass-decayMass>0.)
121 pCM = KinematicsUtils::momentumInCM(motherMass, daughterMass, decayMass);
122 const ThreeVector momentum = Random::normVector(pCM);
123 c->setMomentum(momentum);
125 decayParticle->setMomentum(-momentum);
126 decayParticle->adjustEnergyFromMomentum();
127
128 // Boost to the lab frame
129 decayParticle->boost(velocity);
130 c->boost(velocity);
131
132 // Add the decay particle to the list of decay products
133 decayProducts->push_back(decayParticle);
134 }
G4double getEnergy() const
void setEmissionTime(G4double t)
const G4INCL::ThreeVector & getMomentum() const
G4double getEmissionTime()
virtual void setPosition(const G4INCL::ThreeVector &position)

References G4INCL::Particle::adjustEnergyFromMomentum(), G4INCL::ClusterDecay::AlphaDecay, G4INCL::Cluster::boost(), G4INCL::Particle::boost(), G4INCL::Particle::boostVector(), G4INCL::Particle::getA(), G4INCL::Particle::getEmissionTime(), G4INCL::Particle::getEnergy(), G4INCL::Particle::getMass(), G4INCL::Particle::getMomentum(), G4INCL::Particle::getPosition(), G4INCL::ParticleTable::getRealMass(), G4INCL::Particle::getS(), G4INCL::Particle::getZ(), INCL_ERROR, G4INCL::Lambda, G4INCL::ClusterDecay::LambdaDecay, G4INCL::ThreeVector::mag2(), G4INCL::Particle::makeParticipant(), G4INCL::KinematicsUtils::momentumInCM(), G4INCL::Neutron, G4INCL::ClusterDecay::NeutronDecay, G4INCL::Random::normVector(), pos, G4INCL::Cluster::print(), G4INCL::Proton, G4INCL::ClusterDecay::ProtonDecay, G4INCL::Cluster::setA(), G4INCL::Particle::setEmissionTime(), G4INCL::Cluster::setExcitationEnergy(), G4INCL::Particle::setMass(), G4INCL::Particle::setMomentum(), G4INCL::Particle::setNumberOfDecays(), G4INCL::Particle::setPosition(), G4INCL::Particle::setRealMass(), G4INCL::Cluster::setS(), and G4INCL::Cluster::setZ().

Referenced by recursiveDecay().