diff --git a/Grid/algorithms/iterative/AdefGeneric.h b/Grid/algorithms/iterative/AdefGeneric.h index 4344dfa7..b63db1ba 100644 --- a/Grid/algorithms/iterative/AdefGeneric.h +++ b/Grid/algorithms/iterative/AdefGeneric.h @@ -69,279 +69,339 @@ class TwoLevelCG : public LinearFunction virtual void operator() (const Field &src, Field &x) { -#if 0 - Field resid(grid); + std::cout << GridLogMessage<<"HDCG: fPcg starting"< p(mmax,grid); + std::vector mmp(mmax,grid); + std::vector pAp(mmax); Field z(grid); Field tmp(grid); - Field mmp(grid); - Field r (grid); - Field mu (grid); - Field rp (grid); + Field mp (grid); + Field r (grid); + Field mu (grid); + std::cout << GridLogMessage<<"HDCG: fPcg allocated"< z + b p + b = (rtzp)/rtz; + + int northog; + // k=zero <=> peri_kp=1; northog = 1 + // k=1 <=> peri_kp=2; northog = 2 + // ... ... ... + // k=mmax-2<=> peri_kp=mmax-1; northog = mmax-1 + // k=mmax-1<=> peri_kp=0; northog = 1 + + // northog = (peri_kp==0)?1:peri_kp; // This is the fCG(mmax) algorithm + northog = (k>mmax-1)?(mmax-1):k; // This is the fCG-Tr(mmax-1) algorithm + + std::cout< p(mmax,grid); - std::vector mmp(mmax,grid); - std::vector pAp(mmax); - Field z(grid); - Field tmp(grid); - Field mp (grid); - Field r (grid); - Field mu (grid); - - //Initial residual computation & set up - RealD guess = norm2(x); - RealD src_nrm = norm2(src); - - if ( src_nrm == 0.0 ) { - std::cout << GridLogMessage<<"HDCG: fPcg given trivial source norm "< z + b p ; b = - b = (rtzp)/rtz; - - int northog; - // k=zero <=> peri_kp=1; northog = 1 - // k=1 <=> peri_kp=2; northog = 2 - // ... ... ... - // k=mmax-2<=> peri_kp=mmax-1; northog = mmax-1 - // k=mmax-1<=> peri_kp=0; northog = 1 - - // northog = (peri_kp==0)?1:peri_kp; // This is the fCG(mmax) algorithm - northog = (k>mmax-1)?(mmax-1):k; // This is the fCG-Tr(mmax-1) algorithm - - std::cout< &src, std::vector &x) + { + std::cout << GridLogMessage<<"HDCG: mrhs fPcg starting"<Barrier(); + int nrhs = src.size(); + std::vector f(nrhs); + std::vector rtzp(nrhs); + std::vector rtz(nrhs); + std::vector a(nrhs); + std::vector d(nrhs); + std::vector b(nrhs); + std::vector rptzp(nrhs); + ///////////////////////////// + // Set up history vectors + ///////////////////////////// + int mmax = 2; + std::cout << GridLogMessage<<"HDCG: fPcg allocating"<Barrier(); + std::vector > p(nrhs); for(int r=0;rBarrier(); + std::vector > mmp(nrhs); for(int r=0;rBarrier(); + std::vector > pAp(nrhs); for(int r=0;rBarrier(); + std::vector z(nrhs,grid); + std::vector mp (nrhs,grid); + std::vector r (nrhs,grid); + std::vector mu (nrhs,grid); + std::cout << GridLogMessage<<"HDCG: fPcg allocated z,mp,r,mu"<Barrier(); + + //Initial residual computation & set up + std::vector src_nrm(nrhs); + for(int rhs=0;rhs tn(nrhs); + + GridStopWatch HDCGTimer; + HDCGTimer.Start(); + ////////////////////////// + // x0 = Vstart -- possibly modify guess + ////////////////////////// + for(int rhs=0;rhs ssq(nrhs); + std::vector rsq(nrhs); + std::vector pp(nrhs,grid); + + for(int rhs=0;rhs rn(nrhs); + for (int k=0;k<=MaxIterations;k++){ + + int peri_k = k % mmax; + int peri_kp = (k+1) % mmax; + + for(int rhs=0;rhsmmax-1)?(mmax-1):k; // This is the fCG-Tr(mmax-1) algorithm + std::cout< max_rn ) max_rn = rrn; + } + + // Stopping condition based on worst case + if ( max_rn <= Tolerance ) { + + HDCGTimer.Stop(); + std::cout< & in,std::vector & out) + { + std::cout << "PcgM1 default (cheat) mrhs versoin"<PcgM1(in[rhs],out[rhs]); + } + } virtual void PcgM1(Field & in, Field & out) =0; virtual void Vstart(Field & x,const Field & src)=0; @@ -440,6 +500,7 @@ class TwoLevelADEF2 : public TwoLevelCG virtual void Vstart(Field & x,const Field & src) { + std::cout << GridLogMessage<<"HDCG: fPcg Vstart "< CoarseField PleftProj(this->coarsegrid); CoarseField PleftMss_proj(this->coarsegrid); + std::cout << GridLogMessage<<"HDCG: fPcg Vstart projecting "<_Aggregates.ProjectToSubspace(PleftProj,src); + std::cout << GridLogMessage<<"HDCG: fPcg Vstart coarse solve "<_CoarseSolverPrecise(PleftProj,PleftMss_proj); // Ass^{-1} r_s + std::cout << GridLogMessage<<"HDCG: fPcg Vstart promote "<_Aggregates.PromoteFromSubspace(PleftMss_proj,x); } }; +template +class TwoLevelADEF2mrhs : public TwoLevelADEF2 +{ +public: + GridBase *coarsegridmrhs; + LinearFunction &_CoarseSolverMrhs; + LinearFunction &_CoarseGuesser; + TwoLevelADEF2mrhs(RealD tol, + Integer maxit, + LinearOperatorBase &FineLinop, + LinearFunction &Smoother, + LinearFunction &CoarseSolver, + LinearFunction &CoarseSolverPrecise, + LinearFunction &CoarseSolverMrhs, + LinearFunction &CoarseGuesser, + GridBase *rhsgrid, + Aggregation &Aggregates) : + TwoLevelADEF2(tol, maxit,FineLinop,Smoother,CoarseSolver,CoarseSolverPrecise,Aggregates), + _CoarseSolverMrhs(CoarseSolverMrhs), + _CoarseGuesser(CoarseGuesser) + { + coarsegridmrhs = rhsgrid; + }; + + virtual void PcgM1(std::vector & in,std::vector & out){ + + int nrhs=in.size(); + std::cout << " mrhs PcgM1 for "<grid); + std::vector Min(nrhs,this->grid); + CoarseField PleftProj(this->coarsegrid); + CoarseField PleftMss_proj(this->coarsegrid); + + CoarseField PleftProjMrhs(this->coarsegridmrhs); + CoarseField PleftMss_projMrhs(this->coarsegridmrhs); + + for(int rhs=0;rhsgrid->Barrier(); + std::cout << " Calling smoother for "<grid->Barrier(); + this->_Smoother(in[rhs],Min[rhs]); + this->grid->Barrier(); + std::cout << " smoother done "<grid->Barrier(); + this->_FineLinop.HermOp(Min[rhs],out[rhs]); + this->grid->Barrier(); + std::cout << " Hermop for "<grid->Barrier(); + axpy(tmp,-1.0,out[rhs],in[rhs]); // tmp = in - A Min + this->grid->Barrier(); + std::cout << " axpy "<grid->Barrier(); + this->_Aggregates.ProjectToSubspace(PleftProj,tmp); // can optimise later + this->grid->Barrier(); + std::cout << " project "<grid->Barrier(); + InsertSlice(PleftProj,PleftProjMrhs,rhs,0); + this->grid->Barrier(); + std::cout << " insert rhs "<grid->Barrier(); + this->_CoarseGuesser(PleftProj,PleftMss_proj); + this->grid->Barrier(); + std::cout << " insert guess "<grid->Barrier(); + InsertSlice(PleftMss_proj,PleftMss_projMrhs,rhs,0); + } + + std::cout << " Coarse solve "<_CoarseSolverMrhs(PleftProjMrhs,PleftMss_projMrhs); // Ass^{-1} [in - A Min]_s + + for(int rhs=0;rhs_Aggregates.PromoteFromSubspace(PleftMss_proj,tmp);// tmp = Q[in - A Min] + axpy(out[rhs],1.0,Min[rhs],tmp); // Min+tmp + } + std::cout << " Extracted "< class TwoLevelADEF1defl : public TwoLevelCG {