Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F7879429
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
14 KB
Subscribers
None
View Options
diff --git a/Decay/General/SSSDecayer.cc b/Decay/General/SSSDecayer.cc
--- a/Decay/General/SSSDecayer.cc
+++ b/Decay/General/SSSDecayer.cc
@@ -1,350 +1,350 @@
// -*- C++ -*-
//
// SSSDecayer.cc is a part of Herwig - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2017 The Herwig Collaboration
//
// Herwig is licenced under version 3 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
//
// This is the implementation of the non-inlined, non-templated member
// functions of the SSSDecayer class.
//
#include "SSSDecayer.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
#include "Herwig/Utilities/Kinematics.h"
#include "Herwig/Decay/GeneralDecayMatrixElement.h"
using namespace Herwig;
using namespace ThePEG::Helicity;
IBPtr SSSDecayer::clone() const {
return new_ptr(*this);
}
IBPtr SSSDecayer::fullclone() const {
return new_ptr(*this);
}
void SSSDecayer::doinit() {
_perturbativeVertex = dynamic_ptr_cast<SSSVertexPtr> (getVertex());
_abstractVertex = dynamic_ptr_cast<AbstractSSSVertexPtr>(getVertex());
_abstractIncomingVertex = dynamic_ptr_cast<AbstractVSSVertexPtr>(getIncomingVertex());
_abstractOutgoingVertex1 = dynamic_ptr_cast<AbstractVSSVertexPtr>(getOutgoingVertices()[0]);
_abstractOutgoingVertex2 = dynamic_ptr_cast<AbstractVSSVertexPtr>(getOutgoingVertices()[1]);
GeneralTwoBodyDecayer::doinit();
}
void SSSDecayer::persistentOutput(PersistentOStream & os) const {
os << _abstractVertex << _perturbativeVertex
<< _abstractIncomingVertex << _abstractOutgoingVertex1
<< _abstractOutgoingVertex2;
}
void SSSDecayer::persistentInput(PersistentIStream & is, int) {
is >> _abstractVertex >> _perturbativeVertex
>> _abstractIncomingVertex >> _abstractOutgoingVertex1
>> _abstractOutgoingVertex2;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<SSSDecayer,GeneralTwoBodyDecayer>
describeHerwigSSSDecayer("Herwig::SSSDecayer", "Herwig.so");
void SSSDecayer::Init() {
static ClassDocumentation<SSSDecayer> documentation
("This class implements the decay of a scalar to 2 scalars.");
}
double SSSDecayer::me2(const int , const Particle & inpart,
const ParticleVector & decay,
MEOption meopt) const {
if(!ME())
ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin0,PDT::Spin0)));
if(meopt==Initialize) {
ScalarWaveFunction::
calculateWaveFunctions(_rho,const_ptr_cast<tPPtr>(&inpart),incoming);
_swave = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
}
if(meopt==Terminate) {
ScalarWaveFunction::
constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
for(unsigned int ix=0;ix<2;++ix)
ScalarWaveFunction::
constructSpinInfo(decay[ix],outgoing,true);
}
ScalarWaveFunction s1(decay[0]->momentum(),decay[0]->dataPtr(),outgoing);
ScalarWaveFunction s2(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
Energy2 scale(sqr(inpart.mass()));
(*ME())(0,0,0) = _abstractVertex->evaluate(scale,s1,s2,_swave);
double output = (ME()->contract(_rho)).real()/scale*UnitRemoval::E2;
// colour and identical particle factors
output *= colourFactor(inpart.dataPtr(),decay[0]->dataPtr(),
decay[1]->dataPtr());
// return the answer
return output;
}
Energy SSSDecayer::partialWidth(PMPair inpart, PMPair outa,
PMPair outb) const {
if( inpart.second < outa.second + outb.second ) return ZERO;
- if(_perturbativeVertex) {
+ if(_perturbativeVertex && !_perturbativeVertex->kinematics()) {
Energy2 scale(sqr(inpart.second));
tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
_perturbativeVertex->setCoupling(scale, in, outa.first, outb.first);
Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
outb.second);
double c2 = norm(_perturbativeVertex->norm());
Energy pWidth = c2*pcm/8./Constants::pi/scale*UnitRemoval::E2;
// colour factor
pWidth *= colourFactor(inpart.first,outa.first,outb.first);
return pWidth;
}
else {
return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
}
}
double SSSDecayer::threeBodyME(const int , const Particle & inpart,
const ParticleVector & decay, MEOption meopt) {
// work out which is the scalar and anti scalar
int ianti(0), iscal(1), iglu(2);
int itype[2];
for(unsigned int ix=0;ix<2;++ix) {
if(decay[ix]->dataPtr()->CC()) itype[ix] = decay[ix]->id()>0 ? 0:1;
else itype[ix] = 2;
}
if(itype[0]==0 && itype[1]!=0) swap(ianti, iscal);
if(itype[0]==2 && itype[1]==1) swap(ianti, iscal);
if(itype[0]==0 && itype[1]==0 && abs(decay[0]->dataPtr()->id())>abs(decay[1]->dataPtr()->id()))
swap(iscal, ianti);
if(itype[0]==1 && itype[1]==1 && abs(decay[0]->dataPtr()->id())<abs(decay[1]->dataPtr()->id()))
swap(iscal, ianti);
if(meopt==Initialize) {
// create scalar wavefunction for decaying particle
ScalarWaveFunction::calculateWaveFunctions(_rho3,const_ptr_cast<tPPtr>(&inpart),incoming);
_swave3 = ScalarWaveFunction(inpart.momentum(),inpart.dataPtr(),incoming);
}
// setup spin information when needed
if(meopt==Terminate) {
ScalarWaveFunction::
constructSpinInfo(const_ptr_cast<tPPtr>(&inpart),incoming,true);
ScalarWaveFunction::
constructSpinInfo(decay[iscal],outgoing,true);
ScalarWaveFunction::
constructSpinInfo(decay[ianti],outgoing,true);
VectorWaveFunction::
constructSpinInfo(_gluon,decay[iglu ],outgoing,true,false);
return 0.;
}
// calculate colour factors and number of colour flows
unsigned int nflow;
vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
if(nflow==2) cfactors[0][1]=cfactors[1][0];
vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin0, PDT::Spin0,
PDT::Spin0, PDT::Spin1)));
// create wavefunctions
ScalarWaveFunction scal(decay[iscal]->momentum(), decay[iscal]->dataPtr(),outgoing);
ScalarWaveFunction anti(decay[ianti]->momentum(), decay[ianti]->dataPtr(),outgoing);
VectorWaveFunction::calculateWaveFunctions(_gluon,decay[iglu ],outgoing,true);
// // gauge invariance test
// _gluon.clear();
// for(unsigned int ix=0;ix<3;++ix) {
// if(ix==1) _gluon.push_back(VectorWaveFunction());
// else {
// _gluon.push_back(VectorWaveFunction(decay[iglu ]->momentum(),
// decay[iglu ]->dataPtr(),10,
// outgoing));
// }
// }
AbstractVSSVertexPtr abstractOutgoingVertexS;
AbstractVSSVertexPtr abstractOutgoingVertexA;
identifyVertices(iscal, ianti, inpart, decay, abstractOutgoingVertexS, abstractOutgoingVertexA);
Energy2 scale(sqr(inpart.mass()));
const GeneralTwoBodyDecayer::CFlow & colourFlow
= colourFlows(inpart, decay);
for(unsigned int ig = 0; ig < 2; ++ig) {
// radiation from the incoming scalar
if(inpart.dataPtr()->coloured()) {
assert(_abstractIncomingVertex);
ScalarWaveFunction scalarInter =
_abstractIncomingVertex->evaluate(scale,3,inpart.dataPtr(),
_gluon[2*ig],_swave3,inpart.mass());
if (_swave3.particle()->PDGName()!=scalarInter.particle()->PDGName())
throw Exception()
<< _swave3 .particle()->PDGName() << " was changed to "
<< scalarInter.particle()->PDGName() << " in SSSDecayer::threeBodyME"
<< Exception::runerror;
double gs = _abstractIncomingVertex->strongCoupling(scale);
Complex diag = _abstractVertex->evaluate(scale,scal,anti,scalarInter)/gs;
for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
(*ME[colourFlow[0][ix].first])(0, 0, 0, ig) +=
colourFlow[0][ix].second*diag;
}
}
// radiation from the outgoing scalar
if(decay[iscal]->dataPtr()->coloured()) {
assert(abstractOutgoingVertexS);
// ensure you get correct outgoing particle from first vertex
tcPDPtr off = decay[iscal]->dataPtr();
if(off->CC()) off = off->CC();
ScalarWaveFunction scalarInter =
abstractOutgoingVertexS->evaluate(scale,3,off,_gluon[2*ig],scal,decay[iscal]->mass());
if (scal.particle()->PDGName()!=scalarInter.particle()->PDGName())
throw Exception()
<< scal .particle()->PDGName() << " was changed to "
<< scalarInter.particle()->PDGName() << " in SSSDecayer::threeBodyME"
<< Exception::runerror;
double gs = abstractOutgoingVertexS->strongCoupling(scale);
Complex diag = _abstractVertex->evaluate(scale,_swave3,anti,scalarInter)/gs;
for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
(*ME[colourFlow[1][ix].first])(0, 0, 0, ig) +=
colourFlow[1][ix].second*diag;
}
}
// radiation from the outgoing anti scalar
if(decay[ianti]->dataPtr()->coloured()) {
assert(abstractOutgoingVertexA);
// ensure you get correct outgoing particle from first vertex
tcPDPtr off = decay[ianti]->dataPtr();
if(off->CC()) off = off->CC();
ScalarWaveFunction scalarInter =
abstractOutgoingVertexA->evaluate(scale,3,off, _gluon[2*ig],anti,decay[ianti]->mass());
if (anti.particle()->PDGName()!=scalarInter.particle()->PDGName())
throw Exception()
<< anti .particle()->PDGName() << " was changed to "
<< scalarInter.particle()->PDGName() << " in SSSDecayer::threeBodyME"
<< Exception::runerror;
double gs = abstractOutgoingVertexA->strongCoupling(scale);
Complex diag = _abstractVertex->evaluate(scale,_swave3,scal,scalarInter)/gs;
for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
(*ME[colourFlow[2][ix].first])(0, 0, 0, ig) +=
colourFlow[2][ix].second*diag;
}
}
}
// contract matrices
double output=0.;
for(unsigned int ix=0; ix<nflow; ++ix){
for(unsigned int iy=0; iy<nflow; ++iy){
output+=cfactors[ix][iy]*(ME[ix]->contract(*ME[iy],_rho3)).real();
}
}
output*=(4.*Constants::pi);
// return the answer
return output;
}
void SSSDecayer::identifyVertices(const int iscal, const int ianti,
const Particle & inpart, const ParticleVector & decay,
AbstractVSSVertexPtr & abstractOutgoingVertexS,
AbstractVSSVertexPtr & abstractOutgoingVertexA){
// work out which scalar each outgoing vertex corresponds to
// two outgoing vertices
if( inpart.dataPtr() ->iColour()==PDT::Colour0 &&
((decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&
decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar) ||
(decay[iscal]->dataPtr()->iColour()==PDT::Colour8 &&
decay[ianti]->dataPtr()->iColour()==PDT::Colour8))){
if(_abstractOutgoingVertex1==_abstractOutgoingVertex2){
abstractOutgoingVertexS = _abstractOutgoingVertex1;
abstractOutgoingVertexA = _abstractOutgoingVertex2;
}
else if (_abstractOutgoingVertex1->isIncoming(getParticleData(decay[iscal]->id()))){
abstractOutgoingVertexS = _abstractOutgoingVertex1;
abstractOutgoingVertexA = _abstractOutgoingVertex2;
}
else if (_abstractOutgoingVertex2->isIncoming(getParticleData(decay[iscal]->id()))){
abstractOutgoingVertexS = _abstractOutgoingVertex2;
abstractOutgoingVertexA = _abstractOutgoingVertex1;
}
}
else if(inpart.dataPtr() ->iColour()==PDT::Colour8 &&
decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&
decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar){
if(_abstractOutgoingVertex1==_abstractOutgoingVertex2){
abstractOutgoingVertexS = _abstractOutgoingVertex1;
abstractOutgoingVertexA = _abstractOutgoingVertex2;
}
else if (_abstractOutgoingVertex1->isIncoming(getParticleData(decay[iscal]->id()))){
abstractOutgoingVertexS = _abstractOutgoingVertex1;
abstractOutgoingVertexA = _abstractOutgoingVertex2;
}
else if (_abstractOutgoingVertex2->isIncoming(getParticleData(decay[iscal]->id()))){
abstractOutgoingVertexS = _abstractOutgoingVertex2;
abstractOutgoingVertexA = _abstractOutgoingVertex1;
}
}
// one outgoing vertex
else if(inpart.dataPtr() ->iColour()==PDT::Colour3){
if(decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&
decay[ianti]->dataPtr()->iColour()==PDT::Colour0){
if (_abstractOutgoingVertex1) abstractOutgoingVertexS = _abstractOutgoingVertex1;
else if(_abstractOutgoingVertex2) abstractOutgoingVertexS = _abstractOutgoingVertex2;
}
else if (decay[iscal]->dataPtr()->iColour()==PDT::Colour3 &&
decay[ianti]->dataPtr()->iColour()==PDT::Colour8){
if (_abstractOutgoingVertex1->isIncoming(getParticleData(decay[ianti]->dataPtr()->id()))){
abstractOutgoingVertexS = _abstractOutgoingVertex2;
abstractOutgoingVertexA = _abstractOutgoingVertex1;
}
else {
abstractOutgoingVertexS = _abstractOutgoingVertex1;
abstractOutgoingVertexA = _abstractOutgoingVertex2;
}
}
}
else if(inpart.dataPtr() ->iColour()==PDT::Colour3bar){
if(decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&
decay[iscal]->dataPtr()->iColour()==PDT::Colour0){
if (_abstractOutgoingVertex1) abstractOutgoingVertexA = _abstractOutgoingVertex1;
else if(_abstractOutgoingVertex2) abstractOutgoingVertexA = _abstractOutgoingVertex2;
}
else if (decay[ianti]->dataPtr()->iColour()==PDT::Colour3bar &&
decay[iscal]->dataPtr()->iColour()==PDT::Colour8){
if (_abstractOutgoingVertex1->isIncoming(getParticleData(decay[iscal]->dataPtr()->id()))){
abstractOutgoingVertexS = _abstractOutgoingVertex1;
abstractOutgoingVertexA = _abstractOutgoingVertex2;
}
else {
abstractOutgoingVertexS = _abstractOutgoingVertex2;
abstractOutgoingVertexA = _abstractOutgoingVertex1;
}
}
}
if (! ((_abstractIncomingVertex && (abstractOutgoingVertexS || abstractOutgoingVertexA)) ||
( abstractOutgoingVertexS && abstractOutgoingVertexA)))
throw Exception()
<< "Invalid vertices for QCD radiation in SSS decay in SSSDecayer::identifyVertices"
<< Exception::runerror;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Nov 19, 8:21 PM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3806013
Default Alt Text
(14 KB)
Attached To
R563 testingHerwigHG
Event Timeline
Log In to Comment