diff --git a/Grid/algorithms/LinearOperator.h b/Grid/algorithms/LinearOperator.h index 86d3f030..b86863b8 100644 --- a/Grid/algorithms/LinearOperator.h +++ b/Grid/algorithms/LinearOperator.h @@ -380,6 +380,12 @@ namespace Grid { template class OperatorFunction { public: virtual void operator() (LinearOperatorBase &Linop, const Field &in, Field &out) = 0; + virtual void operator() (LinearOperatorBase &Linop, const std::vector &in,std::vector &out) { + assert(in.size()==out.size()); + for(int k=0;k class LinearFunction { @@ -421,7 +427,7 @@ namespace Grid { // Hermitian operator Linear function and operator function //////////////////////////////////////////////////////////////////////////////////////////// template - class HermOpOperatorFunction : public OperatorFunction { + class HermOpOperatorFunction : public OperatorFunction { void operator() (LinearOperatorBase &Linop, const Field &in, Field &out) { Linop.HermOp(in,out); }; diff --git a/Grid/algorithms/iterative/BlockConjugateGradient.h b/Grid/algorithms/iterative/BlockConjugateGradient.h index 9a1e8b34..972aa608 100644 --- a/Grid/algorithms/iterative/BlockConjugateGradient.h +++ b/Grid/algorithms/iterative/BlockConjugateGradient.h @@ -135,7 +135,7 @@ void operator()(LinearOperatorBase &Linop, const Field &Src, Field &Psi) assert(0); } } -void operator()(LinearOperatorBase &Linop, const std::vector &Src, std::vector &Psi) +virtual void operator()(LinearOperatorBase &Linop, const std::vector &Src, std::vector &Psi) { if ( CGtype == BlockCGrQVec ) { BlockCGrQsolveVec(Linop,Src,Psi); diff --git a/Grid/algorithms/iterative/SchurRedBlack.h b/Grid/algorithms/iterative/SchurRedBlack.h index 5abc4d9f..cf6b5a13 100644 --- a/Grid/algorithms/iterative/SchurRedBlack.h +++ b/Grid/algorithms/iterative/SchurRedBlack.h @@ -327,28 +327,19 @@ namespace Grid { ZeroGuesser guess; (*this)(_Matrix,in,out,guess); } - template - void operator() (Matrix & _Matrix,const Field &in, Field &out,Guesser &guess){ - // FIXME CGdiagonalMee not implemented virtual function - // FIXME use CBfactorise to control schur decomp + template void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o) + { GridBase *grid = _Matrix.RedBlackGrid(); GridBase *fgrid= _Matrix.Grid(); SchurDiagTwoOperator _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); + pickCheckerboard(Even,src_e,src); + pickCheckerboard(Odd ,src_o,src); ///////////////////////////////////////////////////// // src_o = Mdag * (source_o - Moe MeeInv source_e) @@ -359,28 +350,156 @@ namespace Grid { // get the right MpcDag _HermOpEO.MpcDag(tmp,src_o); assert(src_o.checkerboard ==Odd); + } - ////////////////////////////////////////////////////////////// - // Call the red-black solver - ////////////////////////////////////////////////////////////// - std::cout< void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol) + { + GridBase *grid = _Matrix.RedBlackGrid(); + GridBase *fgrid= _Matrix.Grid(); + + Field tmp(grid); + Field sol_e(grid); /////////////////////////////////////////////////// // sol_e = M_ee^-1 * ( src_e - Meo sol_o )... /////////////////////////////////////////////////// _Matrix.Meooe(sol_o,tmp); assert( tmp.checkerboard ==Even); - src_e = src_e-tmp; assert( src_e.checkerboard ==Even); - _Matrix.MooeeInv(src_e,sol_e); assert( sol_e.checkerboard ==Even); + tmp = src_e-tmp; assert( src_e.checkerboard ==Even); + _Matrix.MooeeInv(tmp,sol_e); assert( sol_e.checkerboard ==Even); - setCheckerboard(out,sol_e); assert( sol_e.checkerboard ==Even); - setCheckerboard(out,sol_o); assert( sol_o.checkerboard ==Odd ); + setCheckerboard(sol,sol_e); assert( sol_e.checkerboard ==Even); + setCheckerboard(sol,sol_o); assert( sol_o.checkerboard ==Odd ); + }; + + template + void operator()(Matrix &_Matrix, const std::vector &in, std::vector &out) + { + ZeroGuesser guess; + (*this)(_Matrix,in,out,guess); + } + + template + void operator()(Matrix &_Matrix, const std::vector &in, std::vector &out,Guesser &guess) + { + GridBase *grid = _Matrix.RedBlackGrid(); + GridBase *fgrid= _Matrix.Grid(); + int nblock = in.size(); + + std::vector src_o(nblock,grid); + std::vector sol_o(nblock,grid); + + std::vector guess_save; + + Field resid(fgrid); + Field tmp(grid); + + //////////////////////////////////////////////// + // Prepare RedBlack source + //////////////////////////////////////////////// + for(int b=0;b _HermOpEO(_Matrix); + _HermitianRBSolver(_HermOpEO,src_o,sol_o); + + //////////////////////////////////////////////// + // A2A boolean behavioural control & reconstruct other checkerboard + //////////////////////////////////////////////// + for(int b=0;b + void operator() (Matrix & _Matrix,const Field &in, Field &out,Guesser &guess){ + + // FIXME CGdiagonalMee not implemented virtual function + // FIXME use CBfactorise to control schur decomp + GridBase *grid = _Matrix.RedBlackGrid(); + GridBase *fgrid= _Matrix.Grid(); + + Field resid(fgrid); + Field src_o(grid); + Field src_e(grid); + Field sol_o(grid); + + + //////////////////////////////////////////////// + // RedBlack source + //////////////////////////////////////////////// + RedBlackSource(_Matrix,in,src_e,src_o); + + //////////////////////////////// + // Construct the guess + //////////////////////////////// + Field tmp(grid); + guess(src_o,sol_o); + + Field guess_save(grid); + guess_save = sol_o; + + std::cout< _HermOpEO(_Matrix); + _HermitianRBSolver(_HermOpEO,src_o,sol_o); assert(tmp.checkerboard==Odd); + + //////////////////////////////////////////////// + // Fionn A2A boolean behavioural control + //////////////////////////////////////////////// + if (subGuess) tmp = sol_o-guess_save; + else tmp = sol_o; + + //////////////////////////////////////////////// + // MooeeInv + //////////////////////////////////////////////// + _Matrix.MooeeInv(tmp,sol_o); assert( sol_o.checkerboard ==Odd); + + /////////////////////////////////////////////////// + // RedBlack solution needs the even source + /////////////////////////////////////////////////// + RedBlackSolution(_Matrix,sol_o,src_e,out); // Verify the unprec residual if ( ! subGuess ) { diff --git a/tests/solver/Test_mobius_bcg_prec_nosplit.cc b/tests/solver/Test_mobius_bcg_prec_nosplit.cc index 347322c8..63078613 100644 --- a/tests/solver/Test_mobius_bcg_prec_nosplit.cc +++ b/tests/solver/Test_mobius_bcg_prec_nosplit.cc @@ -83,7 +83,7 @@ int main (int argc, char ** argv) LatticeGaugeField Umu(UGrid); - int conf = 0; + int conf = 2; if(conf==0) { FieldMetaData header; std::string file("./lat.in"); @@ -131,9 +131,12 @@ int main (int argc, char ** argv) for(int s=0;s BCGV (BlockCGrQVec,blockDim,stp,100000); + + { - BCGV(HermOp,src,result); + BlockConjugateGradient BCGV (BlockCGrQVec,blockDim,stp,100000); + SchurRedBlackDiagTwoSolve SchurSolver(BCGV); + SchurSolver(Ddwf,src,result); } for(int rhs=0;rhs