50 G4int theNumberOfDaughters,
55 :
G4VDecayChannel(
"Phase Space", theParentName,theBR, theNumberOfDaughters,
56 theDaughterName1, theDaughterName2,
57 theDaughterName3, theDaughterName4)
71 G4cout <<
"G4PhaseSpaceDecayChannel::DecayIt()" <<
G4endl;
79 if (parentMass >0.0) current_parent_mass.
Put( parentMass );
88 G4cout <<
"G4PhaseSpaceDecayChannel::DecayIt() -";
94 products = OneBodyDecayIt();
97 products = TwoBodyDecayIt();
100 products = ThreeBodyDecayIt();
103 products = ManyBodyDecayIt();
109 G4cout <<
"G4PhaseSpaceDecayChannel::DecayIt() - ";
122 G4cout <<
"G4PhaseSpaceDecayChannel::OneBodyDecayIt()" <<
G4endl;
133 delete parentparticle;
138 if (useGivenDaughterMass) daughterparticle->
SetMass(givenDaughterMasses[0]);
144 G4cout <<
"G4PhaseSpaceDecayChannel::OneBodyDecayIt() -";
145 G4cout <<
" create decay products in rest frame " <<
G4endl;
157 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()" <<
G4endl;
163 G4double daughtermass[2], daughterwidth[2];
175 delete parentparticle;
177 if (!useGivenDaughterMass)
179 G4bool withWidth = (daughterwidth[0]>1.0e-3*daughtermass[0])
180 || (daughterwidth[1]>1.0e-3*daughtermass[1]);
183 G4double sumofdaughterwidthsq = daughterwidth[0]*daughterwidth[0]
184 + daughterwidth[1]*daughterwidth[1];
186 G4double maxDev = (parentmass - daughtermass[0] - daughtermass[1] )
187 / std::sqrt(sumofdaughterwidthsq);
193 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()" <<
G4endl
194 <<
"Sum of daughter mass is larger than parent mass!"
197 <<
" " << current_parent_mass.
Get()/GeV <<
G4endl;
199 <<
" " << daughtermass[0]/GeV <<
G4endl;
201 <<
" " << daughtermass[1]/GeV <<
G4endl;
204 G4Exception(
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()",
206 "Cannot create decay products: sum of daughter mass is \
207 larger than parent mass!");
211 if (daughterwidth[0] > 0.)
212 dm1 =
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
214 if (daughterwidth[1] > 0.)
215 dm2 =
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
216 while (dm1+dm2>parentmass)
218 dm1 =
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
219 dm2 =
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
221 daughtermass[0] = dm1;
222 daughtermass[1] = dm2;
228 daughtermass[0] = givenDaughterMasses[0];
229 daughtermass[1] = givenDaughterMasses[1];
231 if (parentmass < daughtermass[0] + daughtermass[1] )
236 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()" <<
G4endl
237 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
239 <<
" " << current_parent_mass.
Get()/GeV <<
G4endl;
241 <<
" " << daughtermass[0]/GeV <<
G4endl;
243 <<
" " << daughtermass[1]/GeV <<
G4endl;
244 if (useGivenDaughterMass)
250 G4Exception(
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt()",
252 "Cannot create decay products: sum of daughter mass is \
253 larger than parent mass!");
258 G4double daughtermomentum =
Pmx(parentmass,daughtermass[0],daughtermass[1]);
261 G4double sintheta = std::sqrt((1.0 - costheta)*(1.0 + costheta));
264 sintheta*std::sin(phi), costheta);
267 G4double Ekin = std::sqrt(daughtermomentum*daughtermomentum
268 + daughtermass[0]*daughtermass[0]) - daughtermass[0];
272 Ekin = std::sqrt(daughtermomentum*daughtermomentum
273 + daughtermass[1]*daughtermass[1]) - daughtermass[1];
276 Ekin, daughtermass[1]);
282 G4cout <<
"G4PhaseSpaceDecayChannel::TwoBodyDecayIt() -";
283 G4cout <<
" Create decay products in rest frame " <<
G4endl;
297 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()" <<
G4endl;
302 G4double daughtermass[3], daughterwidth[3];
304 G4double sumofdaughterwidthsq = 0.0;
306 for (
G4int index=0; index<3; ++index)
309 sumofdaughtermass += daughtermass[index];
311 sumofdaughterwidthsq += daughterwidth[index]*daughterwidth[index];
312 withWidth = withWidth ||(daughterwidth[index]>1.0e-3*daughtermass[index]);
322 delete parentparticle;
324 if (!useGivenDaughterMass)
328 G4double maxDev = (parentmass - sumofdaughtermass )
329 / std::sqrt(sumofdaughterwidthsq);
335 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()" <<
G4endl
336 <<
"Sum of daughter mass is larger than parent mass!"
339 <<
" " << current_parent_mass.
Get()/GeV <<
G4endl;
341 <<
" " << daughtermass[0]/GeV <<
G4endl;
343 <<
" " << daughtermass[1]/GeV <<
G4endl;
345 <<
" " << daughtermass[2]/GeV <<
G4endl;
348 G4Exception(
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()",
350 "Cannot create decay products: sum of daughter mass \
351 is larger than parent mass!");
355 if (daughterwidth[0] > 0.)
356 dm1=
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
358 if (daughterwidth[1] > 0.)
359 dm2=
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
361 if (daughterwidth[2] > 0.)
362 dm3=
DynamicalMass(daughtermass[2],daughterwidth[2], maxDev);
363 while (dm1+dm2+dm3>parentmass)
365 dm1=
DynamicalMass(daughtermass[0],daughterwidth[0], maxDev);
366 dm2=
DynamicalMass(daughtermass[1],daughterwidth[1], maxDev);
367 dm3=
DynamicalMass(daughtermass[2],daughterwidth[2], maxDev);
369 daughtermass[0] = dm1;
370 daughtermass[1] = dm2;
371 daughtermass[2] = dm3;
372 sumofdaughtermass = dm1+dm2+dm3;
378 daughtermass[0] = givenDaughterMasses[0];
379 daughtermass[1] = givenDaughterMasses[1];
380 daughtermass[2] = givenDaughterMasses[2];
381 sumofdaughtermass = daughtermass[0] + daughtermass[1] + daughtermass[2];
384 if (sumofdaughtermass >parentmass)
389 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()" <<
G4endl
390 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
392 <<
" " << current_parent_mass.
Get()/GeV <<
G4endl;
394 <<
" " << daughtermass[0]/GeV <<
G4endl;
396 <<
" " << daughtermass[1]/GeV <<
G4endl;
398 <<
" " << daughtermass[2]/GeV <<
G4endl;
400 if (useGivenDaughterMass)
405 G4Exception(
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt",
407 "Can not create decay products: sum of daughter mass \
408 is larger than parent mass!");
416 G4double momentummax=0.0, momentumsum = 0.0;
418 const std::size_t MAX_LOOP=10000;
420 for (std::size_t loop_counter=0; loop_counter<MAX_LOOP; ++loop_counter)
433 energy = rd2*(parentmass - sumofdaughtermass);
434 daughtermomentum[0] = std::sqrt(energy*energy
435 + 2.0*energy* daughtermass[0]);
436 if ( daughtermomentum[0] > momentummax )
437 momentummax = daughtermomentum[0];
438 momentumsum += daughtermomentum[0];
440 energy = (1.-rd1)*(parentmass - sumofdaughtermass);
441 daughtermomentum[1] = std::sqrt(energy*energy
442 + 2.0*energy*daughtermass[1]);
443 if ( daughtermomentum[1] >momentummax )momentummax = daughtermomentum[1];
444 momentumsum += daughtermomentum[1];
446 energy = (rd1-rd2)*(parentmass - sumofdaughtermass);
447 daughtermomentum[2] = std::sqrt(energy*energy
448 + 2.0*energy* daughtermass[2]);
449 if ( daughtermomentum[2] > momentummax )
450 momentummax = daughtermomentum[2];
451 momentumsum += daughtermomentum[2];
452 if (momentummax <= momentumsum - momentummax )
break;
459 G4cout <<
" daughter 0:" << daughtermomentum[0]/GeV <<
"[GeV/c]"
461 G4cout <<
" daughter 1:" << daughtermomentum[1]/GeV <<
"[GeV/c]"
463 G4cout <<
" daughter 2:" << daughtermomentum[2]/GeV <<
"[GeV/c]"
465 G4cout <<
" momentum sum:" << momentumsum/GeV <<
"[GeV/c]"
471 G4double costheta, sintheta, phi, sinphi, cosphi;
472 G4double costhetan, sinthetan, phin, sinphin, cosphin;
474 sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
476 sinphi = std::sin(phi);
477 cosphi = std::cos(phi);
479 G4ThreeVector direction0(sintheta*cosphi,sintheta*sinphi,costheta);
480 G4double Ekin = std::sqrt(daughtermomentum[0]*daughtermomentum[0]
481 + daughtermass[0]*daughtermass[0]) - daughtermass[0];
486 costhetan = (daughtermomentum[1]*daughtermomentum[1]
487 - daughtermomentum[2]*daughtermomentum[2]
488 - daughtermomentum[0]*daughtermomentum[0])
489 / (2.0*daughtermomentum[2]*daughtermomentum[0]);
490 sinthetan = std::sqrt((1.0-costhetan)*(1.0+costhetan));
492 sinphin = std::sin(phin);
493 cosphin = std::cos(phin);
495 direction2.
setX( sinthetan*cosphin*costheta*cosphi
496 - sinthetan*sinphin*sinphi + costhetan*sintheta*cosphi);
497 direction2.
setY( sinthetan*cosphin*costheta*sinphi
498 + sinthetan*sinphin*cosphi + costhetan*sintheta*sinphi);
499 direction2.
setZ( -sinthetan*cosphin*sintheta + costhetan*costheta);
501 Ekin = std::sqrt(pmom.
mag2() + daughtermass[2]*daughtermass[2])
505 Ekin, daughtermass[2] );
508 pmom = (direction0*daughtermomentum[0]
509 + direction2*(daughtermomentum[2]/direction2.
mag()))*(-1.0);
510 Ekin = std::sqrt(pmom.
mag2() + daughtermass[1]*daughtermass[1])
514 Ekin, daughtermass[1] );
520 G4cout <<
"G4PhaseSpaceDecayChannel::ThreeBodyDecayIt -";
521 G4cout <<
" create decay products in rest frame " <<
G4endl;
541 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl;
554 delete parentparticle;
562 if (!useGivenDaughterMass)
568 daughtermass[index] = givenDaughterMasses[index];
570 sumofdaughtermass += daughtermass[index];
572 if (sumofdaughtermass >parentmass)
577 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl
578 <<
"Sum of daughter mass is larger than parent mass!" <<
G4endl;
580 <<
" " << current_parent_mass.
Get()/GeV <<
G4endl;
582 <<
" " << daughtermass[0]/GeV <<
G4endl;
584 <<
" " << daughtermass[1]/GeV <<
G4endl;
586 <<
" " << daughtermass[2]/GeV <<
G4endl;
588 <<
" " << daughtermass[3]/GeV <<
G4endl;
591 G4Exception(
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()",
593 "Can not create decay products: sum of daughter mass \
594 is larger than parent mass!");
595 delete [] daughtermass;
606 G4int numberOfTry = 0;
607 const std::size_t MAX_LOOP=10000;
609 for (std::size_t loop_counter=0; loop_counter<MAX_LOOP; ++loop_counter)
624 if (rd[index] < rd[index2])
627 rd[index] = rd[index2];
634 tmas = parentmass - sumofdaughtermass;
635 temp = sumofdaughtermass;
638 sm[index] = rd[index]*tmas + temp;
639 temp -= daughtermass[index];
642 G4cout << index <<
" rundom number:" << rd[index];
643 G4cout <<
" virtual mass:" <<
sm[index]/GeV <<
"[GeV/c/c]" <<
G4endl;
653 smOK = (
sm[index]-daughtermass[index]-
sm[index+1] >=0.);
658 daughtermomentum[index]=
Pmx(sm[index-1],daughtermass[index-1],sm[index]);
663 G4cout <<
" momentum:" << daughtermomentum[index]/GeV <<
"[GeV/c]"
670 daughtermomentum[index]=
Pmx( sm[index],daughtermass[index],sm[index +1]);
671 if(daughtermomentum[index] < 0.0)
677 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl;
678 G4cout <<
" Cannot calculate daughter momentum " <<
G4endl;
680 G4cout <<
" mass:" << parentmass/GeV <<
"[GeV/c/c]" <<
G4endl;
682 G4cout <<
" mass:" << daughtermass[index]/GeV <<
"[GeV/c/c]";
683 G4cout <<
" mass:" << daughtermomentum[index]/GeV <<
"[GeV/c]"
685 if (useGivenDaughterMass)
692 delete [] daughtermass;
693 delete [] daughtermomentum;
695 G4Exception(
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()",
697 "Can not create decay products: sum of daughter mass \
698 is larger than parent mass");
705 weight *= daughtermomentum[index]/
sm[index];
710 G4cout <<
" momentum:" << daughtermomentum[index]/GeV <<
"[GeV/c]"
725 if (++numberOfTry > 100)
730 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()" <<
G4endl;
731 G4cout <<
"Cannot determine Decay Kinematics " <<
G4endl;
741 G4Exception(
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt()",
743 "Cannot decay: Decay Kinematics cannot be calculated");
746 delete [] daughtermass;
747 delete [] daughtermomentum;
757 G4cout <<
"Start calculation of daughters momentum vector " <<
G4endl;
767 sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
769 direction.
setZ(costheta);
770 direction.
setY(sintheta*std::sin(phi));
771 direction.
setX(sintheta*std::cos(phi));
773 direction*daughtermomentum[index] );
775 direction*(-1.0*daughtermomentum[index]) );
781 sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
783 direction.
setZ(costheta);
784 direction.
setY(sintheta*std::sin(phi));
785 direction.
setX(sintheta*std::cos(phi));
788 beta = daughtermomentum[index];
789 beta /= std::sqrt( daughtermomentum[index]*daughtermomentum[index]
790 + sm[index+1]*sm[index+1] );
798 p4.
boost( direction.
x()*beta, direction.
y()*beta, direction.
z()*beta);
805 direction*(-1.0*daughtermomentum[index]));
817 G4cout <<
"G4PhaseSpaceDecayChannel::ManyBodyDecayIt() -";
818 G4cout <<
" create decay products in rest frame " <<
G4endl;
823 delete [] daughterparticle;
824 delete [] daughtermomentum;
825 delete [] daughtermass;
836 givenDaughterMasses[idx] = masses[idx];
838 useGivenDaughterMass =
true;
839 return useGivenDaughterMass;
845 useGivenDaughterMass =
false;
846 return useGivenDaughterMass;
852 if (!useGivenDaughterMass)
861 sumOfDaughterMassMin += givenDaughterMasses[index];
863 return (parentMass >= sumOfDaughterMassMin);
870 G4double ppp = (e+p1+p2)*(e+p1-p2)*(e-p1+p2)*(e-p1-p2)/(4.0*e*e);
871 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)