mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Minor modifications
This commit is contained in:
		@@ -1,490 +1,514 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/qcd/action/fermion/FermionOperatorImpl.h
 | 
			
		||||
Source file: ./lib/qcd/action/fermion/FermionOperatorImpl.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
 | 
			
		||||
Author: paboyle <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 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.
 | 
			
		||||
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.
 | 
			
		||||
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
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#ifndef  GRID_QCD_FERMION_OPERATOR_IMPL_H
 | 
			
		||||
#define  GRID_QCD_FERMION_OPERATOR_IMPL_H
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_QCD_FERMION_OPERATOR_IMPL_H
 | 
			
		||||
#define GRID_QCD_FERMION_OPERATOR_IMPL_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////
 | 
			
		||||
// Template parameter class constructs to package
 | 
			
		||||
// externally control Fermion implementations
 | 
			
		||||
// in orthogonal directions
 | 
			
		||||
//
 | 
			
		||||
// Ultimately need Impl to always define types where XXX is opaque
 | 
			
		||||
//
 | 
			
		||||
//    typedef typename XXX               Simd;
 | 
			
		||||
//    typedef typename XXX     GaugeLinkField;
 | 
			
		||||
//    typedef typename XXX         GaugeField;
 | 
			
		||||
//    typedef typename XXX      GaugeActField;
 | 
			
		||||
//    typedef typename XXX       FermionField;
 | 
			
		||||
//    typedef typename XXX  DoubledGaugeField;
 | 
			
		||||
//    typedef typename XXX         SiteSpinor;
 | 
			
		||||
//    typedef typename XXX     SiteHalfSpinor;
 | 
			
		||||
//    typedef typename XXX         Compressor;
 | 
			
		||||
//
 | 
			
		||||
// and Methods:
 | 
			
		||||
//    void ImportGauge(GridBase *GaugeGrid,DoubledGaugeField &Uds,const
 | 
			
		||||
//    GaugeField &Umu)
 | 
			
		||||
//    void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const
 | 
			
		||||
//    GaugeField &Umu)
 | 
			
		||||
//    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:
 | 
			
		||||
//
 | 
			
		||||
// INHERIT_GIMPL_TYPES(Base)
 | 
			
		||||
// INHERIT_FIMPL_TYPES(Base)
 | 
			
		||||
// INHERIT_IMPL_TYPES(Base)
 | 
			
		||||
//
 | 
			
		||||
// The Fermion operators will do the following:
 | 
			
		||||
//
 | 
			
		||||
// struct MyOpParams {
 | 
			
		||||
//   RealD mass;
 | 
			
		||||
// };
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
// template<class Impl>
 | 
			
		||||
// class MyOp : pubic<Impl> {
 | 
			
		||||
// public:
 | 
			
		||||
//
 | 
			
		||||
//    INHERIT_ALL_IMPL_TYPES(Impl);
 | 
			
		||||
//
 | 
			
		||||
//    MyOp(MyOpParams Myparm, ImplParams &ImplParam) :  Impl(ImplParam)
 | 
			
		||||
//    {
 | 
			
		||||
//
 | 
			
		||||
//    };
 | 
			
		||||
//
 | 
			
		||||
//  }
 | 
			
		||||
//////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////////////////////
 | 
			
		||||
    // Template parameter class constructs to package
 | 
			
		||||
    // externally control Fermion implementations
 | 
			
		||||
    // in orthogonal directions
 | 
			
		||||
    //
 | 
			
		||||
    // Ultimately need Impl to always define types where XXX is opaque
 | 
			
		||||
    //
 | 
			
		||||
    //    typedef typename XXX               Simd;
 | 
			
		||||
    //    typedef typename XXX     GaugeLinkField;	
 | 
			
		||||
    //    typedef typename XXX         GaugeField;
 | 
			
		||||
    //    typedef typename XXX      GaugeActField;
 | 
			
		||||
    //    typedef typename XXX       FermionField;
 | 
			
		||||
    //    typedef typename XXX  DoubledGaugeField;
 | 
			
		||||
    //    typedef typename XXX         SiteSpinor;
 | 
			
		||||
    //    typedef typename XXX     SiteHalfSpinor;	
 | 
			
		||||
    //    typedef typename XXX         Compressor;	
 | 
			
		||||
    //
 | 
			
		||||
    // and Methods:
 | 
			
		||||
    //    void ImportGauge(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
 | 
			
		||||
    //    void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
 | 
			
		||||
    //    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:
 | 
			
		||||
    //
 | 
			
		||||
    // INHERIT_GIMPL_TYPES(Base)
 | 
			
		||||
    // INHERIT_FIMPL_TYPES(Base)
 | 
			
		||||
    // INHERIT_IMPL_TYPES(Base)
 | 
			
		||||
    //
 | 
			
		||||
    // The Fermion operators will do the following:
 | 
			
		||||
    //
 | 
			
		||||
    // struct MyOpParams { 
 | 
			
		||||
    //   RealD mass;
 | 
			
		||||
    // };
 | 
			
		||||
    //
 | 
			
		||||
    //
 | 
			
		||||
    // template<class Impl>
 | 
			
		||||
    // class MyOp : pubic<Impl> { 
 | 
			
		||||
    // public:
 | 
			
		||||
    //
 | 
			
		||||
    //    INHERIT_ALL_IMPL_TYPES(Impl);
 | 
			
		||||
    //
 | 
			
		||||
    //    MyOp(MyOpParams Myparm, ImplParams &ImplParam) :  Impl(ImplParam)
 | 
			
		||||
    //    {
 | 
			
		||||
    //
 | 
			
		||||
    //    };
 | 
			
		||||
    //    
 | 
			
		||||
    //  }
 | 
			
		||||
    //////////////////////////////////////////////
 | 
			
		||||
////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Implementation dependent fermion types
 | 
			
		||||
////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Implementation dependent fermion types
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
#define INHERIT_FIMPL_TYPES(Impl)\
 | 
			
		||||
    typedef typename Impl::FermionField           FermionField;		\
 | 
			
		||||
    typedef typename Impl::DoubledGaugeField DoubledGaugeField;		\
 | 
			
		||||
    typedef typename Impl::SiteSpinor               SiteSpinor;		\
 | 
			
		||||
    typedef typename Impl::SiteHalfSpinor       SiteHalfSpinor;		\
 | 
			
		||||
    typedef typename Impl::Compressor               Compressor;		\
 | 
			
		||||
    typedef typename Impl::StencilImpl              StencilImpl;	\
 | 
			
		||||
    typedef typename Impl::ImplParams ImplParams;
 | 
			
		||||
#define INHERIT_FIMPL_TYPES(Impl)                             \
 | 
			
		||||
  typedef typename Impl::FermionField FermionField;           \
 | 
			
		||||
  typedef typename Impl::DoubledGaugeField DoubledGaugeField; \
 | 
			
		||||
  typedef typename Impl::SiteSpinor SiteSpinor;               \
 | 
			
		||||
  typedef typename Impl::SiteHalfSpinor SiteHalfSpinor;       \
 | 
			
		||||
  typedef typename Impl::Compressor Compressor;               \
 | 
			
		||||
  typedef typename Impl::StencilImpl StencilImpl;             \
 | 
			
		||||
  typedef typename Impl::ImplParams ImplParams;
 | 
			
		||||
 | 
			
		||||
