mirror of
https://github.com/paboyle/Grid.git
synced 2025-04-09 21:50:45 +01: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);
|
ExtractSlice(exported4d, tmp, 0, 0);
|
||||||
}
|
}
|
||||||
template<class Impl>
|
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)
|
void CayleyFermion5D<Impl>::ExportPhysicalFermionSource(const FermionField &solution5d,FermionField &exported4d)
|
||||||
{
|
{
|
||||||
int Ls = this->Ls;
|
int Ls = this->Ls;
|
||||||
|
@ -93,6 +93,14 @@ namespace Grid {
|
|||||||
virtual void ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d);
|
virtual void ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d);
|
||||||
virtual void ImportUnphysicalFermion(const FermionField &solution5d, FermionField &exported4d);
|
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
|
// 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>
|
#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
|
// 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..)
|
// are added, (e.g. extension for gparity, half precision project in comms etc..)
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
// Cayley 5d
|
// Cayley 5d
|
||||||
namespace Grid {
|
namespace Grid {
|
||||||
namespace QCD {
|
namespace QCD {
|
||||||
|
@ -141,6 +141,7 @@ namespace QCD {
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define INHERIT_FIMPL_TYPES(Impl)\
|
#define INHERIT_FIMPL_TYPES(Impl)\
|
||||||
|
typedef Impl Impl_t; \
|
||||||
typedef typename Impl::FermionField FermionField; \
|
typedef typename Impl::FermionField FermionField; \
|
||||||
typedef typename Impl::PropagatorField PropagatorField; \
|
typedef typename Impl::PropagatorField PropagatorField; \
|
||||||
typedef typename Impl::DoubledGaugeField DoubledGaugeField; \
|
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
|
Grid physics library, www.github.com/paboyle/Grid
|
||||||
|
|
||||||
Source file: ./tests/Test_cayley_cg.cc
|
Source file: ./tests/Test_cayley_cg.cc
|
||||||
@ -27,6 +26,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
|
|||||||
*************************************************************************************/
|
*************************************************************************************/
|
||||||
/* END LEGAL */
|
/* END LEGAL */
|
||||||
#include <Grid/Grid.h>
|
#include <Grid/Grid.h>
|
||||||
|
#include <Grid/qcd/action/fermion/Reconstruct5Dprop.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Grid;
|
using namespace Grid;
|
||||||
@ -46,6 +46,7 @@ struct scal {
|
|||||||
|
|
||||||
template<class What>
|
template<class What>
|
||||||
void TestCGinversions(What & Ddwf,
|
void TestCGinversions(What & Ddwf,
|
||||||
|
LatticeGaugeField &Umu,
|
||||||
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
||||||
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
|
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
|
||||||
RealD mass, RealD M5,
|
RealD mass, RealD M5,
|
||||||
@ -75,6 +76,24 @@ void TestCGprec(What & Ddwf,
|
|||||||
GridParallelRNG *RNG4,
|
GridParallelRNG *RNG4,
|
||||||
GridParallelRNG *RNG5);
|
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)
|
int main (int argc, char ** argv)
|
||||||
{
|
{
|
||||||
Grid_init(&argc,&argv);
|
Grid_init(&argc,&argv);
|
||||||
@ -100,46 +119,71 @@ int main (int argc, char ** argv)
|
|||||||
|
|
||||||
RealD mass=0.1;
|
RealD mass=0.1;
|
||||||
RealD M5 =1.8;
|
RealD M5 =1.8;
|
||||||
|
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||||
std::cout<<GridLogMessage <<"DomainWallFermion test"<<std::endl;
|
std::cout<<GridLogMessage <<"DomainWallFermion test"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||||
DomainWallFermionR Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
|
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 b=1.5;// Scale factor b+c=2, b-c=1
|
||||||
RealD c=0.5;
|
RealD c=0.5;
|
||||||
std::vector<ComplexD> gamma(Ls,ComplexD(1.0,0.0));
|
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 <<"MobiusFermion test"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||||
MobiusFermionR Dmob(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,b,c);
|
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 <<"ZMobiusFermion test"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||||
ZMobiusFermionR ZDmob(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,gamma,b,c);
|
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 <<"MobiusZolotarevFermion test"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||||
MobiusZolotarevFermionR Dzolo(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,b,c,0.1,2.0);
|
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 <<"ScaledShamirFermion test"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||||
ScaledShamirFermionR Dsham(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,2.0);
|
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 <<"ShamirZolotarevFermion test"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||||
ShamirZolotarevFermionR Dshamz(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,0.1,2.0);
|
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 <<"OverlapWilsonCayleyTanhFermion test"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||||
OverlapWilsonCayleyTanhFermionR Dov(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,1.0);
|
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 <<"OverlapWilsonCayleyZolotarevFermion test"<<std::endl;
|
||||||
|
std::cout<<GridLogMessage <<"======================"<<std::endl;
|
||||||
OverlapWilsonCayleyZolotarevFermionR Dovz(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,0.1,2.0);
|
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();
|
Grid_finalize();
|
||||||
}
|
}
|
||||||
template<class What>
|
template<class What>
|
||||||
void TestCGinversions(What & Ddwf,
|
void TestCGinversions(What & Ddwf,
|
||||||
|
LatticeGaugeField &Umu,
|
||||||
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
||||||
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
|
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
|
||||||
RealD mass, RealD M5,
|
RealD mass, RealD M5,
|
||||||
@ -154,6 +198,7 @@ void TestCGinversions(What & Ddwf,
|
|||||||
TestCGschur<What>(Ddwf,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,RNG4,RNG5);
|
TestCGschur<What>(Ddwf,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,RNG4,RNG5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class What>
|
template<class What>
|
||||||
void TestCGunprec(What & Ddwf,
|
void TestCGunprec(What & Ddwf,
|
||||||
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
|
||||||
@ -189,6 +234,112 @@ void TestCGprec(What & Ddwf,
|
|||||||
CG(HermOpEO,src_o,result_o);
|
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>
|
template<class What>
|
||||||
void TestCGschur(What & Ddwf,
|
void TestCGschur(What & Ddwf,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user