2016-10-21 13:10:13 +01:00
|
|
|
/*************************************************************************************
|
|
|
|
|
|
|
|
Grid physics library, www.github.com/paboyle/Grid
|
|
|
|
|
|
|
|
Source file: ./lib/qcd/action/gauge/Photon.h
|
|
|
|
|
|
|
|
Copyright (C) 2015
|
|
|
|
|
|
|
|
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
|
|
|
|
See the full license in the file "LICENSE" in the top level distribution directory
|
2018-01-14 22:52:22 +00:00
|
|
|
*************************************************************************************/
|
2016-10-21 13:10:13 +01:00
|
|
|
/* END LEGAL */
|
2016-09-26 09:43:40 +01:00
|
|
|
#ifndef QCD_PHOTON_ACTION_H
|
|
|
|
#define QCD_PHOTON_ACTION_H
|
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
NAMESPACE_BEGIN(Grid);
|
|
|
|
|
|
|
|
template <class S>
|
|
|
|
class QedGimpl
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef S Simd;
|
2016-12-29 21:43:38 +00:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
template <typename vtype>
|
|
|
|
using iImplGaugeLink = iScalar<iScalar<iScalar<vtype>>>;
|
|
|
|
template <typename vtype>
|
|
|
|
using iImplGaugeField = iVector<iScalar<iScalar<vtype>>, Nd>;
|
2016-12-29 21:43:38 +00:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
typedef iImplGaugeLink<Simd> SiteLink;
|
|
|
|
typedef iImplGaugeField<Simd> SiteField;
|
|
|
|
typedef SiteField SiteComplex;
|
2016-12-29 21:43:38 +00:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
typedef Lattice<SiteLink> LinkField;
|
|
|
|
typedef Lattice<SiteField> Field;
|
|
|
|
typedef Field ComplexField;
|
|
|
|
};
|
2016-12-29 21:43:38 +00:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
typedef QedGimpl<vComplex> QedGimplR;
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
template<class Gimpl>
|
|
|
|
class Photon
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
INHERIT_GIMPL_TYPES(Gimpl);
|
|
|
|
GRID_SERIALIZABLE_ENUM(Gauge, undef, feynman, 1, coulomb, 2, landau, 3);
|
|
|
|
GRID_SERIALIZABLE_ENUM(ZmScheme, undef, qedL, 1, qedTL, 2);
|
|
|
|
public:
|
|
|
|
Photon(Gauge gauge, ZmScheme zmScheme);
|
|
|
|
virtual ~Photon(void) = default;
|
|
|
|
void FreePropagator(const GaugeField &in, GaugeField &out);
|
|
|
|
void MomentumSpacePropagator(const GaugeField &in, GaugeField &out);
|
|
|
|
void StochasticWeight(GaugeLinkField &weight);
|
|
|
|
void StochasticField(GaugeField &out, GridParallelRNG &rng);
|
|
|
|
void StochasticField(GaugeField &out, GridParallelRNG &rng,
|
|
|
|
const GaugeLinkField &weight);
|
|
|
|
private:
|
|
|
|
void invKHatSquared(GaugeLinkField &out);
|
|
|
|
void zmSub(GaugeLinkField &out);
|
|
|
|
private:
|
|
|
|
Gauge gauge_;
|
|
|
|
ZmScheme zmScheme_;
|
|
|
|
};
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
typedef Photon<QedGimplR> PhotonR;
|
2016-12-29 21:43:38 +00:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
template<class Gimpl>
|
|
|
|
Photon<Gimpl>::Photon(Gauge gauge, ZmScheme zmScheme)
|
2016-10-21 13:10:13 +01:00
|
|
|
: gauge_(gauge), zmScheme_(zmScheme)
|
2018-01-14 22:52:22 +00:00
|
|
|
{}
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
template<class Gimpl>
|
|
|
|
void Photon<Gimpl>::FreePropagator (const GaugeField &in,GaugeField &out)
|
|
|
|
{
|
|
|
|
FFT theFFT(in._grid);
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
GaugeField in_k(in._grid);
|
|
|
|
GaugeField prop_k(in._grid);
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
theFFT.FFT_all_dim(in_k,in,FFT::forward);
|
|
|
|
MomentumSpacePropagator(prop_k,in_k);
|
|
|
|
theFFT.FFT_all_dim(out,prop_k,FFT::backward);
|
|
|
|
}
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
template<class Gimpl>
|
|
|
|
void Photon<Gimpl>::invKHatSquared(GaugeLinkField &out)
|
|
|
|
{
|
|
|
|
GridBase *grid = out._grid;
|
|
|
|
GaugeLinkField kmu(grid), one(grid);
|
|
|
|
const unsigned int nd = grid->_ndimension;
|
|
|
|
std::vector<int> &l = grid->_fdimensions;
|
|
|
|
std::vector<int> zm(nd,0);
|
|
|
|
TComplex Tone = Complex(1.0,0.0);
|
|
|
|
TComplex Tzero= Complex(0.0,0.0);
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
one = Complex(1.0,0.0);
|
|
|
|
out = zero;
|
|
|
|
for(int mu = 0; mu < nd; mu++)
|
2016-10-21 13:10:13 +01:00
|
|
|
{
|
2016-11-01 16:02:35 +00:00
|
|
|
Real twoPiL = M_PI*2./l[mu];
|
2016-09-26 09:43:40 +01:00
|
|
|
|
2016-10-21 13:10:13 +01:00
|
|
|
LatticeCoordinate(kmu,mu);
|
|
|
|
kmu = 2.*sin(.5*twoPiL*kmu);
|
|
|
|
out = out + kmu*kmu;
|
|
|
|
}
|
2018-01-14 22:52:22 +00:00
|
|
|
pokeSite(Tone, out, zm);
|
|
|
|
out = one/out;
|
|
|
|
pokeSite(Tzero, out, zm);
|
|
|
|
}
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
template<class Gimpl>
|
|
|
|
void Photon<Gimpl>::zmSub(GaugeLinkField &out)
|
|
|
|
{
|
|
|
|
GridBase *grid = out._grid;
|
|
|
|
const unsigned int nd = grid->_ndimension;
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
switch (zmScheme_)
|
2016-10-21 13:10:13 +01:00
|
|
|
{
|
2018-01-14 22:52:22 +00:00
|
|
|
case ZmScheme::qedTL:
|
2016-10-21 13:10:13 +01:00
|
|
|
{
|
|
|
|
std::vector<int> zm(nd,0);
|
2016-11-01 16:02:35 +00:00
|
|
|
TComplex Tzero = Complex(0.0,0.0);
|
2016-10-21 13:10:13 +01:00
|
|
|
|
|
|
|
pokeSite(Tzero, out, zm);
|
|
|
|
|
|
|
|
break;
|
2016-09-26 09:43:40 +01:00
|
|
|
}
|
2018-01-14 22:52:22 +00:00
|
|
|
case ZmScheme::qedL:
|
2016-10-21 13:10:13 +01:00
|
|
|
{
|
|
|
|
LatticeInteger spNrm(grid), coor(grid);
|
|
|
|
GaugeLinkField z(grid);
|
|
|
|
|
|
|
|
spNrm = zero;
|
|
|
|
for(int d = 0; d < grid->_ndimension - 1; d++)
|
2018-01-14 22:52:22 +00:00
|
|
|
{
|
|
|
|
LatticeCoordinate(coor,d);
|
|
|
|
spNrm = spNrm + coor*coor;
|
|
|
|
}
|
2016-10-21 15:20:12 +01:00
|
|
|
out = where(spNrm == Integer(0), 0.*out, out);
|
2016-10-21 13:10:13 +01:00
|
|
|
|
|
|
|
break;
|
2016-09-26 09:43:40 +01:00
|
|
|
}
|
2018-01-14 22:52:22 +00:00
|
|
|
default:
|
|
|
|
break;
|
2016-10-21 13:10:13 +01:00
|
|
|
}
|
2018-01-14 22:52:22 +00:00
|
|
|
}
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
template<class Gimpl>
|
|
|
|
void Photon<Gimpl>::MomentumSpacePropagator(const GaugeField &in,
|
|
|
|
GaugeField &out)
|
|
|
|
{
|
|
|
|
GridBase *grid = out._grid;
|
|
|
|
LatticeComplex k2Inv(grid);
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
invKHatSquared(k2Inv);
|
|
|
|
zmSub(k2Inv);
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
out = in*k2Inv;
|
|
|
|
}
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
template<class Gimpl>
|
|
|
|
void Photon<Gimpl>::StochasticWeight(GaugeLinkField &weight)
|
|
|
|
{
|
|
|
|
auto *grid = dynamic_cast<GridCartesian *>(weight._grid);
|
|
|
|
const unsigned int nd = grid->_ndimension;
|
|
|
|
std::vector<int> latt_size = grid->_fdimensions;
|
2016-10-21 13:10:13 +01:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
Integer vol = 1;
|
|
|
|
for(int d = 0; d < nd; d++)
|
2016-10-29 11:04:02 +01:00
|
|
|
{
|
|
|
|
vol = vol * latt_size[d];
|
|
|
|
}
|
2018-01-14 22:52:22 +00:00
|
|
|
invKHatSquared(weight);
|
|
|
|
weight = sqrt(vol*real(weight));
|
|
|
|
zmSub(weight);
|
|
|
|
}
|
2016-12-21 23:29:19 +00:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
template<class Gimpl>
|
|
|
|
void Photon<Gimpl>::StochasticField(GaugeField &out, GridParallelRNG &rng)
|
|
|
|
{
|
|
|
|
auto *grid = dynamic_cast<GridCartesian *>(out._grid);
|
|
|
|
GaugeLinkField weight(grid);
|
2016-12-21 23:29:19 +00:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
StochasticWeight(weight);
|
|
|
|
StochasticField(out, rng, weight);
|
|
|
|
}
|
2016-12-21 23:29:19 +00:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
template<class Gimpl>
|
|
|
|
void Photon<Gimpl>::StochasticField(GaugeField &out, GridParallelRNG &rng,
|
|
|
|
const GaugeLinkField &weight)
|
|
|
|
{
|
|
|
|
auto *grid = dynamic_cast<GridCartesian *>(out._grid);
|
|
|
|
const unsigned int nd = grid->_ndimension;
|
|
|
|
GaugeLinkField r(grid);
|
|
|
|
GaugeField aTilde(grid);
|
|
|
|
FFT fft(grid);
|
2016-12-21 23:29:19 +00:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
for(int mu = 0; mu < nd; mu++)
|
2016-10-21 13:10:13 +01:00
|
|
|
{
|
|
|
|
gaussian(rng, r);
|
2016-12-21 23:29:19 +00:00
|
|
|
r = weight*r;
|
2016-10-21 13:10:13 +01:00
|
|
|
pokeLorentz(aTilde, r, mu);
|
|
|
|
}
|
2018-01-14 22:52:22 +00:00
|
|
|
fft.FFT_all_dim(out, aTilde, FFT::backward);
|
2016-12-21 23:29:19 +00:00
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
out = real(out);
|
|
|
|
}
|
2016-10-21 13:10:13 +01:00
|
|
|
// template<class Gimpl>
|
|
|
|
// void Photon<Gimpl>::FeynmanGaugeMomentumSpacePropagator_L(GaugeField &out,
|
|
|
|
// const GaugeField &in)
|
|
|
|
// {
|
|
|
|
//
|
|
|
|
// FeynmanGaugeMomentumSpacePropagator_TL(out,in);
|
|
|
|
//
|
|
|
|
// GridBase *grid = out._grid;
|
|
|
|
// LatticeInteger coor(grid);
|
|
|
|
// GaugeField zz(grid); zz=zero;
|
|
|
|
//
|
|
|
|
// // xyzt
|
|
|
|
// for(int d = 0; d < grid->_ndimension-1;d++){
|
|
|
|
// LatticeCoordinate(coor,d);
|
|
|
|
// out = where(coor==Integer(0),zz,out);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// template<class Gimpl>
|
|
|
|
// void Photon<Gimpl>::FeynmanGaugeMomentumSpacePropagator_TL(GaugeField &out,
|
|
|
|
// const GaugeField &in)
|
|
|
|
// {
|
|
|
|
//
|
|
|
|
// // what type LatticeComplex
|
|
|
|
// GridBase *grid = out._grid;
|
|
|
|
// int nd = grid->_ndimension;
|
|
|
|
//
|
|
|
|
// typedef typename GaugeField::vector_type vector_type;
|
|
|
|
// typedef typename GaugeField::scalar_type ScalComplex;
|
|
|
|
// typedef Lattice<iSinglet<vector_type> > LatComplex;
|
|
|
|
//
|
|
|
|
// std::vector<int> latt_size = grid->_fdimensions;
|
|
|
|
//
|
|
|
|
// LatComplex denom(grid); denom= zero;
|
|
|
|
// LatComplex one(grid); one = ScalComplex(1.0,0.0);
|
|
|
|
// LatComplex kmu(grid);
|
|
|
|
//
|
|
|
|
// ScalComplex ci(0.0,1.0);
|
|
|
|
// // momphase = n * 2pi / L
|
|
|
|
// for(int mu=0;mu<Nd;mu++) {
|
|
|
|
//
|
|
|
|
// LatticeCoordinate(kmu,mu);
|
|
|
|
//
|
|
|
|
// RealD TwoPiL = M_PI * 2.0/ latt_size[mu];
|
|
|
|
//
|
|
|
|
// kmu = TwoPiL * kmu ;
|
|
|
|
//
|
|
|
|
// denom = denom + 4.0*sin(kmu*0.5)*sin(kmu*0.5); // Wilson term
|
|
|
|
// }
|
|
|
|
// std::vector<int> zero_mode(nd,0);
|
|
|
|
// TComplexD Tone = ComplexD(1.0,0.0);
|
|
|
|
// TComplexD Tzero= ComplexD(0.0,0.0);
|
|
|
|
//
|
|
|
|
// pokeSite(Tone,denom,zero_mode);
|
|
|
|
//
|
|
|
|
// denom= one/denom;
|
|
|
|
//
|
|
|
|
// pokeSite(Tzero,denom,zero_mode);
|
|
|
|
//
|
|
|
|
// out = zero;
|
|
|
|
// out = in*denom;
|
|
|
|
// };
|
|
|
|
|
2018-01-14 22:52:22 +00:00
|
|
|
NAMESPACE_END(Grid);
|
2016-09-26 09:43:40 +01:00
|
|
|
#endif
|