#ifndef GRID_QCD_FERMION_OPERATOR_H #define GRID_QCD_FERMION_OPERATOR_H namespace Grid { namespace QCD { //////////////////////////////////////////////////////////////// // Hardwire to four spinors, allow to select // between gauge representation rank, and gparity/flavour index, // and single/double precision. //////////////////////////////////////////////////////////////// template class WilsonImpl { public: typedef S Simd; template using iImplSpinor = iScalar, Ns> >; template using iImplHalfSpinor = iScalar, Nhs> >; template using iImplGaugeLink = iScalar > >; template using iImplGaugeField = iVector >, Nd >; template using iImplDoubledGaugeField = iVector >, Nds >; typedef iImplSpinor SiteSpinor; typedef iImplHalfSpinor SiteHalfSpinor; typedef iImplGaugeLink SiteGaugeLink; typedef iImplGaugeField SiteGaugeField; typedef iImplDoubledGaugeField SiteDoubledGaugeField; typedef Lattice FermionField; typedef Lattice GaugeLinkField; // bit ugly naming; polarised gauge field, lorentz... all ugly typedef Lattice GaugeField; typedef Lattice DoubledGaugeField; typedef WilsonCompressor Compressor; // provide the multiply by link that is differentiated between Gparity (with flavour index) and // non-Gparity static inline void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu){ mult(&phi(),&U(mu),&chi()); } static inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu) { conformable(Uds._grid,GaugeGrid); conformable(Umu._grid,GaugeGrid); GaugeLinkField U(GaugeGrid); for(int mu=0;mu(Umu,mu); PokeIndex(Uds,U,mu); U = adj(Cshift(U,mu,-1)); PokeIndex(Uds,U,mu+4); } } }; typedef WilsonImpl WilsonImplR; // Real.. whichever prec typedef WilsonImpl WilsonImplF; // Float typedef WilsonImpl WilsonImplD; // Double template class GparityWilsonImpl { public: typedef S Simd; template using iImplSpinor = iVector, Ns>, Ngp >; template using iImplHalfSpinor = iVector, Nhs>, Ngp >; template using iImplGaugeField = iVector >, Nd >; template using iImplGaugeLink = iScalar > > >; template using iImplDoubledGaugeField = iVector >, Nds >, Ngp >; typedef iImplSpinor SiteSpinor; typedef iImplHalfSpinor SiteHalfSpinor; typedef iImplGaugeLink SiteGaugeLink; typedef iImplGaugeField SiteGaugeField; typedef iImplDoubledGaugeField SiteDoubledGaugeField; typedef Lattice FermionField; typedef Lattice GaugeLinkField; // bit ugly naming; polarised gauge field, lorentz... all ugly typedef Lattice GaugeField; typedef Lattice DoubledGaugeField; typedef GparityWilsonCompressor Compressor; // provide the multiply by link that is differentiated between Gparity (with flavour index) and // non-Gparity static inline void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu){ for(int f=0;f > coor(GaugeGrid); std::vector gpdirs({1,0,0,0}); for(int mu=0;mu(Umu,mu); Uconj = conj(U); int neglink = GaugeGrid->GlobalDimensions()[mu]-1; if ( gpdirs[mu] ) { Uconj = where(coor==neglink,-Uconj,Uconj); } PARALLEL_FOR_LOOP for(auto ss=U.begin();ss WilsonImplR; // Real.. whichever prec typedef WilsonImpl WilsonImplF; // Float typedef WilsonImpl WilsonImplD; // Double ////////////////////////////////////////////////////////////////////////////// // Four component fermions // Should type template the vector and gauge types // Think about multiple representations ////////////////////////////////////////////////////////////////////////////// template class FermionOperator : public CheckerBoardedSparseMatrixBase { public: #include public: GridBase * Grid(void) { return FermionGrid(); }; // this is all the linalg routines need to know GridBase * RedBlackGrid(void) { return FermionRedBlackGrid(); }; virtual GridBase *FermionGrid(void) =0; virtual GridBase *FermionRedBlackGrid(void) =0; virtual GridBase *GaugeGrid(void) =0; virtual GridBase *GaugeRedBlackGrid(void) =0; // override multiply virtual RealD M (const FermionField &in, FermionField &out)=0; virtual RealD Mdag (const FermionField &in, FermionField &out)=0; // half checkerboard operaions virtual void Meooe (const FermionField &in, FermionField &out)=0; virtual void MeooeDag (const FermionField &in, FermionField &out)=0; virtual void Mooee (const FermionField &in, FermionField &out)=0; virtual void MooeeDag (const FermionField &in, FermionField &out)=0; virtual void MooeeInv (const FermionField &in, FermionField &out)=0; virtual void MooeeInvDag (const FermionField &in, FermionField &out)=0; // non-hermitian hopping term; half cb or both virtual void Dhop (const FermionField &in, FermionField &out,int dag)=0; virtual void DhopOE(const FermionField &in, FermionField &out,int dag)=0; virtual void DhopEO(const FermionField &in, FermionField &out,int dag)=0; virtual void DhopDir(const FermionField &in, FermionField &out,int dir,int disp)=0; // implemented by WilsonFermion and WilsonFermion5D // force terms; five routines; default to Dhop on diagonal virtual void MDeriv (GaugeField &mat,const FermionField &U,const FermionField &V,int dag){DhopDeriv(mat,U,V,dag);}; virtual void MoeDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag){DhopDerivOE(mat,U,V,dag);}; virtual void MeoDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag){DhopDerivEO(mat,U,V,dag);}; virtual void MooDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag){mat=zero;}; virtual void MeeDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag){mat=zero;}; virtual void DhopDeriv (GaugeField &mat,const FermionField &U,const FermionField &V,int dag)=0; virtual void DhopDerivEO(GaugeField &mat,const FermionField &U,const FermionField &V,int dag)=0; virtual void DhopDerivOE(GaugeField &mat,const FermionField &U,const FermionField &V,int dag)=0; virtual void Mdiag (const FermionField &in, FermionField &out) { Mooee(in,out);}; // Same as Mooee applied to both CB's virtual void Mdir (const FermionField &in, FermionField &out,int dir,int disp)=0; // case by case Wilson, Clover, Cayley, ContFrac, PartFrac /////////////////////////////////////////////// // Updates gauge field during HMC /////////////////////////////////////////////// virtual void ImportGauge(const GaugeField & _U)=0; }; } } #endif