mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Merge branch 'develop' into feature/conjugate-bc-dirs
This commit is contained in:
		@@ -775,7 +775,26 @@ public:
 | 
				
			|||||||
    for(int p=0;p<npoint;p++) AcceleratorViewContainer[p].ViewClose();
 | 
					    for(int p=0;p<npoint;p++) AcceleratorViewContainer[p].ViewClose();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 CoarsenedMatrix(GridCartesian &CoarseGrid, GridRedBlackCartesian &CoarseRBGrid, int hermitian_=0) 	:
 | 
					  CoarsenedMatrix(GridCartesian &CoarseGrid, int hermitian_=0) 	:
 | 
				
			||||||
 | 
					    _grid(&CoarseGrid),
 | 
				
			||||||
 | 
					    _cbgrid(new GridRedBlackCartesian(&CoarseGrid)),
 | 
				
			||||||
 | 
					    geom(CoarseGrid._ndimension),
 | 
				
			||||||
 | 
					    hermitian(hermitian_),
 | 
				
			||||||
 | 
					    Stencil(&CoarseGrid,geom.npoint,Even,geom.directions,geom.displacements,0),
 | 
				
			||||||
 | 
					    StencilEven(_cbgrid,geom.npoint,Even,geom.directions,geom.displacements,0),
 | 
				
			||||||
 | 
					    StencilOdd(_cbgrid,geom.npoint,Odd,geom.directions,geom.displacements,0),
 | 
				
			||||||
 | 
					    A(geom.npoint,&CoarseGrid),
 | 
				
			||||||
 | 
					    Aeven(geom.npoint,_cbgrid),
 | 
				
			||||||
 | 
					    Aodd(geom.npoint,_cbgrid),
 | 
				
			||||||
 | 
					    AselfInv(&CoarseGrid),
 | 
				
			||||||
 | 
					    AselfInvEven(_cbgrid),
 | 
				
			||||||
 | 
					    AselfInvOdd(_cbgrid),
 | 
				
			||||||
 | 
					    dag_factor(nbasis*nbasis)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    fillFactor();
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CoarsenedMatrix(GridCartesian &CoarseGrid, GridRedBlackCartesian &CoarseRBGrid, int hermitian_=0) 	:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _grid(&CoarseGrid),
 | 
					    _grid(&CoarseGrid),
 | 
				
			||||||
    _cbgrid(&CoarseRBGrid),
 | 
					    _cbgrid(&CoarseRBGrid),
 | 
				
			||||||
