1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
|
// -*- C++ -*-
//
// ThreeBodyAllOnCalculator.h is a part of Herwig++ - A multi-purpose Monte Carlo event generator
// Copyright (C) 2002-2011 The Herwig Collaboration
//
// Herwig++ is licenced under version 2 of the GPL, see COPYING for details.
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
//
#ifndef HERWIG_ThreeBodyAllOnCalculator_H
#define HERWIG_ThreeBodyAllOnCalculator_H
// This is the declaration of the ThreeBodyAllOnCalculator class.
#include "WidthCalculatorBase.h"
#include "Herwig++/Utilities/GSLIntegrator.h"
#include "Herwig++/Decay/DecayIntegrator.h"
#include "Herwig++/Decay/DecayPhaseSpaceMode.h"
namespace Herwig {
using namespace ThePEG;
template <class T>
class ThreeBodyAllOnCalculator;
/** \ingroup PDT
*
* The ThreeBodyAllOnCalculator class is designed to integrate
* a three-body matrix element in which all the outgoing particles are
* on-shell to give the partial width. A multi-channel type approach is
* used together with a GSL integration subroutine.
*
* @see GSLIntegrator
* @see ThreeBodyAllOnOuter
* @see ThreeBodyAllOnIner
*
*/
template <class T>
class ThreeBodyAllOnCalculator: public WidthCalculatorBase {
/** \ingroup PDT
* The class for the outer integrand of the integral of a three body decay matrix
* element. This class is used by the ThreeBodyAllOnCalculator
* to perform the outer integral.
*
* @see ThreeBodyAllOnCalculator
* @see ThreeBodyAllOnInner
*/ struct Outer {
/**
* Constructor with a pointer to the ThreeBodyAllOnCalculator
*/
Outer(typename Ptr<Herwig::ThreeBodyAllOnCalculator<T> >::const_pointer in,
double relerr)
: _integrand(in), _integrator(1e-35,relerr,1000)
{}
/**
* Retreive function value
*/
Energy4 operator ()(double x) const {
Energy2 low, upp;
_integrand->outerVariables(x,low,upp);
return _integrator.value(*_integrand,low,upp);
}
/** Argument type for the GSLIntegrator */
typedef double ArgType;
/** Return type for the GSLIntegrator */
typedef Energy4 ValType;
/**
* pointer to the decay integrator
*/
typename Ptr<Herwig::ThreeBodyAllOnCalculator<T> >::const_pointer _integrand;
/**
* GSL integration class
*/
GSLIntegrator _integrator;
};
public:
/**
* The ThreeBodyAllOnOuter class is a friend so it can access the private
* members and perform the integral.
*/
friend struct ThreeBodyAllOnOuter;
public:
/**
* Constructor with all the parameters
* @param inweights The weights for the different integration channels
* @param intype The types of the different integration channels.
* @param inmass The mass for the Jacobian for the different channels.
* @param inwidth The width for the Jacobian for the different channels.
* @param inpow the power for power-law smoothing for a given channel
* @param inme The pointer to the function which gives the matrix element.
* @param mode The mode to be integrated
* @param m1 The mass of the first particle.
* @param m2 The mass of the second particle.
* @param m3 The mass of the third particle.
*/
ThreeBodyAllOnCalculator(vector<double> inweights,
vector<int> intype,
vector<Energy> inmass,
vector<Energy> inwidth,
vector<double> inpow,
T inme, int mode,
Energy m1,Energy m2,Energy m3,
double relerr=1e-3)
: _channelweights(inweights),_channeltype(intype),_channelmass(inmass),
_channelwidth(inwidth),_channelpower(inpow),_theME(inme),_mode(mode),
_thechannel(0),_souter(ZERO), _integrator(1e-35,relerr,1000),
_relerr(relerr) {
_m.resize(4);
_m[1]=m1;_m[2]=m2;_m[3]=m3;
_m2.resize(4);
for(int ix=1;ix<4;++ix) {
_m2[ix]=sqr(_m[ix]);
}
}
/**
* calculate the width for a given mass
* @param q2 The mass squared of the decaying particle.
* @return The partial width.
*/
Energy partialWidth(Energy2 q2) const;
/**
* Get the mass of one of the decay products. This must be
* implemented in classes inheriting from this one.
* @param imass The mass required.
* @param mass The new value.
* @return The mass required.
*/
void resetMass(int imass,Energy mass) {
assert(imass<4);
_m[imass]=mass;
_m2[imass]=mass*mass;
}
/**
* Get the mass of one of the decay products. This must be
* implemented in classes inheriting from this one.
* @param imass The mass required.
* @return The mass required.
*/
Energy getMass(const int imass) const {
assert(imass>=0&&imass<4);
return _m[imass];
}
/**
* Get the masses of all bar the one specified. Used to get the limits
* for integration.
* @param imass The particle not needed
* @return The sum of the other masses.
*/
Energy otherMass(const int imass) const {
assert(imass>0&&imass<4);
if(imass==1) return _m[2]+_m[3];
else if(imass==2) return _m[1]+_m[3];
else return _m[1]+_m[2];
}
/**
* The integrand for the inner integrand.
* @param argument The mass squared for the inner integral
* @return The value of the inner integrand.
*/
Energy2 operator ()(Energy2 argument) const;
/** Argument type for the GSLIntegrator */
typedef Energy2 ArgType;
/** Return type for the GSLIntegrator */
typedef Energy2 ValType;
protected:
/**
* shift the variables for the outer integrand and give limits for the inner one.
* This member sets the value of the _souter member for the mass squared of the
* outer integral and calculates the limits on the mass squared of the inner
* integral.
* @param x The integration variable
* @param low The lower limit for the inner integral.
* @param upp The upper limit for the inner integral.
*/
void outerVariables(const double & x, Energy2 & low, Energy2 & upp) const;
private:
/**
* Private and non-existent assignment operator.
*/
ThreeBodyAllOnCalculator & operator=(const ThreeBodyAllOnCalculator &);
private:
/**
* weights for the different channels
*/
vector<double> _channelweights;
/**
* the types for the different channels
*/
vector<int> _channeltype;
/**
* the mass of the resonance for a given channel
*/
vector<Energy> _channelmass;
/**
* the width of the resonance for a given channel
*/
vector<Energy> _channelwidth;
/**
* the power for power-law smoothing for a given channel
*/
vector<double> _channelpower;
/**
* Function giving the matrix element as a function of s12,s13,s23
*/
T _theME;
/**
* The mode
*/
int _mode;
/**
* the channel currently being integrated
*/
mutable int _thechannel;
/**
* The mapping currently in used
*/
mutable int _mapping;
/**
* the value of s for the outer integral
*/
mutable Energy2 _souter;
/**
* masses of the external particles
*/
mutable vector<Energy> _m;
/**
* mass squareds of the external particles
*/
mutable vector<Energy2> _m2;
/**
* member to do the integration
*/
GSLIntegrator _integrator;
/**
* Relative error for the integration
*/
double _relerr;
};
}
#ifndef ThePEG_TEMPLATES_IN_CC_FILE
#include "ThreeBodyAllOnCalculator.tcc"
#endif
#endif /* HERWIG_ThreeBodyAllOnCalculator_H */
|