namespace Grid { /* BlockProjector If _HP_BLOCK_PROJECTORS_ is defined, we assume that _evec is a basis that is not fully orthonormalized (to the precision of the coarse field) and we allow for higher-precision coarse field than basis field. */ //#define _HP_BLOCK_PROJECTORS_ template class BlockProjector { public: BasisFieldVector& _evec; BlockedGrid& _bgrid; BlockProjector(BasisFieldVector& evec, BlockedGrid& bgrid) : _evec(evec), _bgrid(bgrid) { } void createOrthonormalBasis(RealD thres = 0.0) { GridStopWatch sw; sw.Start(); int cnt = 0; #pragma omp parallel shared(cnt) { int lcnt = 0; #pragma omp for for (int b=0;b<_bgrid._o_blocks;b++) { for (int i=0;i<_evec._Nm;i++) { auto nrm0 = _bgrid.block_sp(b,_evec._v[i],_evec._v[i]); // |i> -= |j> for (int j=0;j void coarseToFine(const CoarseField& in, Field& out) { out = Zero(); out.Checkerboard() = _evec._v[0].Checkerboard(); int Nbasis = sizeof(in[0]._internal._internal) / sizeof(in[0]._internal._internal[0]); assert(Nbasis == _evec._Nm); #pragma omp parallel for for (int b=0;b<_bgrid._o_blocks;b++) { for (int j=0;j<_evec._Nm;j++) { _bgrid.block_caxpy(b,out,in[b]._internal._internal[j],_evec._v[j],out); } } } template void fineToCoarse(const Field& in, CoarseField& out) { out = Zero(); int Nbasis = sizeof(out[0]._internal._internal) / sizeof(out[0]._internal._internal[0]); assert(Nbasis == _evec._Nm); Field tmp(_bgrid.Grid()); tmp = in; #pragma omp parallel for for (int b=0;b<_bgrid._o_blocks;b++) { for (int j=0;j<_evec._Nm;j++) { // |rhs> -= |j> auto c = _bgrid.block_sp(b,_evec._v[j],tmp); _bgrid.block_caxpy(b,tmp,-c,_evec._v[j],tmp); // may make this more numerically stable out[b]._internal._internal[j] = c; } } } template void deflateFine(BasisFieldVector& _coef,const std::vector& eval,int N,const Field& src_orig,Field& result) { result = Zero(); for (int i=0;i void deflateCoarse(BasisFieldVector& _coef,const std::vector& eval,int N,const Field& src_orig,Field& result) { CoarseField src_coarse(_coef._v[0].Grid()); CoarseField result_coarse = src_coarse; result_coarse = Zero(); fineToCoarse(src_orig,src_coarse); for (int i=0;i void deflate(BasisFieldVector& _coef,const std::vector& eval,int N,const Field& src_orig,Field& result) { // Deflation on coarse Grid is much faster, so use it by default. Deflation on fine Grid is kept for legacy reasons for now. deflateCoarse(_coef,eval,N,src_orig,result); } }; }