Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F10664457
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
36 KB
Subscribers
None
View Options
diff --git a/Decay/General/SSVDecayer.cc b/Decay/General/SSVDecayer.cc
--- a/Decay/General/SSVDecayer.cc
+++ b/Decay/General/SSVDecayer.cc
@@ -1,351 +1,351 @@
// -*- C++ -*-
//
// SSVDecayer.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 SSVDecayer class.
//
#include "SSVDecayer.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "ThePEG/PDT/DecayMode.h"
#include "Herwig/Utilities/Kinematics.h"
#include "ThePEG/Helicity/WaveFunction/ScalarWaveFunction.h"
#include "ThePEG/Helicity/WaveFunction/VectorWaveFunction.h"
#include "Herwig/Decay/GeneralDecayMatrixElement.h"
using namespace Herwig;
using namespace ThePEG::Helicity;
IBPtr SSVDecayer::clone() const {
return new_ptr(*this);
}
IBPtr SSVDecayer::fullclone() const {
return new_ptr(*this);
}
void SSVDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
VertexBasePtr vertex,
map<ShowerInteraction,VertexBasePtr> & inV,
const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
map<ShowerInteraction,VertexBasePtr> fourV) {
decayInfo(incoming,outgoing);
vertex_ = dynamic_ptr_cast<AbstractVSSVertexPtr>(vertex);
perturbativeVertex_ = dynamic_ptr_cast<VSSVertexPtr> (vertex);
vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
for(auto & inter : itemp) {
incomingVertex_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(inV.at(inter));
fourPointVertex_[inter] = dynamic_ptr_cast<AbstractVVSSVertexPtr>(fourV.at(inter));
outgoingVertexS_[inter] = AbstractVSSVertexPtr();
outgoingVertexV_[inter] = AbstractVVVVertexPtr();
if(outV[0].at(inter)) {
if (outV[0].at(inter)->getName()==VertexType::VSS)
outgoingVertexS_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
else
outgoingVertexV_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
}
if(outV[1].at(inter)) {
if (outV[1].at(inter)->getName()==VertexType::VSS)
outgoingVertexS_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
else
outgoingVertexV_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
}
}
}
void SSVDecayer::persistentOutput(PersistentOStream & os) const {
os << vertex_ << perturbativeVertex_
<< incomingVertex_ << outgoingVertexS_
<< outgoingVertexV_ << fourPointVertex_;
}
void SSVDecayer::persistentInput(PersistentIStream & is, int) {
is >> vertex_ >> perturbativeVertex_
>> incomingVertex_ >> outgoingVertexS_
>> outgoingVertexV_ >> fourPointVertex_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<SSVDecayer,GeneralTwoBodyDecayer>
describeHerwigSSVDecayer("Herwig::SSVDecayer", "Herwig.so");
void SSVDecayer::Init() {
static ClassDocumentation<SSVDecayer> documentation
("This implements the decay of a scalar to a vector and a scalar");
}
double SSVDecayer::me2(const int , const Particle & inpart,
const ParticleVector & decay,
MEOption meopt) const {
unsigned int isc(0),ivec(1);
if(decay[0]->dataPtr()->iSpin() != PDT::Spin0) swap(isc,ivec);
if(!ME()) {
if(ivec==1)
ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin0,PDT::Spin1)));
else
ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin0,PDT::Spin1,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);
ScalarWaveFunction::
constructSpinInfo(decay[isc],outgoing,true);
VectorWaveFunction::
constructSpinInfo(vector_,decay[ivec],outgoing,true,false);
}
VectorWaveFunction::
calculateWaveFunctions(vector_,decay[ivec],outgoing,false);
ScalarWaveFunction sca(decay[isc]->momentum(),decay[isc]->dataPtr(),outgoing);
Energy2 scale(sqr(inpart.mass()));
//make sure decay matrix element is in the correct order
double output(0.);
if(ivec == 0) {
for(unsigned int ix = 0; ix < 3; ++ix)
(*ME())(0, ix, 0) = vertex_->evaluate(scale,vector_[ix],sca, swave_);
}
else {
for(unsigned int ix = 0; ix < 3; ++ix)
(*ME())(0, 0, ix) = vertex_->evaluate(scale,vector_[ix],sca,swave_);
}
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 SSVDecayer:: partialWidth(PMPair inpart, PMPair outa,
PMPair outb) const {
if( inpart.second < outa.second + outb.second ) return ZERO;
if(perturbativeVertex_) {
double mu1sq(sqr(outa.second/inpart.second)),
mu2sq(sqr(outb.second/inpart.second));
tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
if(outa.first->iSpin() == PDT::Spin0) {
perturbativeVertex_->setCoupling(sqr(inpart.second), outb.first, outa.first,in);
}
else {
swap(mu1sq,mu2sq);
perturbativeVertex_->setCoupling(sqr(inpart.second), outa.first, outb.first,in);
}
double me2(0.);
if(mu2sq == 0.)
me2 = -2.*mu1sq - 2.;
else
me2 = ( sqr(mu2sq - mu1sq) - 2.*(mu2sq + mu1sq) + 1. )/mu2sq;
Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second, outa.second,
outb.second);
Energy output = pcm*me2*norm(perturbativeVertex_->norm())/8./Constants::pi;
// colour factor
output *= colourFactor(inpart.first,outa.first,outb.first);
// return the answer
return output;
}
else {
return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
}
}
double SSVDecayer::threeBodyME(const int , const Particle & inpart,
const ParticleVector & decay,
ShowerInteraction inter, MEOption meopt) {
int iscal (0), ivect (1), iglu (2);
// get location of outgoing scalar/vector
if(decay[1]->dataPtr()->iSpin()==PDT::Spin0) swap(iscal,ivect);
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);
VectorWaveFunction::
constructSpinInfo(vector3_,decay[ivect],outgoing,true,false);
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);
vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin0, PDT::Spin0,
PDT::Spin1, PDT::Spin1)));
// create wavefunctions
- ScalarWaveFunction scal_(decay[iscal]->momentum(), decay[iscal]->dataPtr(),outgoing);
+ ScalarWaveFunction scal(decay[iscal]->momentum(), decay[iscal]->dataPtr(),outgoing);
VectorWaveFunction::calculateWaveFunctions(vector3_,decay[ivect],outgoing,false);
VectorWaveFunction::calculateWaveFunctions(gluon_, decay[iglu ],outgoing,true );
// gauge invariance test
#ifdef GAUGE_CHECK
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));
}
}
#endif
if (! ((incomingVertex_[inter] && (outgoingVertexS_[inter] || outgoingVertexV_[inter])) ||
(outgoingVertexS_[inter] && outgoingVertexV_[inter])))
throw Exception()
<< "Invalid vertices for radiation in SSV decay in SSVDecayer::threeBodyME"
<< Exception::runerror;
// sort out colour flows
int S(1), V(2);
if (decay[iscal]->dataPtr()->iColour()==PDT::Colour3bar &&
decay[ivect]->dataPtr()->iColour()==PDT::Colour8)
swap(S,V);
else if (decay[ivect]->dataPtr()->iColour()==PDT::Colour3 &&
decay[iscal]->dataPtr()->iColour()==PDT::Colour8)
swap(S,V);
Energy2 scale(sqr(inpart.mass()));
const GeneralTwoBodyDecayer::CFlow & colourFlow
= colourFlows(inpart, decay);
double gs(0.);
bool couplingSet(false);
#ifdef GAUGE_CHECK
double total=0.;
#endif
for(unsigned int iv = 0; iv < 3; ++iv) {
for(unsigned int ig = 0; ig < 2; ++ig) {
// radiation from the incoming scalar
if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
(inpart.dataPtr()->charged() && inter==ShowerInteraction::QED) ) {
assert(incomingVertex_[inter]);
ScalarWaveFunction scalarInter =
incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),
gluon_[2*ig],swave3_,inpart.mass());
assert(swave3_.particle()->id()==scalarInter.particle()->id());
- Complex diag = vertex_->evaluate(scale,vector3_[iv],scal_,scalarInter);
+ Complex diag = vertex_->evaluate(scale,vector3_[iv],scal,scalarInter);
if(!couplingSet) {
gs = abs(incomingVertex_[inter]->norm());
couplingSet = true;
}
for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
(*ME[colourFlow[0][ix].first])(0, 0, iv, ig) +=
colourFlow[0][ix].second*diag;
}
#ifdef GAUGE_CHECK
total+=norm(diag);
#endif
}
// radiation from the outgoing scalar
if((decay[iscal]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
(decay[iscal]->dataPtr()->charged() && inter==ShowerInteraction::QED) ) {
assert(outgoingVertexS_[inter]);
// ensure you get correct outgoing particle from first vertex
tcPDPtr off = decay[iscal]->dataPtr();
if(off->CC()) off = off->CC();
ScalarWaveFunction scalarInter =
- outgoingVertexS_[inter]->evaluate(scale,3,off,gluon_[2*ig],scal_,decay[iscal]->mass());
+ outgoingVertexS_[inter]->evaluate(scale,3,off,gluon_[2*ig],scal,decay[iscal]->mass());
- assert(scal_.particle()->id()==scalarInter.particle()->id());
+ assert(scal.particle()->id()==scalarInter.particle()->id());
if(!couplingSet) {
gs = abs(outgoingVertexS_[inter]->norm());
couplingSet = true;
}
Complex diag = vertex_->evaluate(scale,vector3_[iv],scalarInter,swave3_);
for(unsigned int ix=0;ix<colourFlow[S].size();++ix) {
(*ME[colourFlow[S][ix].first])(0, 0, iv, ig) +=
colourFlow[S][ix].second*diag;
}
#ifdef GAUGE_CHECK
total+=norm(diag);
#endif
}
// radiation from outgoing vector
if((decay[ivect]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
(decay[ivect]->dataPtr()->charged() && inter==ShowerInteraction::QED) ) {
assert(outgoingVertexV_[inter]);
// ensure you get correct outgoing particle from first vertex
tcPDPtr off = decay[ivect]->dataPtr();
if(off->CC()) off = off->CC();
VectorWaveFunction vectorInter =
outgoingVertexV_[inter]->evaluate(scale,3,off,gluon_[2*ig],
vector3_[iv],decay[ivect]->mass());
assert(vector3_[iv].particle()->id()==vectorInter.particle()->id());
if(!couplingSet) {
gs = abs(outgoingVertexV_[inter]->norm());
couplingSet = true;
}
- Complex diag = vertex_->evaluate(scale,vectorInter,scal_,swave3_);
+ Complex diag = vertex_->evaluate(scale,vectorInter,scal,swave3_);
for(unsigned int ix=0;ix<colourFlow[V].size();++ix) {
(*ME[colourFlow[V][ix].first])(0, 0, iv, ig) +=
colourFlow[V][ix].second*diag;
}
#ifdef GAUGE_CHECK
total+=norm(diag);
#endif
}
// radiation from 4 point vertex
if (fourPointVertex_[inter]) {
Complex diag = fourPointVertex_[inter]->evaluate(scale, gluon_[2*ig], vector3_[iv],
- scal_, swave3_);
+ scal, swave3_);
for(unsigned int ix=0;ix<colourFlow[3].size();++ix) {
(*ME[colourFlow[3][ix].first])(0, 0, iv, ig) +=
colourFlow[3][ix].second*diag;
}
#ifdef GAUGE_CHECK
total+=norm(diag);
#endif
}
}
}
// 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();
}
}
// divide by alpha_(S,EM)
output*=(4.*Constants::pi)/sqr(gs);
#ifdef GAUGE_CHECK
double ratio = output/total;
if(abs(ratio)>1e-20) {
generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
for(unsigned int ix=0;ix<decay.size();++ix)
generator()->log() << *decay[ix] << "\n";
generator()->log() << "Test of gauge invariance " << ratio << "\n";
}
#endif
// return the answer
return output;
}
diff --git a/Decay/General/VVSDecayer.cc b/Decay/General/VVSDecayer.cc
--- a/Decay/General/VVSDecayer.cc
+++ b/Decay/General/VVSDecayer.cc
@@ -1,126 +1,302 @@
// -*- C++ -*-
//
// This is the implementation of the non-inlined, non-templated member
// functions of the VVSDecayer class.
//
#include "VVSDecayer.h"
#include "ThePEG/Utilities/DescribeClass.h"
#include "ThePEG/Interface/ClassDocumentation.h"
#include "ThePEG/Persistency/PersistentOStream.h"
#include "ThePEG/Persistency/PersistentIStream.h"
#include "Herwig/Decay/GeneralDecayMatrixElement.h"
using namespace Herwig;
using namespace ThePEG::Helicity;
-
IBPtr VVSDecayer::clone() const {
return new_ptr(*this);
}
IBPtr VVSDecayer::fullclone() const {
return new_ptr(*this);
}
void VVSDecayer::setDecayInfo(PDPtr incoming, PDPair outgoing,
VertexBasePtr vertex,
- map<ShowerInteraction,VertexBasePtr> &,
- const vector<map<ShowerInteraction,VertexBasePtr> > &,
+ map<ShowerInteraction,VertexBasePtr> & inV,
+ const vector<map<ShowerInteraction,VertexBasePtr> > & outV,
map<ShowerInteraction,VertexBasePtr>) {
decayInfo(incoming,outgoing);
vertex_ = dynamic_ptr_cast<AbstractVVSVertexPtr>(vertex);
perturbativeVertex_ = dynamic_ptr_cast<VVSVertexPtr> (vertex);
+ vector<ShowerInteraction> itemp={ShowerInteraction::QCD,ShowerInteraction::QED};
+ for(auto & inter : itemp) {
+ incomingVertex_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(inV.at(inter));
+ outgoingVertexS_[inter] = AbstractVSSVertexPtr();
+ outgoingVertexV_[inter] = AbstractVVVVertexPtr();
+ if(outV[0].at(inter)) {
+ if (outV[0].at(inter)->getName()==VertexType::VSS)
+ outgoingVertexS_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[0].at(inter));
+ else
+ outgoingVertexV_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[0].at(inter));
+ }
+ if(outV[1].at(inter)) {
+ if (outV[1].at(inter)->getName()==VertexType::VSS)
+ outgoingVertexS_[inter] = dynamic_ptr_cast<AbstractVSSVertexPtr>(outV[1].at(inter));
+ else
+ outgoingVertexV_[inter] = dynamic_ptr_cast<AbstractVVVVertexPtr>(outV[1].at(inter));
+ }
+ }
}
void VVSDecayer::persistentOutput(PersistentOStream & os) const {
- os << vertex_ << perturbativeVertex_;
+ os << vertex_ << perturbativeVertex_
+ << incomingVertex_ << outgoingVertexS_ << outgoingVertexV_;
}
void VVSDecayer::persistentInput(PersistentIStream & is, int) {
- is >> vertex_ >> perturbativeVertex_;
+ is >> vertex_ >> perturbativeVertex_
+ >> incomingVertex_ >> outgoingVertexS_ >> outgoingVertexV_;
}
// The following static variable is needed for the type
// description system in ThePEG.
DescribeClass<VVSDecayer,GeneralTwoBodyDecayer>
describeHerwigVVSDecayer("Herwig::VVSDecayer", "Herwig.so");
void VVSDecayer::Init() {
static ClassDocumentation<VVSDecayer> documentation
("The VVSDecayer class implements the decay of a vector"
" to a vector and a scalar");
}
double VVSDecayer::me2(const int , const Particle & inpart,
const ParticleVector & decay,
MEOption meopt) const {
bool massless = ( decay[0]->id()==ParticleID::gamma ||
decay[0]->id()==ParticleID::g );
if(!ME())
ME(new_ptr(GeneralDecayMatrixElement(PDT::Spin1,PDT::Spin1,PDT::Spin0)));
if(meopt==Initialize) {
VectorWaveFunction::calculateWaveFunctions(vectors_[0],rho_,
const_ptr_cast<tPPtr>(&inpart),
incoming,false);
}
if(meopt==Terminate) {
VectorWaveFunction::constructSpinInfo(vectors_[0],const_ptr_cast<tPPtr>(&inpart),
incoming,true,false);
VectorWaveFunction::
constructSpinInfo(vectors_[1],decay[0],outgoing,true,massless);
ScalarWaveFunction::
constructSpinInfo(decay[1],outgoing,true);
return 0.;
}
VectorWaveFunction::
calculateWaveFunctions(vectors_[1],decay[0],outgoing,massless);
ScalarWaveFunction sca(decay[1]->momentum(),decay[1]->dataPtr(),outgoing);
Energy2 scale(sqr(inpart.mass()));
for(unsigned int in=0;in<3;++in) {
for(unsigned int out=0;out<3;++out) {
if(massless&&out==1) ++out;
(*ME())(in,out,0) =
vertex_->evaluate(scale,vectors_[0][in],vectors_[1][out],sca);
}
}
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 VVSDecayer::partialWidth(PMPair inpart, PMPair outa,
PMPair outb) const {
if( inpart.second < outa.second + outb.second ) return ZERO;
if(perturbativeVertex_) {
Energy2 scale(sqr(inpart.second));
double mu1sq = sqr(outa.second/inpart.second);
double mu2sq = sqr(outb.second/inpart.second);
tcPDPtr in = inpart.first->CC() ? tcPDPtr(inpart.first->CC()) : inpart.first;
if( outb.first->iSpin() == PDT::Spin0 )
perturbativeVertex_->setCoupling(sqr(inpart.second), in,
outa.first, outb.first);
else {
perturbativeVertex_->setCoupling(sqr(inpart.second), in,
outb.first, outa.first);
swap(mu1sq, mu2sq);
}
double vn = norm(perturbativeVertex_->norm());
if(vn == ZERO || mu1sq == ZERO) return ZERO;
double me2 = 2. + 0.25*sqr(1. + mu1sq - mu2sq)/mu1sq;
Energy pcm = Kinematics::pstarTwoBodyDecay(inpart.second,outa.second,
outb.second);
Energy output = vn*me2*pcm/(24.*Constants::pi)/scale*UnitRemoval::E2;
// colour factor
output *= colourFactor(inpart.first,outa.first,outb.first);
// return the answer
return output;
}
else {
return GeneralTwoBodyDecayer::partialWidth(inpart,outa,outb);
}
}
+double VVSDecayer::threeBodyME(const int , const Particle & inpart,
+ const ParticleVector & decay,
+ ShowerInteraction inter, MEOption meopt) {
+ unsigned int ivec(0),isca(1);
+ if(decay[ivec]->dataPtr()->iSpin()!=PDT::Spin1) swap(ivec,isca);
+ if(meopt==Initialize) {
+ // create vector wavefunction for decaying particle
+ VectorWaveFunction::calculateWaveFunctions(vectors3_[0], rho3_,
+ const_ptr_cast<tPPtr>(&inpart),
+ incoming, false);
+ }
+ if(meopt==Terminate) {
+ VectorWaveFunction::
+ constructSpinInfo(vectors3_[0] ,const_ptr_cast<tPPtr>(&inpart),outgoing,true,false);
+ VectorWaveFunction::
+ constructSpinInfo(vectors3_[1],decay[ivec],outgoing,true,false);
+ ScalarWaveFunction::
+ constructSpinInfo(decay[isca],outgoing,true);
+ VectorWaveFunction::
+ constructSpinInfo(gluon_ ,decay[2],outgoing,true,false);
+ return 0.;
+ }
+ // calculate colour factors and number of colour flows
+ unsigned int nflow;
+ vector<DVector> cfactors = getColourFactors(inpart, decay, nflow);
+ vector<GeneralDecayMEPtr> ME(nflow,new_ptr(GeneralDecayMatrixElement(PDT::Spin1, PDT::Spin1,
+ PDT::Spin0, PDT::Spin1)));
+ bool massless= decay[ivec]->mass()!=ZERO;
+ // create wavefunctions
+ VectorWaveFunction::calculateWaveFunctions(vectors3_[1],decay[0],outgoing,massless);
+ ScalarWaveFunction scal(decay[isca]->momentum(), decay[isca]->dataPtr(),outgoing);
+ VectorWaveFunction::calculateWaveFunctions(gluon_ ,decay[2],outgoing,true);
+
+ // gauge test
+#ifdef GAUGE_CHECK
+ gluon_.clear();
+ for(unsigned int ix=0;ix<3;++ix) {
+ if(ix==1) gluon_.push_back(VectorWaveFunction());
+ else {
+ gluon_.push_back(VectorWaveFunction(decay[2]->momentum(),
+ decay[2]->dataPtr(),10,
+ outgoing));
+ }
+ }
+#endif
+
+ Energy2 scale(sqr(inpart.mass()));
+
+ const GeneralTwoBodyDecayer::CFlow & colourFlow
+ = colourFlows(inpart, decay);
+ double gs(0.);
+ bool couplingSet(false);
+#ifdef GAUGE_CHECK
+ double total=0.;
+#endif
+
+ for(unsigned int iv0 = 0; iv0 < 3; ++iv0) {
+ for(unsigned int iv1 = 0; iv1 < 3; ++iv1) {
+ if(massless && iv1==1) continue;
+ for(unsigned int ig = 0; ig < 2; ++ig) {
+ // radiation from the incoming vector
+ if((inpart.dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
+ (inpart.dataPtr()->charged() && inter==ShowerInteraction::QED) ) {
+ assert(incomingVertex_[inter]);
+ VectorWaveFunction vectorInter =
+ incomingVertex_[inter]->evaluate(scale,3,inpart.dataPtr(),vectors3_[0][iv0],
+ gluon_[2*ig],inpart.mass());
+
+ assert(vectors3_[0][iv0].particle()->id()==vectorInter.particle()->id());
+ Complex diag = vertex_->evaluate(scale,vectorInter,vectors3_[1][iv1],scal);
+ if(!couplingSet) {
+ gs = abs(incomingVertex_[inter]->norm());
+ couplingSet = true;
+ }
+ for(unsigned int ix=0;ix<colourFlow[0].size();++ix) {
+ (*ME[colourFlow[0][ix].first])(iv0, iv1, 0, ig) +=
+ colourFlow[0][ix].second*diag;
+ }
+#ifdef GAUGE_CHECK
+ total+=norm(diag);
+#endif
+ }
+ // radiation from the outgoing vector
+ if((decay[ivec]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
+ (decay[ivec]->dataPtr()->charged() && inter==ShowerInteraction::QED) ) {
+ assert(outgoingVertexV_[inter]);
+ // ensure you get correct outgoing particle from first vertex
+ tcPDPtr off = decay[ivec]->dataPtr();
+ if(off->CC()) off = off->CC();
+ VectorWaveFunction vectorInter =
+ outgoingVertexV_[inter]->evaluate(scale,3,off,gluon_[2*ig],vectors3_[1][iv1],decay[ivec]->mass());
+
+ assert(vectors3_[1][iv1].particle()->id()==vectorInter.particle()->id());
+
+ Complex diag =vertex_->evaluate(scale,vectors3_[0][iv0],vectorInter,scal);
+ if(!couplingSet) {
+ gs = abs(outgoingVertexV_[inter]->norm());
+ couplingSet = true;
+ }
+ for(unsigned int ix=0;ix<colourFlow[1].size();++ix) {
+ (*ME[colourFlow[1][ix].first])(iv0, iv1, 0, ig) +=
+ colourFlow[1][ix].second*diag;
+ }
+#ifdef GAUGE_CHECK
+ total+=norm(diag);
+#endif
+ }
+ // radiation from the outgoing scalar
+ if((decay[isca]->dataPtr()->coloured() && inter==ShowerInteraction::QCD) ||
+ (decay[isca]->dataPtr()->charged() && inter==ShowerInteraction::QED) ) {
+ assert(outgoingVertexS_[inter]);
+ // ensure you get correct outgoing particle from first vertex
+ tcPDPtr off = decay[isca]->dataPtr();
+ if(off->CC()) off = off->CC();
+ ScalarWaveFunction scalarInter =
+ outgoingVertexS_[inter]->evaluate(scale,3,off,gluon_[2*ig],scal,decay[isca]->mass());
+
+ assert(scal.particle()->id()==scalarInter.particle()->id());
+
+ Complex diag = vertex_->evaluate(scale,vectors3_[0][iv0],vectors3_[1][iv1],scalarInter);
+ if(!couplingSet) {
+ gs = abs(outgoingVertexS_[inter]->norm());
+ couplingSet = true;
+ }
+ for(unsigned int ix=0;ix<colourFlow[2].size();++ix) {
+ (*ME[colourFlow[2][ix].first])(iv0, iv1, 0, ig) +=
+ colourFlow[2][ix].second*diag;
+ }
+#ifdef GAUGE_CHECK
+ total+=norm(diag);
+#endif
+ }
+ }
+ }
+ }
+
+ // 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();
+ }
+ }
+ // divide by alpha_(S,EM)
+ output*=(4.*Constants::pi)/sqr(gs);
+#ifdef GAUGE_CHECK
+ double ratio = output/total;
+ if(abs(ratio)>1e-20) {
+ generator()->log() << "Test of gauge invariance in decay\n" << inpart << "\n";
+ for(unsigned int ix=0;ix<decay.size();++ix)
+ generator()->log() << *decay[ix] << "\n";
+ generator()->log() << "Test of gauge invariance " << ratio << "\n";
+ }
+#endif
+ // return the answer
+ return output;
+}
diff --git a/Decay/General/VVSDecayer.h b/Decay/General/VVSDecayer.h
--- a/Decay/General/VVSDecayer.h
+++ b/Decay/General/VVSDecayer.h
@@ -1,142 +1,193 @@
// -*- C++ -*-
#ifndef THEPEG_VVSDecayer_H
#define THEPEG_VVSDecayer_H
//
// This is the declaration of the VVSDecayer class.
//
#include "GeneralTwoBodyDecayer.h"
#include "ThePEG/Helicity/Vertex/Scalar/VVSVertex.h"
#include "ThePEG/Repository/EventGenerator.h"
namespace Herwig {
using namespace ThePEG;
using Helicity::VVSVertexPtr;
/** \ingroup Decay
* The VVSDecayer class implements the decay of a vector to a
* vector and a scalar in a general model. It holds an VVSVertex pointer
* that must be typecast from the VertexBase pointer helid in the
* GeneralTwoBodyDecayer. It implents the virtual functions me2() and
* partialWidth().
*
* @see \ref VVSDecayerInterfaces "The interfaces"
* defined for VVSDecayer.
*/
class VVSDecayer: public GeneralTwoBodyDecayer {
public:
/**
* The default constructor.
*/
VVSDecayer() {}
/** @name Virtual functions required by the Decayer class. */
//@{
/**
* Return the matrix element squared for a given mode and phase-space channel
* @param ichan The channel we are calculating the matrix element for.
* @param part The decaying Particle.
* @param decay The particles produced in the decay.
* @param meopt Option for the calculation of the matrix element
* @return The matrix element squared for the phase-space configuration.
*/
virtual double me2(const int ichan, const Particle & part,
const ParticleVector & decay, MEOption meopt) const;
/**
* Function to return partial Width
* @param inpart The decaying particle.
* @param outa One of the decay products.
* @param outb The other decay product.
*/
virtual Energy partialWidth(PMPair inpart, PMPair outa,
PMPair outb) const;
/**
* Set the information on the decay
*/
virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
map<ShowerInteraction,VertexBasePtr> &,
const vector<map<ShowerInteraction,VertexBasePtr> > &,
map<ShowerInteraction,VertexBasePtr>);
+
+ /**
+ * Has a POWHEG style correction
+ */
+ virtual POWHEGType hasPOWHEGCorrection() {
+ return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
+ }
+
+ /**
+ * Three-body matrix element including additional QCD radiation
+ */
+ virtual double threeBodyME(const int , const Particle & inpart,
+ const ParticleVector & decay,
+ ShowerInteraction inter, MEOption meopt);
//@}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
VVSDecayer & operator=(const VVSDecayer &);
private:
/**
* Abstract pointer to AbstractVVSVertex
*/
AbstractVVSVertexPtr vertex_;
/**
* Pointer to the perturbative vertex
*/
VVSVertexPtr perturbativeVertex_;
/**
+ * Abstract pointer to AbstractVVVVertex for QCD radiation from incoming vector
+ */
+ map<ShowerInteraction,AbstractVVVVertexPtr> incomingVertex_;
+
+ /**
+ * Abstract pointer to AbstractVVVVertex for QCD radiation from the first outgoing vector
+ */
+ map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertexV_;
+
+ /**
+ * Abstract pointer to AbstractVVVVertex for QCD radiation from the second outgoing vector
+ */
+ map<ShowerInteraction,AbstractVSSVertexPtr> outgoingVertexS_;
+
+ /**
* Spin density matrix
*/
mutable RhoDMatrix rho_;
/**
* Vector wavefunctions
*/
mutable vector<Helicity::VectorWaveFunction> vectors_[2];
+
+private:
+
+ /**
+ * Members for the POWHEG correction
+ */
+ //@{
+ /**
+ * Spin density matrix for 3 body decay
+ */
+ mutable RhoDMatrix rho3_;
+
+ /**
+ * Vector wavefunctions
+ */
+ mutable vector<Helicity::VectorWaveFunction> vectors3_[2];
+
+ /**
+ * Vector wavefunction for 3 body decay
+ */
+ mutable vector<Helicity::VectorWaveFunction> gluon_;
+ //@}
};
}
#endif /* THEPEG_VVSDecayer_H */
diff --git a/Decay/General/VVVDecayer.h b/Decay/General/VVVDecayer.h
--- a/Decay/General/VVVDecayer.h
+++ b/Decay/General/VVVDecayer.h
@@ -1,220 +1,220 @@
// -*- C++ -*-
//
// VVVDecayer.h 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.
//
#ifndef HERWIG_VVVDecayer_H
#define HERWIG_VVVDecayer_H
//
// This is the declaration of the VVVDecayer class.
//
#include "GeneralTwoBodyDecayer.h"
#include "ThePEG/Repository/EventGenerator.h"
#include "ThePEG/Helicity/Vertex/Vector/VVVVertex.h"
#include "ThePEG/Helicity/Vertex/AbstractVVVVVertex.h"
namespace Herwig {
using namespace ThePEG;
using Helicity::VVVVertexPtr;
/** \ingroup Decay
* The VVVDecayer class implements the decay of a vector
* to 2 vectors in a general model. It holds an VVVVertex pointer
* that must be typecast from the VertexBase pointer held in
* GeneralTwoBodyDecayer. It implents the virtual functions me2() and
* partialWidth().
*
* @see GeneralTwoBodyDecayer
*/
class VVVDecayer: public GeneralTwoBodyDecayer {
public:
/**
* The default constructor.
*/
VVVDecayer() {}
/** @name Virtual functions required by the Decayer class. */
//@{
/**
* Return the matrix element squared for a given mode and phase-space channel.
* @param ichan The channel we are calculating the matrix element for.
* @param part The decaying Particle.
* @param decay The particles produced in the decay.
* @param meopt Option for the calculation of the matrix element
* @return The matrix element squared for the phase-space configuration.
*/
virtual double me2(const int ichan, const Particle & part,
const ParticleVector & decay, MEOption meopt) const;
/**
* Function to return partial Width
* @param inpart The decaying particle.
* @param outa One of the decay products.
* @param outb The other decay product.
*/
virtual Energy partialWidth(PMPair inpart, PMPair outa,
PMPair outb) const;
/**
* Set the information on the decay
*/
virtual void setDecayInfo(PDPtr incoming, PDPair outgoing, VertexBasePtr,
map<ShowerInteraction,VertexBasePtr> &,
const vector<map<ShowerInteraction,VertexBasePtr> > &,
map<ShowerInteraction,VertexBasePtr>);
/**
* Has a POWHEG style correction
*/
virtual POWHEGType hasPOWHEGCorrection() {
return (vertex_->orderInGem()+vertex_->orderInGs())==1 ? FSR : No;
}
/**
* Three-body matrix element including additional QCD radiation
*/
virtual double threeBodyME(const int , const Particle & inpart,
const ParticleVector & decay,
ShowerInteraction inter, MEOption meopt);
//@}
public:
/** @name Functions used by the persistent I/O system. */
//@{
/**
* Function used to write out object persistently.
* @param os the persistent output stream written to.
*/
void persistentOutput(PersistentOStream & os) const;
/**
* Function used to read in object persistently.
* @param is the persistent input stream read from.
* @param version the version number of the object when written.
*/
void persistentInput(PersistentIStream & is, int version);
//@}
/**
* The standard Init function used to initialize the interfaces.
* Called exactly once for each class by the class description system
* before the main function starts or
* when this class is dynamically loaded.
*/
static void Init();
protected:
/** @name Clone Methods. */
//@{
/**
* Make a simple clone of this object.
* @return a pointer to the new object.
*/
virtual IBPtr clone() const;
/** Make a clone of this object, possibly modifying the cloned object
* to make it sane.
* @return a pointer to the new object.
*/
virtual IBPtr fullclone() const;
//@}
protected:
/**
* Find the vertices for the decay
*/
void identifyVertices(const Particle & inpart, const ParticleVector & decay,
AbstractVVVVertexPtr & outgoingVertex1,
AbstractVVVVertexPtr & outgoingVertex2,
ShowerInteraction inter);
private:
/**
* The assignment operator is private and must never be called.
* In fact, it should not even be implemented.
*/
VVVDecayer & operator=(const VVVDecayer &);
private:
/**
* Abstract pointer to AbstractVVVVertex
*/
AbstractVVVVertexPtr vertex_;
/**
* Pointer to the perturbative vertex
*/
VVVVertexPtr perturbativeVertex_;
/**
* Abstract pointer to AbstractVVVVertex for QCD radiation from incoming vector
*/
map<ShowerInteraction,AbstractVVVVertexPtr> incomingVertex_;
/**
* Abstract pointer to AbstractVVVVertex for QCD radiation from the first outgoing vector
*/
map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertex1_;
/**
* Abstract pointer to AbstractVVVVertex for QCD radiation from the second outgoing vector
*/
map<ShowerInteraction,AbstractVVVVertexPtr> outgoingVertex2_;
/**
* Abstract pointer to AbstractVVVVertex for QCD radiation from the 4-point vertex
*/
map<ShowerInteraction,AbstractVVVVVertexPtr> fourPointVertex_;
/**
* Spin density matrix
*/
mutable RhoDMatrix rho_;
/**
* Vector wavefunctions
*/
mutable vector<Helicity::VectorWaveFunction> vectors_[3];
private:
/**
- * Member for the POWHEG correction
+ * Members for the POWHEG correction
*/
//@{
/**
* Spin density matrix for 3 body decay
*/
mutable RhoDMatrix rho3_;
/**
* Vector wavefunction for 3 body decay
*/
mutable vector<Helicity::VectorWaveFunction> vector3_;
/**
* Vector wavefunctions
*/
mutable vector<Helicity::VectorWaveFunction> vectors3_[2];
/**
* Vector wavefunction for 3 body decay
*/
mutable vector<Helicity::VectorWaveFunction> gluon_;
//@}
};
}
#endif /* HERWIG_VVVDecayer_H */
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Apr 24, 6:40 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4880448
Default Alt Text
(36 KB)
Attached To
R563 testingHerwigHG
Event Timeline
Log In to Comment