mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-10 07:55:35 +00:00
PauliVillars based 4D -> 5D reconstruction with Fourier Accelerated PV inverse
by Christoph. Differs from the one by Rudy in BFM since it vectorises the twisted 4D solves in pairs.
This commit is contained in:
parent
fe6a372f75
commit
49f25e08e8
@ -68,6 +68,26 @@ void CayleyFermion5D<Impl>::ExportPhysicalFermionSolution(const FermionField &so
|
||||
ExtractSlice(exported4d, tmp, 0, 0);
|
||||
}
|
||||
template<class Impl>
|
||||
void CayleyFermion5D<Impl>::P(const FermionField &psi, FermionField &chi)
|
||||
{
|
||||
int Ls= this->Ls;
|
||||
chi=zero;
|
||||
for(int s=0;s<Ls;s++){
|
||||
axpby_ssp_pminus(chi,1.0,chi,1.0,psi,s,s);
|
||||
axpby_ssp_pplus (chi,1.0,chi,1.0,psi,s,(s+1)%Ls);
|
||||
}
|
||||
}
|
||||
template<class Impl>
|
||||
void CayleyFermion5D<Impl>::Pdag(const FermionField &psi, FermionField &chi)
|
||||
{
|
||||
int Ls= this->Ls;
|
||||
chi=zero;
|
||||
for(int s=0;s<Ls;s++){
|
||||
axpby_ssp_pminus(chi,1.0,chi,1.0,psi,s,s);
|
||||
axpby_ssp_pplus (chi,1.0,chi,1.0,psi,s,(s-1+Ls)%Ls);
|
||||
}
|
||||
}
|
||||
template<class Impl>
|
||||
void CayleyFermion5D<Impl>::ExportPhysicalFermionSource(const FermionField &solution5d,FermionField &exported4d)
|
||||
{
|
||||
int Ls = this->Ls;
|
||||
|
@ -93,6 +93,14 @@ namespace Grid {
|
||||
virtual void ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d);
|
||||
virtual void ImportUnphysicalFermion(const FermionField &solution5d, FermionField &exported4d);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Support for MADWF tricks
|
||||
///////////////////////////////////////////////////////////////
|
||||
RealD Mass(void) { return mass; };
|
||||
void SetMass(RealD _mass) { mass=_mass; } ;
|
||||
void P(const FermionField &psi, FermionField &chi);
|
||||
void Pdag(const FermionField &psi, FermionField &chi);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// Instantiate different versions depending on Impl
|
||||
/////////////////////////////////////////////////////
|
||||
|
@ -80,12 +80,23 @@ Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <Grid/qcd/action/fermion/g5HermitianLinop.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Fourier accelerated Pauli Villars inverse support
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include <Grid/qcd/action/fermion/WilsonTMFermion5D.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Move this group to a DWF specific tools/algorithms subdir?
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include <Grid/qcd/action/fermion/FourierAcceleratedPV.h>
|
||||
#include <Grid/qcd/action/fermion/PauliVillarsInverters.h>
|
||||
#include <Grid/qcd/action/fermion/Reconstruct5Dprop.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// More maintainable to maintain the following typedef list centrally, as more "impl" targets
|
||||
// are added, (e.g. extension for gparity, half precision project in comms etc..)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Cayley 5d
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
@ -141,6 +141,7 @@ namespace QCD {
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define INHERIT_FIMPL_TYPES(Impl)\
|
||||
typedef Impl Impl_t; \
|
||||
typedef typename Impl::FermionField FermionField; \
|
||||
typedef typename Impl::PropagatorField PropagatorField; \
|
||||
typedef typename Impl::DoubledGaugeField DoubledGaugeField; \
|
||||
|
237
Grid/qcd/action/fermion/FourierAcceleratedPV.h
Normal file
237
Grid/qcd/action/fermion/FourierAcceleratedPV.h
Normal file
@ -0,0 +1,237 @@
|
||||
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/qcd/action/fermion/FourierAcceleratedPV.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Christoph Lehner
|
||||
Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
|
||||
|
||||
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<typename M>
|
||||
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<m.bs.size();i++) {
|
||||
assert(m.bs[i] == b);
|
||||
assert(m.cs[i] == c);
|
||||
}
|
||||
assert(b.imag() == 0.0);
|
||||
assert(c.imag() == 0.0);
|
||||
_b = b.real();
|
||||
_c = c.real();
|
||||
}
|
||||
|
||||
|
||||
template<typename Vi, typename M, typename G>
|
||||
class FourierAcceleratedPV {
|
||||
public:
|
||||
|
||||
ConjugateGradient<Vi> &cg;
|
||||
M& dwfPV;
|
||||
G& Umu;
|
||||
GridCartesian* grid5D;
|
||||
GridRedBlackCartesian* gridRB5D;
|
||||
int group_in_s;
|
||||
|
||||
FourierAcceleratedPV(M& _dwfPV, G& _Umu, ConjugateGradient<Vi> &_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<Ls;s++) {
|
||||
Coeff_t a(::cos(phase*s),-::sin(phase*s));
|
||||
axpby_ssp(_tmp,a,_src,bzero,_src,s,s);
|
||||
}
|
||||
gsw1.Stop();
|
||||
|
||||
gsw2.Start();
|
||||
theFFT.FFT_dim(dst,_tmp,0,FFT::forward);
|
||||
gsw2.Stop();
|
||||
|
||||
} else {
|
||||
|
||||
gsw2.Start();
|
||||
theFFT.FFT_dim(_tmp,_src,0,FFT::backward);
|
||||
gsw2.Stop();
|
||||
|
||||
gsw1.Start();
|
||||
for (int s=0;s<Ls;s++) {
|
||||
Coeff_t a(::cos(phase*s),::sin(phase*s));
|
||||
axpby_ssp(dst,a,_tmp,bzero,_tmp,s,s);
|
||||
}
|
||||
gsw1.Stop();
|
||||
}
|
||||
|
||||
std::cout << GridLogMessage << "Timing rotatePV: " << gsw1.Elapsed() << ", " << gsw2.Elapsed() << std::endl;
|
||||
|
||||
}
|
||||
|
||||
void pvInv(const Vi& _src, Vi& _dst) const {
|
||||
|
||||
std::cout << GridLogMessage << "Fourier-Accelerated Outer Pauli Villars"<<std::endl;
|
||||
|
||||
typedef typename Vi::scalar_type Coeff_t;
|
||||
int Ls = _dst._grid->_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<Impl> tm(x.Umu,*x.UGridF,*x.UrbGridF,0.0,0.0,solver_outer.parent.par.wparams_f);
|
||||
std::vector<RealD> vmass(grid5D->_fdimensions[0],0.0);
|
||||
std::vector<RealD> vmu(grid5D->_fdimensions[0],0.0);
|
||||
|
||||
WilsonTMFermion5D<Impl> tm(Umu,*grid5D,*gridRB5D,
|
||||
*(GridCartesian*)dwfPV.GaugeGrid(),
|
||||
*(GridRedBlackCartesian*)dwfPV.GaugeRedBlackGrid(),
|
||||
vmass,vmu);
|
||||
|
||||
//SchurRedBlackDiagTwoSolve<Vi> sol(cg);
|
||||
SchurRedBlackDiagMooeeSolve<Vi> sol(cg); // same performance as DiagTwo
|
||||
gswA.Stop();
|
||||
|
||||
gswB.Start();
|
||||
|
||||
for (int sgroup=0;sgroup<Ls/2/group_in_s;sgroup++) {
|
||||
|
||||
for (int sidx=0;sidx<group_in_s;sidx++) {
|
||||
|
||||
int s = sgroup*group_in_s + sidx;
|
||||
int sprime = Ls-s-1;
|
||||
|
||||
RealD phase = M_PI / (RealD)Ls * (2.0 * s + 1.0);
|
||||
RealD cosp = ::cos(phase);
|
||||
RealD sinp = ::sin(phase);
|
||||
RealD denom = b*b + c*c + 2.0*b*c*cosp;
|
||||
RealD mass = -(b*b*M5 + c*(1.0 - cosp + c*M5) + b*(-1.0 + cosp + 2.0*c*cosp*M5))/denom;
|
||||
RealD mu = (b+c)*sinp/denom;
|
||||
|
||||
vmass[2*sidx + 0] = mass;
|
||||
vmass[2*sidx + 1] = mass;
|
||||
vmu[2*sidx + 0] = mu;
|
||||
vmu[2*sidx + 1] = -mu;
|
||||
|
||||
}
|
||||
|
||||
tm.update(vmass,vmu);
|
||||
|
||||
for (int sidx=0;sidx<group_in_s;sidx++) {
|
||||
|
||||
int s = sgroup*group_in_s + sidx;
|
||||
int sprime = Ls-s-1;
|
||||
|
||||
ExtractSlice(_src_diag_slice,_src_diag,s,0);
|
||||
InsertSlice(_src_diag_slice,_src_diag_slices,2*sidx + 0,0);
|
||||
|
||||
ExtractSlice(_src_diag_slice,_src_diag,sprime,0);
|
||||
InsertSlice(_src_diag_slice,_src_diag_slices,2*sidx + 1,0);
|
||||
|
||||
}
|
||||
|
||||
GridStopWatch gsw;
|
||||
gsw.Start();
|
||||
_dst_diag_slices = zero; // zero guess
|
||||
sol(tm,_src_diag_slices,_dst_diag_slices);
|
||||
gsw.Stop();
|
||||
std::cout << GridLogMessage << "Solve[sgroup=" << sgroup << "] completed in " << gsw.Elapsed() << ", " << gswA.Elapsed() << std::endl;
|
||||
|
||||
for (int sidx=0;sidx<group_in_s;sidx++) {
|
||||
|
||||
int s = sgroup*group_in_s + sidx;
|
||||
int sprime = Ls-s-1;
|
||||
|
||||
RealD phase = M_PI / (RealD)Ls * (2.0 * s + 1.0);
|
||||
RealD cosp = ::cos(phase);
|
||||
RealD sinp = ::sin(phase);
|
||||
|
||||
// now rotate with inverse of
|
||||
Coeff_t pA = b + c*cosp;
|
||||
Coeff_t pB = - Coeff_t(0.0,1.0)*c*sinp;
|
||||
Coeff_t pABden = pA*pA - pB*pB;
|
||||
// (pA + pB * G5) * (pA - pB*G5) = (pA^2 - pB^2)
|
||||
|
||||
ExtractSlice(_dst_diag_slice,_dst_diag_slices,2*sidx + 0,0);
|
||||
_dst_diag_slice = (pA/pABden) * _dst_diag_slice - (pB/pABden) * (G5 * _dst_diag_slice);
|
||||
InsertSlice(_dst_diag_slice,_dst_diag,s,0);
|
||||
|
||||
ExtractSlice(_dst_diag_slice,_dst_diag_slices,2*sidx + 1,0);
|
||||
_dst_diag_slice = (pA/pABden) * _dst_diag_slice + (pB/pABden) * (G5 * _dst_diag_slice);
|
||||
InsertSlice(_dst_diag_slice,_dst_diag,sprime,0);
|
||||
}
|
||||
}
|
||||
gswB.Stop();
|
||||
|
||||
rotatePV(_dst_diag,_dst,true);
|
||||
|
||||
gswT.Stop();
|
||||
std::cout << GridLogMessage << "PV completed in " << gswT.Elapsed() << " (Setup: " << gswA.Elapsed() << ", s-loop: " << gswB.Elapsed() << ")" << std::endl;
|
||||
}
|
||||
|
||||
};
|
||||
}}
|
95
Grid/qcd/action/fermion/PauliVillarsInverters.h
Normal file
95
Grid/qcd/action/fermion/PauliVillarsInverters.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/SchurRedBlack.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
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<class Field>
|
||||
class PauliVillarsSolverUnprec
|
||||
{
|
||||
public:
|
||||
ConjugateGradient<Field> & CG;
|
||||
PauliVillarsSolverUnprec( ConjugateGradient<Field> &_CG) : CG(_CG){};
|
||||
|
||||
template<class Matrix>
|
||||
void operator() (Matrix &_Matrix,const Field &src,Field &sol)
|
||||
{
|
||||
RealD m = _Matrix.Mass();
|
||||
Field A (_Matrix.FermionGrid());
|
||||
|
||||
MdagMLinearOperator<Matrix,Field> HermOp(_Matrix);
|
||||
|
||||
_Matrix.SetMass(1.0);
|
||||
_Matrix.Mdag(src,A);
|
||||
CG(HermOp,A,sol);
|
||||
_Matrix.SetMass(m);
|
||||
};
|
||||
};
|
||||
|
||||
template<class Field,class SchurSolverType>
|
||||
class PauliVillarsSolverRBprec
|
||||
{
|
||||
public:
|
||||
SchurSolverType & SchurSolver;
|
||||
PauliVillarsSolverRBprec( SchurSolverType &_SchurSolver) : SchurSolver(_SchurSolver){};
|
||||
|
||||
template<class Matrix>
|
||||
void operator() (Matrix &_Matrix,const Field &src,Field &sol)
|
||||
{
|
||||
RealD m = _Matrix.Mass();
|
||||
Field A (_Matrix.FermionGrid());
|
||||
|
||||
_Matrix.SetMass(1.0);
|
||||
SchurSolver(_Matrix,src,sol);
|
||||
_Matrix.SetMass(m);
|
||||
};
|
||||
};
|
||||
|
||||
template<class Field,class GaugeField>
|
||||
class PauliVillarsSolverFourierAccel
|
||||
{
|
||||
public:
|
||||
GaugeField & Umu;
|
||||
ConjugateGradient<Field> & CG;
|
||||
|
||||
PauliVillarsSolverFourierAccel(GaugeField &_Umu,ConjugateGradient<Field> &_CG) : Umu(_Umu), CG(_CG)
|
||||
{
|
||||
};
|
||||
|
||||
template<class Matrix>
|
||||
void operator() (Matrix &_Matrix,const Field &src,Field &sol)
|
||||
{
|
||||
FourierAcceleratedPV<Field, Matrix, typename Matrix::GaugeField > faPV(_Matrix,Umu,CG) ;
|
||||
faPV.pvInv(src,sol);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
135
Grid/qcd/action/fermion/Reconstruct5Dprop.h
Normal file
135
Grid/qcd/action/fermion/Reconstruct5Dprop.h
Normal file
@ -0,0 +1,135 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/algorithms/iterative/SchurRedBlack.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
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<class Field,class PVinverter> class Reconstruct5DfromPhysical {
|
||||
private:
|
||||
PVinverter & PauliVillarsSolver;
|
||||
public:
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// First cut works, 10 Oct 2018.
|
||||
//
|
||||
// Must form a plan to get this into production for Zmobius acceleration
|
||||
// of the Mobius exact AMA corrections.
|
||||
//
|
||||
// TODO : understand absence of contact term in eqns in Hantao's thesis
|
||||
// sol4 is contact term subtracted, but thesis & Brower's paper suggests not.
|
||||
//
|
||||
// Step 1: Localise PV inverse in a routine. [DONE]
|
||||
// Step 2: Schur based PV inverse [DONE]
|
||||
// Step 3: Fourier accelerated PV inverse [DONE]
|
||||
//
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
Reconstruct5DfromPhysical(PVinverter &_PauliVillarsSolver)
|
||||
: PauliVillarsSolver(_PauliVillarsSolver)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template<class Matrix>
|
||||
void PV(Matrix &_Matrix,const Field &src,Field &sol)
|
||||
{
|
||||
RealD m = _Matrix.Mass();
|
||||
_Matrix.SetMass(1.0);
|
||||
_Matrix.M(src,sol);
|
||||
_Matrix.SetMass(m);
|
||||
}
|
||||
template<class Matrix>
|
||||
void PVdag(Matrix &_Matrix,const Field &src,Field &sol)
|
||||
{
|
||||
RealD m = _Matrix.Mass();
|
||||
_Matrix.SetMass(1.0);
|
||||
_Matrix.Mdag(src,sol);
|
||||
_Matrix.SetMass(m);
|
||||
}
|
||||
template<class Matrix>
|
||||
void operator() (Matrix & _Matrix,const Field &sol4,const Field &src4, Field &sol5){
|
||||
|
||||
int Ls = _Matrix.Ls;
|
||||
|
||||
Field psi4(_Matrix.GaugeGrid());
|
||||
Field psi(_Matrix.FermionGrid());
|
||||
Field A (_Matrix.FermionGrid());
|
||||
Field B (_Matrix.FermionGrid());
|
||||
Field c (_Matrix.FermionGrid());
|
||||
|
||||
typedef typename Matrix::Coeff_t Coeff_t;
|
||||
|
||||
std::cout << GridLogMessage<< " ************************************************" << std::endl;
|
||||
std::cout << GridLogMessage<< " Reconstruct5Dprop: c.f. MADWF algorithm " << std::endl;
|
||||
std::cout << GridLogMessage<< " ************************************************" << std::endl;
|
||||
|
||||
///////////////////////////////////////
|
||||
//Import source, include Dminus factors
|
||||
///////////////////////////////////////
|
||||
_Matrix.ImportPhysicalFermionSource(src4,B);
|
||||
|
||||
///////////////////////////////////////
|
||||
// Set up c from src4
|
||||
///////////////////////////////////////
|
||||
PauliVillarsSolver(_Matrix,B,A);
|
||||
_Matrix.Pdag(A,c);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Build Pdag PV^-1 Dm P [-sol4,c2,c3... cL]
|
||||
//////////////////////////////////////
|
||||
psi4 = - sol4;
|
||||
InsertSlice(psi4, psi, 0 , 0);
|
||||
for (int s=1;s<Ls;s++) {
|
||||
ExtractSlice(psi4,c,s,0);
|
||||
InsertSlice(psi4,psi,s,0);
|
||||
}
|
||||
|
||||
/////////////////////////////
|
||||
// Pdag PV^-1 Dm P
|
||||
/////////////////////////////
|
||||
_Matrix.P(psi,B);
|
||||
_Matrix.M(B,A);
|
||||
PauliVillarsSolver(_Matrix,A,B);
|
||||
_Matrix.Pdag(B,A);
|
||||
|
||||
//////////////////////////////
|
||||
// Reinsert surface prop
|
||||
//////////////////////////////
|
||||
InsertSlice(sol4,A,0,0);
|
||||
|
||||
//////////////////////////////
|
||||
// Convert from y back to x
|
||||
//////////////////////////////
|
||||
_Matrix.P(A,sol5);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
155
Grid/qcd/action/fermion/WilsonTMFermion5D.h
Normal file
155
Grid/qcd/action/fermion/WilsonTMFermion5D.h
Normal file
@ -0,0 +1,155 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/qcd/action/fermion/WilsonTMFermion5D.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk> ; NB Christoph did similar in GPT
|
||||
|
||||
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
|
||||
|
||||
#include <Grid/qcd/action/fermion/FermionCore.h>
|
||||
#include <Grid/qcd/action/fermion/WilsonFermion.h>
|
||||
|
||||
|
||||
namespace Grid {
|
||||
|
||||
namespace QCD {
|
||||
|
||||
template<class Impl>
|
||||
class WilsonTMFermion5D : public WilsonFermion5D<Impl>
|
||||
{
|
||||
public:
|
||||
INHERIT_IMPL_TYPES(Impl);
|
||||
public:
|
||||
|
||||
virtual void Instantiatable(void) {};
|
||||
|
||||
// Constructors
|
||||
WilsonTMFermion5D(GaugeField &_Umu,
|
||||
GridCartesian &Fgrid,
|
||||
GridRedBlackCartesian &Frbgrid,
|
||||
GridCartesian &Ugrid,
|
||||
GridRedBlackCartesian &Urbgrid,
|
||||
const std::vector<RealD> _mass,
|
||||
const std::vector<RealD> _mu,
|
||||
const ImplParams &p= ImplParams()
|
||||
) :
|
||||
WilsonFermion5D<Impl>(_Umu,
|
||||
Fgrid,
|
||||
Frbgrid,
|
||||
Ugrid,
|
||||
Urbgrid,
|
||||
4.0,p)
|
||||
|
||||
{
|
||||
update(_mass,_mu);
|
||||
}
|
||||
|
||||
virtual void Meooe(const FermionField &in, FermionField &out) {
|
||||
if (in.checkerboard == Odd) {
|
||||
this->DhopEO(in, out, DaggerNo);
|
||||
} else {
|
||||
this->DhopOE(in, out, DaggerNo);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void MeooeDag(const FermionField &in, FermionField &out) {
|
||||
if (in.checkerboard == Odd) {
|
||||
this->DhopEO(in, out, DaggerYes);
|
||||
} else {
|
||||
this->DhopOE(in, out, DaggerYes);
|
||||
}
|
||||
}
|
||||
|
||||
// allow override for twisted mass and clover
|
||||
virtual void Mooee(const FermionField &in, FermionField &out) {
|
||||
out.checkerboard = in.checkerboard;
|
||||
//axpibg5x(out,in,a,b); // out = a*in + b*i*G5*in
|
||||
for (int s=0;s<(int)this->mass.size();s++) {
|
||||
ComplexD a = 4.0+this->mass[s];
|
||||
ComplexD b(0.0,this->mu[s]);
|
||||
axpbg5y_ssp(out,a,in,b,in,s,s);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void MooeeDag(const FermionField &in, FermionField &out) {
|
||||
out.checkerboard = in.checkerboard;
|
||||
for (int s=0;s<(int)this->mass.size();s++) {
|
||||
ComplexD a = 4.0+this->mass[s];
|
||||
ComplexD b(0.0,-this->mu[s]);
|
||||
axpbg5y_ssp(out,a,in,b,in,s,s);
|
||||
}
|
||||
}
|
||||
virtual void MooeeInv(const FermionField &in, FermionField &out) {
|
||||
for (int s=0;s<(int)this->mass.size();s++) {
|
||||
RealD m = this->mass[s];
|
||||
RealD tm = this->mu[s];
|
||||
RealD mtil = 4.0+this->mass[s];
|
||||
RealD sq = mtil*mtil+tm*tm;
|
||||
ComplexD a = mtil/sq;
|
||||
ComplexD b(0.0, -tm /sq);
|
||||
axpbg5y_ssp(out,a,in,b,in,s,s);
|
||||
}
|
||||
}
|
||||
virtual void MooeeInvDag(const FermionField &in, FermionField &out) {
|
||||
for (int s=0;s<(int)this->mass.size();s++) {
|
||||
RealD m = this->mass[s];
|
||||
RealD tm = this->mu[s];
|
||||
RealD mtil = 4.0+this->mass[s];
|
||||
RealD sq = mtil*mtil+tm*tm;
|
||||
ComplexD a = mtil/sq;
|
||||
ComplexD b(0.0,tm /sq);
|
||||
axpbg5y_ssp(out,a,in,b,in,s,s);
|
||||
}
|
||||
}
|
||||
|
||||
virtual RealD M(const FermionField &in, FermionField &out) {
|
||||
out.checkerboard = in.checkerboard;
|
||||
this->Dhop(in, out, DaggerNo);
|
||||
FermionField tmp(out._grid);
|
||||
for (int s=0;s<(int)this->mass.size();s++) {
|
||||
ComplexD a = 4.0+this->mass[s];
|
||||
ComplexD b(0.0,this->mu[s]);
|
||||
axpbg5y_ssp(tmp,a,in,b,in,s,s);
|
||||
}
|
||||
return axpy_norm(out, 1.0, tmp, out);
|
||||
}
|
||||
|
||||
// needed for fast PV
|
||||
void update(const std::vector<RealD>& _mass, const std::vector<RealD>& _mu) {
|
||||
assert(_mass.size() == _mu.size());
|
||||
assert(_mass.size() == this->FermionGrid()->_fdimensions[0]);
|
||||
this->mass = _mass;
|
||||
this->mu = _mu;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<RealD> mu;
|
||||
std::vector<RealD> mass;
|
||||
|
||||
};
|
||||
|
||||
typedef WilsonTMFermion5D<WilsonImplF> WilsonTMFermion5DF;
|
||||
typedef WilsonTMFermion5D<WilsonImplD> WilsonTMFermion5DD;
|
||||
|
||||
}}
|
@ -1,5 +1,4 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./tests/Test_cayley_cg.cc
|
||||
@ -27,6 +26,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/Grid.h>
|
||||
#include <Grid/qcd/action/fermion/Reconstruct5Dprop.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace Grid;
|
||||
@ -46,6 +46,7 @@ struct scal {
|
||||
|
||||
template<class What>
|
||||
void TestCGinversions(What & Ddwf,
|
||||
LatticeGaugeField &Umu,
|
||||
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
||||
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
|
||||
RealD mass, RealD M5,
|
||||
@ -75,6 +76,24 @@ void TestCGprec(What & Ddwf,
|
||||
GridParallelRNG *RNG4,
|
||||
GridParallelRNG *RNG5);
|
||||
|
||||
template<class What>
|
||||
void TestReconstruct5D(What & Ddwf,
|
||||
LatticeGaugeField &Umu,
|
||||
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
||||
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
|
||||
RealD mass, RealD M5,
|
||||
GridParallelRNG *RNG4,
|
||||
GridParallelRNG *RNG5);
|
||||
|
||||
template<class What>
|
||||
void TestReconstruct5DFA(What & Ddwf,
|
||||
LatticeGaugeField &Umu,
|
||||
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
||||
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
|
||||
RealD mass, RealD M5,
|
||||
GridParallelRNG *RNG4,
|
||||
GridParallelRNG *RNG5);
|
||||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
Grid_init(&argc,&argv);
|
||||
@ -100,46 +119,71 @@ int main (int argc, char ** argv)
|
||||
|
||||
RealD mass=0.1;
|
||||
RealD M5 =1.8;
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"DomainWallFermion test"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
DomainWallFermionR Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
|
||||
TestCGinversions<DomainWallFermionR>(Ddwf,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestCGinversions<DomainWallFermionR>(Ddwf,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestReconstruct5DFA<DomainWallFermionR>(Ddwf,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
|
||||
RealD b=1.5;// Scale factor b+c=2, b-c=1
|
||||
RealD c=0.5;
|
||||
std::vector<ComplexD> gamma(Ls,ComplexD(1.0,0.0));
|
||||
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"MobiusFermion test"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
MobiusFermionR Dmob(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,b,c);
|
||||
TestCGinversions<MobiusFermionR>(Dmob,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestCGinversions<MobiusFermionR>(Dmob,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestReconstruct5DFA<MobiusFermionR>(Dmob,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"ZMobiusFermion test"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
ZMobiusFermionR ZDmob(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,gamma,b,c);
|
||||
TestCGinversions<ZMobiusFermionR>(ZDmob,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestCGinversions<ZMobiusFermionR>(ZDmob,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestReconstruct5D<ZMobiusFermionR>(ZDmob,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"MobiusZolotarevFermion test"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
MobiusZolotarevFermionR Dzolo(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,b,c,0.1,2.0);
|
||||
TestCGinversions<MobiusZolotarevFermionR>(Dzolo,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestCGinversions<MobiusZolotarevFermionR>(Dzolo,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestReconstruct5D<MobiusZolotarevFermionR>(Dzolo,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"ScaledShamirFermion test"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
ScaledShamirFermionR Dsham(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,2.0);
|
||||
TestCGinversions<ScaledShamirFermionR>(Dsham,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestCGinversions<ScaledShamirFermionR>(Dsham,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestReconstruct5DFA<ScaledShamirFermionR>(Dsham,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"ShamirZolotarevFermion test"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
ShamirZolotarevFermionR Dshamz(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,0.1,2.0);
|
||||
TestCGinversions<ShamirZolotarevFermionR>(Dshamz,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestCGinversions<ShamirZolotarevFermionR>(Dshamz,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestReconstruct5D<ShamirZolotarevFermionR>(Dshamz,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"OverlapWilsonCayleyTanhFermion test"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
OverlapWilsonCayleyTanhFermionR Dov(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,1.0);
|
||||
TestCGinversions<OverlapWilsonCayleyTanhFermionR>(Dov,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestCGinversions<OverlapWilsonCayleyTanhFermionR>(Dov,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestReconstruct5DFA<OverlapWilsonCayleyTanhFermionR>(Dov,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"OverlapWilsonCayleyZolotarevFermion test"<<std::endl;
|
||||
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||
OverlapWilsonCayleyZolotarevFermionR Dovz(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,0.1,2.0);
|
||||
TestCGinversions<OverlapWilsonCayleyZolotarevFermionR>(Dovz,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestCGinversions<OverlapWilsonCayleyZolotarevFermionR>(Dovz,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
TestReconstruct5D<OverlapWilsonCayleyZolotarevFermionR>(Dovz,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
|
||||
|
||||
Grid_finalize();
|
||||
}
|
||||
template<class What>
|
||||
void TestCGinversions(What & Ddwf,
|
||||
LatticeGaugeField &Umu,
|
||||
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
||||
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
|
||||
RealD mass, RealD M5,
|
||||
@ -154,6 +198,7 @@ void TestCGinversions(What & Ddwf,
|
||||
TestCGschur<What>(Ddwf,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,RNG4,RNG5);
|
||||
}
|
||||
|
||||
|
||||
template<class What>
|
||||
void TestCGunprec(What & Ddwf,
|
||||
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
||||
@ -189,6 +234,112 @@ void TestCGprec(What & Ddwf,
|
||||
CG(HermOpEO,src_o,result_o);
|
||||
}
|
||||
|
||||
template<class What>
|
||||
void TestReconstruct5D(What & Ddwf,
|
||||
LatticeGaugeField & Umu,
|
||||
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
||||
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
|
||||
RealD mass, RealD M5,
|
||||
GridParallelRNG *RNG4,
|
||||
GridParallelRNG *RNG5)
|
||||
{
|
||||
LatticeFermion src4 (UGrid); random(*RNG4,src4);
|
||||
LatticeFermion res4 (UGrid); res4 = zero;
|
||||
|
||||
LatticeFermion src (FGrid);
|
||||
LatticeFermion src_NE(FGrid);
|
||||
LatticeFermion result(FGrid);
|
||||
LatticeFermion result_rec(FGrid);
|
||||
|
||||
MdagMLinearOperator<What,LatticeFermion> HermOp(Ddwf);
|
||||
double Resid = 1.0e-12;
|
||||
ConjugateGradient<LatticeFermion> CG(Resid,10000);
|
||||
|
||||
Ddwf.ImportPhysicalFermionSource(src4,src);
|
||||
Ddwf.Mdag(src,src_NE);
|
||||
CG(HermOp,src_NE,result);
|
||||
|
||||
Ddwf.ExportPhysicalFermionSolution(result, res4);
|
||||
|
||||
Ddwf.M(result,src_NE);
|
||||
src_NE = src_NE - src;
|
||||
std::cout <<GridLogMessage<< " True residual is " << norm2(src_NE)<<std::endl;
|
||||
|
||||
std::cout <<GridLogMessage<< " Reconstructing " <<std::endl;
|
||||
|
||||
////////////////////////////
|
||||
// RBprec PV inverse
|
||||
////////////////////////////
|
||||
typedef LatticeFermion Field;
|
||||
typedef SchurRedBlackDiagMooeeSolve<Field> SchurSolverType;
|
||||
typedef PauliVillarsSolverRBprec<Field,SchurSolverType> PVinverter;
|
||||
SchurSolverType SchurSolver(CG);
|
||||
PVinverter PVinverse(SchurSolver);
|
||||
|
||||
Reconstruct5DfromPhysical<LatticeFermion,PVinverter> reconstructor(PVinverse);
|
||||
|
||||
reconstructor(Ddwf,res4,src4,result_rec);
|
||||
|
||||
std::cout <<GridLogMessage << "Result "<<norm2(result)<<std::endl;
|
||||
std::cout <<GridLogMessage << "Result_rec "<<norm2(result_rec)<<std::endl;
|
||||
|
||||
result_rec = result_rec - result;
|
||||
std::cout <<GridLogMessage << "Difference "<<norm2(result_rec)<<std::endl;
|
||||
|
||||
}
|
||||
template<class What>
|
||||
void TestReconstruct5DFA(What & Ddwf,
|
||||
LatticeGaugeField & Umu,
|
||||
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
||||
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
|
||||
RealD mass, RealD M5,
|
||||
GridParallelRNG *RNG4,
|
||||
GridParallelRNG *RNG5)
|
||||
{
|
||||
LatticeFermion src4 (UGrid); random(*RNG4,src4);
|
||||
LatticeFermion res4 (UGrid); res4 = zero;
|
||||
|
||||
LatticeFermion src (FGrid);
|
||||
LatticeFermion src_NE(FGrid);
|
||||
LatticeFermion result(FGrid);
|
||||
LatticeFermion result_rec(FGrid);
|
||||
|
||||
MdagMLinearOperator<What,LatticeFermion> HermOp(Ddwf);
|
||||
double Resid = 1.0e-12;
|
||||
ConjugateGradient<LatticeFermion> CG(Resid,10000);
|
||||
|
||||
Ddwf.ImportPhysicalFermionSource(src4,src);
|
||||
Ddwf.Mdag(src,src_NE);
|
||||
CG(HermOp,src_NE,result);
|
||||
|
||||
Ddwf.ExportPhysicalFermionSolution(result, res4);
|
||||
|
||||
Ddwf.M(result,src_NE);
|
||||
src_NE = src_NE - src;
|
||||
std::cout <<GridLogMessage<< " True residual is " << norm2(src_NE)<<std::endl;
|
||||
|
||||
std::cout <<GridLogMessage<< " Reconstructing " <<std::endl;
|
||||
|
||||
////////////////////////////
|
||||
// Fourier accel PV inverse
|
||||
////////////////////////////
|
||||
typedef LatticeFermion Field;
|
||||
typedef PauliVillarsSolverFourierAccel<LatticeFermion,LatticeGaugeField> PVinverter;
|
||||
PVinverter PVinverse(Umu,CG);
|
||||
|
||||
Reconstruct5DfromPhysical<LatticeFermion,PVinverter> reconstructor(PVinverse);
|
||||
|
||||
reconstructor(Ddwf,res4,src4,result_rec);
|
||||
|
||||
std::cout <<GridLogMessage << "Result "<<norm2(result)<<std::endl;
|
||||
std::cout <<GridLogMessage << "Result_rec "<<norm2(result_rec)<<std::endl;
|
||||
|
||||
result_rec = result_rec - result;
|
||||
std::cout <<GridLogMessage << "Difference "<<norm2(result_rec)<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class What>
|
||||
void TestCGschur(What & Ddwf,
|
||||
|
Loading…
Reference in New Issue
Block a user