/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/algorithms/iterative/PrecGeneralisedConjugateResidual.h Copyright (C) 2015 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_PREC_GCR_NON_HERM_H #define GRID_PREC_GCR_NON_HERM_H /////////////////////////////////////////////////////////////////////////////////////////////////////// //VPGCR Abe and Zhang, 2005. //INTERNATIONAL JOURNAL OF NUMERICAL ANALYSIS AND MODELING //Computing and Information Volume 2, Number 2, Pages 147-161 //NB. Likely not original reference since they are focussing on a preconditioner variant. // but VPGCR was nicely written up in their paper /////////////////////////////////////////////////////////////////////////////////////////////////////// NAMESPACE_BEGIN(Grid); #define GCRLogLevel std::cout << GridLogMessage < class PrecGeneralisedConjugateResidualNonHermitian : public LinearFunction { public: using LinearFunction::operator(); RealD Tolerance; Integer MaxIterations; int verbose; int mmax; int nstep; int steps; int level; GridStopWatch PrecTimer; GridStopWatch MatTimer; GridStopWatch LinalgTimer; LinearFunction &Preconditioner; LinearOperatorBase &Linop; void Level(int lv) { level=lv; }; PrecGeneralisedConjugateResidualNonHermitian(RealD tol,Integer maxit,LinearOperatorBase &_Linop,LinearFunction &Prec,int _mmax,int _nstep) : Tolerance(tol), MaxIterations(maxit), Linop(_Linop), Preconditioner(Prec), mmax(_mmax), nstep(_nstep) { level=1; verbose=1; }; void operator() (const Field &src, Field &psi){ psi=Zero(); RealD cp, ssq,rsq; ssq=norm2(src); rsq=Tolerance*Tolerance*ssq; Field r(src.Grid()); PrecTimer.Reset(); MatTimer.Reset(); LinalgTimer.Reset(); GridStopWatch SolverTimer; SolverTimer.Start(); steps=0; for(int k=0;k q(mmax,grid); std::vector p(mmax,grid); std::vector qq(mmax); GCRLogLevel<< "PGCR nStep("<(mmax-1))?(mmax-1):(kp); // if more than mmax done, we orthog all mmax history. for(int back=0;back=0); b=-real(innerProduct(q[peri_back],Az))/qq[peri_back]; p[peri_kp]=p[peri_kp]+b*p[peri_back]; q[peri_kp]=q[peri_kp]+b*q[peri_back]; } qq[peri_kp]=norm2(q[peri_kp]); // could use axpy_norm LinalgTimer.Stop(); } assert(0); // never reached return cp; } }; NAMESPACE_END(Grid); #endif