/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/algorithms/iterative/BlockConjugateGradient.h Copyright (C) 2017 Author: Azusa Yamaguchi Author: Peter Boyle This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #ifndef GRID_BLOCK_CONJUGATE_GRADIENT_H #define GRID_BLOCK_CONJUGATE_GRADIENT_H namespace Grid { ////////////////////////////////////////////////////////////////////////// // Block conjugate gradient. Dimension zero should be the block direction ////////////////////////////////////////////////////////////////////////// template class BlockConjugateGradient : public OperatorFunction { public: typedef typename Field::scalar_type scomplex; const int blockDim = 0; int Nblock; bool ErrorOnNoConverge; // throw an assert when the CG fails to converge. // Defaults true. RealD Tolerance; Integer MaxIterations; Integer IterationsToComplete; //Number of iterations the CG took to finish. Filled in upon completion BlockConjugateGradient(RealD tol, Integer maxit, bool err_on_no_conv = true) : Tolerance(tol), MaxIterations(maxit), ErrorOnNoConverge(err_on_no_conv){}; void operator()(LinearOperatorBase &Linop, const Field &Src, Field &Psi) { int Orthog = 0; // First dimension is block dim Nblock = Src._grid->_fdimensions[Orthog]; std::cout< residuals(Nblock); std::vector ssq(Nblock); sliceNorm(ssq,Src,Orthog); RealD sssum=0; for(int b=0;b max_resid ) max_resid = rr; } if ( max_resid < Tolerance*Tolerance ) { SolverTimer.Stop(); std::cout << GridLogMessage<<"BlockCG converged in "< class MultiRHSConjugateGradient : public OperatorFunction { public: typedef typename Field::scalar_type scomplex; const int blockDim = 0; int Nblock; bool ErrorOnNoConverge; // throw an assert when the CG fails to converge. // Defaults true. RealD Tolerance; Integer MaxIterations; Integer IterationsToComplete; //Number of iterations the CG took to finish. Filled in upon completion MultiRHSConjugateGradient(RealD tol, Integer maxit, bool err_on_no_conv = true) : Tolerance(tol), MaxIterations(maxit), ErrorOnNoConverge(err_on_no_conv){}; void operator()(LinearOperatorBase &Linop, const Field &Src, Field &Psi) { int Orthog = 0; // First dimension is block dim Nblock = Src._grid->_fdimensions[Orthog]; std::cout< v_pAp(Nblock); std::vector v_rr (Nblock); std::vector v_rr_inv(Nblock); std::vector v_alpha(Nblock); std::vector v_beta(Nblock); // Initial residual computation & set up std::vector residuals(Nblock); std::vector ssq(Nblock); sliceNorm(ssq,Src,Orthog); RealD sssum=0; for(int b=0;b max_resid ) max_resid = rr; } if ( max_resid < Tolerance*Tolerance ) { SolverTimer.Stop(); std::cout << GridLogMessage<<"MultiRHS solver converged in " <