mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-10-31 12:04:33 +00:00 
			
		
		
		
	CLeanup and no QCD namespace
This commit is contained in:
		| @@ -1,4 +1,4 @@ | |||||||
|     /************************************************************************************* | /************************************************************************************* | ||||||
|  |  | ||||||
|     Grid physics library, www.github.com/paboyle/Grid  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
|  |  | ||||||
| @@ -26,455 +26,455 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  | ||||||
|     See the full license in the file "LICENSE" in the top level distribution directory |     See the full license in the file "LICENSE" in the top level distribution directory | ||||||
|     *************************************************************************************/ | *************************************************************************************/ | ||||||
|     /*  END LEGAL */ | /*  END LEGAL */ | ||||||
| #ifndef  GRID_ALGORITHM_COARSENED_MATRIX_H | #ifndef  GRID_ALGORITHM_COARSENED_MATRIX_H | ||||||
| #define  GRID_ALGORITHM_COARSENED_MATRIX_H | #define  GRID_ALGORITHM_COARSENED_MATRIX_H | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace Grid { | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|   class Geometry { | class Geometry { | ||||||
|     //    int dimension; |   //    int dimension; | ||||||
|   public: | public: | ||||||
|     int npoint; |   int npoint; | ||||||
|     std::vector<int> directions   ; |   std::vector<int> directions   ; | ||||||
|     std::vector<int> displacements; |   std::vector<int> displacements; | ||||||
|  |  | ||||||
|   Geometry(int _d)  { |   Geometry(int _d)  { | ||||||
|    |    | ||||||
|       int base = (_d==5) ? 1:0; |     int base = (_d==5) ? 1:0; | ||||||
|  |  | ||||||
|       // make coarse grid stencil for 4d , not 5d |     // make coarse grid stencil for 4d , not 5d | ||||||
|       if ( _d==5 ) _d=4; |     if ( _d==5 ) _d=4; | ||||||
|  |  | ||||||
|       npoint = 2*_d+1; |     npoint = 2*_d+1; | ||||||
|       directions.resize(npoint); |     directions.resize(npoint); | ||||||
|       displacements.resize(npoint); |     displacements.resize(npoint); | ||||||
|       for(int d=0;d<_d;d++){ |     for(int d=0;d<_d;d++){ | ||||||
| 	directions[2*d  ] = d+base; |       directions[2*d  ] = d+base; | ||||||
| 	directions[2*d+1] = d+base; |       directions[2*d+1] = d+base; | ||||||
| 	displacements[2*d  ] = +1; |       displacements[2*d  ] = +1; | ||||||
| 	displacements[2*d+1] = -1; |       displacements[2*d+1] = -1; | ||||||
|       } |     } | ||||||
|       directions   [2*_d]=0; |     directions   [2*_d]=0; | ||||||
|       displacements[2*_d]=0; |     displacements[2*_d]=0; | ||||||
|        |        | ||||||
|       //// report back |     //// report back | ||||||
|       std::cout<<GridLogMessage<<"directions    :"; |     std::cout<<GridLogMessage<<"directions    :"; | ||||||
|       for(int d=0;d<npoint;d++) std::cout<< directions[d]<< " "; |     for(int d=0;d<npoint;d++) std::cout<< directions[d]<< " "; | ||||||
|       std::cout <<std::endl; |     std::cout <<std::endl; | ||||||
|       std::cout<<GridLogMessage<<"displacements :"; |     std::cout<<GridLogMessage<<"displacements :"; | ||||||
|       for(int d=0;d<npoint;d++) std::cout<< displacements[d]<< " "; |     for(int d=0;d<npoint;d++) std::cout<< displacements[d]<< " "; | ||||||
|       std::cout<<std::endl; |     std::cout<<std::endl; | ||||||
|     } |   } | ||||||
|    |    | ||||||
|     /* |   /* | ||||||
|       // Original cleaner code |   // Original cleaner code | ||||||
|     Geometry(int _d) : dimension(_d), npoint(2*_d+1), directions(npoint), displacements(npoint) { |   Geometry(int _d) : dimension(_d), npoint(2*_d+1), directions(npoint), displacements(npoint) { | ||||||
|       for(int d=0;d<dimension;d++){ |   for(int d=0;d<dimension;d++){ | ||||||
| 	directions[2*d  ] = d; |   directions[2*d  ] = d; | ||||||
| 	directions[2*d+1] = d; |   directions[2*d+1] = d; | ||||||
| 	displacements[2*d  ] = +1; |   displacements[2*d  ] = +1; | ||||||
| 	displacements[2*d+1] = -1; |   displacements[2*d+1] = -1; | ||||||
|       } |   } | ||||||
|       directions   [2*dimension]=0; |   directions   [2*dimension]=0; | ||||||
|       displacements[2*dimension]=0; |   displacements[2*dimension]=0; | ||||||
|     } |   } | ||||||
|     std::vector<int> GetDelta(int point) { |   std::vector<int> GetDelta(int point) { | ||||||
|       std::vector<int> delta(dimension,0); |   std::vector<int> delta(dimension,0); | ||||||
|       delta[directions[point]] = displacements[point]; |   delta[directions[point]] = displacements[point]; | ||||||
|       return delta; |   return delta; | ||||||
|     }; |  | ||||||
|     */     |  | ||||||
|  |  | ||||||
|   }; |   }; | ||||||
|  |   */     | ||||||
|  |  | ||||||
|  | }; | ||||||
|    |    | ||||||
|   template<class Fobj,class CComplex,int nbasis> | template<class Fobj,class CComplex,int nbasis> | ||||||
|   class Aggregation   { | class Aggregation   { | ||||||
|   public: | public: | ||||||
|     typedef iVector<CComplex,nbasis >             siteVector; |   typedef iVector<CComplex,nbasis >             siteVector; | ||||||
|     typedef Lattice<siteVector>                 CoarseVector; |   typedef Lattice<siteVector>                 CoarseVector; | ||||||
|     typedef Lattice<iMatrix<CComplex,nbasis > > CoarseMatrix; |   typedef Lattice<iMatrix<CComplex,nbasis > > CoarseMatrix; | ||||||
|  |  | ||||||
|     typedef Lattice< CComplex >   CoarseScalar; // used for inner products on fine field |   typedef Lattice< CComplex >   CoarseScalar; // used for inner products on fine field | ||||||
|     typedef Lattice<Fobj >        FineField; |   typedef Lattice<Fobj >        FineField; | ||||||
|  |  | ||||||
|     GridBase *CoarseGrid; |   GridBase *CoarseGrid; | ||||||
|     GridBase *FineGrid; |   GridBase *FineGrid; | ||||||
|     std::vector<Lattice<Fobj> > subspace; |   std::vector<Lattice<Fobj> > subspace; | ||||||
|     int checkerboard; |   int checkerboard; | ||||||
|  |  | ||||||
|   Aggregation(GridBase *_CoarseGrid,GridBase *_FineGrid,int _checkerboard) :  |   Aggregation(GridBase *_CoarseGrid,GridBase *_FineGrid,int _checkerboard) :  | ||||||
|     CoarseGrid(_CoarseGrid), |     CoarseGrid(_CoarseGrid), | ||||||
|       FineGrid(_FineGrid), |     FineGrid(_FineGrid), | ||||||
|       subspace(nbasis,_FineGrid), |     subspace(nbasis,_FineGrid), | ||||||
|       checkerboard(_checkerboard) |     checkerboard(_checkerboard) | ||||||
| 	{ |   { | ||||||
| 	}; |   }; | ||||||
|    |    | ||||||
|     void Orthogonalise(void){ |   void Orthogonalise(void){ | ||||||
|       CoarseScalar InnerProd(CoarseGrid);  |     CoarseScalar InnerProd(CoarseGrid);  | ||||||
|       std::cout << GridLogMessage <<" Gramm-Schmidt pass 1"<<std::endl; |     std::cout << GridLogMessage <<" Gramm-Schmidt pass 1"<<std::endl; | ||||||
|       blockOrthogonalise(InnerProd,subspace); |     blockOrthogonalise(InnerProd,subspace); | ||||||
|       std::cout << GridLogMessage <<" Gramm-Schmidt pass 2"<<std::endl; |     std::cout << GridLogMessage <<" Gramm-Schmidt pass 2"<<std::endl; | ||||||
|       blockOrthogonalise(InnerProd,subspace); |     blockOrthogonalise(InnerProd,subspace); | ||||||
|       //      std::cout << GridLogMessage <<" Gramm-Schmidt checking orthogonality"<<std::endl; |     //      std::cout << GridLogMessage <<" Gramm-Schmidt checking orthogonality"<<std::endl; | ||||||
|       //      CheckOrthogonal(); |     //      CheckOrthogonal(); | ||||||
|     }  |   }  | ||||||
|     void CheckOrthogonal(void){ |   void CheckOrthogonal(void){ | ||||||
|       CoarseVector iProj(CoarseGrid);  |     CoarseVector iProj(CoarseGrid);  | ||||||
|       CoarseVector eProj(CoarseGrid);  |     CoarseVector eProj(CoarseGrid);  | ||||||
|       for(int i=0;i<nbasis;i++){ |     for(int i=0;i<nbasis;i++){ | ||||||
| 	blockProject(iProj,subspace[i],subspace); |       blockProject(iProj,subspace[i],subspace); | ||||||
| 	eProj=zero;  |       eProj=zero;  | ||||||
| 	parallel_for(int ss=0;ss<CoarseGrid->oSites();ss++){ |       parallel_for(int ss=0;ss<CoarseGrid->oSites();ss++){ | ||||||
| 	  eProj._odata[ss](i)=CComplex(1.0); | 	eProj._odata[ss](i)=CComplex(1.0); | ||||||
| 	} |  | ||||||
| 	eProj=eProj - iProj; |  | ||||||
| 	std::cout<<GridLogMessage<<"Orthog check error "<<i<<" " << norm2(eProj)<<std::endl; |  | ||||||
|       } |       } | ||||||
|       std::cout<<GridLogMessage <<"CheckOrthog done"<<std::endl; |       eProj=eProj - iProj; | ||||||
|  |       std::cout<<GridLogMessage<<"Orthog check error "<<i<<" " << norm2(eProj)<<std::endl; | ||||||
|     } |     } | ||||||
|     void ProjectToSubspace(CoarseVector &CoarseVec,const FineField &FineVec){ |     std::cout<<GridLogMessage <<"CheckOrthog done"<<std::endl; | ||||||
|       blockProject(CoarseVec,FineVec,subspace); |   } | ||||||
|     } |   void ProjectToSubspace(CoarseVector &CoarseVec,const FineField &FineVec){ | ||||||
|     void PromoteFromSubspace(const CoarseVector &CoarseVec,FineField &FineVec){ |     blockProject(CoarseVec,FineVec,subspace); | ||||||
|       FineVec.checkerboard = subspace[0].checkerboard; |   } | ||||||
|       blockPromote(CoarseVec,FineVec,subspace); |   void PromoteFromSubspace(const CoarseVector &CoarseVec,FineField &FineVec){ | ||||||
|     } |     FineVec.checkerboard = subspace[0].checkerboard; | ||||||
|     void CreateSubspaceRandom(GridParallelRNG &RNG){ |     blockPromote(CoarseVec,FineVec,subspace); | ||||||
|       for(int i=0;i<nbasis;i++){ |   } | ||||||
| 	random(RNG,subspace[i]); |   void CreateSubspaceRandom(GridParallelRNG &RNG){ | ||||||
| 	std::cout<<GridLogMessage<<" norm subspace["<<i<<"] "<<norm2(subspace[i])<<std::endl; |     for(int i=0;i<nbasis;i++){ | ||||||
|       } |       random(RNG,subspace[i]); | ||||||
|       Orthogonalise(); |       std::cout<<GridLogMessage<<" norm subspace["<<i<<"] "<<norm2(subspace[i])<<std::endl; | ||||||
|     } |     } | ||||||
|  |     Orthogonalise(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|     /* |   /* | ||||||
|     virtual void CreateSubspaceLanczos(GridParallelRNG  &RNG,LinearOperatorBase<FineField> &hermop,int nn=nbasis)  |     virtual void CreateSubspaceLanczos(GridParallelRNG  &RNG,LinearOperatorBase<FineField> &hermop,int nn=nbasis)  | ||||||
|     { |     { | ||||||
|       // Run a Lanczos with sloppy convergence |     // Run a Lanczos with sloppy convergence | ||||||
| 	const int Nstop = nn; |     const int Nstop = nn; | ||||||
| 	const int Nk = nn+20; |     const int Nk = nn+20; | ||||||
| 	const int Np = nn+20; |     const int Np = nn+20; | ||||||
| 	const int Nm = Nk+Np; |     const int Nm = Nk+Np; | ||||||
| 	const int MaxIt= 10000; |     const int MaxIt= 10000; | ||||||
| 	RealD resid = 1.0e-3; |     RealD resid = 1.0e-3; | ||||||
|  |  | ||||||
| 	Chebyshev<FineField> Cheb(0.5,64.0,21); |     Chebyshev<FineField> Cheb(0.5,64.0,21); | ||||||
| 	ImplicitlyRestartedLanczos<FineField> IRL(hermop,Cheb,Nstop,Nk,Nm,resid,MaxIt); |     ImplicitlyRestartedLanczos<FineField> IRL(hermop,Cheb,Nstop,Nk,Nm,resid,MaxIt); | ||||||
| 	//	IRL.lock = 1; |     //	IRL.lock = 1; | ||||||
|  |  | ||||||
| 	FineField noise(FineGrid); gaussian(RNG,noise); |     FineField noise(FineGrid); gaussian(RNG,noise); | ||||||
| 	FineField tmp(FineGrid);  |     FineField tmp(FineGrid);  | ||||||
| 	std::vector<RealD>     eval(Nm); |     std::vector<RealD>     eval(Nm); | ||||||
| 	std::vector<FineField> evec(Nm,FineGrid); |     std::vector<FineField> evec(Nm,FineGrid); | ||||||
|  |  | ||||||
| 	int Nconv; |     int Nconv; | ||||||
| 	IRL.calc(eval,evec, |     IRL.calc(eval,evec, | ||||||
| 		 noise, |     noise, | ||||||
| 		 Nconv); |     Nconv); | ||||||
|  |  | ||||||
|     	// pull back nn vectors |     // pull back nn vectors | ||||||
| 	for(int b=0;b<nn;b++){ |     for(int b=0;b<nn;b++){ | ||||||
|  |  | ||||||
| 	  subspace[b]   = evec[b]; |     subspace[b]   = evec[b]; | ||||||
|  |  | ||||||
| 	  std::cout << GridLogMessage <<"subspace["<<b<<"] = "<<norm2(subspace[b])<<std::endl; |     std::cout << GridLogMessage <<"subspace["<<b<<"] = "<<norm2(subspace[b])<<std::endl; | ||||||
|  |  | ||||||
| 	  hermop.Op(subspace[b],tmp);  |     hermop.Op(subspace[b],tmp);  | ||||||
| 	  std::cout<<GridLogMessage << "filtered["<<b<<"] <f|MdagM|f> "<<norm2(tmp)<<std::endl; |     std::cout<<GridLogMessage << "filtered["<<b<<"] <f|MdagM|f> "<<norm2(tmp)<<std::endl; | ||||||
|  |  | ||||||
| 	  noise = tmp -  sqrt(eval[b])*subspace[b] ; |     noise = tmp -  sqrt(eval[b])*subspace[b] ; | ||||||
|  |  | ||||||
| 	  std::cout<<GridLogMessage << " lambda_"<<b<<" = "<< eval[b] <<"  ;  [ M - Lambda ]_"<<b<<" vec_"<<b<<"  = " <<norm2(noise)<<std::endl; |     std::cout<<GridLogMessage << " lambda_"<<b<<" = "<< eval[b] <<"  ;  [ M - Lambda ]_"<<b<<" vec_"<<b<<"  = " <<norm2(noise)<<std::endl; | ||||||
|  |  | ||||||
| 	  noise = tmp +  eval[b]*subspace[b] ; |     noise = tmp +  eval[b]*subspace[b] ; | ||||||
|  |  | ||||||
| 	  std::cout<<GridLogMessage << " lambda_"<<b<<" = "<< eval[b] <<"  ;  [ M - Lambda ]_"<<b<<" vec_"<<b<<"  = " <<norm2(noise)<<std::endl; |     std::cout<<GridLogMessage << " lambda_"<<b<<" = "<< eval[b] <<"  ;  [ M - Lambda ]_"<<b<<" vec_"<<b<<"  = " <<norm2(noise)<<std::endl; | ||||||
|  |  | ||||||
| 	} |  | ||||||
| 	Orthogonalise(); |  | ||||||
| 	for(int b=0;b<nn;b++){ |  | ||||||
| 	  std::cout << GridLogMessage <<"subspace["<<b<<"] = "<<norm2(subspace[b])<<std::endl; |  | ||||||
| 	} |  | ||||||
|     } |     } | ||||||
|     */ |     Orthogonalise(); | ||||||
|     virtual void CreateSubspace(GridParallelRNG  &RNG,LinearOperatorBase<FineField> &hermop,int nn=nbasis) { |     for(int b=0;b<nn;b++){ | ||||||
|  |     std::cout << GridLogMessage <<"subspace["<<b<<"] = "<<norm2(subspace[b])<<std::endl; | ||||||
|  |     } | ||||||
|  |     } | ||||||
|  |   */ | ||||||
|  |   virtual void CreateSubspace(GridParallelRNG  &RNG,LinearOperatorBase<FineField> &hermop,int nn=nbasis) { | ||||||
|  |  | ||||||
|       RealD scale; |     RealD scale; | ||||||
|  |  | ||||||
|       ConjugateGradient<FineField> CG(1.0e-2,10000); |     ConjugateGradient<FineField> CG(1.0e-2,10000); | ||||||
|       FineField noise(FineGrid); |     FineField noise(FineGrid); | ||||||
|       FineField Mn(FineGrid); |     FineField Mn(FineGrid); | ||||||
|  |  | ||||||
|       for(int b=0;b<nn;b++){ |     for(int b=0;b<nn;b++){ | ||||||
| 	 | 	 | ||||||
| 	gaussian(RNG,noise); |       gaussian(RNG,noise); | ||||||
|  |       scale = std::pow(norm2(noise),-0.5);  | ||||||
|  |       noise=noise*scale; | ||||||
|  |  | ||||||
|  |       hermop.Op(noise,Mn); std::cout<<GridLogMessage << "noise   ["<<b<<"] <n|MdagM|n> "<<norm2(Mn)<<std::endl; | ||||||
|  |  | ||||||
|  |       for(int i=0;i<1;i++){ | ||||||
|  |  | ||||||
|  | 	CG(hermop,noise,subspace[b]); | ||||||
|  |  | ||||||
|  | 	noise = subspace[b]; | ||||||
| 	scale = std::pow(norm2(noise),-0.5);  | 	scale = std::pow(norm2(noise),-0.5);  | ||||||
| 	noise=noise*scale; | 	noise=noise*scale; | ||||||
|  |  | ||||||
| 	hermop.Op(noise,Mn); std::cout<<GridLogMessage << "noise   ["<<b<<"] <n|MdagM|n> "<<norm2(Mn)<<std::endl; |  | ||||||
|  |  | ||||||
| 	for(int i=0;i<1;i++){ |  | ||||||
|  |  | ||||||
| 	  CG(hermop,noise,subspace[b]); |  | ||||||
|  |  | ||||||
| 	  noise = subspace[b]; |  | ||||||
| 	  scale = std::pow(norm2(noise),-0.5);  |  | ||||||
| 	  noise=noise*scale; |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	hermop.Op(noise,Mn); std::cout<<GridLogMessage << "filtered["<<b<<"] <f|MdagM|f> "<<norm2(Mn)<<std::endl; |  | ||||||
| 	subspace[b]   = noise; |  | ||||||
|  |  | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       Orthogonalise(); |       hermop.Op(noise,Mn); std::cout<<GridLogMessage << "filtered["<<b<<"] <f|MdagM|f> "<<norm2(Mn)<<std::endl; | ||||||
|  |       subspace[b]   = noise; | ||||||
|  |  | ||||||
|     } |     } | ||||||
|   }; |  | ||||||
|   // Fine Object == (per site) type of fine field |     Orthogonalise(); | ||||||
|   // nbasis      == number of deflation vectors |  | ||||||
|   template<class Fobj,class CComplex,int nbasis> |   } | ||||||
|   class CoarsenedMatrix : public SparseMatrixBase<Lattice<iVector<CComplex,nbasis > > >  { | }; | ||||||
|   public: | // Fine Object == (per site) type of fine field | ||||||
|  | // nbasis      == number of deflation vectors | ||||||
|  | template<class Fobj,class CComplex,int nbasis> | ||||||
|  | class CoarsenedMatrix : public SparseMatrixBase<Lattice<iVector<CComplex,nbasis > > >  { | ||||||
|  | public: | ||||||
|      |      | ||||||
|     typedef iVector<CComplex,nbasis >             siteVector; |   typedef iVector<CComplex,nbasis >             siteVector; | ||||||
|     typedef Lattice<siteVector>                 CoarseVector; |   typedef Lattice<siteVector>                 CoarseVector; | ||||||
|     typedef Lattice<iMatrix<CComplex,nbasis > > CoarseMatrix; |   typedef Lattice<iMatrix<CComplex,nbasis > > CoarseMatrix; | ||||||
|  |  | ||||||
|     typedef Lattice< CComplex >   CoarseScalar; // used for inner products on fine field |   typedef Lattice< CComplex >   CoarseScalar; // used for inner products on fine field | ||||||
|     typedef Lattice<Fobj >        FineField; |   typedef Lattice<Fobj >        FineField; | ||||||
|  |  | ||||||
|     //////////////////// |   //////////////////// | ||||||
|     // Data members |   // Data members | ||||||
|     //////////////////// |   //////////////////// | ||||||
|     Geometry         geom; |   Geometry         geom; | ||||||
|     GridBase *       _grid;  |   GridBase *       _grid;  | ||||||
|     CartesianStencil<siteVector,siteVector> Stencil;  |   CartesianStencil<siteVector,siteVector> Stencil;  | ||||||
|  |  | ||||||
|     std::vector<CoarseMatrix> A; |   std::vector<CoarseMatrix> A; | ||||||
|  |  | ||||||
|        |        | ||||||
|     /////////////////////// |   /////////////////////// | ||||||
|     // Interface |   // Interface | ||||||
|     /////////////////////// |   /////////////////////// | ||||||
|     GridBase * Grid(void)         { return _grid; };   // this is all the linalg routines need to know |   GridBase * Grid(void)         { return _grid; };   // this is all the linalg routines need to know | ||||||
|  |  | ||||||
|     RealD M (const CoarseVector &in, CoarseVector &out){ |   RealD M (const CoarseVector &in, CoarseVector &out){ | ||||||
|  |  | ||||||
|       conformable(_grid,in._grid); |     conformable(_grid,in._grid); | ||||||
|       conformable(in._grid,out._grid); |     conformable(in._grid,out._grid); | ||||||
|  |  | ||||||
|       SimpleCompressor<siteVector> compressor; |     SimpleCompressor<siteVector> compressor; | ||||||
|       Stencil.HaloExchange(in,compressor); |     Stencil.HaloExchange(in,compressor); | ||||||
|  |  | ||||||
|       parallel_for(int ss=0;ss<Grid()->oSites();ss++){ |     parallel_for(int ss=0;ss<Grid()->oSites();ss++){ | ||||||
|         siteVector res = zero; |       siteVector res = zero; | ||||||
| 	siteVector nbr; |       siteVector nbr; | ||||||
| 	int ptype; |       int ptype; | ||||||
| 	StencilEntry *SE; |       StencilEntry *SE; | ||||||
| 	for(int point=0;point<geom.npoint;point++){ |       for(int point=0;point<geom.npoint;point++){ | ||||||
|  |  | ||||||
| 	  SE=Stencil.GetEntry(ptype,point,ss); | 	SE=Stencil.GetEntry(ptype,point,ss); | ||||||
| 	   | 	   | ||||||
| 	  if(SE->_is_local&&SE->_permute) {  | 	if(SE->_is_local&&SE->_permute) {  | ||||||
| 	    permute(nbr,in._odata[SE->_offset],ptype); | 	  permute(nbr,in._odata[SE->_offset],ptype); | ||||||
| 	  } else if(SE->_is_local) {  | 	} else if(SE->_is_local) {  | ||||||
| 	    nbr = in._odata[SE->_offset]; | 	  nbr = in._odata[SE->_offset]; | ||||||
| 	  } else { | 	} else { | ||||||
| 	    nbr = Stencil.CommBuf()[SE->_offset]; | 	  nbr = Stencil.CommBuf()[SE->_offset]; | ||||||
| 	  } |  | ||||||
| 	  res = res + A[point]._odata[ss]*nbr; |  | ||||||
| 	} | 	} | ||||||
| 	vstream(out._odata[ss],res); | 	res = res + A[point]._odata[ss]*nbr; | ||||||
|       } |       } | ||||||
|       return norm2(out); |       vstream(out._odata[ss],res); | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     RealD Mdag (const CoarseVector &in, CoarseVector &out){  |  | ||||||
|       return M(in,out); |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     // Defer support for further coarsening for now |  | ||||||
|     void Mdiag    (const CoarseVector &in,  CoarseVector &out){}; |  | ||||||
|     void Mdir     (const CoarseVector &in,  CoarseVector &out,int dir, int disp){}; |  | ||||||
|  |  | ||||||
|     CoarsenedMatrix(GridCartesian &CoarseGrid) 	:  |  | ||||||
|  |  | ||||||
|       _grid(&CoarseGrid), |  | ||||||
|       geom(CoarseGrid._ndimension), |  | ||||||
|       Stencil(&CoarseGrid,geom.npoint,Even,geom.directions,geom.displacements), |  | ||||||
|       A(geom.npoint,&CoarseGrid) |  | ||||||
|     { |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     void CoarsenOperator(GridBase *FineGrid,LinearOperatorBase<Lattice<Fobj> > &linop, |  | ||||||
| 			 Aggregation<Fobj,CComplex,nbasis> & Subspace){ |  | ||||||
|  |  | ||||||
|       FineField iblock(FineGrid); // contributions from within this block |  | ||||||
|       FineField oblock(FineGrid); // contributions from outwith this block |  | ||||||
|  |  | ||||||
|       FineField     phi(FineGrid); |  | ||||||
|       FineField     tmp(FineGrid); |  | ||||||
|       FineField     zz(FineGrid); zz=zero; |  | ||||||
|       FineField    Mphi(FineGrid); |  | ||||||
|  |  | ||||||
|       Lattice<iScalar<vInteger> > coor(FineGrid); |  | ||||||
|  |  | ||||||
|       CoarseVector iProj(Grid());  |  | ||||||
|       CoarseVector oProj(Grid());  |  | ||||||
|       CoarseScalar InnerProd(Grid());  |  | ||||||
|  |  | ||||||
|       // Orthogonalise the subblocks over the basis |  | ||||||
|       blockOrthogonalise(InnerProd,Subspace.subspace); |  | ||||||
|  |  | ||||||
|       // Compute the matrix elements of linop between this orthonormal |  | ||||||
|       // set of vectors. |  | ||||||
|       int self_stencil=-1; |  | ||||||
|       for(int p=0;p<geom.npoint;p++){  |  | ||||||
| 	A[p]=zero; |  | ||||||
| 	if( geom.displacements[p]==0){ |  | ||||||
| 	  self_stencil=p; |  | ||||||
| 	} |  | ||||||
|       } |  | ||||||
|       assert(self_stencil!=-1); |  | ||||||
|  |  | ||||||
|       for(int i=0;i<nbasis;i++){ |  | ||||||
| 	phi=Subspace.subspace[i]; |  | ||||||
| 	 |  | ||||||
| 	std::cout<<GridLogMessage<<"("<<i<<").."<<std::endl; |  | ||||||
|  |  | ||||||
| 	for(int p=0;p<geom.npoint;p++){  |  | ||||||
|  |  | ||||||
| 	  int dir   = geom.directions[p]; |  | ||||||
| 	  int disp  = geom.displacements[p]; |  | ||||||
|  |  | ||||||
| 	  Integer block=(FineGrid->_rdimensions[dir])/(Grid()->_rdimensions[dir]); |  | ||||||
|  |  | ||||||
| 	  LatticeCoordinate(coor,dir); |  | ||||||
|  |  | ||||||
| 	  if ( disp==0 ){ |  | ||||||
| 	    linop.OpDiag(phi,Mphi); |  | ||||||
| 	  } |  | ||||||
| 	  else  { |  | ||||||
| 	    linop.OpDir(phi,Mphi,dir,disp);  |  | ||||||
| 	  } |  | ||||||
|  |  | ||||||
| 	  //////////////////////////////////////////////////////////////////////// |  | ||||||
| 	  // Pick out contributions coming from this cell and neighbour cell |  | ||||||
| 	  //////////////////////////////////////////////////////////////////////// |  | ||||||
| 	  if ( disp==0 ) { |  | ||||||
| 	    iblock = Mphi; |  | ||||||
| 	    oblock = zero; |  | ||||||
| 	  } else if ( disp==1 ) { |  | ||||||
| 	    oblock = where(mod(coor,block)==(block-1),Mphi,zz); |  | ||||||
| 	    iblock = where(mod(coor,block)!=(block-1),Mphi,zz); |  | ||||||
| 	  } else if ( disp==-1 ) { |  | ||||||
| 	    oblock = where(mod(coor,block)==(Integer)0,Mphi,zz); |  | ||||||
| 	    iblock = where(mod(coor,block)!=(Integer)0,Mphi,zz); |  | ||||||
| 	  } else { |  | ||||||
| 	    assert(0); |  | ||||||
| 	  } |  | ||||||
|  |  | ||||||
| 	  Subspace.ProjectToSubspace(iProj,iblock); |  | ||||||
| 	  Subspace.ProjectToSubspace(oProj,oblock); |  | ||||||
| 	  //	  blockProject(iProj,iblock,Subspace.subspace); |  | ||||||
| 	  //	  blockProject(oProj,oblock,Subspace.subspace); |  | ||||||
| 	  parallel_for(int ss=0;ss<Grid()->oSites();ss++){ |  | ||||||
| 	    for(int j=0;j<nbasis;j++){ |  | ||||||
| 	      if( disp!= 0 ) { |  | ||||||
| 		A[p]._odata[ss](j,i) = oProj._odata[ss](j); |  | ||||||
| 	      } |  | ||||||
| 	      A[self_stencil]._odata[ss](j,i) =	A[self_stencil]._odata[ss](j,i) + iProj._odata[ss](j); |  | ||||||
| 	    } |  | ||||||
| 	  } |  | ||||||
| 	} |  | ||||||
|       } |  | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
|       /////////////////////////// |  | ||||||
|       // test code worth preserving in if block |  | ||||||
|       /////////////////////////// |  | ||||||
|       std::cout<<GridLogMessage<< " Computed matrix elements "<< self_stencil <<std::endl; |  | ||||||
|       for(int p=0;p<geom.npoint;p++){ |  | ||||||
| 	std::cout<<GridLogMessage<< "A["<<p<<"]" << std::endl; |  | ||||||
| 	std::cout<<GridLogMessage<< A[p] << std::endl; |  | ||||||
|       } |  | ||||||
|       std::cout<<GridLogMessage<< " picking by block0 "<< self_stencil <<std::endl; |  | ||||||
|  |  | ||||||
|       phi=Subspace.subspace[0]; |  | ||||||
|       std::vector<int> bc(FineGrid->_ndimension,0); |  | ||||||
|  |  | ||||||
|       blockPick(Grid(),phi,tmp,bc);      // Pick out a block |  | ||||||
|       linop.Op(tmp,Mphi);                // Apply big dop |  | ||||||
|       blockProject(iProj,Mphi,Subspace.subspace); // project it and print it |  | ||||||
|       std::cout<<GridLogMessage<< " Computed matrix elements from block zero only "<<std::endl; |  | ||||||
|       std::cout<<GridLogMessage<< iProj <<std::endl; |  | ||||||
|       std::cout<<GridLogMessage<<"Computed Coarse Operator"<<std::endl; |  | ||||||
| #endif |  | ||||||
|       //      ForceHermitian(); |  | ||||||
|       AssertHermitian(); |  | ||||||
|       // ForceDiagonal(); |  | ||||||
|     } |     } | ||||||
|     void ForceDiagonal(void) { |     return norm2(out); | ||||||
|  |  | ||||||
|  |  | ||||||
|       std::cout<<GridLogMessage<<"**************************************************"<<std::endl; |  | ||||||
|       std::cout<<GridLogMessage<<"****   Forcing coarse operator to be diagonal ****"<<std::endl; |  | ||||||
|       std::cout<<GridLogMessage<<"**************************************************"<<std::endl; |  | ||||||
|       for(int p=0;p<8;p++){ |  | ||||||
| 	A[p]=zero; |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       GridParallelRNG  RNG(Grid()); RNG.SeedFixedIntegers(std::vector<int>({55,72,19,17,34})); |  | ||||||
|       Lattice<iScalar<CComplex> > val(Grid()); random(RNG,val); |  | ||||||
|  |  | ||||||
|       Complex one(1.0); |  | ||||||
|  |  | ||||||
|       iMatrix<CComplex,nbasis> ident;  ident=one; |  | ||||||
|  |  | ||||||
|       val = val*adj(val); |  | ||||||
|       val = val + 1.0; |  | ||||||
|  |  | ||||||
|       A[8] = val*ident; |  | ||||||
|  |  | ||||||
|       //      for(int s=0;s<Grid()->oSites();s++) { |  | ||||||
|       //	A[8]._odata[s]=val._odata[s]; |  | ||||||
|       //      } |  | ||||||
|     } |  | ||||||
|     void ForceHermitian(void) { |  | ||||||
|       for(int d=0;d<4;d++){ |  | ||||||
| 	int dd=d+1; |  | ||||||
| 	A[2*d] = adj(Cshift(A[2*d+1],dd,1)); |  | ||||||
|       } |  | ||||||
|       //      A[8] = 0.5*(A[8] + adj(A[8])); |  | ||||||
|     } |  | ||||||
|     void AssertHermitian(void) { |  | ||||||
|       CoarseMatrix AA    (Grid()); |  | ||||||
|       CoarseMatrix AAc   (Grid()); |  | ||||||
|       CoarseMatrix Diff  (Grid()); |  | ||||||
|       for(int d=0;d<4;d++){ |  | ||||||
| 	 |  | ||||||
| 	int dd=d+1; |  | ||||||
| 	AAc = Cshift(A[2*d+1],dd,1); |  | ||||||
| 	AA  = A[2*d]; |  | ||||||
| 	 |  | ||||||
| 	Diff = AA - adj(AAc); |  | ||||||
|  |  | ||||||
| 	std::cout<<GridLogMessage<<"Norm diff dim "<<d<<" "<< norm2(Diff)<<std::endl; |  | ||||||
| 	std::cout<<GridLogMessage<<"Norm dim "<<d<<" "<< norm2(AA)<<std::endl; |  | ||||||
| 	   |  | ||||||
|       } |  | ||||||
|       Diff = A[8] - adj(A[8]); |  | ||||||
|       std::cout<<GridLogMessage<<"Norm diff local "<< norm2(Diff)<<std::endl; |  | ||||||
|       std::cout<<GridLogMessage<<"Norm local "<< norm2(A[8])<<std::endl; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| } |   RealD Mdag (const CoarseVector &in, CoarseVector &out){  | ||||||
|  |     return M(in,out); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   // Defer support for further coarsening for now | ||||||
|  |   void Mdiag    (const CoarseVector &in,  CoarseVector &out){}; | ||||||
|  |   void Mdir     (const CoarseVector &in,  CoarseVector &out,int dir, int disp){}; | ||||||
|  |  | ||||||
|  |   CoarsenedMatrix(GridCartesian &CoarseGrid) 	:  | ||||||
|  |  | ||||||
|  |     _grid(&CoarseGrid), | ||||||
|  |     geom(CoarseGrid._ndimension), | ||||||
|  |     Stencil(&CoarseGrid,geom.npoint,Even,geom.directions,geom.displacements), | ||||||
|  |     A(geom.npoint,&CoarseGrid) | ||||||
|  |   { | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   void CoarsenOperator(GridBase *FineGrid,LinearOperatorBase<Lattice<Fobj> > &linop, | ||||||
|  | 		       Aggregation<Fobj,CComplex,nbasis> & Subspace){ | ||||||
|  |  | ||||||
|  |     FineField iblock(FineGrid); // contributions from within this block | ||||||
|  |     FineField oblock(FineGrid); // contributions from outwith this block | ||||||
|  |  | ||||||
|  |     FineField     phi(FineGrid); | ||||||
|  |     FineField     tmp(FineGrid); | ||||||
|  |     FineField     zz(FineGrid); zz=zero; | ||||||
|  |     FineField    Mphi(FineGrid); | ||||||
|  |  | ||||||
|  |     Lattice<iScalar<vInteger> > coor(FineGrid); | ||||||
|  |  | ||||||
|  |     CoarseVector iProj(Grid());  | ||||||
|  |     CoarseVector oProj(Grid());  | ||||||
|  |     CoarseScalar InnerProd(Grid());  | ||||||
|  |  | ||||||
|  |     // Orthogonalise the subblocks over the basis | ||||||
|  |     blockOrthogonalise(InnerProd,Subspace.subspace); | ||||||
|  |  | ||||||
|  |     // Compute the matrix elements of linop between this orthonormal | ||||||
|  |     // set of vectors. | ||||||
|  |     int self_stencil=-1; | ||||||
|  |     for(int p=0;p<geom.npoint;p++){  | ||||||
|  |       A[p]=zero; | ||||||
|  |       if( geom.displacements[p]==0){ | ||||||
|  | 	self_stencil=p; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     assert(self_stencil!=-1); | ||||||
|  |  | ||||||
|  |     for(int i=0;i<nbasis;i++){ | ||||||
|  |       phi=Subspace.subspace[i]; | ||||||
|  | 	 | ||||||
|  |       std::cout<<GridLogMessage<<"("<<i<<").."<<std::endl; | ||||||
|  |  | ||||||
|  |       for(int p=0;p<geom.npoint;p++){  | ||||||
|  |  | ||||||
|  | 	int dir   = geom.directions[p]; | ||||||
|  | 	int disp  = geom.displacements[p]; | ||||||
|  |  | ||||||
|  | 	Integer block=(FineGrid->_rdimensions[dir])/(Grid()->_rdimensions[dir]); | ||||||
|  |  | ||||||
|  | 	LatticeCoordinate(coor,dir); | ||||||
|  |  | ||||||
|  | 	if ( disp==0 ){ | ||||||
|  | 	  linop.OpDiag(phi,Mphi); | ||||||
|  | 	} | ||||||
|  | 	else  { | ||||||
|  | 	  linop.OpDir(phi,Mphi,dir,disp);  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	//////////////////////////////////////////////////////////////////////// | ||||||
|  | 	// Pick out contributions coming from this cell and neighbour cell | ||||||
|  | 	//////////////////////////////////////////////////////////////////////// | ||||||
|  | 	if ( disp==0 ) { | ||||||
|  | 	  iblock = Mphi; | ||||||
|  | 	  oblock = zero; | ||||||
|  | 	} else if ( disp==1 ) { | ||||||
|  | 	  oblock = where(mod(coor,block)==(block-1),Mphi,zz); | ||||||
|  | 	  iblock = where(mod(coor,block)!=(block-1),Mphi,zz); | ||||||
|  | 	} else if ( disp==-1 ) { | ||||||
|  | 	  oblock = where(mod(coor,block)==(Integer)0,Mphi,zz); | ||||||
|  | 	  iblock = where(mod(coor,block)!=(Integer)0,Mphi,zz); | ||||||
|  | 	} else { | ||||||
|  | 	  assert(0); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	Subspace.ProjectToSubspace(iProj,iblock); | ||||||
|  | 	Subspace.ProjectToSubspace(oProj,oblock); | ||||||
|  | 	//	  blockProject(iProj,iblock,Subspace.subspace); | ||||||
|  | 	//	  blockProject(oProj,oblock,Subspace.subspace); | ||||||
|  | 	parallel_for(int ss=0;ss<Grid()->oSites();ss++){ | ||||||
|  | 	  for(int j=0;j<nbasis;j++){ | ||||||
|  | 	    if( disp!= 0 ) { | ||||||
|  | 	      A[p]._odata[ss](j,i) = oProj._odata[ss](j); | ||||||
|  | 	    } | ||||||
|  | 	    A[self_stencil]._odata[ss](j,i) =	A[self_stencil]._odata[ss](j,i) + iProj._odata[ss](j); | ||||||
|  | 	  } | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
|  |     /////////////////////////// | ||||||
|  |     // test code worth preserving in if block | ||||||
|  |     /////////////////////////// | ||||||
|  |     std::cout<<GridLogMessage<< " Computed matrix elements "<< self_stencil <<std::endl; | ||||||
|  |     for(int p=0;p<geom.npoint;p++){ | ||||||
|  |       std::cout<<GridLogMessage<< "A["<<p<<"]" << std::endl; | ||||||
|  |       std::cout<<GridLogMessage<< A[p] << std::endl; | ||||||
|  |     } | ||||||
|  |     std::cout<<GridLogMessage<< " picking by block0 "<< self_stencil <<std::endl; | ||||||
|  |  | ||||||
|  |     phi=Subspace.subspace[0]; | ||||||
|  |     std::vector<int> bc(FineGrid->_ndimension,0); | ||||||
|  |  | ||||||
|  |     blockPick(Grid(),phi,tmp,bc);      // Pick out a block | ||||||
|  |     linop.Op(tmp,Mphi);                // Apply big dop | ||||||
|  |     blockProject(iProj,Mphi,Subspace.subspace); // project it and print it | ||||||
|  |     std::cout<<GridLogMessage<< " Computed matrix elements from block zero only "<<std::endl; | ||||||
|  |     std::cout<<GridLogMessage<< iProj <<std::endl; | ||||||
|  |     std::cout<<GridLogMessage<<"Computed Coarse Operator"<<std::endl; | ||||||
|  | #endif | ||||||
|  |     //      ForceHermitian(); | ||||||
|  |     AssertHermitian(); | ||||||
|  |     // ForceDiagonal(); | ||||||
|  |   } | ||||||
|  |   void ForceDiagonal(void) { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     std::cout<<GridLogMessage<<"**************************************************"<<std::endl; | ||||||
|  |     std::cout<<GridLogMessage<<"****   Forcing coarse operator to be diagonal ****"<<std::endl; | ||||||
|  |     std::cout<<GridLogMessage<<"**************************************************"<<std::endl; | ||||||
|  |     for(int p=0;p<8;p++){ | ||||||
|  |       A[p]=zero; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     GridParallelRNG  RNG(Grid()); RNG.SeedFixedIntegers(std::vector<int>({55,72,19,17,34})); | ||||||
|  |     Lattice<iScalar<CComplex> > val(Grid()); random(RNG,val); | ||||||
|  |  | ||||||
|  |     Complex one(1.0); | ||||||
|  |  | ||||||
|  |     iMatrix<CComplex,nbasis> ident;  ident=one; | ||||||
|  |  | ||||||
|  |     val = val*adj(val); | ||||||
|  |     val = val + 1.0; | ||||||
|  |  | ||||||
|  |     A[8] = val*ident; | ||||||
|  |  | ||||||
|  |     //      for(int s=0;s<Grid()->oSites();s++) { | ||||||
|  |     //	A[8]._odata[s]=val._odata[s]; | ||||||
|  |     //      } | ||||||
|  |   } | ||||||
|  |   void ForceHermitian(void) { | ||||||
|  |     for(int d=0;d<4;d++){ | ||||||
|  |       int dd=d+1; | ||||||
|  |       A[2*d] = adj(Cshift(A[2*d+1],dd,1)); | ||||||
|  |     } | ||||||
|  |     //      A[8] = 0.5*(A[8] + adj(A[8])); | ||||||
|  |   } | ||||||
|  |   void AssertHermitian(void) { | ||||||
|  |     CoarseMatrix AA    (Grid()); | ||||||
|  |     CoarseMatrix AAc   (Grid()); | ||||||
|  |     CoarseMatrix Diff  (Grid()); | ||||||
|  |     for(int d=0;d<4;d++){ | ||||||
|  | 	 | ||||||
|  |       int dd=d+1; | ||||||
|  |       AAc = Cshift(A[2*d+1],dd,1); | ||||||
|  |       AA  = A[2*d]; | ||||||
|  | 	 | ||||||
|  |       Diff = AA - adj(AAc); | ||||||
|  |  | ||||||
|  |       std::cout<<GridLogMessage<<"Norm diff dim "<<d<<" "<< norm2(Diff)<<std::endl; | ||||||
|  |       std::cout<<GridLogMessage<<"Norm dim "<<d<<" "<< norm2(AA)<<std::endl; | ||||||
|  | 	   | ||||||
|  |     } | ||||||
|  |     Diff = A[8] - adj(A[8]); | ||||||
|  |     std::cout<<GridLogMessage<<"Norm diff local "<< norm2(Diff)<<std::endl; | ||||||
|  |     std::cout<<GridLogMessage<<"Norm local "<< norm2(A[8])<<std::endl; | ||||||
|  |   } | ||||||
|  |      | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | NAMESPACE_END(Grid); | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
|  |  | ||||||
|     /************************************************************************************* | /************************************************************************************* | ||||||
|  |  | ||||||
|     Grid physics library, www.github.com/paboyle/Grid  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
|  |  | ||||||
| @@ -24,8 +24,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  | ||||||
|     See the full license in the file "LICENSE" in the top level distribution directory |     See the full license in the file "LICENSE" in the top level distribution directory | ||||||
|     *************************************************************************************/ | *************************************************************************************/ | ||||||
|     /*  END LEGAL */ | /*  END LEGAL */ | ||||||
| #ifndef _GRID_FFT_H_ | #ifndef _GRID_FFT_H_ | ||||||
| #define _GRID_FFT_H_ | #define _GRID_FFT_H_ | ||||||
|  |  | ||||||
| @@ -38,64 +38,64 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace Grid { | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|   template<class scalar> struct FFTW { }; | template<class scalar> struct FFTW { }; | ||||||
|  |  | ||||||
| #ifdef HAVE_FFTW	 | #ifdef HAVE_FFTW	 | ||||||
|   template<> struct FFTW<ComplexD> { | template<> struct FFTW<ComplexD> { | ||||||
|   public: | public: | ||||||
|  |  | ||||||
|     typedef fftw_complex FFTW_scalar; |   typedef fftw_complex FFTW_scalar; | ||||||
|     typedef fftw_plan    FFTW_plan; |   typedef fftw_plan    FFTW_plan; | ||||||
|  |  | ||||||
|     static FFTW_plan fftw_plan_many_dft(int rank, const int *n,int howmany, |   static FFTW_plan fftw_plan_many_dft(int rank, const int *n,int howmany, | ||||||
| 					FFTW_scalar *in, const int *inembed,		 | 				      FFTW_scalar *in, const int *inembed,		 | ||||||
| 					int istride, int idist,		 | 				      int istride, int idist,		 | ||||||
| 					FFTW_scalar *out, const int *onembed,		 | 				      FFTW_scalar *out, const int *onembed,		 | ||||||
| 					int ostride, int odist,		 | 				      int ostride, int odist,		 | ||||||
| 					int sign, unsigned flags) { | 				      int sign, unsigned flags) { | ||||||
|       return ::fftw_plan_many_dft(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,sign,flags); |     return ::fftw_plan_many_dft(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,sign,flags); | ||||||
|     }	   |   }	   | ||||||
|      |      | ||||||
|     static void fftw_flops(const FFTW_plan p,double *add, double *mul, double *fmas){ |   static void fftw_flops(const FFTW_plan p,double *add, double *mul, double *fmas){ | ||||||
|       ::fftw_flops(p,add,mul,fmas); |     ::fftw_flops(p,add,mul,fmas); | ||||||
|     } |   } | ||||||
|  |  | ||||||
|     inline static void fftw_execute_dft(const FFTW_plan p,FFTW_scalar *in,FFTW_scalar *out) { |   inline static void fftw_execute_dft(const FFTW_plan p,FFTW_scalar *in,FFTW_scalar *out) { | ||||||
|       ::fftw_execute_dft(p,in,out); |     ::fftw_execute_dft(p,in,out); | ||||||
|     } |   } | ||||||
|     inline static void fftw_destroy_plan(const FFTW_plan p) { |   inline static void fftw_destroy_plan(const FFTW_plan p) { | ||||||
|       ::fftw_destroy_plan(p); |     ::fftw_destroy_plan(p); | ||||||
|     } |   } | ||||||
|   }; | }; | ||||||
|  |  | ||||||
|   template<> struct FFTW<ComplexF> { | template<> struct FFTW<ComplexF> { | ||||||
|   public: | public: | ||||||
|  |  | ||||||
|     typedef fftwf_complex FFTW_scalar; |   typedef fftwf_complex FFTW_scalar; | ||||||
|     typedef fftwf_plan    FFTW_plan; |   typedef fftwf_plan    FFTW_plan; | ||||||
|  |  | ||||||
|     static FFTW_plan fftw_plan_many_dft(int rank, const int *n,int howmany, |   static FFTW_plan fftw_plan_many_dft(int rank, const int *n,int howmany, | ||||||
| 					FFTW_scalar *in, const int *inembed,		 | 				      FFTW_scalar *in, const int *inembed,		 | ||||||
| 					int istride, int idist,		 | 				      int istride, int idist,		 | ||||||
| 					FFTW_scalar *out, const int *onembed,		 | 				      FFTW_scalar *out, const int *onembed,		 | ||||||
| 					int ostride, int odist,		 | 				      int ostride, int odist,		 | ||||||
| 					int sign, unsigned flags) { | 				      int sign, unsigned flags) { | ||||||
|       return ::fftwf_plan_many_dft(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,sign,flags); |     return ::fftwf_plan_many_dft(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,sign,flags); | ||||||
|     }	   |   }	   | ||||||
|      |      | ||||||
|     static void fftw_flops(const FFTW_plan p,double *add, double *mul, double *fmas){ |   static void fftw_flops(const FFTW_plan p,double *add, double *mul, double *fmas){ | ||||||
|       ::fftwf_flops(p,add,mul,fmas); |     ::fftwf_flops(p,add,mul,fmas); | ||||||
|     } |   } | ||||||
|  |  | ||||||
|     inline static void fftw_execute_dft(const FFTW_plan p,FFTW_scalar *in,FFTW_scalar *out) { |   inline static void fftw_execute_dft(const FFTW_plan p,FFTW_scalar *in,FFTW_scalar *out) { | ||||||
|       ::fftwf_execute_dft(p,in,out); |     ::fftwf_execute_dft(p,in,out); | ||||||
|     } |   } | ||||||
|     inline static void fftw_destroy_plan(const FFTW_plan p) { |   inline static void fftw_destroy_plan(const FFTW_plan p) { | ||||||
|       ::fftwf_destroy_plan(p); |     ::fftwf_destroy_plan(p); | ||||||
|     } |   } | ||||||
|   }; | }; | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -104,203 +104,204 @@ namespace Grid { | |||||||
| #define FFTW_BACKWARD (+1) | #define FFTW_BACKWARD (+1) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   class FFT { | class FFT { | ||||||
|   private: | private: | ||||||
|      |      | ||||||
|     GridCartesian *vgrid; |   GridCartesian *vgrid; | ||||||
|     GridCartesian *sgrid; |   GridCartesian *sgrid; | ||||||
|      |      | ||||||
|     int Nd; |   int Nd; | ||||||
|     double flops; |   double flops; | ||||||
|     double flops_call; |   double flops_call; | ||||||
|     uint64_t usec; |   uint64_t usec; | ||||||
|      |      | ||||||
|     std::vector<int> dimensions; |   std::vector<int> dimensions; | ||||||
|     std::vector<int> processors; |   std::vector<int> processors; | ||||||
|     std::vector<int> processor_coor; |   std::vector<int> processor_coor; | ||||||
|      |      | ||||||
|   public: | public: | ||||||
|      |      | ||||||
|     static const int forward=FFTW_FORWARD; |   static const int forward=FFTW_FORWARD; | ||||||
|     static const int backward=FFTW_BACKWARD; |   static const int backward=FFTW_BACKWARD; | ||||||
|      |      | ||||||
|     double Flops(void) {return flops;} |   double Flops(void) {return flops;} | ||||||
|     double MFlops(void) {return flops/usec;} |   double MFlops(void) {return flops/usec;} | ||||||
|     double USec(void)   {return (double)usec;}     |   double USec(void)   {return (double)usec;}     | ||||||
|  |  | ||||||
|     FFT ( GridCartesian * grid ) : |   FFT ( GridCartesian * grid ) : | ||||||
|     vgrid(grid), |     vgrid(grid), | ||||||
|     Nd(grid->_ndimension), |     Nd(grid->_ndimension), | ||||||
|     dimensions(grid->_fdimensions), |     dimensions(grid->_fdimensions), | ||||||
|     processors(grid->_processors), |     processors(grid->_processors), | ||||||
|     processor_coor(grid->_processor_coor) |     processor_coor(grid->_processor_coor) | ||||||
|     { |   { | ||||||
|       flops=0; |     flops=0; | ||||||
|       usec =0; |     usec =0; | ||||||
|       std::vector<int> layout(Nd,1); |     std::vector<int> layout(Nd,1); | ||||||
|       sgrid = new GridCartesian(dimensions,layout,processors); |     sgrid = new GridCartesian(dimensions,layout,processors); | ||||||
|     }; |   }; | ||||||
|      |      | ||||||
|     ~FFT ( void)  { |   ~FFT ( void)  { | ||||||
|       delete sgrid; |     delete sgrid; | ||||||
|     } |   } | ||||||
|      |      | ||||||
|     template<class vobj> |   template<class vobj> | ||||||
|     void FFT_dim_mask(Lattice<vobj> &result,const Lattice<vobj> &source,std::vector<int> mask,int sign){ |   void FFT_dim_mask(Lattice<vobj> &result,const Lattice<vobj> &source,std::vector<int> mask,int sign){ | ||||||
|  |  | ||||||
|       conformable(result._grid,vgrid); |     conformable(result._grid,vgrid); | ||||||
|       conformable(source._grid,vgrid); |     conformable(source._grid,vgrid); | ||||||
|       Lattice<vobj> tmp(vgrid); |     Lattice<vobj> tmp(vgrid); | ||||||
|       tmp = source; |     tmp = source; | ||||||
|       for(int d=0;d<Nd;d++){ |     for(int d=0;d<Nd;d++){ | ||||||
| 	if( mask[d] ) { |       if( mask[d] ) { | ||||||
| 	  FFT_dim(result,tmp,d,sign); | 	FFT_dim(result,tmp,d,sign); | ||||||
| 	  tmp=result; | 	tmp=result; | ||||||
| 	} |  | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|     template<class vobj> |   template<class vobj> | ||||||
|     void FFT_all_dim(Lattice<vobj> &result,const Lattice<vobj> &source,int sign){ |   void FFT_all_dim(Lattice<vobj> &result,const Lattice<vobj> &source,int sign){ | ||||||
|       std::vector<int> mask(Nd,1); |     std::vector<int> mask(Nd,1); | ||||||
|       FFT_dim_mask(result,source,mask,sign); |     FFT_dim_mask(result,source,mask,sign); | ||||||
|     } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|     template<class vobj> |   template<class vobj> | ||||||
|     void FFT_dim(Lattice<vobj> &result,const Lattice<vobj> &source,int dim, int sign){ |   void FFT_dim(Lattice<vobj> &result,const Lattice<vobj> &source,int dim, int sign){ | ||||||
| #ifndef HAVE_FFTW | #ifndef HAVE_FFTW | ||||||
|       assert(0); |     assert(0); | ||||||
| #else | #else | ||||||
|       conformable(result._grid,vgrid); |     conformable(result._grid,vgrid); | ||||||
|       conformable(source._grid,vgrid); |     conformable(source._grid,vgrid); | ||||||
|  |  | ||||||
|       int L = vgrid->_ldimensions[dim]; |     int L = vgrid->_ldimensions[dim]; | ||||||
|       int G = vgrid->_fdimensions[dim]; |     int G = vgrid->_fdimensions[dim]; | ||||||
|        |        | ||||||
|       std::vector<int> layout(Nd,1); |     std::vector<int> layout(Nd,1); | ||||||
|       std::vector<int> pencil_gd(vgrid->_fdimensions); |     std::vector<int> pencil_gd(vgrid->_fdimensions); | ||||||
|        |        | ||||||
|       pencil_gd[dim] = G*processors[dim]; |     pencil_gd[dim] = G*processors[dim]; | ||||||
|        |        | ||||||
|       // Pencil global vol LxLxGxLxL per node |     // Pencil global vol LxLxGxLxL per node | ||||||
|       GridCartesian pencil_g(pencil_gd,layout,processors); |     GridCartesian pencil_g(pencil_gd,layout,processors); | ||||||
|        |        | ||||||
|       // Construct pencils |     // Construct pencils | ||||||
|       typedef typename vobj::scalar_object sobj; |     typedef typename vobj::scalar_object sobj; | ||||||
|       typedef typename sobj::scalar_type   scalar; |     typedef typename sobj::scalar_type   scalar; | ||||||
|        |        | ||||||
|       Lattice<sobj> pgbuf(&pencil_g); |     Lattice<sobj> pgbuf(&pencil_g); | ||||||
|        |        | ||||||
|  |  | ||||||
|       typedef typename FFTW<scalar>::FFTW_scalar FFTW_scalar; |     typedef typename FFTW<scalar>::FFTW_scalar FFTW_scalar; | ||||||
|       typedef typename FFTW<scalar>::FFTW_plan   FFTW_plan; |     typedef typename FFTW<scalar>::FFTW_plan   FFTW_plan; | ||||||
|        |        | ||||||
|       int Ncomp = sizeof(sobj)/sizeof(scalar); |     int Ncomp = sizeof(sobj)/sizeof(scalar); | ||||||
|       int Nlow  = 1; |     int Nlow  = 1; | ||||||
|       for(int d=0;d<dim;d++){ |     for(int d=0;d<dim;d++){ | ||||||
|         Nlow*=vgrid->_ldimensions[d]; |       Nlow*=vgrid->_ldimensions[d]; | ||||||
|       } |     } | ||||||
|        |        | ||||||
|       int rank = 1;  /* 1d transforms */ |     int rank = 1;  /* 1d transforms */ | ||||||
|       int n[] = {G}; /* 1d transforms of length G */ |     int n[] = {G}; /* 1d transforms of length G */ | ||||||
|       int howmany = Ncomp; |     int howmany = Ncomp; | ||||||
|       int odist,idist,istride,ostride; |     int odist,idist,istride,ostride; | ||||||
|       idist   = odist   = 1;          /* Distance between consecutive FT's */ |     idist   = odist   = 1;          /* Distance between consecutive FT's */ | ||||||
|       istride = ostride = Ncomp*Nlow; /* distance between two elements in the same FT */ |     istride = ostride = Ncomp*Nlow; /* distance between two elements in the same FT */ | ||||||
|       int *inembed = n, *onembed = n; |     int *inembed = n, *onembed = n; | ||||||
|        |        | ||||||
|       scalar div; |     scalar div; | ||||||
| 	  if ( sign == backward ) div = 1.0/G; |     if ( sign == backward ) div = 1.0/G; | ||||||
| 	  else if ( sign == forward ) div = 1.0; |     else if ( sign == forward ) div = 1.0; | ||||||
| 	  else assert(0); |     else assert(0); | ||||||
|        |        | ||||||
|       FFTW_plan p; |     FFTW_plan p; | ||||||
|       { |     { | ||||||
|         FFTW_scalar *in = (FFTW_scalar *)&pgbuf._odata[0]; |       FFTW_scalar *in = (FFTW_scalar *)&pgbuf._odata[0]; | ||||||
|         FFTW_scalar *out= (FFTW_scalar *)&pgbuf._odata[0]; |       FFTW_scalar *out= (FFTW_scalar *)&pgbuf._odata[0]; | ||||||
|         p = FFTW<scalar>::fftw_plan_many_dft(rank,n,howmany, |       p = FFTW<scalar>::fftw_plan_many_dft(rank,n,howmany, | ||||||
|                                              in,inembed, | 					   in,inembed, | ||||||
|                                              istride,idist, | 					   istride,idist, | ||||||
|                                              out,onembed, | 					   out,onembed, | ||||||
|                                              ostride, odist, | 					   ostride, odist, | ||||||
|                                              sign,FFTW_ESTIMATE); | 					   sign,FFTW_ESTIMATE); | ||||||
|       } |     } | ||||||
|        |        | ||||||
|       // Barrel shift and collect global pencil |     // Barrel shift and collect global pencil | ||||||
|       std::vector<int> lcoor(Nd), gcoor(Nd); |     std::vector<int> lcoor(Nd), gcoor(Nd); | ||||||
|       result = source; |     result = source; | ||||||
|       int pc = processor_coor[dim]; |     int pc = processor_coor[dim]; | ||||||
|       for(int p=0;p<processors[dim];p++) { |     for(int p=0;p<processors[dim];p++) { | ||||||
|         PARALLEL_REGION |       PARALLEL_REGION | ||||||
|         { |         { | ||||||
|           std::vector<int> cbuf(Nd); |           std::vector<int> cbuf(Nd); | ||||||
|           sobj s; |           sobj s; | ||||||
|            |            | ||||||
|           PARALLEL_FOR_LOOP_INTERN |           PARALLEL_FOR_LOOP_INTERN | ||||||
|           for(int idx=0;idx<sgrid->lSites();idx++) { | 	    for(int idx=0;idx<sgrid->lSites();idx++) { | ||||||
|             sgrid->LocalIndexToLocalCoor(idx,cbuf); | 	      sgrid->LocalIndexToLocalCoor(idx,cbuf); | ||||||
|             peekLocalSite(s,result,cbuf); | 	      peekLocalSite(s,result,cbuf); | ||||||
| 	    cbuf[dim]+=((pc+p) % processors[dim])*L; | 	      cbuf[dim]+=((pc+p) % processors[dim])*L; | ||||||
| 	    //            cbuf[dim]+=p*L; | 	      //            cbuf[dim]+=p*L; | ||||||
|             pokeLocalSite(s,pgbuf,cbuf); | 	      pokeLocalSite(s,pgbuf,cbuf); | ||||||
|           } | 	    } | ||||||
|         } |         } | ||||||
|         if (p != processors[dim] - 1) |       if (p != processors[dim] - 1) | ||||||
|         { |         { | ||||||
|           result = Cshift(result,dim,L); |           result = Cshift(result,dim,L); | ||||||
|         } |         } | ||||||
|       } |     } | ||||||
|        |        | ||||||
|       // Loop over orthog coords |     // Loop over orthog coords | ||||||
|       int NN=pencil_g.lSites(); |     int NN=pencil_g.lSites(); | ||||||
|       GridStopWatch timer; |     GridStopWatch timer; | ||||||
|       timer.Start(); |     timer.Start(); | ||||||
|       PARALLEL_REGION |     PARALLEL_REGION | ||||||
|       { |       { | ||||||
|         std::vector<int> cbuf(Nd); |         std::vector<int> cbuf(Nd); | ||||||
|          |          | ||||||
|         PARALLEL_FOR_LOOP_INTERN |         PARALLEL_FOR_LOOP_INTERN | ||||||
|         for(int idx=0;idx<NN;idx++) { | 	  for(int idx=0;idx<NN;idx++) { | ||||||
|           pencil_g.LocalIndexToLocalCoor(idx, cbuf); | 	    pencil_g.LocalIndexToLocalCoor(idx, cbuf); | ||||||
|           if ( cbuf[dim] == 0 ) {  // restricts loop to plane at lcoor[dim]==0 | 	    if ( cbuf[dim] == 0 ) {  // restricts loop to plane at lcoor[dim]==0 | ||||||
|             FFTW_scalar *in = (FFTW_scalar *)&pgbuf._odata[idx]; | 	      FFTW_scalar *in = (FFTW_scalar *)&pgbuf._odata[idx]; | ||||||
|             FFTW_scalar *out= (FFTW_scalar *)&pgbuf._odata[idx]; | 	      FFTW_scalar *out= (FFTW_scalar *)&pgbuf._odata[idx]; | ||||||
|             FFTW<scalar>::fftw_execute_dft(p,in,out); | 	      FFTW<scalar>::fftw_execute_dft(p,in,out); | ||||||
|           } | 	    } | ||||||
|         } | 	  } | ||||||
|       } |       } | ||||||
|       timer.Stop(); |     timer.Stop(); | ||||||
|        |        | ||||||
|       // performance counting |     // performance counting | ||||||
|       double add,mul,fma; |     double add,mul,fma; | ||||||
|       FFTW<scalar>::fftw_flops(p,&add,&mul,&fma); |     FFTW<scalar>::fftw_flops(p,&add,&mul,&fma); | ||||||
|       flops_call = add+mul+2.0*fma; |     flops_call = add+mul+2.0*fma; | ||||||
|       usec += timer.useconds(); |     usec += timer.useconds(); | ||||||
|       flops+= flops_call*NN; |     flops+= flops_call*NN; | ||||||
|        |        | ||||||
|       // writing out result |     // writing out result | ||||||
|       PARALLEL_REGION |     PARALLEL_REGION | ||||||
|       { |       { | ||||||
|         std::vector<int> clbuf(Nd), cgbuf(Nd); |         std::vector<int> clbuf(Nd), cgbuf(Nd); | ||||||
|         sobj s; |         sobj s; | ||||||
|          |          | ||||||
|         PARALLEL_FOR_LOOP_INTERN |         PARALLEL_FOR_LOOP_INTERN | ||||||
|         for(int idx=0;idx<sgrid->lSites();idx++) { | 	  for(int idx=0;idx<sgrid->lSites();idx++) { | ||||||
|           sgrid->LocalIndexToLocalCoor(idx,clbuf); | 	    sgrid->LocalIndexToLocalCoor(idx,clbuf); | ||||||
|           cgbuf = clbuf; | 	    cgbuf = clbuf; | ||||||
|           cgbuf[dim] = clbuf[dim]+L*pc; | 	    cgbuf[dim] = clbuf[dim]+L*pc; | ||||||
|           peekLocalSite(s,pgbuf,cgbuf); | 	    peekLocalSite(s,pgbuf,cgbuf); | ||||||
|           pokeLocalSite(s,result,clbuf); | 	    pokeLocalSite(s,result,clbuf); | ||||||
|         } | 	  } | ||||||
|       } |       } | ||||||
|       result = result*div; |     result = result*div; | ||||||
|        |        | ||||||
|       // destroying plan |     // destroying plan | ||||||
|       FFTW<scalar>::fftw_destroy_plan(p); |     FFTW<scalar>::fftw_destroy_plan(p); | ||||||
| #endif | #endif | ||||||
|     } |   } | ||||||
|   }; | }; | ||||||
| } |  | ||||||
|  | NAMESPACE_END(Grid); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
|     /************************************************************************************* | /************************************************************************************* | ||||||
|  |  | ||||||
|     Grid physics library, www.github.com/paboyle/Grid  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
|  |  | ||||||
| @@ -24,431 +24,431 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  | ||||||
|     See the full license in the file "LICENSE" in the top level distribution directory |     See the full license in the file "LICENSE" in the top level distribution directory | ||||||
|     *************************************************************************************/ | *************************************************************************************/ | ||||||
|     /*  END LEGAL */ | /*  END LEGAL */ | ||||||
| #ifndef  GRID_ALGORITHM_LINEAR_OP_H | #ifndef  GRID_ALGORITHM_LINEAR_OP_H | ||||||
| #define  GRID_ALGORITHM_LINEAR_OP_H | #define  GRID_ALGORITHM_LINEAR_OP_H | ||||||
|  |  | ||||||
| namespace Grid { | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|   ///////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|   // LinearOperators Take a something and return a something. | // LinearOperators Take a something and return a something. | ||||||
|   ///////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|   // | // | ||||||
|   // Hopefully linearity is satisfied and the AdjOp is indeed the Hermitian conjugateugate (transpose if real): | // Hopefully linearity is satisfied and the AdjOp is indeed the Hermitian conjugateugate (transpose if real): | ||||||
|   //SBase | //SBase | ||||||
|   //   i)  F(a x + b y) = aF(x) + b F(y). | //   i)  F(a x + b y) = aF(x) + b F(y). | ||||||
|   //  ii)  <x|Op|y> = <y|AdjOp|x>^\ast | //  ii)  <x|Op|y> = <y|AdjOp|x>^\ast | ||||||
|   // | // | ||||||
|   // Would be fun to have a test linearity & Herm Conj function! | // Would be fun to have a test linearity & Herm Conj function! | ||||||
|   ///////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|     template<class Field> class LinearOperatorBase { | template<class Field> class LinearOperatorBase { | ||||||
|     public: | public: | ||||||
|  |  | ||||||
|       // Support for coarsening to a multigrid |   // Support for coarsening to a multigrid | ||||||
|       virtual void OpDiag (const Field &in, Field &out) = 0; // Abstract base |   virtual void OpDiag (const Field &in, Field &out) = 0; // Abstract base | ||||||
|       virtual void OpDir  (const Field &in, Field &out,int dir,int disp) = 0; // Abstract base |   virtual void OpDir  (const Field &in, Field &out,int dir,int disp) = 0; // Abstract base | ||||||
|  |  | ||||||
|       virtual void Op     (const Field &in, Field &out) = 0; // Abstract base |   virtual void Op     (const Field &in, Field &out) = 0; // Abstract base | ||||||
|       virtual void AdjOp  (const Field &in, Field &out) = 0; // Abstract base |   virtual void AdjOp  (const Field &in, Field &out) = 0; // Abstract base | ||||||
|       virtual void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2)=0; |   virtual void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2)=0; | ||||||
|       virtual void HermOp(const Field &in, Field &out)=0; |   virtual void HermOp(const Field &in, Field &out)=0; | ||||||
|     }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|   ///////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|   // By sharing the class for Sparse Matrix across multiple operator wrappers, we can share code | // By sharing the class for Sparse Matrix across multiple operator wrappers, we can share code | ||||||
|   // between RB and non-RB variants. Sparse matrix is like the fermion action def, and then | // between RB and non-RB variants. Sparse matrix is like the fermion action def, and then | ||||||
|   // the wrappers implement the specialisation of "Op" and "AdjOp" to the cases minimising | // the wrappers implement the specialisation of "Op" and "AdjOp" to the cases minimising | ||||||
|   // replication of code. | // replication of code. | ||||||
|   // | // | ||||||
|   // I'm not entirely happy with implementation; to share the Schur code between herm and non-herm | // I'm not entirely happy with implementation; to share the Schur code between herm and non-herm | ||||||
|   // while still having a "OpAndNorm" in the abstract base I had to implement it in both cases | // while still having a "OpAndNorm" in the abstract base I had to implement it in both cases | ||||||
|   // with an assert trap in the non-herm. This isn't right; there must be a better C++ way to | // with an assert trap in the non-herm. This isn't right; there must be a better C++ way to | ||||||
|   // do it, but I fear it required multiple inheritance and mixed in abstract base classes | // do it, but I fear it required multiple inheritance and mixed in abstract base classes | ||||||
|   ///////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|     //////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////// | ||||||
|     // Construct herm op from non-herm matrix | // Construct herm op from non-herm matrix | ||||||
|     //////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////// | ||||||
|     template<class Matrix,class Field> | template<class Matrix,class Field> | ||||||
|     class MdagMLinearOperator : public LinearOperatorBase<Field> { | class MdagMLinearOperator : public LinearOperatorBase<Field> { | ||||||
|       Matrix &_Mat; |   Matrix &_Mat; | ||||||
|     public: | public: | ||||||
|     MdagMLinearOperator(Matrix &Mat): _Mat(Mat){}; |   MdagMLinearOperator(Matrix &Mat): _Mat(Mat){}; | ||||||
|  |  | ||||||
|       // Support for coarsening to a multigrid |   // Support for coarsening to a multigrid | ||||||
|       void OpDiag (const Field &in, Field &out) { |   void OpDiag (const Field &in, Field &out) { | ||||||
| 	_Mat.Mdiag(in,out); |     _Mat.Mdiag(in,out); | ||||||
|       } |   } | ||||||
|       void OpDir  (const Field &in, Field &out,int dir,int disp) { |   void OpDir  (const Field &in, Field &out,int dir,int disp) { | ||||||
| 	_Mat.Mdir(in,out,dir,disp); |     _Mat.Mdir(in,out,dir,disp); | ||||||
|       } |   } | ||||||
|       void Op     (const Field &in, Field &out){ |   void Op     (const Field &in, Field &out){ | ||||||
| 	_Mat.M(in,out); |     _Mat.M(in,out); | ||||||
|       } |   } | ||||||
|       void AdjOp     (const Field &in, Field &out){ |   void AdjOp     (const Field &in, Field &out){ | ||||||
| 	_Mat.Mdag(in,out); |     _Mat.Mdag(in,out); | ||||||
|       } |   } | ||||||
|       void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ |   void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ | ||||||
| 	_Mat.MdagM(in,out,n1,n2); |     _Mat.MdagM(in,out,n1,n2); | ||||||
|       } |   } | ||||||
|       void HermOp(const Field &in, Field &out){ |   void HermOp(const Field &in, Field &out){ | ||||||
| 	RealD n1,n2; |     RealD n1,n2; | ||||||
| 	HermOpAndNorm(in,out,n1,n2); |     HermOpAndNorm(in,out,n1,n2); | ||||||
|       } |   } | ||||||
|     }; | }; | ||||||
|  |  | ||||||
|     //////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////// | ||||||
|     // Construct herm op and shift it for mgrid smoother | // Construct herm op and shift it for mgrid smoother | ||||||
|     //////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////// | ||||||
|     template<class Matrix,class Field> | template<class Matrix,class Field> | ||||||
|     class ShiftedMdagMLinearOperator : public LinearOperatorBase<Field> { | class ShiftedMdagMLinearOperator : public LinearOperatorBase<Field> { | ||||||
|       Matrix &_Mat; |   Matrix &_Mat; | ||||||
|       RealD _shift; |   RealD _shift; | ||||||
|     public: | public: | ||||||
|     ShiftedMdagMLinearOperator(Matrix &Mat,RealD shift): _Mat(Mat), _shift(shift){}; |   ShiftedMdagMLinearOperator(Matrix &Mat,RealD shift): _Mat(Mat), _shift(shift){}; | ||||||
|       // Support for coarsening to a multigrid |   // Support for coarsening to a multigrid | ||||||
|       void OpDiag (const Field &in, Field &out) { |   void OpDiag (const Field &in, Field &out) { | ||||||
| 	_Mat.Mdiag(in,out); |     _Mat.Mdiag(in,out); | ||||||
| 	assert(0); |     assert(0); | ||||||
|       } |   } | ||||||
|       void OpDir  (const Field &in, Field &out,int dir,int disp) { |   void OpDir  (const Field &in, Field &out,int dir,int disp) { | ||||||
| 	_Mat.Mdir(in,out,dir,disp); |     _Mat.Mdir(in,out,dir,disp); | ||||||
| 	assert(0); |     assert(0); | ||||||
|       } |   } | ||||||
|       void Op     (const Field &in, Field &out){ |   void Op     (const Field &in, Field &out){ | ||||||
| 	_Mat.M(in,out); |     _Mat.M(in,out); | ||||||
| 	assert(0); |     assert(0); | ||||||
|       } |   } | ||||||
|       void AdjOp     (const Field &in, Field &out){ |   void AdjOp     (const Field &in, Field &out){ | ||||||
| 	_Mat.Mdag(in,out); |     _Mat.Mdag(in,out); | ||||||
| 	assert(0); |     assert(0); | ||||||
|       } |   } | ||||||
|       void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ |   void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ | ||||||
| 	_Mat.MdagM(in,out,n1,n2); |     _Mat.MdagM(in,out,n1,n2); | ||||||
| 	out = out + _shift*in; |     out = out + _shift*in; | ||||||
|  |  | ||||||
| 	ComplexD dot;	 |     ComplexD dot;	 | ||||||
| 	dot= innerProduct(in,out); |     dot= innerProduct(in,out); | ||||||
| 	n1=real(dot); |     n1=real(dot); | ||||||
| 	n2=norm2(out); |     n2=norm2(out); | ||||||
|       } |   } | ||||||
|       void HermOp(const Field &in, Field &out){ |   void HermOp(const Field &in, Field &out){ | ||||||
| 	RealD n1,n2; |     RealD n1,n2; | ||||||
| 	HermOpAndNorm(in,out,n1,n2); |     HermOpAndNorm(in,out,n1,n2); | ||||||
|       } |   } | ||||||
|     }; | }; | ||||||
|  |  | ||||||
|     //////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////// | ||||||
|     // Wrap an already herm matrix | // Wrap an already herm matrix | ||||||
|     //////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////// | ||||||
|     template<class Matrix,class Field> | template<class Matrix,class Field> | ||||||
|     class HermitianLinearOperator : public LinearOperatorBase<Field> { | class HermitianLinearOperator : public LinearOperatorBase<Field> { | ||||||
|       Matrix &_Mat; |   Matrix &_Mat; | ||||||
|     public: | public: | ||||||
|     HermitianLinearOperator(Matrix &Mat): _Mat(Mat){}; |   HermitianLinearOperator(Matrix &Mat): _Mat(Mat){}; | ||||||
|       // Support for coarsening to a multigrid |   // Support for coarsening to a multigrid | ||||||
|       void OpDiag (const Field &in, Field &out) { |   void OpDiag (const Field &in, Field &out) { | ||||||
| 	_Mat.Mdiag(in,out); |     _Mat.Mdiag(in,out); | ||||||
|       } |   } | ||||||
|       void OpDir  (const Field &in, Field &out,int dir,int disp) { |   void OpDir  (const Field &in, Field &out,int dir,int disp) { | ||||||
| 	_Mat.Mdir(in,out,dir,disp); |     _Mat.Mdir(in,out,dir,disp); | ||||||
|       } |   } | ||||||
|       void Op     (const Field &in, Field &out){ |   void Op     (const Field &in, Field &out){ | ||||||
| 	_Mat.M(in,out); |     _Mat.M(in,out); | ||||||
|       } |   } | ||||||
|       void AdjOp     (const Field &in, Field &out){ |   void AdjOp     (const Field &in, Field &out){ | ||||||
| 	_Mat.M(in,out); |     _Mat.M(in,out); | ||||||
|       } |   } | ||||||
|       void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ |   void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ | ||||||
| 	_Mat.M(in,out); |     _Mat.M(in,out); | ||||||
| 	 | 	 | ||||||
| 	ComplexD dot= innerProduct(in,out); n1=real(dot); |     ComplexD dot= innerProduct(in,out); n1=real(dot); | ||||||
| 	n2=norm2(out); |     n2=norm2(out); | ||||||
|       } |   } | ||||||
|       void HermOp(const Field &in, Field &out){ |   void HermOp(const Field &in, Field &out){ | ||||||
| 	_Mat.M(in,out); |     _Mat.M(in,out); | ||||||
|       } |   } | ||||||
|     }; | }; | ||||||
|  |  | ||||||
|     ////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////// | ||||||
|     // Even Odd Schur decomp operators; there are several | // Even Odd Schur decomp operators; there are several | ||||||
|     // ways to introduce the even odd checkerboarding | // ways to introduce the even odd checkerboarding | ||||||
|     ////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|     template<class Field> | template<class Field> | ||||||
|       class SchurOperatorBase :  public LinearOperatorBase<Field> { | class SchurOperatorBase :  public LinearOperatorBase<Field> { | ||||||
|     public: | public: | ||||||
|       virtual  RealD Mpc      (const Field &in, Field &out) =0; |   virtual  RealD Mpc      (const Field &in, Field &out) =0; | ||||||
|       virtual  RealD MpcDag   (const Field &in, Field &out) =0; |   virtual  RealD MpcDag   (const Field &in, Field &out) =0; | ||||||
|       virtual void MpcDagMpc(const Field &in, Field &out,RealD &ni,RealD &no) { |   virtual void MpcDagMpc(const Field &in, Field &out,RealD &ni,RealD &no) { | ||||||
| 	Field tmp(in._grid); |     Field tmp(in._grid); | ||||||
| 	ni=Mpc(in,tmp); |     ni=Mpc(in,tmp); | ||||||
| 	no=MpcDag(tmp,out); |     no=MpcDag(tmp,out); | ||||||
|       } |   } | ||||||
|       virtual void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ |   virtual void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ | ||||||
| 	MpcDagMpc(in,out,n1,n2); |     MpcDagMpc(in,out,n1,n2); | ||||||
|       } |   } | ||||||
|       virtual void HermOp(const Field &in, Field &out){ |   virtual void HermOp(const Field &in, Field &out){ | ||||||
| 	RealD n1,n2; |     RealD n1,n2; | ||||||
| 	HermOpAndNorm(in,out,n1,n2); |     HermOpAndNorm(in,out,n1,n2); | ||||||
|       } |   } | ||||||
|       void Op     (const Field &in, Field &out){ |   void Op     (const Field &in, Field &out){ | ||||||
| 	Mpc(in,out); |     Mpc(in,out); | ||||||
|       } |   } | ||||||
|       void AdjOp     (const Field &in, Field &out){  |   void AdjOp     (const Field &in, Field &out){  | ||||||
| 	MpcDag(in,out); |     MpcDag(in,out); | ||||||
|       } |   } | ||||||
|       // Support for coarsening to a multigrid |   // Support for coarsening to a multigrid | ||||||
|       void OpDiag (const Field &in, Field &out) { |   void OpDiag (const Field &in, Field &out) { | ||||||
| 	assert(0); // must coarsen the unpreconditioned system |     assert(0); // must coarsen the unpreconditioned system | ||||||
|       } |   } | ||||||
|       void OpDir  (const Field &in, Field &out,int dir,int disp) { |   void OpDir  (const Field &in, Field &out,int dir,int disp) { | ||||||
| 	assert(0); |     assert(0); | ||||||
|       } |   } | ||||||
|     }; | }; | ||||||
|     template<class Matrix,class Field> | template<class Matrix,class Field> | ||||||
|       class SchurDiagMooeeOperator :  public SchurOperatorBase<Field> { | class SchurDiagMooeeOperator :  public SchurOperatorBase<Field> { | ||||||
|     protected: | protected: | ||||||
|       Matrix &_Mat; |   Matrix &_Mat; | ||||||
|     public: | public: | ||||||
|       SchurDiagMooeeOperator (Matrix &Mat): _Mat(Mat){}; |   SchurDiagMooeeOperator (Matrix &Mat): _Mat(Mat){}; | ||||||
|       virtual  RealD Mpc      (const Field &in, Field &out) { |   virtual  RealD Mpc      (const Field &in, Field &out) { | ||||||
| 	Field tmp(in._grid); |     Field tmp(in._grid); | ||||||
| //	std::cout <<"grid pointers: in._grid="<< in._grid << " out._grid=" << out._grid << "  _Mat.Grid=" << _Mat.Grid() << " _Mat.RedBlackGrid=" << _Mat.RedBlackGrid() << std::endl; |     //	std::cout <<"grid pointers: in._grid="<< in._grid << " out._grid=" << out._grid << "  _Mat.Grid=" << _Mat.Grid() << " _Mat.RedBlackGrid=" << _Mat.RedBlackGrid() << std::endl; | ||||||
|  |  | ||||||
| 	_Mat.Meooe(in,tmp); |     _Mat.Meooe(in,tmp); | ||||||
| 	_Mat.MooeeInv(tmp,out); |     _Mat.MooeeInv(tmp,out); | ||||||
| 	_Mat.Meooe(out,tmp); |     _Mat.Meooe(out,tmp); | ||||||
|  |  | ||||||
| 	_Mat.Mooee(in,out); |     _Mat.Mooee(in,out); | ||||||
| 	return axpy_norm(out,-1.0,tmp,out); |     return axpy_norm(out,-1.0,tmp,out); | ||||||
|       } |   } | ||||||
|       virtual  RealD MpcDag   (const Field &in, Field &out){ |   virtual  RealD MpcDag   (const Field &in, Field &out){ | ||||||
| 	Field tmp(in._grid); |     Field tmp(in._grid); | ||||||
|  |  | ||||||
| 	_Mat.MeooeDag(in,tmp); |     _Mat.MeooeDag(in,tmp); | ||||||
|         _Mat.MooeeInvDag(tmp,out); |     _Mat.MooeeInvDag(tmp,out); | ||||||
| 	_Mat.MeooeDag(out,tmp); |     _Mat.MeooeDag(out,tmp); | ||||||
|  |  | ||||||
| 	_Mat.MooeeDag(in,out); |     _Mat.MooeeDag(in,out); | ||||||
| 	return axpy_norm(out,-1.0,tmp,out); |     return axpy_norm(out,-1.0,tmp,out); | ||||||
|       } |   } | ||||||
|     }; | }; | ||||||
|     template<class Matrix,class Field> | template<class Matrix,class Field> | ||||||
|       class SchurDiagOneOperator :  public SchurOperatorBase<Field> { | class SchurDiagOneOperator :  public SchurOperatorBase<Field> { | ||||||
|     protected: | protected: | ||||||
|       Matrix &_Mat; |   Matrix &_Mat; | ||||||
|     public: | public: | ||||||
|       SchurDiagOneOperator (Matrix &Mat): _Mat(Mat){}; |   SchurDiagOneOperator (Matrix &Mat): _Mat(Mat){}; | ||||||
|  |  | ||||||
|       virtual  RealD Mpc      (const Field &in, Field &out) { |   virtual  RealD Mpc      (const Field &in, Field &out) { | ||||||
| 	Field tmp(in._grid); |     Field tmp(in._grid); | ||||||
|  |  | ||||||
| 	_Mat.Meooe(in,out); |     _Mat.Meooe(in,out); | ||||||
| 	_Mat.MooeeInv(out,tmp); |     _Mat.MooeeInv(out,tmp); | ||||||
| 	_Mat.Meooe(tmp,out); |     _Mat.Meooe(tmp,out); | ||||||
| 	_Mat.MooeeInv(out,tmp); |     _Mat.MooeeInv(out,tmp); | ||||||
|  |  | ||||||
| 	return axpy_norm(out,-1.0,tmp,in); |     return axpy_norm(out,-1.0,tmp,in); | ||||||
|       } |   } | ||||||
|       virtual  RealD MpcDag   (const Field &in, Field &out){ |   virtual  RealD MpcDag   (const Field &in, Field &out){ | ||||||
| 	Field tmp(in._grid); |     Field tmp(in._grid); | ||||||
|  |  | ||||||
| 	_Mat.MooeeInvDag(in,out); |     _Mat.MooeeInvDag(in,out); | ||||||
| 	_Mat.MeooeDag(out,tmp); |     _Mat.MeooeDag(out,tmp); | ||||||
| 	_Mat.MooeeInvDag(tmp,out); |     _Mat.MooeeInvDag(tmp,out); | ||||||
| 	_Mat.MeooeDag(out,tmp); |     _Mat.MeooeDag(out,tmp); | ||||||
|  |  | ||||||
| 	return axpy_norm(out,-1.0,tmp,in); |     return axpy_norm(out,-1.0,tmp,in); | ||||||
|       } |   } | ||||||
|     }; | }; | ||||||
|     template<class Matrix,class Field> | template<class Matrix,class Field> | ||||||
|       class SchurDiagTwoOperator :  public SchurOperatorBase<Field> { | class SchurDiagTwoOperator :  public SchurOperatorBase<Field> { | ||||||
|     protected: | protected: | ||||||
|       Matrix &_Mat; |   Matrix &_Mat; | ||||||
|     public: | public: | ||||||
|       SchurDiagTwoOperator (Matrix &Mat): _Mat(Mat){}; |   SchurDiagTwoOperator (Matrix &Mat): _Mat(Mat){}; | ||||||
|  |  | ||||||
|       virtual  RealD Mpc      (const Field &in, Field &out) { |   virtual  RealD Mpc      (const Field &in, Field &out) { | ||||||
| 	Field tmp(in._grid); |     Field tmp(in._grid); | ||||||
|  |  | ||||||
| 	_Mat.MooeeInv(in,out); |     _Mat.MooeeInv(in,out); | ||||||
| 	_Mat.Meooe(out,tmp); |     _Mat.Meooe(out,tmp); | ||||||
| 	_Mat.MooeeInv(tmp,out); |     _Mat.MooeeInv(tmp,out); | ||||||
| 	_Mat.Meooe(out,tmp); |     _Mat.Meooe(out,tmp); | ||||||
|  |  | ||||||
| 	return axpy_norm(out,-1.0,tmp,in); |     return axpy_norm(out,-1.0,tmp,in); | ||||||
|       } |   } | ||||||
|       virtual  RealD MpcDag   (const Field &in, Field &out){ |   virtual  RealD MpcDag   (const Field &in, Field &out){ | ||||||
| 	Field tmp(in._grid); |     Field tmp(in._grid); | ||||||
|  |  | ||||||
| 	_Mat.MeooeDag(in,out); |     _Mat.MeooeDag(in,out); | ||||||
| 	_Mat.MooeeInvDag(out,tmp); |     _Mat.MooeeInvDag(out,tmp); | ||||||
| 	_Mat.MeooeDag(tmp,out); |     _Mat.MeooeDag(tmp,out); | ||||||
| 	_Mat.MooeeInvDag(out,tmp); |     _Mat.MooeeInvDag(out,tmp); | ||||||
|  |  | ||||||
| 	return axpy_norm(out,-1.0,tmp,in); |     return axpy_norm(out,-1.0,tmp,in); | ||||||
|       } |   } | ||||||
|     }; | }; | ||||||
|     /////////////////////////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|     // Left  handed Moo^-1 ; (Moo - Moe Mee^-1 Meo) psi = eta  -->  ( 1 - Moo^-1 Moe Mee^-1 Meo ) psi = Moo^-1 eta | // Left  handed Moo^-1 ; (Moo - Moe Mee^-1 Meo) psi = eta  -->  ( 1 - Moo^-1 Moe Mee^-1 Meo ) psi = Moo^-1 eta | ||||||
|     // Right handed Moo^-1 ; (Moo - Moe Mee^-1 Meo) Moo^-1 Moo psi = eta  -->  ( 1 - Moe Mee^-1 Meo ) Moo^-1 phi=eta ; psi = Moo^-1 phi | // Right handed Moo^-1 ; (Moo - Moe Mee^-1 Meo) Moo^-1 Moo psi = eta  -->  ( 1 - Moe Mee^-1 Meo ) Moo^-1 phi=eta ; psi = Moo^-1 phi | ||||||
|     /////////////////////////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|     template<class Matrix,class Field> using SchurDiagOneRH = SchurDiagTwoOperator<Matrix,Field> ; | template<class Matrix,class Field> using SchurDiagOneRH = SchurDiagTwoOperator<Matrix,Field> ; | ||||||
|     template<class Matrix,class Field> using SchurDiagOneLH = SchurDiagOneOperator<Matrix,Field> ; | template<class Matrix,class Field> using SchurDiagOneLH = SchurDiagOneOperator<Matrix,Field> ; | ||||||
|     /////////////////////////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|     //  Staggered use | //  Staggered use | ||||||
|     /////////////////////////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|     template<class Matrix,class Field> | template<class Matrix,class Field> | ||||||
|       class SchurStaggeredOperator :  public SchurOperatorBase<Field> { | class SchurStaggeredOperator :  public SchurOperatorBase<Field> { | ||||||
|     protected: | protected: | ||||||
|       Matrix &_Mat; |   Matrix &_Mat; | ||||||
|     public: | public: | ||||||
|       SchurStaggeredOperator (Matrix &Mat): _Mat(Mat){}; |   SchurStaggeredOperator (Matrix &Mat): _Mat(Mat){}; | ||||||
|       virtual void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ |   virtual void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ | ||||||
| 	GridLogIterative.TimingMode(1); |     GridLogIterative.TimingMode(1); | ||||||
| 	std::cout << GridLogIterative << " HermOpAndNorm "<<std::endl; |     std::cout << GridLogIterative << " HermOpAndNorm "<<std::endl; | ||||||
| 	n2 = Mpc(in,out); |     n2 = Mpc(in,out); | ||||||
| 	std::cout << GridLogIterative << " HermOpAndNorm.Mpc "<<std::endl; |     std::cout << GridLogIterative << " HermOpAndNorm.Mpc "<<std::endl; | ||||||
| 	ComplexD dot= innerProduct(in,out); |     ComplexD dot= innerProduct(in,out); | ||||||
| 	std::cout << GridLogIterative << " HermOpAndNorm.innerProduct "<<std::endl; |     std::cout << GridLogIterative << " HermOpAndNorm.innerProduct "<<std::endl; | ||||||
| 	n1 = real(dot); |     n1 = real(dot); | ||||||
|       } |   } | ||||||
|       virtual void HermOp(const Field &in, Field &out){ |   virtual void HermOp(const Field &in, Field &out){ | ||||||
| 	std::cout << GridLogIterative << " HermOp "<<std::endl; |     std::cout << GridLogIterative << " HermOp "<<std::endl; | ||||||
| 	Mpc(in,out); |     Mpc(in,out); | ||||||
|       } |   } | ||||||
|       virtual  RealD Mpc      (const Field &in, Field &out) { |   virtual  RealD Mpc      (const Field &in, Field &out) { | ||||||
| 	Field tmp(in._grid); |     Field tmp(in._grid); | ||||||
| 	Field tmp2(in._grid); |     Field tmp2(in._grid); | ||||||
|  |  | ||||||
| 	std::cout << GridLogIterative << " HermOp.Mpc "<<std::endl; |     std::cout << GridLogIterative << " HermOp.Mpc "<<std::endl; | ||||||
| 	_Mat.Mooee(in,out); |     _Mat.Mooee(in,out); | ||||||
| 	_Mat.Mooee(out,tmp); |     _Mat.Mooee(out,tmp); | ||||||
| 	std::cout << GridLogIterative << " HermOp.MooeeMooee "<<std::endl; |     std::cout << GridLogIterative << " HermOp.MooeeMooee "<<std::endl; | ||||||
|  |  | ||||||
| 	_Mat.Meooe(in,out); |     _Mat.Meooe(in,out); | ||||||
| 	_Mat.Meooe(out,tmp2); |     _Mat.Meooe(out,tmp2); | ||||||
| 	std::cout << GridLogIterative << " HermOp.MeooeMeooe "<<std::endl; |     std::cout << GridLogIterative << " HermOp.MeooeMeooe "<<std::endl; | ||||||
|  |  | ||||||
| 	RealD nn=axpy_norm(out,-1.0,tmp2,tmp); |     RealD nn=axpy_norm(out,-1.0,tmp2,tmp); | ||||||
| 	std::cout << GridLogIterative << " HermOp.axpy_norm "<<std::endl; |     std::cout << GridLogIterative << " HermOp.axpy_norm "<<std::endl; | ||||||
| 	return nn; |     return nn; | ||||||
|       } |   } | ||||||
|       virtual  RealD MpcDag   (const Field &in, Field &out){ |   virtual  RealD MpcDag   (const Field &in, Field &out){ | ||||||
| 	return Mpc(in,out); |     return Mpc(in,out); | ||||||
|       } |   } | ||||||
|       virtual void MpcDagMpc(const Field &in, Field &out,RealD &ni,RealD &no) { |   virtual void MpcDagMpc(const Field &in, Field &out,RealD &ni,RealD &no) { | ||||||
| 	assert(0);// Never need with staggered |     assert(0);// Never need with staggered | ||||||
|       } |   } | ||||||
|     }; | }; | ||||||
|     template<class Matrix,class Field> using SchurStagOperator = SchurStaggeredOperator<Matrix,Field>; | template<class Matrix,class Field> using SchurStagOperator = SchurStaggeredOperator<Matrix,Field>; | ||||||
|  |  | ||||||
|  |  | ||||||
|     ///////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////// | ||||||
|     // Base classes for functions of operators | // Base classes for functions of operators | ||||||
|     ///////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////// | ||||||
|     template<class Field> class OperatorFunction { | template<class Field> class OperatorFunction { | ||||||
|     public: | public: | ||||||
|       virtual void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) = 0; |   virtual void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) = 0; | ||||||
|     }; | }; | ||||||
|  |  | ||||||
|     template<class Field> class LinearFunction { | template<class Field> class LinearFunction { | ||||||
|     public: | public: | ||||||
|       virtual void operator() (const Field &in, Field &out) = 0; |   virtual void operator() (const Field &in, Field &out) = 0; | ||||||
|     }; | }; | ||||||
|  |  | ||||||
|     template<class Field> class IdentityLinearFunction : public LinearFunction<Field> { | template<class Field> class IdentityLinearFunction : public LinearFunction<Field> { | ||||||
|     public: | public: | ||||||
|       void operator() (const Field &in, Field &out){ |   void operator() (const Field &in, Field &out){ | ||||||
| 	out = in; |     out = in; | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     ///////////////////////////////////////////////////////////// |  | ||||||
|     // Base classes for Multishift solvers for operators |  | ||||||
|     ///////////////////////////////////////////////////////////// |  | ||||||
|     template<class Field> class OperatorMultiFunction { |  | ||||||
|     public: |  | ||||||
|       virtual void operator() (LinearOperatorBase<Field> &Linop, const Field &in, std::vector<Field> &out) = 0; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     // FIXME : To think about |  | ||||||
|  |  | ||||||
|     // Chroma functionality list defining LinearOperator |  | ||||||
|     /* |  | ||||||
|      virtual void operator() (T& chi, const T& psi, enum PlusMinus isign) const = 0; |  | ||||||
|      virtual void operator() (T& chi, const T& psi, enum PlusMinus isign, Real epsilon) const |  | ||||||
|      virtual const Subset& subset() const = 0; |  | ||||||
|      virtual unsigned long nFlops() const { return 0; } |  | ||||||
|      virtual void deriv(P& ds_u, const T& chi, const T& psi, enum PlusMinus isign) const |  | ||||||
|      class UnprecLinearOperator : public DiffLinearOperator<T,P,Q> |  | ||||||
|        const Subset& subset() const {return all;} |  | ||||||
|      }; |  | ||||||
|     */ |  | ||||||
|  |  | ||||||
|   //////////////////////////////////////////////////////////////////////////////////////////// |  | ||||||
|   // Hermitian operator Linear function and operator function |  | ||||||
|   //////////////////////////////////////////////////////////////////////////////////////////// |  | ||||||
|     template<class Field> |  | ||||||
|       class HermOpOperatorFunction : public OperatorFunction<Field> { |  | ||||||
|       void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) { |  | ||||||
| 	Linop.HermOp(in,out); |  | ||||||
|       }; |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     template<typename Field> |  | ||||||
|       class PlainHermOp : public LinearFunction<Field> { |  | ||||||
|     public: |  | ||||||
|       LinearOperatorBase<Field> &_Linop; |  | ||||||
|        |  | ||||||
|       PlainHermOp(LinearOperatorBase<Field>& linop) : _Linop(linop)  |  | ||||||
|       {} |  | ||||||
|        |  | ||||||
|       void operator()(const Field& in, Field& out) { |  | ||||||
| 	_Linop.HermOp(in,out); |  | ||||||
|       } |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     template<typename Field> |  | ||||||
|     class FunctionHermOp : public LinearFunction<Field> { |  | ||||||
|     public: |  | ||||||
|       OperatorFunction<Field>   & _poly; |  | ||||||
|       LinearOperatorBase<Field> &_Linop; |  | ||||||
|        |  | ||||||
|       FunctionHermOp(OperatorFunction<Field> & poly,LinearOperatorBase<Field>& linop)  |  | ||||||
| 	: _poly(poly), _Linop(linop) {}; |  | ||||||
|        |  | ||||||
|       void operator()(const Field& in, Field& out) { |  | ||||||
| 	_poly(_Linop,in,out); |  | ||||||
|       } |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|   template<class Field> |  | ||||||
|   class Polynomial : public OperatorFunction<Field> { |  | ||||||
|   private: |  | ||||||
|     std::vector<RealD> Coeffs; |  | ||||||
|   public: |  | ||||||
|     Polynomial(std::vector<RealD> &_Coeffs) : Coeffs(_Coeffs) { }; |  | ||||||
|  |  | ||||||
|     // Implement the required interface |  | ||||||
|     void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) { |  | ||||||
|  |  | ||||||
|       Field AtoN(in._grid); |  | ||||||
|       Field Mtmp(in._grid); |  | ||||||
|       AtoN = in; |  | ||||||
|       out = AtoN*Coeffs[0]; |  | ||||||
|       for(int n=1;n<Coeffs.size();n++){ |  | ||||||
| 	Mtmp = AtoN; |  | ||||||
| 	Linop.HermOp(Mtmp,AtoN); |  | ||||||
| 	out=out+AtoN*Coeffs[n]; |  | ||||||
|       } |  | ||||||
|     }; |  | ||||||
|   }; |   }; | ||||||
|  | }; | ||||||
|  |  | ||||||
| } |  | ||||||
|  | ///////////////////////////////////////////////////////////// | ||||||
|  | // Base classes for Multishift solvers for operators | ||||||
|  | ///////////////////////////////////////////////////////////// | ||||||
|  | template<class Field> class OperatorMultiFunction { | ||||||
|  | public: | ||||||
|  |   virtual void operator() (LinearOperatorBase<Field> &Linop, const Field &in, std::vector<Field> &out) = 0; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | // FIXME : To think about | ||||||
|  |  | ||||||
|  | // Chroma functionality list defining LinearOperator | ||||||
|  | /* | ||||||
|  |   virtual void operator() (T& chi, const T& psi, enum PlusMinus isign) const = 0; | ||||||
|  |   virtual void operator() (T& chi, const T& psi, enum PlusMinus isign, Real epsilon) const | ||||||
|  |   virtual const Subset& subset() const = 0; | ||||||
|  |   virtual unsigned long nFlops() const { return 0; } | ||||||
|  |   virtual void deriv(P& ds_u, const T& chi, const T& psi, enum PlusMinus isign) const | ||||||
|  |   class UnprecLinearOperator : public DiffLinearOperator<T,P,Q> | ||||||
|  |   const Subset& subset() const {return all;} | ||||||
|  |   }; | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | //////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Hermitian operator Linear function and operator function | ||||||
|  | //////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  | template<class Field> | ||||||
|  | class HermOpOperatorFunction : public OperatorFunction<Field> { | ||||||
|  |   void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) { | ||||||
|  |     Linop.HermOp(in,out); | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template<typename Field> | ||||||
|  | class PlainHermOp : public LinearFunction<Field> { | ||||||
|  | public: | ||||||
|  |   LinearOperatorBase<Field> &_Linop; | ||||||
|  |        | ||||||
|  |   PlainHermOp(LinearOperatorBase<Field>& linop) : _Linop(linop)  | ||||||
|  |   {} | ||||||
|  |        | ||||||
|  |   void operator()(const Field& in, Field& out) { | ||||||
|  |     _Linop.HermOp(in,out); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template<typename Field> | ||||||
|  | class FunctionHermOp : public LinearFunction<Field> { | ||||||
|  | public: | ||||||
|  |   OperatorFunction<Field>   & _poly; | ||||||
|  |   LinearOperatorBase<Field> &_Linop; | ||||||
|  |        | ||||||
|  |   FunctionHermOp(OperatorFunction<Field> & poly,LinearOperatorBase<Field>& linop)  | ||||||
|  |     : _poly(poly), _Linop(linop) {}; | ||||||
|  |        | ||||||
|  |   void operator()(const Field& in, Field& out) { | ||||||
|  |     _poly(_Linop,in,out); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template<class Field> | ||||||
|  | class Polynomial : public OperatorFunction<Field> { | ||||||
|  | private: | ||||||
|  |   std::vector<RealD> Coeffs; | ||||||
|  | public: | ||||||
|  |   Polynomial(std::vector<RealD> &_Coeffs) : Coeffs(_Coeffs) { }; | ||||||
|  |  | ||||||
|  |   // Implement the required interface | ||||||
|  |   void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) { | ||||||
|  |  | ||||||
|  |     Field AtoN(in._grid); | ||||||
|  |     Field Mtmp(in._grid); | ||||||
|  |     AtoN = in; | ||||||
|  |     out = AtoN*Coeffs[0]; | ||||||
|  |     for(int n=1;n<Coeffs.size();n++){ | ||||||
|  |       Mtmp = AtoN; | ||||||
|  |       Linop.HermOp(Mtmp,AtoN); | ||||||
|  |       out=out+AtoN*Coeffs[n]; | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | NAMESPACE_END(Grid); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
|     /************************************************************************************* | /************************************************************************************* | ||||||
|  |  | ||||||
|     Grid physics library, www.github.com/paboyle/Grid  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
|  |  | ||||||
| @@ -23,24 +23,24 @@ Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk> | |||||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  | ||||||
|     See the full license in the file "LICENSE" in the top level distribution directory |     See the full license in the file "LICENSE" in the top level distribution directory | ||||||
|     *************************************************************************************/ | *************************************************************************************/ | ||||||
|     /*  END LEGAL */ | /*  END LEGAL */ | ||||||
| #ifndef GRID_PRECONDITIONER_H | #ifndef GRID_PRECONDITIONER_H | ||||||
| #define GRID_PRECONDITIONER_H | #define GRID_PRECONDITIONER_H | ||||||
|  |  | ||||||
| namespace Grid { | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|   template<class Field> class Preconditioner :  public LinearFunction<Field> {  | template<class Field> class Preconditioner :  public LinearFunction<Field> {  | ||||||
|     virtual void operator()(const Field &src, Field & psi)=0; |   virtual void operator()(const Field &src, Field & psi)=0; | ||||||
|   }; | }; | ||||||
|  |  | ||||||
|   template<class Field> class TrivialPrecon :  public Preconditioner<Field> {  | template<class Field> class TrivialPrecon :  public Preconditioner<Field> {  | ||||||
|   public: | public: | ||||||
|     void operator()(const Field &src, Field & psi){ |   void operator()(const Field &src, Field & psi){ | ||||||
|       psi = src; |     psi = src; | ||||||
|     } |   } | ||||||
|     TrivialPrecon(void){}; |   TrivialPrecon(void){}; | ||||||
|   }; | }; | ||||||
|  |  | ||||||
| } | NAMESPACE_END(Grid); | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
|     /************************************************************************************* | /************************************************************************************* | ||||||
|  |  | ||||||
|     Grid physics library, www.github.com/paboyle/Grid  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
|  |  | ||||||
| @@ -23,49 +23,49 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  | ||||||
|     See the full license in the file "LICENSE" in the top level distribution directory |     See the full license in the file "LICENSE" in the top level distribution directory | ||||||
|     *************************************************************************************/ | *************************************************************************************/ | ||||||
|     /*  END LEGAL */ | /*  END LEGAL */ | ||||||
| #ifndef  GRID_ALGORITHM_SPARSE_MATRIX_H | #ifndef  GRID_ALGORITHM_SPARSE_MATRIX_H | ||||||
| #define  GRID_ALGORITHM_SPARSE_MATRIX_H | #define  GRID_ALGORITHM_SPARSE_MATRIX_H | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace Grid { | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|   ///////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|   // Interface defining what I expect of a general sparse matrix, such as a Fermion action | // Interface defining what I expect of a general sparse matrix, such as a Fermion action | ||||||
|   ///////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|     template<class Field> class SparseMatrixBase { | template<class Field> class SparseMatrixBase { | ||||||
|     public: | public: | ||||||
|       virtual GridBase *Grid(void) =0; |   virtual GridBase *Grid(void) =0; | ||||||
|       // Full checkerboar operations |   // Full checkerboar operations | ||||||
|       virtual RealD M    (const Field &in, Field &out)=0; |   virtual RealD M    (const Field &in, Field &out)=0; | ||||||
|       virtual RealD Mdag (const Field &in, Field &out)=0; |   virtual RealD Mdag (const Field &in, Field &out)=0; | ||||||
|       virtual void  MdagM(const Field &in, Field &out,RealD &ni,RealD &no) { |   virtual void  MdagM(const Field &in, Field &out,RealD &ni,RealD &no) { | ||||||
| 	Field tmp (in._grid); |     Field tmp (in._grid); | ||||||
| 	ni=M(in,tmp); |     ni=M(in,tmp); | ||||||
| 	no=Mdag(tmp,out); |     no=Mdag(tmp,out); | ||||||
|       } |   } | ||||||
|       virtual  void Mdiag    (const Field &in, Field &out)=0; |   virtual  void Mdiag    (const Field &in, Field &out)=0; | ||||||
|       virtual  void Mdir     (const Field &in, Field &out,int dir, int disp)=0; |   virtual  void Mdir     (const Field &in, Field &out,int dir, int disp)=0; | ||||||
|     }; | }; | ||||||
|  |  | ||||||
|   ///////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|   // Interface augmented by a red black sparse matrix, such as a Fermion action | // Interface augmented by a red black sparse matrix, such as a Fermion action | ||||||
|   ///////////////////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|     template<class Field> class CheckerBoardedSparseMatrixBase : public SparseMatrixBase<Field> { | template<class Field> class CheckerBoardedSparseMatrixBase : public SparseMatrixBase<Field> { | ||||||
|     public: | public: | ||||||
|       virtual GridBase *RedBlackGrid(void)=0; |   virtual GridBase *RedBlackGrid(void)=0; | ||||||
|       // half checkerboard operaions |   // half checkerboard operaions | ||||||
|       virtual  void Meooe    (const Field &in, Field &out)=0; |   virtual  void Meooe    (const Field &in, Field &out)=0; | ||||||
|       virtual  void Mooee    (const Field &in, Field &out)=0; |   virtual  void Mooee    (const Field &in, Field &out)=0; | ||||||
|       virtual  void MooeeInv (const Field &in, Field &out)=0; |   virtual  void MooeeInv (const Field &in, Field &out)=0; | ||||||
|  |  | ||||||
|       virtual  void MeooeDag    (const Field &in, Field &out)=0; |   virtual  void MeooeDag    (const Field &in, Field &out)=0; | ||||||
|       virtual  void MooeeDag    (const Field &in, Field &out)=0; |   virtual  void MooeeDag    (const Field &in, Field &out)=0; | ||||||
|       virtual  void MooeeInvDag (const Field &in, Field &out)=0; |   virtual  void MooeeInvDag (const Field &in, Field &out)=0; | ||||||
|  |  | ||||||
|     }; | }; | ||||||
|  |  | ||||||
| } | NAMESPACE_END(Grid); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user