diff --git a/lib/algorithms/LinearOperator.h b/lib/algorithms/LinearOperator.h index 53f3573e..d7cc1927 100644 --- a/lib/algorithms/LinearOperator.h +++ b/lib/algorithms/LinearOperator.h @@ -8,6 +8,7 @@ Author: Azusa Yamaguchi Author: Peter Boyle +Author: Chulwoo Jung 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 @@ -330,7 +331,61 @@ namespace Grid { assert(0);// Never need with staggered } }; - template using SchurStagOperator = SchurStaggeredOperator; +// template using SchurStagOperator = SchurStaggeredOperator; + template +// class SchurStagOperator : public LinearOperatorBase { + class SchurStagOperator : public SchurOperatorBase { + protected: + Matrix &_Mat; + public: + SchurStagOperator (Matrix &Mat): _Mat(Mat){}; + virtual RealD Mpc (const Field &in, Field &out) { + Field tmp(in._grid); + Field tmp2(in._grid); + + _Mat.Mooee(in,out); + _Mat.Mooee(out,tmp); + + _Mat.Meooe(in,out); + _Mat.Meooe(out,tmp2); + + return axpy_norm(out,-1.0,tmp2,tmp); + } + virtual RealD MpcDag (const Field &in, Field &out){ + + return Mpc(in,out); + } +#if 0 + virtual void MpcDagMpc(const Field &in, Field &out,RealD &ni,RealD &no) { + Field tmp(in._grid); + ni=Mpc(in,tmp); + no=MpcDag(tmp,out); + } +#endif + void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ + n2 = Mpc(in,out); + ComplexD dot = innerProduct(in,out); + n1 = real(dot); + } + void HermOp(const Field &in, Field &out){ + RealD n1,n2; + HermOpAndNorm(in,out,n1,n2); + } + void Op (const Field &in, Field &out){ + Mpc(in,out); + } + void AdjOp (const Field &in, Field &out){ + MpcDag(in,out); + } + // Support for coarsening to a multigrid + void OpDiag (const Field &in, Field &out) { + assert(0); // must coarsen the unpreconditioned system + } + void OpDir (const Field &in, Field &out,int dir,int disp) { + assert(0); + } + + }; #if 0 // This is specific to (Z)mobius fermions diff --git a/lib/algorithms/iterative/SchurRedBlack.h b/lib/algorithms/iterative/SchurRedBlack.h index a0fd86a6..54277641 100644 --- a/lib/algorithms/iterative/SchurRedBlack.h +++ b/lib/algorithms/iterative/SchurRedBlack.h @@ -164,7 +164,83 @@ namespace Grid { std::cout< using SchurRedBlackStagSolve = SchurRedBlackStaggeredSolve; +// template using SchurRedBlackStagSolve = SchurRedBlackStaggeredSolve; + template class SchurRedBlackStagSolve { + private: + OperatorFunction & _HermitianRBSolver; + int CBfactorise; + public: + + ///////////////////////////////////////////////////// + // Wrap the usual normal equations Schur trick + ///////////////////////////////////////////////////// + SchurRedBlackStagSolve(OperatorFunction &HermitianRBSolver) : + _HermitianRBSolver(HermitianRBSolver) + { + CBfactorise=0; + }; + + template + void operator() (Matrix & _Matrix,const Field &in, Field &out){ + + // FIXME CGdiagonalMee not implemented virtual function + // FIXME use CBfactorise to control schur decomp + GridBase *grid = _Matrix.RedBlackGrid(); + GridBase *fgrid= _Matrix.Grid(); + + SchurStagOperator _HermOpEO(_Matrix); + + Field src_e(grid); + Field src_o(grid); + Field sol_e(grid); + Field sol_o(grid); + Field tmp(grid); + Field Mtmp(grid); + Field resid(fgrid); + + pickCheckerboard(Even,src_e,in); + pickCheckerboard(Odd ,src_o,in); + pickCheckerboard(Even,sol_e,out); + pickCheckerboard(Odd ,sol_o,out); + + ///////////////////////////////////////////////////// + // src_o = Mdag * (source_o - Moe MeeInv source_e) + ///////////////////////////////////////////////////// + _Matrix.MooeeInv(src_e,tmp); assert( tmp.checkerboard ==Even); + _Matrix.Meooe (tmp,Mtmp); assert( Mtmp.checkerboard ==Odd); + tmp=src_o-Mtmp; assert( tmp.checkerboard ==Odd); + +#if 0 + // get the right MpcDag +// _HermOpEO.MpcDag(tmp,src_o); assert(src_o.checkerboard ==Odd); +#else + _Matrix.Mooee(tmp,src_o); assert(src_o.checkerboard ==Odd); +#endif + ////////////////////////////////////////////////////////////// + // Call the red-black solver + ////////////////////////////////////////////////////////////// + std::cout< class SchurRedBlackStagMixed { + private: + LinearFunction & _HermitianRBSolver; + int CBfactorise; + public: + + ///////////////////////////////////////////////////// + // Wrap the usual normal equations Schur trick + ///////////////////////////////////////////////////// + SchurRedBlackStagMixed(LinearFunction &HermitianRBSolver) : + _HermitianRBSolver(HermitianRBSolver) + { + CBfactorise=0; + }; + + template + void operator() (Matrix & _Matrix,const Field &in, Field &out){ + + // FIXME CGdiagonalMee not implemented virtual function + // FIXME use CBfactorise to control schur decomp + GridBase *grid = _Matrix.RedBlackGrid(); + GridBase *fgrid= _Matrix.Grid(); + + SchurStagOperator _HermOpEO(_Matrix); + + Field src_e(grid); + Field src_o(grid); + Field sol_e(grid); + Field sol_o(grid); + Field tmp(grid); + Field Mtmp(grid); + Field resid(fgrid); + + pickCheckerboard(Even,src_e,in); + pickCheckerboard(Odd ,src_o,in); + pickCheckerboard(Even,sol_e,out); + pickCheckerboard(Odd ,sol_o,out); + + ///////////////////////////////////////////////////// + // src_o = Mdag * (source_o - Moe MeeInv source_e) + ///////////////////////////////////////////////////// + _Matrix.MooeeInv(src_e,tmp); assert( tmp.checkerboard ==Even); + _Matrix.Meooe (tmp,Mtmp); assert( Mtmp.checkerboard ==Odd); + tmp=src_o-Mtmp; assert( tmp.checkerboard ==Odd); + + _Matrix.Mooee(tmp,src_o); assert(src_o.checkerboard ==Odd); + ////////////////////////////////////////////////////////////// + // Call the red-black solver + ////////////////////////////////////////////////////////////// + std::cout<