// SusyWidthFunctions.cc is a part of the PYTHIA event generator. // Copyright (C) 2017 Torbjorn Sjostrand // Authors: N. Desai, P. Skands // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details. // Please respect the MCnet Guidelines, see GUIDELINES for details. // Function definitions (not found in the header) for the // SUSY Resonance three-body decay width classes. #include "Pythia8/SusyResonanceWidths.h" #include "Pythia8/SusyWidthFunctions.h" #include "Pythia8/SusyCouplings.h" #include "Pythia8/PythiaComplex.h" namespace Pythia8 { //========================================================================== // The WidthFunctions class. // Functions to be integrated for calculating the 3-body decay widths. //-------------------------------------------------------------------------- void WidthFunction::setPointers( ParticleData* particleDataPtrIn, CoupSUSY* coupSUSYPtrIn, Info* infoPtrIn) { particleDataPtr = particleDataPtrIn; coupSUSYPtr = coupSUSYPtrIn; infoPtr = infoPtrIn; } //-------------------------------------------------------------------------- double WidthFunction::function(double) { infoPtr->errorMsg("Error in WidthFunction::function: " "using dummy width function"); return 0.; } //-------------------------------------------------------------------------- // Adapted from the CERNLIB DGAUSS routine by K.S. Kolbig. double WidthFunction::integrateGauss(double xlo, double xhi, double tol) { // 8-point unweighted. static double x8[4]={0.96028985649753623, 0.79666647741362674, 0.52553240991632899, 0.18343464249564980}; static double w8[4]={0.10122853629037626, 0.22238103445337447, 0.31370664587788729, 0.36268378337836198}; // 16-point unweighted. static double x16[8]={0.98940093499164993, 0.94457502307323258, 0.86563120238783174, 0.75540440835500303, 0.61787624440264375, 0.45801677765722739, 0.28160355077925891, 0.09501250983763744}; static double w16[8]={0.027152459411754095, 0.062253523938647893, 0.095158511682492785, 0.12462897125553387, 0.14959598881657673, 0.16915651939500254, 0.18260341504492359, 0.18945061045506850}; // Boundary checks. if (xlo >= xhi) { infoPtr->errorMsg("Error in WidthFunction::integrateGauss: " "xlo >= xhi"); return 0.0; } // Initialize. double sum = 0.0; double c = 0.001/abs(xhi-xlo); double zlo = xlo; double zhi = xhi; bool nextbin = true; while ( nextbin ) { double zmi = 0.5*(zhi+zlo); // midpoint double zmr = 0.5*(zhi-zlo); // midpoint, relative to zlo // Calculate 8-point and 16-point quadratures. double s8=0.0; for (int i=0;i<4;i++) { double dz = zmr * x8[i]; s8 += w8[i]*(function(zmi+dz) + function(zmi-dz)); } s8 *= zmr; double s16=0.0; for (int i=0;i<8;i++) { double dz = zmr * x16[i]; s16 += w16[i]*(function(zmi+dz) + function(zmi-dz)); } s16 *= zmr; if (abs(s16-s8) < tol*(1+abs(s16))) { // Precision in this bin OK, add to cumulative and go to next. nextbin=true; sum += s16; // Next bin: LO = end of current, HI = end of integration region. zlo=zhi; zhi=xhi; if ( zlo == zhi ) nextbin = false; } else { // Precision in this bin not OK, subdivide. if (1.0 + c*abs(zmr) == 1.0) { infoPtr->errorMsg("Error in WidthFunction::integrateGauss: " "too high accuracy required"); sum = 0.0 ; break; } zhi=zmi; nextbin=true; } } return sum; } //========================================================================== // The StauWidths class. // Width functions for 3-body stau decays. //-------------------------------------------------------------------------- double StauWidths::getWidth(int idResIn, int idIn){ setChannel(idResIn, idIn); // Calculate integration limits and return integrated width. if (idResIn % 2 == 0) return 0.0; double width = integrateGauss(0.0,1.0,1.0e-3); return width; } //-------------------------------------------------------------------------- void StauWidths::setChannel(int idResIn, int idIn) { // Common masses. idRes = abs(idResIn); idIn = abs(idIn); mRes = particleDataPtr->m0(idRes); m1 = particleDataPtr->m0(1000022); m2 = particleDataPtr->m0(idIn); mInt = particleDataPtr->m0(15); gammaInt = particleDataPtr->mWidth(15); // Couplings etc. f0 = 92.4; //MeV gf = coupSUSYPtr->GF(); delm = mRes - m1; cons = pow2(f0)*pow2(gf)*(pow2(delm) - pow2(m2)) * coupSUSYPtr->V2CKMid(1,1) / (128.0 * pow(mRes*M_PI,3)); if (idIn == 900111) wparam = 1.16; else if (idIn == 113) wparam = 0.808; else wparam = 1.0; double g = coupSUSYPtr->alphaEM(mRes * mRes); int ksusy = 1000000; int isl = (abs(idRes)/ksusy == 2) ? (abs(idRes)%10+1)/2 + 3 : (abs(idRes)%10+1)/2; gL = g * coupSUSYPtr->LsllX[isl][3][1] / ( sqrt(2.0) * coupSUSYPtr->cosb); gR = g * coupSUSYPtr->RsllX[isl][3][1] / ( sqrt(2.0) * coupSUSYPtr->cosb); // Set function switch and internal propagators depending on decay product. if (idIn == 111) fnSwitch = 1; else if (idIn == 900111 || idIn == 113) fnSwitch = 2; else if (idIn == 14 || idIn == 12) { m2 = particleDataPtr->m0(idIn-1); fnSwitch = 3; } else { stringstream mess; mess << " unknown decay channel idIn = " << idIn; infoPtr->errorMsg("Warning in StauWidths::setChannel:", mess.str() ); } return; } //------------------------------------------------------------------------ double StauWidths::function(double x){ // Decay width functions documented in arXiv:1212.2886 Citron et. al. double value = 0.0; double qf2 = pow2(delm) - (pow2(delm) - pow2(m2)) * x; double fac = 1.0 / pow3(mRes); double term3 = (norm(gL) * qf2 + norm(gR) * mInt * mInt) * (delm * delm + 2.0 * m1 * delm - qf2); double term4 = -2.0 * real(gL * conj(gR)) * m2 * mInt * qf2; // ~tau -> pi0 nu_tau ~chi0. if (fnSwitch == 1 ) { fac *= pow2(delm) - pow2(m2); double term1 = sqrt((pow2(delm) - qf2) * (pow2(delm + 2 * m1) - qf2)); double term2 = pow2(qf2 - pow2(m2)) / qf2 / (pow2(qf2 - pow2(mInt)) + pow2(mInt*gammaInt)); value = fac * (term1 * term2 * (term3 + term4)); } else if (fnSwitch == 2 ) { double term1 = sqrt((pow2(delm) - qf2) * (pow2(delm + 2 * m1) - qf2)); double term2 = pow2(qf2 - pow2(m2)) * (qf2 + pow2(m2)) / (qf2 * qf2 * (pow2(qf2 - pow2(mInt)) + pow2(mInt*gammaInt))); value = fac * (term1 * term2 * (term3 + term4)); } else if (fnSwitch == 3 ) { double qf4 = qf2 * qf2; double m24 = pow2(m2*m2); double term1 = sqrt((pow2(delm) - qf2) * (pow2(delm + 2 * m1) - qf2)); double term2a = 1.0 / (pow2(qf2 - pow2(mInt)) + pow2(mInt*gammaInt)) / qf4; double term2b = 12 * m24 * qf4 * log(qf2/pow2(m2)) + (qf4 - m24) * (qf4 - 8 * m2 * m2 * qf2 + m24); value = fac * (term1 * term2a * term2b * (term3 + term4)); } else { stringstream mess; mess << " unknown decay channel fnSwitch = " << fnSwitch; infoPtr->errorMsg("Warning in StauWidths::function:", mess.str() ); } return value; } //========================================================================== } //end namespace Pythia8