mirror of
https://github.com/paboyle/Grid.git
synced 2025-06-12 20:27:06 +01:00
Conjugate residual algorithm; some more unary functions
This commit is contained in:
@ -165,6 +165,27 @@ namespace QCD {
|
||||
}
|
||||
}
|
||||
|
||||
void CayleyFermion5D::Mdir (const LatticeFermion &psi, LatticeFermion &chi,int dir,int disp){
|
||||
LatticeFermion tmp(psi._grid);
|
||||
// Assemble the 5d matrix
|
||||
for(int s=0;s<Ls;s++){
|
||||
if ( s==0 ) {
|
||||
// tmp = bs psi[s] + cs[s] psi[s+1}
|
||||
// tmp+= -mass*cs[s] psi[s+1}
|
||||
axpby_ssp_pminus(tmp,beo[s],psi,-ceo[s],psi ,s, s+1);
|
||||
axpby_ssp_pplus(tmp,1.0,tmp,mass*ceo[s],psi,s,Ls-1);
|
||||
} else if ( s==(Ls-1)) {
|
||||
axpby_ssp_pminus(tmp,beo[s],psi,mass*ceo[s],psi,s,0);
|
||||
axpby_ssp_pplus(tmp,1.0,tmp,-ceo[s],psi,s,s-1);
|
||||
} else {
|
||||
axpby_ssp_pminus(tmp,beo[s],psi,-ceo[s],psi,s,s+1);
|
||||
axpby_ssp_pplus (tmp,1.0,tmp,-ceo[s],psi,s,s-1);
|
||||
}
|
||||
}
|
||||
// Apply 4d dslash fragment
|
||||
DhopDir(tmp,chi,dir,disp);
|
||||
}
|
||||
|
||||
void CayleyFermion5D::MooeeDag (const LatticeFermion &psi, LatticeFermion &chi)
|
||||
{
|
||||
for (int s=0;s<Ls;s++){
|
||||
|
@ -21,6 +21,10 @@ namespace Grid {
|
||||
virtual void MooeeInv (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void Instantiatable(void)=0;
|
||||
|
||||
// Efficient support for multigrid coarsening
|
||||
virtual void Mdir (const LatticeFermion &in, LatticeFermion &out,int dir,int disp);
|
||||
|
||||
// protected:
|
||||
RealD mass;
|
||||
|
||||
|
@ -90,6 +90,18 @@ namespace Grid {
|
||||
// Can ignore "dag"
|
||||
return M(psi,chi);
|
||||
}
|
||||
void ContinuedFractionFermion5D::Mdir (const LatticeFermion &psi, LatticeFermion &chi,int dir,int disp){
|
||||
DhopDir(psi,chi,dir,disp); // Dslash on diagonal. g5 Dslash is hermitian
|
||||
int sign=1;
|
||||
for(int s=0;s<Ls;s++){
|
||||
if ( s==(Ls-1) ){
|
||||
ag5xpby_ssp(chi,Beta[s]*ZoloHiInv,chi,0.0,chi,s,s);
|
||||
} else {
|
||||
ag5xpby_ssp(chi,cc[s]*Beta[s]*sign*ZoloHiInv,chi,0.0,chi,s,s);
|
||||
}
|
||||
sign=-sign;
|
||||
}
|
||||
}
|
||||
void ContinuedFractionFermion5D::Meooe (const LatticeFermion &psi, LatticeFermion &chi)
|
||||
{
|
||||
// Apply 4d dslash
|
||||
|
@ -24,6 +24,9 @@ namespace Grid {
|
||||
// virtual void Instantiatable(void)=0;
|
||||
virtual void Instantiatable(void) =0;
|
||||
|
||||
// Efficient support for multigrid coarsening
|
||||
virtual void Mdir (const LatticeFermion &in, LatticeFermion &out,int dir,int disp);
|
||||
|
||||
// Constructors
|
||||
ContinuedFractionFermion5D(LatticeGaugeField &_Umu,
|
||||
GridCartesian &FiveDimGrid,
|
||||
|
@ -40,6 +40,9 @@ namespace Grid {
|
||||
virtual void DhopOE(const FermionField &in, FermionField &out,int dag)=0;
|
||||
virtual void DhopEO(const FermionField &in, FermionField &out,int dag)=0;
|
||||
|
||||
virtual void Mdiag(const FermionField &in, FermionField &out) { Mooee(in,out);}; // Same as Mooee applied to both CB's
|
||||
virtual void Mdir (const FermionField &in, FermionField &out,int dir,int disp)=0; // case by case Wilson, Clover, Cayley, ContFrac, PartFrac
|
||||
virtual void DhopDir(const FermionField &in, FermionField &out,int dir,int disp)=0; // implemented by WilsonFermion and WilsonFermion5D
|
||||
|
||||
};
|
||||
|
||||
|
@ -2,6 +2,22 @@
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
|
||||
void PartialFractionFermion5D::Mdir (const LatticeFermion &psi, LatticeFermion &chi,int dir,int disp){
|
||||
// this does both dag and undag but is trivial; make a common helper routing
|
||||
|
||||
int sign = 1;
|
||||
|
||||
DhopDir(psi,chi,dir,disp);
|
||||
|
||||
int nblock=(Ls-1)/2;
|
||||
for(int b=0;b<nblock;b++){
|
||||
int s = 2*b;
|
||||
ag5xpby_ssp(chi,-scale,chi,0.0,chi,s,s);
|
||||
ag5xpby_ssp(chi, scale,chi,0.0,chi,s+1,s+1);
|
||||
}
|
||||
ag5xpby_ssp(chi,p[nblock]*scale/amax,chi,0.0,chi,Ls-1,Ls-1);
|
||||
|
||||
}
|
||||
void PartialFractionFermion5D::Meooe_internal(const LatticeFermion &psi, LatticeFermion &chi,int dag)
|
||||
{
|
||||
// this does both dag and undag but is trivial; make a common helper routing
|
||||
|
@ -30,6 +30,9 @@ namespace Grid {
|
||||
|
||||
virtual void Instantiatable(void) =0; // ensure no make-eee
|
||||
|
||||
// Efficient support for multigrid coarsening
|
||||
virtual void Mdir (const LatticeFermion &in, LatticeFermion &out,int dir,int disp);
|
||||
|
||||
// Constructors
|
||||
PartialFractionFermion5D(LatticeGaugeField &_Umu,
|
||||
GridCartesian &FiveDimGrid,
|
||||
|
@ -93,6 +93,26 @@ void WilsonFermion::MooeeInvDag(const LatticeFermion &in, LatticeFermion &out)
|
||||
out.checkerboard = in.checkerboard;
|
||||
MooeeInv(in,out);
|
||||
}
|
||||
void WilsonFermion::Mdir (const LatticeFermion &in, LatticeFermion &out,int dir,int disp)
|
||||
{
|
||||
DhopDir(in,out,dir,disp);
|
||||
}
|
||||
void WilsonFermion::DhopDir(const LatticeFermion &in, LatticeFermion &out,int dir,int disp){
|
||||
WilsonCompressor compressor(DaggerNo);
|
||||
Stencil.HaloExchange<vSpinColourVector,vHalfSpinColourVector,WilsonCompressor>(in,comm_buf,compressor);
|
||||
|
||||
assert( (disp==1)||(disp==-1) );
|
||||
|
||||
int skip = (disp==1) ? 0 : 1;
|
||||
|
||||
int dirdisp = dir+skip*4;
|
||||
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int sss=0;sss<in._grid->oSites();sss++){
|
||||
DiracOpt::DhopDir(Stencil,Umu,comm_buf,sss,sss,in,out,dirdisp);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void WilsonFermion::DhopInternal(CartesianStencil & st,LatticeDoubledGaugeField & U,
|
||||
const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
|
@ -26,7 +26,7 @@ namespace Grid {
|
||||
void MeooeDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
virtual void Mooee (const LatticeFermion &in, LatticeFermion &out); // remain virtual so we
|
||||
virtual void MooeeDag (const LatticeFermion &in, LatticeFermion &out); // can derive Clover
|
||||
virtual void MooeeInv (const LatticeFermion &in, LatticeFermion &out); // from Wilson bas
|
||||
virtual void MooeeInv (const LatticeFermion &in, LatticeFermion &out); // from Wilson base
|
||||
virtual void MooeeInvDag (const LatticeFermion &in, LatticeFermion &out);
|
||||
|
||||
// non-hermitian hopping term; half cb or both
|
||||
@ -34,6 +34,10 @@ namespace Grid {
|
||||
void DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
void DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
|
||||
// Multigrid assistance
|
||||
void Mdir (const LatticeFermion &in, LatticeFermion &out,int dir,int disp);
|
||||
void DhopDir(const LatticeFermion &in, LatticeFermion &out,int dir,int disp);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Extra methods added by derived
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
@ -82,6 +82,28 @@ void WilsonFermion5D::DoubleStore(LatticeDoubledGaugeField &Uds,const LatticeGau
|
||||
pokeIndex<LorentzIndex>(Uds,U,mu+4);
|
||||
}
|
||||
}
|
||||
void WilsonFermion5D::DhopDir(const LatticeFermion &in, LatticeFermion &out,int dir,int disp)
|
||||
{
|
||||
assert( (disp==1)||(disp==-1) );
|
||||
|
||||
WilsonCompressor compressor(DaggerNo);
|
||||
Stencil.HaloExchange<vSpinColourVector,vHalfSpinColourVector,WilsonCompressor>(in,comm_buf,compressor);
|
||||
|
||||
int skip = (disp==1) ? 0 : 1;
|
||||
|
||||
int dirdisp = dir+skip*4;
|
||||
|
||||
PARALLEL_FOR_LOOP
|
||||
for(int ss=0;ss<Umu._grid->oSites();ss++){
|
||||
for(int s=0;s<Ls;s++){
|
||||
int sU=ss;
|
||||
int sF = s+Ls*sU;
|
||||
DiracOpt::DhopDir(Stencil,Umu,comm_buf,sF,sU,in,out,dirdisp);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void WilsonFermion5D::DhopInternal(CartesianStencil & st, LebesgueOrder &lo,
|
||||
LatticeDoubledGaugeField & U,
|
||||
const LatticeFermion &in, LatticeFermion &out,int dag)
|
||||
|
@ -57,6 +57,10 @@ namespace Grid {
|
||||
void DhopOE(const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
void DhopEO(const LatticeFermion &in, LatticeFermion &out,int dag);
|
||||
|
||||
// add a DhopComm
|
||||
// -- suboptimal interface will presently trigger multiple comms.
|
||||
void DhopDir(const LatticeFermion &in, LatticeFermion &out,int dir,int disp);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// New methods added
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
@ -13,7 +13,6 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
vHalfSpinColourVector Uchi;
|
||||
int offset,local,perm, ptype;
|
||||
|
||||
//#define VERBOSE( A) if ( ss<10 ) { std::cout << "site " <<ss << " " #A " neigh " << offset << " perm "<< perm <<std::endl;}
|
||||
|
||||
// Xp
|
||||
int ss = sF;
|
||||
@ -33,12 +32,6 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
mult(&Uchi(),&U._odata[sU](Xp),&chi());
|
||||
spReconXp(result,Uchi);
|
||||
|
||||
// std::cout << "XP_RECON"<<std::endl;
|
||||
// std::cout << result()(0)(0) <<" "<<result()(0)(1) <<" "<<result()(0)(2) <<std::endl;
|
||||
// std::cout << result()(1)(0) <<" "<<result()(1)(1) <<" "<<result()(1)(2) <<std::endl;
|
||||
// std::cout << result()(2)(0) <<" "<<result()(2)(1) <<" "<<result()(2)(2) <<std::endl;
|
||||
// std::cout << result()(3)(0) <<" "<<result()(3)(1) <<" "<<result()(3)(2) <<std::endl;
|
||||
|
||||
// Yp
|
||||
offset = st._offsets [Yp][ss];
|
||||
local = st._is_local[Yp][ss];
|
||||
@ -93,8 +86,7 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
perm = st._permute[Xm][ss];
|
||||
ptype = st._permute_type[Xm];
|
||||
|
||||
if ( local && perm )
|
||||
{
|
||||
if ( local && perm ) {
|
||||
spProjXm(tmp,in._odata[offset]);
|
||||
permute(chi,tmp,ptype);
|
||||
} else if ( local ) {
|
||||
@ -104,12 +96,6 @@ void DiracOpt::DhopSite(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
}
|
||||
mult(&Uchi(),&U._odata[sU](Xm),&chi());
|
||||
accumReconXm(result,Uchi);
|
||||
// std::cout << "XM_RECON_ACCUM"<<std::endl;
|
||||
// std::cout << result()(0)(0) <<" "<<result()(0)(1) <<" "<<result()(0)(2) <<std::endl;
|
||||
// std::cout << result()(1)(0) <<" "<<result()(1)(1) <<" "<<result()(1)(2) <<std::endl;
|
||||
// std::cout << result()(2)(0) <<" "<<result()(2)(1) <<" "<<result()(2)(2) <<std::endl;
|
||||
// std::cout << result()(3)(0) <<" "<<result()(3)(1) <<" "<<result()(3)(2) <<std::endl;
|
||||
|
||||
|
||||
// Ym
|
||||
offset = st._offsets [Ym][ss];
|
||||
@ -308,4 +294,136 @@ void DiracOpt::DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
|
||||
vstream(out._odata[ss],result*(-0.5));
|
||||
}
|
||||
|
||||
void DiracOpt::DhopDir(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int sF,int sU,const LatticeFermion &in, LatticeFermion &out,int dirdisp)
|
||||
{
|
||||
vHalfSpinColourVector tmp;
|
||||
vHalfSpinColourVector chi;
|
||||
vSpinColourVector result;
|
||||
vHalfSpinColourVector Uchi;
|
||||
int offset,local,perm, ptype;
|
||||
int ss=sF;
|
||||
|
||||
offset = st._offsets [dirdisp][ss];
|
||||
local = st._is_local[dirdisp][ss];
|
||||
perm = st._permute[dirdisp][ss];
|
||||
ptype = st._permute_type[dirdisp];
|
||||
|
||||
// Xp
|
||||
if(dirdisp==Xp){
|
||||
if ( local && perm ) {
|
||||
spProjXp(tmp,in._odata[offset]);
|
||||
permute(chi,tmp,ptype);
|
||||
} else if ( local ) {
|
||||
spProjXp(chi,in._odata[offset]);
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[sU](Xp),&chi());
|
||||
spReconXp(result,Uchi);
|
||||
}
|
||||
|
||||
// Yp
|
||||
if ( dirdisp==Yp ){
|
||||
if ( local && perm ) {
|
||||
spProjYp(tmp,in._odata[offset]);
|
||||
permute(chi,tmp,ptype);
|
||||
} else if ( local ) {
|
||||
spProjYp(chi,in._odata[offset]);
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[sU](Yp),&chi());
|
||||
spReconYp(result,Uchi);
|
||||
}
|
||||
|
||||
// Zp
|
||||
if ( dirdisp ==Zp ){
|
||||
if ( local && perm ) {
|
||||
spProjZp(tmp,in._odata[offset]);
|
||||
permute(chi,tmp,ptype);
|
||||
} else if ( local ) {
|
||||
spProjZp(chi,in._odata[offset]);
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[sU](Zp),&chi());
|
||||
spReconZp(result,Uchi);
|
||||
}
|
||||
|
||||
// Tp
|
||||
if ( dirdisp ==Tp ){
|
||||
if ( local && perm ) {
|
||||
spProjTp(tmp,in._odata[offset]);
|
||||
permute(chi,tmp,ptype);
|
||||
} else if ( local ) {
|
||||
spProjTp(chi,in._odata[offset]);
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[sU](Tp),&chi());
|
||||
spReconTp(result,Uchi);
|
||||
}
|
||||
|
||||
// Xm
|
||||
if ( dirdisp==Xm ){
|
||||
if ( local && perm ) {
|
||||
spProjXm(tmp,in._odata[offset]);
|
||||
permute(chi,tmp,ptype);
|
||||
} else if ( local ) {
|
||||
spProjXm(chi,in._odata[offset]);
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[sU](Xm),&chi());
|
||||
spReconXm(result,Uchi);
|
||||
}
|
||||
|
||||
// Ym
|
||||
if ( dirdisp == Ym ){
|
||||
if ( local && perm ) {
|
||||
spProjYm(tmp,in._odata[offset]);
|
||||
permute(chi,tmp,ptype);
|
||||
} else if ( local ) {
|
||||
spProjYm(chi,in._odata[offset]);
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[sU](Ym),&chi());
|
||||
spReconYm(result,Uchi);
|
||||
}
|
||||
|
||||
// Zm
|
||||
if ( dirdisp == Zm ){
|
||||
if ( local && perm ) {
|
||||
spProjZm(tmp,in._odata[offset]);
|
||||
permute(chi,tmp,ptype);
|
||||
} else if ( local ) {
|
||||
spProjZm(chi,in._odata[offset]);
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[sU](Zm),&chi());
|
||||
spReconZm(result,Uchi);
|
||||
}
|
||||
|
||||
// Tm
|
||||
if ( dirdisp==Tm ) {
|
||||
if ( local && perm ) {
|
||||
spProjTm(tmp,in._odata[offset]);
|
||||
permute(chi,tmp,ptype);
|
||||
} else if ( local ) {
|
||||
spProjTm(chi,in._odata[offset]);
|
||||
} else {
|
||||
chi=buf[offset];
|
||||
}
|
||||
mult(&Uchi(),&U._odata[sU](Tm),&chi());
|
||||
spReconTm(result,Uchi);
|
||||
}
|
||||
|
||||
vstream(out._odata[ss],result*(-0.5));
|
||||
}
|
||||
|
||||
}}
|
||||
|
@ -20,6 +20,9 @@ namespace Grid {
|
||||
static void DhopSiteDag(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int sF,int sU,const LatticeFermion &in, LatticeFermion &out);
|
||||
static void DhopDir(CartesianStencil &st,LatticeDoubledGaugeField &U,
|
||||
std::vector<vHalfSpinColourVector,alignedAllocator<vHalfSpinColourVector> > &buf,
|
||||
int sF,int sU,const LatticeFermion &in, LatticeFermion &out,int dirdisp);
|
||||
|
||||
};
|
||||
|
||||
|
@ -11,11 +11,22 @@ class Gamma5HermitianLinearOperator : public LinearOperatorBase<Field> {
|
||||
public:
|
||||
Gamma5HermitianLinearOperator(Matrix &Mat): _Mat(Mat){};
|
||||
void Op (const Field &in, Field &out){
|
||||
_Mat.M(in,out);
|
||||
HermOp(in,out);
|
||||
}
|
||||
void AdjOp (const Field &in, Field &out){
|
||||
_Mat.M(in,out);
|
||||
HermOp(in,out);
|
||||
}
|
||||
void OpDiag (const Field &in, Field &out) {
|
||||
Field tmp(in._grid);
|
||||
_Mat.Mdiag(in,tmp);
|
||||
G5R5(out,tmp);
|
||||
}
|
||||
void OpDir (const Field &in, Field &out,int dir,int disp) {
|
||||
Field tmp(in._grid);
|
||||
_Mat.Mdir(in,tmp,dir,disp);
|
||||
G5R5(out,tmp);
|
||||
}
|
||||
|
||||
void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){
|
||||
|
||||
HermOp(in,out);
|
||||
|
Reference in New Issue
Block a user