/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/algorithms/iterative/LocalCoherenceLanczos.h Copyright (C) 2015 Author: Christoph Lehner Author: paboyle 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_LOCAL_COHERENCE_IRL_H #define GRID_LOCAL_COHERENCE_IRL_H namespace Grid { struct LanczosParams : Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(LanczosParams, ChebyParams, Cheby,/*Chebyshev*/ int, Nstop, /*Vecs in Lanczos must converge Nstop < Nk < Nm*/ int, Nk, /*Vecs in Lanczos seek converge*/ int, Nm, /*Total vecs in Lanczos include restart*/ RealD, resid, /*residual*/ int, MaxIt, RealD, betastp, /* ? */ int, MinRes); // Must restart }; struct LocalCoherenceLanczosParams : Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(LocalCoherenceLanczosParams, bool, saveEvecs, bool, doFine, bool, doFineRead, bool, doCoarse, bool, doCoarseRead, LanczosParams, FineParams, LanczosParams, CoarseParams, ChebyParams, Smoother, RealD , coarse_relax_tol, std::vector, blockSize, std::string, config, std::vector < std::complex >, omega, RealD, mass, RealD, M5); }; // Duplicate functionality; ProjectedFunctionHermOp could be used with the trivial function template class ProjectedHermOp : public LinearFunction > > { public: typedef iVector CoarseSiteVector; typedef Lattice CoarseField; typedef Lattice CoarseScalar; // used for inner products on fine field typedef Lattice FineField; LinearOperatorBase &_Linop; std::vector &subspace; ProjectedHermOp(LinearOperatorBase& linop, std::vector & _subspace) : _Linop(linop), subspace(_subspace) { assert(subspace.size() >0); }; void operator()(const CoarseField& in, CoarseField& out) { GridBase *FineGrid = subspace[0]._grid; int checkerboard = subspace[0].checkerboard; FineField fin (FineGrid); fin.checkerboard= checkerboard; FineField fout(FineGrid); fout.checkerboard = checkerboard; blockPromote(in,fin,subspace); std::cout< class ProjectedFunctionHermOp : public LinearFunction > > { public: typedef iVector CoarseSiteVector; typedef Lattice CoarseField; typedef Lattice CoarseScalar; // used for inner products on fine field typedef Lattice FineField; OperatorFunction & _poly; LinearOperatorBase &_Linop; std::vector &subspace; ProjectedFunctionHermOp(OperatorFunction & poly, LinearOperatorBase& linop, std::vector & _subspace) : _poly(poly), _Linop(linop), subspace(_subspace) { }; void operator()(const CoarseField& in, CoarseField& out) { GridBase *FineGrid = subspace[0]._grid; int checkerboard = subspace[0].checkerboard; FineField fin (FineGrid); fin.checkerboard =checkerboard; FineField fout(FineGrid);fout.checkerboard =checkerboard; blockPromote(in,fin,subspace); std::cout< class ImplicitlyRestartedLanczosSmoothedTester : public ImplicitlyRestartedLanczosTester > > { public: typedef iVector CoarseSiteVector; typedef Lattice CoarseField; typedef Lattice CoarseScalar; // used for inner products on fine field typedef Lattice FineField; LinearFunction & _Poly; OperatorFunction & _smoother; LinearOperatorBase &_Linop; RealD _coarse_relax_tol; std::vector &_subspace; ImplicitlyRestartedLanczosSmoothedTester(LinearFunction &Poly, OperatorFunction &smoother, LinearOperatorBase &Linop, std::vector &subspace, RealD coarse_relax_tol=5.0e3) : _smoother(smoother), _Linop(Linop), _Poly(Poly), _subspace(subspace), _coarse_relax_tol(coarse_relax_tol) { }; int TestConvergence(int j,RealD eresid,CoarseField &B, RealD &eval,RealD evalMaxApprox) { CoarseField v(B); RealD eval_poly = eval; // Apply operator _Poly(B,v); RealD vnum = real(innerProduct(B,v)); // HermOp. RealD vden = norm2(B); RealD vv0 = norm2(v); eval = vnum/vden; v -= eval*B; RealD vv = norm2(v) / ::pow(evalMaxApprox,2.0); std::cout.precision(13); std::cout< nbasis ) eresid = eresid*_coarse_relax_tol; if( (vv class LocalCoherenceLanczos { public: typedef iVector CoarseSiteVector; typedef Lattice CoarseScalar; // used for inner products on fine field typedef Lattice CoarseField; typedef Lattice FineField; protected: GridBase *_CoarseGrid; GridBase *_FineGrid; int _checkerboard; LinearOperatorBase & _FineOp; std::vector &evals_fine; std::vector &evals_coarse; std::vector &subspace; std::vector &evec_coarse; private: std::vector _evals_fine; std::vector _evals_coarse; std::vector _subspace; std::vector _evec_coarse; public: LocalCoherenceLanczos(GridBase *FineGrid, GridBase *CoarseGrid, LinearOperatorBase &FineOp, int checkerboard) : _CoarseGrid(CoarseGrid), _FineGrid(FineGrid), _FineOp(FineOp), _checkerboard(checkerboard), evals_fine (_evals_fine), evals_coarse(_evals_coarse), subspace (_subspace), evec_coarse(_evec_coarse) { evals_fine.resize(0); evals_coarse.resize(0); }; ////////////////////////////////////////////////////////////////////////// // Alternate constructore, external storage for use by Hadrons module ////////////////////////////////////////////////////////////////////////// LocalCoherenceLanczos(GridBase *FineGrid, GridBase *CoarseGrid, LinearOperatorBase &FineOp, int checkerboard, std::vector &ext_subspace, std::vector &ext_coarse, std::vector &ext_eval_fine, std::vector &ext_eval_coarse ) : _CoarseGrid(CoarseGrid), _FineGrid(FineGrid), _FineOp(FineOp), _checkerboard(checkerboard), evals_fine (ext_eval_fine), evals_coarse(ext_eval_coarse), subspace (ext_subspace), evec_coarse (ext_coarse) { evals_fine.resize(0); evals_coarse.resize(0); }; void Orthogonalise(void ) { CoarseScalar InnerProd(_CoarseGrid); blockOrthogonalise(InnerProd,subspace);std::cout << GridLogMessage <<" Gramm-Schmidt pass 1"< static RealD normalise(T& v) { RealD nn = norm2(v); nn = ::sqrt(nn); v = v * (1.0/nn); return nn; } /* void fakeFine(void) { int Nk = nbasis; subspace.resize(Nk,_FineGrid); subspace[0]=1.0; subspace[0].checkerboard=_checkerboard; normalise(subspace[0]); PlainHermOp Op(_FineOp); for(int k=1;k Op(_FineOp); ImplicitlyRestartedLanczosHermOpTester SimpleTester(Op); for(int k=0;k ChebySmooth(cheby_smooth); ProjectedFunctionHermOp ChebyOp (ChebySmooth,_FineOp,_subspace); ImplicitlyRestartedLanczosSmoothedTester ChebySmoothTester(ChebyOp,ChebySmooth,_FineOp,subspace,relax); for(int k=0;k Cheby(cheby_parms); FunctionHermOp ChebyOp(Cheby,_FineOp); PlainHermOp Op(_FineOp); evals_fine.resize(Nm); subspace.resize(Nm,_FineGrid); ImplicitlyRestartedLanczos IRL(ChebyOp,Op,Nstop,Nk,Nm,resid,MaxIt,betastp,MinRes); FineField src(_FineGrid); src=1.0; src.checkerboard = _checkerboard; int Nconv; IRL.calc(evals_fine,subspace,src,Nconv,false); // Shrink down to number saved assert(Nstop>=nbasis); assert(Nconv>=nbasis); evals_fine.resize(nbasis); subspace.resize(nbasis,_FineGrid); } void calcCoarse(ChebyParams cheby_op,ChebyParams cheby_smooth,RealD relax, int Nstop, int Nk, int Nm,RealD resid, RealD MaxIt, RealD betastp, int MinRes) { Chebyshev Cheby(cheby_op); ProjectedHermOp Op(_FineOp,_subspace); ProjectedFunctionHermOp ChebyOp (Cheby,_FineOp,_subspace); ////////////////////////////////////////////////////////////////////////////////////////////////// // create a smoother and see if we can get a cheap convergence test and smooth inside the IRL ////////////////////////////////////////////////////////////////////////////////////////////////// Chebyshev ChebySmooth(cheby_smooth); ImplicitlyRestartedLanczosSmoothedTester ChebySmoothTester(ChebyOp,ChebySmooth,_FineOp,_subspace,relax); evals_coarse.resize(Nm); evec_coarse.resize(Nm,_CoarseGrid); CoarseField src(_CoarseGrid); src=1.0; ImplicitlyRestartedLanczos IRL(ChebyOp,ChebyOp,ChebySmoothTester,Nstop,Nk,Nm,resid,MaxIt,betastp,MinRes); int Nconv=0; IRL.calc(evals_coarse,evec_coarse,src,Nconv,false); assert(Nconv>=Nstop); evals_coarse.resize(Nstop); evec_coarse.resize (Nstop,_CoarseGrid); for (int i=0;i