mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-03 05:24:32 +00:00 
			
		
		
		
	First pass at continued fraction; solver and even odd decomposition tests pass.
Have to make ContFrac class virtual and derive end non-abstract actions for the particular cases.
This commit is contained in:
		@@ -229,7 +229,14 @@ namespace QCD {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  void CayleyFermion5D::SetCoefficients(RealD scale,Approx::zolotarev_data *zdata,RealD b,RealD c)
 | 
			
		||||
  // Tanh
 | 
			
		||||
  void CayleyFermion5D::SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c)
 | 
			
		||||
  {
 | 
			
		||||
    SetCoefficientsZolotarev(1.0,zdata,b,c);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
  //Zolo
 | 
			
		||||
  void CayleyFermion5D::SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata,RealD b,RealD c)
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
    ///////////////////////////////////////////////////////////
 | 
			
		||||
@@ -266,7 +273,7 @@ namespace QCD {
 | 
			
		||||
    double bmc = b-c;
 | 
			
		||||
    for(int i=0; i < Ls; i++){
 | 
			
		||||
      as[i] = 1.0;
 | 
			
		||||
      omega[i] = ((double)zdata->gamma[i]); //NB reciprocal relative to Chroma NEF code
 | 
			
		||||
      omega[i] = ((double)zdata->gamma[i])*zolo_hi; //NB reciprocal relative to Chroma NEF code
 | 
			
		||||
      bs[i] = 0.5*(bpc/omega[i] + bmc);
 | 
			
		||||
      cs[i] = 0.5*(bpc/omega[i] - bmc);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ namespace Grid {
 | 
			
		||||
      virtual void   MooeeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeInv    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      virtual void   Instantiatable(void)=0;
 | 
			
		||||
      //    protected:
 | 
			
		||||
      RealD mass;
 | 
			
		||||
 | 
			
		||||
@@ -52,7 +52,8 @@ namespace Grid {
 | 
			
		||||
		      RealD _mass,RealD _M5);
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
      void SetCoefficients(RealD scale,Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
			
		||||
      void SetCoefficientsZolotarev(RealD zolohi,Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
			
		||||
      void SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,56 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    void ContinuedFractionFermion5D::SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c)
 | 
			
		||||
    {
 | 
			
		||||
      SetCoefficientsZolotarev(1.0,zdata,b,c);
 | 
			
		||||
    }
 | 
			
		||||
    void ContinuedFractionFermion5D::SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata,RealD b,RealD c)
 | 
			
		||||
    {
 | 
			
		||||
      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;
 | 
			
		||||
      double dw_diag = (4.0-M5)*ZoloHiInv;
 | 
			
		||||
    
 | 
			
		||||
      See.resize(Ls);
 | 
			
		||||
      Aee.resize(Ls);
 | 
			
		||||
      int sign=1;
 | 
			
		||||
      for(int s=0;s<Ls;s++){
 | 
			
		||||
	Aee[s] = sign * Beta[s] * dw_diag;
 | 
			
		||||
	sign   = - sign;
 | 
			
		||||
      }
 | 
			
		||||
      Aee[Ls-1] += R;
 | 
			
		||||
    
 | 
			
		||||
      See[0] = Aee[0];
 | 
			
		||||
      for(int s=1;s<Ls;s++){
 | 
			
		||||
	See[s] = Aee[s] - 1.0/See[s-1];
 | 
			
		||||
      }
 | 
			
		||||
      for(int s=0;s<Ls;s++){
 | 
			
		||||
	std::cout <<"s = "<<s<<" Beta "<<Beta[s]<<" Aee "<<Aee[s] <<" See "<<See[s] <<std::endl;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    RealD  ContinuedFractionFermion5D::M           (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
    {
 | 
			
		||||
      LatticeFermion D(psi._grid);
 | 
			
		||||
@@ -13,13 +60,13 @@ namespace Grid {
 | 
			
		||||
      int sign=1;
 | 
			
		||||
      for(int s=0;s<Ls;s++){
 | 
			
		||||
	if ( s==0 ) {
 | 
			
		||||
	  ag5xpby_ssp(chi,cc[0]*Beta[0]*sign*scale,D,sqrt_cc[0],psi,s,s+1); // Multiplies Dw by G5 so Hw
 | 
			
		||||
	  ag5xpby_ssp(chi,cc[0]*Beta[0]*sign*ZoloHiInv,D,sqrt_cc[0],psi,s,s+1); // Multiplies Dw by G5 so Hw
 | 
			
		||||
	} else if ( s==(Ls-1) ){
 | 
			
		||||
	  RealD R=(1.0+mass)/(1.0-mass);
 | 
			
		||||
	  ag5xpby_ssp(chi,Beta[s]*scale,D,sqrt_cc[s-1],psi,s,s-1);
 | 
			
		||||
	  ag5xpby_ssp(chi,Beta[s]*ZoloHiInv,D,sqrt_cc[s-1],psi,s,s-1);
 | 
			
		||||
	  ag5xpby_ssp(chi,R,psi,1.0,chi,s,s);
 | 
			
		||||
	} else {
 | 
			
		||||
	  ag5xpby_ssp(chi,cc[s]*Beta[s]*sign*scale,D,sqrt_cc[s],psi,s,s+1);
 | 
			
		||||
	  ag5xpby_ssp(chi,cc[s]*Beta[s]*sign*ZoloHiInv,D,sqrt_cc[s],psi,s,s+1);
 | 
			
		||||
  	  axpby_ssp(chi,1.0,chi,sqrt_cc[s-1],psi,s,s-1);
 | 
			
		||||
	}
 | 
			
		||||
	sign=-sign; 
 | 
			
		||||
@@ -35,18 +82,22 @@ namespace Grid {
 | 
			
		||||
    }
 | 
			
		||||
    void   ContinuedFractionFermion5D::Meooe       (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
    {
 | 
			
		||||
      Dhop(psi,chi,DaggerNo); // Dslash on diagonal. g5 Dslash is hermitian
 | 
			
		||||
      // Apply 4d dslash
 | 
			
		||||
      if ( psi.checkerboard == Odd ) {
 | 
			
		||||
	DhopEO(psi,chi,DaggerNo); // Dslash on diagonal. g5 Dslash is hermitian
 | 
			
		||||
      } else {
 | 
			
		||||
	DhopOE(psi,chi,DaggerNo); // Dslash on diagonal. g5 Dslash is hermitian
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      int sign=1;
 | 
			
		||||
      for(int s=0;s<Ls;s++){
 | 
			
		||||
	if ( s==(Ls-1) ){
 | 
			
		||||
	  ag5xpby_ssp(chi,Beta[s]*scale,chi,0.0,chi,s,s);
 | 
			
		||||
	  ag5xpby_ssp(chi,Beta[s]*ZoloHiInv,chi,0.0,chi,s,s);
 | 
			
		||||
	} else {
 | 
			
		||||
	  ag5xpby_ssp(chi,cc[s]*Beta[s]*sign*scale,chi,0.0,chi,s,s);
 | 
			
		||||
	  ag5xpby_ssp(chi,cc[s]*Beta[s]*sign*ZoloHiInv,chi,0.0,chi,s,s);
 | 
			
		||||
	}
 | 
			
		||||
	sign=-sign; 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    void   ContinuedFractionFermion5D::MeooeDag    (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
    {
 | 
			
		||||
@@ -54,7 +105,7 @@ namespace Grid {
 | 
			
		||||
    }
 | 
			
		||||
    void   ContinuedFractionFermion5D::Mooee       (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
    {
 | 
			
		||||
      double dw_diag = (4.0-this->M5)*scale;
 | 
			
		||||
      double dw_diag = (4.0-M5)*ZoloHiInv;
 | 
			
		||||
    
 | 
			
		||||
      int sign=1;
 | 
			
		||||
      for(int s=0;s<Ls;s++){
 | 
			
		||||
@@ -62,7 +113,7 @@ namespace Grid {
 | 
			
		||||
	  ag5xpby_ssp(chi,cc[0]*Beta[0]*sign*dw_diag,psi,sqrt_cc[0],psi,s,s+1); // Multiplies Dw by G5 so Hw
 | 
			
		||||
	} else if ( s==(Ls-1) ){
 | 
			
		||||
	  // Drop the CC here.
 | 
			
		||||
	  double R=(1+this->mass)/(1-this->mass);
 | 
			
		||||
	  double R=(1+mass)/(1-mass);
 | 
			
		||||
	  ag5xpby_ssp(chi,Beta[s]*dw_diag,psi,sqrt_cc[s-1],psi,s,s-1);
 | 
			
		||||
	  ag5xpby_ssp(chi,R,psi,1.0,chi,s,s);
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -80,7 +131,7 @@ namespace Grid {
 | 
			
		||||
    void   ContinuedFractionFermion5D::MooeeInv    (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
    {
 | 
			
		||||
      // Apply Linv
 | 
			
		||||
      axpby_ssp(chi,1.0/cc_d[0],psi,0.0,psi,0,0);
 | 
			
		||||
      axpby_ssp(chi,1.0/cc_d[0],psi,0.0,psi,0,0); 
 | 
			
		||||
      for(int s=1;s<Ls;s++){
 | 
			
		||||
	axpbg5y_ssp(chi,1.0/cc_d[s],psi,-1.0/See[s-1],chi,s,s-1);
 | 
			
		||||
      }
 | 
			
		||||
@@ -89,7 +140,7 @@ namespace Grid {
 | 
			
		||||
	ag5xpby_ssp(chi,1.0/See[s],chi,0.0,chi,s,s); //only appearance of See[0]
 | 
			
		||||
      }
 | 
			
		||||
      // Apply Uinv = (Linv)^T
 | 
			
		||||
      axpby_ssp(chi,1.0/cc_d[Ls-1],chi,0.0,chi,this->Ls-1,this->Ls-1);
 | 
			
		||||
      axpby_ssp(chi,1.0/cc_d[Ls-1],chi,0.0,chi,Ls-1,Ls-1);
 | 
			
		||||
      for(int s=Ls-2;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);
 | 
			
		||||
      }
 | 
			
		||||
@@ -112,6 +163,10 @@ namespace Grid {
 | 
			
		||||
		      FourDimGrid, FourDimRedBlackGrid,M5),
 | 
			
		||||
      mass(_mass)
 | 
			
		||||
    {
 | 
			
		||||
      assert((Ls&0x1)==1); // Odd Ls required
 | 
			
		||||
      int nrational=Ls-1;// Even rational order
 | 
			
		||||
      zdata = Approx::grid_higham(1.0,nrational);// eps is ignored for higham
 | 
			
		||||
      SetCoefficientsTanh(zdata,1.0,0.0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -21,20 +21,8 @@ namespace Grid {
 | 
			
		||||
      virtual void   MooeeInv    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
      Approx::zolotarev_data *zdata;
 | 
			
		||||
 | 
			
		||||
      // Cont frac
 | 
			
		||||
      RealD mass;
 | 
			
		||||
      RealD R;
 | 
			
		||||
      RealD scale;
 | 
			
		||||
      std::vector<double> Beta;
 | 
			
		||||
      std::vector<double> cc;;
 | 
			
		||||
      std::vector<double> cc_d;;
 | 
			
		||||
      std::vector<double> sqrt_cc;
 | 
			
		||||
      std::vector<double> See;
 | 
			
		||||
      std::vector<double> Aee;
 | 
			
		||||
      //      virtual void   Instantiatable(void)=0;
 | 
			
		||||
      virtual void   Instantiatable(void) {};
 | 
			
		||||
 | 
			
		||||
      // Constructors
 | 
			
		||||
      ContinuedFractionFermion5D(LatticeGaugeField &_Umu,
 | 
			
		||||
@@ -44,6 +32,24 @@ namespace Grid {
 | 
			
		||||
				 GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
				 RealD _mass,RealD M5);
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
 | 
			
		||||
      void SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
			
		||||
      void SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
			
		||||
 | 
			
		||||
      Approx::zolotarev_data *zdata;
 | 
			
		||||
 | 
			
		||||
      // Cont frac
 | 
			
		||||
      RealD mass;
 | 
			
		||||
      RealD R;
 | 
			
		||||
      RealD ZoloHiInv;
 | 
			
		||||
      std::vector<double> Beta;
 | 
			
		||||
      std::vector<double> cc;;
 | 
			
		||||
      std::vector<double> cc_d;;
 | 
			
		||||
      std::vector<double> sqrt_cc;
 | 
			
		||||
      std::vector<double> See;
 | 
			
		||||
      std::vector<double> Aee;
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ namespace Grid {
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      virtual void   Instantiatable(void) {};
 | 
			
		||||
      // Constructors
 | 
			
		||||
      DomainWallFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
			GridCartesian         &FiveDimGrid,
 | 
			
		||||
@@ -33,7 +34,7 @@ namespace Grid {
 | 
			
		||||
	
 | 
			
		||||
	std::cout << "DomainWallFermion with Ls="<<Ls<<std::endl;
 | 
			
		||||
	// Call base setter
 | 
			
		||||
	this->CayleyFermion5D::SetCoefficients(1.0,zdata,1.0,0.0);
 | 
			
		||||
	this->CayleyFermion5D::SetCoefficientsTanh(zdata,1.0,0.0);
 | 
			
		||||
 
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ namespace Grid {
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      virtual void   Instantiatable(void) {};
 | 
			
		||||
      // Constructors
 | 
			
		||||
      MobiusFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
		    GridCartesian         &FiveDimGrid,
 | 
			
		||||
@@ -34,7 +35,7 @@ namespace Grid {
 | 
			
		||||
	assert(zdata->n==this->Ls);
 | 
			
		||||
	
 | 
			
		||||
	// Call base setter
 | 
			
		||||
	this->CayleyFermion5D::SetCoefficients(1.0,zdata,b,c);
 | 
			
		||||
	this->CayleyFermion5D::SetCoefficientsTanh(zdata,b,c);
 | 
			
		||||
 
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@ namespace Grid {
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      virtual void   Instantiatable(void) {};
 | 
			
		||||
      // Constructors
 | 
			
		||||
       MobiusZolotarevFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
			      GridCartesian         &FiveDimGrid,
 | 
			
		||||
@@ -34,10 +35,9 @@ namespace Grid {
 | 
			
		||||
	assert(zdata->n==this->Ls);
 | 
			
		||||
 | 
			
		||||
	std::cout << "MobiusZolotarevFermion (b="<<b<<",c="<<c<<") with Ls= "<<Ls<<" Zolotarev range ["<<lo<<","<<hi<<"]"<<std::endl;
 | 
			
		||||
	std::cout << "MobiusZolotarevFermion : note there is a degeneracy between (b+c) and Zolo param hi"<<std::endl;
 | 
			
		||||
	
 | 
			
		||||
	// Call base setter
 | 
			
		||||
	this->CayleyFermion5D::SetCoefficients(1.0,zdata,b,c);
 | 
			
		||||
	this->CayleyFermion5D::SetCoefficientsZolotarev(hi,zdata,b,c);
 | 
			
		||||
 
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user