1
0
mirror of https://github.com/paboyle/Grid.git synced 2024-09-20 09:15:38 +01:00

Minor modifications

This commit is contained in:
Guido Cossu 2016-07-06 11:41:27 +01:00
parent fc4a043663
commit ffedeb1c58
4 changed files with 1029 additions and 1025 deletions

View File

@ -25,7 +25,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef GRID_QCD_FERMION_OPERATOR_IMPL_H #ifndef GRID_QCD_FERMION_OPERATOR_IMPL_H
@ -35,7 +36,6 @@ namespace Grid {
namespace QCD { namespace QCD {
////////////////////////////////////////////// //////////////////////////////////////////////
// Template parameter class constructs to package // Template parameter class constructs to package
// externally control Fermion implementations // externally control Fermion implementations
@ -54,14 +54,20 @@ namespace Grid {
// typedef typename XXX Compressor; // typedef typename XXX Compressor;
// //
// and Methods: // and Methods:
// void ImportGauge(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu) // void ImportGauge(GridBase *GaugeGrid,DoubledGaugeField &Uds,const
// void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu) // GaugeField &Umu)
// void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu,StencilEntry *SE,StencilImpl &St) // void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const
// void InsertForce4D(GaugeField &mat,const FermionField &Btilde,const FermionField &A,int mu) // GaugeField &Umu)
// void InsertForce5D(GaugeField &mat,const FermionField &Btilde,const FermionField &A,int mu) // void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const
// SiteHalfSpinor &chi,int mu,StencilEntry *SE,StencilImpl &St)
// void InsertForce4D(GaugeField &mat,const FermionField &Btilde,const
// FermionField &A,int mu)
// void InsertForce5D(GaugeField &mat,const FermionField &Btilde,const
// FermionField &A,int mu)
// //
// //
// To acquire the typedefs from "Base" (either a base class or template param) use: // To acquire the typedefs from "Base" (either a base class or template param)
// use:
// //
// INHERIT_GIMPL_TYPES(Base) // INHERIT_GIMPL_TYPES(Base)
// INHERIT_FIMPL_TYPES(Base) // INHERIT_FIMPL_TYPES(Base)
@ -88,7 +94,6 @@ namespace Grid {
// } // }
////////////////////////////////////////////// //////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Implementation dependent fermion types // Implementation dependent fermion types
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -110,16 +115,21 @@ namespace Grid {
// Single flavour four spinors with colour index // Single flavour four spinors with colour index
/////// ///////
template <class S, int Nrepresentation = Nc> template <class S, int Nrepresentation = Nc>
class WilsonImpl : public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepresentation> > { class WilsonImpl
: public PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > {
public: public:
typedef PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > Gimpl; typedef PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > Gimpl;
INHERIT_GIMPL_TYPES(Gimpl); INHERIT_GIMPL_TYPES(Gimpl);
template<typename vtype> using iImplSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >; template <typename vtype>
template<typename vtype> using iImplHalfSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Nhs> >; using iImplSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
template<typename vtype> using iImplDoubledGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds >; template <typename vtype>
using iImplHalfSpinor =
iScalar<iVector<iVector<vtype, Nrepresentation>, Nhs> >;
template <typename vtype>
using iImplDoubledGaugeField =
iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds>;
typedef iImplSpinor<Simd> SiteSpinor; typedef iImplSpinor<Simd> SiteSpinor;
typedef iImplHalfSpinor<Simd> SiteHalfSpinor; typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
@ -138,7 +148,9 @@ namespace Grid {
bool overlapCommsCompute(void) { return Params.overlapCommsCompute; }; bool overlapCommsCompute(void) { return Params.overlapCommsCompute; };
inline void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu,StencilEntry *SE,StencilImpl &St){ inline void multLink(SiteHalfSpinor &phi, const SiteDoubledGaugeField &U,
const SiteHalfSpinor &chi, int mu, StencilEntry *SE,
StencilImpl &St) {
mult(&phi(), &U(mu), &chi()); mult(&phi(), &U(mu), &chi());
} }
@ -146,8 +158,8 @@ namespace Grid {
inline void loadLinkElement(Simd &reg, ref &memory) { inline void loadLinkElement(Simd &reg, ref &memory) {
reg = memory; reg = memory;
} }
inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu) inline void DoubleStore(GridBase *GaugeGrid, DoubledGaugeField &Uds,
{ const GaugeField &Umu) {
conformable(Uds._grid, GaugeGrid); conformable(Uds._grid, GaugeGrid);
conformable(Umu._grid, GaugeGrid); conformable(Umu._grid, GaugeGrid);
GaugeLinkField U(GaugeGrid); GaugeLinkField U(GaugeGrid);
@ -159,14 +171,15 @@ namespace Grid {
} }
} }
inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A,int mu){ inline void InsertForce4D(GaugeField &mat, FermionField &Btilde,
FermionField &A, int mu) {
GaugeLinkField link(mat._grid); GaugeLinkField link(mat._grid);
link = TraceIndex<SpinIndex>(outerProduct(Btilde, A)); link = TraceIndex<SpinIndex>(outerProduct(Btilde, A));
PokeIndex<LorentzIndex>(mat, link, mu); PokeIndex<LorentzIndex>(mat, link, mu);
} }
inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField &Atilde,int mu){ inline void InsertForce5D(GaugeField &mat, FermionField &Btilde,
FermionField &Atilde, int mu) {
int Ls = Btilde._grid->_fdimensions[0]; int Ls = Btilde._grid->_fdimensions[0];
GaugeLinkField tmp(mat._grid); GaugeLinkField tmp(mat._grid);
@ -176,42 +189,50 @@ PARALLEL_FOR_LOOP
int sU = sss; int sU = sss;
for (int s = 0; s < Ls; s++) { for (int s = 0; s < Ls; s++) {
int sF = s + Ls * sU; int sF = s + Ls * sU;
tmp[sU] = tmp[sU]+ traceIndex<SpinIndex>(outerProduct(Btilde[sF],Atilde[sF])); // ordering here tmp[sU] = tmp[sU] + traceIndex<SpinIndex>(outerProduct(
Btilde[sF], Atilde[sF])); // ordering here
} }
} }
PokeIndex<LorentzIndex>(mat, tmp, mu); PokeIndex<LorentzIndex>(mat, tmp, mu);
} }
}; };
/////// ///////
// Single flavour four spinors with colour index, 5d redblack // Single flavour four spinors with colour index, 5d redblack
/////// ///////
template <class S, int Nrepresentation = Nc> template <class S, int Nrepresentation = Nc>
class DomainWallRedBlack5dImpl : public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepresentation> > { class DomainWallRedBlack5dImpl
: public PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > {
public: public:
typedef PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > Gimpl; typedef PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > Gimpl;
INHERIT_GIMPL_TYPES(Gimpl); INHERIT_GIMPL_TYPES(Gimpl);
template<typename vtype> using iImplSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >; template <typename vtype>
template<typename vtype> using iImplHalfSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Nhs> >; using iImplSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
template<typename vtype> using iImplDoubledGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds >; template <typename vtype>
template<typename vtype> using iImplGaugeField = iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nd >; using iImplHalfSpinor =
template<typename vtype> using iImplGaugeLink = iScalar<iScalar<iMatrix<vtype, Nrepresentation> > >; iScalar<iVector<iVector<vtype, Nrepresentation>, Nhs> >;
template <typename vtype>
using iImplDoubledGaugeField =
iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds>;
template <typename vtype>
using iImplGaugeField =
iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nd>;
template <typename vtype>
using iImplGaugeLink = iScalar<iScalar<iMatrix<vtype, Nrepresentation> > >;
typedef iImplSpinor<Simd> SiteSpinor; typedef iImplSpinor<Simd> SiteSpinor;
typedef iImplHalfSpinor<Simd> SiteHalfSpinor; typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
typedef Lattice<SiteSpinor> FermionField; typedef Lattice<SiteSpinor> FermionField;
// Make the doubled gauge field a *scalar* // Make the doubled gauge field a *scalar*
typedef iImplDoubledGaugeField<typename Simd::scalar_type> SiteDoubledGaugeField; // This is a scalar typedef iImplDoubledGaugeField<typename Simd::scalar_type>
typedef iImplGaugeField<typename Simd::scalar_type> SiteScalarGaugeField; // scalar SiteDoubledGaugeField; // This is a scalar
typedef iImplGaugeLink <typename Simd::scalar_type> SiteScalarGaugeLink; // scalar typedef iImplGaugeField<typename Simd::scalar_type>
SiteScalarGaugeField; // scalar
typedef iImplGaugeLink<typename Simd::scalar_type>
SiteScalarGaugeLink; // scalar
typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField; typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
@ -229,8 +250,9 @@ PARALLEL_FOR_LOOP
inline void loadLinkElement(Simd &reg, ref &memory) { inline void loadLinkElement(Simd &reg, ref &memory) {
vsplat(reg, memory); vsplat(reg, memory);
} }
inline void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu,StencilEntry *SE,StencilImpl &St) inline void multLink(SiteHalfSpinor &phi, const SiteDoubledGaugeField &U,
{ const SiteHalfSpinor &chi, int mu, StencilEntry *SE,
StencilImpl &St) {
SiteGaugeLink UU; SiteGaugeLink UU;
for (int i = 0; i < Nrepresentation; i++) { for (int i = 0; i < Nrepresentation; i++) {
for (int j = 0; j < Nrepresentation; j++) { for (int j = 0; j < Nrepresentation; j++) {
@ -240,8 +262,8 @@ PARALLEL_FOR_LOOP
mult(&phi(), &UU(), &chi()); mult(&phi(), &UU(), &chi());
} }
inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu) inline void DoubleStore(GridBase *GaugeGrid, DoubledGaugeField &Uds,
{ const GaugeField &Umu) {
SiteScalarGaugeField ScalarUmu; SiteScalarGaugeField ScalarUmu;
SiteDoubledGaugeField ScalarUds; SiteDoubledGaugeField ScalarUds;
@ -265,35 +287,40 @@ PARALLEL_FOR_LOOP
pokeLocalSite(ScalarUds, Uds, lcoor); pokeLocalSite(ScalarUds, Uds, lcoor);
} }
} }
inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A,int mu){ inline void InsertForce4D(GaugeField &mat, FermionField &Btilde,
FermionField &A, int mu) {
assert(0); assert(0);
} }
inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField &Atilde,int mu){ inline void InsertForce5D(GaugeField &mat, FermionField &Btilde,
FermionField &Atilde, int mu) {
assert(0); assert(0);
} }
}; };
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// Flavour doubled spinors; is Gparity the only? what about C*? // Flavour doubled spinors; is Gparity the only? what about C*?
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
template <class S, int Nrepresentation> template <class S, int Nrepresentation>
class GparityWilsonImpl : public ConjugateGaugeImpl< GaugeImplTypes<S,Nrepresentation> >{ class GparityWilsonImpl
: public ConjugateGaugeImpl<GaugeImplTypes<S, Nrepresentation> > {
public: public:
typedef ConjugateGaugeImpl<GaugeImplTypes<S, Nrepresentation> > Gimpl; typedef ConjugateGaugeImpl<GaugeImplTypes<S, Nrepresentation> > Gimpl;
INHERIT_GIMPL_TYPES(Gimpl); INHERIT_GIMPL_TYPES(Gimpl);
template<typename vtype> using iImplSpinor = iVector<iVector<iVector<vtype, Nrepresentation>, Ns>, Ngp >; template <typename vtype>
template<typename vtype> using iImplHalfSpinor = iVector<iVector<iVector<vtype, Nrepresentation>, Nhs>, Ngp >; using iImplSpinor =
template<typename vtype> using iImplDoubledGaugeField = iVector<iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds >, Ngp >; iVector<iVector<iVector<vtype, Nrepresentation>, Ns>, Ngp>;
template <typename vtype>
using iImplHalfSpinor =
iVector<iVector<iVector<vtype, Nrepresentation>, Nhs>, Ngp>;
template <typename vtype>
using iImplDoubledGaugeField =
iVector<iVector<iScalar<iMatrix<vtype, Nrepresentation> >, Nds>, Ngp>;
typedef iImplSpinor<Simd> SiteSpinor; typedef iImplSpinor<Simd> SiteSpinor;
typedef iImplHalfSpinor<Simd> SiteHalfSpinor; typedef iImplHalfSpinor<Simd> SiteHalfSpinor;
@ -313,9 +340,11 @@ PARALLEL_FOR_LOOP
bool overlapCommsCompute(void) { return Params.overlapCommsCompute; }; bool overlapCommsCompute(void) { return Params.overlapCommsCompute; };
// provide the multiply by link that is differentiated between Gparity (with flavour index) and non-Gparity // provide the multiply by link that is differentiated between Gparity (with
inline void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu,StencilEntry *SE,StencilImpl &St){ // flavour index) and non-Gparity
inline void multLink(SiteHalfSpinor &phi, const SiteDoubledGaugeField &U,
const SiteHalfSpinor &chi, int mu, StencilEntry *SE,
StencilImpl &St) {
typedef SiteHalfSpinor vobj; typedef SiteHalfSpinor vobj;
typedef typename SiteHalfSpinor::scalar_object sobj; typedef typename SiteHalfSpinor::scalar_object sobj;
@ -335,20 +364,18 @@ PARALLEL_FOR_LOOP
int mmu = mu % Nd; int mmu = mu % Nd;
// assert our assumptions // assert our assumptions
assert((distance==1)||(distance==-1)); // nearest neighbour stencil hard code assert((distance == 1) ||
(distance == -1)); // nearest neighbour stencil hard code
assert((sl == 1) || (sl == 2)); assert((sl == 1) || (sl == 2));
std::vector<int> icoor; std::vector<int> icoor;
if (SE->_around_the_world && Params.twists[mmu]) { if (SE->_around_the_world && Params.twists[mmu]) {
if (sl == 2) { if (sl == 2) {
std::vector<sobj> vals(Nsimd); std::vector<sobj> vals(Nsimd);
extract(chi, vals); extract(chi, vals);
for (int s = 0; s < Nsimd; s++) { for (int s = 0; s < Nsimd; s++) {
grid->iCoorFromIindex(icoor, s); grid->iCoorFromIindex(icoor, s);
assert((icoor[direction] == 0) || (icoor[direction] == 1)); assert((icoor[direction] == 0) || (icoor[direction] == 1));
@ -379,12 +406,10 @@ PARALLEL_FOR_LOOP
mult(&phi(0), &U(0)(mu), &chi(0)); mult(&phi(0), &U(0)(mu), &chi(0));
mult(&phi(1), &U(1)(mu), &chi(1)); mult(&phi(1), &U(1)(mu), &chi(1));
} }
} }
inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu) inline void DoubleStore(GridBase *GaugeGrid, DoubledGaugeField &Uds,
{ const GaugeField &Umu) {
conformable(Uds._grid, GaugeGrid); conformable(Uds._grid, GaugeGrid);
conformable(Umu._grid, GaugeGrid); conformable(Umu._grid, GaugeGrid);
@ -394,9 +419,7 @@ PARALLEL_FOR_LOOP
Lattice<iScalar<vInteger> > coor(GaugeGrid); Lattice<iScalar<vInteger> > coor(GaugeGrid);
for (int mu = 0; mu < Nd; mu++) { for (int mu = 0; mu < Nd; mu++) {
LatticeCoordinate(coor, mu); LatticeCoordinate(coor, mu);
U = PeekIndex<LorentzIndex>(Umu, mu); U = PeekIndex<LorentzIndex>(Umu, mu);
@ -408,7 +431,6 @@ PARALLEL_FOR_LOOP
Uconj = where(coor == neglink, -Uconj, Uconj); Uconj = where(coor == neglink, -Uconj, Uconj);
} }
PARALLEL_FOR_LOOP PARALLEL_FOR_LOOP
for (auto ss = U.begin(); ss < U.end(); ss++) { for (auto ss = U.begin(); ss < U.end(); ss++) {
Uds[ss](0)(mu) = U[ss](); Uds[ss](0)(mu) = U[ss]();
@ -437,12 +459,11 @@ PARALLEL_FOR_LOOP
for (auto ss = U.begin(); ss < U.end(); ss++) { for (auto ss = U.begin(); ss < U.end(); ss++) {
Uds[ss](1)(mu + 4) = Utmp[ss](); Uds[ss](1)(mu + 4) = Utmp[ss]();
} }
} }
} }
inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A,int mu){ inline void InsertForce4D(GaugeField &mat, FermionField &Btilde,
FermionField &A, int mu) {
// DhopDir provides U or Uconj depending on coor/flavour. // DhopDir provides U or Uconj depending on coor/flavour.
GaugeLinkField link(mat._grid); GaugeLinkField link(mat._grid);
// use lorentz for flavour as hack. // use lorentz for flavour as hack.
@ -454,8 +475,8 @@ PARALLEL_FOR_LOOP
PokeIndex<LorentzIndex>(mat, link, mu); PokeIndex<LorentzIndex>(mat, link, mu);
return; return;
} }
inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField &Atilde,int mu){ inline void InsertForce5D(GaugeField &mat, FermionField &Btilde,
FermionField &Atilde, int mu) {
int Ls = Btilde._grid->_fdimensions[0]; int Ls = Btilde._grid->_fdimensions[0];
GaugeLinkField tmp(mat._grid); GaugeLinkField tmp(mat._grid);
@ -477,14 +498,17 @@ PARALLEL_FOR_LOOP
typedef WilsonImpl<vComplexF, Nc> WilsonImplF; // Float typedef WilsonImpl<vComplexF, Nc> WilsonImplF; // Float
typedef WilsonImpl<vComplexD, Nc> WilsonImplD; // Double typedef WilsonImpl<vComplexD, Nc> WilsonImplD; // Double
typedef DomainWallRedBlack5dImpl<vComplex ,Nc> DomainWallRedBlack5dImplR; // Real.. whichever prec typedef DomainWallRedBlack5dImpl<vComplex, Nc>
typedef DomainWallRedBlack5dImpl<vComplexF,Nc> DomainWallRedBlack5dImplF; // Float DomainWallRedBlack5dImplR; // Real.. whichever prec
typedef DomainWallRedBlack5dImpl<vComplexD,Nc> DomainWallRedBlack5dImplD; // Double typedef DomainWallRedBlack5dImpl<vComplexF, Nc>
DomainWallRedBlack5dImplF; // Float
typedef DomainWallRedBlack5dImpl<vComplexD, Nc>
DomainWallRedBlack5dImplD; // Double
typedef GparityWilsonImpl<vComplex ,Nc> GparityWilsonImplR; // Real.. whichever prec typedef GparityWilsonImpl<vComplex, Nc>
GparityWilsonImplR; // Real.. whichever prec
typedef GparityWilsonImpl<vComplexF, Nc> GparityWilsonImplF; // Float typedef GparityWilsonImpl<vComplexF, Nc> GparityWilsonImplF; // Float
typedef GparityWilsonImpl<vComplexD, Nc> GparityWilsonImplD; // Double typedef GparityWilsonImpl<vComplexD, Nc> GparityWilsonImplD; // Double
} }
} }
#endif #endif

