diff --git a/lib/qcd/action/fermion/DomainWallEOFAFermion.cc b/lib/qcd/action/fermion/DomainWallEOFAFermion.cc index 37ab5fa6..248ebcd3 100644 --- a/lib/qcd/action/fermion/DomainWallEOFAFermion.cc +++ b/lib/qcd/action/fermion/DomainWallEOFAFermion.cc @@ -28,411 +28,410 @@ with this program; if not, write to the Free Software Foundation, Inc., See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ -/* END LEGAL */ + /* END LEGAL */ #include #include #include -namespace Grid { -namespace QCD { +NAMESPACE_BEGIN(Grid); - 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); +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); + 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 - 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)); + std::cout << std::endl; + } + std::cout << GridLogMessage << "Pminus:" << std::endl; + for(int s=0; s - RealD DomainWallEOFAFermion::Mdag(const FermionField& psi, FermionField& chi) - { - int Ls = this->Ls; + if(inv) { + PplusMat = Pplus.inverse(); + PminusMat = Pminus.inverse(); + } else { + PplusMat = Pplus; + PminusMat = Pminus; + } - FermionField Din(psi._grid); + if(dag){ + PplusMat.adjointInPlace(); + PminusMat.adjointInPlace(); + } - this->DW(psi, Din, DaggerYes); - this->MeooeDag5D(Din, chi); - this->M5Ddag(psi, chi); - axpby(chi, 1.0, 1.0, chi, psi); - return(norm2(chi)); - } + typedef typename SiteHalfSpinor::scalar_type scalar_type; + const int Nsimd = Simd::Nsimd(); + Matp.resize(Ls*LLs); + Matm.resize(Ls*LLs); - /******************************************************************** - * Performance critical fermion operators called inside the inverter - ********************************************************************/ + for(int s2=0; s2::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; + }} +} - 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; +FermOpTemplateInstantiate(DomainWallEOFAFermion); +GparityFermOpTemplateInstantiate(DomainWallEOFAFermion); - // 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); - -}} +NAMESPACE_END(Grid);