/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/action/fermion/ContinuedFractionFermion5D.cc 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 */ #include #include namespace Grid { namespace QCD { template void ContinuedFractionFermion5D::SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD scale) { SetCoefficientsZolotarev(1.0/scale,zdata); } template void ContinuedFractionFermion5D::SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata) { // How to check Ls matches?? // std::cout<n << " - n"<da << " -da "<db << " -db"<dn << " -dn"<dd << " -dd"<Ls; assert(zdata->db==Ls);// Beta has Ls coeffs R=(1+this->mass)/(1-this->mass); Beta.resize(Ls); cc.resize(Ls); cc_d.resize(Ls); sqrt_cc.resize(Ls); for(int i=0; i < Ls ; i++){ Beta[i] = zdata -> beta[i]; cc[i] = 1.0/Beta[i]; cc_d[i]=sqrt(cc[i]); } cc_d[Ls-1]=1.0; for(int i=0; i < Ls-1 ; i++){ sqrt_cc[i]= sqrt(cc[i]*cc[i+1]); } sqrt_cc[Ls-2]=sqrt(cc[Ls-2]); ZoloHiInv =1.0/zolo_hi; dw_diag = (4.0-this->M5)*ZoloHiInv; See.resize(Ls); Aee.resize(Ls); int sign=1; for(int s=0;s RealD ContinuedFractionFermion5D::M (const FermionField &psi, FermionField &chi) { int Ls = this->Ls; FermionField D(psi._grid); this->DW(psi,D,DaggerNo); int sign=1; for(int s=0;s RealD ContinuedFractionFermion5D::Mdag (const FermionField &psi, FermionField &chi) { // This matrix is already hermitian. (g5 Dw) = Dw dag g5 = (g5 Dw)dag // The rest of matrix is symmetric. // Can ignore "dag" return M(psi,chi); } template void ContinuedFractionFermion5D::Mdir (const FermionField &psi, FermionField &chi,int dir,int disp){ int Ls = this->Ls; this->DhopDir(psi,chi,dir,disp); // Dslash on diagonal. g5 Dslash is hermitian int sign=1; for(int s=0;s void ContinuedFractionFermion5D::Meooe (const FermionField &psi, FermionField &chi) { int Ls = this->Ls; // Apply 4d dslash if ( psi.checkerboard == Odd ) { this->DhopEO(psi,chi,DaggerNo); // Dslash on diagonal. g5 Dslash is hermitian } else { this->DhopOE(psi,chi,DaggerNo); // Dslash on diagonal. g5 Dslash is hermitian } int sign=1; for(int s=0;s void ContinuedFractionFermion5D::MeooeDag (const FermionField &psi, FermionField &chi) { this->Meooe(psi,chi); } template void ContinuedFractionFermion5D::Mooee (const FermionField &psi, FermionField &chi) { int Ls = this->Ls; int sign=1; for(int s=0;s void ContinuedFractionFermion5D::MooeeDag (const FermionField &psi, FermionField &chi) { this->Mooee(psi,chi); } template void ContinuedFractionFermion5D::MooeeInv (const FermionField &psi, FermionField &chi) { int Ls = this->Ls; // Apply Linv axpby_ssp(chi,1.0/cc_d[0],psi,0.0,psi,0,0); for(int s=1;s=0;s--){ axpbg5y_ssp(chi,1.0/cc_d[s],chi,-1.0*cc_d[s+1]/See[s]/cc_d[s],chi,s,s+1); } } template void ContinuedFractionFermion5D::MooeeInvDag (const FermionField &psi, FermionField &chi) { this->MooeeInv(psi,chi); } // force terms; five routines; default to Dhop on diagonal template void ContinuedFractionFermion5D::MDeriv (GaugeField &mat,const FermionField &U,const FermionField &V,int dag) { int Ls = this->Ls; FermionField D(V._grid); int sign=1; for(int s=0;sDhopDeriv(mat,D,V,DaggerNo); }; template void ContinuedFractionFermion5D::MoeDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag) { int Ls = this->Ls; FermionField D(V._grid); int sign=1; for(int s=0;sDhopDerivOE(mat,D,V,DaggerNo); }; template void ContinuedFractionFermion5D::MeoDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag) { int Ls = this->Ls; FermionField D(V._grid); int sign=1; for(int s=0;sDhopDerivEO(mat,D,V,DaggerNo); }; // Constructors template ContinuedFractionFermion5D::ContinuedFractionFermion5D( GaugeField &_Umu, GridCartesian &FiveDimGrid, GridRedBlackCartesian &FiveDimRedBlackGrid, GridCartesian &FourDimGrid, GridRedBlackCartesian &FourDimRedBlackGrid, RealD _mass,RealD M5,const ImplParams &p) : WilsonFermion5D(_Umu, FiveDimGrid, FiveDimRedBlackGrid, FourDimGrid, FourDimRedBlackGrid,M5,p), mass(_mass) { int Ls = this->Ls; assert((Ls&0x1)==1); // Odd Ls required } template void ContinuedFractionFermion5D::ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d) { int Ls = this->Ls; conformable(solution5d._grid,this->FermionGrid()); conformable(exported4d._grid,this->GaugeGrid()); ExtractSlice(exported4d, solution5d, Ls-1, Ls-1); } template void ContinuedFractionFermion5D::ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d) { int Ls = this->Ls; conformable(imported5d._grid,this->FermionGrid()); conformable(input4d._grid ,this->GaugeGrid()); FermionField tmp(this->FermionGrid()); tmp=zero; InsertSlice(input4d, tmp, Ls-1, Ls-1); tmp=Gamma(Gamma::Algebra::Gamma5)*tmp; this->Dminus(tmp,imported5d); } FermOpTemplateInstantiate(ContinuedFractionFermion5D); } }