@@ -817,6 +836,8 @@ public:
 | 
				
			|||||||
    typedef Lattice<typename Fobj::tensor_reduced> FineComplexField;
 | 
					    typedef Lattice<typename Fobj::tensor_reduced> FineComplexField;
 | 
				
			||||||
    typedef typename Fobj::scalar_type scalar_type;
 | 
					    typedef typename Fobj::scalar_type scalar_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage<< "CoarsenMatrix "<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FineComplexField one(FineGrid); one=scalar_type(1.0,0.0);
 | 
					    FineComplexField one(FineGrid); one=scalar_type(1.0,0.0);
 | 
				
			||||||
    FineComplexField zero(FineGrid); zero=scalar_type(0.0,0.0);
 | 
					    FineComplexField zero(FineGrid); zero=scalar_type(0.0,0.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -847,11 +868,13 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    CoarseScalar InnerProd(Grid()); 
 | 
					    CoarseScalar InnerProd(Grid()); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage<< "CoarsenMatrix Orthog "<< std::endl;
 | 
				
			||||||
    // Orthogonalise the subblocks over the basis
 | 
					    // Orthogonalise the subblocks over the basis
 | 
				
			||||||
    blockOrthogonalise(InnerProd,Subspace.subspace);
 | 
					    blockOrthogonalise(InnerProd,Subspace.subspace);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Compute the matrix elements of linop between this orthonormal
 | 
					    // Compute the matrix elements of linop between this orthonormal
 | 
				
			||||||
    // set of vectors.
 | 
					    // set of vectors.
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage<< "CoarsenMatrix masks "<< std::endl;
 | 
				
			||||||
    int self_stencil=-1;
 | 
					    int self_stencil=-1;
 | 
				
			||||||
    for(int p=0;p<geom.npoint;p++)
 | 
					    for(int p=0;p<geom.npoint;p++)
 | 
				
			||||||
    { 
 | 
					    { 
 | 
				
			||||||
@@ -890,7 +913,7 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
      phi=Subspace.subspace[i];
 | 
					      phi=Subspace.subspace[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      //      std::cout << GridLogMessage<< "CoarsenMatrix vector "<<i << std::endl;
 | 
					      std::cout << GridLogMessage<< "CoarsenMatrix vector "<<i << std::endl;
 | 
				
			||||||
      linop.OpDirAll(phi,Mphi_p);
 | 
					      linop.OpDirAll(phi,Mphi_p);
 | 
				
			||||||
      linop.OpDiag  (phi,Mphi_p[geom.npoint-1]);
 | 
					      linop.OpDiag  (phi,Mphi_p[geom.npoint-1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -919,6 +942,18 @@ public:
 | 
				
			|||||||
	    autoView( A_self  , A[self_stencil], AcceleratorWrite);
 | 
						    autoView( A_self  , A[self_stencil], AcceleratorWrite);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    accelerator_for(ss, Grid()->oSites(), Fobj::Nsimd(),{ coalescedWrite(A_p[ss](j,i),oZProj_v(ss)); });
 | 
						    accelerator_for(ss, Grid()->oSites(), Fobj::Nsimd(),{ coalescedWrite(A_p[ss](j,i),oZProj_v(ss)); });
 | 
				
			||||||
 | 
						    if ( hermitian && (disp==-1) ) {
 | 
				
			||||||
 | 
						      for(int pp=0;pp<geom.npoint;pp++){// Find the opposite link and set <j|A|i> = <i|A|j>*
 | 
				
			||||||
 | 
							int dirp   = geom.directions[pp];
 | 
				
			||||||
 | 
							int dispp  = geom.displacements[pp];
 | 
				
			||||||
 | 
							if ( (dirp==dir) && (dispp==1) ){
 | 
				
			||||||
 | 
							  auto sft = conjugate(Cshift(oZProj,dir,1));
 | 
				
			||||||
 | 
							  autoView( sft_v    ,  sft  , AcceleratorWrite);
 | 
				
			||||||
 | 
							  autoView( A_pp     ,  A[pp], AcceleratorWrite);
 | 
				
			||||||
 | 
							  accelerator_for(ss, Grid()->oSites(), Fobj::Nsimd(),{ coalescedWrite(A_pp[ss](i,j),sft_v(ss)); });
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						      }
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  }
 | 
						  }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -957,33 +992,12 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    if(hermitian) {
 | 
					    if(hermitian) {
 | 
				
			||||||
      std::cout << GridLogMessage << " ForceHermitian, new code "<<std::endl;
 | 
					      std::cout << GridLogMessage << " ForceHermitian, new code "<<std::endl;
 | 
				
			||||||
      ForceHermitian();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    InvertSelfStencilLink(); std::cout << GridLogMessage << "Coarse self link inverted" << std::endl;
 | 
					    InvertSelfStencilLink(); std::cout << GridLogMessage << "Coarse self link inverted" << std::endl;
 | 
				
			||||||
    FillHalfCbs(); std::cout << GridLogMessage << "Coarse half checkerboards filled" << std::endl;
 | 
					    FillHalfCbs(); std::cout << GridLogMessage << "Coarse half checkerboards filled" << std::endl;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void ForceHermitian(void) {
 | 
					 | 
				
			||||||
    CoarseMatrix Diff  (Grid());
 | 
					 | 
				
			||||||
    for(int p=0;p<geom.npoint;p++){
 | 
					 | 
				
			||||||
      int dir   = geom.directions[p];
 | 
					 | 
				
			||||||
      int disp  = geom.displacements[p];
 | 
					 | 
				
			||||||
      if(disp==-1) {
 | 
					 | 
				
			||||||
	// Find the opposite link
 | 
					 | 
				
			||||||
	for(int pp=0;pp<geom.npoint;pp++){
 | 
					 | 
				
			||||||
	  int dirp   = geom.directions[pp];
 | 
					 | 
				
			||||||
	  int dispp  = geom.displacements[pp];
 | 
					 | 
				
			||||||
	  if ( (dirp==dir) && (dispp==1) ){
 | 
					 | 
				
			||||||
	    //	    Diff = adj(Cshift(A[p],dir,1)) - A[pp]; 
 | 
					 | 
				
			||||||
	    //	    std::cout << GridLogMessage<<" Replacing stencil leg "<<pp<<" with leg "<<p<< " diff "<<norm2(Diff) <<std::endl;
 | 
					 | 
				
			||||||
	    A[pp] = adj(Cshift(A[p],dir,1));
 | 
					 | 
				
			||||||
	  }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void InvertSelfStencilLink() {
 | 
					  void InvertSelfStencilLink() {
 | 
				
			||||||
    std::cout << GridLogDebug << "CoarsenedMatrix::InvertSelfStencilLink" << std::endl;
 | 
					    std::cout << GridLogDebug << "CoarsenedMatrix::InvertSelfStencilLink" << std::endl;
 | 
				
			||||||
    int localVolume = Grid()->lSites();
 | 
					    int localVolume = Grid()->lSites();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,6 +80,13 @@ template<typename T> struct isSpinor {
 | 
				
			|||||||
template <typename T> using IfSpinor    = Invoke<std::enable_if< isSpinor<T>::value,int> > ;
 | 
					template <typename T> using IfSpinor    = Invoke<std::enable_if< isSpinor<T>::value,int> > ;
 | 
				
			||||||
template <typename T> using IfNotSpinor = Invoke<std::enable_if<!isSpinor<T>::value,int> > ;
 | 
					template <typename T> using IfNotSpinor = Invoke<std::enable_if<!isSpinor<T>::value,int> > ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const int CoarseIndex = 4;
 | 
				
			||||||
 | 
					template<typename T> struct isCoarsened {
 | 
				
			||||||
 | 
					   static constexpr bool value = (CoarseIndex<=T::TensorLevel);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					template <typename T> using IfCoarsened    = Invoke<std::enable_if< isCoarsened<T>::value,int> > ;
 | 
				
			||||||
 | 
					template <typename T> using IfNotCoarsened = Invoke<std::enable_if<!isCoarsened<T>::value,int> > ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ChrisK very keen to add extra space for Gparity doubling.
 | 
					// ChrisK very keen to add extra space for Gparity doubling.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Also add domain wall index, in a way where Wilson operator 
 | 
					// Also add domain wall index, in a way where Wilson operator 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -128,7 +128,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spProjTm (iVector<vtype,Nhs> &hspin,const iVector<vtype,Ns> &fspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spProjTm (iVector<vtype,Nhs> &hspin,const iVector<vtype,Ns> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  hspin(0)=fspin(0)-fspin(2);
 | 
					  hspin(0)=fspin(0)-fspin(2);
 | 
				
			||||||
  hspin(1)=fspin(1)-fspin(3);
 | 
					  hspin(1)=fspin(1)-fspin(3);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -138,40 +137,50 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
 *  0 0 -1  0
 | 
					 *  0 0 -1  0
 | 
				
			||||||
 *  0 0  0 -1
 | 
					 *  0 0  0 -1
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spProj5p (iVector<vtype,Nhs> &hspin,const iVector<vtype,Ns> &fspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spProj5p (iVector<vtype,Nhs> &hspin,const iVector<vtype,Ns> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  hspin(0)=fspin(0);
 | 
					  hspin(0)=fspin(0);
 | 
				
			||||||
  hspin(1)=fspin(1);
 | 
					  hspin(1)=fspin(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spProj5m (iVector<vtype,Nhs> &hspin,const iVector<vtype,Ns> &fspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spProj5m (iVector<vtype,Nhs> &hspin,const iVector<vtype,Ns> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  hspin(0)=fspin(2);
 | 
					  hspin(0)=fspin(2);
 | 
				
			||||||
  hspin(1)=fspin(3);
 | 
					  hspin(1)=fspin(3);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
//  template<class vtype> accelerator_inline void fspProj5p (iVector<vtype,Ns> &rfspin,const iVector<vtype,Ns> &fspin)
 | 
					 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spProj5p (iVector<vtype,Ns> &rfspin,const iVector<vtype,Ns> &fspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spProj5p (iVector<vtype,Ns> &rfspin,const iVector<vtype,Ns> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  rfspin(0)=fspin(0);
 | 
					  rfspin(0)=fspin(0);
 | 
				
			||||||
  rfspin(1)=fspin(1);
 | 
					  rfspin(1)=fspin(1);
 | 
				
			||||||
  rfspin(2)=Zero();
 | 
					  rfspin(2)=Zero();
 | 
				
			||||||
  rfspin(3)=Zero();
 | 
					  rfspin(3)=Zero();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//  template<class vtype> accelerator_inline void fspProj5m (iVector<vtype,Ns> &rfspin,const iVector<vtype,Ns> &fspin)
 | 
					 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spProj5m (iVector<vtype,Ns> &rfspin,const iVector<vtype,Ns> &fspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spProj5m (iVector<vtype,Ns> &rfspin,const iVector<vtype,Ns> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  rfspin(0)=Zero();
 | 
					  rfspin(0)=Zero();
 | 
				
			||||||
  rfspin(1)=Zero();
 | 
					  rfspin(1)=Zero();
 | 
				
			||||||
  rfspin(2)=fspin(2);
 | 
					  rfspin(2)=fspin(2);
 | 
				
			||||||
  rfspin(3)=fspin(3);
 | 
					  rfspin(3)=fspin(3);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class vtype,int N,IfCoarsened<iVector<vtype,N> > = 0> accelerator_inline void spProj5p (iVector<vtype,N> &rfspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  const int hN = N>>1;
 | 
				
			||||||
 | 
					  for(int s=0;s<hN;s++){
 | 
				
			||||||
 | 
					    rfspin(s)=fspin(s);
 | 
				
			||||||
 | 
					    rfspin(s+hN)=Zero();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					template<class vtype,int N,IfCoarsened<iVector<vtype,N> > = 0> accelerator_inline void spProj5m (iVector<vtype,N> &rfspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  const int hN = N>>1;
 | 
				
			||||||
 | 
					  for(int s=0;s<hN;s++){
 | 
				
			||||||
 | 
					    rfspin(s)=Zero();
 | 
				
			||||||
 | 
					    rfspin(s+hN)=fspin(s+hN);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
// Reconstruction routines to move back again to four spin
 | 
					// Reconstruction routines to move back again to four spin
 | 
				
			||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
					////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
@@ -183,7 +192,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconXp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconXp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)=hspin(0);
 | 
					  fspin(0)=hspin(0);
 | 
				
			||||||
  fspin(1)=hspin(1);
 | 
					  fspin(1)=hspin(1);
 | 
				
			||||||
  fspin(2)=timesMinusI(hspin(1));
 | 
					  fspin(2)=timesMinusI(hspin(1));
 | 
				
			||||||
@@ -191,7 +199,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconXm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconXm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)=hspin(0);
 | 
					  fspin(0)=hspin(0);
 | 
				
			||||||
  fspin(1)=hspin(1);
 | 
					  fspin(1)=hspin(1);
 | 
				
			||||||
  fspin(2)=timesI(hspin(1));
 | 
					  fspin(2)=timesI(hspin(1));
 | 
				
			||||||
@@ -199,7 +206,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconXp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconXp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)+=hspin(0);
 | 
					  fspin(0)+=hspin(0);
 | 
				
			||||||
  fspin(1)+=hspin(1);
 | 
					  fspin(1)+=hspin(1);
 | 
				
			||||||
  fspin(2)-=timesI(hspin(1));
 | 
					  fspin(2)-=timesI(hspin(1));
 | 
				
			||||||
@@ -207,7 +213,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void a
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconXm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconXm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)+=hspin(0);
 | 
					  fspin(0)+=hspin(0);
 | 
				
			||||||
  fspin(1)+=hspin(1);
 | 
					  fspin(1)+=hspin(1);
 | 
				
			||||||
  fspin(2)+=timesI(hspin(1));
 | 
					  fspin(2)+=timesI(hspin(1));
 | 
				
			||||||
@@ -221,7 +226,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void a
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconYp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconYp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)=hspin(0);
 | 
					  fspin(0)=hspin(0);
 | 
				
			||||||
  fspin(1)=hspin(1);
 | 
					  fspin(1)=hspin(1);
 | 
				
			||||||
  fspin(2)= hspin(1);
 | 
					  fspin(2)= hspin(1);
 | 
				
			||||||
@@ -229,7 +233,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconYm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconYm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)=hspin(0);
 | 
					  fspin(0)=hspin(0);
 | 
				
			||||||
  fspin(1)=hspin(1);
 | 
					  fspin(1)=hspin(1);
 | 
				
			||||||
  fspin(2)=-hspin(1);
 | 
					  fspin(2)=-hspin(1);
 | 
				
			||||||
@@ -237,7 +240,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconYp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconYp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)+=hspin(0);
 | 
					  fspin(0)+=hspin(0);
 | 
				
			||||||
  fspin(1)+=hspin(1);
 | 
					  fspin(1)+=hspin(1);
 | 
				
			||||||
  fspin(2)+=hspin(1);
 | 
					  fspin(2)+=hspin(1);
 | 
				
			||||||
@@ -245,7 +247,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void a
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconYm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconYm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)+=hspin(0);
 | 
					  fspin(0)+=hspin(0);
 | 
				
			||||||
  fspin(1)+=hspin(1);
 | 
					  fspin(1)+=hspin(1);
 | 
				
			||||||
  fspin(2)-=hspin(1);
 | 
					  fspin(2)-=hspin(1);
 | 
				
			||||||
@@ -260,7 +261,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void a
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconZp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconZp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)=hspin(0);
 | 
					  fspin(0)=hspin(0);
 | 
				
			||||||
  fspin(1)=hspin(1);
 | 
					  fspin(1)=hspin(1);
 | 
				
			||||||
  fspin(2)=timesMinusI(hspin(0));
 | 
					  fspin(2)=timesMinusI(hspin(0));
 | 
				
			||||||
@@ -268,7 +268,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconZm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconZm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)=hspin(0);
 | 
					  fspin(0)=hspin(0);
 | 
				
			||||||
  fspin(1)=hspin(1);
 | 
					  fspin(1)=hspin(1);
 | 
				
			||||||
  fspin(2)=     timesI(hspin(0));
 | 
					  fspin(2)=     timesI(hspin(0));
 | 
				
			||||||
@@ -276,7 +275,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconZp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconZp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)+=hspin(0);
 | 
					  fspin(0)+=hspin(0);
 | 
				
			||||||
  fspin(1)+=hspin(1);
 | 
					  fspin(1)+=hspin(1);
 | 
				
			||||||
  fspin(2)-=timesI(hspin(0));
 | 
					  fspin(2)-=timesI(hspin(0));
 | 
				
			||||||
@@ -284,7 +282,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void a
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconZm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconZm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)+=hspin(0);
 | 
					  fspin(0)+=hspin(0);
 | 
				
			||||||
  fspin(1)+=hspin(1);
 | 
					  fspin(1)+=hspin(1);
 | 
				
			||||||
  fspin(2)+=timesI(hspin(0));
 | 
					  fspin(2)+=timesI(hspin(0));
 | 
				
			||||||
@@ -298,7 +295,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void a
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconTp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconTp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)=hspin(0);
 | 
					  fspin(0)=hspin(0);
 | 
				
			||||||
  fspin(1)=hspin(1);
 | 
					  fspin(1)=hspin(1);
 | 
				
			||||||
  fspin(2)=hspin(0);
 | 
					  fspin(2)=hspin(0);
 | 
				
			||||||
@@ -306,7 +302,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconTm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spReconTm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)=hspin(0);
 | 
					  fspin(0)=hspin(0);
 | 
				
			||||||
  fspin(1)=hspin(1);
 | 
					  fspin(1)=hspin(1);
 | 
				
			||||||
  fspin(2)=-hspin(0);
 | 
					  fspin(2)=-hspin(0);
 | 
				
			||||||
@@ -314,7 +309,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconTp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconTp (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)+=hspin(0);
 | 
					  fspin(0)+=hspin(0);
 | 
				
			||||||
  fspin(1)+=hspin(1);
 | 
					  fspin(1)+=hspin(1);
 | 
				
			||||||
  fspin(2)+=hspin(0);
 | 
					  fspin(2)+=hspin(0);
 | 
				
			||||||
@@ -322,7 +316,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void a
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconTm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumReconTm (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)+=hspin(0);
 | 
					  fspin(0)+=hspin(0);
 | 
				
			||||||
  fspin(1)+=hspin(1);
 | 
					  fspin(1)+=hspin(1);
 | 
				
			||||||
  fspin(2)-=hspin(0);
 | 
					  fspin(2)-=hspin(0);
 | 
				
			||||||
@@ -336,7 +329,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void a
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spRecon5p (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spRecon5p (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)=hspin(0)+hspin(0); // add is lower latency than mul
 | 
					  fspin(0)=hspin(0)+hspin(0); // add is lower latency than mul
 | 
				
			||||||
  fspin(1)=hspin(1)+hspin(1); // probably no measurable diffence though
 | 
					  fspin(1)=hspin(1)+hspin(1); // probably no measurable diffence though
 | 
				
			||||||
  fspin(2)=Zero();
 | 
					  fspin(2)=Zero();
 | 
				
			||||||
@@ -344,7 +336,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spRecon5m (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void spRecon5m (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)=Zero();
 | 
					  fspin(0)=Zero();
 | 
				
			||||||
  fspin(1)=Zero();
 | 
					  fspin(1)=Zero();
 | 
				
			||||||
  fspin(2)=hspin(0)+hspin(0);
 | 
					  fspin(2)=hspin(0)+hspin(0);
 | 
				
			||||||
@@ -352,7 +343,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void s
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumRecon5p (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
					template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void accumRecon5p (iVector<vtype,Ns> &fspin,const iVector<vtype,Nhs> &hspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,Ns>,SpinorIndex>::value,iVector<vtype,Ns> >::type *SFINAE;
 | 
					 | 
				
			||||||
  fspin(0)+=hspin(0)+hspin(0);
 | 
					  fspin(0)+=hspin(0)+hspin(0);
 | 
				
			||||||
  fspin(1)+=hspin(1)+hspin(1);
 | 
					  fspin(1)+=hspin(1)+hspin(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -372,7 +362,6 @@ template<class vtype,IfSpinor<iVector<vtype,Ns> > = 0> accelerator_inline void a
 | 
				
			|||||||
//////////
 | 
					//////////
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjXp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjXp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProjXp(hspin._internal[i],fspin._internal[i]);
 | 
					    spProjXp(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -426,26 +415,21 @@ template<class rtype,class vtype,int N> accelerator_inline void accumReconXp (iM
 | 
				
			|||||||
    }}
 | 
					    }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
// Xm
 | 
					// Xm
 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spProjXm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spProjXm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spProjXm(hspin._internal,fspin._internal);
 | 
					  spProjXm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjXm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjXm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProjXm(hspin._internal[i],fspin._internal[i]);
 | 
					    spProjXm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spProjXm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spProjXm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spProjXm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spProjXm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -455,19 +439,16 @@ template<class rtype,class vtype,int N> accelerator_inline void spProjXm (iMatri
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spReconXm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spReconXm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spReconXm(hspin._internal,fspin._internal);
 | 
					  spReconXm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconXm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconXm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spReconXm(hspin._internal[i],fspin._internal[i]);
 | 
					    spReconXm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spReconXm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spReconXm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spReconXm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spReconXm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -476,45 +457,37 @@ template<class rtype,class vtype,int N> accelerator_inline void spReconXm (iMatr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void accumReconXm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void accumReconXm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  accumReconXm(hspin._internal,fspin._internal);
 | 
					  accumReconXm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconXm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconXm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    accumReconXm(hspin._internal[i],fspin._internal[i]);
 | 
					    accumReconXm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void accumReconXm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void accumReconXm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      accumReconXm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      accumReconXm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					    }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
// Yp
 | 
					// Yp
 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spProjYp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spProjYp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spProjYp(hspin._internal,fspin._internal);
 | 
					  spProjYp(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjYp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjYp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProjYp(hspin._internal[i],fspin._internal[i]);
 | 
					    spProjYp(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spProjYp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spProjYp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spProjYp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spProjYp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -524,19 +497,16 @@ template<class rtype,class vtype,int N> accelerator_inline void spProjYp (iMatri
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spReconYp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spReconYp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spReconYp(hspin._internal,fspin._internal);
 | 
					  spReconYp(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconYp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconYp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spReconYp(hspin._internal[i],fspin._internal[i]);
 | 
					    spReconYp(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spReconYp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spReconYp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spReconYp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spReconYp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -545,66 +515,55 @@ template<class rtype,class vtype,int N> accelerator_inline void spReconYp (iMatr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void accumReconYp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void accumReconYp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  accumReconYp(hspin._internal,fspin._internal);
 | 
					  accumReconYp(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconYp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconYp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    accumReconYp(hspin._internal[i],fspin._internal[i]);
 | 
					    accumReconYp(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void accumReconYp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void accumReconYp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      accumReconYp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      accumReconYp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					    }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
// Ym
 | 
					// Ym
 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spProjYm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spProjYm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spProjYm(hspin._internal,fspin._internal);
 | 
					  spProjYm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjYm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjYm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProjYm(hspin._internal[i],fspin._internal[i]);
 | 
					    spProjYm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spProjYm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spProjYm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spProjYm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spProjYm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					    }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spReconYm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spReconYm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spReconYm(hspin._internal,fspin._internal);
 | 
					  spReconYm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconYm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconYm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,const iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spReconYm(hspin._internal[i],fspin._internal[i]);
 | 
					    spReconYm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spReconYm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spReconYm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spReconYm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spReconYm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -613,19 +572,16 @@ template<class rtype,class vtype,int N> accelerator_inline void spReconYm (iMatr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void accumReconYm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void accumReconYm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  accumReconYm(hspin._internal,fspin._internal);
 | 
					  accumReconYm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconYm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconYm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    accumReconYm(hspin._internal[i],fspin._internal[i]);
 | 
					    accumReconYm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void accumReconYm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void accumReconYm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      accumReconYm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      accumReconYm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -638,66 +594,57 @@ template<class rtype,class vtype,int N> accelerator_inline void accumReconYm (iM
 | 
				
			|||||||
////////
 | 
					////////
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spProjZp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spProjZp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spProjZp(hspin._internal,fspin._internal);
 | 
					  spProjZp(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjZp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjZp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProjZp(hspin._internal[i],fspin._internal[i]);
 | 
					    spProjZp(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spProjZp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spProjZp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spProjZp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spProjZp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					  }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spReconZp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spReconZp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spReconZp(hspin._internal,fspin._internal);
 | 
					  spReconZp(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconZp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconZp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spReconZp(hspin._internal[i],fspin._internal[i]);
 | 
					    spReconZp(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spReconZp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spReconZp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spReconZp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spReconZp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					  }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void accumReconZp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void accumReconZp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  accumReconZp(hspin._internal,fspin._internal);
 | 
					  accumReconZp(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconZp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconZp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    accumReconZp(hspin._internal[i],fspin._internal[i]);
 | 
					    accumReconZp(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void accumReconZp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void accumReconZp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      accumReconZp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      accumReconZp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					  }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -706,62 +653,53 @@ template<class rtype,class vtype,int N> accelerator_inline void accumReconZp (iM
 | 
				
			|||||||
////////
 | 
					////////
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spProjZm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spProjZm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spProjZm(hspin._internal,fspin._internal);
 | 
					  spProjZm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjZm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjZm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProjZm(hspin._internal[i],fspin._internal[i]);
 | 
					    spProjZm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spProjZm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spProjZm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spProjZm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spProjZm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					  }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spReconZm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spReconZm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spReconZm(hspin._internal,fspin._internal);
 | 
					  spReconZm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconZm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconZm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spReconZm(hspin._internal[i],fspin._internal[i]);
 | 
					    spReconZm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spReconZm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spReconZm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spReconZm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spReconZm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					  }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void accumReconZm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void accumReconZm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  accumReconZm(hspin._internal,fspin._internal);
 | 
					  accumReconZm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconZm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconZm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    accumReconZm(hspin._internal[i],fspin._internal[i]);
 | 
					    accumReconZm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void accumReconZm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void accumReconZm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      accumReconZm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      accumReconZm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -774,41 +712,35 @@ template<class rtype,class vtype,int N> accelerator_inline void accumReconZm (iM
 | 
				
			|||||||
////////
 | 
					////////
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spProjTp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spProjTp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spProjTp(hspin._internal,fspin._internal);
 | 
					  spProjTp(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjTp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjTp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProjTp(hspin._internal[i],fspin._internal[i]);
 | 
					    spProjTp(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spProjTp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spProjTp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spProjTp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spProjTp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					  }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spReconTp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spReconTp (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spReconTp(hspin._internal,fspin._internal);
 | 
					  spReconTp(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconTp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconTp (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spReconTp(hspin._internal[i],fspin._internal[i]);
 | 
					    spReconTp(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spReconTp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spReconTp (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spReconTp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spReconTp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -817,44 +749,37 @@ template<class rtype,class vtype,int N> accelerator_inline void spReconTp (iMatr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void accumReconTp (iScalar<rtype> &hspin, iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void accumReconTp (iScalar<rtype> &hspin, iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  accumReconTp(hspin._internal,fspin._internal);
 | 
					  accumReconTp(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconTp (iVector<rtype,N> &hspin, const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconTp (iVector<rtype,N> &hspin, const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    accumReconTp(hspin._internal[i],fspin._internal[i]);
 | 
					    accumReconTp(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void accumReconTp (iMatrix<rtype,N> &hspin, const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void accumReconTp (iMatrix<rtype,N> &hspin, const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      accumReconTp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      accumReconTp(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					    }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
// Tm
 | 
					// Tm
 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spProjTm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spProjTm (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spProjTm(hspin._internal,fspin._internal);
 | 
					  spProjTm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjTm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProjTm (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProjTm(hspin._internal[i],fspin._internal[i]);
 | 
					    spProjTm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spProjTm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spProjTm (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spProjTm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spProjTm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -864,19 +789,16 @@ template<class rtype,class vtype,int N> accelerator_inline void spProjTm (iMatri
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spReconTm (iScalar<rtype> &hspin, const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spReconTm (iScalar<rtype> &hspin, const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spReconTm(hspin._internal,fspin._internal);
 | 
					  spReconTm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconTm (iVector<rtype,N> &hspin, const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spReconTm (iVector<rtype,N> &hspin, const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spReconTm(hspin._internal[i],fspin._internal[i]);
 | 
					    spReconTm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spReconTm (iMatrix<rtype,N> &hspin, const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spReconTm (iMatrix<rtype,N> &hspin, const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spReconTm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spReconTm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -885,44 +807,37 @@ template<class rtype,class vtype,int N> accelerator_inline void spReconTm (iMatr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void accumReconTm (iScalar<rtype> &hspin, const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void accumReconTm (iScalar<rtype> &hspin, const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  accumReconTm(hspin._internal,fspin._internal);
 | 
					  accumReconTm(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconTm (iVector<rtype,N> &hspin, const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumReconTm (iVector<rtype,N> &hspin, const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    accumReconTm(hspin._internal[i],fspin._internal[i]);
 | 
					    accumReconTm(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void accumReconTm (iMatrix<rtype,N> &hspin, const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void accumReconTm (iMatrix<rtype,N> &hspin, const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      accumReconTm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      accumReconTm(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					    }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
// 5p
 | 
					// 5p
 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spProj5p (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5p (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spProj5p(hspin._internal,fspin._internal);
 | 
					  spProj5p(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProj5p (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProj5p (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProj5p(hspin._internal[i],fspin._internal[i]);
 | 
					    spProj5p(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spProj5p (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5p (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spProj5p(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spProj5p(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -931,19 +846,16 @@ template<class rtype,class vtype,int N> accelerator_inline void spProj5p (iMatri
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spRecon5p (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spRecon5p (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spRecon5p(hspin._internal,fspin._internal);
 | 
					  spRecon5p(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spRecon5p (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spRecon5p (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spRecon5p(hspin._internal[i],fspin._internal[i]);
 | 
					    spRecon5p(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spRecon5p (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spRecon5p (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spRecon5p(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spRecon5p(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -952,19 +864,16 @@ template<class rtype,class vtype,int N> accelerator_inline void spRecon5p (iMatr
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void accumRecon5p (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void accumRecon5p (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  accumRecon5p(hspin._internal,fspin._internal);
 | 
					  accumRecon5p(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumRecon5p (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumRecon5p (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    accumRecon5p(hspin._internal[i],fspin._internal[i]);
 | 
					    accumRecon5p(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void accumRecon5p (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void accumRecon5p (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      accumRecon5p(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      accumRecon5p(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -972,24 +881,18 @@ template<class rtype,class vtype,int N> accelerator_inline void accumRecon5p (iM
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// four spinor projectors for chiral proj
 | 
					// four spinor projectors for chiral proj
 | 
				
			||||||
//  template<class vtype> accelerator_inline void fspProj5p (iScalar<vtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class vtype,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5p (iScalar<vtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
template<class vtype> accelerator_inline void spProj5p (iScalar<vtype> &hspin,const iScalar<vtype> &fspin)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spProj5p(hspin._internal,fspin._internal);
 | 
					  spProj5p(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//  template<class vtype,int N> accelerator_inline void fspProj5p (iVector<vtype,N> &hspin,iVector<vtype,N> &fspin)
 | 
					template<class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5p (iVector<vtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
template<class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProj5p (iVector<vtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProj5p(hspin._internal[i],fspin._internal[i]);
 | 
					    spProj5p(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//  template<class vtype,int N> accelerator_inline void fspProj5p (iMatrix<vtype,N> &hspin,iMatrix<vtype,N> &fspin)
 | 
					template<class vtype,int N,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5p (iMatrix<vtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
template<class vtype,int N> accelerator_inline void spProj5p (iMatrix<vtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spProj5p(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spProj5p(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -1001,17 +904,17 @@ template<class vtype,int N> accelerator_inline void spProj5p (iMatrix<vtype,N> &
 | 
				
			|||||||
// 5m
 | 
					// 5m
 | 
				
			||||||
////////
 | 
					////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spProj5m (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5m (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  spProj5m(hspin._internal,fspin._internal);
 | 
					  spProj5m(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<rtype,N> > = 0> accelerator_inline void spProj5m (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<rtype,N> > = 0,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5m (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProj5m(hspin._internal[i],fspin._internal[i]);
 | 
					    spProj5m(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spProj5m (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5m (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
@@ -1021,40 +924,34 @@ template<class rtype,class vtype,int N> accelerator_inline void spProj5m (iMatri
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void spRecon5m (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void spRecon5m (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spRecon5m(hspin._internal,fspin._internal);
 | 
					  spRecon5m(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spRecon5m (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spRecon5m (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spRecon5m(hspin._internal[i],fspin._internal[i]);
 | 
					    spRecon5m(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void spRecon5m (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void spRecon5m (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spRecon5m(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spRecon5m(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
    }}
 | 
					  }}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class rtype,class vtype> accelerator_inline void accumRecon5m (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class rtype,class vtype> accelerator_inline void accumRecon5m (iScalar<rtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  accumRecon5m(hspin._internal,fspin._internal);
 | 
					  accumRecon5m(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumRecon5m (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void accumRecon5m (iVector<rtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    accumRecon5m(hspin._internal[i],fspin._internal[i]);
 | 
					    accumRecon5m(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
template<class rtype,class vtype,int N> accelerator_inline void accumRecon5m (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					template<class rtype,class vtype,int N> accelerator_inline void accumRecon5m (iMatrix<rtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      accumRecon5m(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      accumRecon5m(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
@@ -1063,24 +960,18 @@ template<class rtype,class vtype,int N> accelerator_inline void accumRecon5m (iM
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// four spinor projectors for chiral proj
 | 
					// four spinor projectors for chiral proj
 | 
				
			||||||
//  template<class vtype> accelerator_inline void fspProj5m (iScalar<vtype> &hspin,const iScalar<vtype> &fspin)
 | 
					template<class vtype,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5m (iScalar<vtype> &hspin,const iScalar<vtype> &fspin)
 | 
				
			||||||
template<class vtype> accelerator_inline void spProj5m (iScalar<vtype> &hspin,const iScalar<vtype> &fspin)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iScalar<vtype>,SpinorIndex>::notvalue,iScalar<vtype> >::type *temp;
 | 
					 | 
				
			||||||
  spProj5m(hspin._internal,fspin._internal);
 | 
					  spProj5m(hspin._internal,fspin._internal);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//  template<class vtype,int N> accelerator_inline void fspProj5m (iVector<vtype,N> &hspin,iVector<vtype,N> &fspin)
 | 
					template<class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5m (iVector<vtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
				
			||||||
template<class vtype,int N,IfNotSpinor<iVector<vtype,N> > = 0> accelerator_inline void spProj5m (iVector<vtype,N> &hspin,const iVector<vtype,N> &fspin)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iVector<vtype,N>,SpinorIndex>::notvalue,iVector<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++) {
 | 
					  for(int i=0;i<N;i++) {
 | 
				
			||||||
    spProj5m(hspin._internal[i],fspin._internal[i]);
 | 
					    spProj5m(hspin._internal[i],fspin._internal[i]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
//  template<class vtype,int N> accelerator_inline void fspProj5m (iMatrix<vtype,N> &hspin,iMatrix<vtype,N> &fspin)
 | 
					template<class vtype,int N,IfNotCoarsened<iScalar<vtype> > = 0> accelerator_inline void spProj5m (iMatrix<vtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
				
			||||||
template<class vtype,int N> accelerator_inline void spProj5m (iMatrix<vtype,N> &hspin,const iMatrix<vtype,N> &fspin)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  //typename std::enable_if<matchGridTensorIndex<iMatrix<vtype,N>,SpinorIndex>::notvalue,iMatrix<vtype,N> >::type *temp;
 | 
					 | 
				
			||||||
  for(int i=0;i<N;i++){ 
 | 
					  for(int i=0;i<N;i++){ 
 | 
				
			||||||
    for(int j=0;j<N;j++){
 | 
					    for(int j=0;j<N;j++){
 | 
				
			||||||
      spProj5m(hspin._internal[i][j],fspin._internal[i][j]);
 | 
					      spProj5m(hspin._internal[i][j],fspin._internal[i][j]);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -155,7 +155,7 @@ void axpby_ssp_pminus(Lattice<vobj> &z,Coeff a,const Lattice<vobj> &x,Coeff b,co
 | 
				
			|||||||
    uint64_t ss = sss*Ls;
 | 
					    uint64_t ss = sss*Ls;
 | 
				
			||||||
    decltype(coalescedRead(y_v[ss+sp])) tmp;
 | 
					    decltype(coalescedRead(y_v[ss+sp])) tmp;
 | 
				
			||||||
    spProj5m(tmp,y_v(ss+sp)); 
 | 
					    spProj5m(tmp,y_v(ss+sp)); 
 | 
				
			||||||
    tmp = a*x_v(ss+s)+b*tmp;
 | 
					   tmp = a*x_v(ss+s)+b*tmp;
 | 
				
			||||||
    coalescedWrite(z_v[ss+s],tmp);
 | 
					    coalescedWrite(z_v[ss+s],tmp);
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -188,7 +188,6 @@ void G5R5(Lattice<vobj> &z,const Lattice<vobj> &x)
 | 
				
			|||||||
  z.Checkerboard() = x.Checkerboard();
 | 
					  z.Checkerboard() = x.Checkerboard();
 | 
				
			||||||
  conformable(x,z);
 | 
					  conformable(x,z);
 | 
				
			||||||
  int Ls = grid->_rdimensions[0];
 | 
					  int Ls = grid->_rdimensions[0];
 | 
				
			||||||
  Gamma G5(Gamma::Algebra::Gamma5);
 | 
					 | 
				
			||||||
  autoView( x_v, x, AcceleratorRead);
 | 
					  autoView( x_v, x, AcceleratorRead);
 | 
				
			||||||
  autoView( z_v, z, AcceleratorWrite);
 | 
					  autoView( z_v, z, AcceleratorWrite);
 | 
				
			||||||
  uint64_t nloop = grid->oSites()/Ls;
 | 
					  uint64_t nloop = grid->oSites()/Ls;
 | 
				
			||||||
@@ -196,7 +195,13 @@ void G5R5(Lattice<vobj> &z,const Lattice<vobj> &x)
 | 
				
			|||||||
    uint64_t ss = sss*Ls;
 | 
					    uint64_t ss = sss*Ls;
 | 
				
			||||||
    for(int s=0;s<Ls;s++){
 | 
					    for(int s=0;s<Ls;s++){
 | 
				
			||||||
      int sp = Ls-1-s;
 | 
					      int sp = Ls-1-s;
 | 
				
			||||||
      coalescedWrite(z_v[ss+sp],G5*x_v(ss+s));
 | 
					      auto tmp = x_v(ss+s);
 | 
				
			||||||
 | 
					      decltype(tmp) tmp_p;
 | 
				
			||||||
 | 
					      decltype(tmp) tmp_m;
 | 
				
			||||||
 | 
					      spProj5p(tmp_p,tmp);
 | 
				
			||||||
 | 
					      spProj5m(tmp_m,tmp);
 | 
				
			||||||
 | 
					      // Use of spProj5m, 5p captures the coarse space too
 | 
				
			||||||
 | 
					      coalescedWrite(z_v[ss+sp],tmp_p - tmp_m);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -208,10 +213,20 @@ void G5C(Lattice<vobj> &z, const Lattice<vobj> &x)
 | 
				
			|||||||
  z.Checkerboard() = x.Checkerboard();
 | 
					  z.Checkerboard() = x.Checkerboard();
 | 
				
			||||||
  conformable(x, z);
 | 
					  conformable(x, z);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Gamma G5(Gamma::Algebra::Gamma5);
 | 
					  autoView( x_v, x, AcceleratorRead);
 | 
				
			||||||
  z = G5 * x;
 | 
					  autoView( z_v, z, AcceleratorWrite);
 | 
				
			||||||
 | 
					  uint64_t nloop = grid->oSites();
 | 
				
			||||||
 | 
					  accelerator_for(ss,nloop,vobj::Nsimd(),{
 | 
				
			||||||
 | 
					    auto tmp = x_v(ss);
 | 
				
			||||||
 | 
					    decltype(tmp) tmp_p;
 | 
				
			||||||
 | 
					    decltype(tmp) tmp_m;
 | 
				
			||||||
 | 
					    spProj5p(tmp_p,tmp);
 | 
				
			||||||
 | 
					    spProj5m(tmp_m,tmp);
 | 
				
			||||||
 | 
					    coalescedWrite(z_v[ss],tmp_p - tmp_m);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
template<class CComplex, int nbasis>
 | 
					template<class CComplex, int nbasis>
 | 
				
			||||||
void G5C(Lattice<iVector<CComplex, nbasis>> &z, const Lattice<iVector<CComplex, nbasis>> &x)
 | 
					void G5C(Lattice<iVector<CComplex, nbasis>> &z, const Lattice<iVector<CComplex, nbasis>> &x)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -234,6 +249,7 @@ void G5C(Lattice<iVector<CComplex, nbasis>> &z, const Lattice<iVector<CComplex,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
NAMESPACE_END(Grid);
 | 
					NAMESPACE_END(Grid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -222,9 +222,16 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  GridCartesian *Coarse4d =  SpaceTimeGrid::makeFourDimGrid(clatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
					  GridCartesian *Coarse4d =  SpaceTimeGrid::makeFourDimGrid(clatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
  GridCartesian *Coarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,Coarse4d);
 | 
					  GridCartesian *Coarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,Coarse4d);
 | 
				
			||||||
  GridCartesian *CoarseCoarse4d =  SpaceTimeGrid::makeFourDimGrid(cclatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian *CoarseCoarse4d =  SpaceTimeGrid::makeFourDimGrid(cclatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
 | 
				
			||||||
  GridCartesian *CoarseCoarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,CoarseCoarse4d);
 | 
					  GridCartesian *CoarseCoarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,CoarseCoarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse4dRB = SpaceTimeGrid::makeFourDimRedBlackGrid(Coarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse5dRB = SpaceTimeGrid::makeFiveDimRedBlackGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian *CoarseCoarse4dRB = SpaceTimeGrid::makeFourDimRedBlackGrid(CoarseCoarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian *CoarseCoarse5dRB = SpaceTimeGrid::makeFiveDimRedBlackGrid(1,CoarseCoarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<int> seeds4({1,2,3,4});
 | 
					  std::vector<int> seeds4({1,2,3,4});
 | 
				
			||||||
  std::vector<int> seeds5({5,6,7,8});
 | 
					  std::vector<int> seeds5({5,6,7,8});
 | 
				
			||||||
  std::vector<int> cseeds({5,6,7,8});
 | 
					  std::vector<int> cseeds({5,6,7,8});
 | 
				
			||||||
@@ -282,8 +289,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  Gamma5R5HermitianLinearOperator<DomainWallFermionR,LatticeFermion> HermIndefOp(Ddwf);
 | 
					  Gamma5R5HermitianLinearOperator<DomainWallFermionR,LatticeFermion> HermIndefOp(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Level1Op LDOp(*Coarse5d,1); LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates);
 | 
					  Level1Op LDOp(*Coarse5d,*Coarse5dRB,1); LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates);
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //////////////////////////////////////////////////
 | 
					  //////////////////////////////////////////////////
 | 
				
			||||||
  // Deflate the course space. Recursive multigrid?
 | 
					  // Deflate the course space. Recursive multigrid?
 | 
				
			||||||
@@ -311,12 +317,11 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Level2Op L2Op(*CoarseCoarse5d,1); // Hermitian matrix
 | 
					  Level2Op L2Op(*CoarseCoarse5d,*CoarseCoarse5dRB,1); // Hermitian matrix
 | 
				
			||||||
  typedef Level2Op::CoarseVector CoarseCoarseVector;
 | 
					  typedef Level2Op::CoarseVector CoarseCoarseVector;
 | 
				
			||||||
  HermitianLinearOperator<Level1Op,CoarseVector> L1LinOp(LDOp);
 | 
					  HermitianLinearOperator<Level1Op,CoarseVector> L1LinOp(LDOp);
 | 
				
			||||||
  L2Op.CoarsenOperator(Coarse5d,L1LinOp,CoarseAggregates);
 | 
					  L2Op.CoarsenOperator(Coarse5d,L1LinOp,CoarseAggregates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << " Running CoarseCoarse grid Lanczos "<< std::endl;
 | 
					  std::cout<<GridLogMessage << " Running CoarseCoarse grid Lanczos "<< std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										397
									
								
								tests/solver/Test_dwf_hdcr_16_rb.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										397
									
								
								tests/solver/Test_dwf_hdcr_16_rb.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,397 @@
 | 
				
			|||||||
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Grid physics library, www.github.com/paboyle/Grid 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Source file: ./tests/Test_dwf_hdcr.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Antonin Portelli <antonin.portelli@me.com>
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					    it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					    the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					    (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					    GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
 | 
					    *************************************************************************************/
 | 
				
			||||||
 | 
					    /*  END LEGAL */
 | 
				
			||||||
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
 | 
					#include <Grid/algorithms/iterative/PrecGeneralisedConjugateResidual.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					using namespace Grid;
 | 
				
			||||||
 | 
					/* Params
 | 
				
			||||||
 | 
					 * Grid: 
 | 
				
			||||||
 | 
					 * block1(4)
 | 
				
			||||||
 | 
					 * block2(4)
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * Subspace
 | 
				
			||||||
 | 
					 * * Fine  : Subspace(nbasis,hi,lo,order,first,step) -- 32, 60,0.02,500,100,100
 | 
				
			||||||
 | 
					 * * Coarse: Subspace(nbasis,hi,lo,order,first,step) -- 32, 18,0.02,500,100,100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Smoother:
 | 
				
			||||||
 | 
					 * * Fine: Cheby(hi, lo, order)            --  60,0.5,10
 | 
				
			||||||
 | 
					 * * Coarse: Cheby(hi, lo, order)          --  12,0.1,4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Lanczos:
 | 
				
			||||||
 | 
					 * CoarseCoarse IRL( Nk, Nm, Nstop, poly(lo,hi,order))   24,36,24,0.002,4.0,61 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					RealD InverseApproximation(RealD x){
 | 
				
			||||||
 | 
					  return 1.0/x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Field> class SolverWrapper : public LinearFunction<Field> {
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  CheckerBoardedSparseMatrixBase<Field> & _Matrix;
 | 
				
			||||||
 | 
					  SchurRedBlackBase<Field> & _Solver;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Wrap the usual normal equations trick
 | 
				
			||||||
 | 
					  /////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  SolverWrapper(CheckerBoardedSparseMatrixBase<Field> &Matrix,
 | 
				
			||||||
 | 
							SchurRedBlackBase<Field> &Solver)
 | 
				
			||||||
 | 
					   :  _Matrix(Matrix), _Solver(Solver) {}; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator() (const Field &in, Field &out){
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    _Solver(_Matrix,in,out);  // Mdag M out = Mdag in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }     
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Field,class Matrix> class ChebyshevSmoother : public LinearFunction<Field>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<Field>                            FineOperator;
 | 
				
			||||||
 | 
					  Matrix         & _SmootherMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & _SmootherOperator;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  Chebyshev<Field> Cheby;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ChebyshevSmoother(RealD _lo,RealD _hi,int _ord, FineOperator &SmootherOperator,Matrix &SmootherMatrix) :
 | 
				
			||||||
 | 
					    _SmootherOperator(SmootherOperator),
 | 
				
			||||||
 | 
					    _SmootherMatrix(SmootherMatrix),
 | 
				
			||||||
 | 
					    Cheby(_lo,_hi,_ord,InverseApproximation)
 | 
				
			||||||
 | 
					  {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator() (const Field &in, Field &out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    Field tmp(in.Grid());
 | 
				
			||||||
 | 
					    MdagMLinearOperator<Matrix,Field>   MdagMOp(_SmootherMatrix); 
 | 
				
			||||||
 | 
					    _SmootherOperator.AdjOp(in,tmp);
 | 
				
			||||||
 | 
					    Cheby(MdagMOp,tmp,out);         
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					template<class Field,class Matrix> class MirsSmoother : public LinearFunction<Field>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<Field>                            FineOperator;
 | 
				
			||||||
 | 
					  Matrix         & SmootherMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & SmootherOperator;
 | 
				
			||||||
 | 
					  RealD tol;
 | 
				
			||||||
 | 
					  RealD shift;
 | 
				
			||||||
 | 
					  int   maxit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MirsSmoother(RealD _shift,RealD _tol,int _maxit,FineOperator &_SmootherOperator,Matrix &_SmootherMatrix) :
 | 
				
			||||||
 | 
					    shift(_shift),tol(_tol),maxit(_maxit),
 | 
				
			||||||
 | 
					    SmootherOperator(_SmootherOperator),
 | 
				
			||||||
 | 
					    SmootherMatrix(_SmootherMatrix)
 | 
				
			||||||
 | 
					  {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator() (const Field &in, Field &out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    ZeroGuesser<Field> Guess;
 | 
				
			||||||
 | 
					    ConjugateGradient<Field>  CG(tol,maxit,false);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    Field src(in.Grid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ShiftedMdagMLinearOperator<SparseMatrixBase<Field>,Field> MdagMOp(SmootherMatrix,shift);
 | 
				
			||||||
 | 
					    SmootherOperator.AdjOp(in,src);
 | 
				
			||||||
 | 
					    Guess(src,out);
 | 
				
			||||||
 | 
					    CG(MdagMOp,src,out); 
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Fobj,class CComplex,int nbasis, class Matrix, class Guesser, class CoarseSolver>
 | 
				
			||||||
 | 
					class MultiGridPreconditioner : public LinearFunction< Lattice<Fobj> > {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Aggregation<Fobj,CComplex,nbasis> Aggregates;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<Fobj,CComplex,nbasis> CoarseOperator;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::CoarseVector CoarseVector;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::CoarseMatrix CoarseMatrix;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::FineField    FineField;
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<FineField>                            FineOperator;
 | 
				
			||||||
 | 
					  typedef LinearFunction    <FineField>                            FineSmoother;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Aggregates     & _Aggregates;
 | 
				
			||||||
 | 
					  CoarseOperator & _CoarseOperator;
 | 
				
			||||||
 | 
					  Matrix         & _FineMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & _FineOperator;
 | 
				
			||||||
 | 
					  Guesser        & _Guess;
 | 
				
			||||||
 | 
					  FineSmoother   & _Smoother;
 | 
				
			||||||
 | 
					  CoarseSolver   & _CoarseSolve;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int    level;  void Level(int lv) {level = lv; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GridLogLevel std::cout << GridLogMessage <<std::string(level,'\t')<< " Level "<<level <<" "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MultiGridPreconditioner(Aggregates &Agg, CoarseOperator &Coarse, 
 | 
				
			||||||
 | 
								  FineOperator &Fine,Matrix &FineMatrix,
 | 
				
			||||||
 | 
								  FineSmoother &Smoother,
 | 
				
			||||||
 | 
								  Guesser &Guess_,
 | 
				
			||||||
 | 
								  CoarseSolver &CoarseSolve_)
 | 
				
			||||||
 | 
					    : _Aggregates(Agg),
 | 
				
			||||||
 | 
					      _CoarseOperator(Coarse),
 | 
				
			||||||
 | 
					      _FineOperator(Fine),
 | 
				
			||||||
 | 
					      _FineMatrix(FineMatrix),
 | 
				
			||||||
 | 
					      _Smoother(Smoother),
 | 
				
			||||||
 | 
					      _Guess(Guess_),
 | 
				
			||||||
 | 
					      _CoarseSolve(CoarseSolve_),
 | 
				
			||||||
 | 
					      level(1)  {  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void operator()(const FineField &in, FineField & out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    CoarseVector Csrc(_CoarseOperator.Grid());
 | 
				
			||||||
 | 
					    CoarseVector Csol(_CoarseOperator.Grid()); 
 | 
				
			||||||
 | 
					    FineField vec1(in.Grid());
 | 
				
			||||||
 | 
					    FineField vec2(in.Grid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    double t;
 | 
				
			||||||
 | 
					    // Fine Smoother
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Smoother(in,out);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Smoother took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update the residual
 | 
				
			||||||
 | 
					    _FineOperator.Op(out,vec1);  sub(vec1, in ,vec1);   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fine to Coarse 
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Aggregates.ProjectToSubspace  (Csrc,vec1);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Project to coarse took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Coarse correction
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _CoarseSolve(Csrc,Csol);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Coarse solve took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Coarse to Fine
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Aggregates.PromoteFromSubspace(Csol,vec1); 
 | 
				
			||||||
 | 
					    add(out,out,vec1);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Promote to this level took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Residual
 | 
				
			||||||
 | 
					    _FineOperator.Op(out,vec1);  sub(vec1 ,in , vec1);  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fine Smoother
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Smoother(vec1,vec2);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Smoother took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add( out,out,vec2);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (int argc, char ** argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Grid_init(&argc,&argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const int Ls=16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian         * UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian         * FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Construct a coarsened grid; utility for this?
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  std::vector<int> block ({2,2,2,2});
 | 
				
			||||||
 | 
					  std::vector<int> blockc ({2,2,2,2});
 | 
				
			||||||
 | 
					  const int nbasis= 32;
 | 
				
			||||||
 | 
					  const int nbasisc= 32;
 | 
				
			||||||
 | 
					  auto clatt = GridDefaultLatt();
 | 
				
			||||||
 | 
					  for(int d=0;d<clatt.size();d++){
 | 
				
			||||||
 | 
					    clatt[d] = clatt[d]/block[d];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  auto cclatt = clatt;
 | 
				
			||||||
 | 
					  for(int d=0;d<clatt.size();d++){
 | 
				
			||||||
 | 
					    cclatt[d] = clatt[d]/blockc[d];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian *Coarse4d =  SpaceTimeGrid::makeFourDimGrid(clatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
 | 
					  GridCartesian *Coarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					  //  GridCartesian *CoarseCoarse4d =  SpaceTimeGrid::makeFourDimGrid(cclatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
 | 
					  //  GridCartesian *CoarseCoarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,CoarseCoarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::vector<int> seeds4({1,2,3,4});
 | 
				
			||||||
 | 
					  std::vector<int> seeds5({5,6,7,8});
 | 
				
			||||||
 | 
					  std::vector<int> cseeds({5,6,7,8});
 | 
				
			||||||
 | 
					  GridParallelRNG          RNG5(FGrid);   RNG5.SeedFixedIntegers(seeds5);
 | 
				
			||||||
 | 
					  GridParallelRNG          RNG4(UGrid);   RNG4.SeedFixedIntegers(seeds4);
 | 
				
			||||||
 | 
					  GridParallelRNG          CRNG(Coarse5d);CRNG.SeedFixedIntegers(cseeds);
 | 
				
			||||||
 | 
					  LatticeFermion    src(FGrid); gaussian(RNG5,src);// src=src+g5*src;
 | 
				
			||||||
 | 
					  LatticeFermion result(FGrid); 
 | 
				
			||||||
 | 
					  LatticeGaugeField Umu(UGrid); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FieldMetaData header;
 | 
				
			||||||
 | 
					  std::string file("./ckpoint_lat.4000");
 | 
				
			||||||
 | 
					  //std::string file("./ckpoint_lat.1000");
 | 
				
			||||||
 | 
					  NerscIO::readConfiguration(Umu,header,file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building g5R5 hermitian DWF operator" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  RealD mass=0.001;
 | 
				
			||||||
 | 
					  RealD M5=1.8;
 | 
				
			||||||
 | 
					  DomainWallFermionR Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Aggregation<vSpinColourVector,vTComplex,nbasis>              Subspace;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<vSpinColourVector,vTComplex,nbasis>          CoarseOperator;
 | 
				
			||||||
 | 
					  typedef CoarseOperator::CoarseVector                                 CoarseVector;
 | 
				
			||||||
 | 
					  typedef CoarseOperator::siteVector siteVector;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling Aggregation class to build subspace" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  MdagMLinearOperator<DomainWallFermionR,LatticeFermion> HermDefOp(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Subspace Aggregates(Coarse5d,FGrid,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert ( (nbasis & 0x1)==0);
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    int nb=nbasis/2;
 | 
				
			||||||
 | 
					    LatticeFermion A(FGrid);
 | 
				
			||||||
 | 
					    LatticeFermion B(FGrid);
 | 
				
			||||||
 | 
					    //    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.002,1000,800,100,0.0);
 | 
				
			||||||
 | 
					    //    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.02,1000,800,100,0.0); 
 | 
				
			||||||
 | 
					    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.05,500,200,150,0.0);//
 | 
				
			||||||
 | 
					    //    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.01,1000,100,100,0.0); // Slightly faster
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(int n=0;n<nb;n++){
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " G5R5 "<<n<<std::endl;
 | 
				
			||||||
 | 
					      G5R5(Aggregates.subspace[n+nb],Aggregates.subspace[n]);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " Projection "<<n<<std::endl;
 | 
				
			||||||
 | 
					      A = Aggregates.subspace[n];
 | 
				
			||||||
 | 
					      B = Aggregates.subspace[n+nb];
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " Copy "<<n<<std::endl;
 | 
				
			||||||
 | 
					      Aggregates.subspace[n]   = A+B; // 1+G5 // eigen value of G5R5 is +1
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " P+ "<<n<<std::endl;
 | 
				
			||||||
 | 
					      Aggregates.subspace[n+nb]= A-B; // 1-G5 // eigen value of G5R5 is -1
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " P- "<<n<<std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building coarse representation of Indef operator" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<vSpinColourVector,vTComplex,nbasis>    Level1Op;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<siteVector,iScalar<vTComplex>,nbasisc> Level2Op;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Gamma5R5HermitianLinearOperator<DomainWallFermionR,LatticeFermion> HermIndefOp(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse4dRB = SpaceTimeGrid::makeFourDimRedBlackGrid(Coarse4d);
 | 
				
			||||||
 | 
					  std::cout << " Making 5D coarse RB grid " <<std::endl;
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse5dRB = SpaceTimeGrid::makeFiveDimRedBlackGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					  std::cout << " Made 5D coarse RB grid " <<std::endl;
 | 
				
			||||||
 | 
					  Level1Op LDOp(*Coarse5d,*Coarse5dRB,1); LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Deflate the course space. Recursive multigrid?
 | 
				
			||||||
 | 
					  //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  typedef Aggregation<siteVector,iScalar<vTComplex>,nbasisc>                   CoarseSubspace;
 | 
				
			||||||
 | 
					  //  CoarseSubspace CoarseAggregates(CoarseCoarse5d,Coarse5d,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Build deflation space in coarse operator "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MdagMLinearOperator<CoarseOperator,CoarseVector> PosdefLdop(LDOp);
 | 
				
			||||||
 | 
					  typedef Level2Op::CoarseVector CoarseCoarseVector;
 | 
				
			||||||
 | 
					  CoarseVector c_src(Coarse5d); c_src=1.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building 3 level Multigrid            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<vSpinColourVector,  vTComplex,nbasis, DomainWallFermionR,ZeroGuesser<CoarseVector> , SolverWrapper<CoarseVector> >   TwoLevelMG;
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<siteVector,iScalar<vTComplex>,nbasisc,Level1Op, DeflatedGuesser<CoarseCoarseVector>, NormalEquations<CoarseCoarseVector> > CoarseMG;
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<vSpinColourVector,  vTComplex,nbasis, DomainWallFermionR,ZeroGuesser<CoarseVector>, LinearFunction<CoarseVector> >     ThreeLevelMG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ChebyshevSmoother<LatticeFermion,DomainWallFermionR> FineSmoother(0.5,60.0,12,HermIndefOp,Ddwf);
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling 2 level Multigrid            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ZeroGuesser<CoarseVector> CoarseZeroGuesser;
 | 
				
			||||||
 | 
					  ConjugateGradient<CoarseVector>  CoarseCG(0.005,1000);
 | 
				
			||||||
 | 
					  //  SchurDiagMooeeOperator<CoarseOperator,CoarseVector> CoarseMpcDagMpc(LDOp);
 | 
				
			||||||
 | 
					  SchurRedBlackDiagMooeeSolve<CoarseVector> CoarseRBCG(CoarseCG);
 | 
				
			||||||
 | 
					  SolverWrapper<CoarseVector> CoarseSolver(LDOp,CoarseRBCG);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					  //  NormalEquations<CoarseVector> CoarseCGNE(LDOp,CoarseCG,CoarseZeroGuesser);
 | 
				
			||||||
 | 
					  TwoLevelMG TwoLevelPrecon(Aggregates, LDOp,
 | 
				
			||||||
 | 
								    HermIndefOp,Ddwf,
 | 
				
			||||||
 | 
								    FineSmoother,
 | 
				
			||||||
 | 
								    CoarseZeroGuesser,	
 | 
				
			||||||
 | 
								    CoarseSolver);
 | 
				
			||||||
 | 
					  TwoLevelPrecon.Level(1);
 | 
				
			||||||
 | 
					  PrecGeneralisedConjugateResidual<LatticeFermion> l1PGCR(1.0e-8,20,HermIndefOp,TwoLevelPrecon,16,16);
 | 
				
			||||||
 | 
					  l1PGCR.Level(1);
 | 
				
			||||||
 | 
					  l1PGCR(src,result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling CG            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  ConjugateGradient<LatticeFermion> pCG(1.0e-8,60000);
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					  //  pCG(HermDefOp,src,result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling red black CG            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LatticeFermion    src_o(FrbGrid);
 | 
				
			||||||
 | 
					    LatticeFermion result_o(FrbGrid);
 | 
				
			||||||
 | 
					    pickCheckerboard(Odd,src_o,src);
 | 
				
			||||||
 | 
					    result_o=Zero();
 | 
				
			||||||
 | 
					    SchurDiagMooeeOperator<DomainWallFermionR,LatticeFermion> HermOpEO(Ddwf);
 | 
				
			||||||
 | 
					    //    pCG(HermOpEO,src_o,result_o);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Fine        PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  PowerMethod<LatticeFermion>       PM;   PM(HermDefOp,src);
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Coarse       PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  PowerMethod<CoarseVector>        cPM;  cPM(PosdefLdop,c_src);
 | 
				
			||||||
 | 
					  //  std::cout<<GridLogMessage << " CoarseCoarse PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  //  PowerMethod<CoarseCoarseVector> ccPM; ccPM(IRLHermOpL2,cc_src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Done "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  Grid_finalize();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										477
									
								
								tests/solver/Test_dwf_hdcr_24_regression.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										477
									
								
								tests/solver/Test_dwf_hdcr_24_regression.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,477 @@
 | 
				
			|||||||
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Grid physics library, www.github.com/paboyle/Grid 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Source file: ./tests/Test_dwf_hdcr.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Antonin Portelli <antonin.portelli@me.com>
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					    it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					    the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					    (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					    GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
 | 
					    *************************************************************************************/
 | 
				
			||||||
 | 
					    /*  END LEGAL */
 | 
				
			||||||
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
 | 
					#include <Grid/algorithms/iterative/PrecGeneralisedConjugateResidual.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					using namespace Grid;
 | 
				
			||||||
 | 
					/* Params
 | 
				
			||||||
 | 
					 * Grid: 
 | 
				
			||||||
 | 
					 * block1(4)
 | 
				
			||||||
 | 
					 * block2(4)
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * Subspace
 | 
				
			||||||
 | 
					 * * Fine  : Subspace(nbasis,hi,lo,order,first,step) -- 32, 60,0.02,500,100,100
 | 
				
			||||||
 | 
					 * * Coarse: Subspace(nbasis,hi,lo,order,first,step) -- 32, 18,0.02,500,100,100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Smoother:
 | 
				
			||||||
 | 
					 * * Fine: Cheby(hi, lo, order)            --  60,0.5,10
 | 
				
			||||||
 | 
					 * * Coarse: Cheby(hi, lo, order)          --  12,0.1,4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Lanczos:
 | 
				
			||||||
 | 
					 * CoarseCoarse IRL( Nk, Nm, Nstop, poly(lo,hi,order))   24,36,24,0.002,4.0,61 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					RealD InverseApproximation(RealD x){
 | 
				
			||||||
 | 
					  return 1.0/x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Field,class Matrix> class ChebyshevSmoother : public LinearFunction<Field>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<Field>                            FineOperator;
 | 
				
			||||||
 | 
					  Matrix         & _SmootherMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & _SmootherOperator;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  Chebyshev<Field> Cheby;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ChebyshevSmoother(RealD _lo,RealD _hi,int _ord, FineOperator &SmootherOperator,Matrix &SmootherMatrix) :
 | 
				
			||||||
 | 
					    _SmootherOperator(SmootherOperator),
 | 
				
			||||||
 | 
					    _SmootherMatrix(SmootherMatrix),
 | 
				
			||||||
 | 
					    Cheby(_lo,_hi,_ord,InverseApproximation)
 | 
				
			||||||
 | 
					  {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator() (const Field &in, Field &out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    Field tmp(in.Grid());
 | 
				
			||||||
 | 
					    MdagMLinearOperator<Matrix,Field>   MdagMOp(_SmootherMatrix); 
 | 
				
			||||||
 | 
					    _SmootherOperator.AdjOp(in,tmp);
 | 
				
			||||||
 | 
					    Cheby(MdagMOp,tmp,out);         
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					template<class Field,class Matrix> class MirsSmoother : public LinearFunction<Field>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<Field>                            FineOperator;
 | 
				
			||||||
 | 
					  Matrix         & SmootherMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & SmootherOperator;
 | 
				
			||||||
 | 
					  RealD tol;
 | 
				
			||||||
 | 
					  RealD shift;
 | 
				
			||||||
 | 
					  int   maxit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MirsSmoother(RealD _shift,RealD _tol,int _maxit,FineOperator &_SmootherOperator,Matrix &_SmootherMatrix) :
 | 
				
			||||||
 | 
					    shift(_shift),tol(_tol),maxit(_maxit),
 | 
				
			||||||
 | 
					    SmootherOperator(_SmootherOperator),
 | 
				
			||||||
 | 
					    SmootherMatrix(_SmootherMatrix)
 | 
				
			||||||
 | 
					  {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator() (const Field &in, Field &out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    ZeroGuesser<Field> Guess;
 | 
				
			||||||
 | 
					    ConjugateGradient<Field>  CG(tol,maxit,false);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    Field src(in.Grid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ShiftedMdagMLinearOperator<SparseMatrixBase<Field>,Field> MdagMOp(SmootherMatrix,shift);
 | 
				
			||||||
 | 
					    SmootherOperator.AdjOp(in,src);
 | 
				
			||||||
 | 
					    Guess(src,out);
 | 
				
			||||||
 | 
					    CG(MdagMOp,src,out); 
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Fobj,class CComplex,int nbasis, class Matrix, class Guesser, class CoarseSolver>
 | 
				
			||||||
 | 
					class MultiGridPreconditioner : public LinearFunction< Lattice<Fobj> > {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Aggregation<Fobj,CComplex,nbasis> Aggregates;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<Fobj,CComplex,nbasis> CoarseOperator;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::CoarseVector CoarseVector;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::CoarseMatrix CoarseMatrix;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::FineField    FineField;
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<FineField>                            FineOperator;
 | 
				
			||||||
 | 
					  typedef LinearFunction    <FineField>                            FineSmoother;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Aggregates     & _Aggregates;
 | 
				
			||||||
 | 
					  CoarseOperator & _CoarseOperator;
 | 
				
			||||||
 | 
					  Matrix         & _FineMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & _FineOperator;
 | 
				
			||||||
 | 
					  Guesser        & _Guess;
 | 
				
			||||||
 | 
					  FineSmoother   & _Smoother;
 | 
				
			||||||
 | 
					  CoarseSolver   & _CoarseSolve;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int    level;  void Level(int lv) {level = lv; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GridLogLevel std::cout << GridLogMessage <<std::string(level,'\t')<< " Level "<<level <<" "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MultiGridPreconditioner(Aggregates &Agg, CoarseOperator &Coarse, 
 | 
				
			||||||
 | 
								  FineOperator &Fine,Matrix &FineMatrix,
 | 
				
			||||||
 | 
								  FineSmoother &Smoother,
 | 
				
			||||||
 | 
								  Guesser &Guess_,
 | 
				
			||||||
 | 
								  CoarseSolver &CoarseSolve_)
 | 
				
			||||||
 | 
					    : _Aggregates(Agg),
 | 
				
			||||||
 | 
					      _CoarseOperator(Coarse),
 | 
				
			||||||
 | 
					      _FineOperator(Fine),
 | 
				
			||||||
 | 
					      _FineMatrix(FineMatrix),
 | 
				
			||||||
 | 
					      _Smoother(Smoother),
 | 
				
			||||||
 | 
					      _Guess(Guess_),
 | 
				
			||||||
 | 
					      _CoarseSolve(CoarseSolve_),
 | 
				
			||||||
 | 
					      level(1)  {  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void operator()(const FineField &in, FineField & out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    CoarseVector Csrc(_CoarseOperator.Grid());
 | 
				
			||||||
 | 
					    CoarseVector Csol(_CoarseOperator.Grid()); 
 | 
				
			||||||
 | 
					    FineField vec1(in.Grid());
 | 
				
			||||||
 | 
					    FineField vec2(in.Grid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    double t;
 | 
				
			||||||
 | 
					    // Fine Smoother
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Smoother(in,out);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Smoother took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update the residual
 | 
				
			||||||
 | 
					    _FineOperator.Op(out,vec1);  sub(vec1, in ,vec1);   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fine to Coarse 
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Aggregates.ProjectToSubspace  (Csrc,vec1);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Project to coarse took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Coarse correction
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _CoarseSolve(Csrc,Csol);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Coarse solve took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Coarse to Fine
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Aggregates.PromoteFromSubspace(Csol,vec1); 
 | 
				
			||||||
 | 
					    add(out,out,vec1);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Promote to this level took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Residual
 | 
				
			||||||
 | 
					    _FineOperator.Op(out,vec1);  sub(vec1 ,in , vec1);  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fine Smoother
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Smoother(vec1,vec2);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Smoother took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add( out,out,vec2);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (int argc, char ** argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Grid_init(&argc,&argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const int Ls=24;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian         * UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian         * FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Construct a coarsened grid; utility for this?
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  std::vector<int> block ({2,2,2,2});
 | 
				
			||||||
 | 
					  std::vector<int> blockc ({2,2,2,2});
 | 
				
			||||||
 | 
					  const int nbasis= 40;
 | 
				
			||||||
 | 
					  const int nbasisc= 40;
 | 
				
			||||||
 | 
					  auto clatt = GridDefaultLatt();
 | 
				
			||||||
 | 
					  for(int d=0;d<clatt.size();d++){
 | 
				
			||||||
 | 
					    clatt[d] = clatt[d]/block[d];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  auto cclatt = clatt;
 | 
				
			||||||
 | 
					  for(int d=0;d<clatt.size();d++){
 | 
				
			||||||
 | 
					    cclatt[d] = clatt[d]/blockc[d];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian *Coarse4d =  SpaceTimeGrid::makeFourDimGrid(clatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
 | 
					  GridCartesian *Coarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					  //  GridCartesian *CoarseCoarse4d =  SpaceTimeGrid::makeFourDimGrid(cclatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
 | 
					  //  GridCartesian *CoarseCoarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,CoarseCoarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::vector<int> seeds4({1,2,3,4});
 | 
				
			||||||
 | 
					  std::vector<int> seeds5({5,6,7,8});
 | 
				
			||||||
 | 
					  std::vector<int> cseeds({5,6,7,8});
 | 
				
			||||||
 | 
					  GridParallelRNG          RNG5(FGrid);   RNG5.SeedFixedIntegers(seeds5);
 | 
				
			||||||
 | 
					  GridParallelRNG          RNG4(UGrid);   RNG4.SeedFixedIntegers(seeds4);
 | 
				
			||||||
 | 
					  GridParallelRNG          CRNG(Coarse5d);CRNG.SeedFixedIntegers(cseeds);
 | 
				
			||||||
 | 
					  LatticeFermion    src(FGrid); gaussian(RNG5,src);// src=src+g5*src;
 | 
				
			||||||
 | 
					  LatticeFermion result(FGrid); 
 | 
				
			||||||
 | 
					  LatticeGaugeField Umu(UGrid); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FieldMetaData header;
 | 
				
			||||||
 | 
					  //  std::string file("./ckpoint_lat.4000");
 | 
				
			||||||
 | 
					  //  std::string file("./ckpoint_lat.1000");
 | 
				
			||||||
 | 
					  //  NerscIO::readConfiguration(Umu,header,file);
 | 
				
			||||||
 | 
					  SU<Nc>::HotConfiguration(RNG4,Umu);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building g5R5 hermitian DWF operator" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  RealD mass=0.00078;
 | 
				
			||||||
 | 
					  RealD M5=1.8;
 | 
				
			||||||
 | 
					  DomainWallFermionR Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Aggregation<vSpinColourVector,vTComplex,nbasis>              Subspace;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<vSpinColourVector,vTComplex,nbasis>          CoarseOperator;
 | 
				
			||||||
 | 
					  typedef CoarseOperator::CoarseVector                                 CoarseVector;
 | 
				
			||||||
 | 
					  typedef CoarseOperator::siteVector siteVector;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling Aggregation class to build subspace" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  MdagMLinearOperator<DomainWallFermionR,LatticeFermion> HermDefOp(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Subspace Aggregates(Coarse5d,FGrid,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert ( (nbasis & 0x1)==0);
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    int nb=nbasis/2;
 | 
				
			||||||
 | 
					    LatticeFermion A(FGrid);
 | 
				
			||||||
 | 
					    LatticeFermion B(FGrid);
 | 
				
			||||||
 | 
					    //    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.002,1000,800,100,0.0);
 | 
				
			||||||
 | 
					    //    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.02,1000,800,100,0.0); 
 | 
				
			||||||
 | 
					    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.01,400,50,50,0.0); // Slightly faster
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(int n=0;n<nb;n++){
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " G5R5 "<<n<<std::endl;
 | 
				
			||||||
 | 
					      G5R5(Aggregates.subspace[n+nb],Aggregates.subspace[n]);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " Projection "<<n<<std::endl;
 | 
				
			||||||
 | 
					      A = Aggregates.subspace[n];
 | 
				
			||||||
 | 
					      B = Aggregates.subspace[n+nb];
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " Copy "<<n<<std::endl;
 | 
				
			||||||
 | 
					      Aggregates.subspace[n]   = A+B; // 1+G5 // eigen value of G5R5 is +1
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " P+ "<<n<<std::endl;
 | 
				
			||||||
 | 
					      Aggregates.subspace[n+nb]= A-B; // 1-G5 // eigen value of G5R5 is -1
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " P- "<<n<<std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building coarse representation of Indef operator" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<vSpinColourVector,vTComplex,nbasis>    Level1Op;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<siteVector,iScalar<vTComplex>,nbasisc> Level2Op;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Gamma5R5HermitianLinearOperator<DomainWallFermionR,LatticeFermion> HermIndefOp(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse4dRB = SpaceTimeGrid::makeFourDimRedBlackGrid(Coarse4d);
 | 
				
			||||||
 | 
					  std::cout << " Making 5D coarse RB grid " <<std::endl;
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse5dRB = SpaceTimeGrid::makeFiveDimRedBlackGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					  std::cout << " Made 5D coarse RB grid " <<std::endl;
 | 
				
			||||||
 | 
					  Level1Op LDOp(*Coarse5d,*Coarse5dRB,1); 
 | 
				
			||||||
 | 
					  std::cout << " LDOp.CoarsenOperator " <<std::endl;
 | 
				
			||||||
 | 
					  LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates);
 | 
				
			||||||
 | 
					  std::cout << " Coarsened Operator " <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Deflate the course space. Recursive multigrid?
 | 
				
			||||||
 | 
					  //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  typedef Aggregation<siteVector,iScalar<vTComplex>,nbasisc>                   CoarseSubspace;
 | 
				
			||||||
 | 
					  //  CoarseSubspace CoarseAggregates(CoarseCoarse5d,Coarse5d,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Build deflation space in coarse operator "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MdagMLinearOperator<CoarseOperator,CoarseVector> PosdefLdop(LDOp);
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    int nb=nbasisc/2;
 | 
				
			||||||
 | 
					    CoarseAggregates.CreateSubspaceChebyshev(CRNG,PosdefLdop,nb,15.0,0.02,1000,800,100,0.0);
 | 
				
			||||||
 | 
					    for(int n=0;n<nb;n++){
 | 
				
			||||||
 | 
					      autoView( subspace   , CoarseAggregates.subspace[n],CpuWrite);
 | 
				
			||||||
 | 
					      autoView( subspace_g5, CoarseAggregates.subspace[n+nb],CpuWrite);
 | 
				
			||||||
 | 
					      for(int nn=0;nn<nb;nn++){
 | 
				
			||||||
 | 
						for(int site=0;site<Coarse5d->oSites();site++){
 | 
				
			||||||
 | 
						  subspace_g5[site](nn)   = subspace[site](nn);
 | 
				
			||||||
 | 
						  subspace_g5[site](nn+nb)=-subspace[site](nn+nb);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  typedef Level2Op::CoarseVector CoarseCoarseVector;
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  Level2Op L2Op(*CoarseCoarse5d,1); // Hermitian matrix
 | 
				
			||||||
 | 
					  HermitianLinearOperator<Level1Op,CoarseVector> L1LinOp(LDOp);
 | 
				
			||||||
 | 
					  L2Op.CoarsenOperator(Coarse5d,L1LinOp,CoarseAggregates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Running CoarseCoarse grid Lanczos "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  MdagMLinearOperator<Level2Op,CoarseCoarseVector> IRLHermOpL2(L2Op);
 | 
				
			||||||
 | 
					  CoarseCoarseVector cc_src(CoarseCoarse5d); cc_src=1.0;
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  Chebyshev<CoarseCoarseVector> IRLChebyL2(0.001,15.0,301);
 | 
				
			||||||
 | 
					  FunctionHermOp<CoarseCoarseVector> IRLOpChebyL2(IRLChebyL2,IRLHermOpL2);
 | 
				
			||||||
 | 
					  PlainHermOp<CoarseCoarseVector> IRLOpL2    (IRLHermOpL2);
 | 
				
			||||||
 | 
					  int cNk=24;
 | 
				
			||||||
 | 
					  int cNm=36;
 | 
				
			||||||
 | 
					  int cNstop=24;
 | 
				
			||||||
 | 
					  ImplicitlyRestartedLanczos<CoarseCoarseVector> IRLL2(IRLOpChebyL2,IRLOpL2,cNstop,cNk,cNm,1.0e-3,20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int cNconv;
 | 
				
			||||||
 | 
					  std::vector<RealD>          eval2(cNm);
 | 
				
			||||||
 | 
					  std::vector<CoarseCoarseVector>   evec2(cNm,CoarseCoarse5d);
 | 
				
			||||||
 | 
					  IRLL2.calc(eval2,evec2,cc_src,cNconv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ConjugateGradient<CoarseCoarseVector>  CoarseCoarseCG(0.1,1000);
 | 
				
			||||||
 | 
					  DeflatedGuesser<CoarseCoarseVector> DeflCoarseCoarseGuesser(evec2,eval2);
 | 
				
			||||||
 | 
					  NormalEquations<CoarseCoarseVector> DeflCoarseCoarseCGNE(L2Op,CoarseCoarseCG,DeflCoarseCoarseGuesser);
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Running Coarse grid Lanczos "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MdagMLinearOperator<Level1Op,CoarseVector> IRLHermOp(LDOp);
 | 
				
			||||||
 | 
					  //  Chebyshev<CoarseVector>      IRLCheby(0.001,15.0,301);
 | 
				
			||||||
 | 
					  Chebyshev<CoarseVector>      IRLCheby(0.03,12.0,101);
 | 
				
			||||||
 | 
					  FunctionHermOp<CoarseVector> IRLOpCheby(IRLCheby,IRLHermOp);
 | 
				
			||||||
 | 
					  PlainHermOp<CoarseVector>    IRLOp    (IRLHermOp);
 | 
				
			||||||
 | 
					  int Nk=64;
 | 
				
			||||||
 | 
					  int Nm=128;
 | 
				
			||||||
 | 
					  int Nstop=Nk;
 | 
				
			||||||
 | 
					  ImplicitlyRestartedLanczos<CoarseVector> IRL(IRLOpCheby,IRLOp,Nstop,Nk,Nm,1.0e-3,20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int Nconv;
 | 
				
			||||||
 | 
					  std::vector<RealD>            eval(Nm);
 | 
				
			||||||
 | 
					  std::vector<CoarseVector>     evec(Nm,Coarse5d);
 | 
				
			||||||
 | 
					  IRL.calc(eval,evec,c_src,Nconv);
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  CoarseVector c_src(Coarse5d); c_src=1.0;
 | 
				
			||||||
 | 
					  //  DeflatedGuesser<CoarseVector> DeflCoarseGuesser(evec,eval);
 | 
				
			||||||
 | 
					  //  NormalEquations<CoarseVector> DeflCoarseCGNE(LDOp,CoarseCG,DeflCoarseGuesser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building 3 level Multigrid            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  //  typedef MultiGridPreconditioner<vSpinColourVector,  vTComplex,nbasis, DomainWallFermionR,DeflatedGuesser<CoarseVector> , NormalEquations<CoarseVector> >   TwoLevelMG;
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<vSpinColourVector,  vTComplex,nbasis, DomainWallFermionR,ZeroGuesser<CoarseVector> , NormalEquations<CoarseVector> >   TwoLevelMG;
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<siteVector,iScalar<vTComplex>,nbasisc,Level1Op, DeflatedGuesser<CoarseCoarseVector>, NormalEquations<CoarseCoarseVector> > CoarseMG;
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<vSpinColourVector,  vTComplex,nbasis, DomainWallFermionR,ZeroGuesser<CoarseVector>, LinearFunction<CoarseVector> >     ThreeLevelMG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ChebyshevSmoother<LatticeFermion,DomainWallFermionR> FineSmoother(0.25,60.0,12,HermIndefOp,Ddwf);
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  // MultiGrid preconditioner acting on the coarse space <-> coarsecoarse space
 | 
				
			||||||
 | 
					  ChebyshevSmoother<CoarseVector,  Level1Op >        CoarseSmoother(0.1,15.0,3,L1LinOp,LDOp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //  MirsSmoother<CoarseVector,  Level1Op >        CoarseCGSmoother(0.1,0.1,4,L1LinOp,LDOp);
 | 
				
			||||||
 | 
					  //  MirsSmoother<LatticeFermion,DomainWallFermionR> FineCGSmoother(0.0,0.01,8,HermIndefOp,Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CoarseMG Level2Precon (CoarseAggregates, L2Op,
 | 
				
			||||||
 | 
								 L1LinOp,LDOp,
 | 
				
			||||||
 | 
								 CoarseSmoother,
 | 
				
			||||||
 | 
								 DeflCoarseCoarseGuesser,	
 | 
				
			||||||
 | 
							 DeflCoarseCoarseCGNE);
 | 
				
			||||||
 | 
					  Level2Precon.Level(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // PGCR Applying this solver to solve the coarse space problem
 | 
				
			||||||
 | 
					  PrecGeneralisedConjugateResidual<CoarseVector>  l2PGCR(0.1, 100, L1LinOp,Level2Precon,16,16);
 | 
				
			||||||
 | 
					  l2PGCR.Level(2);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Wrap the 2nd level solver in a MultiGrid preconditioner acting on the fine space
 | 
				
			||||||
 | 
					  ZeroGuesser<CoarseVector> CoarseZeroGuesser;
 | 
				
			||||||
 | 
					  ThreeLevelMG ThreeLevelPrecon(Aggregates, LDOp,
 | 
				
			||||||
 | 
									HermIndefOp,Ddwf,
 | 
				
			||||||
 | 
									FineSmoother,
 | 
				
			||||||
 | 
									CoarseZeroGuesser,
 | 
				
			||||||
 | 
									l2PGCR);
 | 
				
			||||||
 | 
					  ThreeLevelPrecon.Level(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Apply the fine-coarse-coarsecoarse 2 deep MG preconditioner in an outer PGCR on the fine fgrid
 | 
				
			||||||
 | 
					  PrecGeneralisedConjugateResidual<LatticeFermion> l1PGCR(1.0e-8,1000,HermIndefOp,ThreeLevelPrecon,16,16);
 | 
				
			||||||
 | 
					  l1PGCR.Level(1);
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling 2 level Multigrid            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ZeroGuesser<CoarseVector> CoarseZeroGuesser;
 | 
				
			||||||
 | 
					    ConjugateGradient<CoarseVector>  CoarseCG(0.01,1000);
 | 
				
			||||||
 | 
					    NormalEquations<CoarseVector> CoarseCGNE(LDOp,CoarseCG,CoarseZeroGuesser);
 | 
				
			||||||
 | 
					    TwoLevelMG TwoLevelPrecon(Aggregates, LDOp,
 | 
				
			||||||
 | 
								      HermIndefOp,Ddwf,
 | 
				
			||||||
 | 
								      FineSmoother,
 | 
				
			||||||
 | 
								      CoarseZeroGuesser,	
 | 
				
			||||||
 | 
								      CoarseCGNE);
 | 
				
			||||||
 | 
					    TwoLevelPrecon.Level(1);
 | 
				
			||||||
 | 
					    PrecGeneralisedConjugateResidual<LatticeFermion> l1PGCR(1.0e-8,20,HermIndefOp,TwoLevelPrecon,16,16);
 | 
				
			||||||
 | 
					    l1PGCR.Level(1);
 | 
				
			||||||
 | 
					    l1PGCR(src,result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling CG            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  ConjugateGradient<LatticeFermion> pCG(1.0e-8,60000);
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					  //  pCG(HermDefOp,src,result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling red black CG            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LatticeFermion    src_o(FrbGrid);
 | 
				
			||||||
 | 
					    LatticeFermion result_o(FrbGrid);
 | 
				
			||||||
 | 
					    pickCheckerboard(Odd,src_o,src);
 | 
				
			||||||
 | 
					    result_o=Zero();
 | 
				
			||||||
 | 
					    SchurDiagMooeeOperator<DomainWallFermionR,LatticeFermion> HermOpEO(Ddwf);
 | 
				
			||||||
 | 
					    //    pCG(HermOpEO,src_o,result_o);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Fine        PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  PowerMethod<LatticeFermion>       PM;   PM(HermDefOp,src);
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Coarse       PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  PowerMethod<CoarseVector>        cPM;  cPM(PosdefLdop,c_src);
 | 
				
			||||||
 | 
					  //  std::cout<<GridLogMessage << " CoarseCoarse PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  //  PowerMethod<CoarseCoarseVector> ccPM; ccPM(IRLHermOpL2,cc_src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Done "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  Grid_finalize();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -262,6 +262,8 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  GridCartesian *Coarse4d =  SpaceTimeGrid::makeFourDimGrid(clatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
					  GridCartesian *Coarse4d =  SpaceTimeGrid::makeFourDimGrid(clatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
  GridCartesian *Coarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,Coarse4d);
 | 
					  GridCartesian *Coarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse4dRB = SpaceTimeGrid::makeFourDimRedBlackGrid(Coarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse5dRB = SpaceTimeGrid::makeFiveDimRedBlackGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<int> seeds4({1,2,3,4});
 | 
					  std::vector<int> seeds4({1,2,3,4});
 | 
				
			||||||
  std::vector<int> seeds5({5,6,7,8});
 | 
					  std::vector<int> seeds5({5,6,7,8});
 | 
				
			||||||
@@ -328,7 +330,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  Gamma5R5HermitianLinearOperator<DomainWallFermionR,LatticeFermion> HermIndefOp(Ddwf);
 | 
					  Gamma5R5HermitianLinearOperator<DomainWallFermionR,LatticeFermion> HermIndefOp(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Level1Op LDOp(*Coarse5d,1); LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates);
 | 
					  Level1Op LDOp(*Coarse5d,*Coarse5dRB,1); LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << " Running Coarse grid Lanczos "<< std::endl;
 | 
					  std::cout<<GridLogMessage << " Running Coarse grid Lanczos "<< std::endl;
 | 
				
			||||||
@@ -352,7 +354,9 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  //  ConjugateGradient<CoarseVector>  CoarseCG(0.01,1000);
 | 
					  //  ConjugateGradient<CoarseVector>  CoarseCG(0.01,1000);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  ConjugateGradient<CoarseVector>  CoarseCG(0.02,1000);// 14.7s
 | 
					  ConjugateGradient<CoarseVector>  CoarseCG(0.01,2000);// 14.7s
 | 
				
			||||||
 | 
					  eval.resize(0);
 | 
				
			||||||
 | 
					  evec.resize(0,Coarse5d);
 | 
				
			||||||
  DeflatedGuesser<CoarseVector> DeflCoarseGuesser(evec,eval);
 | 
					  DeflatedGuesser<CoarseVector> DeflCoarseGuesser(evec,eval);
 | 
				
			||||||
  NormalEquations<CoarseVector> DeflCoarseCGNE(LDOp,CoarseCG,DeflCoarseGuesser);
 | 
					  NormalEquations<CoarseVector> DeflCoarseCGNE(LDOp,CoarseCG,DeflCoarseGuesser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										397
									
								
								tests/solver/Test_dwf_hdcr_48_rb.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										397
									
								
								tests/solver/Test_dwf_hdcr_48_rb.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,397 @@
 | 
				
			|||||||
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Grid physics library, www.github.com/paboyle/Grid 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Source file: ./tests/Test_dwf_hdcr.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Antonin Portelli <antonin.portelli@me.com>
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					    it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					    the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					    (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					    GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
 | 
					    *************************************************************************************/
 | 
				
			||||||
 | 
					    /*  END LEGAL */
 | 
				
			||||||
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
 | 
					#include <Grid/algorithms/iterative/PrecGeneralisedConjugateResidual.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					using namespace Grid;
 | 
				
			||||||
 | 
					/* Params
 | 
				
			||||||
 | 
					 * Grid: 
 | 
				
			||||||
 | 
					 * block1(4)
 | 
				
			||||||
 | 
					 * block2(4)
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * Subspace
 | 
				
			||||||
 | 
					 * * Fine  : Subspace(nbasis,hi,lo,order,first,step) -- 32, 60,0.02,500,100,100
 | 
				
			||||||
 | 
					 * * Coarse: Subspace(nbasis,hi,lo,order,first,step) -- 32, 18,0.02,500,100,100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Smoother:
 | 
				
			||||||
 | 
					 * * Fine: Cheby(hi, lo, order)            --  60,0.5,10
 | 
				
			||||||
 | 
					 * * Coarse: Cheby(hi, lo, order)          --  12,0.1,4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Lanczos:
 | 
				
			||||||
 | 
					 * CoarseCoarse IRL( Nk, Nm, Nstop, poly(lo,hi,order))   24,36,24,0.002,4.0,61 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					RealD InverseApproximation(RealD x){
 | 
				
			||||||
 | 
					  return 1.0/x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Field> class SolverWrapper : public LinearFunction<Field> {
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					  CheckerBoardedSparseMatrixBase<Field> & _Matrix;
 | 
				
			||||||
 | 
					  SchurRedBlackBase<Field> & _Solver;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Wrap the usual normal equations trick
 | 
				
			||||||
 | 
					  /////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  SolverWrapper(CheckerBoardedSparseMatrixBase<Field> &Matrix,
 | 
				
			||||||
 | 
							SchurRedBlackBase<Field> &Solver)
 | 
				
			||||||
 | 
					   :  _Matrix(Matrix), _Solver(Solver) {}; 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator() (const Field &in, Field &out){
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    _Solver(_Matrix,in,out);  // Mdag M out = Mdag in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }     
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Field,class Matrix> class ChebyshevSmoother : public LinearFunction<Field>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<Field>                            FineOperator;
 | 
				
			||||||
 | 
					  Matrix         & _SmootherMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & _SmootherOperator;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  Chebyshev<Field> Cheby;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ChebyshevSmoother(RealD _lo,RealD _hi,int _ord, FineOperator &SmootherOperator,Matrix &SmootherMatrix) :
 | 
				
			||||||
 | 
					    _SmootherOperator(SmootherOperator),
 | 
				
			||||||
 | 
					    _SmootherMatrix(SmootherMatrix),
 | 
				
			||||||
 | 
					    Cheby(_lo,_hi,_ord,InverseApproximation)
 | 
				
			||||||
 | 
					  {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator() (const Field &in, Field &out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    Field tmp(in.Grid());
 | 
				
			||||||
 | 
					    MdagMLinearOperator<Matrix,Field>   MdagMOp(_SmootherMatrix); 
 | 
				
			||||||
 | 
					    _SmootherOperator.AdjOp(in,tmp);
 | 
				
			||||||
 | 
					    Cheby(MdagMOp,tmp,out);         
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					template<class Field,class Matrix> class MirsSmoother : public LinearFunction<Field>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<Field>                            FineOperator;
 | 
				
			||||||
 | 
					  Matrix         & SmootherMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & SmootherOperator;
 | 
				
			||||||
 | 
					  RealD tol;
 | 
				
			||||||
 | 
					  RealD shift;
 | 
				
			||||||
 | 
					  int   maxit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MirsSmoother(RealD _shift,RealD _tol,int _maxit,FineOperator &_SmootherOperator,Matrix &_SmootherMatrix) :
 | 
				
			||||||
 | 
					    shift(_shift),tol(_tol),maxit(_maxit),
 | 
				
			||||||
 | 
					    SmootherOperator(_SmootherOperator),
 | 
				
			||||||
 | 
					    SmootherMatrix(_SmootherMatrix)
 | 
				
			||||||
 | 
					  {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator() (const Field &in, Field &out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    ZeroGuesser<Field> Guess;
 | 
				
			||||||
 | 
					    ConjugateGradient<Field>  CG(tol,maxit,false);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    Field src(in.Grid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ShiftedMdagMLinearOperator<SparseMatrixBase<Field>,Field> MdagMOp(SmootherMatrix,shift);
 | 
				
			||||||
 | 
					    SmootherOperator.AdjOp(in,src);
 | 
				
			||||||
 | 
					    Guess(src,out);
 | 
				
			||||||
 | 
					    CG(MdagMOp,src,out); 
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Fobj,class CComplex,int nbasis, class Matrix, class Guesser, class CoarseSolver>
 | 
				
			||||||
 | 
					class MultiGridPreconditioner : public LinearFunction< Lattice<Fobj> > {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Aggregation<Fobj,CComplex,nbasis> Aggregates;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<Fobj,CComplex,nbasis> CoarseOperator;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::CoarseVector CoarseVector;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::CoarseMatrix CoarseMatrix;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::FineField    FineField;
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<FineField>                            FineOperator;
 | 
				
			||||||
 | 
					  typedef LinearFunction    <FineField>                            FineSmoother;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Aggregates     & _Aggregates;
 | 
				
			||||||
 | 
					  CoarseOperator & _CoarseOperator;
 | 
				
			||||||
 | 
					  Matrix         & _FineMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & _FineOperator;
 | 
				
			||||||
 | 
					  Guesser        & _Guess;
 | 
				
			||||||
 | 
					  FineSmoother   & _Smoother;
 | 
				
			||||||
 | 
					  CoarseSolver   & _CoarseSolve;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int    level;  void Level(int lv) {level = lv; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GridLogLevel std::cout << GridLogMessage <<std::string(level,'\t')<< " Level "<<level <<" "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MultiGridPreconditioner(Aggregates &Agg, CoarseOperator &Coarse, 
 | 
				
			||||||
 | 
								  FineOperator &Fine,Matrix &FineMatrix,
 | 
				
			||||||
 | 
								  FineSmoother &Smoother,
 | 
				
			||||||
 | 
								  Guesser &Guess_,
 | 
				
			||||||
 | 
								  CoarseSolver &CoarseSolve_)
 | 
				
			||||||
 | 
					    : _Aggregates(Agg),
 | 
				
			||||||
 | 
					      _CoarseOperator(Coarse),
 | 
				
			||||||
 | 
					      _FineOperator(Fine),
 | 
				
			||||||
 | 
					      _FineMatrix(FineMatrix),
 | 
				
			||||||
 | 
					      _Smoother(Smoother),
 | 
				
			||||||
 | 
					      _Guess(Guess_),
 | 
				
			||||||
 | 
					      _CoarseSolve(CoarseSolve_),
 | 
				
			||||||
 | 
					      level(1)  {  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void operator()(const FineField &in, FineField & out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    CoarseVector Csrc(_CoarseOperator.Grid());
 | 
				
			||||||
 | 
					    CoarseVector Csol(_CoarseOperator.Grid()); 
 | 
				
			||||||
 | 
					    FineField vec1(in.Grid());
 | 
				
			||||||
 | 
					    FineField vec2(in.Grid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    double t;
 | 
				
			||||||
 | 
					    // Fine Smoother
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Smoother(in,out);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Smoother took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update the residual
 | 
				
			||||||
 | 
					    _FineOperator.Op(out,vec1);  sub(vec1, in ,vec1);   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fine to Coarse 
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Aggregates.ProjectToSubspace  (Csrc,vec1);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Project to coarse took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Coarse correction
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _CoarseSolve(Csrc,Csol);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Coarse solve took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Coarse to Fine
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Aggregates.PromoteFromSubspace(Csol,vec1); 
 | 
				
			||||||
 | 
					    add(out,out,vec1);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Promote to this level took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Residual
 | 
				
			||||||
 | 
					    _FineOperator.Op(out,vec1);  sub(vec1 ,in , vec1);  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fine Smoother
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Smoother(vec1,vec2);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Smoother took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add( out,out,vec2);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (int argc, char ** argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Grid_init(&argc,&argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const int Ls=24;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian         * UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian         * FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Construct a coarsened grid; utility for this?
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  std::vector<int> block ({2,2,2,2});
 | 
				
			||||||
 | 
					  //std::vector<int> block ({2,2,2,2});
 | 
				
			||||||
 | 
					  const int nbasis= 40;
 | 
				
			||||||
 | 
					  const int nbasisc= 40;
 | 
				
			||||||
 | 
					  auto clatt = GridDefaultLatt();
 | 
				
			||||||
 | 
					  for(int d=0;d<clatt.size();d++){
 | 
				
			||||||
 | 
					    clatt[d] = clatt[d]/block[d];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian *Coarse4d =  SpaceTimeGrid::makeFourDimGrid(clatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
 | 
					  GridCartesian *Coarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					  //  GridCartesian *CoarseCoarse4d =  SpaceTimeGrid::makeFourDimGrid(cclatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
 | 
					  //  GridCartesian *CoarseCoarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,CoarseCoarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::vector<int> seeds4({1,2,3,4});
 | 
				
			||||||
 | 
					  std::vector<int> seeds5({5,6,7,8});
 | 
				
			||||||
 | 
					  std::vector<int> cseeds({5,6,7,8});
 | 
				
			||||||
 | 
					  GridParallelRNG          RNG5(FGrid);   RNG5.SeedFixedIntegers(seeds5);
 | 
				
			||||||
 | 
					  GridParallelRNG          RNG4(UGrid);   RNG4.SeedFixedIntegers(seeds4);
 | 
				
			||||||
 | 
					  GridParallelRNG          CRNG(Coarse5d);CRNG.SeedFixedIntegers(cseeds);
 | 
				
			||||||
 | 
					  LatticeFermion    src(FGrid); gaussian(RNG5,src);// src=src+g5*src;
 | 
				
			||||||
 | 
					  LatticeFermion result(FGrid); 
 | 
				
			||||||
 | 
					  LatticeGaugeField Umu(UGrid); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FieldMetaData header;
 | 
				
			||||||
 | 
					  //std::string file("./ckpoint_lat.4000");
 | 
				
			||||||
 | 
					  std::string file("./ckpoint_lat.1000");
 | 
				
			||||||
 | 
					  NerscIO::readConfiguration(Umu,header,file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building g5R5 hermitian DWF operator" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  RealD mass=0.00078;
 | 
				
			||||||
 | 
					  RealD M5=1.8;
 | 
				
			||||||
 | 
					  DomainWallFermionR Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Aggregation<vSpinColourVector,vTComplex,nbasis>              Subspace;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<vSpinColourVector,vTComplex,nbasis>          CoarseOperator;
 | 
				
			||||||
 | 
					  typedef CoarseOperator::CoarseVector                                 CoarseVector;
 | 
				
			||||||
 | 
					  typedef CoarseOperator::siteVector siteVector;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling Aggregation class to build subspace" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  MdagMLinearOperator<DomainWallFermionR,LatticeFermion> HermDefOp(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Subspace Aggregates(Coarse5d,FGrid,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert ( (nbasis & 0x1)==0);
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    int nb=nbasis/2;
 | 
				
			||||||
 | 
					    LatticeFermion A(FGrid);
 | 
				
			||||||
 | 
					    LatticeFermion B(FGrid);
 | 
				
			||||||
 | 
					    //    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.002,1000,800,100,0.0);
 | 
				
			||||||
 | 
					    //    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.02,1000,800,100,0.0); 
 | 
				
			||||||
 | 
					    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.01,1000,100,100,0.0); // Slightly faster
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(int n=0;n<nb;n++){
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " G5R5 "<<n<<std::endl;
 | 
				
			||||||
 | 
					      G5R5(Aggregates.subspace[n+nb],Aggregates.subspace[n]);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " Projection "<<n<<std::endl;
 | 
				
			||||||
 | 
					      A = Aggregates.subspace[n];
 | 
				
			||||||
 | 
					      B = Aggregates.subspace[n+nb];
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " Copy "<<n<<std::endl;
 | 
				
			||||||
 | 
					      Aggregates.subspace[n]   = A+B; // 1+G5 // eigen value of G5R5 is +1
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " P+ "<<n<<std::endl;
 | 
				
			||||||
 | 
					      Aggregates.subspace[n+nb]= A-B; // 1-G5 // eigen value of G5R5 is -1
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " P- "<<n<<std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building coarse representation of Indef operator" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<vSpinColourVector,vTComplex,nbasis>    Level1Op;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<siteVector,iScalar<vTComplex>,nbasisc> Level2Op;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Gamma5R5HermitianLinearOperator<DomainWallFermionR,LatticeFermion> HermIndefOp(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse4dRB = SpaceTimeGrid::makeFourDimRedBlackGrid(Coarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse5dRB = SpaceTimeGrid::makeFiveDimRedBlackGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Level1Op LDOp(*Coarse5d,*Coarse5dRB,1); LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Deflate the course space. Recursive multigrid?
 | 
				
			||||||
 | 
					  //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  typedef Aggregation<siteVector,iScalar<vTComplex>,nbasisc>                   CoarseSubspace;
 | 
				
			||||||
 | 
					  //  CoarseSubspace CoarseAggregates(CoarseCoarse5d,Coarse5d,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Build deflation space in coarse operator "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MdagMLinearOperator<CoarseOperator,CoarseVector> PosdefLdop(LDOp);
 | 
				
			||||||
 | 
					  typedef Level2Op::CoarseVector CoarseCoarseVector;
 | 
				
			||||||
 | 
					  CoarseVector c_src(Coarse5d); c_src=1.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building 3 level Multigrid            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<vSpinColourVector,  vTComplex,nbasis, DomainWallFermionR,ZeroGuesser<CoarseVector> , SolverWrapper<CoarseVector> >   TwoLevelMG;
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<siteVector,iScalar<vTComplex>,nbasisc,Level1Op, DeflatedGuesser<CoarseCoarseVector>, NormalEquations<CoarseCoarseVector> > CoarseMG;
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<vSpinColourVector,  vTComplex,nbasis, DomainWallFermionR,ZeroGuesser<CoarseVector>, LinearFunction<CoarseVector> >     ThreeLevelMG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling 2 level Multigrid            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::vector<RealD> tols({0.015});
 | 
				
			||||||
 | 
					  std::vector<int>   ords({12});
 | 
				
			||||||
 | 
					  std::vector<RealD>   los({0.8});
 | 
				
			||||||
 | 
					  for(int l=0;l<los.size();l++){
 | 
				
			||||||
 | 
					  for(int o=0;o<ords.size();o++){
 | 
				
			||||||
 | 
					  for(int t=0;t<tols.size();t++){
 | 
				
			||||||
 | 
					    result=Zero();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::cout << GridLogMessage <<" tol  " << tols[t] << " cheby order " <<ords[o]<< " lo "<<los[l] <<std::endl;
 | 
				
			||||||
 | 
					    ChebyshevSmoother<LatticeFermion,DomainWallFermionR> FineSmoother(los[l],60.0,ords[o],HermIndefOp,Ddwf);
 | 
				
			||||||
 | 
					    ZeroGuesser<CoarseVector> CoarseZeroGuesser;
 | 
				
			||||||
 | 
					    ConjugateGradient<CoarseVector>  CoarseCG(tols[t],10000);
 | 
				
			||||||
 | 
					    SchurRedBlackDiagMooeeSolve<CoarseVector> CoarseRBCG(CoarseCG);
 | 
				
			||||||
 | 
					    SolverWrapper<CoarseVector> CoarseSolver(LDOp,CoarseRBCG);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    TwoLevelMG TwoLevelPrecon(Aggregates, LDOp,
 | 
				
			||||||
 | 
								      HermIndefOp,Ddwf,
 | 
				
			||||||
 | 
								      FineSmoother,
 | 
				
			||||||
 | 
								      CoarseZeroGuesser,	
 | 
				
			||||||
 | 
								      CoarseSolver);
 | 
				
			||||||
 | 
					    TwoLevelPrecon.Level(1);
 | 
				
			||||||
 | 
					    PrecGeneralisedConjugateResidual<LatticeFermion> l1PGCR(1.0e-8,20,HermIndefOp,TwoLevelPrecon,16,16);
 | 
				
			||||||
 | 
					    l1PGCR.Level(1);
 | 
				
			||||||
 | 
					    l1PGCR(src,result);
 | 
				
			||||||
 | 
					  }}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ConjugateGradient<LatticeFermion> pCG(1.0e-8,60000);
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling red black CG            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LatticeFermion    src_o(FrbGrid);
 | 
				
			||||||
 | 
					    LatticeFermion result_o(FrbGrid);
 | 
				
			||||||
 | 
					    pickCheckerboard(Odd,src_o,src);
 | 
				
			||||||
 | 
					    result_o=Zero();
 | 
				
			||||||
 | 
					    SchurDiagMooeeOperator<DomainWallFermionR,LatticeFermion> HermOpEO(Ddwf);
 | 
				
			||||||
 | 
					    pCG(HermOpEO,src_o,result_o);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling CG            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					  pCG(HermDefOp,src,result);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Fine        PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  PowerMethod<LatticeFermion>       PM;   PM(HermDefOp,src);
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Coarse       PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  PowerMethod<CoarseVector>        cPM;  cPM(PosdefLdop,c_src);
 | 
				
			||||||
 | 
					  //  std::cout<<GridLogMessage << " CoarseCoarse PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  //  PowerMethod<CoarseCoarseVector> ccPM; ccPM(IRLHermOpL2,cc_src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Done "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  Grid_finalize();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										473
									
								
								tests/solver/Test_dwf_hdcr_48_regression.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										473
									
								
								tests/solver/Test_dwf_hdcr_48_regression.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,473 @@
 | 
				
			|||||||
 | 
					/*************************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Grid physics library, www.github.com/paboyle/Grid 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Source file: ./tests/Test_dwf_hdcr.cc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Copyright (C) 2015
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author: Antonin Portelli <antonin.portelli@me.com>
 | 
				
			||||||
 | 
					Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					    it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					    the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					    (at your option) any later version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					    GNU General Public License for more details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    You should have received a copy of the GNU General Public License along
 | 
				
			||||||
 | 
					    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
				
			||||||
 | 
					    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    See the full license in the file "LICENSE" in the top level distribution directory
 | 
				
			||||||
 | 
					    *************************************************************************************/
 | 
				
			||||||
 | 
					    /*  END LEGAL */
 | 
				
			||||||
 | 
					#include <Grid/Grid.h>
 | 
				
			||||||
 | 
					#include <Grid/algorithms/iterative/PrecGeneralisedConjugateResidual.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					using namespace Grid;
 | 
				
			||||||
 | 
					/* Params
 | 
				
			||||||
 | 
					 * Grid: 
 | 
				
			||||||
 | 
					 * block1(4)
 | 
				
			||||||
 | 
					 * block2(4)
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * Subspace
 | 
				
			||||||
 | 
					 * * Fine  : Subspace(nbasis,hi,lo,order,first,step) -- 32, 60,0.02,500,100,100
 | 
				
			||||||
 | 
					 * * Coarse: Subspace(nbasis,hi,lo,order,first,step) -- 32, 18,0.02,500,100,100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Smoother:
 | 
				
			||||||
 | 
					 * * Fine: Cheby(hi, lo, order)            --  60,0.5,10
 | 
				
			||||||
 | 
					 * * Coarse: Cheby(hi, lo, order)          --  12,0.1,4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * Lanczos:
 | 
				
			||||||
 | 
					 * CoarseCoarse IRL( Nk, Nm, Nstop, poly(lo,hi,order))   24,36,24,0.002,4.0,61 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					RealD InverseApproximation(RealD x){
 | 
				
			||||||
 | 
					  return 1.0/x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Field,class Matrix> class ChebyshevSmoother : public LinearFunction<Field>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<Field>                            FineOperator;
 | 
				
			||||||
 | 
					  Matrix         & _SmootherMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & _SmootherOperator;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  Chebyshev<Field> Cheby;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ChebyshevSmoother(RealD _lo,RealD _hi,int _ord, FineOperator &SmootherOperator,Matrix &SmootherMatrix) :
 | 
				
			||||||
 | 
					    _SmootherOperator(SmootherOperator),
 | 
				
			||||||
 | 
					    _SmootherMatrix(SmootherMatrix),
 | 
				
			||||||
 | 
					    Cheby(_lo,_hi,_ord,InverseApproximation)
 | 
				
			||||||
 | 
					  {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator() (const Field &in, Field &out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    Field tmp(in.Grid());
 | 
				
			||||||
 | 
					    MdagMLinearOperator<Matrix,Field>   MdagMOp(_SmootherMatrix); 
 | 
				
			||||||
 | 
					    _SmootherOperator.AdjOp(in,tmp);
 | 
				
			||||||
 | 
					    Cheby(MdagMOp,tmp,out);         
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					template<class Field,class Matrix> class MirsSmoother : public LinearFunction<Field>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<Field>                            FineOperator;
 | 
				
			||||||
 | 
					  Matrix         & SmootherMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & SmootherOperator;
 | 
				
			||||||
 | 
					  RealD tol;
 | 
				
			||||||
 | 
					  RealD shift;
 | 
				
			||||||
 | 
					  int   maxit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MirsSmoother(RealD _shift,RealD _tol,int _maxit,FineOperator &_SmootherOperator,Matrix &_SmootherMatrix) :
 | 
				
			||||||
 | 
					    shift(_shift),tol(_tol),maxit(_maxit),
 | 
				
			||||||
 | 
					    SmootherOperator(_SmootherOperator),
 | 
				
			||||||
 | 
					    SmootherMatrix(_SmootherMatrix)
 | 
				
			||||||
 | 
					  {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void operator() (const Field &in, Field &out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    ZeroGuesser<Field> Guess;
 | 
				
			||||||
 | 
					    ConjugateGradient<Field>  CG(tol,maxit,false);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    Field src(in.Grid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ShiftedMdagMLinearOperator<SparseMatrixBase<Field>,Field> MdagMOp(SmootherMatrix,shift);
 | 
				
			||||||
 | 
					    SmootherOperator.AdjOp(in,src);
 | 
				
			||||||
 | 
					    Guess(src,out);
 | 
				
			||||||
 | 
					    CG(MdagMOp,src,out); 
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class Fobj,class CComplex,int nbasis, class Matrix, class Guesser, class CoarseSolver>
 | 
				
			||||||
 | 
					class MultiGridPreconditioner : public LinearFunction< Lattice<Fobj> > {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Aggregation<Fobj,CComplex,nbasis> Aggregates;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<Fobj,CComplex,nbasis> CoarseOperator;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::CoarseVector CoarseVector;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::CoarseMatrix CoarseMatrix;
 | 
				
			||||||
 | 
					  typedef typename Aggregation<Fobj,CComplex,nbasis>::FineField    FineField;
 | 
				
			||||||
 | 
					  typedef LinearOperatorBase<FineField>                            FineOperator;
 | 
				
			||||||
 | 
					  typedef LinearFunction    <FineField>                            FineSmoother;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Aggregates     & _Aggregates;
 | 
				
			||||||
 | 
					  CoarseOperator & _CoarseOperator;
 | 
				
			||||||
 | 
					  Matrix         & _FineMatrix;
 | 
				
			||||||
 | 
					  FineOperator   & _FineOperator;
 | 
				
			||||||
 | 
					  Guesser        & _Guess;
 | 
				
			||||||
 | 
					  FineSmoother   & _Smoother;
 | 
				
			||||||
 | 
					  CoarseSolver   & _CoarseSolve;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int    level;  void Level(int lv) {level = lv; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GridLogLevel std::cout << GridLogMessage <<std::string(level,'\t')<< " Level "<<level <<" "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MultiGridPreconditioner(Aggregates &Agg, CoarseOperator &Coarse, 
 | 
				
			||||||
 | 
								  FineOperator &Fine,Matrix &FineMatrix,
 | 
				
			||||||
 | 
								  FineSmoother &Smoother,
 | 
				
			||||||
 | 
								  Guesser &Guess_,
 | 
				
			||||||
 | 
								  CoarseSolver &CoarseSolve_)
 | 
				
			||||||
 | 
					    : _Aggregates(Agg),
 | 
				
			||||||
 | 
					      _CoarseOperator(Coarse),
 | 
				
			||||||
 | 
					      _FineOperator(Fine),
 | 
				
			||||||
 | 
					      _FineMatrix(FineMatrix),
 | 
				
			||||||
 | 
					      _Smoother(Smoother),
 | 
				
			||||||
 | 
					      _Guess(Guess_),
 | 
				
			||||||
 | 
					      _CoarseSolve(CoarseSolve_),
 | 
				
			||||||
 | 
					      level(1)  {  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  virtual void operator()(const FineField &in, FineField & out) 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    CoarseVector Csrc(_CoarseOperator.Grid());
 | 
				
			||||||
 | 
					    CoarseVector Csol(_CoarseOperator.Grid()); 
 | 
				
			||||||
 | 
					    FineField vec1(in.Grid());
 | 
				
			||||||
 | 
					    FineField vec2(in.Grid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    double t;
 | 
				
			||||||
 | 
					    // Fine Smoother
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Smoother(in,out);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Smoother took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update the residual
 | 
				
			||||||
 | 
					    _FineOperator.Op(out,vec1);  sub(vec1, in ,vec1);   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fine to Coarse 
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Aggregates.ProjectToSubspace  (Csrc,vec1);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Project to coarse took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Coarse correction
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _CoarseSolve(Csrc,Csol);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Coarse solve took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Coarse to Fine
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Aggregates.PromoteFromSubspace(Csol,vec1); 
 | 
				
			||||||
 | 
					    add(out,out,vec1);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Promote to this level took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Residual
 | 
				
			||||||
 | 
					    _FineOperator.Op(out,vec1);  sub(vec1 ,in , vec1);  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fine Smoother
 | 
				
			||||||
 | 
					    t=-usecond();
 | 
				
			||||||
 | 
					    _Smoother(vec1,vec2);
 | 
				
			||||||
 | 
					    t+=usecond();
 | 
				
			||||||
 | 
					    GridLogLevel << "Smoother took "<< t/1000.0<< "ms" <<std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add( out,out,vec2);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main (int argc, char ** argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Grid_init(&argc,&argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const int Ls=24;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian         * UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian         * FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Construct a coarsened grid; utility for this?
 | 
				
			||||||
 | 
					  ///////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  std::vector<int> block ({2,2,2,2});
 | 
				
			||||||
 | 
					  std::vector<int> blockc ({2,2,2,2});
 | 
				
			||||||
 | 
					  const int nbasis= 40;
 | 
				
			||||||
 | 
					  const int nbasisc= 40;
 | 
				
			||||||
 | 
					  auto clatt = GridDefaultLatt();
 | 
				
			||||||
 | 
					  for(int d=0;d<clatt.size();d++){
 | 
				
			||||||
 | 
					    clatt[d] = clatt[d]/block[d];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  auto cclatt = clatt;
 | 
				
			||||||
 | 
					  for(int d=0;d<clatt.size();d++){
 | 
				
			||||||
 | 
					    cclatt[d] = clatt[d]/blockc[d];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridCartesian *Coarse4d =  SpaceTimeGrid::makeFourDimGrid(clatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
 | 
					  GridCartesian *Coarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					  //  GridCartesian *CoarseCoarse4d =  SpaceTimeGrid::makeFourDimGrid(cclatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
 | 
					  //  GridCartesian *CoarseCoarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,CoarseCoarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::vector<int> seeds4({1,2,3,4});
 | 
				
			||||||
 | 
					  std::vector<int> seeds5({5,6,7,8});
 | 
				
			||||||
 | 
					  std::vector<int> cseeds({5,6,7,8});
 | 
				
			||||||
 | 
					  GridParallelRNG          RNG5(FGrid);   RNG5.SeedFixedIntegers(seeds5);
 | 
				
			||||||
 | 
					  GridParallelRNG          RNG4(UGrid);   RNG4.SeedFixedIntegers(seeds4);
 | 
				
			||||||
 | 
					  GridParallelRNG          CRNG(Coarse5d);CRNG.SeedFixedIntegers(cseeds);
 | 
				
			||||||
 | 
					  LatticeFermion    src(FGrid); gaussian(RNG5,src);// src=src+g5*src;
 | 
				
			||||||
 | 
					  LatticeFermion result(FGrid); 
 | 
				
			||||||
 | 
					  LatticeGaugeField Umu(UGrid); 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  FieldMetaData header;
 | 
				
			||||||
 | 
					  //  std::string file("./ckpoint_lat.4000");
 | 
				
			||||||
 | 
					  std::string file("./ckpoint_lat.1000");
 | 
				
			||||||
 | 
					  NerscIO::readConfiguration(Umu,header,file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building g5R5 hermitian DWF operator" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  RealD mass=0.00078;
 | 
				
			||||||
 | 
					  RealD M5=1.8;
 | 
				
			||||||
 | 
					  DomainWallFermionR Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  typedef Aggregation<vSpinColourVector,vTComplex,nbasis>              Subspace;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<vSpinColourVector,vTComplex,nbasis>          CoarseOperator;
 | 
				
			||||||
 | 
					  typedef CoarseOperator::CoarseVector                                 CoarseVector;
 | 
				
			||||||
 | 
					  typedef CoarseOperator::siteVector siteVector;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling Aggregation class to build subspace" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  MdagMLinearOperator<DomainWallFermionR,LatticeFermion> HermDefOp(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Subspace Aggregates(Coarse5d,FGrid,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  assert ( (nbasis & 0x1)==0);
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    int nb=nbasis/2;
 | 
				
			||||||
 | 
					    LatticeFermion A(FGrid);
 | 
				
			||||||
 | 
					    LatticeFermion B(FGrid);
 | 
				
			||||||
 | 
					    //    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.002,1000,800,100,0.0);
 | 
				
			||||||
 | 
					    //    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.02,1000,800,100,0.0); 
 | 
				
			||||||
 | 
					    Aggregates.CreateSubspaceChebyshev(RNG5,HermDefOp,nb,60.0,0.01,1000,100,100,0.0); // Slightly faster
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(int n=0;n<nb;n++){
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " G5R5 "<<n<<std::endl;
 | 
				
			||||||
 | 
					      G5R5(Aggregates.subspace[n+nb],Aggregates.subspace[n]);
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " Projection "<<n<<std::endl;
 | 
				
			||||||
 | 
					      A = Aggregates.subspace[n];
 | 
				
			||||||
 | 
					      B = Aggregates.subspace[n+nb];
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " Copy "<<n<<std::endl;
 | 
				
			||||||
 | 
					      Aggregates.subspace[n]   = A+B; // 1+G5 // eigen value of G5R5 is +1
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " P+ "<<n<<std::endl;
 | 
				
			||||||
 | 
					      Aggregates.subspace[n+nb]= A-B; // 1-G5 // eigen value of G5R5 is -1
 | 
				
			||||||
 | 
					      std::cout << GridLogMessage << " P- "<<n<<std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building coarse representation of Indef operator" <<std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<vSpinColourVector,vTComplex,nbasis>    Level1Op;
 | 
				
			||||||
 | 
					  typedef CoarsenedMatrix<siteVector,iScalar<vTComplex>,nbasisc> Level2Op;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Gamma5R5HermitianLinearOperator<DomainWallFermionR,LatticeFermion> HermIndefOp(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse4dRB = SpaceTimeGrid::makeFourDimRedBlackGrid(Coarse4d);
 | 
				
			||||||
 | 
					  std::cout << " Making 5D coarse RB grid " <<std::endl;
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse5dRB = SpaceTimeGrid::makeFiveDimRedBlackGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					  std::cout << " Made 5D coarse RB grid " <<std::endl;
 | 
				
			||||||
 | 
					  Level1Op LDOp(*Coarse5d,*Coarse5dRB,1); LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  // Deflate the course space. Recursive multigrid?
 | 
				
			||||||
 | 
					  //////////////////////////////////////////////////
 | 
				
			||||||
 | 
					  typedef Aggregation<siteVector,iScalar<vTComplex>,nbasisc>                   CoarseSubspace;
 | 
				
			||||||
 | 
					  //  CoarseSubspace CoarseAggregates(CoarseCoarse5d,Coarse5d,0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Build deflation space in coarse operator "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MdagMLinearOperator<CoarseOperator,CoarseVector> PosdefLdop(LDOp);
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    int nb=nbasisc/2;
 | 
				
			||||||
 | 
					    CoarseAggregates.CreateSubspaceChebyshev(CRNG,PosdefLdop,nb,15.0,0.02,1000,800,100,0.0);
 | 
				
			||||||
 | 
					    for(int n=0;n<nb;n++){
 | 
				
			||||||
 | 
					      autoView( subspace   , CoarseAggregates.subspace[n],CpuWrite);
 | 
				
			||||||
 | 
					      autoView( subspace_g5, CoarseAggregates.subspace[n+nb],CpuWrite);
 | 
				
			||||||
 | 
					      for(int nn=0;nn<nb;nn++){
 | 
				
			||||||
 | 
						for(int site=0;site<Coarse5d->oSites();site++){
 | 
				
			||||||
 | 
						  subspace_g5[site](nn)   = subspace[site](nn);
 | 
				
			||||||
 | 
						  subspace_g5[site](nn+nb)=-subspace[site](nn+nb);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  typedef Level2Op::CoarseVector CoarseCoarseVector;
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  Level2Op L2Op(*CoarseCoarse5d,1); // Hermitian matrix
 | 
				
			||||||
 | 
					  HermitianLinearOperator<Level1Op,CoarseVector> L1LinOp(LDOp);
 | 
				
			||||||
 | 
					  L2Op.CoarsenOperator(Coarse5d,L1LinOp,CoarseAggregates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Running CoarseCoarse grid Lanczos "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  MdagMLinearOperator<Level2Op,CoarseCoarseVector> IRLHermOpL2(L2Op);
 | 
				
			||||||
 | 
					  CoarseCoarseVector cc_src(CoarseCoarse5d); cc_src=1.0;
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  Chebyshev<CoarseCoarseVector> IRLChebyL2(0.001,15.0,301);
 | 
				
			||||||
 | 
					  FunctionHermOp<CoarseCoarseVector> IRLOpChebyL2(IRLChebyL2,IRLHermOpL2);
 | 
				
			||||||
 | 
					  PlainHermOp<CoarseCoarseVector> IRLOpL2    (IRLHermOpL2);
 | 
				
			||||||
 | 
					  int cNk=24;
 | 
				
			||||||
 | 
					  int cNm=36;
 | 
				
			||||||
 | 
					  int cNstop=24;
 | 
				
			||||||
 | 
					  ImplicitlyRestartedLanczos<CoarseCoarseVector> IRLL2(IRLOpChebyL2,IRLOpL2,cNstop,cNk,cNm,1.0e-3,20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int cNconv;
 | 
				
			||||||
 | 
					  std::vector<RealD>          eval2(cNm);
 | 
				
			||||||
 | 
					  std::vector<CoarseCoarseVector>   evec2(cNm,CoarseCoarse5d);
 | 
				
			||||||
 | 
					  IRLL2.calc(eval2,evec2,cc_src,cNconv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ConjugateGradient<CoarseCoarseVector>  CoarseCoarseCG(0.1,1000);
 | 
				
			||||||
 | 
					  DeflatedGuesser<CoarseCoarseVector> DeflCoarseCoarseGuesser(evec2,eval2);
 | 
				
			||||||
 | 
					  NormalEquations<CoarseCoarseVector> DeflCoarseCoarseCGNE(L2Op,CoarseCoarseCG,DeflCoarseCoarseGuesser);
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Running Coarse grid Lanczos "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MdagMLinearOperator<Level1Op,CoarseVector> IRLHermOp(LDOp);
 | 
				
			||||||
 | 
					  //  Chebyshev<CoarseVector>      IRLCheby(0.001,15.0,301);
 | 
				
			||||||
 | 
					  Chebyshev<CoarseVector>      IRLCheby(0.03,12.0,101);
 | 
				
			||||||
 | 
					  FunctionHermOp<CoarseVector> IRLOpCheby(IRLCheby,IRLHermOp);
 | 
				
			||||||
 | 
					  PlainHermOp<CoarseVector>    IRLOp    (IRLHermOp);
 | 
				
			||||||
 | 
					  int Nk=64;
 | 
				
			||||||
 | 
					  int Nm=128;
 | 
				
			||||||
 | 
					  int Nstop=Nk;
 | 
				
			||||||
 | 
					  ImplicitlyRestartedLanczos<CoarseVector> IRL(IRLOpCheby,IRLOp,Nstop,Nk,Nm,1.0e-3,20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int Nconv;
 | 
				
			||||||
 | 
					  std::vector<RealD>            eval(Nm);
 | 
				
			||||||
 | 
					  std::vector<CoarseVector>     evec(Nm,Coarse5d);
 | 
				
			||||||
 | 
					  IRL.calc(eval,evec,c_src,Nconv);
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  CoarseVector c_src(Coarse5d); c_src=1.0;
 | 
				
			||||||
 | 
					  //  DeflatedGuesser<CoarseVector> DeflCoarseGuesser(evec,eval);
 | 
				
			||||||
 | 
					  //  NormalEquations<CoarseVector> DeflCoarseCGNE(LDOp,CoarseCG,DeflCoarseGuesser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Building 3 level Multigrid            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  //  typedef MultiGridPreconditioner<vSpinColourVector,  vTComplex,nbasis, DomainWallFermionR,DeflatedGuesser<CoarseVector> , NormalEquations<CoarseVector> >   TwoLevelMG;
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<vSpinColourVector,  vTComplex,nbasis, DomainWallFermionR,ZeroGuesser<CoarseVector> , NormalEquations<CoarseVector> >   TwoLevelMG;
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<siteVector,iScalar<vTComplex>,nbasisc,Level1Op, DeflatedGuesser<CoarseCoarseVector>, NormalEquations<CoarseCoarseVector> > CoarseMG;
 | 
				
			||||||
 | 
					  typedef MultiGridPreconditioner<vSpinColourVector,  vTComplex,nbasis, DomainWallFermionR,ZeroGuesser<CoarseVector>, LinearFunction<CoarseVector> >     ThreeLevelMG;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ChebyshevSmoother<LatticeFermion,DomainWallFermionR> FineSmoother(0.25,60.0,12,HermIndefOp,Ddwf);
 | 
				
			||||||
 | 
					  /*
 | 
				
			||||||
 | 
					  // MultiGrid preconditioner acting on the coarse space <-> coarsecoarse space
 | 
				
			||||||
 | 
					  ChebyshevSmoother<CoarseVector,  Level1Op >        CoarseSmoother(0.1,15.0,3,L1LinOp,LDOp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //  MirsSmoother<CoarseVector,  Level1Op >        CoarseCGSmoother(0.1,0.1,4,L1LinOp,LDOp);
 | 
				
			||||||
 | 
					  //  MirsSmoother<LatticeFermion,DomainWallFermionR> FineCGSmoother(0.0,0.01,8,HermIndefOp,Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CoarseMG Level2Precon (CoarseAggregates, L2Op,
 | 
				
			||||||
 | 
								 L1LinOp,LDOp,
 | 
				
			||||||
 | 
								 CoarseSmoother,
 | 
				
			||||||
 | 
								 DeflCoarseCoarseGuesser,	
 | 
				
			||||||
 | 
							 DeflCoarseCoarseCGNE);
 | 
				
			||||||
 | 
					  Level2Precon.Level(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // PGCR Applying this solver to solve the coarse space problem
 | 
				
			||||||
 | 
					  PrecGeneralisedConjugateResidual<CoarseVector>  l2PGCR(0.1, 100, L1LinOp,Level2Precon,16,16);
 | 
				
			||||||
 | 
					  l2PGCR.Level(2);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Wrap the 2nd level solver in a MultiGrid preconditioner acting on the fine space
 | 
				
			||||||
 | 
					  ZeroGuesser<CoarseVector> CoarseZeroGuesser;
 | 
				
			||||||
 | 
					  ThreeLevelMG ThreeLevelPrecon(Aggregates, LDOp,
 | 
				
			||||||
 | 
									HermIndefOp,Ddwf,
 | 
				
			||||||
 | 
									FineSmoother,
 | 
				
			||||||
 | 
									CoarseZeroGuesser,
 | 
				
			||||||
 | 
									l2PGCR);
 | 
				
			||||||
 | 
					  ThreeLevelPrecon.Level(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Apply the fine-coarse-coarsecoarse 2 deep MG preconditioner in an outer PGCR on the fine fgrid
 | 
				
			||||||
 | 
					  PrecGeneralisedConjugateResidual<LatticeFermion> l1PGCR(1.0e-8,1000,HermIndefOp,ThreeLevelPrecon,16,16);
 | 
				
			||||||
 | 
					  l1PGCR.Level(1);
 | 
				
			||||||
 | 
					  */
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling 2 level Multigrid            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ZeroGuesser<CoarseVector> CoarseZeroGuesser;
 | 
				
			||||||
 | 
					    ConjugateGradient<CoarseVector>  CoarseCG(0.01,1000);
 | 
				
			||||||
 | 
					    NormalEquations<CoarseVector> CoarseCGNE(LDOp,CoarseCG,CoarseZeroGuesser);
 | 
				
			||||||
 | 
					    TwoLevelMG TwoLevelPrecon(Aggregates, LDOp,
 | 
				
			||||||
 | 
								      HermIndefOp,Ddwf,
 | 
				
			||||||
 | 
								      FineSmoother,
 | 
				
			||||||
 | 
								      CoarseZeroGuesser,	
 | 
				
			||||||
 | 
								      CoarseCGNE);
 | 
				
			||||||
 | 
					    TwoLevelPrecon.Level(1);
 | 
				
			||||||
 | 
					    PrecGeneralisedConjugateResidual<LatticeFermion> l1PGCR(1.0e-8,20,HermIndefOp,TwoLevelPrecon,16,16);
 | 
				
			||||||
 | 
					    l1PGCR.Level(1);
 | 
				
			||||||
 | 
					    l1PGCR(src,result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling CG            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  ConjugateGradient<LatticeFermion> pCG(1.0e-8,60000);
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					  //  pCG(HermDefOp,src,result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Calling red black CG            "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  result=Zero();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LatticeFermion    src_o(FrbGrid);
 | 
				
			||||||
 | 
					    LatticeFermion result_o(FrbGrid);
 | 
				
			||||||
 | 
					    pickCheckerboard(Odd,src_o,src);
 | 
				
			||||||
 | 
					    result_o=Zero();
 | 
				
			||||||
 | 
					    SchurDiagMooeeOperator<DomainWallFermionR,LatticeFermion> HermOpEO(Ddwf);
 | 
				
			||||||
 | 
					    pCG(HermOpEO,src_o,result_o);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Fine        PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  PowerMethod<LatticeFermion>       PM;   PM(HermDefOp,src);
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << " Coarse       PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  PowerMethod<CoarseVector>        cPM;  cPM(PosdefLdop,c_src);
 | 
				
			||||||
 | 
					  //  std::cout<<GridLogMessage << " CoarseCoarse PowerMethod           "<< std::endl;
 | 
				
			||||||
 | 
					  //  PowerMethod<CoarseCoarseVector> ccPM; ccPM(IRLHermOpL2,cc_src);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "Done "<< std::endl;
 | 
				
			||||||
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					  Grid_finalize();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -370,6 +370,11 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
  GridCartesian *CoarseCoarse4d =  SpaceTimeGrid::makeFourDimGrid(cclatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
					  GridCartesian *CoarseCoarse4d =  SpaceTimeGrid::makeFourDimGrid(cclatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
  GridCartesian *CoarseCoarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,CoarseCoarse4d);
 | 
					  GridCartesian *CoarseCoarse5d =  SpaceTimeGrid::makeFiveDimGrid(1,CoarseCoarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse4dRB = SpaceTimeGrid::makeFourDimRedBlackGrid(Coarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse5dRB = SpaceTimeGrid::makeFiveDimRedBlackGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian *CoarseCoarse4dRB = SpaceTimeGrid::makeFourDimRedBlackGrid(CoarseCoarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian *CoarseCoarse5dRB = SpaceTimeGrid::makeFiveDimRedBlackGrid(1,CoarseCoarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<int> seeds4({1,2,3,4});
 | 
					  std::vector<int> seeds4({1,2,3,4});
 | 
				
			||||||
  std::vector<int> seeds5({5,6,7,8});
 | 
					  std::vector<int> seeds5({5,6,7,8});
 | 
				
			||||||
  std::vector<int> cseeds({5,6,7,8});
 | 
					  std::vector<int> cseeds({5,6,7,8});
 | 
				
			||||||
@@ -434,8 +439,8 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
  std::cout<<GridLogMessage << "Building coarse representation of Indef operator" <<std::endl;
 | 
					  std::cout<<GridLogMessage << "Building coarse representation of Indef operator" <<std::endl;
 | 
				
			||||||
  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Level1Op LDOp(*Coarse5d,1);   LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates);
 | 
					  Level1Op LDOp(*Coarse5d,*Coarse5dRB,1);   LDOp.CoarsenOperator(FGrid,HermIndefOp,Aggregates);
 | 
				
			||||||
  Level1Op LDOpPV(*Coarse5d,1); LDOpPV.CoarsenOperator(FGrid,HermIndefOpPV,Aggregates);
 | 
					  Level1Op LDOpPV(*Coarse5d,*Coarse5dRB,1); LDOpPV.CoarsenOperator(FGrid,HermIndefOpPV,Aggregates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
					  std::cout<<GridLogMessage << "**************************************************"<< std::endl;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -274,6 +274,8 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  GridCartesian *Coarse4d =  SpaceTimeGrid::makeFourDimGrid(clatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
					  GridCartesian *Coarse4d =  SpaceTimeGrid::makeFourDimGrid(clatt, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());;
 | 
				
			||||||
  GridCartesian *Coarse5d =  SpaceTimeGrid::makeFiveDimGrid(Ls,Coarse4d);
 | 
					  GridCartesian *Coarse5d =  SpaceTimeGrid::makeFiveDimGrid(Ls,Coarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse4dRB = SpaceTimeGrid::makeFourDimRedBlackGrid(Coarse4d);
 | 
				
			||||||
 | 
					  GridRedBlackCartesian * Coarse5dRB = SpaceTimeGrid::makeFiveDimRedBlackGrid(1,Coarse4d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  std::vector<int> seeds({1,2,3,4});
 | 
					  std::vector<int> seeds({1,2,3,4});
 | 
				
			||||||
  GridParallelRNG          RNG5(FGrid);   RNG5.SeedFixedIntegers(seeds);
 | 
					  GridParallelRNG          RNG5(FGrid);   RNG5.SeedFixedIntegers(seeds);
 | 
				
			||||||
@@ -335,7 +337,7 @@ int main (int argc, char ** argv)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  NonHermitianLinearOperator<DomainWallFermionR,LatticeFermion>  LinOpDwf(Ddwf);
 | 
					  NonHermitianLinearOperator<DomainWallFermionR,LatticeFermion>  LinOpDwf(Ddwf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Level1Op LDOp  (*Coarse5d,0);   
 | 
					  Level1Op LDOp  (*Coarse5d,*Coarse5dRB,0);   
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  std::cout<<GridLogMessage << " Callinig Coarsen the operator                          " <<std::endl;
 | 
					  std::cout<<GridLogMessage << " Callinig Coarsen the operator                          " <<std::endl;
 | 
				
			||||||
  LDOp.CoarsenOperator(FGrid,LinOpDwf,Aggregates5D);
 | 
					  LDOp.CoarsenOperator(FGrid,LinOpDwf,Aggregates5D);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1287
									
								
								tests/solver/Test_hw_multigrid_mixed_48.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1287
									
								
								tests/solver/Test_hw_multigrid_mixed_48.cc
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1326
									
								
								tests/solver/Test_hw_multigrid_mixed_48_rb.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1326
									
								
								tests/solver/Test_hw_multigrid_mixed_48_rb.cc
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user