/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/action/fermion/DomainWallEOFAFermion.cc Copyright (C) 2017 Author: Peter Boyle Author: Peter Boyle Author: Peter Boyle Author: paboyle Author: David Murphy 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 */ #include #include #include namespace Grid { namespace QCD { template DomainWallEOFAFermion::DomainWallEOFAFermion( GaugeField &_Umu, GridCartesian &FiveDimGrid, GridRedBlackCartesian &FiveDimRedBlackGrid, GridCartesian &FourDimGrid, GridRedBlackCartesian &FourDimRedBlackGrid, RealD _mq1, RealD _mq2, RealD _mq3, RealD _shift, int _pm, RealD _M5, const ImplParams &p) : AbstractEOFAFermion(_Umu, FiveDimGrid, FiveDimRedBlackGrid, FourDimGrid, FourDimRedBlackGrid, _mq1, _mq2, _mq3, _shift, _pm, _M5, 1.0, 0.0, p) { RealD eps = 1.0; Approx::zolotarev_data *zdata = Approx::higham(eps,this->Ls); assert(zdata->n == this->Ls); std::cout << GridLogMessage << "DomainWallEOFAFermion with Ls=" << this->Ls << std::endl; this->SetCoefficientsTanh(zdata, 1.0, 0.0); Approx::zolotarev_free(zdata); } /*************************************************************** /* Additional EOFA operators only called outside the inverter. /* Since speed is not essential, simple axpby-style /* implementations should be fine. /***************************************************************/ template void DomainWallEOFAFermion::Omega(const FermionField& psi, FermionField& Din, int sign, int dag) { int Ls = this->Ls; Din = zero; if((sign == 1) && (dag == 0)){ axpby_ssp(Din, 0.0, psi, 1.0, psi, Ls-1, 0); } else if((sign == -1) && (dag == 0)){ axpby_ssp(Din, 0.0, psi, 1.0, psi, 0, 0); } else if((sign == 1 ) && (dag == 1)){ axpby_ssp(Din, 0.0, psi, 1.0, psi, 0, Ls-1); } else if((sign == -1) && (dag == 1)){ axpby_ssp(Din, 0.0, psi, 1.0, psi, 0, 0); } } // This is just the identity for DWF template void DomainWallEOFAFermion::Dtilde(const FermionField& psi, FermionField& chi){ chi = psi; } // This is just the identity for DWF template void DomainWallEOFAFermion::DtildeInv(const FermionField& psi, FermionField& chi){ chi = psi; } /*****************************************************************************************************/ template RealD DomainWallEOFAFermion::M(const FermionField& psi, FermionField& chi) { int Ls = this->Ls; FermionField Din(psi._grid); this->Meooe5D(psi, Din); this->DW(Din, chi, DaggerNo); axpby(chi, 1.0, 1.0, chi, psi); this->M5D(psi, chi); return(norm2(chi)); } template RealD DomainWallEOFAFermion::Mdag(const FermionField& psi, FermionField& chi) { int Ls = this->Ls; FermionField Din(psi._grid); this->DW(psi, Din, DaggerYes); this->MeooeDag5D(Din, chi); this->M5Ddag(psi, chi); axpby(chi, 1.0, 1.0, chi, psi); return(norm2(chi)); } /******************************************************************** /* Performance critical fermion operators called inside the inverter /********************************************************************/ template void DomainWallEOFAFermion::M5D(const FermionField& psi, FermionField& chi) { int Ls = this->Ls; int pm = this->pm; RealD shift = this->shift; RealD mq1 = this->mq1; RealD mq2 = this->mq2; RealD mq3 = this->mq3; // coefficients for shift operator ( = shift*\gamma_{5}*R_{5}*\Delta_{\pm}(mq2,mq3)*P_{\pm} ) Coeff_t shiftp(0.0), shiftm(0.0); if(shift != 0.0){ if(pm == 1){ shiftp = shift*(mq3-mq2); } else{ shiftm = -shift*(mq3-mq2); } } std::vector diag(Ls,1.0); std::vector upper(Ls,-1.0); upper[Ls-1] = mq1 + shiftm; std::vector lower(Ls,-1.0); lower[0] = mq1 + shiftp; #if(0) std::cout << GridLogMessage << "DomainWallEOFAFermion::M5D(FF&,FF&):" << std::endl; for(int i=0; i::iscomplex()) { sp[l] = PplusMat (l*istride+s1*ostride,s2); sm[l] = PminusMat(l*istride+s1*ostride,s2); } else { // if real scalar_type tmp; tmp = PplusMat (l*istride+s1*ostride,s2); sp[l] = scalar_type(tmp.real(),tmp.real()); tmp = PminusMat(l*istride+s1*ostride,s2); sm[l] = scalar_type(tmp.real(),tmp.real()); } } Matp[LLs*s2+s1] = Vp; Matm[LLs*s2+s1] = Vm; }} } FermOpTemplateInstantiate(DomainWallEOFAFermion); GparityFermOpTemplateInstantiate(DomainWallEOFAFermion); }}