#define INHERIT_IMPL_TYPES(Base) \
 | 
			
		||||
    INHERIT_GIMPL_TYPES(Base)\
 | 
			
		||||
    INHERIT_FIMPL_TYPES(Base)
 | 
			
		||||
 | 
			
		||||
    ///////
 | 
			
		||||
    // Single flavour four spinors with colour index
 | 
			
		||||
    ///////
 | 
			
		||||
    template<class S,int Nrepresentation=Nc>
 | 
			
		||||
    class WilsonImpl :  public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepresentation> > { 
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      typedef PeriodicGaugeImpl< GaugeImplTypes< S,Nrepresentation> > Gimpl;
 | 
			
		||||
 | 
			
		||||
      INHERIT_GIMPL_TYPES(Gimpl);
 | 
			
		||||
 | 
			
		||||
      template<typename vtype> using iImplSpinor             = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
 | 
			
		||||
      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 iImplHalfSpinor<Simd>           SiteHalfSpinor;
 | 
			
		||||
      typedef iImplDoubledGaugeField<Simd>    SiteDoubledGaugeField;
 | 
			
		||||
 | 
			
		||||
      typedef Lattice<SiteSpinor>                 FermionField;
 | 
			
		||||
      typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
 | 
			
		||||
 | 
			
		||||
      typedef WilsonCompressor<SiteHalfSpinor,SiteSpinor> Compressor;
 | 
			
		||||
      typedef WilsonImplParams ImplParams;
 | 
			
		||||
      typedef WilsonStencil<SiteSpinor,SiteHalfSpinor> StencilImpl;
 | 
			
		||||
 | 
			
		||||
      ImplParams Params;
 | 
			
		||||
 | 
			
		||||
      WilsonImpl(const ImplParams &p= ImplParams()) : Params(p) {}; 
 | 
			
		||||
 | 
			
		||||
      bool overlapCommsCompute(void) { return Params.overlapCommsCompute; };
 | 
			
		||||
    
 | 
			
		||||
      inline void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu,StencilEntry *SE,StencilImpl &St){
 | 
			
		||||
        mult(&phi(),&U(mu),&chi());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      template<class ref>
 | 
			
		||||
      inline void loadLinkElement(Simd & reg,ref &memory){
 | 
			
		||||
	reg = memory;
 | 
			
		||||
      }
 | 
			
		||||
      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<Nd;mu++){
 | 
			
		||||
  	  U = PeekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
	  PokeIndex<LorentzIndex>(Uds,U,mu);
 | 
			
		||||
	  U = adj(Cshift(U,mu,-1));
 | 
			
		||||
	  PokeIndex<LorentzIndex>(Uds,U,mu+4);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A,int mu){
 | 
			
		||||
	GaugeLinkField link(mat._grid);
 | 
			
		||||
	link = TraceIndex<SpinIndex>(outerProduct(Btilde,A)); 
 | 
			
		||||
	PokeIndex<LorentzIndex>(mat,link,mu);
 | 
			
		||||
      }   
 | 
			
		||||
 | 
			
		||||
      inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã,int mu){
 | 
			
		||||
 | 
			
		||||
	int Ls=Btilde._grid->_fdimensions[0];
 | 
			
		||||
 | 
			
		||||
	GaugeLinkField tmp(mat._grid);
 | 
			
		||||
	tmp = zero;
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
	for(int sss=0;sss<tmp._grid->oSites();sss++){
 | 
			
		||||
	  int sU=sss;
 | 
			
		||||
	  for(int s=0;s<Ls;s++){
 | 
			
		||||
	    int sF = s+Ls*sU;
 | 
			
		||||
	    tmp[sU] = tmp[sU]+ traceIndex<SpinIndex>(outerProduct(Btilde[sF],Atilde[sF])); // ordering here
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
	PokeIndex<LorentzIndex>(mat,tmp,mu);
 | 
			
		||||
	
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ///////
 | 
			
		||||
    // Single flavour four spinors with colour index, 5d redblack
 | 
			
		||||
    ///////
 | 
			
		||||
    template<class S,int Nrepresentation=Nc>
 | 
			
		||||
    class DomainWallRedBlack5dImpl :  public PeriodicGaugeImpl< GaugeImplTypes< S,Nrepresentation> > { 
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      typedef PeriodicGaugeImpl< GaugeImplTypes< S,Nrepresentation> > Gimpl;
 | 
			
		||||
 | 
			
		||||
      INHERIT_GIMPL_TYPES(Gimpl);
 | 
			
		||||
      
 | 
			
		||||
      template<typename vtype> using iImplSpinor             = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
 | 
			
		||||
      template<typename vtype> using iImplHalfSpinor         = 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 iImplHalfSpinor<Simd>           SiteHalfSpinor;
 | 
			
		||||
      typedef Lattice<SiteSpinor>             FermionField;
 | 
			
		||||
 | 
			
		||||
      // Make the doubled gauge field a *scalar*
 | 
			
		||||
      typedef iImplDoubledGaugeField<typename Simd::scalar_type>    SiteDoubledGaugeField; // This is a scalar
 | 
			
		||||
      typedef iImplGaugeField<typename Simd::scalar_type>           SiteScalarGaugeField;  // scalar
 | 
			
		||||
      typedef iImplGaugeLink <typename Simd::scalar_type>           SiteScalarGaugeLink;   // scalar
 | 
			
		||||
 | 
			
		||||
      typedef Lattice<SiteDoubledGaugeField>                  DoubledGaugeField;
 | 
			
		||||
 | 
			
		||||
      typedef WilsonCompressor<SiteHalfSpinor,SiteSpinor> Compressor;
 | 
			
		||||
      typedef WilsonImplParams ImplParams;
 | 
			
		||||
      typedef WilsonStencil<SiteSpinor,SiteHalfSpinor> StencilImpl;
 | 
			
		||||
 | 
			
		||||
      ImplParams Params;
 | 
			
		||||
 | 
			
		||||
      DomainWallRedBlack5dImpl(const ImplParams &p= ImplParams()) : Params(p) {}; 
 | 
			
		||||
 | 
			
		||||
      bool overlapCommsCompute(void) { return false; };
 | 
			
		||||
    
 | 
			
		||||
      template<class ref>
 | 
			
		||||
      inline void loadLinkElement(Simd & reg,ref &memory){
 | 
			
		||||
	vsplat(reg,memory);
 | 
			
		||||
      }
 | 
			
		||||
      inline void multLink(SiteHalfSpinor &phi,const SiteDoubledGaugeField &U,const SiteHalfSpinor &chi,int mu,StencilEntry *SE,StencilImpl &St)
 | 
			
		||||
      {
 | 
			
		||||
	SiteGaugeLink UU;
 | 
			
		||||
	for(int i=0;i<Nrepresentation;i++){
 | 
			
		||||
	  for(int j=0;j<Nrepresentation;j++){
 | 
			
		||||
	    vsplat(UU()()(i,j),U(mu)()(i,j));
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
        mult(&phi(),&UU(),&chi());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
 | 
			
		||||
      {
 | 
			
		||||
	SiteScalarGaugeField  ScalarUmu;
 | 
			
		||||
	SiteDoubledGaugeField ScalarUds;
 | 
			
		||||
 | 
			
		||||
        GaugeLinkField U   (Umu._grid);
 | 
			
		||||
	GaugeField     Uadj(Umu._grid);
 | 
			
		||||
        for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
  	  U = PeekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
	  U = adj(Cshift(U,mu,-1));
 | 
			
		||||
	  PokeIndex<LorentzIndex>(Uadj,U,mu);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for(int lidx=0;lidx<GaugeGrid->lSites();lidx++){
 | 
			
		||||
	  std::vector<int> lcoor;
 | 
			
		||||
	  GaugeGrid->LocalIndexToLocalCoor(lidx,lcoor);
 | 
			
		||||
 | 
			
		||||
	  peekLocalSite(ScalarUmu,Umu,lcoor);
 | 
			
		||||
	  for(int mu=0;mu<4;mu++) ScalarUds(mu) = ScalarUmu(mu);
 | 
			
		||||
 | 
			
		||||
	  peekLocalSite(ScalarUmu,Uadj,lcoor);
 | 
			
		||||
	  for(int mu=0;mu<4;mu++) ScalarUds(mu+4) = ScalarUmu(mu);
 | 
			
		||||
 | 
			
		||||
	  pokeLocalSite(ScalarUds,Uds,lcoor);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
	
 | 
			
		||||
      inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A,int mu){
 | 
			
		||||
	assert(0);
 | 
			
		||||
      }   
 | 
			
		||||
 | 
			
		||||
      inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã,int mu){
 | 
			
		||||
	assert(0);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Flavour doubled spinors; is Gparity the only? what about C*?
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
    template<class S,int Nrepresentation>
 | 
			
		||||
    class GparityWilsonImpl : public ConjugateGaugeImpl< GaugeImplTypes<S,Nrepresentation> >{ 
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      typedef ConjugateGaugeImpl< GaugeImplTypes<S,Nrepresentation> > Gimpl;
 | 
			
		||||
 | 
			
		||||
      INHERIT_GIMPL_TYPES(Gimpl);
 | 
			
		||||
 | 
			
		||||
      template<typename vtype> using iImplSpinor             = 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 iImplHalfSpinor<Simd>           SiteHalfSpinor;
 | 
			
		||||
      typedef iImplDoubledGaugeField<Simd>    SiteDoubledGaugeField;
 | 
			
		||||
 | 
			
		||||
      typedef Lattice<SiteSpinor>                 FermionField;
 | 
			
		||||
      typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
 | 
			
		||||
 | 
			
		||||
      typedef WilsonCompressor<SiteHalfSpinor,SiteSpinor> Compressor;
 | 
			
		||||
      typedef WilsonStencil<SiteSpinor,SiteHalfSpinor> StencilImpl;
 | 
			
		||||
 | 
			
		||||
      typedef GparityWilsonImplParams ImplParams;
 | 
			
		||||
 | 
			
		||||
      ImplParams Params;
 | 
			
		||||
 | 
			
		||||
      GparityWilsonImpl(const ImplParams &p= ImplParams()) : Params(p) {}; 
 | 
			
		||||
      
 | 
			
		||||
      bool overlapCommsCompute(void) { return Params.overlapCommsCompute; };
 | 
			
		||||
 | 
			
		||||
      // provide the multiply by link that is differentiated between Gparity (with 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 typename SiteHalfSpinor::scalar_object sobj;
 | 
			
		||||
 | 
			
		||||
	vobj vtmp;
 | 
			
		||||
	sobj stmp;
 | 
			
		||||
	
 | 
			
		||||
	GridBase *grid = St._grid;
 | 
			
		||||
      
 | 
			
		||||
	const int Nsimd = grid->Nsimd();
 | 
			
		||||
	
 | 
			
		||||
	int direction    = St._directions[mu];
 | 
			
		||||
	int distance     = St._distances[mu];
 | 
			
		||||
	int ptype        = St._permute_type[mu]; 
 | 
			
		||||
	int sl           = St._grid->_simd_layout[direction];
 | 
			
		||||
 | 
			
		||||
	// Fixme X.Y.Z.T hardcode in stencil
 | 
			
		||||
	int mmu          = mu % Nd;
 | 
			
		||||
 | 
			
		||||
	// assert our assumptions
 | 
			
		||||
	assert((distance==1)||(distance==-1)); // nearest neighbour stencil hard code
 | 
			
		||||
	assert((sl==1)||(sl==2));
 | 
			
		||||
	
 | 
			
		||||
	std::vector<int> icoor;
 | 
			
		||||
      
 | 
			
		||||
	if ( SE->_around_the_world && Params.twists[mmu] ) {
 | 
			
		||||
 | 
			
		||||
	  if ( sl == 2 ) {
 | 
			
		||||
 | 
			
		||||
	    std::vector<sobj> vals(Nsimd);
 | 
			
		||||
 | 
			
		||||
	    extract(chi,vals);
 | 
			
		||||
	    for(int s=0;s<Nsimd;s++){
 | 
			
		||||
 | 
			
		||||
	      grid->iCoorFromIindex(icoor,s);
 | 
			
		||||
	      
 | 
			
		||||
	      assert((icoor[direction]==0)||(icoor[direction]==1));
 | 
			
		||||
	      
 | 
			
		||||
	      int permute_lane;
 | 
			
		||||
	      if ( distance == 1) {
 | 
			
		||||
		permute_lane = icoor[direction]?1:0;
 | 
			
		||||
	      } else {
 | 
			
		||||
		permute_lane = icoor[direction]?0:1;
 | 
			
		||||
	      }
 | 
			
		||||
	      
 | 
			
		||||
	      if ( permute_lane ) { 
 | 
			
		||||
		stmp(0) = vals[s](1);
 | 
			
		||||
		stmp(1) = vals[s](0);
 | 
			
		||||
		vals[s] = stmp;
 | 
			
		||||
	      }
 | 
			
		||||
	    }
 | 
			
		||||
	    merge(vtmp,vals);
 | 
			
		||||
 | 
			
		||||
	  } else { 
 | 
			
		||||
	    vtmp(0) = chi(1);
 | 
			
		||||
	    vtmp(1) = chi(0);
 | 
			
		||||
	  }
 | 
			
		||||
	  mult(&phi(0),&U(0)(mu),&vtmp(0));
 | 
			
		||||
	  mult(&phi(1),&U(1)(mu),&vtmp(1));
 | 
			
		||||
	  
 | 
			
		||||
	} else { 
 | 
			
		||||
	  mult(&phi(0),&U(0)(mu),&chi(0));
 | 
			
		||||
	  mult(&phi(1),&U(1)(mu),&chi(1));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu)
 | 
			
		||||
      {
 | 
			
		||||
	
 | 
			
		||||
	conformable(Uds._grid,GaugeGrid);
 | 
			
		||||
	conformable(Umu._grid,GaugeGrid);
 | 
			
		||||
	
 | 
			
		||||
	GaugeLinkField Utmp (GaugeGrid);
 | 
			
		||||
	GaugeLinkField U    (GaugeGrid);
 | 
			
		||||
	GaugeLinkField Uconj(GaugeGrid);
 | 
			
		||||
	
 | 
			
		||||
	Lattice<iScalar<vInteger> > coor(GaugeGrid);
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
	  
 | 
			
		||||
	  LatticeCoordinate(coor,mu);
 | 
			
		||||
	  
 | 
			
		||||
	  U     = PeekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
	  Uconj = conjugate(U);
 | 
			
		||||
 | 
			
		||||
	  // This phase could come from a simple bc 1,1,-1,1 ..
 | 
			
		||||
	  int neglink = GaugeGrid->GlobalDimensions()[mu]-1;
 | 
			
		||||
	  if ( Params.twists[mu] ) { 
 | 
			
		||||
	    Uconj = where(coor==neglink,-Uconj,Uconj);
 | 
			
		||||
	  }
 | 
			
		||||
 | 
			
		||||
	  
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
	  for(auto ss=U.begin();ss<U.end();ss++){
 | 
			
		||||
	    Uds[ss](0)(mu) = U[ss]();
 | 
			
		||||
	    Uds[ss](1)(mu) = Uconj[ss]();
 | 
			
		||||
	  }
 | 
			
		||||
	  
 | 
			
		||||
	  U     = adj(Cshift(U    ,mu,-1));      // correct except for spanning the boundary
 | 
			
		||||
	  Uconj = adj(Cshift(Uconj,mu,-1));
 | 
			
		||||
	  
 | 
			
		||||
	  Utmp = U;
 | 
			
		||||
	  if ( Params.twists[mu] ) { 
 | 
			
		||||
	    Utmp = where(coor==0,Uconj,Utmp);
 | 
			
		||||
	  }
 | 
			
		||||
	  
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
	  for(auto ss=U.begin();ss<U.end();ss++){
 | 
			
		||||
	    Uds[ss](0)(mu+4) = Utmp[ss]();
 | 
			
		||||
	  }
 | 
			
		||||
	  
 | 
			
		||||
	  Utmp = Uconj;
 | 
			
		||||
	  if ( Params.twists[mu] ) { 
 | 
			
		||||
	    Utmp = where(coor==0,U,Utmp);
 | 
			
		||||
	  }
 | 
			
		||||
	  
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
	  for(auto ss=U.begin();ss<U.end();ss++){
 | 
			
		||||
	    Uds[ss](1)(mu+4) = Utmp[ss]();
 | 
			
		||||
	  }
 | 
			
		||||
	  
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A,int mu){
 | 
			
		||||
	
 | 
			
		||||
	// DhopDir provides U or Uconj depending on coor/flavour.
 | 
			
		||||
	GaugeLinkField link(mat._grid);
 | 
			
		||||
	// use lorentz for flavour as hack.
 | 
			
		||||
	auto tmp = TraceIndex<SpinIndex>(outerProduct(Btilde,A));  
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
        for(auto ss=tmp.begin();ss<tmp.end();ss++){
 | 
			
		||||
	  link[ss]() = tmp[ss](0,0) - conjugate(tmp[ss](1,1)) ;
 | 
			
		||||
	}
 | 
			
		||||
	PokeIndex<LorentzIndex>(mat,link,mu);
 | 
			
		||||
	return;
 | 
			
		||||
      }
 | 
			
		||||
      inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã,int mu){
 | 
			
		||||
 | 
			
		||||
	int Ls=Btilde._grid->_fdimensions[0];
 | 
			
		||||
 | 
			
		||||
	GaugeLinkField tmp(mat._grid);
 | 
			
		||||
	tmp = zero;
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
	for(int ss=0;ss<tmp._grid->oSites();ss++){
 | 
			
		||||
	  for(int s=0;s<Ls;s++){
 | 
			
		||||
	    int sF = s+Ls*ss;
 | 
			
		||||
	    auto ttmp = traceIndex<SpinIndex>(outerProduct(Btilde[sF],Atilde[sF]));
 | 
			
		||||
	    tmp[ss]() = tmp[ss]()+ ttmp(0,0) + conjugate(ttmp(1,1));
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
	PokeIndex<LorentzIndex>(mat,tmp,mu);
 | 
			
		||||
	return;
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef WilsonImpl<vComplex ,Nc> WilsonImplR; // Real.. whichever prec
 | 
			
		||||
    typedef WilsonImpl<vComplexF,Nc> WilsonImplF; // Float
 | 
			
		||||
    typedef WilsonImpl<vComplexD,Nc> WilsonImplD; // Double
 | 
			
		||||
 | 
			
		||||
    typedef DomainWallRedBlack5dImpl<vComplex ,Nc> DomainWallRedBlack5dImplR; // Real.. whichever prec
 | 
			
		||||
    typedef DomainWallRedBlack5dImpl<vComplexF,Nc> DomainWallRedBlack5dImplF; // Float
 | 
			
		||||
    typedef DomainWallRedBlack5dImpl<vComplexD,Nc> DomainWallRedBlack5dImplD; // Double
 | 
			
		||||
 | 
			
		||||
    typedef GparityWilsonImpl<vComplex ,Nc> GparityWilsonImplR; // Real.. whichever prec
 | 
			
		||||
    typedef GparityWilsonImpl<vComplexF,Nc> GparityWilsonImplF; // Float
 | 
			
		||||
    typedef GparityWilsonImpl<vComplexD,Nc> GparityWilsonImplD; // Double
 | 
			
		||||
 | 
			
		||||
  INHERIT_GIMPL_TYPES(Base)      \
 | 
			
		||||
  INHERIT_FIMPL_TYPES(Base)
 | 
			
		||||
 | 
			
		||||
///////
 | 
			
		||||
// Single flavour four spinors with colour index
 | 
			
		||||
///////
 | 
			
		||||
template <class S, int Nrepresentation = Nc>
 | 
			
		||||
class WilsonImpl
 | 
			
		||||
    : public PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > {
 | 
			
		||||
 public:
 | 
			
		||||
  typedef PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > Gimpl;
 | 
			
		||||
 | 
			
		||||
  INHERIT_GIMPL_TYPES(Gimpl);
 | 
			
		||||
 | 
			
		||||
  template <typename vtype>
 | 
			
		||||
  using iImplSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
 | 
			
		||||
  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 iImplHalfSpinor<Simd> SiteHalfSpinor;
 | 
			
		||||
  typedef iImplDoubledGaugeField<Simd> SiteDoubledGaugeField;
 | 
			
		||||
 | 
			
		||||
  typedef Lattice<SiteSpinor> FermionField;
 | 
			
		||||
  typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
 | 
			
		||||
 | 
			
		||||
  typedef WilsonCompressor<SiteHalfSpinor, SiteSpinor> Compressor;
 | 
			
		||||
  typedef WilsonImplParams ImplParams;
 | 
			
		||||
  typedef WilsonStencil<SiteSpinor, SiteHalfSpinor> StencilImpl;
 | 
			
		||||
 | 
			
		||||
  ImplParams Params;
 | 
			
		||||
 | 
			
		||||
  WilsonImpl(const ImplParams &p = ImplParams()) : Params(p){};
 | 
			
		||||
 | 
			
		||||
  bool overlapCommsCompute(void) { return Params.overlapCommsCompute; };
 | 
			
		||||
 | 
			
		||||
  inline void multLink(SiteHalfSpinor &phi, const SiteDoubledGaugeField &U,
 | 
			
		||||
                       const SiteHalfSpinor &chi, int mu, StencilEntry *SE,
 | 
			
		||||
                       StencilImpl &St) {
 | 
			
		||||
    mult(&phi(), &U(mu), &chi());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <class ref>
 | 
			
		||||
  inline void loadLinkElement(Simd ®, ref &memory) {
 | 
			
		||||
    reg = memory;
 | 
			
		||||
  }
 | 
			
		||||
  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 < Nd; mu++) {
 | 
			
		||||
      U = PeekIndex<LorentzIndex>(Umu, mu);
 | 
			
		||||
      PokeIndex<LorentzIndex>(Uds, U, mu);
 | 
			
		||||
      U = adj(Cshift(U, mu, -1));
 | 
			
		||||
      PokeIndex<LorentzIndex>(Uds, U, mu + 4);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void InsertForce4D(GaugeField &mat, FermionField &Btilde,
 | 
			
		||||
                            FermionField &A, int mu) {
 | 
			
		||||
    GaugeLinkField link(mat._grid);
 | 
			
		||||
    link = TraceIndex<SpinIndex>(outerProduct(Btilde, A));
 | 
			
		||||
    PokeIndex<LorentzIndex>(mat, link, mu);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void InsertForce5D(GaugeField &mat, FermionField &Btilde,
 | 
			
		||||
                            FermionField Ã, int mu) {
 | 
			
		||||
    int Ls = Btilde._grid->_fdimensions[0];
 | 
			
		||||
 | 
			
		||||
    GaugeLinkField tmp(mat._grid);
 | 
			
		||||
    tmp = zero;
 | 
			
		||||
    PARALLEL_FOR_LOOP
 | 
			
		||||
    for (int sss = 0; sss < tmp._grid->oSites(); sss++) {
 | 
			
		||||
      int sU = sss;
 | 
			
		||||
      for (int s = 0; s < Ls; s++) {
 | 
			
		||||
        int sF = s + Ls * sU;
 | 
			
		||||
        tmp[sU] = tmp[sU] + traceIndex<SpinIndex>(outerProduct(
 | 
			
		||||
                                Btilde[sF], Atilde[sF]));  // ordering here
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    PokeIndex<LorentzIndex>(mat, tmp, mu);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
///////
 | 
			
		||||
// Single flavour four spinors with colour index, 5d redblack
 | 
			
		||||
///////
 | 
			
		||||
template <class S, int Nrepresentation = Nc>
 | 
			
		||||
class DomainWallRedBlack5dImpl
 | 
			
		||||
    : public PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > {
 | 
			
		||||
 public:
 | 
			
		||||
  typedef PeriodicGaugeImpl<GaugeImplTypes<S, Nrepresentation> > Gimpl;
 | 
			
		||||
 | 
			
		||||
  INHERIT_GIMPL_TYPES(Gimpl);
 | 
			
		||||
 | 
			
		||||
  template <typename vtype>
 | 
			
		||||
  using iImplSpinor = iScalar<iVector<iVector<vtype, Nrepresentation>, Ns> >;
 | 
			
		||||
  template <typename vtype>
 | 
			
		||||
  using iImplHalfSpinor =
 | 
			
		||||
      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 iImplHalfSpinor<Simd> SiteHalfSpinor;
 | 
			
		||||
  typedef Lattice<SiteSpinor> FermionField;
 | 
			
		||||
 | 
			
		||||
  // Make the doubled gauge field a *scalar*
 | 
			
		||||
  typedef iImplDoubledGaugeField<typename Simd::scalar_type>
 | 
			
		||||
      SiteDoubledGaugeField;  // This is a scalar
 | 
			
		||||
  typedef iImplGaugeField<typename Simd::scalar_type>
 | 
			
		||||
      SiteScalarGaugeField;  // scalar
 | 
			
		||||
  typedef iImplGaugeLink<typename Simd::scalar_type>
 | 
			
		||||
      SiteScalarGaugeLink;  // scalar
 | 
			
		||||
 | 
			
		||||
  typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
 | 
			
		||||
 | 
			
		||||
  typedef WilsonCompressor<SiteHalfSpinor, SiteSpinor> Compressor;
 | 
			
		||||
  typedef WilsonImplParams ImplParams;
 | 
			
		||||
  typedef WilsonStencil<SiteSpinor, SiteHalfSpinor> StencilImpl;
 | 
			
		||||
 | 
			
		||||
  ImplParams Params;
 | 
			
		||||
 | 
			
		||||
  DomainWallRedBlack5dImpl(const ImplParams &p = ImplParams()) : Params(p){};
 | 
			
		||||
 | 
			
		||||
  bool overlapCommsCompute(void) { return false; };
 | 
			
		||||
 | 
			
		||||
  template <class ref>
 | 
			
		||||
  inline void loadLinkElement(Simd ®, ref &memory) {
 | 
			
		||||
    vsplat(reg, memory);
 | 
			
		||||
  }
 | 
			
		||||
  inline void multLink(SiteHalfSpinor &phi, const SiteDoubledGaugeField &U,
 | 
			
		||||
                       const SiteHalfSpinor &chi, int mu, StencilEntry *SE,
 | 
			
		||||
                       StencilImpl &St) {
 | 
			
		||||
    SiteGaugeLink UU;
 | 
			
		||||
    for (int i = 0; i < Nrepresentation; i++) {
 | 
			
		||||
      for (int j = 0; j < Nrepresentation; j++) {
 | 
			
		||||
        vsplat(UU()()(i, j), U(mu)()(i, j));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    mult(&phi(), &UU(), &chi());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void DoubleStore(GridBase *GaugeGrid, DoubledGaugeField &Uds,
 | 
			
		||||
                          const GaugeField &Umu) {
 | 
			
		||||
    SiteScalarGaugeField ScalarUmu;
 | 
			
		||||
    SiteDoubledGaugeField ScalarUds;
 | 
			
		||||
 | 
			
		||||
    GaugeLinkField U(Umu._grid);
 | 
			
		||||
    GaugeField Uadj(Umu._grid);
 | 
			
		||||
    for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
      U = PeekIndex<LorentzIndex>(Umu, mu);
 | 
			
		||||
      U = adj(Cshift(U, mu, -1));
 | 
			
		||||
      PokeIndex<LorentzIndex>(Uadj, U, mu);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int lidx = 0; lidx < GaugeGrid->lSites(); lidx++) {
 | 
			
		||||
      std::vector<int> lcoor;
 | 
			
		||||
      GaugeGrid->LocalIndexToLocalCoor(lidx, lcoor);
 | 
			
		||||
 | 
			
		||||
      peekLocalSite(ScalarUmu, Umu, lcoor);
 | 
			
		||||
      for (int mu = 0; mu < 4; mu++) ScalarUds(mu) = ScalarUmu(mu);
 | 
			
		||||
 | 
			
		||||
      peekLocalSite(ScalarUmu, Uadj, lcoor);
 | 
			
		||||
      for (int mu = 0; mu < 4; mu++) ScalarUds(mu + 4) = ScalarUmu(mu);
 | 
			
		||||
 | 
			
		||||
      pokeLocalSite(ScalarUds, Uds, lcoor);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void InsertForce4D(GaugeField &mat, FermionField &Btilde,
 | 
			
		||||
                            FermionField &A, int mu) {
 | 
			
		||||
    assert(0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void InsertForce5D(GaugeField &mat, FermionField &Btilde,
 | 
			
		||||
                            FermionField Ã, int mu) {
 | 
			
		||||
    assert(0);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Flavour doubled spinors; is Gparity the only? what about C*?
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template <class S, int Nrepresentation>
 | 
			
		||||
class GparityWilsonImpl
 | 
			
		||||
    : public ConjugateGaugeImpl<GaugeImplTypes<S, Nrepresentation> > {
 | 
			
		||||
 public:
 | 
			
		||||
  typedef ConjugateGaugeImpl<GaugeImplTypes<S, Nrepresentation> > Gimpl;
 | 
			
		||||
 | 
			
		||||
  INHERIT_GIMPL_TYPES(Gimpl);
 | 
			
		||||
 | 
			
		||||
  template <typename vtype>
 | 
			
		||||
  using iImplSpinor =
 | 
			
		||||
      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 iImplHalfSpinor<Simd> SiteHalfSpinor;
 | 
			
		||||
  typedef iImplDoubledGaugeField<Simd> SiteDoubledGaugeField;
 | 
			
		||||
 | 
			
		||||
  typedef Lattice<SiteSpinor> FermionField;
 | 
			
		||||
  typedef Lattice<SiteDoubledGaugeField> DoubledGaugeField;
 | 
			
		||||
 | 
			
		||||
  typedef WilsonCompressor<SiteHalfSpinor, SiteSpinor> Compressor;
 | 
			
		||||
  typedef WilsonStencil<SiteSpinor, SiteHalfSpinor> StencilImpl;
 | 
			
		||||
 | 
			
		||||
  typedef GparityWilsonImplParams ImplParams;
 | 
			
		||||
 | 
			
		||||
  ImplParams Params;
 | 
			
		||||
 | 
			
		||||
  GparityWilsonImpl(const ImplParams &p = ImplParams()) : Params(p){};
 | 
			
		||||
 | 
			
		||||
  bool overlapCommsCompute(void) { return Params.overlapCommsCompute; };
 | 
			
		||||
 | 
			
		||||
  // provide the multiply by link that is differentiated between Gparity (with
 | 
			
		||||
  // 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 typename SiteHalfSpinor::scalar_object sobj;
 | 
			
		||||
 | 
			
		||||
    vobj vtmp;
 | 
			
		||||
    sobj stmp;
 | 
			
		||||
 | 
			
		||||
    GridBase *grid = St._grid;
 | 
			
		||||
 | 
			
		||||
    const int Nsimd = grid->Nsimd();
 | 
			
		||||
 | 
			
		||||
    int direction = St._directions[mu];
 | 
			
		||||
    int distance = St._distances[mu];
 | 
			
		||||
    int ptype = St._permute_type[mu];
 | 
			
		||||
    int sl = St._grid->_simd_layout[direction];
 | 
			
		||||
 | 
			
		||||
    // Fixme X.Y.Z.T hardcode in stencil
 | 
			
		||||
    int mmu = mu % Nd;
 | 
			
		||||
 | 
			
		||||
    // assert our assumptions
 | 
			
		||||
    assert((distance == 1) ||
 | 
			
		||||
           (distance == -1));  // nearest neighbour stencil hard code
 | 
			
		||||
    assert((sl == 1) || (sl == 2));
 | 
			
		||||
 | 
			
		||||
    std::vector<int> icoor;
 | 
			
		||||
 | 
			
		||||
    if (SE->_around_the_world && Params.twists[mmu]) {
 | 
			
		||||
      if (sl == 2) {
 | 
			
		||||
        std::vector<sobj> vals(Nsimd);
 | 
			
		||||
 | 
			
		||||
        extract(chi, vals);
 | 
			
		||||
        for (int s = 0; s < Nsimd; s++) {
 | 
			
		||||
          grid->iCoorFromIindex(icoor, s);
 | 
			
		||||
 | 
			
		||||
          assert((icoor[direction] == 0) || (icoor[direction] == 1));
 | 
			
		||||
 | 
			
		||||
          int permute_lane;
 | 
			
		||||
          if (distance == 1) {
 | 
			
		||||
            permute_lane = icoor[direction] ? 1 : 0;
 | 
			
		||||
          } else {
 | 
			
		||||
            permute_lane = icoor[direction] ? 0 : 1;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (permute_lane) {
 | 
			
		||||
            stmp(0) = vals[s](1);
 | 
			
		||||
            stmp(1) = vals[s](0);
 | 
			
		||||
            vals[s] = stmp;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        merge(vtmp, vals);
 | 
			
		||||
 | 
			
		||||
      } else {
 | 
			
		||||
        vtmp(0) = chi(1);
 | 
			
		||||
        vtmp(1) = chi(0);
 | 
			
		||||
      }
 | 
			
		||||
      mult(&phi(0), &U(0)(mu), &vtmp(0));
 | 
			
		||||
      mult(&phi(1), &U(1)(mu), &vtmp(1));
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
      mult(&phi(0), &U(0)(mu), &chi(0));
 | 
			
		||||
      mult(&phi(1), &U(1)(mu), &chi(1));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void DoubleStore(GridBase *GaugeGrid, DoubledGaugeField &Uds,
 | 
			
		||||
                          const GaugeField &Umu) {
 | 
			
		||||
    conformable(Uds._grid, GaugeGrid);
 | 
			
		||||
    conformable(Umu._grid, GaugeGrid);
 | 
			
		||||
 | 
			
		||||
    GaugeLinkField Utmp(GaugeGrid);
 | 
			
		||||
    GaugeLinkField U(GaugeGrid);
 | 
			
		||||
    GaugeLinkField Uconj(GaugeGrid);
 | 
			
		||||
 | 
			
		||||
    Lattice<iScalar<vInteger> > coor(GaugeGrid);
 | 
			
		||||
 | 
			
		||||
    for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
      LatticeCoordinate(coor, mu);
 | 
			
		||||
 | 
			
		||||
      U = PeekIndex<LorentzIndex>(Umu, mu);
 | 
			
		||||
      Uconj = conjugate(U);
 | 
			
		||||
 | 
			
		||||
      // This phase could come from a simple bc 1,1,-1,1 ..
 | 
			
		||||
      int neglink = GaugeGrid->GlobalDimensions()[mu] - 1;
 | 
			
		||||
      if (Params.twists[mu]) {
 | 
			
		||||
        Uconj = where(coor == neglink, -Uconj, Uconj);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      PARALLEL_FOR_LOOP
 | 
			
		||||
      for (auto ss = U.begin(); ss < U.end(); ss++) {
 | 
			
		||||
        Uds[ss](0)(mu) = U[ss]();
 | 
			
		||||
        Uds[ss](1)(mu) = Uconj[ss]();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      U = adj(Cshift(U, mu, -1));  // correct except for spanning the boundary
 | 
			
		||||
      Uconj = adj(Cshift(Uconj, mu, -1));
 | 
			
		||||
 | 
			
		||||
      Utmp = U;
 | 
			
		||||
      if (Params.twists[mu]) {
 | 
			
		||||
        Utmp = where(coor == 0, Uconj, Utmp);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      PARALLEL_FOR_LOOP
 | 
			
		||||
      for (auto ss = U.begin(); ss < U.end(); ss++) {
 | 
			
		||||
        Uds[ss](0)(mu + 4) = Utmp[ss]();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      Utmp = Uconj;
 | 
			
		||||
      if (Params.twists[mu]) {
 | 
			
		||||
        Utmp = where(coor == 0, U, Utmp);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      PARALLEL_FOR_LOOP
 | 
			
		||||
      for (auto ss = U.begin(); ss < U.end(); ss++) {
 | 
			
		||||
        Uds[ss](1)(mu + 4) = Utmp[ss]();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  inline void InsertForce4D(GaugeField &mat, FermionField &Btilde,
 | 
			
		||||
                            FermionField &A, int mu) {
 | 
			
		||||
    // DhopDir provides U or Uconj depending on coor/flavour.
 | 
			
		||||
    GaugeLinkField link(mat._grid);
 | 
			
		||||
    // use lorentz for flavour as hack.
 | 
			
		||||
    auto tmp = TraceIndex<SpinIndex>(outerProduct(Btilde, A));
 | 
			
		||||
    PARALLEL_FOR_LOOP
 | 
			
		||||
    for (auto ss = tmp.begin(); ss < tmp.end(); ss++) {
 | 
			
		||||
      link[ss]() = tmp[ss](0, 0) - conjugate(tmp[ss](1, 1));
 | 
			
		||||
    }
 | 
			
		||||
    PokeIndex<LorentzIndex>(mat, link, mu);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  inline void InsertForce5D(GaugeField &mat, FermionField &Btilde,
 | 
			
		||||
                            FermionField Ã, int mu) {
 | 
			
		||||
    int Ls = Btilde._grid->_fdimensions[0];
 | 
			
		||||
 | 
			
		||||
    GaugeLinkField tmp(mat._grid);
 | 
			
		||||
    tmp = zero;
 | 
			
		||||
    PARALLEL_FOR_LOOP
 | 
			
		||||
    for (int ss = 0; ss < tmp._grid->oSites(); ss++) {
 | 
			
		||||
      for (int s = 0; s < Ls; s++) {
 | 
			
		||||
        int sF = s + Ls * ss;
 | 
			
		||||
        auto ttmp = traceIndex<SpinIndex>(outerProduct(Btilde[sF], Atilde[sF]));
 | 
			
		||||
        tmp[ss]() = tmp[ss]() + ttmp(0, 0) + conjugate(ttmp(1, 1));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    PokeIndex<LorentzIndex>(mat, tmp, mu);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef WilsonImpl<vComplex, Nc> WilsonImplR;   // Real.. whichever prec
 | 
			
		||||
typedef WilsonImpl<vComplexF, Nc> WilsonImplF;  // Float
 | 
			
		||||
typedef WilsonImpl<vComplexD, Nc> WilsonImplD;  // Double
 | 
			
		||||
 | 
			
		||||
typedef DomainWallRedBlack5dImpl<vComplex, Nc>
 | 
			
		||||
    DomainWallRedBlack5dImplR;  // Real.. whichever prec
 | 
			
		||||
typedef DomainWallRedBlack5dImpl<vComplexF, Nc>
 | 
			
		||||
    DomainWallRedBlack5dImplF;  // Float
 | 
			
		||||
typedef DomainWallRedBlack5dImpl<vComplexD, Nc>
 | 
			
		||||
    DomainWallRedBlack5dImplD;  // Double
 | 
			
		||||
 | 
			
		||||
typedef GparityWilsonImpl<vComplex, Nc>
 | 
			
		||||
    GparityWilsonImplR;  // Real.. whichever prec
 | 
			
		||||
typedef GparityWilsonImpl<vComplexF, Nc> GparityWilsonImplF;  // Float
 | 
			
		||||
typedef GparityWilsonImpl<vComplexD, Nc> GparityWilsonImplD;  // Double
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,319 +1,313 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/qcd/action/fermion/WilsonFermion.cc
 | 
			
		||||
Source file: ./lib/qcd/action/fermion/WilsonFermion.cc
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
 | 
			
		||||
Author: paboyle <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 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.
 | 
			
		||||
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.
 | 
			
		||||
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
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
  const std::vector<int> WilsonFermionStatic::directions   ({0,1,2,3, 0, 1, 2, 3});
 | 
			
		||||
  const std::vector<int> WilsonFermionStatic::displacements({1,1,1,1,-1,-1,-1,-1});
 | 
			
		||||
  int WilsonFermionStatic::HandOptDslash;
 | 
			
		||||
const std::vector<int> WilsonFermionStatic::directions({0, 1, 2, 3, 0, 1, 2,
 | 
			
		||||
                                                        3});
 | 
			
		||||
const std::vector<int> WilsonFermionStatic::displacements({1, 1, 1, 1, -1, -1,
 | 
			
		||||
                                                           -1, -1});
 | 
			
		||||
int WilsonFermionStatic::HandOptDslash;
 | 
			
		||||
 | 
			
		||||
  /////////////////////////////////
 | 
			
		||||
  // Constructor and gauge import
 | 
			
		||||
  /////////////////////////////////
 | 
			
		||||
/////////////////////////////////
 | 
			
		||||
// Constructor and gauge import
 | 
			
		||||
/////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  WilsonFermion<Impl>::WilsonFermion(GaugeField &_Umu,
 | 
			
		||||
				     GridCartesian         &Fgrid,
 | 
			
		||||
				     GridRedBlackCartesian &Hgrid, 
 | 
			
		||||
				     RealD _mass,const ImplParams &p) :
 | 
			
		||||
        Kernels(p),
 | 
			
		||||
        _grid(&Fgrid),
 | 
			
		||||
	_cbgrid(&Hgrid),
 | 
			
		||||
	Stencil    (&Fgrid,npoint,Even,directions,displacements),
 | 
			
		||||
	StencilEven(&Hgrid,npoint,Even,directions,displacements), // source is Even
 | 
			
		||||
	StencilOdd (&Hgrid,npoint,Odd ,directions,displacements), // source is Odd
 | 
			
		||||
	mass(_mass),
 | 
			
		||||
	Lebesgue(_grid),
 | 
			
		||||
	LebesgueEvenOdd(_cbgrid),
 | 
			
		||||
	Umu(&Fgrid),
 | 
			
		||||
	UmuEven(&Hgrid),
 | 
			
		||||
	UmuOdd (&Hgrid) 
 | 
			
		||||
  {
 | 
			
		||||
    // Allocate the required comms buffer
 | 
			
		||||
    ImportGauge(_Umu);
 | 
			
		||||
template <class Impl>
 | 
			
		||||
WilsonFermion<Impl>::WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid,
 | 
			
		||||
                                   GridRedBlackCartesian &Hgrid, RealD _mass,
 | 
			
		||||
                                   const ImplParams &p)
 | 
			
		||||
    : Kernels(p),
 | 
			
		||||
      _grid(&Fgrid),
 | 
			
		||||
      _cbgrid(&Hgrid),
 | 
			
		||||
      Stencil(&Fgrid, npoint, Even, directions, displacements),
 | 
			
		||||
      StencilEven(&Hgrid, npoint, Even, directions,
 | 
			
		||||
                  displacements),  // source is Even
 | 
			
		||||
      StencilOdd(&Hgrid, npoint, Odd, directions,
 | 
			
		||||
                 displacements),  // source is Odd
 | 
			
		||||
      mass(_mass),
 | 
			
		||||
      Lebesgue(_grid),
 | 
			
		||||
      LebesgueEvenOdd(_cbgrid),
 | 
			
		||||
      Umu(&Fgrid),
 | 
			
		||||
      UmuEven(&Hgrid),
 | 
			
		||||
      UmuOdd(&Hgrid) {
 | 
			
		||||
  // Allocate the required comms buffer
 | 
			
		||||
  ImportGauge(_Umu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::ImportGauge(const GaugeField &_Umu) {
 | 
			
		||||
  GaugeField HUmu(_Umu._grid);
 | 
			
		||||
  HUmu = _Umu * (-0.5);
 | 
			
		||||
  Impl::DoubleStore(GaugeGrid(), Umu, HUmu);
 | 
			
		||||
  pickCheckerboard(Even, UmuEven, Umu);
 | 
			
		||||
  pickCheckerboard(Odd, UmuOdd, Umu);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////////////////////////////
 | 
			
		||||
// Implement the interface
 | 
			
		||||
/////////////////////////////
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
RealD WilsonFermion<Impl>::M(const FermionField &in, FermionField &out) {
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  Dhop(in, out, DaggerNo);
 | 
			
		||||
  return axpy_norm(out, 4 + mass, in, out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
RealD WilsonFermion<Impl>::Mdag(const FermionField &in, FermionField &out) {
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  Dhop(in, out, DaggerYes);
 | 
			
		||||
  return axpy_norm(out, 4 + mass, in, out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::Meooe(const FermionField &in, FermionField &out) {
 | 
			
		||||
  if (in.checkerboard == Odd) {
 | 
			
		||||
    DhopEO(in, out, DaggerNo);
 | 
			
		||||
  } else {
 | 
			
		||||
    DhopOE(in, out, DaggerNo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::ImportGauge(const GaugeField &_Umu)
 | 
			
		||||
  {
 | 
			
		||||
    GaugeField HUmu(_Umu._grid);
 | 
			
		||||
    HUmu = _Umu*(-0.5);
 | 
			
		||||
    Impl::DoubleStore(GaugeGrid(),Umu,HUmu);
 | 
			
		||||
    pickCheckerboard(Even,UmuEven,Umu);
 | 
			
		||||
    pickCheckerboard(Odd ,UmuOdd,Umu);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /////////////////////////////
 | 
			
		||||
  // Implement the interface
 | 
			
		||||
  /////////////////////////////
 | 
			
		||||
      
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  RealD WilsonFermion<Impl>::M(const FermionField &in, FermionField &out) 
 | 
			
		||||
  {
 | 
			
		||||
    out.checkerboard=in.checkerboard;
 | 
			
		||||
    Dhop(in,out,DaggerNo);
 | 
			
		||||
    return axpy_norm(out,4+mass,in,out);
 | 
			
		||||
}
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::MeooeDag(const FermionField &in, FermionField &out) {
 | 
			
		||||
  if (in.checkerboard == Odd) {
 | 
			
		||||
    DhopEO(in, out, DaggerYes);
 | 
			
		||||
  } else {
 | 
			
		||||
    DhopOE(in, out, DaggerYes);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  RealD WilsonFermion<Impl>::Mdag(const FermionField &in, FermionField &out) 
 | 
			
		||||
  {
 | 
			
		||||
    out.checkerboard=in.checkerboard;
 | 
			
		||||
    Dhop(in,out,DaggerYes);
 | 
			
		||||
    return axpy_norm(out,4+mass,in,out);
 | 
			
		||||
  }
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::Mooee(const FermionField &in, FermionField &out) {
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  typename FermionField::scalar_type scal(4.0 + mass);
 | 
			
		||||
  out = scal * in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::Meooe(const FermionField &in, FermionField &out) 
 | 
			
		||||
  {
 | 
			
		||||
    if ( in.checkerboard == Odd ) {
 | 
			
		||||
      DhopEO(in,out,DaggerNo);
 | 
			
		||||
    } else {
 | 
			
		||||
      DhopOE(in,out,DaggerNo);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::MeooeDag(const FermionField &in, FermionField &out) 
 | 
			
		||||
  {
 | 
			
		||||
    if ( in.checkerboard == Odd ) {
 | 
			
		||||
      DhopEO(in,out,DaggerYes);
 | 
			
		||||
    } else {
 | 
			
		||||
      DhopOE(in,out,DaggerYes);
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::MooeeDag(const FermionField &in, FermionField &out) {
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  Mooee(in, out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::MooeeInv(const FermionField &in, FermionField &out) {
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  out = (1.0 / (4.0 + mass)) * in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::MooeeInvDag(const FermionField &in,
 | 
			
		||||
                                      FermionField &out) {
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  MooeeInv(in, out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////
 | 
			
		||||
// Internal
 | 
			
		||||
///////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::DerivInternal(StencilImpl &st, DoubledGaugeField &U,
 | 
			
		||||
                                        GaugeField &mat, const FermionField &A,
 | 
			
		||||
                                        const FermionField &B, int dag) {
 | 
			
		||||
  assert((dag == DaggerNo) || (dag == DaggerYes));
 | 
			
		||||
 | 
			
		||||
  Compressor compressor(dag);
 | 
			
		||||
 | 
			
		||||
  FermionField Btilde(B._grid);
 | 
			
		||||
  FermionField Atilde(B._grid);
 | 
			
		||||
  Atilde = A;
 | 
			
		||||
 | 
			
		||||
  st.HaloExchange(B, compressor);
 | 
			
		||||
 | 
			
		||||
  for (int mu = 0; mu < Nd; mu++) {
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Flip gamma (1+g)<->(1-g) if dag
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    int gamma = mu;
 | 
			
		||||
    if (!dag) gamma += Nd;
 | 
			
		||||
 | 
			
		||||
    ////////////////////////
 | 
			
		||||
    // Call the single hop
 | 
			
		||||
    ////////////////////////
 | 
			
		||||
    PARALLEL_FOR_LOOP
 | 
			
		||||
    for (int sss = 0; sss < B._grid->oSites(); sss++) {
 | 
			
		||||
      Kernels::DiracOptDhopDir(st, U, st.comm_buf, sss, sss, B, Btilde, mu,
 | 
			
		||||
                               gamma);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////////////////////////
 | 
			
		||||
    // spin trace outer product
 | 
			
		||||
    //////////////////////////////////////////////////
 | 
			
		||||
    Impl::InsertForce4D(mat, Btilde, Atilde, mu);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::DhopDeriv(GaugeField &mat, const FermionField &U,
 | 
			
		||||
                                    const FermionField &V, int dag) {
 | 
			
		||||
  conformable(U._grid, _grid);
 | 
			
		||||
  conformable(U._grid, V._grid);
 | 
			
		||||
  conformable(U._grid, mat._grid);
 | 
			
		||||
 | 
			
		||||
  mat.checkerboard = U.checkerboard;
 | 
			
		||||
 | 
			
		||||
  DerivInternal(Stencil, Umu, mat, U, V, dag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::DhopDerivOE(GaugeField &mat, const FermionField &U,
 | 
			
		||||
                                      const FermionField &V, int dag) {
 | 
			
		||||
  conformable(U._grid, _cbgrid);
 | 
			
		||||
  conformable(U._grid, V._grid);
 | 
			
		||||
  conformable(U._grid, mat._grid);
 | 
			
		||||
 | 
			
		||||
  assert(V.checkerboard == Even);
 | 
			
		||||
  assert(U.checkerboard == Odd);
 | 
			
		||||
  mat.checkerboard = Odd;
 | 
			
		||||
 | 
			
		||||
  DerivInternal(StencilEven, UmuOdd, mat, U, V, dag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::DhopDerivEO(GaugeField &mat, const FermionField &U,
 | 
			
		||||
                                      const FermionField &V, int dag) {
 | 
			
		||||
  conformable(U._grid, _cbgrid);
 | 
			
		||||
  conformable(U._grid, V._grid);
 | 
			
		||||
  conformable(U._grid, mat._grid);
 | 
			
		||||
 | 
			
		||||
  assert(V.checkerboard == Odd);
 | 
			
		||||
  assert(U.checkerboard == Even);
 | 
			
		||||
  mat.checkerboard = Even;
 | 
			
		||||
 | 
			
		||||
  DerivInternal(StencilOdd, UmuEven, mat, U, V, dag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::Dhop(const FermionField &in, FermionField &out,
 | 
			
		||||
                               int dag) {
 | 
			
		||||
  conformable(in._grid, _grid);  // verifies full grid
 | 
			
		||||
  conformable(in._grid, out._grid);
 | 
			
		||||
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(Stencil, Lebesgue, Umu, in, out, dag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::DhopOE(const FermionField &in, FermionField &out,
 | 
			
		||||
                                 int dag) {
 | 
			
		||||
  conformable(in._grid, _cbgrid);    // verifies half grid
 | 
			
		||||
  conformable(in._grid, out._grid);  // drops the cb check
 | 
			
		||||
 | 
			
		||||
  assert(in.checkerboard == Even);
 | 
			
		||||
  out.checkerboard = Odd;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(StencilEven, LebesgueEvenOdd, UmuOdd, in, out, dag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::DhopEO(const FermionField &in, FermionField &out,
 | 
			
		||||
                                 int dag) {
 | 
			
		||||
  conformable(in._grid, _cbgrid);    // verifies half grid
 | 
			
		||||
  conformable(in._grid, out._grid);  // drops the cb check
 | 
			
		||||
 | 
			
		||||
  assert(in.checkerboard == Odd);
 | 
			
		||||
  out.checkerboard = Even;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(StencilOdd, LebesgueEvenOdd, UmuEven, in, out, dag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::Mdir(const FermionField &in, FermionField &out,
 | 
			
		||||
                               int dir, int disp) {
 | 
			
		||||
  DhopDir(in, out, dir, disp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::DhopDir(const FermionField &in, FermionField &out,
 | 
			
		||||
                                  int dir, int disp) {
 | 
			
		||||
  int skip = (disp == 1) ? 0 : 1;
 | 
			
		||||
  int dirdisp = dir + skip * 4;
 | 
			
		||||
  int gamma = dir + (1 - skip) * 4;
 | 
			
		||||
 | 
			
		||||
  DhopDirDisp(in, out, dirdisp, gamma, DaggerNo);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::DhopDirDisp(const FermionField &in, FermionField &out,
 | 
			
		||||
                                      int dirdisp, int gamma, int dag) {
 | 
			
		||||
  Compressor compressor(dag);
 | 
			
		||||
 | 
			
		||||
  Stencil.HaloExchange(in, compressor);
 | 
			
		||||
 | 
			
		||||
  PARALLEL_FOR_LOOP
 | 
			
		||||
  for (int sss = 0; sss < in._grid->oSites(); sss++) {
 | 
			
		||||
    Kernels::DiracOptDhopDir(Stencil, Umu, Stencil.comm_buf, sss, sss, in, out,
 | 
			
		||||
                             dirdisp, gamma);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class Impl>
 | 
			
		||||
void WilsonFermion<Impl>::DhopInternal(StencilImpl &st, LebesgueOrder &lo,
 | 
			
		||||
                                       DoubledGaugeField &U,
 | 
			
		||||
                                       const FermionField &in,
 | 
			
		||||
                                       FermionField &out, int dag) {
 | 
			
		||||
  assert((dag == DaggerNo) || (dag == DaggerYes));
 | 
			
		||||
 | 
			
		||||
  Compressor compressor(dag);
 | 
			
		||||
  st.HaloExchange(in, compressor);
 | 
			
		||||
 | 
			
		||||
  if (dag == DaggerYes) {
 | 
			
		||||
    PARALLEL_FOR_LOOP
 | 
			
		||||
    for (int sss = 0; sss < in._grid->oSites(); sss++) {
 | 
			
		||||
      Kernels::DiracOptDhopSiteDag(st, lo, U, st.comm_buf, sss, sss, 1, 1, in,
 | 
			
		||||
                                   out);
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    PARALLEL_FOR_LOOP
 | 
			
		||||
    for (int sss = 0; sss < in._grid->oSites(); sss++) {
 | 
			
		||||
      Kernels::DiracOptDhopSite(st, lo, U, st.comm_buf, sss, sss, 1, 1, in,
 | 
			
		||||
                                out);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::Mooee(const FermionField &in, FermionField &out) {
 | 
			
		||||
    out.checkerboard = in.checkerboard;
 | 
			
		||||
    typename FermionField::scalar_type scal(4.0+mass);
 | 
			
		||||
    out = scal*in;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::MooeeDag(const FermionField &in, FermionField &out) {
 | 
			
		||||
    out.checkerboard = in.checkerboard;
 | 
			
		||||
    Mooee(in,out);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::MooeeInv(const FermionField &in, FermionField &out) {
 | 
			
		||||
    out.checkerboard = in.checkerboard;
 | 
			
		||||
    out = (1.0/(4.0+mass))*in;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::MooeeInvDag(const FermionField &in, FermionField &out) {
 | 
			
		||||
    out.checkerboard = in.checkerboard;
 | 
			
		||||
    MooeeInv(in,out);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  ///////////////////////////////////
 | 
			
		||||
  // Internal
 | 
			
		||||
  ///////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::DerivInternal(StencilImpl & st,
 | 
			
		||||
					  DoubledGaugeField & U,
 | 
			
		||||
					  GaugeField &mat,
 | 
			
		||||
					  const FermionField &A,
 | 
			
		||||
					  const FermionField &B,int dag) {
 | 
			
		||||
	
 | 
			
		||||
    assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
			
		||||
    
 | 
			
		||||
    Compressor compressor(dag);
 | 
			
		||||
    
 | 
			
		||||
    FermionField Btilde(B._grid);
 | 
			
		||||
    FermionField Atilde(B._grid);
 | 
			
		||||
    Atilde = A;
 | 
			
		||||
 | 
			
		||||
    st.HaloExchange(B,compressor);
 | 
			
		||||
    
 | 
			
		||||
    for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
      
 | 
			
		||||
      ////////////////////////////////////////////////////////////////////////
 | 
			
		||||
      // Flip gamma (1+g)<->(1-g) if dag
 | 
			
		||||
      ////////////////////////////////////////////////////////////////////////
 | 
			
		||||
      int gamma = mu;
 | 
			
		||||
      if ( !dag ) gamma+= Nd;
 | 
			
		||||
      
 | 
			
		||||
      ////////////////////////
 | 
			
		||||
      // Call the single hop
 | 
			
		||||
      ////////////////////////
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
	for(int sss=0;sss<B._grid->oSites();sss++){
 | 
			
		||||
	  Kernels::DiracOptDhopDir(st,U,st.comm_buf,sss,sss,B,Btilde,mu,gamma);
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      //////////////////////////////////////////////////
 | 
			
		||||
      // spin trace outer product
 | 
			
		||||
      //////////////////////////////////////////////////
 | 
			
		||||
      Impl::InsertForce4D(mat,Btilde,Atilde,mu);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::DhopDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag)
 | 
			
		||||
  {
 | 
			
		||||
    conformable(U._grid,_grid);  
 | 
			
		||||
    conformable(U._grid,V._grid);
 | 
			
		||||
    conformable(U._grid,mat._grid);
 | 
			
		||||
    
 | 
			
		||||
    mat.checkerboard = U.checkerboard;
 | 
			
		||||
    
 | 
			
		||||
    DerivInternal(Stencil,Umu,mat,U,V,dag);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::DhopDerivOE(GaugeField &mat,const FermionField &U,const FermionField &V,int dag)
 | 
			
		||||
  {
 | 
			
		||||
    conformable(U._grid,_cbgrid);  
 | 
			
		||||
    conformable(U._grid,V._grid);
 | 
			
		||||
    conformable(U._grid,mat._grid);
 | 
			
		||||
    
 | 
			
		||||
    assert(V.checkerboard==Even);
 | 
			
		||||
    assert(U.checkerboard==Odd);
 | 
			
		||||
    mat.checkerboard = Odd;
 | 
			
		||||
    
 | 
			
		||||
    DerivInternal(StencilEven,UmuOdd,mat,U,V,dag);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::DhopDerivEO(GaugeField &mat,const FermionField &U,const FermionField &V,int dag)
 | 
			
		||||
  {
 | 
			
		||||
    conformable(U._grid,_cbgrid);  
 | 
			
		||||
    conformable(U._grid,V._grid);
 | 
			
		||||
    conformable(U._grid,mat._grid);
 | 
			
		||||
	
 | 
			
		||||
    assert(V.checkerboard==Odd);
 | 
			
		||||
    assert(U.checkerboard==Even);
 | 
			
		||||
    mat.checkerboard = Even;
 | 
			
		||||
	
 | 
			
		||||
    DerivInternal(StencilOdd,UmuEven,mat,U,V,dag);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::Dhop(const FermionField &in, FermionField &out,int dag) {
 | 
			
		||||
    conformable(in._grid,_grid); // verifies full grid
 | 
			
		||||
    conformable(in._grid,out._grid);
 | 
			
		||||
    
 | 
			
		||||
    out.checkerboard = in.checkerboard;
 | 
			
		||||
    
 | 
			
		||||
    DhopInternal(Stencil,Lebesgue,Umu,in,out,dag);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::DhopOE(const FermionField &in, FermionField &out,int dag) {
 | 
			
		||||
    conformable(in._grid,_cbgrid);    // verifies half grid
 | 
			
		||||
    conformable(in._grid,out._grid); // drops the cb check
 | 
			
		||||
    
 | 
			
		||||
    assert(in.checkerboard==Even);
 | 
			
		||||
    out.checkerboard = Odd;
 | 
			
		||||
    
 | 
			
		||||
    DhopInternal(StencilEven,LebesgueEvenOdd,UmuOdd,in,out,dag);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::DhopEO(const FermionField &in, FermionField &out,int dag) {
 | 
			
		||||
    conformable(in._grid,_cbgrid);    // verifies half grid
 | 
			
		||||
    conformable(in._grid,out._grid); // drops the cb check
 | 
			
		||||
    
 | 
			
		||||
    assert(in.checkerboard==Odd);
 | 
			
		||||
    out.checkerboard = Even;
 | 
			
		||||
    
 | 
			
		||||
    DhopInternal(StencilOdd,LebesgueEvenOdd,UmuEven,in,out,dag);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::Mdir (const FermionField &in, FermionField &out,int dir,int disp) {
 | 
			
		||||
    DhopDir(in,out,dir,disp);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::DhopDir(const FermionField &in, FermionField &out,int dir,int disp){
 | 
			
		||||
    
 | 
			
		||||
    int skip = (disp==1) ? 0 : 1;
 | 
			
		||||
    int dirdisp  = dir+skip*4;
 | 
			
		||||
    int gamma    = dir+(1-skip)*4;
 | 
			
		||||
    
 | 
			
		||||
    DhopDirDisp(in,out,dirdisp,gamma,DaggerNo);
 | 
			
		||||
    
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::DhopDirDisp(const FermionField &in, FermionField &out,int dirdisp,int gamma,int dag) {
 | 
			
		||||
    
 | 
			
		||||
    Compressor compressor(dag);
 | 
			
		||||
    
 | 
			
		||||
    Stencil.HaloExchange(in,compressor);
 | 
			
		||||
    
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
	Kernels::DiracOptDhopDir(Stencil,Umu,Stencil.comm_buf,sss,sss,in,out,dirdisp,gamma);
 | 
			
		||||
      }
 | 
			
		||||
    
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template<class Impl>
 | 
			
		||||
  void WilsonFermion<Impl>::DhopInternal(StencilImpl & st,LebesgueOrder& lo,DoubledGaugeField & U,
 | 
			
		||||
					 const FermionField &in, FermionField &out,int dag) 
 | 
			
		||||
  {
 | 
			
		||||
    assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
			
		||||
 | 
			
		||||
    Compressor compressor(dag);
 | 
			
		||||
    st.HaloExchange(in,compressor);
 | 
			
		||||
    
 | 
			
		||||
    if ( dag == DaggerYes ) {
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
	Kernels::DiracOptDhopSiteDag(st,lo,U,st.comm_buf,sss,sss,1,1,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
	Kernels::DiracOptDhopSite(st,lo,U,st.comm_buf,sss,sss,1,1,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
  FermOpTemplateInstantiate(WilsonFermion);
 | 
			
		||||
  GparityFermOpTemplateInstantiate(WilsonFermion);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FermOpTemplateInstantiate(WilsonFermion);
 | 
			
		||||
GparityFermOpTemplateInstantiate(WilsonFermion);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,161 +1,153 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/qcd/action/fermion/WilsonFermion.h
 | 
			
		||||
Source file: ./lib/qcd/action/fermion/WilsonFermion.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: paboyle <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 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.
 | 
			
		||||
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.
 | 
			
		||||
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
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#ifndef  GRID_QCD_WILSON_FERMION_H
 | 
			
		||||
#define  GRID_QCD_WILSON_FERMION_H
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_QCD_WILSON_FERMION_H
 | 
			
		||||
#define GRID_QCD_WILSON_FERMION_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class WilsonFermionStatic {
 | 
			
		||||
    public:
 | 
			
		||||
      static int HandOptDslash; // these are a temporary hack
 | 
			
		||||
      static int MortonOrder;
 | 
			
		||||
      static const std::vector<int> directions   ;
 | 
			
		||||
      static const std::vector<int> displacements;
 | 
			
		||||
      static const int npoint=8;
 | 
			
		||||
    };
 | 
			
		||||
class WilsonFermionStatic {
 | 
			
		||||
 public:
 | 
			
		||||
  static int HandOptDslash;  // these are a temporary hack
 | 
			
		||||
  static int MortonOrder;
 | 
			
		||||
  static const std::vector<int> directions;
 | 
			
		||||
  static const std::vector<int> displacements;
 | 
			
		||||
  static const int npoint = 8;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
    template<class Impl>
 | 
			
		||||
    class WilsonFermion : public WilsonKernels<Impl>, public WilsonFermionStatic
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
    INHERIT_IMPL_TYPES(Impl);
 | 
			
		||||
    typedef WilsonKernels<Impl> Kernels;
 | 
			
		||||
template <class Impl>
 | 
			
		||||
class WilsonFermion : public WilsonKernels<Impl>, public WilsonFermionStatic {
 | 
			
		||||
 public:
 | 
			
		||||
  INHERIT_IMPL_TYPES(Impl);
 | 
			
		||||
  typedef WilsonKernels<Impl> Kernels;
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Implement the abstract base
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      GridBase *GaugeGrid(void)              { return _grid ;}
 | 
			
		||||
      GridBase *GaugeRedBlackGrid(void)      { return _cbgrid ;}
 | 
			
		||||
      GridBase *FermionGrid(void)            { return _grid;}
 | 
			
		||||
      GridBase *FermionRedBlackGrid(void)    { return _cbgrid;}
 | 
			
		||||
  ///////////////////////////////////////////////////////////////
 | 
			
		||||
  // Implement the abstract base
 | 
			
		||||
  ///////////////////////////////////////////////////////////////
 | 
			
		||||
  GridBase *GaugeGrid(void) { return _grid; }
 | 
			
		||||
  GridBase *GaugeRedBlackGrid(void) { return _cbgrid; }
 | 
			
		||||
  GridBase *FermionGrid(void) { return _grid; }
 | 
			
		||||
  GridBase *FermionRedBlackGrid(void) { return _cbgrid; }
 | 
			
		||||
 | 
			
		||||
      //////////////////////////////////////////////////////////////////
 | 
			
		||||
      // override multiply; cut number routines if pass dagger argument
 | 
			
		||||
      // and also make interface more uniformly consistent
 | 
			
		||||
      //////////////////////////////////////////////////////////////////
 | 
			
		||||
      RealD M(const FermionField &in, FermionField &out);
 | 
			
		||||
      RealD Mdag(const FermionField &in, FermionField &out);
 | 
			
		||||
  //////////////////////////////////////////////////////////////////
 | 
			
		||||
  // override multiply; cut number routines if pass dagger argument
 | 
			
		||||
  // and also make interface more uniformly consistent
 | 
			
		||||
  //////////////////////////////////////////////////////////////////
 | 
			
		||||
  RealD M(const FermionField &in, FermionField &out);
 | 
			
		||||
  RealD Mdag(const FermionField &in, FermionField &out);
 | 
			
		||||
 | 
			
		||||
      /////////////////////////////////////////////////////////
 | 
			
		||||
      // half checkerboard operations
 | 
			
		||||
      // could remain virtual so we  can derive Clover from Wilson base
 | 
			
		||||
      /////////////////////////////////////////////////////////
 | 
			
		||||
      void Meooe(const FermionField &in, FermionField &out) ;
 | 
			
		||||
      void MeooeDag(const FermionField &in, FermionField &out) ;
 | 
			
		||||
  /////////////////////////////////////////////////////////
 | 
			
		||||
  // half checkerboard operations
 | 
			
		||||
  // could remain virtual so we  can derive Clover from Wilson base
 | 
			
		||||
  /////////////////////////////////////////////////////////
 | 
			
		||||
  void Meooe(const FermionField &in, FermionField &out);
 | 
			
		||||
  void MeooeDag(const FermionField &in, FermionField &out);
 | 
			
		||||
 | 
			
		||||
      // allow override for twisted mass and clover
 | 
			
		||||
      virtual void Mooee(const FermionField &in, FermionField &out) ;
 | 
			
		||||
      virtual void MooeeDag(const FermionField &in, FermionField &out) ;
 | 
			
		||||
      virtual void MooeeInv(const FermionField &in, FermionField &out) ;
 | 
			
		||||
      virtual void MooeeInvDag(const FermionField &in, FermionField &out) ;
 | 
			
		||||
  // allow override for twisted mass and clover
 | 
			
		||||
  virtual void Mooee(const FermionField &in, FermionField &out);
 | 
			
		||||
  virtual void MooeeDag(const FermionField &in, FermionField &out);
 | 
			
		||||
  virtual void MooeeInv(const FermionField &in, FermionField &out);
 | 
			
		||||
  virtual void MooeeInvDag(const FermionField &in, FermionField &out);
 | 
			
		||||
 | 
			
		||||
      ////////////////////////
 | 
			
		||||
      // Derivative interface
 | 
			
		||||
      ////////////////////////
 | 
			
		||||
      // Interface calls an internal routine
 | 
			
		||||
      void DhopDeriv(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);
 | 
			
		||||
  ////////////////////////
 | 
			
		||||
  // Derivative interface
 | 
			
		||||
  ////////////////////////
 | 
			
		||||
  // Interface calls an internal routine
 | 
			
		||||
  void DhopDeriv(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
 | 
			
		||||
  ///////////////////////////////////////////////////////////////
 | 
			
		||||
  void Dhop(const FermionField &in, FermionField &out, int dag);
 | 
			
		||||
  void DhopOE(const FermionField &in, FermionField &out, int dag);
 | 
			
		||||
  void DhopEO(const FermionField &in, FermionField &out, int dag);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // non-hermitian hopping term; half cb or both
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      void Dhop(const FermionField &in, FermionField &out,int dag) ;
 | 
			
		||||
      void DhopOE(const FermionField &in, FermionField &out,int dag) ;
 | 
			
		||||
      void DhopEO(const FermionField &in, FermionField &out,int dag) ;
 | 
			
		||||
  ///////////////////////////////////////////////////////////////
 | 
			
		||||
  // Multigrid assistance; force term uses too
 | 
			
		||||
  ///////////////////////////////////////////////////////////////
 | 
			
		||||
  void Mdir(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);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Multigrid assistance; force term uses too
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      void Mdir (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) ;
 | 
			
		||||
  ///////////////////////////////////////////////////////////////
 | 
			
		||||
  // Extra methods added by derived
 | 
			
		||||
  ///////////////////////////////////////////////////////////////
 | 
			
		||||
  void DerivInternal(StencilImpl &st, DoubledGaugeField &U, GaugeField &mat,
 | 
			
		||||
                     const FermionField &A, const FermionField &B, int dag);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Extra methods added by derived
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      void DerivInternal(StencilImpl & st,
 | 
			
		||||
			 DoubledGaugeField & U,
 | 
			
		||||
			 GaugeField &mat,
 | 
			
		||||
			 const FermionField &A,
 | 
			
		||||
			 const FermionField &B,
 | 
			
		||||
			 int dag);
 | 
			
		||||
  void DhopInternal(StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U,
 | 
			
		||||
                    const FermionField &in, FermionField &out, int dag);
 | 
			
		||||
 | 
			
		||||
      void DhopInternal(StencilImpl & st,LebesgueOrder & lo,DoubledGaugeField & U,
 | 
			
		||||
			const FermionField &in, FermionField &out,int dag) ;
 | 
			
		||||
  // Constructor
 | 
			
		||||
  WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid,
 | 
			
		||||
                GridRedBlackCartesian &Hgrid, RealD _mass,
 | 
			
		||||
                const ImplParams &p = ImplParams());
 | 
			
		||||
 | 
			
		||||
      // Constructor
 | 
			
		||||
      WilsonFermion(GaugeField &_Umu,
 | 
			
		||||
		    GridCartesian         &Fgrid,
 | 
			
		||||
		    GridRedBlackCartesian &Hgrid, 
 | 
			
		||||
		    RealD _mass,
 | 
			
		||||
		    const ImplParams &p= ImplParams()
 | 
			
		||||
		    ) ;
 | 
			
		||||
  // DoubleStore impl dependent
 | 
			
		||||
  void ImportGauge(const GaugeField &_Umu);
 | 
			
		||||
 | 
			
		||||
      // DoubleStore impl dependent
 | 
			
		||||
      void ImportGauge(const GaugeField &_Umu);
 | 
			
		||||
  ///////////////////////////////////////////////////////////////
 | 
			
		||||
  // Data members require to support the functionality
 | 
			
		||||
  ///////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Data members require to support the functionality
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
  //    protected:
 | 
			
		||||
 public:
 | 
			
		||||
  RealD mass;
 | 
			
		||||
 | 
			
		||||
      //    protected:
 | 
			
		||||
    public:
 | 
			
		||||
  GridBase *_grid;
 | 
			
		||||
  GridBase *_cbgrid;
 | 
			
		||||
 | 
			
		||||
      RealD                        mass;
 | 
			
		||||
  // Defines the stencils for even and odd
 | 
			
		||||
  StencilImpl Stencil;
 | 
			
		||||
  StencilImpl StencilEven;
 | 
			
		||||
  StencilImpl StencilOdd;
 | 
			
		||||
 | 
			
		||||
      GridBase                     *    _grid; 
 | 
			
		||||
      GridBase                     *  _cbgrid;
 | 
			
		||||
  // Copy of the gauge field , with even and odd subsets
 | 
			
		||||
  DoubledGaugeField Umu;
 | 
			
		||||
  DoubledGaugeField UmuEven;
 | 
			
		||||
  DoubledGaugeField UmuOdd;
 | 
			
		||||
 | 
			
		||||
      //Defines the stencils for even and odd
 | 
			
		||||
      StencilImpl Stencil; 
 | 
			
		||||
      StencilImpl StencilEven; 
 | 
			
		||||
      StencilImpl StencilOdd; 
 | 
			
		||||
  LebesgueOrder Lebesgue;
 | 
			
		||||
  LebesgueOrder LebesgueEvenOdd;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
      // Copy of the gauge field , with even and odd subsets
 | 
			
		||||
      DoubledGaugeField Umu;
 | 
			
		||||
      DoubledGaugeField UmuEven;
 | 
			
		||||
      DoubledGaugeField UmuOdd;
 | 
			
		||||
 | 
			
		||||
      LebesgueOrder Lebesgue;
 | 
			
		||||
      LebesgueOrder LebesgueEvenOdd;
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef WilsonFermion<WilsonImplF> WilsonFermionF;
 | 
			
		||||
    typedef WilsonFermion<WilsonImplD> WilsonFermionD;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
typedef WilsonFermion<WilsonImplF> WilsonFermionF;
 | 
			
		||||
typedef WilsonFermion<WilsonImplD> WilsonFermionD;
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,185 +1,179 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/qcd/action/pseudofermion/TwoFlavourEvenOdd.h
 | 
			
		||||
Source file: ./lib/qcd/action/pseudofermion/TwoFlavourEvenOdd.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
 | 
			
		||||
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 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.
 | 
			
		||||
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.
 | 
			
		||||
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
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_H
 | 
			
		||||
#define QCD_PSEUDOFERMION_TWO_FLAVOUR_EVEN_ODD_H
 | 
			
		||||
 | 
			
		||||
namespace Grid{
 | 
			
		||||
  namespace QCD{
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Two flavour pseudofermion action for any EO prec dop
 | 
			
		||||
////////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <class Impl>
 | 
			
		||||
class TwoFlavourEvenOddPseudoFermionAction
 | 
			
		||||
    : public Action<typename Impl::GaugeField> {
 | 
			
		||||
 public:
 | 
			
		||||
  INHERIT_IMPL_TYPES(Impl);
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  FermionOperator<Impl> &FermOp;  // the basic operator
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Two flavour pseudofermion action for any EO prec dop
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    template<class Impl>
 | 
			
		||||
    class TwoFlavourEvenOddPseudoFermionAction : public Action<typename Impl::GaugeField> {
 | 
			
		||||
  OperatorFunction<FermionField> &DerivativeSolver;
 | 
			
		||||
  OperatorFunction<FermionField> &ActionSolver;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
  FermionField PhiOdd;   // the pseudo fermion field for this trajectory
 | 
			
		||||
  FermionField PhiEven;  // the pseudo fermion field for this trajectory
 | 
			
		||||
 | 
			
		||||
      INHERIT_IMPL_TYPES(Impl);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
      
 | 
			
		||||
      FermionOperator<Impl> & FermOp;// the basic operator
 | 
			
		||||
 | 
			
		||||
      OperatorFunction<FermionField> &DerivativeSolver;
 | 
			
		||||
      OperatorFunction<FermionField> &ActionSolver;
 | 
			
		||||
 | 
			
		||||
      FermionField PhiOdd;   // the pseudo fermion field for this trajectory
 | 
			
		||||
      FermionField PhiEven;  // the pseudo fermion field for this trajectory
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
      /////////////////////////////////////////////////
 | 
			
		||||
      // Pass in required objects.
 | 
			
		||||
      /////////////////////////////////////////////////
 | 
			
		||||
      TwoFlavourEvenOddPseudoFermionAction(FermionOperator<Impl>  &Op, 
 | 
			
		||||
					 OperatorFunction<FermionField> & DS,
 | 
			
		||||
					 OperatorFunction<FermionField> & AS
 | 
			
		||||
					   ) : 
 | 
			
		||||
        FermOp(Op), 
 | 
			
		||||
	DerivativeSolver(DS), 
 | 
			
		||||
	ActionSolver(AS), 
 | 
			
		||||
 public:
 | 
			
		||||
  /////////////////////////////////////////////////
 | 
			
		||||
  // Pass in required objects.
 | 
			
		||||
  /////////////////////////////////////////////////
 | 
			
		||||
  TwoFlavourEvenOddPseudoFermionAction(FermionOperator<Impl> &Op,
 | 
			
		||||
                                       OperatorFunction<FermionField> &DS,
 | 
			
		||||
                                       OperatorFunction<FermionField> &AS)
 | 
			
		||||
      : FermOp(Op),
 | 
			
		||||
        DerivativeSolver(DS),
 | 
			
		||||
        ActionSolver(AS),
 | 
			
		||||
        PhiEven(Op.FermionRedBlackGrid()),
 | 
			
		||||
	PhiOdd(Op.FermionRedBlackGrid())
 | 
			
		||||
		  {};
 | 
			
		||||
      
 | 
			
		||||
      //////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
      // Push the gauge field in to the dops. Assume any BC's and smearing already applied
 | 
			
		||||
      //////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
      virtual void refresh(const GaugeField &U, GridParallelRNG& pRNG) {
 | 
			
		||||
        PhiOdd(Op.FermionRedBlackGrid()){};
 | 
			
		||||
 | 
			
		||||
	// P(phi) = e^{- phi^dag (MpcdagMpc)^-1 phi}
 | 
			
		||||
	// Phi = McpDag eta 
 | 
			
		||||
	// P(eta) = e^{- eta^dag eta}
 | 
			
		||||
	//
 | 
			
		||||
	// e^{x^2/2 sig^2} => sig^2 = 0.5.
 | 
			
		||||
  //////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  // Push the gauge field in to the dops. Assume any BC's and smearing already
 | 
			
		||||
  // applied
 | 
			
		||||
  //////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  virtual void refresh(const GaugeField &U, GridParallelRNG &pRNG) {
 | 
			
		||||
    // P(phi) = e^{- phi^dag (MpcdagMpc)^-1 phi}
 | 
			
		||||
    // Phi = McpDag eta
 | 
			
		||||
    // P(eta) = e^{- eta^dag eta}
 | 
			
		||||
    //
 | 
			
		||||
    // e^{x^2/2 sig^2} => sig^2 = 0.5.
 | 
			
		||||
 | 
			
		||||
	RealD scale = std::sqrt(0.5);
 | 
			
		||||
    RealD scale = std::sqrt(0.5);
 | 
			
		||||
 | 
			
		||||
	FermionField eta    (FermOp.FermionGrid());
 | 
			
		||||
	FermionField etaOdd (FermOp.FermionRedBlackGrid());
 | 
			
		||||
	FermionField etaEven(FermOp.FermionRedBlackGrid());
 | 
			
		||||
    FermionField eta(FermOp.FermionGrid());
 | 
			
		||||
    FermionField etaOdd(FermOp.FermionRedBlackGrid());
 | 
			
		||||
    FermionField etaEven(FermOp.FermionRedBlackGrid());
 | 
			
		||||
 | 
			
		||||
	gaussian(pRNG,eta);
 | 
			
		||||
	pickCheckerboard(Even,etaEven,eta);
 | 
			
		||||
	pickCheckerboard(Odd,etaOdd,eta);
 | 
			
		||||
     gaussian(pRNG, eta);
 | 
			
		||||
    pickCheckerboard(Even, etaEven, eta);
 | 
			
		||||
    pickCheckerboard(Odd, etaOdd, eta);
 | 
			
		||||
 | 
			
		||||
	FermOp.ImportGauge(U);
 | 
			
		||||
	SchurDifferentiableOperator<Impl> PCop(FermOp);
 | 
			
		||||
	
 | 
			
		||||
    FermOp.ImportGauge(U);
 | 
			
		||||
    SchurDifferentiableOperator<Impl> PCop(FermOp);
 | 
			
		||||
 | 
			
		||||
	PCop.MpcDag(etaOdd,PhiOdd);
 | 
			
		||||
    PCop.MpcDag(etaOdd, PhiOdd);
 | 
			
		||||
 | 
			
		||||
	FermOp.MooeeDag(etaEven,PhiEven);
 | 
			
		||||
    FermOp.MooeeDag(etaEven, PhiEven);
 | 
			
		||||
 | 
			
		||||
	PhiOdd =PhiOdd*scale;
 | 
			
		||||
	PhiEven=PhiEven*scale;
 | 
			
		||||
	
 | 
			
		||||
      };
 | 
			
		||||
    PhiOdd = PhiOdd * scale;
 | 
			
		||||
    PhiEven = PhiEven * scale;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
      //////////////////////////////////////////////////////
 | 
			
		||||
      // S = phi^dag (Mdag M)^-1 phi  (odd)
 | 
			
		||||
      //   + phi^dag (Mdag M)^-1 phi  (even)
 | 
			
		||||
      //////////////////////////////////////////////////////
 | 
			
		||||
      virtual RealD S(const GaugeField &U) {
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  // S = phi^dag (Mdag M)^-1 phi  (odd)
 | 
			
		||||
  //   + phi^dag (Mdag M)^-1 phi  (even)
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  virtual RealD S(const GaugeField &U) {
 | 
			
		||||
    FermOp.ImportGauge(U);
 | 
			
		||||
 | 
			
		||||
	FermOp.ImportGauge(U);
 | 
			
		||||
    FermionField X(FermOp.FermionRedBlackGrid());
 | 
			
		||||
    FermionField Y(FermOp.FermionRedBlackGrid());
 | 
			
		||||
 | 
			
		||||
	FermionField X(FermOp.FermionRedBlackGrid());
 | 
			
		||||
	FermionField Y(FermOp.FermionRedBlackGrid());
 | 
			
		||||
	
 | 
			
		||||
	SchurDifferentiableOperator<Impl> PCop(FermOp);
 | 
			
		||||
    SchurDifferentiableOperator<Impl> PCop(FermOp);
 | 
			
		||||
 | 
			
		||||
	X=zero;
 | 
			
		||||
	ActionSolver(PCop,PhiOdd,X);
 | 
			
		||||
	PCop.Op(X,Y);
 | 
			
		||||
	RealD action = norm2(Y);
 | 
			
		||||
    X = zero;
 | 
			
		||||
    ActionSolver(PCop, PhiOdd, X);
 | 
			
		||||
    PCop.Op(X, Y);
 | 
			
		||||
    RealD action = norm2(Y);
 | 
			
		||||
 | 
			
		||||
	// The EE factorised block; normally can replace with zero if det is constant (gauge field indept)
 | 
			
		||||
	// Only really clover term that creates this.
 | 
			
		||||
	FermOp.MooeeInvDag(PhiEven,Y);
 | 
			
		||||
	action = action + norm2(Y);
 | 
			
		||||
    // The EE factorised block; normally can replace with zero if det is
 | 
			
		||||
    // constant (gauge field indept)
 | 
			
		||||
    // Only really clover term that creates this.
 | 
			
		||||
    FermOp.MooeeInvDag(PhiEven, Y);
 | 
			
		||||
    action = action + norm2(Y);
 | 
			
		||||
 | 
			
		||||
	std::cout << GridLogMessage << "Pseudofermion EO action "<<action<<std::endl;
 | 
			
		||||
	return action;
 | 
			
		||||
      };
 | 
			
		||||
    std::cout << GridLogMessage << "Pseudofermion EO action " << action
 | 
			
		||||
              << std::endl;
 | 
			
		||||
    return action;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
      //////////////////////////////////////////////////////
 | 
			
		||||
      //
 | 
			
		||||
      // 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 
 | 
			
		||||
      //
 | 
			
		||||
      //       = - Ydag dM X  - Xdag dMdag Y
 | 
			
		||||
      //
 | 
			
		||||
      //////////////////////////////////////////////////////
 | 
			
		||||
      virtual void deriv(const GaugeField &U,GaugeField & dSdU) {
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  //
 | 
			
		||||
  // 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
 | 
			
		||||
  //
 | 
			
		||||
  //       = - Ydag dM X  - Xdag dMdag Y
 | 
			
		||||
  //
 | 
			
		||||
  //////////////////////////////////////////////////////
 | 
			
		||||
  virtual void deriv(const GaugeField &U, GaugeField &dSdU) {
 | 
			
		||||
    FermOp.ImportGauge(U);
 | 
			
		||||
 | 
			
		||||
	FermOp.ImportGauge(U);
 | 
			
		||||
    FermionField X(FermOp.FermionRedBlackGrid());
 | 
			
		||||
    FermionField Y(FermOp.FermionRedBlackGrid());
 | 
			
		||||
    GaugeField tmp(FermOp.GaugeGrid());
 | 
			
		||||
 | 
			
		||||
	FermionField X(FermOp.FermionRedBlackGrid());
 | 
			
		||||
	FermionField Y(FermOp.FermionRedBlackGrid());
 | 
			
		||||
	GaugeField tmp(FermOp.GaugeGrid());
 | 
			
		||||
    SchurDifferentiableOperator<Impl> Mpc(FermOp);
 | 
			
		||||
 | 
			
		||||
	SchurDifferentiableOperator<Impl> Mpc(FermOp);
 | 
			
		||||
    // 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.
 | 
			
		||||
 | 
			
		||||
	// 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.
 | 
			
		||||
    X = zero;
 | 
			
		||||
    DerivativeSolver(Mpc, PhiOdd, X);
 | 
			
		||||
    Mpc.Mpc(X, Y);
 | 
			
		||||
    Mpc.MpcDeriv(tmp, Y, X);
 | 
			
		||||
    dSdU = tmp;
 | 
			
		||||
    Mpc.MpcDagDeriv(tmp, X, Y);
 | 
			
		||||
    dSdU = dSdU + tmp;
 | 
			
		||||
 | 
			
		||||
	X=zero;
 | 
			
		||||
	DerivativeSolver(Mpc,PhiOdd,X);
 | 
			
		||||
	Mpc.Mpc(X,Y);
 | 
			
		||||
  	Mpc.MpcDeriv(tmp , Y, X );    dSdU=tmp;
 | 
			
		||||
	Mpc.MpcDagDeriv(tmp , X, Y);  dSdU=dSdU+tmp;
 | 
			
		||||
    // Treat the EE case. (MdagM)^-1 = Minv Minvdag
 | 
			
		||||
    // Deriv defaults to zero.
 | 
			
		||||
    //        FermOp.MooeeInvDag(PhiOdd,Y);
 | 
			
		||||
    //      FermOp.MooeeInv(Y,X);
 | 
			
		||||
    //  FermOp.MeeDeriv(tmp , Y, X,DaggerNo );    dSdU=tmp;
 | 
			
		||||
    //  FermOp.MeeDeriv(tmp , X, Y,DaggerYes);  dSdU=dSdU+tmp;
 | 
			
		||||
 | 
			
		||||
	// Treat the EE case. (MdagM)^-1 = Minv Minvdag
 | 
			
		||||
	// Deriv defaults to zero.
 | 
			
		||||
	//        FermOp.MooeeInvDag(PhiOdd,Y);
 | 
			
		||||
	//      FermOp.MooeeInv(Y,X);
 | 
			
		||||
	//	FermOp.MeeDeriv(tmp , Y, X,DaggerNo );    dSdU=tmp;
 | 
			
		||||
	//  FermOp.MeeDeriv(tmp , X, Y,DaggerYes);  dSdU=dSdU+tmp;
 | 
			
		||||
    assert(FermOp.ConstEE() == 1);
 | 
			
		||||
 | 
			
		||||
	assert(FermOp.ConstEE() == 1);
 | 
			
		||||
    /*
 | 
			
		||||
    FermOp.MooeeInvDag(PhiOdd,Y);
 | 
			
		||||
    FermOp.MooeeInv(Y,X);
 | 
			
		||||
    FermOp.MeeDeriv(tmp , Y, X,DaggerNo );    dSdU=tmp;
 | 
			
		||||
    FermOp.MeeDeriv(tmp , X, Y,DaggerYes);  dSdU=dSdU+tmp;
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
        FermOp.MooeeInvDag(PhiOdd,Y);
 | 
			
		||||
        FermOp.MooeeInv(Y,X);
 | 
			
		||||
  	FermOp.MeeDeriv(tmp , Y, X,DaggerNo );    dSdU=tmp;
 | 
			
		||||
	FermOp.MeeDeriv(tmp , X, Y,DaggerYes);  dSdU=dSdU+tmp;
 | 
			
		||||
	*/
 | 
			
		||||
	
 | 
			
		||||
	dSdU = Ta(dSdU);
 | 
			
		||||
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
  }
 | 
			
		||||
    dSdU = Ta(dSdU);
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user