53 useGivenDaughterMass(false)
61 G4int theNumberOfDaughters,
73 useGivenDaughterMass(false)
93 if (parentMass >0.0) current_parent_mass.
Put( parentMass );
100 G4cout <<
"G4PhaseSpaceDecayChannel::DecayIt ";
106 products = OneBodyDecayIt();
109 products = TwoBodyDecayIt();
112 products = ThreeBodyDecayIt();
115 products = ManyBodyDecayIt();
120 G4cout <<
"G4PhaseSpaceDecayChannel::DecayIt ";
141 delete parentparticle;
145 if (useGivenDaughterMass) daughterparticle->
SetMass(givenDaughterMasses[0]);
150 G4cout <<
"G4PhaseSpaceDecayChannel::OneBodyDecayIt ";
151 G4cout <<
" create decay products in rest frame " <<
G4endl;
167 G4double daughtermass[2], daughterwidth[2];
178 delete parentparticle;
180 if (!useGivenDaughterMass) {
181 G4bool withWidth = (daughterwidth[0]>1.0e-3*daughtermass[0])
182 || (daughterwidth[1]>1.0e-3*daughtermass[1]);
184 G4double sumofdaughterwidthsq = daughterwidth[0]*daughterwidth[0]+daughterwidth[1]*daughterwidth[1];
186 G4double maxDev = (parentmass - daughtermass[0] - daughtermass[1] )/std::sqrt(sumofdaughterwidthsq);
190 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt "
191 <<
"sum of daughter mass is larger than parent mass" <<
G4endl;
197 G4Exception(
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt",
199 "Can not create decay products: sum of daughter mass is larger than parent mass");
203 if (daughterwidth[0] > 0.) dm1=
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
205 if (daughterwidth[1] > 0.) dm2=
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
206 while (dm1+dm2>parentmass){
207 dm1=
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
208 dm2=
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
210 daughtermass[0] = dm1;
211 daughtermass[1] = dm2;
215 daughtermass[0] = givenDaughterMasses[0];
216 daughtermass[1] = givenDaughterMasses[1];
218 if (parentmass < daughtermass[0] + daughtermass[1] ){
221 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt "
222 <<
"sum of daughter mass is larger than parent mass" <<
G4endl;
226 if (useGivenDaughterMass) {
231 G4Exception(
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt",
233 "Can not create decay products: sum of daughter mass is larger than parent mass");
238 G4double daughtermomentum =
Pmx(parentmass,daughtermass[0],daughtermass[1]);
241 G4double sintheta = std::sqrt((1.0 - costheta)*(1.0 + costheta));
243 G4ThreeVector direction(sintheta*std::cos(phi),sintheta*std::sin(phi),costheta);
246 G4double Ekin = std::sqrt(daughtermomentum*daughtermomentum + daughtermass[0]*daughtermass[0]) - daughtermass[0];
249 Ekin = std::sqrt(daughtermomentum*daughtermomentum + daughtermass[1]*daughtermass[1]) - daughtermass[1];
255 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt ";
256 G4cout <<
" create decay products in rest frame " <<
G4endl;
272 G4double daughtermass[3], daughterwidth[3];
274 G4double sumofdaughterwidthsq = 0.0;
276 for (
G4int index=0; index<3; index++){
278 sumofdaughtermass += daughtermass[index];
280 sumofdaughterwidthsq += daughterwidth[index]*daughterwidth[index];
281 withWidth = withWidth ||(daughterwidth[index]>1.0e-3*daughtermass[index]);
291 delete parentparticle;
293 if (!useGivenDaughterMass) {
295 G4double maxDev = (parentmass - sumofdaughtermass )/std::sqrt(sumofdaughterwidthsq) ;
299 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt "
300 <<
"sum of daughter mass is larger than parent mass" <<
G4endl;
307 G4Exception(
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt",
309 "Can not create decay products: sum of daughter mass is larger than parent mass");
313 if (daughterwidth[0] > 0.) dm1=
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
315 if (daughterwidth[1] > 0.) dm2=
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
317 if (daughterwidth[2] > 0.) dm3=
DynamicalMass(daughtermass[2],daughterwidth[2], maxDev);
318 while (dm1+dm2+dm3>parentmass){
319 dm1=
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
320 dm2=
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
321 dm3=
DynamicalMass(daughtermass[2],daughterwidth[2], maxDev);
323 daughtermass[0] = dm1;
324 daughtermass[1] = dm2;
325 daughtermass[2] = dm3;
326 sumofdaughtermass = dm1+dm2+dm3;
330 daughtermass[0] = givenDaughterMasses[0];
331 daughtermass[1] = givenDaughterMasses[1];
332 daughtermass[2] = givenDaughterMasses[2];
333 sumofdaughtermass = daughtermass[0] + daughtermass[1] + daughtermass[2];
336 if (sumofdaughtermass >parentmass) {
339 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt "
340 <<
"sum of daughter mass is larger than parent mass" <<
G4endl;
346 if (useGivenDaughterMass) {
350 G4Exception(
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt",
352 "Can not create decay products: sum of daughter mass is larger than parent mass");
362 G4double momentummax=0.0, momentumsum = 0.0;
364 const size_t MAX_LOOP=10000;
366 for (
size_t loop_counter=0; loop_counter <MAX_LOOP; ++loop_counter){
377 energy = rd2*(parentmass - sumofdaughtermass);
378 daughtermomentum[0] = std::sqrt(energy*energy + 2.0*energy* daughtermass[0]);
379 if ( daughtermomentum[0] >momentummax )momentummax = daughtermomentum[0];
380 momentumsum += daughtermomentum[0];
382 energy = (1.-rd1)*(parentmass - sumofdaughtermass);
383 daughtermomentum[1] = std::sqrt(energy*energy + 2.0*energy* daughtermass[1]);
384 if ( daughtermomentum[1] >momentummax )momentummax = daughtermomentum[1];
385 momentumsum += daughtermomentum[1];
387 energy = (rd1-rd2)*(parentmass - sumofdaughtermass);
388 daughtermomentum[2] = std::sqrt(energy*energy + 2.0*energy* daughtermass[2]);
389 if ( daughtermomentum[2] >momentummax )momentummax = daughtermomentum[2];
390 momentumsum += daughtermomentum[2];
391 if (momentummax <= momentumsum - momentummax )
break;
397 G4cout <<
" daughter 0:" << daughtermomentum[0]/
GeV <<
"[GeV/c]" <<
G4endl;
398 G4cout <<
" daughter 1:" << daughtermomentum[1]/
GeV <<
"[GeV/c]" <<
G4endl;
399 G4cout <<
" daughter 2:" << daughtermomentum[2]/
GeV <<
"[GeV/c]" <<
G4endl;
405 G4double costheta, sintheta, phi, sinphi, cosphi;
406 G4double costhetan, sinthetan, phin, sinphin, cosphin;
408 sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
410 sinphi = std::sin(phi);
411 cosphi = std::cos(phi);
413 G4ThreeVector direction0(sintheta*cosphi,sintheta*sinphi,costheta);
414 G4double Ekin = std::sqrt(daughtermomentum[0]*daughtermomentum[0] + daughtermass[0]*daughtermass[0]) - daughtermass[0];
417 Ekin, daughtermass[0]);
420 costhetan = (daughtermomentum[1]*daughtermomentum[1]-daughtermomentum[2]*daughtermomentum[2]-daughtermomentum[0]*daughtermomentum[0])/(2.0*daughtermomentum[2]*daughtermomentum[0]);
421 sinthetan = std::sqrt((1.0-costhetan)*(1.0+costhetan));
423 sinphin = std::sin(phin);
424 cosphin = std::cos(phin);
426 direction2.
setX( sinthetan*cosphin*costheta*cosphi - sinthetan*sinphin*sinphi + costhetan*sintheta*cosphi);
427 direction2.
setY( sinthetan*cosphin*costheta*sinphi + sinthetan*sinphin*cosphi + costhetan*sintheta*sinphi);
428 direction2.
setZ( -sinthetan*cosphin*sintheta + costhetan*costheta);
430 Ekin = std::sqrt(pmom.
mag2() + daughtermass[2]*daughtermass[2]) - daughtermass[2];
433 Ekin, daughtermass[2]);
436 pmom = (direction0*daughtermomentum[0] + direction2*(daughtermomentum[2]/direction2.
mag()))*(-1.0);
437 Ekin = std::sqrt(pmom.
mag2() + daughtermass[1]*daughtermass[1]) - daughtermass[1];
441 Ekin, daughtermass[1]);
446 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt ";
447 G4cout <<
" create decay products in rest frame " <<
G4endl;
481 delete parentparticle;
488 if (!useGivenDaughterMass) {
491 daughtermass[index] = givenDaughterMasses[index];
493 sumofdaughtermass += daughtermass[index];
495 if (sumofdaughtermass >parentmass) {
498 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt "
499 <<
"sum of daughter mass is larger than parent mass" <<
G4endl;
507 G4Exception(
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt",
509 "Can not create decay products: sum of daughter mass is larger than parent mass");
510 delete [] daughtermass;
521 G4int numberOfTry = 0;
522 const size_t MAX_LOOP=10000;
524 for (
size_t loop_counter=0; loop_counter <MAX_LOOP; ++loop_counter){
529 for(index =1; index < numberOfDaughters -1; index++) rd[index] =
G4UniformRand();
530 rd[ numberOfDaughters -1] = 0.0;
531 for(index =1; index < numberOfDaughters -1; index++) {
533 if (rd[index] < rd[index2]){
535 rd[index] = rd[index2];
542 tmas = parentmass - sumofdaughtermass;
543 temp = sumofdaughtermass;
545 sm[index] = rd[index]*tmas + temp;
546 temp -= daughtermass[index];
548 G4cout << index <<
" rundom number:" << rd[index];
557 for(index =0; index< numberOfDaughters-1 && smOK; index--) {
558 smOK = (sm[index]-daughtermass[index]- sm[index+1] >=0.);
562 index =numberOfDaughters-1;
563 daughtermomentum[index]=
Pmx( sm[index-1],daughtermass[index-1], sm[index]);
567 G4cout <<
" momentum:" << daughtermomentum[index]/
GeV <<
"[GeV/c]" <<
G4endl;
570 for(index =numberOfDaughters-2; index>=0; index--) {
572 daughtermomentum[index]=
Pmx( sm[index],daughtermass[index], sm[index +1]);
573 if(daughtermomentum[index] < 0.0) {
577 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt ";
578 G4cout <<
" can not calculate daughter momentum " <<
G4endl;
582 G4cout <<
" mass:" << daughtermass[index]/
GeV <<
"[GeV/c/c]" ;
583 G4cout <<
" mass:" << daughtermomentum[index]/
GeV <<
"[GeV/c]" <<
G4endl;
584 if (useGivenDaughterMass) {
590 delete [] daughtermass;
591 delete [] daughtermomentum;
593 G4Exception(
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt",
595 "Can not create decay products: sum of daughter mass is larger than parent mass");
601 weight *= daughtermomentum[index]/sm[index];
605 G4cout <<
" momentum:" << daughtermomentum[index]/
GeV <<
"[GeV/c]" <<
G4endl;
618 if (numberOfTry++ >100) {
621 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt: ";
622 G4cout <<
" can not determine Decay Kinematics " <<
G4endl;
631 G4Exception(
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt: ",
633 " Cannot decay : Decay Kinematics cannot be calculated ");
636 delete [] daughtermass;
637 delete [] daughtermomentum;
645 G4cout <<
"Start calulation of daughters momentum vector "<<
G4endl;
653 index = numberOfDaughters -2;
655 sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
657 direction.
setZ(costheta);
658 direction.
setY(sintheta*std::sin(phi));
659 direction.
setX(sintheta*std::cos(phi));
663 for (index = numberOfDaughters -3; index >= 0; index--) {
666 sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
668 direction.
setZ(costheta);
669 direction.
setY(sintheta*std::sin(phi));
670 direction.
setX(sintheta*std::cos(phi));
673 beta = daughtermomentum[index];
674 beta /= std::sqrt( daughtermomentum[index]*daughtermomentum[index] + sm[index+1]*sm[index+1] );
681 p4.
boost( direction.
x()*beta, direction.
y()*beta, direction.
z()*beta);
697 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt ";
698 G4cout <<
" create decay products in rest frame " <<
G4endl;
703 delete [] daughterparticle;
704 delete [] daughtermomentum;
705 delete [] daughtermass;
714 givenDaughterMasses[idx] = masses[idx];
716 useGivenDaughterMass =
true;
717 return useGivenDaughterMass;
722 useGivenDaughterMass =
false;
723 return useGivenDaughterMass;
734 sumOfDaughterMassMin += givenDaughterMasses[index];
736 return (parentMass >= sumOfDaughterMassMin);
742 G4double ppp = (e+p1+p2)*(e+p1-p2)*(e-p1+p2)*(e-p1-p2)/(4.0*e*e);
743 if (ppp>0)
return std::sqrt(ppp);
virtual G4DecayProducts * DecayIt(G4double)
void CheckAndFillDaughters()
G4double * G4MT_daughters_mass
G4bool SetDaughterMasses(G4double masses[])
G4int PushProducts(G4DynamicParticle *aParticle)
G4ParticleDefinition * G4MT_parent
G4bool IsOKWithParentMass(G4double parentMass)
G4ParticleDefinition ** G4MT_daughters
G4double G4MT_parent_mass
virtual G4bool IsOKWithParentMass(G4double parentMass)
G4bool SampleDaughterMasses()
static constexpr double rad
const G4String & GetParticleName() const
static constexpr double twopi
virtual ~G4PhaseSpaceDecayChannel()
G4GLOB_DLL std::ostream G4cout
HepLorentzVector & boost(double, double, double)
G4LorentzVector Get4Momentum() const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
void Set4Momentum(const G4LorentzVector &momentum)
G4int GetVerboseLevel() const
G4double * G4MT_daughters_width
G4double energy(const ThreeVector &p, const G4double m)
static constexpr double GeV
G4double DynamicalMass(G4double massPDG, G4double width, G4double maxDev=+1.) const
G4PhaseSpaceDecayChannel(G4int Verbose=1)
void Put(const value_type &val) const
void SetMass(G4double mass)
G4String ** daughters_name
void CheckAndFillParent()
static G4double Pmx(G4double e, G4double p1, G4double p2)