/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/action/fermion/CayleyFermion5D.h Copyright (C) 2015 Author: Peter Boyle Author: Peter Boyle This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #ifndef GRID_QCD_CAYLEY_FERMION_H #define GRID_QCD_CAYLEY_FERMION_H #include namespace Grid { namespace QCD { template struct switcheroo { static inline int iscomplex() { return 0; } template static inline vec mult(vec a, vec b) { return real_mult(a,b); } }; template<> struct switcheroo { static inline int iscomplex() { return 1; } template static inline vec mult(vec a, vec b) { return a*b; } }; template<> struct switcheroo { static inline int iscomplex() { return 1; } template static inline vec mult(vec a, vec b) { return a*b; } }; template class CayleyFermion5D : public WilsonFermion5D { public: INHERIT_IMPL_TYPES(Impl); public: // override multiply virtual RealD M (const FermionField &in, FermionField &out); virtual RealD Mdag (const FermionField &in, FermionField &out); // half checkerboard operations virtual void Meooe (const FermionField &in, FermionField &out); virtual void MeooeDag (const FermionField &in, FermionField &out); 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); virtual void Meo5D (const FermionField &psi, FermionField &chi); virtual void M5D (const FermionField &psi, FermionField &chi); virtual void M5Ddag(const FermionField &psi, FermionField &chi); /////////////////////////////////////////////////////////////// // Physical surface field utilities /////////////////////////////////////////////////////////////// virtual void Dminus(const FermionField &psi, FermionField &chi); virtual void DminusDag(const FermionField &psi, FermionField &chi); virtual void ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d); virtual void ExportPhysicalFermionSource(const FermionField &solution5d, FermionField &exported4d); virtual void ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d); virtual void ImportUnphysicalFermion(const FermionField &solution5d, FermionField &exported4d); ///////////////////////////////////////////////////// // Instantiate different versions depending on Impl ///////////////////////////////////////////////////// void M5D(const FermionField &psi, const FermionField &phi, FermionField &chi, std::vector &lower, std::vector &diag, std::vector &upper); void M5Ddag(const FermionField &psi, const FermionField &phi, FermionField &chi, std::vector &lower, std::vector &diag, std::vector &upper); void MooeeInternal(const FermionField &in, FermionField &out,int dag,int inv); void MooeeInternalCompute(int dag, int inv, Vector > & Matp, Vector > & Matm); void MooeeInternalAsm(const FermionField &in, FermionField &out, int LLs, int site, Vector > &Matp, Vector > &Matm); void MooeeInternalZAsm(const FermionField &in, FermionField &out, int LLs, int site, Vector > &Matp, Vector > &Matm); virtual void Instantiatable(void)=0; // force terms; five routines; default to Dhop on diagonal virtual void MDeriv (GaugeField &mat,const FermionField &U,const FermionField &V,int dag); virtual void MoeDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag); virtual void MeoDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag); // Efficient support for multigrid coarsening virtual void Mdir (const FermionField &in, FermionField &out,int dir,int disp); void Meooe5D (const FermionField &in, FermionField &out); void MeooeDag5D (const FermionField &in, FermionField &out); // protected: RealD mass; // Cayley form Moebius (tanh and zolotarev) std::vector omega; std::vector bs; // S dependent coeffs std::vector cs; std::vector as; // For preconditioning Cayley form std::vector bee; std::vector cee; std::vector aee; std::vector beo; std::vector ceo; std::vector aeo; // LDU factorisation of the eeoo matrix std::vector lee; std::vector leem; std::vector uee; std::vector ueem; std::vector dee; // Matrices of 5d ee inverse params Vector > MatpInv; Vector > MatmInv; Vector > MatpInvDag; Vector > MatmInvDag; // Constructors CayleyFermion5D(GaugeField &_Umu, GridCartesian &FiveDimGrid, GridRedBlackCartesian &FiveDimRedBlackGrid, GridCartesian &FourDimGrid, GridRedBlackCartesian &FourDimRedBlackGrid, RealD _mass,RealD _M5,const ImplParams &p= ImplParams()); void CayleyReport(void); void CayleyZeroCounters(void); double M5Dflops; double M5Dcalls; double M5Dtime; double MooeeInvFlops; double MooeeInvCalls; double MooeeInvTime; protected: virtual void SetCoefficientsZolotarev(RealD zolohi,Approx::zolotarev_data *zdata,RealD b,RealD c); virtual void SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c); virtual void SetCoefficientsInternal(RealD zolo_hi,std::vector & gamma,RealD b,RealD c); }; } } #define INSTANTIATE_DPERP(A)\ template void CayleyFermion5D< A >::M5D(const FermionField &psi,const FermionField &phi,FermionField &chi,\ std::vector &lower,std::vector &diag,std::vector &upper); \ template void CayleyFermion5D< A >::M5Ddag(const FermionField &psi,const FermionField &phi,FermionField &chi,\ std::vector &lower,std::vector &diag,std::vector &upper); \ template void CayleyFermion5D< A >::MooeeInv (const FermionField &psi, FermionField &chi); \ template void CayleyFermion5D< A >::MooeeInvDag (const FermionField &psi, FermionField &chi); #undef CAYLEY_DPERP_DENSE #define CAYLEY_DPERP_CACHE #undef CAYLEY_DPERP_LINALG #define CAYLEY_DPERP_VEC #endif