View File

@ -25,7 +25,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#include <Grid.h> #include <Grid.h>
@ -33,8 +34,10 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
namespace Grid { namespace Grid {
namespace QCD { namespace QCD {
const std::vector<int> WilsonFermionStatic::directions ({0,1,2,3, 0, 1, 2, 3}); const std::vector<int> WilsonFermionStatic::directions({0, 1, 2, 3, 0, 1, 2,
const std::vector<int> WilsonFermionStatic::displacements({1,1,1,1,-1,-1,-1,-1}); 3});
const std::vector<int> WilsonFermionStatic::displacements({1, 1, 1, 1, -1, -1,
-1, -1});
int WilsonFermionStatic::HandOptDslash; int WilsonFermionStatic::HandOptDslash;
///////////////////////////////// /////////////////////////////////
@ -42,30 +45,29 @@ namespace QCD {
///////////////////////////////// /////////////////////////////////
template <class Impl> template <class Impl>
WilsonFermion<Impl>::WilsonFermion(GaugeField &_Umu, WilsonFermion<Impl>::WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid,
GridCartesian &Fgrid, GridRedBlackCartesian &Hgrid, RealD _mass,
GridRedBlackCartesian &Hgrid, const ImplParams &p)
RealD _mass,const ImplParams &p) : : Kernels(p),
Kernels(p),
_grid(&Fgrid), _grid(&Fgrid),
_cbgrid(&Hgrid), _cbgrid(&Hgrid),
Stencil(&Fgrid, npoint, Even, directions, displacements), Stencil(&Fgrid, npoint, Even, directions, displacements),
StencilEven(&Hgrid,npoint,Even,directions,displacements), // source is Even StencilEven(&Hgrid, npoint, Even, directions,
StencilOdd (&Hgrid,npoint,Odd ,directions,displacements), // source is Odd displacements), // source is Even
StencilOdd(&Hgrid, npoint, Odd, directions,
displacements), // source is Odd
mass(_mass), mass(_mass),
Lebesgue(_grid), Lebesgue(_grid),
LebesgueEvenOdd(_cbgrid), LebesgueEvenOdd(_cbgrid),
Umu(&Fgrid), Umu(&Fgrid),
UmuEven(&Hgrid), UmuEven(&Hgrid),
UmuOdd (&Hgrid) UmuOdd(&Hgrid) {
{
// Allocate the required comms buffer // Allocate the required comms buffer
ImportGauge(_Umu); ImportGauge(_Umu);
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::ImportGauge(const GaugeField &_Umu) void WilsonFermion<Impl>::ImportGauge(const GaugeField &_Umu) {
{
GaugeField HUmu(_Umu._grid); GaugeField HUmu(_Umu._grid);
HUmu = _Umu * (-0.5); HUmu = _Umu * (-0.5);
Impl::DoubleStore(GaugeGrid(), Umu, HUmu); Impl::DoubleStore(GaugeGrid(), Umu, HUmu);
@ -78,24 +80,21 @@ namespace QCD {
///////////////////////////// /////////////////////////////
template <class Impl> template <class Impl>
RealD WilsonFermion<Impl>::M(const FermionField &in, FermionField &out) RealD WilsonFermion<Impl>::M(const FermionField &in, FermionField &out) {
{
out.checkerboard = in.checkerboard; out.checkerboard = in.checkerboard;
Dhop(in, out, DaggerNo); Dhop(in, out, DaggerNo);
return axpy_norm(out, 4 + mass, in, out); return axpy_norm(out, 4 + mass, in, out);
} }
template <class Impl> template <class Impl>
RealD WilsonFermion<Impl>::Mdag(const FermionField &in, FermionField &out) RealD WilsonFermion<Impl>::Mdag(const FermionField &in, FermionField &out) {
{
out.checkerboard = in.checkerboard; out.checkerboard = in.checkerboard;
Dhop(in, out, DaggerYes); Dhop(in, out, DaggerYes);
return axpy_norm(out, 4 + mass, in, out); return axpy_norm(out, 4 + mass, in, out);
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::Meooe(const FermionField &in, FermionField &out) void WilsonFermion<Impl>::Meooe(const FermionField &in, FermionField &out) {
{
if (in.checkerboard == Odd) { if (in.checkerboard == Odd) {
DhopEO(in, out, DaggerNo); DhopEO(in, out, DaggerNo);
} else { } else {
@ -103,8 +102,7 @@ namespace QCD {
} }
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::MeooeDag(const FermionField &in, FermionField &out) void WilsonFermion<Impl>::MeooeDag(const FermionField &in, FermionField &out) {
{
if (in.checkerboard == Odd) { if (in.checkerboard == Odd) {
DhopEO(in, out, DaggerYes); DhopEO(in, out, DaggerYes);
} else { } else {
@ -132,7 +130,8 @@ namespace QCD {
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::MooeeInvDag(const FermionField &in, FermionField &out) { void WilsonFermion<Impl>::MooeeInvDag(const FermionField &in,
FermionField &out) {
out.checkerboard = in.checkerboard; out.checkerboard = in.checkerboard;
MooeeInv(in, out); MooeeInv(in, out);
} }
@ -142,12 +141,9 @@ namespace QCD {
/////////////////////////////////// ///////////////////////////////////
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::DerivInternal(StencilImpl & st, void WilsonFermion<Impl>::DerivInternal(StencilImpl &st, DoubledGaugeField &U,
DoubledGaugeField & U, GaugeField &mat, const FermionField &A,
GaugeField &mat,
const FermionField &A,
const FermionField &B, int dag) { const FermionField &B, int dag) {
assert((dag == DaggerNo) || (dag == DaggerYes)); assert((dag == DaggerNo) || (dag == DaggerYes));
Compressor compressor(dag); Compressor compressor(dag);
@ -159,7 +155,6 @@ namespace QCD {
st.HaloExchange(B, compressor); st.HaloExchange(B, compressor);
for (int mu = 0; mu < Nd; mu++) { for (int mu = 0; mu < Nd; mu++) {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Flip gamma (1+g)<->(1-g) if dag // Flip gamma (1+g)<->(1-g) if dag
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -171,20 +166,20 @@ namespace QCD {
//////////////////////// ////////////////////////
PARALLEL_FOR_LOOP PARALLEL_FOR_LOOP
for (int sss = 0; sss < B._grid->oSites(); sss++) { for (int sss = 0; sss < B._grid->oSites(); sss++) {
Kernels::DiracOptDhopDir(st,U,st.comm_buf,sss,sss,B,Btilde,mu,gamma); Kernels::DiracOptDhopDir(st, U, st.comm_buf, sss, sss, B, Btilde, mu,
gamma);
} }
////////////////////////////////////////////////// //////////////////////////////////////////////////
// spin trace outer product // spin trace outer product
////////////////////////////////////////////////// //////////////////////////////////////////////////
Impl::InsertForce4D(mat, Btilde, Atilde, mu); Impl::InsertForce4D(mat, Btilde, Atilde, mu);
} }
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::DhopDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag) void WilsonFermion<Impl>::DhopDeriv(GaugeField &mat, const FermionField &U,
{ const FermionField &V, int dag) {
conformable(U._grid, _grid); conformable(U._grid, _grid);
conformable(U._grid, V._grid); conformable(U._grid, V._grid);
conformable(U._grid, mat._grid); conformable(U._grid, mat._grid);
@ -195,8 +190,8 @@ PARALLEL_FOR_LOOP
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::DhopDerivOE(GaugeField &mat,const FermionField &U,const FermionField &V,int dag) void WilsonFermion<Impl>::DhopDerivOE(GaugeField &mat, const FermionField &U,
{ const FermionField &V, int dag) {
conformable(U._grid, _cbgrid); conformable(U._grid, _cbgrid);
conformable(U._grid, V._grid); conformable(U._grid, V._grid);
conformable(U._grid, mat._grid); conformable(U._grid, mat._grid);
@ -209,8 +204,8 @@ PARALLEL_FOR_LOOP
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::DhopDerivEO(GaugeField &mat,const FermionField &U,const FermionField &V,int dag) void WilsonFermion<Impl>::DhopDerivEO(GaugeField &mat, const FermionField &U,
{ const FermionField &V, int dag) {
conformable(U._grid, _cbgrid); conformable(U._grid, _cbgrid);
conformable(U._grid, V._grid); conformable(U._grid, V._grid);
conformable(U._grid, mat._grid); conformable(U._grid, mat._grid);
@ -222,9 +217,9 @@ PARALLEL_FOR_LOOP
DerivInternal(StencilOdd, UmuEven, mat, U, V, dag); DerivInternal(StencilOdd, UmuEven, mat, U, V, dag);
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::Dhop(const FermionField &in, FermionField &out,int dag) { void WilsonFermion<Impl>::Dhop(const FermionField &in, FermionField &out,
int dag) {
conformable(in._grid, _grid); // verifies full grid conformable(in._grid, _grid); // verifies full grid
conformable(in._grid, out._grid); conformable(in._grid, out._grid);
@ -234,7 +229,8 @@ PARALLEL_FOR_LOOP
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::DhopOE(const FermionField &in, FermionField &out,int dag) { void WilsonFermion<Impl>::DhopOE(const FermionField &in, FermionField &out,
int dag) {
conformable(in._grid, _cbgrid); // verifies half grid conformable(in._grid, _cbgrid); // verifies half grid
conformable(in._grid, out._grid); // drops the cb check conformable(in._grid, out._grid); // drops the cb check
@ -245,7 +241,8 @@ PARALLEL_FOR_LOOP
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::DhopEO(const FermionField &in, FermionField &out,int dag) { void WilsonFermion<Impl>::DhopEO(const FermionField &in, FermionField &out,
int dag) {
conformable(in._grid, _cbgrid); // verifies half grid conformable(in._grid, _cbgrid); // verifies half grid
conformable(in._grid, out._grid); // drops the cb check conformable(in._grid, out._grid); // drops the cb check
@ -256,40 +253,40 @@ PARALLEL_FOR_LOOP
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::Mdir (const FermionField &in, FermionField &out,int dir,int disp) { void WilsonFermion<Impl>::Mdir(const FermionField &in, FermionField &out,
int dir, int disp) {
DhopDir(in, out, dir, disp); DhopDir(in, out, dir, disp);
} }
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::DhopDir(const FermionField &in, FermionField &out,int dir,int disp){ void WilsonFermion<Impl>::DhopDir(const FermionField &in, FermionField &out,
int dir, int disp) {
int skip = (disp == 1) ? 0 : 1; int skip = (disp == 1) ? 0 : 1;
int dirdisp = dir + skip * 4; int dirdisp = dir + skip * 4;
int gamma = dir + (1 - skip) * 4; int gamma = dir + (1 - skip) * 4;
DhopDirDisp(in, out, dirdisp, gamma, DaggerNo); DhopDirDisp(in, out, dirdisp, gamma, DaggerNo);
}; };
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::DhopDirDisp(const FermionField &in, FermionField &out,int dirdisp,int gamma,int dag) { void WilsonFermion<Impl>::DhopDirDisp(const FermionField &in, FermionField &out,
int dirdisp, int gamma, int dag) {
Compressor compressor(dag); Compressor compressor(dag);
Stencil.HaloExchange(in, compressor); Stencil.HaloExchange(in, compressor);
PARALLEL_FOR_LOOP PARALLEL_FOR_LOOP
for (int sss = 0; sss < in._grid->oSites(); sss++) { for (int sss = 0; sss < in._grid->oSites(); sss++) {
Kernels::DiracOptDhopDir(Stencil,Umu,Stencil.comm_buf,sss,sss,in,out,dirdisp,gamma); Kernels::DiracOptDhopDir(Stencil, Umu, Stencil.comm_buf, sss, sss, in, out,
dirdisp, gamma);
} }
}; };
template <class Impl> template <class Impl>
void WilsonFermion<Impl>::DhopInternal(StencilImpl & st,LebesgueOrder& lo,DoubledGaugeField & U, void WilsonFermion<Impl>::DhopInternal(StencilImpl &st, LebesgueOrder &lo,
const FermionField &in, FermionField &out,int dag) DoubledGaugeField &U,
{ const FermionField &in,
FermionField &out, int dag) {
assert((dag == DaggerNo) || (dag == DaggerYes)); assert((dag == DaggerNo) || (dag == DaggerYes));
Compressor compressor(dag); Compressor compressor(dag);
@ -298,22 +295,19 @@ PARALLEL_FOR_LOOP
if (dag == DaggerYes) { if (dag == DaggerYes) {
PARALLEL_FOR_LOOP PARALLEL_FOR_LOOP
for (int sss = 0; sss < in._grid->oSites(); sss++) { for (int sss = 0; sss < in._grid->oSites(); sss++) {
Kernels::DiracOptDhopSiteDag(st,lo,U,st.comm_buf,sss,sss,1,1,in,out); Kernels::DiracOptDhopSiteDag(st, lo, U, st.comm_buf, sss, sss, 1, 1, in,
out);
} }
} else { } else {
PARALLEL_FOR_LOOP PARALLEL_FOR_LOOP
for (int sss = 0; sss < in._grid->oSites(); sss++) { for (int sss = 0; sss < in._grid->oSites(); sss++) {
Kernels::DiracOptDhopSite(st,lo,U,st.comm_buf,sss,sss,1,1,in,out); Kernels::DiracOptDhopSite(st, lo, U, st.comm_buf, sss, sss, 1, 1, in,
out);
} }
} }
}; };
FermOpTemplateInstantiate(WilsonFermion); FermOpTemplateInstantiate(WilsonFermion);
GparityFermOpTemplateInstantiate(WilsonFermion); GparityFermOpTemplateInstantiate(WilsonFermion);
}
}
}}

View File

@ -24,7 +24,8 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef GRID_QCD_WILSON_FERMION_H #ifndef GRID_QCD_WILSON_FERMION_H
@ -44,8 +45,7 @@ namespace Grid {
}; };
template <class Impl> template <class Impl>
class WilsonFermion : public WilsonKernels<Impl>, public WilsonFermionStatic class WilsonFermion : public WilsonKernels<Impl>, public WilsonFermionStatic {
{
public: public:
INHERIT_IMPL_TYPES(Impl); INHERIT_IMPL_TYPES(Impl);
typedef WilsonKernels<Impl> Kernels; typedef WilsonKernels<Impl> Kernels;
@ -82,10 +82,12 @@ namespace Grid {
// Derivative interface // Derivative interface
//////////////////////// ////////////////////////
// Interface calls an internal routine // Interface calls an internal routine
void DhopDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag); void DhopDeriv(GaugeField &mat, const FermionField &U, const FermionField &V,
void DhopDerivOE(GaugeField &mat,const FermionField &U,const FermionField &V,int dag); int dag);
void DhopDerivEO(GaugeField &mat,const FermionField &U,const FermionField &V,int dag); void DhopDerivOE(GaugeField &mat, const FermionField &U,
const FermionField &V, int dag);
void DhopDerivEO(GaugeField &mat, const FermionField &U,
const FermionField &V, int dag);
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
// non-hermitian hopping term; half cb or both // non-hermitian hopping term; half cb or both
@ -99,28 +101,22 @@ namespace Grid {
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
void Mdir(const FermionField &in, FermionField &out, int dir, int disp); void Mdir(const FermionField &in, FermionField &out, int dir, int disp);
void DhopDir(const FermionField &in, FermionField &out, int dir, int disp); void DhopDir(const FermionField &in, FermionField &out, int dir, int disp);
void DhopDirDisp(const FermionField &in, FermionField &out,int dirdisp,int gamma,int dag) ; void DhopDirDisp(const FermionField &in, FermionField &out, int dirdisp,
int gamma, int dag);
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
// Extra methods added by derived // Extra methods added by derived
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
void DerivInternal(StencilImpl & st, void DerivInternal(StencilImpl &st, DoubledGaugeField &U, GaugeField &mat,
DoubledGaugeField & U, const FermionField &A, const FermionField &B, int dag);
GaugeField &mat,
const FermionField &A,
const FermionField &B,
int dag);
void DhopInternal(StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U, void DhopInternal(StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
const FermionField &in, FermionField &out, int dag); const FermionField &in, FermionField &out, int dag);
// Constructor // Constructor
WilsonFermion(GaugeField &_Umu, WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid,
GridCartesian &Fgrid, GridRedBlackCartesian &Hgrid, RealD _mass,
GridRedBlackCartesian &Hgrid, const ImplParams &p = ImplParams());
RealD _mass,
const ImplParams &p= ImplParams()
) ;
// DoubleStore impl dependent // DoubleStore impl dependent
void ImportGauge(const GaugeField &_Umu); void ImportGauge(const GaugeField &_Umu);
@ -131,7 +127,6 @@ namespace Grid {
// protected: // protected:
public: public:
RealD mass; RealD mass;
GridBase *_grid; GridBase *_grid;
@ -149,13 +144,10 @@ namespace Grid {
LebesgueOrder Lebesgue; LebesgueOrder Lebesgue;
LebesgueOrder LebesgueEvenOdd; LebesgueOrder LebesgueEvenOdd;
}; };
typedef WilsonFermion<WilsonImplF> WilsonFermionF; typedef WilsonFermion<WilsonImplF> WilsonFermionF;
typedef WilsonFermion<WilsonImplD> WilsonFermionD; typedef WilsonFermion<WilsonImplD> WilsonFermionD;
} }
} }
#endif #endif

View File

@ -23,7 +23,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
See the full license in the file "LICENSE" in the top level distribution directory See the full license in the file "LICENSE" in the top level distribution
directory
*************************************************************************************/ *************************************************************************************/
/* END LEGAL */ /* END LEGAL */
#ifndef QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_H #ifndef QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_H
@ -32,20 +33,16 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
namespace Grid { namespace Grid {
namespace QCD { namespace QCD {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Two flavour pseudofermion action for any EO prec dop // Two flavour pseudofermion action for any EO prec dop
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
template <class Impl> template <class Impl>
class TwoFlavourEvenOddPseudoFermionAction : public Action<typename Impl::GaugeField> { class TwoFlavourEvenOddPseudoFermionAction
: public Action<typename Impl::GaugeField> {
public: public:
INHERIT_IMPL_TYPES(Impl); INHERIT_IMPL_TYPES(Impl);
private: private:
FermionOperator<Impl> &FermOp; // the basic operator FermionOperator<Impl> &FermOp; // the basic operator
OperatorFunction<FermionField> &DerivativeSolver; OperatorFunction<FermionField> &DerivativeSolver;
@ -60,20 +57,18 @@ namespace Grid{
///////////////////////////////////////////////// /////////////////////////////////////////////////
TwoFlavourEvenOddPseudoFermionAction(FermionOperator<Impl> &Op, TwoFlavourEvenOddPseudoFermionAction(FermionOperator<Impl> &Op,
OperatorFunction<FermionField> &DS, OperatorFunction<FermionField> &DS,
OperatorFunction<FermionField> & AS OperatorFunction<FermionField> &AS)
) : : FermOp(Op),
FermOp(Op),
DerivativeSolver(DS), DerivativeSolver(DS),
ActionSolver(AS), ActionSolver(AS),
PhiEven(Op.FermionRedBlackGrid()), PhiEven(Op.FermionRedBlackGrid()),
PhiOdd(Op.FermionRedBlackGrid()) PhiOdd(Op.FermionRedBlackGrid()){};
{};
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
// Push the gauge field in to the dops. Assume any BC's and smearing already applied // Push the gauge field in to the dops. Assume any BC's and smearing already
// applied
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) { virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) {
// P(phi) = e^{- phi^dag (MpcdagMpc)^-1 phi} // P(phi) = e^{- phi^dag (MpcdagMpc)^-1 phi}
// Phi = McpDag eta // Phi = McpDag eta
// P(eta) = e^{- eta^dag eta} // P(eta) = e^{- eta^dag eta}
@ -93,14 +88,12 @@ namespace Grid{
FermOp.ImportGauge(U); FermOp.ImportGauge(U);
SchurDifferentiableOperator<Impl> PCop(FermOp); SchurDifferentiableOperator<Impl> PCop(FermOp);
PCop.MpcDag(etaOdd, PhiOdd); PCop.MpcDag(etaOdd, PhiOdd);
FermOp.MooeeDag(etaEven, PhiEven); FermOp.MooeeDag(etaEven, PhiEven);
PhiOdd = PhiOdd * scale; PhiOdd = PhiOdd * scale;
PhiEven = PhiEven * scale; PhiEven = PhiEven * scale;
}; };
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
@ -108,7 +101,6 @@ namespace Grid{
// + phi^dag (Mdag M)^-1 phi (even) // + phi^dag (Mdag M)^-1 phi (even)
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
virtual RealD S(const GaugeField &U) { virtual RealD S(const GaugeField &U) {
FermOp.ImportGauge(U); FermOp.ImportGauge(U);
FermionField X(FermOp.FermionRedBlackGrid()); FermionField X(FermOp.FermionRedBlackGrid());
@ -121,25 +113,27 @@ namespace Grid{
PCop.Op(X, Y); PCop.Op(X, Y);
RealD action = norm2(Y); RealD action = norm2(Y);
// The EE factorised block; normally can replace with zero if det is constant (gauge field indept) // The EE factorised block; normally can replace with zero if det is
// constant (gauge field indept)
// Only really clover term that creates this. // Only really clover term that creates this.
FermOp.MooeeInvDag(PhiEven, Y); FermOp.MooeeInvDag(PhiEven, Y);
action = action + norm2(Y); action = action + norm2(Y);
std::cout << GridLogMessage << "Pseudofermion EO action "<<action<<std::endl; std::cout << GridLogMessage << "Pseudofermion EO action " << action
<< std::endl;
return action; return action;
}; };
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
// //
// dS/du = - phi^dag (Mdag M)^-1 [ Mdag dM + dMdag M ] (Mdag M)^-1 phi // dS/du = - phi^dag (Mdag M)^-1 [ Mdag dM + dMdag M ] (Mdag M)^-1 phi
// = - phi^dag M^-1 dM (MdagM)^-1 phi - phi^dag (MdagM)^-1 dMdag dM (Mdag)^-1 phi // = - phi^dag M^-1 dM (MdagM)^-1 phi - phi^dag (MdagM)^-1 dMdag dM
// (Mdag)^-1 phi
// //
// = - Ydag dM X - Xdag dMdag Y // = - Ydag dM X - Xdag dMdag Y
// //
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
virtual void deriv(const GaugeField &U, GaugeField &dSdU) { virtual void deriv(const GaugeField &U, GaugeField &dSdU) {
FermOp.ImportGauge(U); FermOp.ImportGauge(U);
FermionField X(FermOp.FermionRedBlackGrid()); FermionField X(FermOp.FermionRedBlackGrid());
@ -148,14 +142,17 @@ namespace Grid{
SchurDifferentiableOperator<Impl> Mpc(FermOp); SchurDifferentiableOperator<Impl> Mpc(FermOp);
// Our conventions really make this UdSdU; We do not differentiate wrt Udag here. // Our conventions really make this UdSdU; We do not differentiate wrt Udag
// here.
// So must take dSdU - adj(dSdU) and left multiply by mom to get dS/dt. // So must take dSdU - adj(dSdU) and left multiply by mom to get dS/dt.
X = zero; X = zero;
DerivativeSolver(Mpc, PhiOdd, X); DerivativeSolver(Mpc, PhiOdd, X);
Mpc.Mpc(X, Y); Mpc.Mpc(X, Y);
Mpc.MpcDeriv(tmp , Y, X ); dSdU=tmp; Mpc.MpcDeriv(tmp, Y, X);
Mpc.MpcDagDeriv(tmp , X, Y); dSdU=dSdU+tmp; dSdU = tmp;
Mpc.MpcDagDeriv(tmp, X, Y);
dSdU = dSdU + tmp;
// Treat the EE case. (MdagM)^-1 = Minv Minvdag // Treat the EE case. (MdagM)^-1 = Minv Minvdag
// Deriv defaults to zero. // Deriv defaults to zero.
@ -174,11 +171,8 @@ namespace Grid{
*/ */
dSdU = Ta(dSdU); dSdU = Ta(dSdU);
}; };
}; };
} }
} }