47 G4int theNumberOfDaughters,
53 :
G4VDecayChannel(
"Phase Space", theParentName, theBR, theNumberOfDaughters, theDaughterName1,
54 theDaughterName2, theDaughterName3, theDaughterName4, theDaughterName5)
69 current_parent_mass.
Put(parentMass);
77 G4cout <<
"G4PhaseSpaceDecayChannel::DecayIt() -";
83 products = OneBodyDecayIt();
86 products = TwoBodyDecayIt();
89 products = ThreeBodyDecayIt();
92 products = ManyBodyDecayIt();
97 G4cout <<
"G4PhaseSpaceDecayChannel::DecayIt() - ";
118 delete parentparticle;
122 if (useGivenDaughterMass) daughterparticle->SetMass(givenDaughterMasses[0]);
123 products->PushProducts(daughterparticle);
127 G4cout <<
"G4PhaseSpaceDecayChannel::OneBodyDecayIt() -";
128 G4cout <<
" create decay products in rest frame " <<
G4endl;
129 products->DumpInfo();
144 G4double daughtermass[2], daughterwidth[2];
155 delete parentparticle;
157 if (!useGivenDaughterMass) {
158 G4bool withWidth = (daughterwidth[0] > 1.0e-3 * daughtermass[0])
159 || (daughterwidth[1] > 1.0e-3 * daughtermass[1]);
162 daughterwidth[0] * daughterwidth[0] + daughterwidth[1] * daughterwidth[1];
165 (parentmass - daughtermass[0] - daughtermass[1]) / std::sqrt(sumofdaughterwidthsq);
169 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()" <<
G4endl
170 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
172 << current_parent_mass.
Get() / GeV <<
G4endl;
174 << daughtermass[0] / GeV <<
G4endl;
176 << daughtermass[1] / GeV <<
G4endl;
180 "Cannot create decay products: sum of daughter mass is \
181 larger than parent mass!");
185 if (daughterwidth[0] > 0.) dm1 =
DynamicalMass(daughtermass[0], daughterwidth[0], maxDev);
187 if (daughterwidth[1] > 0.) dm2 =
DynamicalMass(daughtermass[1], daughterwidth[1], maxDev);
188 while (dm1 + dm2 > parentmass)
190 dm1 =
DynamicalMass(daughtermass[0], daughterwidth[0], maxDev);
191 dm2 =
DynamicalMass(daughtermass[1], daughterwidth[1], maxDev);
193 daughtermass[0] = dm1;
194 daughtermass[1] = dm2;
199 daughtermass[0] = givenDaughterMasses[0];
200 daughtermass[1] = givenDaughterMasses[1];
202 if (parentmass < daughtermass[0] + daughtermass[1]) {
205 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()" <<
G4endl
206 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
208 << current_parent_mass.
Get() / GeV <<
G4endl;
210 << daughtermass[0] / GeV <<
G4endl;
212 << daughtermass[1] / GeV <<
G4endl;
213 if (useGivenDaughterMass) {
219 "Cannot create decay products: sum of daughter mass is \
220 larger than parent mass!");
225 G4double daughtermomentum =
Pmx(parentmass, daughtermass[0], daughtermass[1]);
228 G4double sintheta = std::sqrt((1.0 - costheta) * (1.0 + costheta));
230 G4ThreeVector direction(sintheta * std::cos(phi), sintheta * std::sin(phi), costheta);
233 G4double Ekin = std::sqrt(daughtermomentum * daughtermomentum + daughtermass[0] * daughtermass[0])
235 auto daughterparticle =
237 products->PushProducts(daughterparticle);
238 Ekin = std::sqrt(daughtermomentum * daughtermomentum + daughtermass[1] * daughtermass[1])
242 products->PushProducts(daughterparticle);
246 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt() -";
247 G4cout <<
" Create decay products in rest frame " <<
G4endl;
248 products->DumpInfo();
264 G4double daughtermass[3], daughterwidth[3];
266 G4double sumofdaughterwidthsq = 0.0;
268 for (
G4int index = 0; index < 3; ++index) {
270 sumofdaughtermass += daughtermass[index];
272 sumofdaughterwidthsq += daughterwidth[index] * daughterwidth[index];
273 withWidth = withWidth || (daughterwidth[index] > 1.0e-3 * daughtermass[index]);
282 delete parentparticle;
284 if (!useGivenDaughterMass) {
286 G4double maxDev = (parentmass - sumofdaughtermass) / std::sqrt(sumofdaughterwidthsq);
290 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()" <<
G4endl
291 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
293 << current_parent_mass.
Get() / GeV <<
G4endl;
295 << daughtermass[0] / GeV <<
G4endl;
297 << daughtermass[1] / GeV <<
G4endl;
299 << daughtermass[2] / GeV <<
G4endl;
303 "Cannot create decay products: sum of daughter mass \
304 is larger than parent mass!");
308 if (daughterwidth[0] > 0.) dm1 =
DynamicalMass(daughtermass[0], daughterwidth[0], maxDev);
310 if (daughterwidth[1] > 0.) dm2 =
DynamicalMass(daughtermass[1], daughterwidth[1], maxDev);
312 if (daughterwidth[2] > 0.) dm3 =
DynamicalMass(daughtermass[2], daughterwidth[2], maxDev);
313 while (dm1 + dm2 + dm3 > parentmass)
315 dm1 =
DynamicalMass(daughtermass[0], daughterwidth[0], maxDev);
316 dm2 =
DynamicalMass(daughtermass[1], daughterwidth[1], maxDev);
317 dm3 =
DynamicalMass(daughtermass[2], daughterwidth[2], maxDev);
319 daughtermass[0] = dm1;
320 daughtermass[1] = dm2;
321 daughtermass[2] = dm3;
322 sumofdaughtermass = dm1 + dm2 + dm3;
327 daughtermass[0] = givenDaughterMasses[0];
328 daughtermass[1] = givenDaughterMasses[1];
329 daughtermass[2] = givenDaughterMasses[2];
330 sumofdaughtermass = daughtermass[0] + daughtermass[1] + daughtermass[2];
333 if (sumofdaughtermass > parentmass) {
336 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()" <<
G4endl
337 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
339 << current_parent_mass.
Get() / GeV <<
G4endl;
341 << daughtermass[0] / GeV <<
G4endl;
343 << daughtermass[1] / GeV <<
G4endl;
345 << daughtermass[2] / GeV <<
G4endl;
347 if (useGivenDaughterMass) {
352 "Can not create decay products: sum of daughter mass \
353 is larger than parent mass!");
361 G4double momentummax = 0.0, momentumsum = 0.0;
363 const std::size_t MAX_LOOP = 10000;
365 for (std::size_t loop_counter = 0; loop_counter < MAX_LOOP; ++loop_counter) {
376 energy = rd2 * (parentmass - sumofdaughtermass);
377 daughtermomentum[0] = std::sqrt(energy * energy + 2.0 * energy * daughtermass[0]);
378 if (daughtermomentum[0] > momentummax) momentummax = daughtermomentum[0];
379 momentumsum += daughtermomentum[0];
381 energy = (1. - rd1) * (parentmass - sumofdaughtermass);
382 daughtermomentum[1] = std::sqrt(energy * energy + 2.0 * energy * daughtermass[1]);
383 if (daughtermomentum[1] > momentummax) momentummax = daughtermomentum[1];
384 momentumsum += daughtermomentum[1];
386 energy = (rd1 - rd2) * (parentmass - sumofdaughtermass);
387 daughtermomentum[2] = std::sqrt(energy * energy + 2.0 * energy * daughtermass[2]);
388 if (daughtermomentum[2] > momentummax) momentummax = daughtermomentum[2];
389 momentumsum += daughtermomentum[2];
390 if (momentummax <= momentumsum - momentummax)
break;
396 G4cout <<
" daughter 0:" << daughtermomentum[0] / GeV <<
"[GeV/c]" <<
G4endl;
397 G4cout <<
" daughter 1:" << daughtermomentum[1] / GeV <<
"[GeV/c]" <<
G4endl;
398 G4cout <<
" daughter 2:" << daughtermomentum[2] / GeV <<
"[GeV/c]" <<
G4endl;
399 G4cout <<
" momentum sum:" << momentumsum / GeV <<
"[GeV/c]" <<
G4endl;
404 G4double costheta, sintheta, phi, sinphi, cosphi;
405 G4double costhetan, sinthetan, phin, sinphin, cosphin;
407 sintheta = std::sqrt((1.0 - costheta) * (1.0 + costheta));
409 sinphi = std::sin(phi);
410 cosphi = std::cos(phi);
412 G4ThreeVector direction0(sintheta * cosphi, sintheta * sinphi, costheta);
414 std::sqrt(daughtermomentum[0] * daughtermomentum[0] + daughtermass[0] * daughtermass[0])
416 auto daughterparticle =
418 products->PushProducts(daughterparticle);
420 costhetan = (daughtermomentum[1] * daughtermomentum[1] - daughtermomentum[2] * daughtermomentum[2]
421 - daughtermomentum[0] * daughtermomentum[0])
422 / (2.0 * daughtermomentum[2] * daughtermomentum[0]);
423 sinthetan = std::sqrt((1.0 - costhetan) * (1.0 + costhetan));
425 sinphin = std::sin(phin);
426 cosphin = std::cos(phin);
428 direction2.
setX(sinthetan * cosphin * costheta * cosphi - sinthetan * sinphin * sinphi
429 + costhetan * sintheta * cosphi);
430 direction2.
setY(sinthetan * cosphin * costheta * sinphi + sinthetan * sinphin * cosphi
431 + costhetan * sintheta * sinphi);
432 direction2.
setZ(-sinthetan * cosphin * sintheta + costhetan * costheta);
434 Ekin = std::sqrt(pmom.
mag2() + daughtermass[2] * daughtermass[2]) - daughtermass[2];
437 products->PushProducts(daughterparticle);
439 pmom = (direction0 * daughtermomentum[0] + direction2 * (daughtermomentum[2] / direction2.
mag()))
441 Ekin = std::sqrt(pmom.
mag2() + daughtermass[1] * daughtermass[1]) - daughtermass[1];
444 products->PushProducts(daughterparticle);
448 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt -";
449 G4cout <<
" create decay products in rest frame " <<
G4endl;
450 products->DumpInfo();
479 delete parentparticle;
486 if (!useGivenDaughterMass) {
490 daughtermass[index] = givenDaughterMasses[index];
492 sumofdaughtermass += daughtermass[index];
494 if (sumofdaughtermass > parentmass) {
497 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl
498 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
500 << current_parent_mass.
Get() / GeV <<
G4endl;
502 << daughtermass[0] / GeV <<
G4endl;
504 << daughtermass[1] / GeV <<
G4endl;
506 << daughtermass[2] / GeV <<
G4endl;
508 << daughtermass[3] / GeV <<
G4endl;
510 << daughtermass[4] / GeV <<
G4endl;
514 "Can not create decay products: sum of daughter mass \
515 is larger than parent mass!");
516 delete[] daughtermass;
527 G4int numberOfTry = 0;
528 const std::size_t MAX_LOOP = 10000;
530 for (std::size_t loop_counter = 0; loop_counter < MAX_LOOP; ++loop_counter) {
541 if (rd[index] < rd[index2]) {
543 rd[index] = rd[index2];
550 tmas = parentmass - sumofdaughtermass;
551 temp = sumofdaughtermass;
553 sm[index] = rd[index] * tmas + temp;
554 temp -= daughtermass[index];
556 G4cout << index <<
" rundom number:" << rd[index];
557 G4cout <<
" virtual mass:" <<
sm[index] / GeV <<
"[GeV/c/c]" <<
G4endl;
566 smOK = (
sm[index] - daughtermass[index] -
sm[index + 1] >= 0.);
571 daughtermomentum[index] =
Pmx(sm[index - 1], daughtermass[index - 1], sm[index]);
575 G4cout <<
" momentum:" << daughtermomentum[index] / GeV <<
"[GeV/c]" <<
G4endl;
580 daughtermomentum[index] =
Pmx(sm[index], daughtermass[index], sm[index + 1]);
581 if (daughtermomentum[index] < 0.0) {
585 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl;
586 G4cout <<
" Cannot calculate daughter momentum " <<
G4endl;
588 G4cout <<
" mass:" << parentmass / GeV <<
"[GeV/c/c]" <<
G4endl;
590 G4cout <<
" mass:" << daughtermass[index] / GeV <<
"[GeV/c/c]";
591 G4cout <<
" mass:" << daughtermomentum[index] / GeV <<
"[GeV/c]" <<
G4endl;
592 if (useGivenDaughterMass) {
598 delete[] daughtermass;
599 delete[] daughtermomentum;
602 "Can not create decay products: sum of daughter mass \
603 is larger than parent mass");
608 weight *= daughtermomentum[index] /
sm[index];
612 G4cout <<
" momentum:" << daughtermomentum[index] / GeV <<
"[GeV/c]" <<
G4endl;
624 if (++numberOfTry > 100) {
627 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl;
628 G4cout <<
"Cannot determine Decay Kinematics " <<
G4endl;
638 "Cannot decay: Decay Kinematics cannot be calculated");
641 delete[] daughtermass;
642 delete[] daughtermomentum;
651 G4cout <<
"Start calculation of daughters momentum vector " <<
G4endl;
661 sintheta = std::sqrt((1.0 - costheta) * (1.0 + costheta));
663 direction.
setZ(costheta);
664 direction.
setY(sintheta * std::sin(phi));
665 direction.
setX(sintheta * std::cos(phi));
666 daughterparticle[index] =
668 daughterparticle[index + 1] =
674 sintheta = std::sqrt((1.0 - costheta) * (1.0 + costheta));
676 direction.
setZ(costheta);
677 direction.
setY(sintheta * std::sin(phi));
678 direction.
setX(sintheta * std::cos(phi));
681 beta = daughtermomentum[index];
683 std::sqrt(daughtermomentum[index] * daughtermomentum[index] + sm[index + 1] * sm[index + 1]);
690 p4.
boost(direction.
x() * beta, direction.
y() * beta, direction.
z() * beta);
696 daughterparticle[index] =
702 products->PushProducts(daughterparticle[index]);
707 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt() -";
708 G4cout <<
" create decay products in rest frame " <<
G4endl;
709 products->DumpInfo();
713 delete[] daughterparticle;
714 delete[] daughtermomentum;
715 delete[] daughtermass;
724 givenDaughterMasses[idx] = masses[idx];
726 useGivenDaughterMass =
true;
727 return useGivenDaughterMass;
732 useGivenDaughterMass =
false;
733 return useGivenDaughterMass;
743 G4double sumOfDaughterMassMin = 0.0;
745 sumOfDaughterMassMin += givenDaughterMasses[index];
747 return (parentMass >= sumOfDaughterMassMin);
753 G4double ppp = (e + p1 + p2) * (e + p1 - p2) * (e - p1 + p2) * (e - p1 - p2) / (4.0 * e * e);
754 if (ppp > 0)
return std::sqrt(ppp);
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4GLOB_DLL std::ostream G4cout
HepLorentzVector & boost(double, double, double)
void Put(const value_type &val) const
G4LorentzVector Get4Momentum() const
void Set4Momentum(const G4LorentzVector &momentum)
const G4String & GetParticleName() const
G4DecayProducts * DecayIt(G4double) override
static G4double Pmx(G4double e, G4double p1, G4double p2)
G4PhaseSpaceDecayChannel(G4int Verbose=1)
G4bool SetDaughterMasses(G4double masses[])
G4bool SampleDaughterMasses()
G4bool IsOKWithParentMass(G4double parentMass) override
G4ParticleDefinition ** G4MT_daughters
void CheckAndFillParent()
G4String ** daughters_name
G4double DynamicalMass(G4double massPDG, G4double width, G4double maxDev=1.0) const
G4int GetVerboseLevel() const
G4double G4MT_parent_mass
G4ParticleDefinition * G4MT_parent
virtual G4bool IsOKWithParentMass(G4double parentMass)
void CheckAndFillDaughters()
G4double * G4MT_daughters_mass
G4double * G4MT_daughters_width
G4double energy(const ThreeVector &p, const G4double m)