mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Addedd Ta functionality to the tensor types
Merge remote-tracking branch 'upstream/master' Conflicts: configure
This commit is contained in:
		
							
								
								
									
										0
									
								
								lib/qcd/action/fermion/.dirstamp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								lib/qcd/action/fermion/.dirstamp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										346
									
								
								lib/qcd/action/fermion/CayleyFermion5D.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										346
									
								
								lib/qcd/action/fermion/CayleyFermion5D.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,346 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
 CayleyFermion5D::CayleyFermion5D(LatticeGaugeField &_Umu,
 | 
			
		||||
				  GridCartesian         &FiveDimGrid,
 | 
			
		||||
				  GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
				  GridCartesian         &FourDimGrid,
 | 
			
		||||
				  GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
				  RealD _mass,RealD _M5) :
 | 
			
		||||
   WilsonFermion5D(_Umu,
 | 
			
		||||
		   FiveDimGrid,
 | 
			
		||||
		   FiveDimRedBlackGrid,
 | 
			
		||||
		   FourDimGrid,
 | 
			
		||||
		   FourDimRedBlackGrid,_M5),
 | 
			
		||||
   mass(_mass)
 | 
			
		||||
 {
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
  // override multiply
 | 
			
		||||
  RealD CayleyFermion5D::M    (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
  {
 | 
			
		||||
    LatticeFermion Din(psi._grid);
 | 
			
		||||
 | 
			
		||||
    // Assemble Din
 | 
			
		||||
    for(int s=0;s<Ls;s++){
 | 
			
		||||
      if ( s==0 ) {
 | 
			
		||||
	//	Din = bs psi[s] + cs[s] psi[s+1}
 | 
			
		||||
	axpby_ssp_pminus(Din,bs[s],psi,cs[s],psi,s,s+1);
 | 
			
		||||
	//      Din+= -mass*cs[s] psi[s+1}
 | 
			
		||||
	axpby_ssp_pplus (Din,1.0,Din,-mass*cs[s],psi,s,Ls-1);
 | 
			
		||||
      } else if ( s==(Ls-1)) { 
 | 
			
		||||
	axpby_ssp_pminus(Din,bs[s],psi,-mass*cs[s],psi,s,0);
 | 
			
		||||
	axpby_ssp_pplus (Din,1.0,Din,cs[s],psi,s,s-1);
 | 
			
		||||
      } else {
 | 
			
		||||
	axpby_ssp_pminus(Din,bs[s],psi,cs[s],psi,s,s+1);
 | 
			
		||||
	axpby_ssp_pplus(Din,1.0,Din,cs[s],psi,s,s-1);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DW(Din,chi,DaggerNo);
 | 
			
		||||
    // ((b D_W + D_w hop terms +1) on s-diag
 | 
			
		||||
    axpby(chi,1.0,1.0,chi,psi); 
 | 
			
		||||
 | 
			
		||||
    for(int s=0;s<Ls;s++){
 | 
			
		||||
      if ( s==0 ){
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,-1.0,psi,s,s+1);
 | 
			
		||||
	axpby_ssp_pplus (chi,1.0,chi,mass,psi,s,Ls-1);
 | 
			
		||||
      } else if ( s==(Ls-1)) {
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,mass,psi,s,0);
 | 
			
		||||
	axpby_ssp_pplus (chi,1.0,chi,-1.0,psi,s,s-1);
 | 
			
		||||
      } else {
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,-1.0,psi,s,s+1);
 | 
			
		||||
	axpby_ssp_pplus (chi,1.0,chi,-1.0,psi,s,s-1);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return norm2(chi);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  RealD CayleyFermion5D::Mdag (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
  {
 | 
			
		||||
    // Under adjoint
 | 
			
		||||
    //D1+        D1- P-    ->   D1+^dag   P+ D2-^dag
 | 
			
		||||
    //D2- P+     D2+            P-D1-^dag D2+dag
 | 
			
		||||
 | 
			
		||||
    LatticeFermion Din(psi._grid);
 | 
			
		||||
    // Apply Dw
 | 
			
		||||
    DW(psi,Din,DaggerYes); 
 | 
			
		||||
 | 
			
		||||
    for(int s=0;s<Ls;s++){
 | 
			
		||||
      // Collect the terms in DW
 | 
			
		||||
      //	Chi = bs Din[s] + cs[s] Din[s+1}
 | 
			
		||||
      //    Chi+= -mass*cs[s] psi[s+1}
 | 
			
		||||
      if ( s==0 ) {
 | 
			
		||||
	axpby_ssp_pplus (chi,bs[s],Din,cs[s+1],Din,s,s+1);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,-mass*cs[Ls-1],Din,s,Ls-1);
 | 
			
		||||
      } else if ( s==(Ls-1)) { 
 | 
			
		||||
	axpby_ssp_pplus (chi,bs[s],Din,-mass*cs[0],Din,s,0);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,cs[s-1],Din,s,s-1);
 | 
			
		||||
      } else {
 | 
			
		||||
	axpby_ssp_pplus (chi,bs[s],Din,cs[s+1],Din,s,s+1);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,cs[s-1],Din,s,s-1);
 | 
			
		||||
      }
 | 
			
		||||
      // Collect the terms indept of DW
 | 
			
		||||
      if ( s==0 ){
 | 
			
		||||
	axpby_ssp_pplus (chi,1.0,chi,-1.0,psi,s,s+1);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,mass,psi,s,Ls-1);
 | 
			
		||||
      } else if ( s==(Ls-1)) {
 | 
			
		||||
	axpby_ssp_pplus (chi,1.0,chi,mass,psi,s,0);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,-1.0,psi,s,s-1);
 | 
			
		||||
      } else {
 | 
			
		||||
	axpby_ssp_pplus(chi,1.0,chi,-1.0,psi,s,s+1);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,-1.0,psi,s,s-1);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // ((b D_W + D_w hop terms +1) on s-diag
 | 
			
		||||
    axpby (chi,1.0,1.0,chi,psi); 
 | 
			
		||||
    return norm2(chi);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // half checkerboard operations
 | 
			
		||||
  void CayleyFermion5D::Meooe       (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
  {
 | 
			
		||||
    LatticeFermion tmp(psi._grid);
 | 
			
		||||
    // Assemble the 5d matrix
 | 
			
		||||
    for(int s=0;s<Ls;s++){
 | 
			
		||||
      if ( s==0 ) {
 | 
			
		||||
	//	tmp = bs psi[s] + cs[s] psi[s+1}
 | 
			
		||||
	//      tmp+= -mass*cs[s] psi[s+1}
 | 
			
		||||
	axpby_ssp_pminus(tmp,beo[s],psi,-ceo[s],psi ,s, s+1);
 | 
			
		||||
	axpby_ssp_pplus(tmp,1.0,tmp,mass*ceo[s],psi,s,Ls-1);
 | 
			
		||||
      } else if ( s==(Ls-1)) { 
 | 
			
		||||
	axpby_ssp_pminus(tmp,beo[s],psi,mass*ceo[s],psi,s,0);
 | 
			
		||||
	axpby_ssp_pplus(tmp,1.0,tmp,-ceo[s],psi,s,s-1);
 | 
			
		||||
      } else {
 | 
			
		||||
	axpby_ssp_pminus(tmp,beo[s],psi,-ceo[s],psi,s,s+1);
 | 
			
		||||
	axpby_ssp_pplus (tmp,1.0,tmp,-ceo[s],psi,s,s-1);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // Apply 4d dslash
 | 
			
		||||
    if ( psi.checkerboard == Odd ) {
 | 
			
		||||
      DhopEO(tmp,chi,DaggerNo);
 | 
			
		||||
    } else {
 | 
			
		||||
      DhopOE(tmp,chi,DaggerNo);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void CayleyFermion5D::MeooeDag    (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
  {
 | 
			
		||||
    LatticeFermion tmp(psi._grid);
 | 
			
		||||
    // Apply 4d dslash
 | 
			
		||||
    if ( psi.checkerboard == Odd ) {
 | 
			
		||||
      DhopEO(psi,tmp,DaggerYes);
 | 
			
		||||
    } else {
 | 
			
		||||
      DhopOE(psi,tmp,DaggerYes);
 | 
			
		||||
    }
 | 
			
		||||
    // Assemble the 5d matrix
 | 
			
		||||
    for(int s=0;s<Ls;s++){
 | 
			
		||||
      if ( s==0 ) {
 | 
			
		||||
	axpby_ssp_pplus(chi,beo[s],tmp,   -ceo[s+1]  ,tmp,s,s+1);
 | 
			
		||||
	axpby_ssp_pminus(chi,   1.0,chi,mass*ceo[Ls-1],tmp,s,Ls-1);
 | 
			
		||||
      } else if ( s==(Ls-1)) { 
 | 
			
		||||
	axpby_ssp_pplus(chi,beo[s],tmp,mass*ceo[0],tmp,s,0);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,-ceo[s-1],tmp,s,s-1);
 | 
			
		||||
      } else {
 | 
			
		||||
	axpby_ssp_pplus(chi,beo[s],tmp,-ceo[s+1],tmp,s,s+1);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0   ,chi,-ceo[s-1],tmp,s,s-1);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void CayleyFermion5D::Mooee       (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
  {
 | 
			
		||||
    for (int s=0;s<Ls;s++){
 | 
			
		||||
      if ( s==0 ) {
 | 
			
		||||
	axpby_ssp_pminus(chi,bee[s],psi ,-cee[s],psi,s,s+1);
 | 
			
		||||
	axpby_ssp_pplus (chi,1.0,chi,mass*cee[s],psi,s,Ls-1);
 | 
			
		||||
      } else if ( s==(Ls-1)) { 
 | 
			
		||||
	axpby_ssp_pminus(chi,bee[s],psi,mass*cee[s],psi,s,0);
 | 
			
		||||
	axpby_ssp_pplus (chi,1.0,chi,-cee[s],psi,s,s-1);
 | 
			
		||||
      } else {
 | 
			
		||||
	axpby_ssp_pminus(chi,bee[s],psi,-cee[s],psi,s,s+1);
 | 
			
		||||
	axpby_ssp_pplus (chi,1.0,chi,-cee[s],psi,s,s-1);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void CayleyFermion5D::MooeeDag    (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
  {
 | 
			
		||||
    for (int s=0;s<Ls;s++){
 | 
			
		||||
      // Assemble the 5d matrix
 | 
			
		||||
      if ( s==0 ) {
 | 
			
		||||
	axpby_ssp_pplus(chi,bee[s],psi,-cee[s+1]  ,psi,s,s+1);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,mass*cee[Ls-1],psi,s,Ls-1);
 | 
			
		||||
      } else if ( s==(Ls-1)) { 
 | 
			
		||||
	axpby_ssp_pplus(chi,bee[s],psi,mass*cee[0],psi,s,0);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0,chi,-cee[s-1],psi,s,s-1);
 | 
			
		||||
      } else {
 | 
			
		||||
	axpby_ssp_pplus(chi,bee[s],psi,-cee[s+1],psi,s,s+1);
 | 
			
		||||
	axpby_ssp_pminus(chi,1.0   ,chi,-cee[s-1],psi,s,s-1);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void CayleyFermion5D::MooeeInv    (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
  {
 | 
			
		||||
    // Apply (L^{\prime})^{-1}
 | 
			
		||||
    axpby_ssp (chi,1.0,psi,     0.0,psi,0,0);      // chi[0]=psi[0]
 | 
			
		||||
    for (int s=1;s<Ls;s++){
 | 
			
		||||
      axpby_ssp_pplus(chi,1.0,psi,-lee[s-1],chi,s,s-1);// recursion Psi[s] -lee P_+ chi[s-1]
 | 
			
		||||
    }
 | 
			
		||||
    // L_m^{-1} 
 | 
			
		||||
    for (int s=0;s<Ls-1;s++){ // Chi[ee] = 1 - sum[s<Ls-1] -leem[s]P_- chi
 | 
			
		||||
      axpby_ssp_pminus(chi,1.0,chi,-leem[s],chi,Ls-1,s);
 | 
			
		||||
    }
 | 
			
		||||
    // U_m^{-1} D^{-1}
 | 
			
		||||
    for (int s=0;s<Ls-1;s++){
 | 
			
		||||
      // Chi[s] + 1/d chi[s] 
 | 
			
		||||
      axpby_ssp_pplus(chi,1.0/dee[s],chi,-ueem[s]/dee[Ls-1],chi,s,Ls-1);
 | 
			
		||||
    }	
 | 
			
		||||
    axpby_ssp(chi,1.0/dee[Ls-1],chi,0.0,chi,Ls-1,Ls-1); // Modest avoidable 
 | 
			
		||||
    
 | 
			
		||||
    // Apply U^{-1}
 | 
			
		||||
    for (int s=Ls-2;s>=0;s--){
 | 
			
		||||
      axpby_ssp_pminus (chi,1.0,chi,-uee[s],chi,s,s+1);  // chi[Ls]
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void CayleyFermion5D::MooeeInvDag (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
  {
 | 
			
		||||
    // Apply (U^{\prime})^{-dagger}
 | 
			
		||||
    axpby_ssp (chi,1.0,psi,     0.0,psi,0,0);      // chi[0]=psi[0]
 | 
			
		||||
    for (int s=1;s<Ls;s++){
 | 
			
		||||
      axpby_ssp_pminus(chi,1.0,psi,-uee[s-1],chi,s,s-1);
 | 
			
		||||
    }
 | 
			
		||||
    // U_m^{-\dagger} 
 | 
			
		||||
    for (int s=0;s<Ls-1;s++){
 | 
			
		||||
      axpby_ssp_pplus(chi,1.0,chi,-ueem[s],chi,Ls-1,s);
 | 
			
		||||
    }
 | 
			
		||||
    // L_m^{-\dagger} D^{-dagger}
 | 
			
		||||
    for (int s=0;s<Ls-1;s++){
 | 
			
		||||
      axpby_ssp_pminus(chi,1.0/dee[s],chi,-leem[s]/dee[Ls-1],chi,s,Ls-1);
 | 
			
		||||
    }	
 | 
			
		||||
    axpby_ssp(chi,1.0/dee[Ls-1],chi,0.0,chi,Ls-1,Ls-1); // Modest avoidable 
 | 
			
		||||
    
 | 
			
		||||
    // Apply L^{-dagger}
 | 
			
		||||
    for (int s=Ls-2;s>=0;s--){
 | 
			
		||||
      axpby_ssp_pplus (chi,1.0,chi,-lee[s],chi,s,s+1);  // chi[Ls]
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // 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)
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
    ///////////////////////////////////////////////////////////
 | 
			
		||||
    // The Cayley coeffs (unprec)
 | 
			
		||||
    ///////////////////////////////////////////////////////////
 | 
			
		||||
    omega.resize(Ls);
 | 
			
		||||
    bs.resize(Ls);
 | 
			
		||||
    cs.resize(Ls);
 | 
			
		||||
    as.resize(Ls);
 | 
			
		||||
    
 | 
			
		||||
    // 
 | 
			
		||||
    // Ts = (    [bs+cs]Dw        )^-1 (    (bs+cs) Dw         )
 | 
			
		||||
    //     -(g5  -------       -1 )    ( g5 ---------     + 1  )
 | 
			
		||||
    //      (   {2+(bs-cs)Dw}     )    (    2+(bs-cs) Dw       )
 | 
			
		||||
    //
 | 
			
		||||
    //  bs = 1/2( (1/omega_s + 1)*b + (1/omega - 1)*c ) = 1/2(  1/omega(b+c) + (b-c) )
 | 
			
		||||
    //  cs = 1/2( (1/omega_s - 1)*b + (1/omega + 1)*c ) = 1/2(  1/omega(b+c) - (b-c) )
 | 
			
		||||
    //
 | 
			
		||||
    // bs+cs = 0.5*( 1/omega(b+c) + (b-c) + 1/omega(b+c) - (b-c) ) = 1/omega(b+c)
 | 
			
		||||
    // bs-cs = 0.5*( 1/omega(b+c) + (b-c) - 1/omega(b+c) + (b-c) ) = b-c
 | 
			
		||||
    //
 | 
			
		||||
    // So 
 | 
			
		||||
    //
 | 
			
		||||
    // Ts = (    [b+c]Dw/omega_s    )^-1 (    (b+c) Dw /omega_s        )
 | 
			
		||||
    //     -(g5  -------         -1 )    ( g5 ---------           + 1  )
 | 
			
		||||
    //      (   {2+(b-c)Dw}         )    (    2+(b-c) Dw               )
 | 
			
		||||
    //
 | 
			
		||||
    // Ts = (    [b+c]Dw            )^-1 (    (b+c) Dw                 )
 | 
			
		||||
    //     -(g5  -------    -omega_s)    ( g5 ---------      + omega_s )
 | 
			
		||||
    //      (   {2+(b-c)Dw}         )    (    2+(b-c) Dw               )
 | 
			
		||||
    // 
 | 
			
		||||
    
 | 
			
		||||
    double bpc = b+c;
 | 
			
		||||
    double bmc = b-c;
 | 
			
		||||
    for(int i=0; i < Ls; i++){
 | 
			
		||||
      as[i] = 1.0;
 | 
			
		||||
      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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////////////////////
 | 
			
		||||
    // Constants for the preconditioned matrix Cayley form
 | 
			
		||||
    ////////////////////////////////////////////////////////
 | 
			
		||||
    bee.resize(Ls);
 | 
			
		||||
    cee.resize(Ls);
 | 
			
		||||
    beo.resize(Ls);
 | 
			
		||||
    ceo.resize(Ls);
 | 
			
		||||
    
 | 
			
		||||
    for(int i=0;i<Ls;i++){
 | 
			
		||||
      bee[i]=as[i]*(bs[i]*(4.0-M5) +1.0);
 | 
			
		||||
      cee[i]=as[i]*(1.0-cs[i]*(4.0-M5));
 | 
			
		||||
      beo[i]=as[i]*bs[i];
 | 
			
		||||
      ceo[i]=-as[i]*cs[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    aee.resize(Ls);
 | 
			
		||||
    aeo.resize(Ls);
 | 
			
		||||
    for(int i=0;i<Ls;i++){
 | 
			
		||||
      aee[i]=cee[i];
 | 
			
		||||
      aeo[i]=ceo[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////////////////
 | 
			
		||||
    // LDU decomposition of eeoo
 | 
			
		||||
    //////////////////////////////////////////
 | 
			
		||||
    dee.resize(Ls);
 | 
			
		||||
    lee.resize(Ls);
 | 
			
		||||
    leem.resize(Ls);
 | 
			
		||||
    uee.resize(Ls);
 | 
			
		||||
    ueem.resize(Ls);
 | 
			
		||||
    
 | 
			
		||||
    for(int i=0;i<Ls;i++){
 | 
			
		||||
      
 | 
			
		||||
      dee[i] = bee[i];
 | 
			
		||||
      
 | 
			
		||||
      if ( i < Ls-1 ) {
 | 
			
		||||
	
 | 
			
		||||
	lee[i] =-cee[i+1]/bee[i]; // sub-diag entry on the ith column
 | 
			
		||||
	    
 | 
			
		||||
	leem[i]=mass*cee[Ls-1]/bee[0];
 | 
			
		||||
	for(int j=0;j<i;j++)  leem[i]*= aee[j]/bee[j+1];
 | 
			
		||||
	
 | 
			
		||||
	uee[i] =-aee[i]/bee[i];   // up-diag entry on the ith row
 | 
			
		||||
	
 | 
			
		||||
	ueem[i]=mass;
 | 
			
		||||
	for(int j=1;j<=i;j++) ueem[i]*= cee[j]/bee[j];
 | 
			
		||||
	ueem[i]*= aee[0]/bee[0];
 | 
			
		||||
	    
 | 
			
		||||
      } else { 
 | 
			
		||||
	lee[i] =0.0;
 | 
			
		||||
	leem[i]=0.0;
 | 
			
		||||
	uee[i] =0.0;
 | 
			
		||||
	ueem[i]=0.0;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
	
 | 
			
		||||
    { 
 | 
			
		||||
      double delta_d=mass*cee[Ls-1];
 | 
			
		||||
      for(int j=0;j<Ls-1;j++) delta_d *= cee[j]/bee[j];
 | 
			
		||||
      dee[Ls-1] += delta_d;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								lib/qcd/action/fermion/CayleyFermion5D.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								lib/qcd/action/fermion/CayleyFermion5D.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
#ifndef  GRID_QCD_CAYLEY_FERMION_H
 | 
			
		||||
#define  GRID_QCD_CAYLEY_FERMION_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class CayleyFermion5D : public WilsonFermion5D
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      // override multiply
 | 
			
		||||
      virtual RealD  M    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual RealD  Mdag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // half checkerboard operations
 | 
			
		||||
      virtual void   Meooe       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MeooeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   Mooee       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      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;
 | 
			
		||||
 | 
			
		||||
      // Cayley form Moebius (tanh and zolotarev)
 | 
			
		||||
      std::vector<RealD> omega; 
 | 
			
		||||
      std::vector<RealD> bs;    // S dependent coeffs
 | 
			
		||||
      std::vector<RealD> cs;    
 | 
			
		||||
      std::vector<RealD> as;    
 | 
			
		||||
      // For preconditioning Cayley form
 | 
			
		||||
      std::vector<RealD> bee;    
 | 
			
		||||
      std::vector<RealD> cee;    
 | 
			
		||||
      std::vector<RealD> aee;    
 | 
			
		||||
      std::vector<RealD> beo;    
 | 
			
		||||
      std::vector<RealD> ceo;    
 | 
			
		||||
      std::vector<RealD> aeo;    
 | 
			
		||||
      // LDU factorisation of the eeoo matrix
 | 
			
		||||
      std::vector<RealD> lee;    
 | 
			
		||||
      std::vector<RealD> leem;    
 | 
			
		||||
      std::vector<RealD> uee;    
 | 
			
		||||
      std::vector<RealD> ueem;    
 | 
			
		||||
      std::vector<RealD> dee;    
 | 
			
		||||
 | 
			
		||||
      // Constructors
 | 
			
		||||
      CayleyFermion5D(LatticeGaugeField &_Umu,
 | 
			
		||||
		      GridCartesian         &FiveDimGrid,
 | 
			
		||||
		      GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
		      GridCartesian         &FourDimGrid,
 | 
			
		||||
		      GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
		      RealD _mass,RealD _M5);
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
      void SetCoefficientsZolotarev(RealD zolohi,Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
			
		||||
      void SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										171
									
								
								lib/qcd/action/fermion/ContinuedFractionFermion5D.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								lib/qcd/action/fermion/ContinuedFractionFermion5D.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,171 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    void ContinuedFractionFermion5D::SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD scale)
 | 
			
		||||
    {
 | 
			
		||||
      SetCoefficientsZolotarev(1.0/scale,zdata);
 | 
			
		||||
    }
 | 
			
		||||
    void ContinuedFractionFermion5D::SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata)
 | 
			
		||||
    {
 | 
			
		||||
      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);
 | 
			
		||||
 | 
			
		||||
      DW(psi,D,DaggerNo); 
 | 
			
		||||
 | 
			
		||||
      int sign=1;
 | 
			
		||||
      for(int s=0;s<Ls;s++){
 | 
			
		||||
	if ( s==0 ) {
 | 
			
		||||
	  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]*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*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; 
 | 
			
		||||
      }
 | 
			
		||||
      return norm2(chi);
 | 
			
		||||
    }
 | 
			
		||||
    RealD  ContinuedFractionFermion5D::Mdag        (const LatticeFermion &psi, LatticeFermion &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);
 | 
			
		||||
    }
 | 
			
		||||
    void   ContinuedFractionFermion5D::Meooe       (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
    {
 | 
			
		||||
      // 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]*ZoloHiInv,chi,0.0,chi,s,s);
 | 
			
		||||
	} else {
 | 
			
		||||
	  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)
 | 
			
		||||
    {
 | 
			
		||||
      Meooe(psi,chi);
 | 
			
		||||
    }
 | 
			
		||||
    void   ContinuedFractionFermion5D::Mooee       (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
    {
 | 
			
		||||
      double dw_diag = (4.0-M5)*ZoloHiInv;
 | 
			
		||||
    
 | 
			
		||||
      int sign=1;
 | 
			
		||||
      for(int s=0;s<Ls;s++){
 | 
			
		||||
	if ( s==0 ) {
 | 
			
		||||
	  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+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 {
 | 
			
		||||
	  ag5xpby_ssp(chi,cc[s]*Beta[s]*sign*dw_diag,psi,sqrt_cc[s],psi,s,s+1);
 | 
			
		||||
	  axpby_ssp(chi,1.0,chi,sqrt_cc[s-1],psi,s,s-1);
 | 
			
		||||
	}
 | 
			
		||||
	sign=-sign; 
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void   ContinuedFractionFermion5D::MooeeDag    (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
    {
 | 
			
		||||
      Mooee(psi,chi);
 | 
			
		||||
    }
 | 
			
		||||
    void   ContinuedFractionFermion5D::MooeeInv    (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
    {
 | 
			
		||||
      // Apply Linv
 | 
			
		||||
      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);
 | 
			
		||||
      }
 | 
			
		||||
      // Apply Dinv
 | 
			
		||||
      for(int s=0;s<Ls;s++){
 | 
			
		||||
	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,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);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    void   ContinuedFractionFermion5D::MooeeInvDag (const LatticeFermion &psi, LatticeFermion &chi)
 | 
			
		||||
    {
 | 
			
		||||
      MooeeInv(psi,chi);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Constructors
 | 
			
		||||
    ContinuedFractionFermion5D::ContinuedFractionFermion5D(
 | 
			
		||||
							   LatticeGaugeField &_Umu,
 | 
			
		||||
							   GridCartesian         &FiveDimGrid,
 | 
			
		||||
							   GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
							   GridCartesian         &FourDimGrid,
 | 
			
		||||
							   GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
							   RealD _mass,RealD M5) :
 | 
			
		||||
      WilsonFermion5D(_Umu,
 | 
			
		||||
		      FiveDimGrid, FiveDimRedBlackGrid,
 | 
			
		||||
		      FourDimGrid, FourDimRedBlackGrid,M5),
 | 
			
		||||
      mass(_mass)
 | 
			
		||||
    {
 | 
			
		||||
      assert((Ls&0x1)==1); // Odd Ls required
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										59
									
								
								lib/qcd/action/fermion/ContinuedFractionFermion5D.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								lib/qcd/action/fermion/ContinuedFractionFermion5D.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
#ifndef  GRID_QCD_CONTINUED_FRACTION_H
 | 
			
		||||
#define  GRID_QCD_CONTINUED_FRACTION_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class ContinuedFractionFermion5D : public WilsonFermion5D
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      // override multiply
 | 
			
		||||
      virtual RealD  M    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual RealD  Mdag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // half checkerboard operaions
 | 
			
		||||
      virtual void   Meooe       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MeooeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   Mooee       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      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;
 | 
			
		||||
      virtual void   Instantiatable(void) =0;
 | 
			
		||||
 | 
			
		||||
      // Constructors
 | 
			
		||||
      ContinuedFractionFermion5D(LatticeGaugeField &_Umu,
 | 
			
		||||
				 GridCartesian         &FiveDimGrid,
 | 
			
		||||
				 GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
				 GridCartesian         &FourDimGrid,
 | 
			
		||||
				 GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
				 RealD _mass,RealD M5);
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
 | 
			
		||||
      void SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD scale);
 | 
			
		||||
      void SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata);;
 | 
			
		||||
 | 
			
		||||
      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;
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										46
									
								
								lib/qcd/action/fermion/DomainWallFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								lib/qcd/action/fermion/DomainWallFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
#ifndef  GRID_QCD_DOMAIN_WALL_FERMION_H
 | 
			
		||||
#define  GRID_QCD_DOMAIN_WALL_FERMION_H
 | 
			
		||||
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class DomainWallFermion : public CayleyFermion5D
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      virtual void   Instantiatable(void) {};
 | 
			
		||||
      // Constructors
 | 
			
		||||
      DomainWallFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
			GridCartesian         &FiveDimGrid,
 | 
			
		||||
			GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
			GridCartesian         &FourDimGrid,
 | 
			
		||||
			GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
			RealD _mass,RealD _M5) : 
 | 
			
		||||
 | 
			
		||||
      CayleyFermion5D(_Umu,
 | 
			
		||||
		      FiveDimGrid,
 | 
			
		||||
		      FiveDimRedBlackGrid,
 | 
			
		||||
		      FourDimGrid,
 | 
			
		||||
		      FourDimRedBlackGrid,_mass,_M5)
 | 
			
		||||
 | 
			
		||||
      {
 | 
			
		||||
	RealD eps = 1.0;
 | 
			
		||||
 | 
			
		||||
	Approx::zolotarev_data *zdata = Approx::grid_higham(eps,this->Ls);// eps is ignored for higham
 | 
			
		||||
	assert(zdata->n==this->Ls);
 | 
			
		||||
	
 | 
			
		||||
	std::cout << "DomainWallFermion with Ls="<<Ls<<std::endl;
 | 
			
		||||
	// Call base setter
 | 
			
		||||
	this->CayleyFermion5D::SetCoefficientsTanh(zdata,1.0,0.0);
 | 
			
		||||
 
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										48
									
								
								lib/qcd/action/fermion/FermionOperator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								lib/qcd/action/fermion/FermionOperator.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
#ifndef  GRID_QCD_FERMION_OPERATOR_H
 | 
			
		||||
#define  GRID_QCD_FERMION_OPERATOR_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Four component fermions
 | 
			
		||||
    // Should type template the vector and gauge types
 | 
			
		||||
    // Think about multiple representations
 | 
			
		||||
    //////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    template<class FermionField,class GaugeField>
 | 
			
		||||
    class FermionOperator : public CheckerBoardedSparseMatrixBase<FermionField>
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      GridBase * Grid(void)   { return FermionGrid(); };   // this is all the linalg routines need to know
 | 
			
		||||
      GridBase * RedBlackGrid(void) { return FermionRedBlackGrid(); };
 | 
			
		||||
 | 
			
		||||
      virtual GridBase *FermionGrid(void)         =0;
 | 
			
		||||
      virtual GridBase *FermionRedBlackGrid(void) =0;
 | 
			
		||||
      virtual GridBase *GaugeGrid(void)           =0;
 | 
			
		||||
      virtual GridBase *GaugeRedBlackGrid(void)   =0;
 | 
			
		||||
 | 
			
		||||
      // override multiply
 | 
			
		||||
      virtual RealD  M    (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual RealD  Mdag (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
 | 
			
		||||
      // half checkerboard operaions
 | 
			
		||||
      virtual void   Meooe       (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual void   MeooeDag    (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual void   Mooee       (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual void   MooeeDag    (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual void   MooeeInv    (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
      virtual void   MooeeInvDag (const FermionField &in, FermionField &out)=0;
 | 
			
		||||
 | 
			
		||||
      // non-hermitian hopping term; half cb or both
 | 
			
		||||
      virtual void Dhop  (const FermionField &in, FermionField &out,int dag)=0;
 | 
			
		||||
      virtual void DhopOE(const FermionField &in, FermionField &out,int dag)=0;
 | 
			
		||||
      virtual void DhopEO(const FermionField &in, FermionField &out,int dag)=0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										47
									
								
								lib/qcd/action/fermion/MobiusFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								lib/qcd/action/fermion/MobiusFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
#ifndef  GRID_QCD_MOBIUS_FERMION_H
 | 
			
		||||
#define  GRID_QCD_MOBIUS_FERMION_H
 | 
			
		||||
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class MobiusFermion : public CayleyFermion5D
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      virtual void   Instantiatable(void) {};
 | 
			
		||||
      // Constructors
 | 
			
		||||
      MobiusFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
		    GridCartesian         &FiveDimGrid,
 | 
			
		||||
		    GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
		    GridCartesian         &FourDimGrid,
 | 
			
		||||
		    GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
		    RealD _mass,RealD _M5,
 | 
			
		||||
		    RealD b, RealD c) : 
 | 
			
		||||
      
 | 
			
		||||
      CayleyFermion5D(_Umu,
 | 
			
		||||
		      FiveDimGrid,
 | 
			
		||||
		      FiveDimRedBlackGrid,
 | 
			
		||||
		      FourDimGrid,
 | 
			
		||||
		      FourDimRedBlackGrid,_mass,_M5)
 | 
			
		||||
 | 
			
		||||
      {
 | 
			
		||||
	RealD eps = 1.0;
 | 
			
		||||
 | 
			
		||||
	std::cout << "MobiusFermion (b="<<b<<",c="<<c<<") with Ls= "<<Ls<<" Tanh approx"<<std::endl;
 | 
			
		||||
	Approx::zolotarev_data *zdata = Approx::grid_higham(eps,this->Ls);// eps is ignored for higham
 | 
			
		||||
	assert(zdata->n==this->Ls);
 | 
			
		||||
	
 | 
			
		||||
	// Call base setter
 | 
			
		||||
	this->CayleyFermion5D::SetCoefficientsTanh(zdata,b,c);
 | 
			
		||||
 
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										49
									
								
								lib/qcd/action/fermion/MobiusZolotarevFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								lib/qcd/action/fermion/MobiusZolotarevFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
#ifndef  GRID_QCD_MOBIUS_ZOLOTAREV_FERMION_H
 | 
			
		||||
#define  GRID_QCD_MOBIUS_ZOLOTAREV_FERMION_H
 | 
			
		||||
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class MobiusZolotarevFermion : public CayleyFermion5D
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      virtual void   Instantiatable(void) {};
 | 
			
		||||
      // Constructors
 | 
			
		||||
       MobiusZolotarevFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
			      GridCartesian         &FiveDimGrid,
 | 
			
		||||
			      GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
			      GridCartesian         &FourDimGrid,
 | 
			
		||||
			      GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
			      RealD _mass,RealD _M5,
 | 
			
		||||
			      RealD b, RealD c,
 | 
			
		||||
			      RealD lo, RealD hi) : 
 | 
			
		||||
      
 | 
			
		||||
      CayleyFermion5D(_Umu,
 | 
			
		||||
		      FiveDimGrid,
 | 
			
		||||
		      FiveDimRedBlackGrid,
 | 
			
		||||
		      FourDimGrid,
 | 
			
		||||
		      FourDimRedBlackGrid,_mass,_M5)
 | 
			
		||||
 | 
			
		||||
      {
 | 
			
		||||
	RealD eps = lo/hi;
 | 
			
		||||
 | 
			
		||||
	Approx::zolotarev_data *zdata = Approx::grid_zolotarev(eps,this->Ls,0);// eps is ignored for higham
 | 
			
		||||
	assert(zdata->n==this->Ls);
 | 
			
		||||
 | 
			
		||||
	std::cout << "MobiusZolotarevFermion (b="<<b<<",c="<<c<<") with Ls= "<<Ls<<" Zolotarev range ["<<lo<<","<<hi<<"]"<<std::endl;
 | 
			
		||||
	
 | 
			
		||||
	// Call base setter
 | 
			
		||||
	this->CayleyFermion5D::SetCoefficientsZolotarev(hi,zdata,b,c);
 | 
			
		||||
 
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										34
									
								
								lib/qcd/action/fermion/OverlapWilsonCayleyTanhFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								lib/qcd/action/fermion/OverlapWilsonCayleyTanhFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
#ifndef OVERLAP_WILSON_CAYLEY_TANH_FERMION_H
 | 
			
		||||
#define OVERLAP_WILSON_CAYLEY_TANH_FERMION_H
 | 
			
		||||
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class OverlapWilsonCayleyTanhFermion : public MobiusFermion
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      // Constructors
 | 
			
		||||
    OverlapWilsonCayleyTanhFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
				   GridCartesian         &FiveDimGrid,
 | 
			
		||||
				   GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
				   GridCartesian         &FourDimGrid,
 | 
			
		||||
				   GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
				   RealD _mass,RealD _M5,
 | 
			
		||||
				   RealD scale) :
 | 
			
		||||
      
 | 
			
		||||
      // b+c=scale, b-c = 0 <=> b =c = scale/2
 | 
			
		||||
      MobiusFermion(_Umu,
 | 
			
		||||
		    FiveDimGrid,
 | 
			
		||||
		    FiveDimRedBlackGrid,
 | 
			
		||||
		    FourDimGrid,
 | 
			
		||||
		    FourDimRedBlackGrid,_mass,_M5,0.5*scale,0.5*scale)
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										37
									
								
								lib/qcd/action/fermion/OverlapWilsonCayleyZolotarevFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/qcd/action/fermion/OverlapWilsonCayleyZolotarevFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
#ifndef  OVERLAP_WILSON_CAYLEY_ZOLOTAREV_FERMION_H
 | 
			
		||||
#define  OVERLAP_WILSON_CAYLEY_ZOLOTAREV_FERMION_H
 | 
			
		||||
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class OverlapWilsonCayleyZolotarevFermion : public MobiusZolotarevFermion
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      // Constructors
 | 
			
		||||
 | 
			
		||||
    OverlapWilsonCayleyZolotarevFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
					GridCartesian         &FiveDimGrid,
 | 
			
		||||
					GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
					GridCartesian         &FourDimGrid,
 | 
			
		||||
					GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
					RealD _mass,RealD _M5,
 | 
			
		||||
					RealD lo, RealD hi) : 
 | 
			
		||||
      // b+c=1.0, b-c = 0 <=> b =c = 1/2
 | 
			
		||||
      MobiusZolotarevFermion(_Umu,
 | 
			
		||||
			     FiveDimGrid,
 | 
			
		||||
			     FiveDimRedBlackGrid,
 | 
			
		||||
			     FourDimGrid,
 | 
			
		||||
			     FourDimRedBlackGrid,_mass,_M5,0.5,0.5,lo,hi)
 | 
			
		||||
 | 
			
		||||
      {}
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										39
									
								
								lib/qcd/action/fermion/OverlapWilsonContfracTanhFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								lib/qcd/action/fermion/OverlapWilsonContfracTanhFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
#ifndef OVERLAP_WILSON_CONTFRAC_TANH_FERMION_H
 | 
			
		||||
#define OVERLAP_WILSON_CONTFRAC_TANH_FERMION_H
 | 
			
		||||
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class OverlapWilsonContFracTanhFermion : public ContinuedFractionFermion5D
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      virtual void   Instantiatable(void){};
 | 
			
		||||
      // Constructors
 | 
			
		||||
    OverlapWilsonContFracTanhFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
				     GridCartesian         &FiveDimGrid,
 | 
			
		||||
				     GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
				     GridCartesian         &FourDimGrid,
 | 
			
		||||
				     GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
				     RealD _mass,RealD _M5,
 | 
			
		||||
				     RealD scale) :
 | 
			
		||||
      
 | 
			
		||||
      // b+c=scale, b-c = 0 <=> b =c = scale/2
 | 
			
		||||
      ContinuedFractionFermion5D(_Umu,
 | 
			
		||||
				 FiveDimGrid,
 | 
			
		||||
				 FiveDimRedBlackGrid,
 | 
			
		||||
				 FourDimGrid,
 | 
			
		||||
				 FourDimRedBlackGrid,_mass,_M5)
 | 
			
		||||
	{
 | 
			
		||||
	  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,scale);
 | 
			
		||||
	}
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,44 @@
 | 
			
		||||
#ifndef OVERLAP_WILSON_CONTFRAC_ZOLOTAREV_FERMION_H
 | 
			
		||||
#define OVERLAP_WILSON_CONTFRAC_ZOLOTAREV_FERMION_H
 | 
			
		||||
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class OverlapWilsonContFracZolotarevFermion : public ContinuedFractionFermion5D
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      virtual void   Instantiatable(void){};
 | 
			
		||||
      // Constructors
 | 
			
		||||
    OverlapWilsonContFracZolotarevFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
					  GridCartesian         &FiveDimGrid,
 | 
			
		||||
					  GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
					  GridCartesian         &FourDimGrid,
 | 
			
		||||
					  GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
					  RealD _mass,RealD _M5,
 | 
			
		||||
					  RealD lo,RealD hi):
 | 
			
		||||
      
 | 
			
		||||
      // b+c=scale, b-c = 0 <=> b =c = scale/2
 | 
			
		||||
      ContinuedFractionFermion5D(_Umu,
 | 
			
		||||
				 FiveDimGrid,
 | 
			
		||||
				 FiveDimRedBlackGrid,
 | 
			
		||||
				 FourDimGrid,
 | 
			
		||||
				 FourDimRedBlackGrid,_mass,_M5)
 | 
			
		||||
	{
 | 
			
		||||
	  assert((Ls&0x1)==1); // Odd Ls required
 | 
			
		||||
 | 
			
		||||
	  int nrational=Ls-1;// Even rational order
 | 
			
		||||
	  RealD eps = lo/hi;
 | 
			
		||||
 | 
			
		||||
	  Approx::zolotarev_data *zdata = Approx::grid_zolotarev(eps,nrational,0);
 | 
			
		||||
 | 
			
		||||
	  SetCoefficientsZolotarev(hi,zdata);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										1
									
								
								lib/qcd/action/fermion/PartialFractionFermion5D.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								lib/qcd/action/fermion/PartialFractionFermion5D.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										49
									
								
								lib/qcd/action/fermion/PartialFractionFermion5D.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								lib/qcd/action/fermion/PartialFractionFermion5D.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
#ifndef  GRID_QCD_PARTIAL_FRACTION_H
 | 
			
		||||
#define  GRID_QCD_PARTIAL_FRACTION_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class PartialFractionFermion5D : public WilsonFermion5D
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      // override multiply
 | 
			
		||||
      virtual RealD  M    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual RealD  Mdag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // half checkerboard operaions
 | 
			
		||||
      virtual void   Meooe       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MeooeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   Mooee       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeInv    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
      virtual void PartialFractionCoefficients(void);
 | 
			
		||||
 | 
			
		||||
      Approx::zolotarev_data *zdata;
 | 
			
		||||
 | 
			
		||||
      // Part frac
 | 
			
		||||
      double R;
 | 
			
		||||
      std::vector<double> p; 
 | 
			
		||||
      std::vector<double> q;
 | 
			
		||||
 | 
			
		||||
      // Constructors
 | 
			
		||||
      PartialFractionFermion5D(LatticeGaugeField &_Umu,
 | 
			
		||||
				    GridCartesian         &FiveDimGrid,
 | 
			
		||||
				    GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
				    GridCartesian         &FourDimGrid,
 | 
			
		||||
				    GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
				    RealD _mass,RealD M5);
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										37
									
								
								lib/qcd/action/fermion/ScaledShamirFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/qcd/action/fermion/ScaledShamirFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
#ifndef  GRID_QCD_SCALED_SHAMIR_FERMION_H
 | 
			
		||||
#define  GRID_QCD_SCALED_SHAMIR_FERMION_H
 | 
			
		||||
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class ScaledShamirFermion : public MobiusFermion
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      // Constructors
 | 
			
		||||
    ScaledShamirFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
			GridCartesian         &FiveDimGrid,
 | 
			
		||||
			GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
			GridCartesian         &FourDimGrid,
 | 
			
		||||
			GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
			RealD _mass,RealD _M5,
 | 
			
		||||
			RealD scale) :
 | 
			
		||||
      
 | 
			
		||||
      // b+c=scale, b-c = 1 <=> 2b = scale+1; 2c = scale-1
 | 
			
		||||
      MobiusFermion(_Umu,
 | 
			
		||||
		    FiveDimGrid,
 | 
			
		||||
		    FiveDimRedBlackGrid,
 | 
			
		||||
		    FourDimGrid,
 | 
			
		||||
		    FourDimRedBlackGrid,_mass,_M5,0.5*(scale+1.0),0.5*(scale-1.0))
 | 
			
		||||
      {
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										39
									
								
								lib/qcd/action/fermion/ShamirZolotarevFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								lib/qcd/action/fermion/ShamirZolotarevFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
#ifndef  GRID_QCD_SHAMIR_ZOLOTAREV_FERMION_H
 | 
			
		||||
#define  GRID_QCD_SHAMIR_ZOLOTAREV_FERMION_H
 | 
			
		||||
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class ShamirZolotarevFermion : public MobiusZolotarevFermion
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      // Constructors
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    ShamirZolotarevFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
			   GridCartesian         &FiveDimGrid,
 | 
			
		||||
			   GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
			   GridCartesian         &FourDimGrid,
 | 
			
		||||
			   GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
			   RealD _mass,RealD _M5,
 | 
			
		||||
			   RealD lo, RealD hi) : 
 | 
			
		||||
      
 | 
			
		||||
      // b+c = 1; b-c = 1 => b=1, c=0
 | 
			
		||||
      MobiusZolotarevFermion(_Umu,
 | 
			
		||||
			     FiveDimGrid,
 | 
			
		||||
			     FiveDimRedBlackGrid,
 | 
			
		||||
			     FourDimGrid,
 | 
			
		||||
			     FourDimRedBlackGrid,_mass,_M5,1.0,0.0,lo,hi)
 | 
			
		||||
      
 | 
			
		||||
      {}
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										61
									
								
								lib/qcd/action/fermion/WilsonCompressor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								lib/qcd/action/fermion/WilsonCompressor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
#ifndef  GRID_QCD_WILSON_COMPRESSOR_H
 | 
			
		||||
#define  GRID_QCD_WILSON_COMPRESSOR_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
  class WilsonCompressor {
 | 
			
		||||
  public:
 | 
			
		||||
    int mu;
 | 
			
		||||
    int dag;
 | 
			
		||||
 | 
			
		||||
    WilsonCompressor(int _dag){
 | 
			
		||||
      mu=0;
 | 
			
		||||
      dag=_dag;
 | 
			
		||||
      assert((dag==0)||(dag==1));
 | 
			
		||||
    }
 | 
			
		||||
    void Point(int p) { 
 | 
			
		||||
      mu=p;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    vHalfSpinColourVector operator () (const vSpinColourVector &in)
 | 
			
		||||
    {
 | 
			
		||||
      vHalfSpinColourVector ret;
 | 
			
		||||
      int mudag=mu;
 | 
			
		||||
      if (dag) {
 | 
			
		||||
	mudag=(mu+Nd)%(2*Nd);
 | 
			
		||||
      }
 | 
			
		||||
      switch(mudag) {
 | 
			
		||||
      case Xp:
 | 
			
		||||
	spProjXp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Yp:
 | 
			
		||||
	spProjYp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Zp:
 | 
			
		||||
	spProjZp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Tp:
 | 
			
		||||
	spProjTp(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Xm:
 | 
			
		||||
	spProjXm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Ym:
 | 
			
		||||
	spProjYm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Zm:
 | 
			
		||||
	spProjZm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      case Tm:
 | 
			
		||||
	spProjTm(ret,in);
 | 
			
		||||
	break;
 | 
			
		||||
      default: 
 | 
			
		||||
	assert(0);
 | 
			
		||||
	break;
 | 
			
		||||
      }
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
}} // namespace close
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										163
									
								
								lib/qcd/action/fermion/WilsonFermion.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								lib/qcd/action/fermion/WilsonFermion.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
const std::vector<int> WilsonFermion::directions   ({0,1,2,3, 0, 1, 2, 3});
 | 
			
		||||
const std::vector<int> WilsonFermion::displacements({1,1,1,1,-1,-1,-1,-1});
 | 
			
		||||
 | 
			
		||||
int WilsonFermion::HandOptDslash;
 | 
			
		||||
 | 
			
		||||
WilsonFermion::WilsonFermion(LatticeGaugeField &_Umu,
 | 
			
		||||
			     GridCartesian         &Fgrid,
 | 
			
		||||
			     GridRedBlackCartesian &Hgrid, 
 | 
			
		||||
			     RealD _mass) :
 | 
			
		||||
  _grid(&Fgrid),
 | 
			
		||||
  _cbgrid(&Hgrid),
 | 
			
		||||
  Stencil    (&Fgrid,npoint,Even,directions,displacements),
 | 
			
		||||
  StencilEven(&Hgrid,npoint,Even,directions,displacements), // source is Even
 | 
			
		||||
  StencilOdd (&Hgrid,npoint,Odd ,directions,displacements), // source is Odd
 | 
			
		||||
  mass(_mass),
 | 
			
		||||
  Umu(&Fgrid),
 | 
			
		||||
  UmuEven(&Hgrid),
 | 
			
		||||
  UmuOdd (&Hgrid)
 | 
			
		||||
{
 | 
			
		||||
  // Allocate the required comms buffer
 | 
			
		||||
  comm_buf.resize(Stencil._unified_buffer_size); // this is always big enough to contain EO
 | 
			
		||||
  DoubleStore(Umu,_Umu);
 | 
			
		||||
  pickCheckerboard(Even,UmuEven,Umu);
 | 
			
		||||
  pickCheckerboard(Odd ,UmuOdd,Umu);
 | 
			
		||||
}
 | 
			
		||||
      
 | 
			
		||||
void WilsonFermion::DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu)
 | 
			
		||||
{
 | 
			
		||||
  conformable(Uds._grid,GaugeGrid());
 | 
			
		||||
  conformable(Umu._grid,GaugeGrid());
 | 
			
		||||
  LatticeColourMatrix U(GaugeGrid());
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    U = peekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
    pokeIndex<LorentzIndex>(Uds,U,mu);
 | 
			
		||||
    U = adj(Cshift(U,mu,-1));
 | 
			
		||||
    pokeIndex<LorentzIndex>(Uds,U,mu+4);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RealD WilsonFermion::M(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard=in.checkerboard;
 | 
			
		||||
  Dhop(in,out,DaggerNo);
 | 
			
		||||
  return axpy_norm(out,4+mass,in,out);
 | 
			
		||||
}
 | 
			
		||||
RealD WilsonFermion::Mdag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard=in.checkerboard;
 | 
			
		||||
  Dhop(in,out,DaggerYes);
 | 
			
		||||
  return axpy_norm(out,4+mass,in,out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WilsonFermion::Meooe(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  if ( in.checkerboard == Odd ) {
 | 
			
		||||
    DhopEO(in,out,DaggerNo);
 | 
			
		||||
  } else {
 | 
			
		||||
    DhopOE(in,out,DaggerNo);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::MeooeDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  if ( in.checkerboard == Odd ) {
 | 
			
		||||
    DhopEO(in,out,DaggerYes);
 | 
			
		||||
  } else {
 | 
			
		||||
    DhopOE(in,out,DaggerYes);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::Mooee(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  out = (4.0+mass)*in;
 | 
			
		||||
  return ;
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::MooeeDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  Mooee(in,out);
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::MooeeInv(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  out = (1.0/(4.0+mass))*in;
 | 
			
		||||
  return ;
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::MooeeInvDag(const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
  MooeeInv(in,out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WilsonFermion::DhopInternal(CartesianStencil & st,LatticeDoubledGaugeField & U,
 | 
			
		||||
				const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
			
		||||
  WilsonCompressor compressor(dag);
 | 
			
		||||
  st.HaloExchange<vSpinColourVector,vHalfSpinColourVector,WilsonCompressor>(in,comm_buf,compressor);
 | 
			
		||||
 | 
			
		||||
  if ( dag == DaggerYes ) {
 | 
			
		||||
    if( HandOptDslash ) {
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOptHand::DhopSiteDag(st,U,comm_buf,sss,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    } else { 
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOpt::DhopSiteDag(st,U,comm_buf,sss,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    if( HandOptDslash ) {
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOptHand::DhopSite(st,U,comm_buf,sss,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    } else { 
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int sss=0;sss<in._grid->oSites();sss++){
 | 
			
		||||
        DiracOpt::DhopSite(st,U,comm_buf,sss,sss,in,out);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,_cbgrid);    // verifies half grid
 | 
			
		||||
  conformable(in._grid,out._grid); // drops the cb check
 | 
			
		||||
 | 
			
		||||
  assert(in.checkerboard==Even);
 | 
			
		||||
  out.checkerboard = Odd;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(StencilEven,UmuOdd,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,_cbgrid);    // verifies half grid
 | 
			
		||||
  conformable(in._grid,out._grid); // drops the cb check
 | 
			
		||||
 | 
			
		||||
  assert(in.checkerboard==Odd);
 | 
			
		||||
  out.checkerboard = Even;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(StencilOdd,UmuEven,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion::Dhop(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,_grid); // verifies full grid
 | 
			
		||||
  conformable(in._grid,out._grid);
 | 
			
		||||
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(Stencil,Umu,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										87
									
								
								lib/qcd/action/fermion/WilsonFermion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								lib/qcd/action/fermion/WilsonFermion.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
			
		||||
#ifndef  GRID_QCD_WILSON_FERMION_H
 | 
			
		||||
#define  GRID_QCD_WILSON_FERMION_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    class WilsonFermion : public FermionOperator<LatticeFermion,LatticeGaugeField>
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Implement the abstract base
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      GridBase *GaugeGrid(void)              { return _grid ;}
 | 
			
		||||
      GridBase *GaugeRedBlackGrid(void)      { return _cbgrid ;}
 | 
			
		||||
      GridBase *FermionGrid(void)            { return _grid;}
 | 
			
		||||
      GridBase *FermionRedBlackGrid(void)    { return _cbgrid;}
 | 
			
		||||
 | 
			
		||||
      // override multiply
 | 
			
		||||
      virtual RealD  M    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual RealD  Mdag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // half checkerboard operaions
 | 
			
		||||
      void   Meooe       (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      void   MeooeDag    (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      virtual void   Mooee       (const LatticeFermion &in, LatticeFermion &out); // remain virtual so we 
 | 
			
		||||
      virtual void   MooeeDag    (const LatticeFermion &in, LatticeFermion &out); // can derive Clover
 | 
			
		||||
      virtual void   MooeeInv    (const LatticeFermion &in, LatticeFermion &out); // from Wilson bas
 | 
			
		||||
      virtual void   MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
      // non-hermitian hopping term; half cb or both
 | 
			
		||||
      void Dhop  (const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Extra methods added by derived
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      void DhopInternal(CartesianStencil & st,
 | 
			
		||||
			LatticeDoubledGaugeField &U,
 | 
			
		||||
			const LatticeFermion &in, 
 | 
			
		||||
			LatticeFermion &out,
 | 
			
		||||
			int dag);
 | 
			
		||||
 | 
			
		||||
      // Constructor
 | 
			
		||||
      WilsonFermion(LatticeGaugeField &_Umu,GridCartesian &Fgrid,GridRedBlackCartesian &Hgrid,RealD _mass);
 | 
			
		||||
 | 
			
		||||
      // DoubleStore
 | 
			
		||||
      void DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Data members require to support the functionality
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      static int HandOptDslash; // these are a temporary hack
 | 
			
		||||
      static int MortonOrder;
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
 | 
			
		||||
      RealD                        mass;
 | 
			
		||||
 | 
			
		||||
      GridBase                     *    _grid; 
 | 
			
		||||
      GridBase                     *  _cbgrid;
 | 
			
		||||
 | 
			
		||||
      static const int npoint=8;
 | 
			
		||||
      static const std::vector<int> directions   ;
 | 
			
		||||
      static const std::vector<int> displacements;
 | 
			
		||||
 | 
			
		||||
      //Defines the stencils for even and odd
 | 
			
		||||
      CartesianStencil Stencil; 
 | 
			
		||||
      CartesianStencil StencilEven; 
 | 
			
		||||
      CartesianStencil StencilOdd; 
 | 
			
		||||
 | 
			
		||||
      // Copy of the gauge field , with even and odd subsets
 | 
			
		||||
      LatticeDoubledGaugeField Umu;
 | 
			
		||||
      LatticeDoubledGaugeField UmuEven;
 | 
			
		||||
      LatticeDoubledGaugeField UmuOdd;
 | 
			
		||||
 | 
			
		||||
      // Comms buffer
 | 
			
		||||
      std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  comm_buf;
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										186
									
								
								lib/qcd/action/fermion/WilsonFermion5D.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								lib/qcd/action/fermion/WilsonFermion5D.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,186 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
  
 | 
			
		||||
  // S-direction is INNERMOST and takes no part in the parity.
 | 
			
		||||
  const std::vector<int> WilsonFermion5D::directions   ({1,2,3,4, 1, 2, 3, 4});
 | 
			
		||||
  const std::vector<int> WilsonFermion5D::displacements({1,1,1,1,-1,-1,-1,-1});
 | 
			
		||||
 | 
			
		||||
  int WilsonFermion5D::HandOptDslash;
 | 
			
		||||
 | 
			
		||||
  // 5d lattice for DWF.
 | 
			
		||||
  WilsonFermion5D::WilsonFermion5D(LatticeGaugeField &_Umu,
 | 
			
		||||
					   GridCartesian         &FiveDimGrid,
 | 
			
		||||
					   GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
					   GridCartesian         &FourDimGrid,
 | 
			
		||||
					   GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
					   RealD _M5) :
 | 
			
		||||
  _FiveDimGrid(&FiveDimGrid),
 | 
			
		||||
  _FiveDimRedBlackGrid(&FiveDimRedBlackGrid),
 | 
			
		||||
  _FourDimGrid(&FourDimGrid),
 | 
			
		||||
  _FourDimRedBlackGrid(&FourDimRedBlackGrid),
 | 
			
		||||
  Stencil    (_FiveDimGrid,npoint,Even,directions,displacements),
 | 
			
		||||
  StencilEven(_FiveDimRedBlackGrid,npoint,Even,directions,displacements), // source is Even
 | 
			
		||||
  StencilOdd (_FiveDimRedBlackGrid,npoint,Odd ,directions,displacements), // source is Odd
 | 
			
		||||
  M5(_M5),
 | 
			
		||||
  Umu(_FourDimGrid),
 | 
			
		||||
  UmuEven(_FourDimRedBlackGrid),
 | 
			
		||||
  UmuOdd (_FourDimRedBlackGrid),
 | 
			
		||||
  Lebesgue(_FourDimGrid),
 | 
			
		||||
  LebesgueEvenOdd(_FourDimRedBlackGrid)
 | 
			
		||||
{
 | 
			
		||||
  // some assertions
 | 
			
		||||
  assert(FiveDimGrid._ndimension==5);
 | 
			
		||||
  assert(FourDimGrid._ndimension==4);
 | 
			
		||||
  
 | 
			
		||||
  assert(FiveDimRedBlackGrid._ndimension==5);
 | 
			
		||||
  assert(FourDimRedBlackGrid._ndimension==4);
 | 
			
		||||
 | 
			
		||||
  assert(FiveDimRedBlackGrid._checker_dim==1);
 | 
			
		||||
 | 
			
		||||
  // Dimension zero of the five-d is the Ls direction
 | 
			
		||||
  Ls=FiveDimGrid._fdimensions[0];
 | 
			
		||||
  assert(FiveDimRedBlackGrid._fdimensions[0]==Ls);
 | 
			
		||||
  assert(FiveDimRedBlackGrid._processors[0] ==1);
 | 
			
		||||
  assert(FiveDimRedBlackGrid._simd_layout[0]==1);
 | 
			
		||||
  assert(FiveDimGrid._processors[0]         ==1);
 | 
			
		||||
  assert(FiveDimGrid._simd_layout[0]        ==1);
 | 
			
		||||
 | 
			
		||||
  // Other dimensions must match the decomposition of the four-D fields 
 | 
			
		||||
  for(int d=0;d<4;d++){
 | 
			
		||||
    assert(FourDimRedBlackGrid._fdimensions[d]  ==FourDimGrid._fdimensions[d]);
 | 
			
		||||
    assert(FiveDimRedBlackGrid._fdimensions[d+1]==FourDimGrid._fdimensions[d]);
 | 
			
		||||
 | 
			
		||||
    assert(FourDimRedBlackGrid._processors[d]   ==FourDimGrid._processors[d]);
 | 
			
		||||
    assert(FiveDimRedBlackGrid._processors[d+1] ==FourDimGrid._processors[d]);
 | 
			
		||||
 | 
			
		||||
    assert(FourDimRedBlackGrid._simd_layout[d]  ==FourDimGrid._simd_layout[d]);
 | 
			
		||||
    assert(FiveDimRedBlackGrid._simd_layout[d+1]==FourDimGrid._simd_layout[d]);
 | 
			
		||||
 | 
			
		||||
    assert(FiveDimGrid._fdimensions[d+1]        ==FourDimGrid._fdimensions[d]);
 | 
			
		||||
    assert(FiveDimGrid._processors[d+1]         ==FourDimGrid._processors[d]);
 | 
			
		||||
    assert(FiveDimGrid._simd_layout[d+1]        ==FourDimGrid._simd_layout[d]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Allocate the required comms buffer
 | 
			
		||||
  comm_buf.resize(Stencil._unified_buffer_size); // this is always big enough to contain EO
 | 
			
		||||
  
 | 
			
		||||
  DoubleStore(Umu,_Umu);
 | 
			
		||||
  pickCheckerboard(Even,UmuEven,Umu);
 | 
			
		||||
  pickCheckerboard(Odd ,UmuOdd,Umu);
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion5D::DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu)
 | 
			
		||||
{
 | 
			
		||||
  conformable(Uds._grid,GaugeGrid());
 | 
			
		||||
  conformable(Umu._grid,GaugeGrid());
 | 
			
		||||
  LatticeColourMatrix U(GaugeGrid());
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    U = peekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
    pokeIndex<LorentzIndex>(Uds,U,mu);
 | 
			
		||||
    U = adj(Cshift(U,mu,-1));
 | 
			
		||||
    pokeIndex<LorentzIndex>(Uds,U,mu+4);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion5D::DhopInternal(CartesianStencil & st, LebesgueOrder &lo,
 | 
			
		||||
				   LatticeDoubledGaugeField & U,
 | 
			
		||||
				   const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  assert((dag==DaggerNo) ||(dag==DaggerYes));
 | 
			
		||||
 | 
			
		||||
  WilsonCompressor compressor(dag);
 | 
			
		||||
 | 
			
		||||
  st.HaloExchange<vSpinColourVector,vHalfSpinColourVector,WilsonCompressor>(in,comm_buf,compressor);
 | 
			
		||||
  
 | 
			
		||||
  // Dhop takes the 4d grid from U, and makes a 5d index for fermion
 | 
			
		||||
  // Not loop ordering and data layout.
 | 
			
		||||
  // Designed to create 
 | 
			
		||||
  // - per thread reuse in L1 cache for U
 | 
			
		||||
  // - 8 linear access unit stride streams per thread for Fermion for hw prefetchable.
 | 
			
		||||
  if ( dag == DaggerYes ) {
 | 
			
		||||
    if( HandOptDslash ) {
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int ss=0;ss<U._grid->oSites();ss++){
 | 
			
		||||
	for(int s=0;s<Ls;s++){
 | 
			
		||||
	  //int sU=lo.Reorder(ss);
 | 
			
		||||
	  int sU=ss;
 | 
			
		||||
	  int sF = s+Ls*sU;
 | 
			
		||||
	  DiracOptHand::DhopSiteDag(st,U,comm_buf,sF,sU,in,out);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
    } else { 
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int ss=0;ss<U._grid->oSites();ss++){
 | 
			
		||||
	for(int s=0;s<Ls;s++){
 | 
			
		||||
	  //	  int sU=lo.Reorder(ss);
 | 
			
		||||
	  int sU=ss;
 | 
			
		||||
	  int sF = s+Ls*sU;
 | 
			
		||||
	  DiracOpt::DhopSiteDag(st,U,comm_buf,sF,sU,in,out);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    if( HandOptDslash ) {
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int ss=0;ss<U._grid->oSites();ss++){
 | 
			
		||||
	for(int s=0;s<Ls;s++){
 | 
			
		||||
	  //	  int sU=lo.Reorder(ss);
 | 
			
		||||
	  int sU=ss;
 | 
			
		||||
	  int sF = s+Ls*sU;
 | 
			
		||||
	  DiracOptHand::DhopSite(st,U,comm_buf,sF,sU,in,out);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    } else { 
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int ss=0;ss<U._grid->oSites();ss++){
 | 
			
		||||
	for(int s=0;s<Ls;s++){
 | 
			
		||||
	  //	  int sU=lo.Reorder(ss);
 | 
			
		||||
	  int sU=ss;
 | 
			
		||||
	  int sF = s+Ls*sU; 
 | 
			
		||||
	  DiracOpt::DhopSite(st,U,comm_buf,sF,sU,in,out);
 | 
			
		||||
	}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion5D::DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,FermionRedBlackGrid());    // verifies half grid
 | 
			
		||||
  conformable(in._grid,out._grid); // drops the cb check
 | 
			
		||||
 | 
			
		||||
  assert(in.checkerboard==Even);
 | 
			
		||||
  out.checkerboard = Odd;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(StencilEven,LebesgueEvenOdd,UmuOdd,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion5D::DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,FermionRedBlackGrid());    // verifies half grid
 | 
			
		||||
  conformable(in._grid,out._grid); // drops the cb check
 | 
			
		||||
 | 
			
		||||
  assert(in.checkerboard==Odd);
 | 
			
		||||
  out.checkerboard = Even;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(StencilOdd,LebesgueEvenOdd,UmuEven,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion5D::Dhop(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  conformable(in._grid,FermionGrid()); // verifies full grid
 | 
			
		||||
  conformable(in._grid,out._grid);
 | 
			
		||||
 | 
			
		||||
  out.checkerboard = in.checkerboard;
 | 
			
		||||
 | 
			
		||||
  DhopInternal(Stencil,Lebesgue,Umu,in,out,dag);
 | 
			
		||||
}
 | 
			
		||||
void WilsonFermion5D::DW(const LatticeFermion &in, LatticeFermion &out,int dag)
 | 
			
		||||
{
 | 
			
		||||
  out.checkerboard=in.checkerboard;
 | 
			
		||||
  Dhop(in,out,dag); // -0.5 is included
 | 
			
		||||
  axpy(out,4.0-M5,in,out);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										121
									
								
								lib/qcd/action/fermion/WilsonFermion5D.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								lib/qcd/action/fermion/WilsonFermion5D.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
			
		||||
#ifndef  GRID_QCD_DWF_H
 | 
			
		||||
#define  GRID_QCD_DWF_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // This is the 4d red black case appropriate to support
 | 
			
		||||
    //
 | 
			
		||||
    // parity = (x+y+z+t)|2;
 | 
			
		||||
    // generalised five dim fermions like mobius, zolotarev etc..	
 | 
			
		||||
    //
 | 
			
		||||
    // i.e. even even contains fifth dim hopping term.
 | 
			
		||||
    //
 | 
			
		||||
    // [DIFFERS from original CPS red black implementation parity = (x+y+z+t+s)|2 ]
 | 
			
		||||
    ////////////////////////////
 | 
			
		||||
    //ContFrac:
 | 
			
		||||
    //  Ls always odd. Rational poly deg is either Ls or Ls-1
 | 
			
		||||
    //PartFrac 
 | 
			
		||||
    //  Ls always odd. Rational poly deg is either Ls or Ls-1
 | 
			
		||||
    //
 | 
			
		||||
    //Cayley: Ls always even, Rational poly deg is Ls
 | 
			
		||||
    // 
 | 
			
		||||
    // Just set nrational as Ls. Forget about Ls-1 cases.
 | 
			
		||||
    //
 | 
			
		||||
    // Require odd Ls for cont and part frac
 | 
			
		||||
    ////////////////////////////
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    class WilsonFermion5D : public FermionOperator<LatticeFermion,LatticeGaugeField>
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Implement the abstract base
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      GridBase *GaugeGrid(void)              { return _FourDimGrid ;}
 | 
			
		||||
      GridBase *GaugeRedBlackGrid(void)      { return _FourDimRedBlackGrid ;}
 | 
			
		||||
      GridBase *FermionGrid(void)            { return _FiveDimGrid;}
 | 
			
		||||
      GridBase *FermionRedBlackGrid(void)    { return _FiveDimRedBlackGrid;}
 | 
			
		||||
 | 
			
		||||
      // full checkerboard operations; leave unimplemented as abstract for now
 | 
			
		||||
      //virtual RealD  M    (const LatticeFermion &in, LatticeFermion &out)=0;
 | 
			
		||||
      //virtual RealD  Mdag (const LatticeFermion &in, LatticeFermion &out)=0;
 | 
			
		||||
 | 
			
		||||
      // half checkerboard operations; leave unimplemented as abstract for now
 | 
			
		||||
      //      virtual void   Meooe       (const LatticeFermion &in, LatticeFermion &out)=0;
 | 
			
		||||
      //      virtual void   MeooeDag    (const LatticeFermion &in, LatticeFermion &out)=0;
 | 
			
		||||
      //      virtual void   Mooee       (const LatticeFermion &in, LatticeFermion &out)=0;
 | 
			
		||||
      //      virtual void   MooeeDag    (const LatticeFermion &in, LatticeFermion &out)=0;
 | 
			
		||||
      //      virtual void   MooeeInv    (const LatticeFermion &in, LatticeFermion &out)=0;
 | 
			
		||||
      //      virtual void   MooeeInvDag (const LatticeFermion &in, LatticeFermion &out)=0;
 | 
			
		||||
 | 
			
		||||
      // Implement hopping term non-hermitian hopping term; half cb or both
 | 
			
		||||
      // Implement s-diagonal DW
 | 
			
		||||
      void DW    (const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void Dhop  (const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
      void DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // New methods added 
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      void DhopInternal(CartesianStencil & st,
 | 
			
		||||
			LebesgueOrder &lo,
 | 
			
		||||
			LatticeDoubledGaugeField &U,
 | 
			
		||||
			const LatticeFermion &in, 
 | 
			
		||||
			LatticeFermion &out,
 | 
			
		||||
			int dag);
 | 
			
		||||
 | 
			
		||||
      // Constructors
 | 
			
		||||
      WilsonFermion5D(LatticeGaugeField &_Umu,
 | 
			
		||||
			  GridCartesian         &FiveDimGrid,
 | 
			
		||||
			  GridRedBlackCartesian &FiveDimRedBlackGrid,
 | 
			
		||||
			  GridCartesian         &FourDimGrid,
 | 
			
		||||
			  GridRedBlackCartesian &FourDimRedBlackGrid,
 | 
			
		||||
			  double _M5);
 | 
			
		||||
 | 
			
		||||
      // DoubleStore
 | 
			
		||||
      void DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGaugeField &Umu);
 | 
			
		||||
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      // Data members require to support the functionality
 | 
			
		||||
      ///////////////////////////////////////////////////////////////
 | 
			
		||||
      static int HandOptDslash; // these are a temporary hack
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
 | 
			
		||||
      // Add these to the support from Wilson
 | 
			
		||||
      GridBase *_FourDimGrid;
 | 
			
		||||
      GridBase *_FourDimRedBlackGrid;
 | 
			
		||||
      GridBase *_FiveDimGrid;
 | 
			
		||||
      GridBase *_FiveDimRedBlackGrid;
 | 
			
		||||
 | 
			
		||||
      static const int npoint=8;
 | 
			
		||||
      static const std::vector<int> directions   ;
 | 
			
		||||
      static const std::vector<int> displacements;
 | 
			
		||||
 | 
			
		||||
      double                        M5;
 | 
			
		||||
      int Ls;
 | 
			
		||||
 | 
			
		||||
      //Defines the stencils for even and odd
 | 
			
		||||
      CartesianStencil Stencil; 
 | 
			
		||||
      CartesianStencil StencilEven; 
 | 
			
		||||
      CartesianStencil StencilOdd; 
 | 
			
		||||
 | 
			
		||||
      // Copy of the gauge field , with even and odd subsets
 | 
			
		||||
      LatticeDoubledGaugeField Umu;
 | 
			
		||||
      LatticeDoubledGaugeField UmuEven;
 | 
			
		||||
      LatticeDoubledGaugeField UmuOdd;
 | 
			
		||||
 | 
			
		||||
      LebesgueOrder Lebesgue;
 | 
			
		||||
      LebesgueOrder LebesgueEvenOdd;
 | 
			
		||||
 | 
			
		||||
      // Comms buffer
 | 
			
		||||
      std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  comm_buf;
 | 
			
		||||
      
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										311
									
								
								lib/qcd/action/fermion/WilsonKernels.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										311
									
								
								lib/qcd/action/fermion/WilsonKernels.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,311 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			int sF,int sU,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
    vHalfSpinColourVector  tmp;    
 | 
			
		||||
    vHalfSpinColourVector  chi;    
 | 
			
		||||
    vSpinColourVector result;
 | 
			
		||||
    vHalfSpinColourVector Uchi;
 | 
			
		||||
    int offset,local,perm, ptype;
 | 
			
		||||
 | 
			
		||||
    //#define VERBOSE( A)  if ( ss<10 ) { std::cout << "site " <<ss << " " #A " neigh " << offset << " perm "<< perm <<std::endl;}    
 | 
			
		||||
 | 
			
		||||
    // Xp
 | 
			
		||||
    int ss = sF;
 | 
			
		||||
    offset = st._offsets [Xp][ss];
 | 
			
		||||
    local  = st._is_local[Xp][ss];
 | 
			
		||||
    perm   = st._permute[Xp][ss];
 | 
			
		||||
 | 
			
		||||
    ptype  = st._permute_type[Xp];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjXp(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjXp(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Xp),&chi());
 | 
			
		||||
    spReconXp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    //    std::cout << "XP_RECON"<<std::endl;
 | 
			
		||||
    //    std::cout << result()(0)(0) <<" "<<result()(0)(1) <<" "<<result()(0)(2) <<std::endl;
 | 
			
		||||
    //    std::cout << result()(1)(0) <<" "<<result()(1)(1) <<" "<<result()(1)(2) <<std::endl;
 | 
			
		||||
    //    std::cout << result()(2)(0) <<" "<<result()(2)(1) <<" "<<result()(2)(2) <<std::endl;
 | 
			
		||||
    //    std::cout << result()(3)(0) <<" "<<result()(3)(1) <<" "<<result()(3)(2) <<std::endl;
 | 
			
		||||
 | 
			
		||||
    // Yp
 | 
			
		||||
    offset = st._offsets [Yp][ss];
 | 
			
		||||
    local  = st._is_local[Yp][ss];
 | 
			
		||||
    perm   = st._permute[Yp][ss];
 | 
			
		||||
    ptype  = st._permute_type[Yp];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjYp(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjYp(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Yp),&chi());
 | 
			
		||||
    accumReconYp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Zp
 | 
			
		||||
    offset = st._offsets [Zp][ss];
 | 
			
		||||
    local  = st._is_local[Zp][ss];
 | 
			
		||||
    perm   = st._permute[Zp][ss];
 | 
			
		||||
    ptype  = st._permute_type[Zp];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjZp(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjZp(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Zp),&chi());
 | 
			
		||||
    accumReconZp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Tp
 | 
			
		||||
    offset = st._offsets [Tp][ss];
 | 
			
		||||
    local  = st._is_local[Tp][ss];
 | 
			
		||||
    perm   = st._permute[Tp][ss];
 | 
			
		||||
    ptype  = st._permute_type[Tp];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjTp(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjTp(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Tp),&chi());
 | 
			
		||||
    accumReconTp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Xm
 | 
			
		||||
    offset = st._offsets [Xm][ss];
 | 
			
		||||
    local  = st._is_local[Xm][ss];
 | 
			
		||||
    perm   = st._permute[Xm][ss];
 | 
			
		||||
    ptype  = st._permute_type[Xm];
 | 
			
		||||
 | 
			
		||||
    if ( local && perm ) 
 | 
			
		||||
    {
 | 
			
		||||
      spProjXm(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjXm(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Xm),&chi());
 | 
			
		||||
    accumReconXm(result,Uchi);
 | 
			
		||||
    //  std::cout << "XM_RECON_ACCUM"<<std::endl;
 | 
			
		||||
    //    std::cout << result()(0)(0) <<" "<<result()(0)(1) <<" "<<result()(0)(2) <<std::endl;
 | 
			
		||||
    //    std::cout << result()(1)(0) <<" "<<result()(1)(1) <<" "<<result()(1)(2) <<std::endl;
 | 
			
		||||
    //    std::cout << result()(2)(0) <<" "<<result()(2)(1) <<" "<<result()(2)(2) <<std::endl;
 | 
			
		||||
    //    std::cout << result()(3)(0) <<" "<<result()(3)(1) <<" "<<result()(3)(2) <<std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Ym
 | 
			
		||||
    offset = st._offsets [Ym][ss];
 | 
			
		||||
    local  = st._is_local[Ym][ss];
 | 
			
		||||
    perm   = st._permute[Ym][ss];
 | 
			
		||||
    ptype  = st._permute_type[Ym];
 | 
			
		||||
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjYm(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjYm(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Ym),&chi());
 | 
			
		||||
    accumReconYm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Zm
 | 
			
		||||
    offset = st._offsets [Zm][ss];
 | 
			
		||||
    local  = st._is_local[Zm][ss];
 | 
			
		||||
    perm   = st._permute[Zm][ss];
 | 
			
		||||
    ptype  = st._permute_type[Zm];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjZm(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjZm(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Zm),&chi());
 | 
			
		||||
    accumReconZm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Tm
 | 
			
		||||
    offset = st._offsets [Tm][ss];
 | 
			
		||||
    local  = st._is_local[Tm][ss];
 | 
			
		||||
    perm   = st._permute[Tm][ss];
 | 
			
		||||
    ptype  = st._permute_type[Tm];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjTm(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjTm(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Tm),&chi());
 | 
			
		||||
    accumReconTm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    vstream(out._odata[ss],result*(-0.5));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			   std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			   int sF,int sU,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
    vHalfSpinColourVector  tmp;    
 | 
			
		||||
    vHalfSpinColourVector  chi;    
 | 
			
		||||
    vSpinColourVector result;
 | 
			
		||||
    vHalfSpinColourVector Uchi;
 | 
			
		||||
    int offset,local,perm, ptype;
 | 
			
		||||
 | 
			
		||||
    // Xp
 | 
			
		||||
    int ss=sF;
 | 
			
		||||
    offset = st._offsets [Xm][ss];
 | 
			
		||||
    local  = st._is_local[Xm][ss];
 | 
			
		||||
    perm   = st._permute[Xm][ss];
 | 
			
		||||
 | 
			
		||||
    ptype  = st._permute_type[Xm];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjXp(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjXp(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Xm),&chi());
 | 
			
		||||
    spReconXp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Yp
 | 
			
		||||
    offset = st._offsets [Ym][ss];
 | 
			
		||||
    local  = st._is_local[Ym][ss];
 | 
			
		||||
    perm   = st._permute[Ym][ss];
 | 
			
		||||
    ptype  = st._permute_type[Ym];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjYp(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjYp(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Ym),&chi());
 | 
			
		||||
    accumReconYp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Zp
 | 
			
		||||
    offset = st._offsets [Zm][ss];
 | 
			
		||||
    local  = st._is_local[Zm][ss];
 | 
			
		||||
    perm   = st._permute[Zm][ss];
 | 
			
		||||
    ptype  = st._permute_type[Zm];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjZp(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjZp(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Zm),&chi());
 | 
			
		||||
    accumReconZp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Tp
 | 
			
		||||
    offset = st._offsets [Tm][ss];
 | 
			
		||||
    local  = st._is_local[Tm][ss];
 | 
			
		||||
    perm   = st._permute[Tm][ss];
 | 
			
		||||
    ptype  = st._permute_type[Tm];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjTp(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjTp(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Tm),&chi());
 | 
			
		||||
    accumReconTp(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Xm
 | 
			
		||||
    offset = st._offsets [Xp][ss];
 | 
			
		||||
    local  = st._is_local[Xp][ss];
 | 
			
		||||
    perm   = st._permute[Xp][ss];
 | 
			
		||||
    ptype  = st._permute_type[Xp];
 | 
			
		||||
 | 
			
		||||
    if ( local && perm ) 
 | 
			
		||||
    {
 | 
			
		||||
      spProjXm(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjXm(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Xp),&chi());
 | 
			
		||||
    accumReconXm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Ym
 | 
			
		||||
    offset = st._offsets [Yp][ss];
 | 
			
		||||
    local  = st._is_local[Yp][ss];
 | 
			
		||||
    perm   = st._permute[Yp][ss];
 | 
			
		||||
    ptype  = st._permute_type[Yp];
 | 
			
		||||
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjYm(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjYm(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Yp),&chi());
 | 
			
		||||
    accumReconYm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Zm
 | 
			
		||||
    offset = st._offsets [Zp][ss];
 | 
			
		||||
    local  = st._is_local[Zp][ss];
 | 
			
		||||
    perm   = st._permute[Zp][ss];
 | 
			
		||||
    ptype  = st._permute_type[Zp];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjZm(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjZm(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Zp),&chi());
 | 
			
		||||
    accumReconZm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    // Tm
 | 
			
		||||
    offset = st._offsets [Tp][ss];
 | 
			
		||||
    local  = st._is_local[Tp][ss];
 | 
			
		||||
    perm   = st._permute[Tp][ss];
 | 
			
		||||
    ptype  = st._permute_type[Tp];
 | 
			
		||||
    if ( local && perm ) {
 | 
			
		||||
      spProjTm(tmp,in._odata[offset]);
 | 
			
		||||
      permute(chi,tmp,ptype);
 | 
			
		||||
    } else if ( local ) {
 | 
			
		||||
      spProjTm(chi,in._odata[offset]);
 | 
			
		||||
    } else { 
 | 
			
		||||
      chi=buf[offset];
 | 
			
		||||
    }
 | 
			
		||||
    mult(&Uchi(),&U._odata[sU](Tp),&chi());
 | 
			
		||||
    accumReconTm(result,Uchi);
 | 
			
		||||
 | 
			
		||||
    vstream(out._odata[ss],result*(-0.5));
 | 
			
		||||
}
 | 
			
		||||
}}
 | 
			
		||||
							
								
								
									
										42
									
								
								lib/qcd/action/fermion/WilsonKernels.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								lib/qcd/action/fermion/WilsonKernels.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
#ifndef  GRID_QCD_DHOP_H
 | 
			
		||||
#define  GRID_QCD_DHOP_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
  namespace QCD {
 | 
			
		||||
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    // Helper classes that implement Wilson stencil for a single site.
 | 
			
		||||
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
    
 | 
			
		||||
    // Generic version works for any Nc and with extra flavour indices
 | 
			
		||||
    class DiracOpt {
 | 
			
		||||
    public:
 | 
			
		||||
      // These ones will need to be package intelligently. WilsonType base class
 | 
			
		||||
      // for use by DWF etc..
 | 
			
		||||
      static void DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			   std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			   int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			      std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			      int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Hand unrolled for Nc=3, one flavour
 | 
			
		||||
    class DiracOptHand {
 | 
			
		||||
    public:
 | 
			
		||||
      // These ones will need to be package intelligently. WilsonType base class
 | 
			
		||||
      // for use by DWF etc..
 | 
			
		||||
      static void DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			   std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			   int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
      static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			      std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			      int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										770
									
								
								lib/qcd/action/fermion/WilsonKernelsHand.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										770
									
								
								lib/qcd/action/fermion/WilsonKernelsHand.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,770 @@
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
 | 
			
		||||
#define REGISTER
 | 
			
		||||
 | 
			
		||||
#define LOAD_CHIMU \
 | 
			
		||||
  const vSpinColourVector & ref (in._odata[offset]);	\
 | 
			
		||||
    Chimu_00=ref()(0)(0);\
 | 
			
		||||
    Chimu_01=ref()(0)(1);\
 | 
			
		||||
    Chimu_02=ref()(0)(2);\
 | 
			
		||||
    Chimu_10=ref()(1)(0);\
 | 
			
		||||
    Chimu_11=ref()(1)(1);\
 | 
			
		||||
    Chimu_12=ref()(1)(2);\
 | 
			
		||||
    Chimu_20=ref()(2)(0);\
 | 
			
		||||
    Chimu_21=ref()(2)(1);\
 | 
			
		||||
    Chimu_22=ref()(2)(2);\
 | 
			
		||||
    Chimu_30=ref()(3)(0);\
 | 
			
		||||
    Chimu_31=ref()(3)(1);\
 | 
			
		||||
    Chimu_32=ref()(3)(2);
 | 
			
		||||
 | 
			
		||||
#define LOAD_CHI\
 | 
			
		||||
  const vHalfSpinColourVector &ref(buf[offset]);	\
 | 
			
		||||
    Chi_00 = ref()(0)(0);\
 | 
			
		||||
    Chi_01 = ref()(0)(1);\
 | 
			
		||||
    Chi_02 = ref()(0)(2);\
 | 
			
		||||
    Chi_10 = ref()(1)(0);\
 | 
			
		||||
    Chi_11 = ref()(1)(1);\
 | 
			
		||||
    Chi_12 = ref()(1)(2);
 | 
			
		||||
 | 
			
		||||
#define MULT_2SPIN(A)\
 | 
			
		||||
   auto & ref(U._odata[sU](A));	\
 | 
			
		||||
    U_00 = ref()(0,0);\
 | 
			
		||||
    U_10 = ref()(1,0);\
 | 
			
		||||
    U_20 = ref()(2,0);\
 | 
			
		||||
    U_01 = ref()(0,1);\
 | 
			
		||||
    U_11 = ref()(1,1);				\
 | 
			
		||||
    U_21 = ref()(2,1);\
 | 
			
		||||
    UChi_00 = U_00*Chi_00;\
 | 
			
		||||
    UChi_10 = U_00*Chi_10;\
 | 
			
		||||
    UChi_01 = U_10*Chi_00;\
 | 
			
		||||
    UChi_11 = U_10*Chi_10;\
 | 
			
		||||
    UChi_02 = U_20*Chi_00;\
 | 
			
		||||
    UChi_12 = U_20*Chi_10;\
 | 
			
		||||
    UChi_00+= U_01*Chi_01;\
 | 
			
		||||
    UChi_10+= U_01*Chi_11;\
 | 
			
		||||
    UChi_01+= U_11*Chi_01;\
 | 
			
		||||
    UChi_11+= U_11*Chi_11;\
 | 
			
		||||
    UChi_02+= U_21*Chi_01;\
 | 
			
		||||
    UChi_12+= U_21*Chi_11;\
 | 
			
		||||
    U_00 = ref()(0,2);\
 | 
			
		||||
    U_10 = ref()(1,2);\
 | 
			
		||||
    U_20 = ref()(2,2);\
 | 
			
		||||
    UChi_00+= U_00*Chi_02;\
 | 
			
		||||
    UChi_10+= U_00*Chi_12;\
 | 
			
		||||
    UChi_01+= U_10*Chi_02;\
 | 
			
		||||
    UChi_11+= U_10*Chi_12;\
 | 
			
		||||
    UChi_02+= U_20*Chi_02;\
 | 
			
		||||
    UChi_12+= U_20*Chi_12;
 | 
			
		||||
 | 
			
		||||
#define PERMUTE\
 | 
			
		||||
      permute(Chi_00,Chi_00,ptype);\
 | 
			
		||||
      permute(Chi_01,Chi_01,ptype);\
 | 
			
		||||
      permute(Chi_02,Chi_02,ptype);\
 | 
			
		||||
      permute(Chi_10,Chi_10,ptype);\
 | 
			
		||||
      permute(Chi_11,Chi_11,ptype);\
 | 
			
		||||
      permute(Chi_12,Chi_12,ptype);
 | 
			
		||||
 | 
			
		||||
//      hspin(0)=fspin(0)+timesI(fspin(3));
 | 
			
		||||
//      hspin(1)=fspin(1)+timesI(fspin(2));
 | 
			
		||||
#define XP_PROJ \
 | 
			
		||||
    Chi_00 = Chimu_00+timesI(Chimu_30);\
 | 
			
		||||
    Chi_01 = Chimu_01+timesI(Chimu_31);\
 | 
			
		||||
    Chi_02 = Chimu_02+timesI(Chimu_32);\
 | 
			
		||||
    Chi_10 = Chimu_10+timesI(Chimu_20);\
 | 
			
		||||
    Chi_11 = Chimu_11+timesI(Chimu_21);\
 | 
			
		||||
    Chi_12 = Chimu_12+timesI(Chimu_22);
 | 
			
		||||
 | 
			
		||||
#define YP_PROJ \
 | 
			
		||||
    Chi_00 = Chimu_00-Chimu_30;\
 | 
			
		||||
    Chi_01 = Chimu_01-Chimu_31;\
 | 
			
		||||
    Chi_02 = Chimu_02-Chimu_32;\
 | 
			
		||||
    Chi_10 = Chimu_10+Chimu_20;\
 | 
			
		||||
    Chi_11 = Chimu_11+Chimu_21;\
 | 
			
		||||
    Chi_12 = Chimu_12+Chimu_22;
 | 
			
		||||
 | 
			
		||||
#define ZP_PROJ \
 | 
			
		||||
  Chi_00 = Chimu_00+timesI(Chimu_20);		\
 | 
			
		||||
  Chi_01 = Chimu_01+timesI(Chimu_21);		\
 | 
			
		||||
  Chi_02 = Chimu_02+timesI(Chimu_22);		\
 | 
			
		||||
  Chi_10 = Chimu_10-timesI(Chimu_30);		\
 | 
			
		||||
  Chi_11 = Chimu_11-timesI(Chimu_31);		\
 | 
			
		||||
  Chi_12 = Chimu_12-timesI(Chimu_32);
 | 
			
		||||
 | 
			
		||||
#define TP_PROJ \
 | 
			
		||||
  Chi_00 = Chimu_00+Chimu_20;		\
 | 
			
		||||
  Chi_01 = Chimu_01+Chimu_21;		\
 | 
			
		||||
  Chi_02 = Chimu_02+Chimu_22;		\
 | 
			
		||||
  Chi_10 = Chimu_10+Chimu_30;		\
 | 
			
		||||
  Chi_11 = Chimu_11+Chimu_31;		\
 | 
			
		||||
  Chi_12 = Chimu_12+Chimu_32;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//      hspin(0)=fspin(0)-timesI(fspin(3));
 | 
			
		||||
//      hspin(1)=fspin(1)-timesI(fspin(2));
 | 
			
		||||
#define XM_PROJ \
 | 
			
		||||
    Chi_00 = Chimu_00-timesI(Chimu_30);\
 | 
			
		||||
    Chi_01 = Chimu_01-timesI(Chimu_31);\
 | 
			
		||||
    Chi_02 = Chimu_02-timesI(Chimu_32);\
 | 
			
		||||
    Chi_10 = Chimu_10-timesI(Chimu_20);\
 | 
			
		||||
    Chi_11 = Chimu_11-timesI(Chimu_21);\
 | 
			
		||||
    Chi_12 = Chimu_12-timesI(Chimu_22);
 | 
			
		||||
 | 
			
		||||
#define YM_PROJ \
 | 
			
		||||
    Chi_00 = Chimu_00+Chimu_30;\
 | 
			
		||||
    Chi_01 = Chimu_01+Chimu_31;\
 | 
			
		||||
    Chi_02 = Chimu_02+Chimu_32;\
 | 
			
		||||
    Chi_10 = Chimu_10-Chimu_20;\
 | 
			
		||||
    Chi_11 = Chimu_11-Chimu_21;\
 | 
			
		||||
    Chi_12 = Chimu_12-Chimu_22;
 | 
			
		||||
 | 
			
		||||
#define ZM_PROJ \
 | 
			
		||||
  Chi_00 = Chimu_00-timesI(Chimu_20);		\
 | 
			
		||||
  Chi_01 = Chimu_01-timesI(Chimu_21);		\
 | 
			
		||||
  Chi_02 = Chimu_02-timesI(Chimu_22);		\
 | 
			
		||||
  Chi_10 = Chimu_10+timesI(Chimu_30);		\
 | 
			
		||||
  Chi_11 = Chimu_11+timesI(Chimu_31);		\
 | 
			
		||||
  Chi_12 = Chimu_12+timesI(Chimu_32);
 | 
			
		||||
 | 
			
		||||
#define TM_PROJ \
 | 
			
		||||
  Chi_00 = Chimu_00-Chimu_20;		\
 | 
			
		||||
  Chi_01 = Chimu_01-Chimu_21;		\
 | 
			
		||||
  Chi_02 = Chimu_02-Chimu_22;		\
 | 
			
		||||
  Chi_10 = Chimu_10-Chimu_30;		\
 | 
			
		||||
  Chi_11 = Chimu_11-Chimu_31;		\
 | 
			
		||||
  Chi_12 = Chimu_12-Chimu_32;
 | 
			
		||||
 | 
			
		||||
//      fspin(0)=hspin(0);
 | 
			
		||||
//      fspin(1)=hspin(1);
 | 
			
		||||
//      fspin(2)=timesMinusI(hspin(1));
 | 
			
		||||
//      fspin(3)=timesMinusI(hspin(0));
 | 
			
		||||
#define XP_RECON\
 | 
			
		||||
  result_00 = UChi_00;\
 | 
			
		||||
  result_01 = UChi_01;\
 | 
			
		||||
  result_02 = UChi_02;\
 | 
			
		||||
  result_10 = UChi_10;\
 | 
			
		||||
  result_11 = UChi_11;\
 | 
			
		||||
  result_12 = UChi_12;\
 | 
			
		||||
  result_20 = timesMinusI(UChi_10);\
 | 
			
		||||
  result_21 = timesMinusI(UChi_11);\
 | 
			
		||||
  result_22 = timesMinusI(UChi_12);\
 | 
			
		||||
  result_30 = timesMinusI(UChi_00);\
 | 
			
		||||
  result_31 = timesMinusI(UChi_01);\
 | 
			
		||||
  result_32 = timesMinusI(UChi_02);
 | 
			
		||||
 | 
			
		||||
#define XP_RECON_ACCUM\
 | 
			
		||||
  result_00+=UChi_00;\
 | 
			
		||||
  result_01+=UChi_01;\
 | 
			
		||||
  result_02+=UChi_02;\
 | 
			
		||||
  result_10+=UChi_10;\
 | 
			
		||||
  result_11+=UChi_11;\
 | 
			
		||||
  result_12+=UChi_12;\
 | 
			
		||||
  result_20-=timesI(UChi_10);\
 | 
			
		||||
  result_21-=timesI(UChi_11);\
 | 
			
		||||
  result_22-=timesI(UChi_12);\
 | 
			
		||||
  result_30-=timesI(UChi_00);\
 | 
			
		||||
  result_31-=timesI(UChi_01);\
 | 
			
		||||
  result_32-=timesI(UChi_02);
 | 
			
		||||
 | 
			
		||||
#define XM_RECON\
 | 
			
		||||
  result_00 = UChi_00;\
 | 
			
		||||
  result_01 = UChi_01;\
 | 
			
		||||
  result_02 = UChi_02;\
 | 
			
		||||
  result_10 = UChi_10;\
 | 
			
		||||
  result_11 = UChi_11;\
 | 
			
		||||
  result_12 = UChi_12;\
 | 
			
		||||
  result_20 = timesI(UChi_10);\
 | 
			
		||||
  result_21 = timesI(UChi_11);\
 | 
			
		||||
  result_22 = timesI(UChi_12);\
 | 
			
		||||
  result_30 = timesI(UChi_00);\
 | 
			
		||||
  result_31 = timesI(UChi_01);\
 | 
			
		||||
  result_32 = timesI(UChi_02);
 | 
			
		||||
 | 
			
		||||
#define XM_RECON_ACCUM\
 | 
			
		||||
  result_00+= UChi_00;\
 | 
			
		||||
  result_01+= UChi_01;\
 | 
			
		||||
  result_02+= UChi_02;\
 | 
			
		||||
  result_10+= UChi_10;\
 | 
			
		||||
  result_11+= UChi_11;\
 | 
			
		||||
  result_12+= UChi_12;\
 | 
			
		||||
  result_20+= timesI(UChi_10);\
 | 
			
		||||
  result_21+= timesI(UChi_11);\
 | 
			
		||||
  result_22+= timesI(UChi_12);\
 | 
			
		||||
  result_30+= timesI(UChi_00);\
 | 
			
		||||
  result_31+= timesI(UChi_01);\
 | 
			
		||||
  result_32+= timesI(UChi_02);
 | 
			
		||||
 | 
			
		||||
#define YP_RECON_ACCUM\
 | 
			
		||||
  result_00+= UChi_00;\
 | 
			
		||||
  result_01+= UChi_01;\
 | 
			
		||||
  result_02+= UChi_02;\
 | 
			
		||||
  result_10+= UChi_10;\
 | 
			
		||||
  result_11+= UChi_11;\
 | 
			
		||||
  result_12+= UChi_12;\
 | 
			
		||||
  result_20+= UChi_10;\
 | 
			
		||||
  result_21+= UChi_11;\
 | 
			
		||||
  result_22+= UChi_12;\
 | 
			
		||||
  result_30-= UChi_00;\
 | 
			
		||||
  result_31-= UChi_01;\
 | 
			
		||||
  result_32-= UChi_02;
 | 
			
		||||
 | 
			
		||||
#define YM_RECON_ACCUM\
 | 
			
		||||
  result_00+= UChi_00;\
 | 
			
		||||
  result_01+= UChi_01;\
 | 
			
		||||
  result_02+= UChi_02;\
 | 
			
		||||
  result_10+= UChi_10;\
 | 
			
		||||
  result_11+= UChi_11;\
 | 
			
		||||
  result_12+= UChi_12;\
 | 
			
		||||
  result_20-= UChi_10;\
 | 
			
		||||
  result_21-= UChi_11;\
 | 
			
		||||
  result_22-= UChi_12;\
 | 
			
		||||
  result_30+= UChi_00;\
 | 
			
		||||
  result_31+= UChi_01;\
 | 
			
		||||
  result_32+= UChi_02;
 | 
			
		||||
 | 
			
		||||
#define ZP_RECON_ACCUM\
 | 
			
		||||
  result_00+= UChi_00;\
 | 
			
		||||
  result_01+= UChi_01;\
 | 
			
		||||
  result_02+= UChi_02;\
 | 
			
		||||
  result_10+= UChi_10;\
 | 
			
		||||
  result_11+= UChi_11;\
 | 
			
		||||
  result_12+= UChi_12;\
 | 
			
		||||
  result_20-= timesI(UChi_00);			\
 | 
			
		||||
  result_21-= timesI(UChi_01);			\
 | 
			
		||||
  result_22-= timesI(UChi_02);			\
 | 
			
		||||
  result_30+= timesI(UChi_10);			\
 | 
			
		||||
  result_31+= timesI(UChi_11);			\
 | 
			
		||||
  result_32+= timesI(UChi_12);
 | 
			
		||||
 | 
			
		||||
#define ZM_RECON_ACCUM\
 | 
			
		||||
  result_00+= UChi_00;\
 | 
			
		||||
  result_01+= UChi_01;\
 | 
			
		||||
  result_02+= UChi_02;\
 | 
			
		||||
  result_10+= UChi_10;\
 | 
			
		||||
  result_11+= UChi_11;\
 | 
			
		||||
  result_12+= UChi_12;\
 | 
			
		||||
  result_20+= timesI(UChi_00);			\
 | 
			
		||||
  result_21+= timesI(UChi_01);			\
 | 
			
		||||
  result_22+= timesI(UChi_02);			\
 | 
			
		||||
  result_30-= timesI(UChi_10);			\
 | 
			
		||||
  result_31-= timesI(UChi_11);			\
 | 
			
		||||
  result_32-= timesI(UChi_12);
 | 
			
		||||
 | 
			
		||||
#define TP_RECON_ACCUM\
 | 
			
		||||
  result_00+= UChi_00;\
 | 
			
		||||
  result_01+= UChi_01;\
 | 
			
		||||
  result_02+= UChi_02;\
 | 
			
		||||
  result_10+= UChi_10;\
 | 
			
		||||
  result_11+= UChi_11;\
 | 
			
		||||
  result_12+= UChi_12;\
 | 
			
		||||
  result_20+= UChi_00;			\
 | 
			
		||||
  result_21+= UChi_01;			\
 | 
			
		||||
  result_22+= UChi_02;			\
 | 
			
		||||
  result_30+= UChi_10;			\
 | 
			
		||||
  result_31+= UChi_11;			\
 | 
			
		||||
  result_32+= UChi_12;
 | 
			
		||||
 | 
			
		||||
#define TM_RECON_ACCUM\
 | 
			
		||||
  result_00+= UChi_00;\
 | 
			
		||||
  result_01+= UChi_01;\
 | 
			
		||||
  result_02+= UChi_02;\
 | 
			
		||||
  result_10+= UChi_10;\
 | 
			
		||||
  result_11+= UChi_11;\
 | 
			
		||||
  result_12+= UChi_12;\
 | 
			
		||||
  result_20-= UChi_00;	\
 | 
			
		||||
  result_21-= UChi_01;	\
 | 
			
		||||
  result_22-= UChi_02;	\
 | 
			
		||||
  result_30-= UChi_10;	\
 | 
			
		||||
  result_31-= UChi_11;	\
 | 
			
		||||
  result_32-= UChi_12;
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
namespace QCD {
 | 
			
		||||
 | 
			
		||||
void DiracOptHand::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			    std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			    int sF,int sU,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  REGISTER vComplex result_00; // 12 regs on knc
 | 
			
		||||
  REGISTER vComplex result_01;
 | 
			
		||||
  REGISTER vComplex result_02;
 | 
			
		||||
  
 | 
			
		||||
  REGISTER vComplex result_10;
 | 
			
		||||
  REGISTER vComplex result_11;
 | 
			
		||||
  REGISTER vComplex result_12;
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex result_20;
 | 
			
		||||
  REGISTER vComplex result_21;
 | 
			
		||||
  REGISTER vComplex result_22;
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex result_30;
 | 
			
		||||
  REGISTER vComplex result_31;
 | 
			
		||||
  REGISTER vComplex result_32; // 20 left
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex Chi_00;    // two spinor; 6 regs
 | 
			
		||||
  REGISTER vComplex Chi_01;
 | 
			
		||||
  REGISTER vComplex Chi_02;
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex Chi_10;
 | 
			
		||||
  REGISTER vComplex Chi_11;
 | 
			
		||||
  REGISTER vComplex Chi_12;   // 14 left
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex UChi_00;  // two spinor; 6 regs
 | 
			
		||||
  REGISTER vComplex UChi_01;
 | 
			
		||||
  REGISTER vComplex UChi_02;
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex UChi_10;
 | 
			
		||||
  REGISTER vComplex UChi_11;
 | 
			
		||||
  REGISTER vComplex UChi_12;  // 8 left
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex U_00;  // two rows of U matrix
 | 
			
		||||
  REGISTER vComplex U_10;
 | 
			
		||||
  REGISTER vComplex U_20;  
 | 
			
		||||
  REGISTER vComplex U_01;
 | 
			
		||||
  REGISTER vComplex U_11;
 | 
			
		||||
  REGISTER vComplex U_21;  // 2 reg left.
 | 
			
		||||
 | 
			
		||||
#define Chimu_00 Chi_00
 | 
			
		||||
#define Chimu_01 Chi_01
 | 
			
		||||
#define Chimu_02 Chi_02
 | 
			
		||||
#define Chimu_10 Chi_10
 | 
			
		||||
#define Chimu_11 Chi_11
 | 
			
		||||
#define Chimu_12 Chi_12
 | 
			
		||||
#define Chimu_20 UChi_00
 | 
			
		||||
#define Chimu_21 UChi_01
 | 
			
		||||
#define Chimu_22 UChi_02
 | 
			
		||||
#define Chimu_30 UChi_10
 | 
			
		||||
#define Chimu_31 UChi_11
 | 
			
		||||
#define Chimu_32 UChi_12
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  int offset,local,perm, ptype;
 | 
			
		||||
  int ss=sF;
 | 
			
		||||
  
 | 
			
		||||
  // Xp
 | 
			
		||||
  offset = st._offsets [Xp][ss];
 | 
			
		||||
  local  = st._is_local[Xp][ss];
 | 
			
		||||
  perm   = st._permute[Xp][ss];
 | 
			
		||||
  ptype  = st._permute_type[Xp];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    XP_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Xp);
 | 
			
		||||
  }
 | 
			
		||||
  XP_RECON;
 | 
			
		||||
  //  std::cout << "XP_RECON"<<std::endl;
 | 
			
		||||
  //  std::cout << result_00 <<" "<<result_01 <<" "<<result_02 <<std::endl;
 | 
			
		||||
  //  std::cout << result_10 <<" "<<result_11 <<" "<<result_12 <<std::endl;
 | 
			
		||||
  //  std::cout << result_20 <<" "<<result_21 <<" "<<result_22 <<std::endl;
 | 
			
		||||
  //  std::cout << result_30 <<" "<<result_31 <<" "<<result_32 <<std::endl;
 | 
			
		||||
 | 
			
		||||
  // Yp
 | 
			
		||||
  offset = st._offsets [Yp][ss];
 | 
			
		||||
  local  = st._is_local[Yp][ss];
 | 
			
		||||
  perm   = st._permute[Yp][ss];
 | 
			
		||||
  ptype  = st._permute_type[Yp];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    YP_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Yp);
 | 
			
		||||
  }
 | 
			
		||||
  YP_RECON_ACCUM;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Zp
 | 
			
		||||
  offset = st._offsets [Zp][ss];
 | 
			
		||||
  local  = st._is_local[Zp][ss];
 | 
			
		||||
  perm   = st._permute[Zp][ss];
 | 
			
		||||
  ptype  = st._permute_type[Zp];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    ZP_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Zp);
 | 
			
		||||
  }
 | 
			
		||||
  ZP_RECON_ACCUM;
 | 
			
		||||
 | 
			
		||||
  // Tp
 | 
			
		||||
  offset = st._offsets [Tp][ss];
 | 
			
		||||
  local  = st._is_local[Tp][ss];
 | 
			
		||||
  perm   = st._permute[Tp][ss];
 | 
			
		||||
  ptype  = st._permute_type[Tp];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    TP_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Tp);
 | 
			
		||||
  }
 | 
			
		||||
  TP_RECON_ACCUM;
 | 
			
		||||
  
 | 
			
		||||
  // Xm
 | 
			
		||||
  offset = st._offsets [Xm][ss];
 | 
			
		||||
  local  = st._is_local[Xm][ss];
 | 
			
		||||
  perm   = st._permute[Xm][ss];
 | 
			
		||||
  ptype  = st._permute_type[Xm];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    XM_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Xm);
 | 
			
		||||
  }
 | 
			
		||||
  XM_RECON_ACCUM;
 | 
			
		||||
  //  std::cout << "XM_RECON_ACCUM"<<std::endl;
 | 
			
		||||
  //  std::cout << result_00 <<" "<<result_01 <<" "<<result_02 <<std::endl;
 | 
			
		||||
  //  std::cout << result_10 <<" "<<result_11 <<" "<<result_12 <<std::endl;
 | 
			
		||||
  //  std::cout << result_20 <<" "<<result_21 <<" "<<result_22 <<std::endl;
 | 
			
		||||
  //  std::cout << result_30 <<" "<<result_31 <<" "<<result_32 <<std::endl;
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  // Ym
 | 
			
		||||
  offset = st._offsets [Ym][ss];
 | 
			
		||||
  local  = st._is_local[Ym][ss];
 | 
			
		||||
  perm   = st._permute[Ym][ss];
 | 
			
		||||
  ptype  = st._permute_type[Ym];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    YM_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Ym);
 | 
			
		||||
  }
 | 
			
		||||
  YM_RECON_ACCUM;
 | 
			
		||||
 | 
			
		||||
  // Zm
 | 
			
		||||
  offset = st._offsets [Zm][ss];
 | 
			
		||||
  local  = st._is_local[Zm][ss];
 | 
			
		||||
  perm   = st._permute[Zm][ss];
 | 
			
		||||
  ptype  = st._permute_type[Zm];
 | 
			
		||||
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    ZM_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Zm);
 | 
			
		||||
  }
 | 
			
		||||
  ZM_RECON_ACCUM;
 | 
			
		||||
 | 
			
		||||
  // Tm
 | 
			
		||||
  offset = st._offsets [Tm][ss];
 | 
			
		||||
  local  = st._is_local[Tm][ss];
 | 
			
		||||
  perm   = st._permute[Tm][ss];
 | 
			
		||||
  ptype  = st._permute_type[Tm];
 | 
			
		||||
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    TM_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Tm);
 | 
			
		||||
  }
 | 
			
		||||
  TM_RECON_ACCUM;
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    vSpinColourVector & ref (out._odata[ss]);
 | 
			
		||||
    vstream(ref()(0)(0),result_00*(-0.5));
 | 
			
		||||
    vstream(ref()(0)(1),result_01*(-0.5));
 | 
			
		||||
    vstream(ref()(0)(2),result_02*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(0),result_10*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(1),result_11*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(2),result_12*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(0),result_20*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(1),result_21*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(2),result_22*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(0),result_30*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(1),result_31*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(2),result_32*(-0.5));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DiracOptHand::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
 | 
			
		||||
			       std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> >  &buf,
 | 
			
		||||
			       int ss,int sU,const LatticeFermion &in, LatticeFermion &out)
 | 
			
		||||
{
 | 
			
		||||
  REGISTER vComplex result_00; // 12 regs on knc
 | 
			
		||||
  REGISTER vComplex result_01;
 | 
			
		||||
  REGISTER vComplex result_02;
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex result_10;
 | 
			
		||||
  REGISTER vComplex result_11;
 | 
			
		||||
  REGISTER vComplex result_12;
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex result_20;
 | 
			
		||||
  REGISTER vComplex result_21;
 | 
			
		||||
  REGISTER vComplex result_22;
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex result_30;
 | 
			
		||||
  REGISTER vComplex result_31;
 | 
			
		||||
  REGISTER vComplex result_32; // 20 left
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex Chi_00;    // two spinor; 6 regs
 | 
			
		||||
  REGISTER vComplex Chi_01;
 | 
			
		||||
  REGISTER vComplex Chi_02;
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex Chi_10;
 | 
			
		||||
  REGISTER vComplex Chi_11;
 | 
			
		||||
  REGISTER vComplex Chi_12;   // 14 left
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex UChi_00;  // two spinor; 6 regs
 | 
			
		||||
  REGISTER vComplex UChi_01;
 | 
			
		||||
  REGISTER vComplex UChi_02;
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex UChi_10;
 | 
			
		||||
  REGISTER vComplex UChi_11;
 | 
			
		||||
  REGISTER vComplex UChi_12;  // 8 left
 | 
			
		||||
 | 
			
		||||
  REGISTER vComplex U_00;  // two rows of U matrix
 | 
			
		||||
  REGISTER vComplex U_10;
 | 
			
		||||
  REGISTER vComplex U_20;  
 | 
			
		||||
  REGISTER vComplex U_01;
 | 
			
		||||
  REGISTER vComplex U_11;
 | 
			
		||||
  REGISTER vComplex U_21;  // 2 reg left.
 | 
			
		||||
 | 
			
		||||
#define Chimu_00 Chi_00
 | 
			
		||||
#define Chimu_01 Chi_01
 | 
			
		||||
#define Chimu_02 Chi_02
 | 
			
		||||
#define Chimu_10 Chi_10
 | 
			
		||||
#define Chimu_11 Chi_11
 | 
			
		||||
#define Chimu_12 Chi_12
 | 
			
		||||
#define Chimu_20 UChi_00
 | 
			
		||||
#define Chimu_21 UChi_01
 | 
			
		||||
#define Chimu_22 UChi_02
 | 
			
		||||
#define Chimu_30 UChi_10
 | 
			
		||||
#define Chimu_31 UChi_11
 | 
			
		||||
#define Chimu_32 UChi_12
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  int offset,local,perm, ptype;
 | 
			
		||||
 | 
			
		||||
  // Xp
 | 
			
		||||
  offset = st._offsets [Xp][ss];
 | 
			
		||||
  local  = st._is_local[Xp][ss];
 | 
			
		||||
  perm   = st._permute[Xp][ss];
 | 
			
		||||
  ptype  = st._permute_type[Xp];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    XM_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Xp);
 | 
			
		||||
  }
 | 
			
		||||
  XM_RECON;
 | 
			
		||||
  
 | 
			
		||||
  // Yp
 | 
			
		||||
  offset = st._offsets [Yp][ss];
 | 
			
		||||
  local  = st._is_local[Yp][ss];
 | 
			
		||||
  perm   = st._permute[Yp][ss];
 | 
			
		||||
  ptype  = st._permute_type[Yp];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    YM_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Yp);
 | 
			
		||||
  }
 | 
			
		||||
  YM_RECON_ACCUM;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Zp
 | 
			
		||||
  offset = st._offsets [Zp][ss];
 | 
			
		||||
  local  = st._is_local[Zp][ss];
 | 
			
		||||
  perm   = st._permute[Zp][ss];
 | 
			
		||||
  ptype  = st._permute_type[Zp];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    ZM_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Zp);
 | 
			
		||||
  }
 | 
			
		||||
  ZM_RECON_ACCUM;
 | 
			
		||||
 | 
			
		||||
  // Tp
 | 
			
		||||
  offset = st._offsets [Tp][ss];
 | 
			
		||||
  local  = st._is_local[Tp][ss];
 | 
			
		||||
  perm   = st._permute[Tp][ss];
 | 
			
		||||
  ptype  = st._permute_type[Tp];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    TM_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Tp);
 | 
			
		||||
  }
 | 
			
		||||
  TM_RECON_ACCUM;
 | 
			
		||||
  
 | 
			
		||||
  // Xm
 | 
			
		||||
  offset = st._offsets [Xm][ss];
 | 
			
		||||
  local  = st._is_local[Xm][ss];
 | 
			
		||||
  perm   = st._permute[Xm][ss];
 | 
			
		||||
  ptype  = st._permute_type[Xm];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    XP_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Xm);
 | 
			
		||||
  }
 | 
			
		||||
  XP_RECON_ACCUM;
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
  // Ym
 | 
			
		||||
  offset = st._offsets [Ym][ss];
 | 
			
		||||
  local  = st._is_local[Ym][ss];
 | 
			
		||||
  perm   = st._permute[Ym][ss];
 | 
			
		||||
  ptype  = st._permute_type[Ym];
 | 
			
		||||
  
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    YP_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Ym);
 | 
			
		||||
  }
 | 
			
		||||
  YP_RECON_ACCUM;
 | 
			
		||||
 | 
			
		||||
  // Zm
 | 
			
		||||
  offset = st._offsets [Zm][ss];
 | 
			
		||||
  local  = st._is_local[Zm][ss];
 | 
			
		||||
  perm   = st._permute[Zm][ss];
 | 
			
		||||
  ptype  = st._permute_type[Zm];
 | 
			
		||||
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    ZP_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Zm);
 | 
			
		||||
  }
 | 
			
		||||
  ZP_RECON_ACCUM;
 | 
			
		||||
 | 
			
		||||
  // Tm
 | 
			
		||||
  offset = st._offsets [Tm][ss];
 | 
			
		||||
  local  = st._is_local[Tm][ss];
 | 
			
		||||
  perm   = st._permute[Tm][ss];
 | 
			
		||||
  ptype  = st._permute_type[Tm];
 | 
			
		||||
 | 
			
		||||
  if ( local ) {
 | 
			
		||||
    LOAD_CHIMU;
 | 
			
		||||
    TP_PROJ;
 | 
			
		||||
    if ( perm) {
 | 
			
		||||
      PERMUTE;
 | 
			
		||||
    }
 | 
			
		||||
  } else { 
 | 
			
		||||
    LOAD_CHI;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    MULT_2SPIN(Tm);
 | 
			
		||||
  }
 | 
			
		||||
  TP_RECON_ACCUM;
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    vSpinColourVector & ref (out._odata[ss]);
 | 
			
		||||
    vstream(ref()(0)(0),result_00*(-0.5));
 | 
			
		||||
    vstream(ref()(0)(1),result_01*(-0.5));
 | 
			
		||||
    vstream(ref()(0)(2),result_02*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(0),result_10*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(1),result_11*(-0.5));
 | 
			
		||||
    vstream(ref()(1)(2),result_12*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(0),result_20*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(1),result_21*(-0.5));
 | 
			
		||||
    vstream(ref()(2)(2),result_22*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(0),result_30*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(1),result_31*(-0.5));
 | 
			
		||||
    vstream(ref()(3)(2),result_32*(-0.5));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}}
 | 
			
		||||
		Reference in New Issue
	
	Block a user