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._odata[0]._internal._internal) / sizeof(in._odata[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._odata[b]._internal._internal[j],_evec._v[j],out); } } } template void fineToCoarse(const Field& in, CoarseField& out) { out = zero; int Nbasis = sizeof(out._odata[0]._internal._internal) / sizeof(out._odata[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._odata[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); } }; }