#ifndef GRID_ALGORITHM_COARSENED_MATRIX_H #define GRID_ALGORITHM_COARSENED_MATRIX_H #include namespace Grid { class Geometry { // int dimension; public: int npoint; std::vector directions ; std::vector displacements; std::vector opdirs; // FIXME -- don't like xposing the operator directions // as different to the geometrical dirs // Also don't like special casing five dim.. should pass an object in template Geometry(int _d) { int base = (_d==5) ? 1:0; // make coarse grid stencil for 4d , not 5d if ( _d==5 ) _d=4; npoint = 2*_d+1; directions.resize(npoint); displacements.resize(npoint); opdirs.resize(npoint); for(int d=0;d<_d;d++){ directions[2*d ] = d+base; directions[2*d+1] = d+base; opdirs[2*d ] = d; opdirs[2*d+1] = d; displacements[2*d ] = +1; displacements[2*d+1] = -1; } directions [2*_d]=0; displacements[2*_d]=0; opdirs [2*_d]=0; } /* // Original cleaner code Geometry(int _d) : dimension(_d), npoint(2*_d+1), directions(npoint), displacements(npoint) { for(int d=0;d GetDelta(int point) { std::vector delta(dimension,0); delta[directions[point]] = displacements[point]; return delta; }; */ }; // Fine Object == (per site) type of fine field // nbasis == number of deflation vectors template class CoarsenedMatrix : public SparseMatrixBase > > { public: typedef iVector siteVector; typedef Lattice > CoarseVector; typedef Lattice > CoarseMatrix; typedef Lattice< CComplex > CoarseScalar; // used for inner products on fine field typedef Lattice FineField; //////////////////// // Data members //////////////////// Geometry geom; GridBase * _grid; CartesianStencil Stencil; std::vector A; std::vector Aslow; std::vector > comm_buf; /////////////////////// // Interface /////////////////////// GridBase * Grid(void) { return _grid; }; // this is all the linalg routines need to know RealD M (const CoarseVector &in, CoarseVector &out){ SimpleCompressor compressor; Stencil.HaloExchange(in,comm_buf,compressor); PARALLEL_FOR_LOOP for(int ss=0;ssoSites();ss++){ siteVector res = zero; siteVector tmp; siteVector nbr; int offset,local,perm; for(int point=0;point > &linop,std::vector > & 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 > coor(FineGrid); CoarseVector iProj(Grid()); CoarseVector oProj(Grid()); CoarseScalar InnerProd(Grid()); // Orthogonalise the subblocks over the basis blockOrthogonalise(InnerProd,subspace); blockProject(iProj,subspace[0],subspace); // Compute the matrix elements of linop between this orthonormal // set of vectors. int self_stencil=-1; for(int p=0;p_rdimensions[dir])/(Grid()->_rdimensions[dir]); LatticeCoordinate(coor,dir); if ( disp==0 ){ linop.OpDiag(phi,Mphi); } else { linop.OpDir(phi,Mphi,opdir,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)==0,Mphi,zz); iblock = where(mod(coor,block)!=0,Mphi,zz); } else { assert(0); } blockProject(iProj,iblock,subspace); blockProject(oProj,oblock,subspace); for(int ss=0;ssoSites();ss++){ for(int j=0;j bc(FineGrid->_ndimension,0); blockPick(Grid(),phi,tmp,bc); // Pick out a block linop.Op(tmp,Mphi); // Apply big dop blockProject(iProj,Mphi,subspace); // project it and print it std::cout<< " Computed matrix elements from block zero only "<