00001
00002
00003
00004
00005
00006
00007 #ifdef HAVE_CONFIG_H
00008 #include "config.h"
00009 #endif
00010
00011 #include "gismo/PhaseSpace.h"
00012
00013 #include "gismo/GParticle.h"
00014 #include <cmath>
00015 #include "Random.h"
00016 #include "facilities/error.h"
00017 #include <algorithm>
00018 #include <cmath>
00019 static inline double sqr(double x) { return x*x;}
00020
00021 int PhaseSpace::decay(GParticle* parent)const
00022 {
00023 weight = 1;
00024
00025 int n =parent->numChildren();
00026 if( n==2 ) return decay2( parent);
00027 else if(n==3) return decay3( parent );
00028 else
00029 FATAL("PhaseSpace: not set up to decay other than 2 or 3 secondaries");
00030 return 0;
00031 }
00032 int PhaseSpace::decay2(GParticle* parent)const
00033 {
00034
00035 GParticle& b = *parent->child(0);
00036 GParticle& c = *parent->child(1);
00037 float m1 = b.mass();
00038 float m2 = c.mass();
00039
00040 float M = parent->mass();
00041
00042 float pstar = (sqr(M)-sqr(m1+m2))*(sqr(M)-sqr(m1-m2));
00043 if (pstar<0.)
00044 { WARNING( "*** decay kinematically forbidden");
00045 return 0;
00046 }
00047 pstar = sqrt(pstar)/(2.0*M);
00048 float costh = Random::flat(-1.0, 1.0);
00049 float phi = Random::flat(2*M_PI);
00050 Vector pcm(0,0,pstar);
00051 pcm.Hep3Vector::rotateY(acos(costh));
00052 pcm.Hep3Vector::rotateZ(phi);
00053
00054 b.setMomentum(pcm);
00055 c.setMomentum(-pcm);
00056
00057 return 1;
00058 }
00059 int PhaseSpace::decay3(GParticle* parent)const
00060 {
00061 GParticle& a = *parent->child(0);
00062 GParticle& b = *parent->child(1);
00063 GParticle& c = *parent->child(2);
00064 double m1 = a.mass();
00065 double m2 = b.mass();
00066 double m3 = c.mass();
00067
00068 double M = parent->mass();
00069
00070
00071
00072 double t0 = M - m1 - m2 - m3;
00073 if( t0 <= 0 ) return 0;
00074 double te, tm, tn;
00075 double pa1, pa2, pa3, pmax;
00076 do
00077 {
00078 double g1 = Random::flat();
00079 double g2 = Random::flat();
00080 double gmi = std::min(g1,g2);
00081 double gma = std::max(g1,g2);
00082 te = gmi * t0;
00083 tm = (1. - gma) * t0;
00084 tn = (gma - gmi) * t0;
00085 pa1 = sqrt(sqr(te) + m1 * 2. * te);
00086 pa2 = sqrt(sqr(tm) + m2 * 2. * tm);
00087 pa3 = sqrt(sqr(tn) + m3 * 2. * tn);
00088
00089
00090
00091 pmax = std::max(pa3,std::max(pa1,pa2));
00092 }
00093 while( pmax >= pa1 + pa2 + pa3 - pmax );
00094
00095
00096
00097
00098 double cte = Random::flat(-1,1);
00099 double ste = sqrt( abs(1. - sqr(cte)) );
00100 double fe = Random::flat(0, 2*M_PI);
00101 double cfe = cos(fe);
00102 double sfe = sin(fe);
00103 Hep3Vector pa(pa1 * ste * cfe,pa1 * ste * sfe,pa1 * cte);
00104 a.setMomentum(pa);
00105 double cten = (sqr(pa2) - sqr(pa1) - sqr(pa3)) / (pa1 * 2. * pa3);
00106 double sten = sqrt(abs(1. - sqr(cten)) );
00107 double fen = Random::flat(0,2*M_PI);
00108 double cfen = cos(fen);
00109 double sfen = sin(fen);
00110 Hep3Vector pc(
00111 pa3 * ( sten * cfen * cte * cfe - sten * sfen * sfe + cten * ste * cfe)
00112 ,pa3 * ( sten * cfen * cte * sfe + sten * sfen * cfe + cten * ste * sfe)
00113 ,pa3 * (-sten * cfen * ste + cten * cte)
00114 );
00115 c.setMomentum( pc);
00116 b.setMomentum( -pa-pc );
00117 return 1;
00118 }
00119