50 G4int theNumberOfDaughters,
56 :
G4VDecayChannel(
"Phase Space", theParentName,theBR, theNumberOfDaughters,
57 theDaughterName1, theDaughterName2,
58 theDaughterName3, theDaughterName4, theDaughterName5)
72 G4cout <<
"G4PhaseSpaceDecayChannel::DecayIt()" <<
G4endl;
80 if (parentMass >0.0) current_parent_mass.
Put( parentMass );
89 G4cout <<
"G4PhaseSpaceDecayChannel::DecayIt() -";
95 products = OneBodyDecayIt();
98 products = TwoBodyDecayIt();
101 products = ThreeBodyDecayIt();
104 products = ManyBodyDecayIt();
110 G4cout <<
"G4PhaseSpaceDecayChannel::DecayIt() - ";
123 G4cout <<
"G4PhaseSpaceDecayChannel::OneBodyDecayIt()" <<
G4endl;
134 delete parentparticle;
139 if (useGivenDaughterMass) daughterparticle->
SetMass(givenDaughterMasses[0]);
145 G4cout <<
"G4PhaseSpaceDecayChannel::OneBodyDecayIt() -";
146 G4cout <<
" create decay products in rest frame " <<
G4endl;
158 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()" <<
G4endl;
164 G4double daughtermass[2], daughterwidth[2];
176 delete parentparticle;
178 if (!useGivenDaughterMass)
180 G4bool withWidth = (daughterwidth[0]>1.0e-3*daughtermass[0])
181 || (daughterwidth[1]>1.0e-3*daughtermass[1]);
184 G4double sumofdaughterwidthsq = daughterwidth[0]*daughterwidth[0]
185 + daughterwidth[1]*daughterwidth[1];
187 G4double maxDev = (parentmass - daughtermass[0] - daughtermass[1] )
188 / std::sqrt(sumofdaughterwidthsq);
194 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()" <<
G4endl
195 <<
"Sum of daughter mass is larger than parent mass!"
198 <<
" " << current_parent_mass.
Get()/GeV <<
G4endl;
200 <<
" " << daughtermass[0]/GeV <<
G4endl;
202 <<
" " << daughtermass[1]/GeV <<
G4endl;
205 G4Exception(
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()",
207 "Cannot create decay products: sum of daughter mass is \
208 larger than parent mass!");
212 if (daughterwidth[0] > 0.)
213 dm1 =
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
215 if (daughterwidth[1] > 0.)
216 dm2 =
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
217 while (dm1+dm2>parentmass)
219 dm1 =
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
220 dm2 =
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
222 daughtermass[0] = dm1;
223 daughtermass[1] = dm2;
229 daughtermass[0] = givenDaughterMasses[0];
230 daughtermass[1] = givenDaughterMasses[1];
232 if (parentmass < daughtermass[0] + daughtermass[1] )
237 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()" <<
G4endl
238 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
240 <<
" " << current_parent_mass.
Get()/GeV <<
G4endl;
242 <<
" " << daughtermass[0]/GeV <<
G4endl;
244 <<
" " << daughtermass[1]/GeV <<
G4endl;
245 if (useGivenDaughterMass)
251 G4Exception(
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()",
253 "Cannot create decay products: sum of daughter mass is \
254 larger than parent mass!");
259 G4double daughtermomentum =
Pmx(parentmass,daughtermass[0],daughtermass[1]);
262 G4double sintheta = std::sqrt((1.0 - costheta)*(1.0 + costheta));
265 sintheta*std::sin(phi), costheta);
268 G4double Ekin = std::sqrt(daughtermomentum*daughtermomentum
269 + daughtermass[0]*daughtermass[0]) - daughtermass[0];
273 Ekin = std::sqrt(daughtermomentum*daughtermomentum
274 + daughtermass[1]*daughtermass[1]) - daughtermass[1];
277 Ekin, daughtermass[1]);
283 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt() -";
284 G4cout <<
" Create decay products in rest frame " <<
G4endl;
298 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()" <<
G4endl;
303 G4double daughtermass[3], daughterwidth[3];
305 G4double sumofdaughterwidthsq = 0.0;
307 for (
G4int index=0; index<3; ++index)
310 sumofdaughtermass += daughtermass[index];
312 sumofdaughterwidthsq += daughterwidth[index]*daughterwidth[index];
313 withWidth = withWidth ||(daughterwidth[index]>1.0e-3*daughtermass[index]);
323 delete parentparticle;
325 if (!useGivenDaughterMass)
329 G4double maxDev = (parentmass - sumofdaughtermass )
330 / std::sqrt(sumofdaughterwidthsq);
336 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()" <<
G4endl
337 <<
"Sum of daughter mass is larger than parent mass!"
340 <<
" " << current_parent_mass.
Get()/GeV <<
G4endl;
342 <<
" " << daughtermass[0]/GeV <<
G4endl;
344 <<
" " << daughtermass[1]/GeV <<
G4endl;
346 <<
" " << daughtermass[2]/GeV <<
G4endl;
349 G4Exception(
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()",
351 "Cannot create decay products: sum of daughter mass \
352 is larger than parent mass!");
356 if (daughterwidth[0] > 0.)
357 dm1=
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
359 if (daughterwidth[1] > 0.)
360 dm2=
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
362 if (daughterwidth[2] > 0.)
363 dm3=
DynamicalMass(daughtermass[2],daughterwidth[2], maxDev);
364 while (dm1+dm2+dm3>parentmass)
366 dm1=
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
367 dm2=
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
368 dm3=
DynamicalMass(daughtermass[2],daughterwidth[2], maxDev);
370 daughtermass[0] = dm1;
371 daughtermass[1] = dm2;
372 daughtermass[2] = dm3;
373 sumofdaughtermass = dm1+dm2+dm3;
379 daughtermass[0] = givenDaughterMasses[0];
380 daughtermass[1] = givenDaughterMasses[1];
381 daughtermass[2] = givenDaughterMasses[2];
382 sumofdaughtermass = daughtermass[0] + daughtermass[1] + daughtermass[2];
385 if (sumofdaughtermass >parentmass)
390 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()" <<
G4endl
391 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
393 <<
" " << current_parent_mass.
Get()/GeV <<
G4endl;
395 <<
" " << daughtermass[0]/GeV <<
G4endl;
397 <<
" " << daughtermass[1]/GeV <<
G4endl;
399 <<
" " << daughtermass[2]/GeV <<
G4endl;
401 if (useGivenDaughterMass)
406 G4Exception(
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt",
408 "Can not create decay products: sum of daughter mass \
409 is larger than parent mass!");
417 G4double momentummax=0.0, momentumsum = 0.0;
419 const std::size_t MAX_LOOP=10000;
421 for (std::size_t loop_counter=0; loop_counter<MAX_LOOP; ++loop_counter)
434 energy = rd2*(parentmass - sumofdaughtermass);
435 daughtermomentum[0] = std::sqrt(energy*energy
436 + 2.0*energy* daughtermass[0]);
437 if ( daughtermomentum[0] > momentummax )
438 momentummax = daughtermomentum[0];
439 momentumsum += daughtermomentum[0];
441 energy = (1.-rd1)*(parentmass - sumofdaughtermass);
442 daughtermomentum[1] = std::sqrt(energy*energy
443 + 2.0*energy*daughtermass[1]);
444 if ( daughtermomentum[1] >momentummax )momentummax = daughtermomentum[1];
445 momentumsum += daughtermomentum[1];
447 energy = (rd1-rd2)*(parentmass - sumofdaughtermass);
448 daughtermomentum[2] = std::sqrt(energy*energy
449 + 2.0*energy* daughtermass[2]);
450 if ( daughtermomentum[2] > momentummax )
451 momentummax = daughtermomentum[2];
452 momentumsum += daughtermomentum[2];
453 if (momentummax <= momentumsum - momentummax )
break;
460 G4cout <<
" daughter 0:" << daughtermomentum[0]/GeV <<
"[GeV/c]"
462 G4cout <<
" daughter 1:" << daughtermomentum[1]/GeV <<
"[GeV/c]"
464 G4cout <<
" daughter 2:" << daughtermomentum[2]/GeV <<
"[GeV/c]"
466 G4cout <<
" momentum sum:" << momentumsum/GeV <<
"[GeV/c]"
472 G4double costheta, sintheta, phi, sinphi, cosphi;
473 G4double costhetan, sinthetan, phin, sinphin, cosphin;
475 sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
477 sinphi = std::sin(phi);
478 cosphi = std::cos(phi);
480 G4ThreeVector direction0(sintheta*cosphi,sintheta*sinphi,costheta);
481 G4double Ekin = std::sqrt(daughtermomentum[0]*daughtermomentum[0]
482 + daughtermass[0]*daughtermass[0]) - daughtermass[0];
487 costhetan = (daughtermomentum[1]*daughtermomentum[1]
488 - daughtermomentum[2]*daughtermomentum[2]
489 - daughtermomentum[0]*daughtermomentum[0])
490 / (2.0*daughtermomentum[2]*daughtermomentum[0]);
491 sinthetan = std::sqrt((1.0-costhetan)*(1.0+costhetan));
493 sinphin = std::sin(phin);
494 cosphin = std::cos(phin);
496 direction2.
setX( sinthetan*cosphin*costheta*cosphi
497 - sinthetan*sinphin*sinphi + costhetan*sintheta*cosphi);
498 direction2.
setY( sinthetan*cosphin*costheta*sinphi
499 + sinthetan*sinphin*cosphi + costhetan*sintheta*sinphi);
500 direction2.
setZ( -sinthetan*cosphin*sintheta + costhetan*costheta);
502 Ekin = std::sqrt(pmom.
mag2() + daughtermass[2]*daughtermass[2])
506 Ekin, daughtermass[2] );
509 pmom = (direction0*daughtermomentum[0]
510 + direction2*(daughtermomentum[2]/direction2.
mag()))*(-1.0);
511 Ekin = std::sqrt(pmom.
mag2() + daughtermass[1]*daughtermass[1])
515 Ekin, daughtermass[1] );
521 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt -";
522 G4cout <<
" create decay products in rest frame " <<
G4endl;
542 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl;
555 delete parentparticle;
563 if (!useGivenDaughterMass)
569 daughtermass[index] = givenDaughterMasses[index];
571 sumofdaughtermass += daughtermass[index];
573 if (sumofdaughtermass >parentmass)
578 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl
579 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
581 <<
" " << current_parent_mass.
Get()/GeV <<
G4endl;
583 <<
" " << daughtermass[0]/GeV <<
G4endl;
585 <<
" " << daughtermass[1]/GeV <<
G4endl;
587 <<
" " << daughtermass[2]/GeV <<
G4endl;
589 <<
" " << daughtermass[3]/GeV <<
G4endl;
591 <<
" " << daughtermass[4]/GeV <<
G4endl;
594 G4Exception(
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()",
596 "Can not create decay products: sum of daughter mass \
597 is larger than parent mass!");
598 delete [] daughtermass;
609 G4int numberOfTry = 0;
610 const std::size_t MAX_LOOP=10000;
612 for (std::size_t loop_counter=0; loop_counter<MAX_LOOP; ++loop_counter)
627 if (rd[index] < rd[index2])
630 rd[index] = rd[index2];
637 tmas = parentmass - sumofdaughtermass;
638 temp = sumofdaughtermass;
641 sm[index] = rd[index]*tmas + temp;
642 temp -= daughtermass[index];
645 G4cout << index <<
" rundom number:" << rd[index];
646 G4cout <<
" virtual mass:" <<
sm[index]/GeV <<
"[GeV/c/c]" <<
G4endl;
656 smOK = (
sm[index]-daughtermass[index]-
sm[index+1] >=0.);
661 daughtermomentum[index]=
Pmx(sm[index-1],daughtermass[index-1],sm[index]);
666 G4cout <<
" momentum:" << daughtermomentum[index]/GeV <<
"[GeV/c]"
673 daughtermomentum[index]=
Pmx( sm[index],daughtermass[index],sm[index +1]);
674 if(daughtermomentum[index] < 0.0)
680 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl;
681 G4cout <<
" Cannot calculate daughter momentum " <<
G4endl;
683 G4cout <<
" mass:" << parentmass/GeV <<
"[GeV/c/c]" <<
G4endl;
685 G4cout <<
" mass:" << daughtermass[index]/GeV <<
"[GeV/c/c]";
686 G4cout <<
" mass:" << daughtermomentum[index]/GeV <<
"[GeV/c]"
688 if (useGivenDaughterMass)
695 delete [] daughtermass;
696 delete [] daughtermomentum;
698 G4Exception(
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()",
700 "Can not create decay products: sum of daughter mass \
701 is larger than parent mass");
708 weight *= daughtermomentum[index]/
sm[index];
713 G4cout <<
" momentum:" << daughtermomentum[index]/GeV <<
"[GeV/c]"
728 if (++numberOfTry > 100)
733 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl;
734 G4cout <<
"Cannot determine Decay Kinematics " <<
G4endl;
744 G4Exception(
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()",
746 "Cannot decay: Decay Kinematics cannot be calculated");
749 delete [] daughtermass;
750 delete [] daughtermomentum;
760 G4cout <<
"Start calculation of daughters momentum vector " <<
G4endl;
770 sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
772 direction.
setZ(costheta);
773 direction.
setY(sintheta*std::sin(phi));
774 direction.
setX(sintheta*std::cos(phi));
776 direction*daughtermomentum[index] );
778 direction*(-1.0*daughtermomentum[index]) );
784 sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
786 direction.
setZ(costheta);
787 direction.
setY(sintheta*std::sin(phi));
788 direction.
setX(sintheta*std::cos(phi));
791 beta = daughtermomentum[index];
792 beta /= std::sqrt( daughtermomentum[index]*daughtermomentum[index]
793 + sm[index+1]*sm[index+1] );
801 p4.
boost( direction.
x()*beta, direction.
y()*beta, direction.
z()*beta);
808 direction*(-1.0*daughtermomentum[index]));
820 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt() -";
821 G4cout <<
" create decay products in rest frame " <<
G4endl;
826 delete [] daughterparticle;
827 delete [] daughtermomentum;
828 delete [] daughtermass;
839 givenDaughterMasses[idx] = masses[idx];
841 useGivenDaughterMass =
true;
842 return useGivenDaughterMass;
848 useGivenDaughterMass =
false;
849 return useGivenDaughterMass;
855 if (!useGivenDaughterMass)
864 sumOfDaughterMassMin += givenDaughterMasses[index];
866 return (parentMass >= sumOfDaughterMassMin);
873 G4double ppp = (e+p1+p2)*(e+p1-p2)*(e-p1+p2)*(e-p1-p2)/(4.0*e*e);
874 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
G4int PushProducts(G4DynamicParticle *aParticle)
void SetMass(G4double mass)
G4LorentzVector Get4Momentum() const
void Set4Momentum(const G4LorentzVector &momentum)
const G4String & GetParticleName() const
virtual ~G4PhaseSpaceDecayChannel()
static G4double Pmx(G4double e, G4double p1, G4double p2)
virtual G4DecayProducts * DecayIt(G4double)
G4bool IsOKWithParentMass(G4double parentMass)
G4PhaseSpaceDecayChannel(G4int Verbose=1)
G4bool SetDaughterMasses(G4double masses[])
G4bool SampleDaughterMasses()
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)