/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/action/fermion/FourierAcceleratedPV.h Copyright (C) 2015 Author: Christoph Lehner (lifted with permission by Peter Boyle, brought back to Grid) 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 */ #pragma once namespace Grid { namespace QCD { template void get_real_const_bc(M& m, RealD& _b, RealD& _c) { ComplexD b,c; b=m.bs[0]; c=m.cs[0]; std::cout << GridLogMessage << "b=" << b << ", c=" << c << std::endl; for (size_t i=1;i class FourierAcceleratedPV { public: ConjugateGradient &cg; M& dwfPV; G& Umu; GridCartesian* grid5D; GridRedBlackCartesian* gridRB5D; int group_in_s; FourierAcceleratedPV(M& _dwfPV, G& _Umu, ConjugateGradient &_cg, int _group_in_s = 2) : dwfPV(_dwfPV), Umu(_Umu), cg(_cg), group_in_s(_group_in_s) { assert( dwfPV.FermionGrid()->_fdimensions[0] % (2*group_in_s) == 0); grid5D = QCD::SpaceTimeGrid::makeFiveDimGrid(2*group_in_s, (GridCartesian*)Umu._grid); gridRB5D = QCD::SpaceTimeGrid::makeFiveDimRedBlackGrid(2*group_in_s, (GridCartesian*)Umu._grid); } void rotatePV(const Vi& _src, Vi& dst, bool forward) const { GridStopWatch gsw1, gsw2; typedef typename Vi::scalar_type Coeff_t; int Ls = dst._grid->_fdimensions[0]; Vi _tmp(dst._grid); double phase = M_PI / (double)Ls; Coeff_t bzero(0.0,0.0); FFT theFFT((GridCartesian*)dst._grid); if (!forward) { gsw1.Start(); for (int s=0;s_fdimensions[0]; GridStopWatch gswT; gswT.Start(); RealD b,c; get_real_const_bc(dwfPV,b,c); RealD M5 = dwfPV.M5; // U(true) Rightinv TMinv U(false) = Minv Vi _src_diag(_dst._grid); Vi _src_diag_slice(dwfPV.GaugeGrid()); Vi _dst_diag_slice(dwfPV.GaugeGrid()); Vi _src_diag_slices(grid5D); Vi _dst_diag_slices(grid5D); Vi _dst_diag(_dst._grid); rotatePV(_src,_src_diag,false); // now do TM solves Gamma G5(Gamma::Algebra::Gamma5); GridStopWatch gswA, gswB; gswA.Start(); typedef typename M::Impl_t Impl; //WilsonTMFermion tm(x.Umu,*x.UGridF,*x.UrbGridF,0.0,0.0,solver_outer.parent.par.wparams_f); std::vector vmass(grid5D->_fdimensions[0],0.0); std::vector vmu(grid5D->_fdimensions[0],0.0); WilsonTMFermion5D tm(Umu,*grid5D,*gridRB5D, *(GridCartesian*)dwfPV.GaugeGrid(), *(GridRedBlackCartesian*)dwfPV.GaugeRedBlackGrid(), vmass,vmu); //SchurRedBlackDiagTwoSolve sol(cg); SchurRedBlackDiagMooeeSolve sol(cg); // same performance as DiagTwo gswA.Stop(); gswB.Start(); for (int sgroup=0;sgroup