1
0
mirror of https://github.com/paboyle/Grid.git synced 2025-04-24 12:45:56 +01:00

Inner mixed tolerance

This commit is contained in:
Quadro 2021-06-08 21:17:06 -04:00
parent 216c178c16
commit f68036c79f

View File

@ -28,6 +28,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
#pragma once #pragma once
#include <Grid/qcd/utils/MixedPrecisionOperatorFunction.h> #include <Grid/qcd/utils/MixedPrecisionOperatorFunction.h>
#include <Grid/qcd/action/momentum/Domains.h>
NAMESPACE_BEGIN(Grid); NAMESPACE_BEGIN(Grid);
@ -112,16 +113,19 @@ public:
Integer maxinnerit; Integer maxinnerit;
Integer maxouterit; Integer maxouterit;
RealD tol; RealD tol;
RealD tolinner;
Coordinate Block; Coordinate Block;
Coordinate InnerBlock;
DomainDecomposition Domains;
SchurFactoredFermionOperator(FermionOperator<ImplD> & _PeriodicFermOpD, SchurFactoredFermionOperator(FermionOperator<ImplD> & _PeriodicFermOpD,
FermionOperator<ImplF> & _PeriodicFermOpF, FermionOperator<ImplF> & _PeriodicFermOpF,
FermionOperator<ImplD> & _DirichletFermOpD, FermionOperator<ImplD> & _DirichletFermOpD,
FermionOperator<ImplF> & _DirichletFermOpF, FermionOperator<ImplF> & _DirichletFermOpF,
Coordinate &_Block) Coordinate &_Block)
: Block(_Block), : Domains(Block),
PeriodicFermOpD(_PeriodicFermOpD), PeriodicFermOpD(_PeriodicFermOpD),
PeriodicFermOpF(_PeriodicFermOpF), PeriodicFermOpF(_PeriodicFermOpF),
DirichletFermOpD(_DirichletFermOpD), DirichletFermOpD(_DirichletFermOpD),
@ -135,8 +139,8 @@ public:
PeriodicLinOpDagD(PeriodicFermOpD), PeriodicLinOpDagD(PeriodicFermOpD),
PeriodicLinOpDagF(PeriodicFermOpF) PeriodicLinOpDagF(PeriodicFermOpF)
{ {
InnerBlock = Coordinate({16,16,16,20});
tol=1.0e-10; tol=1.0e-10;
tolinner=1.0e-6;
maxinnerit=1000; maxinnerit=1000;
maxouterit=10; maxouterit=10;
assert(PeriodicFermOpD.FermionGrid() == DirichletFermOpD.FermionGrid()); assert(PeriodicFermOpD.FermionGrid() == DirichletFermOpD.FermionGrid());
@ -147,10 +151,17 @@ public:
void ImportGauge(const GaugeField &Umu) void ImportGauge(const GaugeField &Umu)
{ {
PeriodicFermOpD.ImportGauge(Umu);
DirichletFermOpD.ImportGauge(Umu);
// Single precision will update in the mixed prec CG // Single precision will update in the mixed prec CG
PeriodicFermOpD.ImportGauge(Umu);
GaugeField dUmu(Umu.Grid());
dUmu=Umu;
// DirchletBCs(dUmu);
DirichletFilter<GaugeField> Filter(Block);
Filter.applyFilter(dUmu);
DirichletFermOpD.ImportGauge(dUmu);
} }
/*
void ProjectBoundaryBothDomains (FermionField &f,int sgn) void ProjectBoundaryBothDomains (FermionField &f,int sgn)
{ {
assert((sgn==1)||(sgn==-1)); assert((sgn==1)||(sgn==-1));
@ -170,7 +181,6 @@ public:
LatticeInteger zero(grid); zero = 0; LatticeInteger zero(grid); zero = 0;
LatticeInteger nface(grid); nface=Zero(); LatticeInteger nface(grid); nface=Zero();
ComplexField zz(grid); zz=Zero();
FermionField projected(grid); projected=Zero(); FermionField projected(grid); projected=Zero();
FermionField sp_proj (grid); FermionField sp_proj (grid);
@ -210,8 +220,88 @@ public:
projected = where(nface>Integer(1),f,projected); projected = where(nface>Integer(1),f,projected);
f=projected; f=projected;
} }
*/
void ProjectBoundaryBothDomains (FermionField &f,int sgn)
{
assert((sgn==1)||(sgn==-1));
Real rsgn = sgn;
Gamma::Algebra Gmu [] = {
Gamma::Algebra::GammaX,
Gamma::Algebra::GammaY,
Gamma::Algebra::GammaZ,
Gamma::Algebra::GammaT
};
GridBase *grid = f.Grid();
LatticeInteger coor(grid);
LatticeInteger face(grid);
LatticeInteger one(grid); one = 1;
LatticeInteger zero(grid); zero = 0;
LatticeInteger omega(grid);
LatticeInteger omegabar(grid);
LatticeInteger tmp(grid);
omega=one; Domains.ProjectDomain(omega,0);
omegabar=one; Domains.ProjectDomain(omegabar,1);
LatticeInteger nface(grid); nface=Zero();
FermionField projected(grid); projected=Zero();
FermionField sp_proj (grid);
int dims = grid->Nd();
int isDWF= (dims==Nd+1);
assert((dims==Nd)||(dims==Nd+1));
Coordinate Global=grid->GlobalDimensions();
for(int mmu=0;mmu<Nd;mmu++){
Gamma G(Gmu[mmu]);
// need to worry about DWF 5th dim first
int mu = mmu+isDWF;
if ( Block[mmu] && (Block[mmu] <= Global[mu]) ) {
// Lower face receives (1-gamma)/2 in normal forward hopping term
tmp = Cshift(omegabar,mu,-1);
tmp = tmp + omega;
face = where(tmp == Integer(2),one,zero );
tmp = Cshift(omega,mu,-1);
tmp = tmp + omegabar;
face = where(tmp == Integer(2),one,face );
nface = nface + face;
sp_proj = 0.5*(f-G*f*rsgn);
projected= where(face,sp_proj,projected);
// Upper face receives (1+gamma)/2 in normal backward hopping term
tmp = Cshift(omegabar,mu,1);
tmp = tmp + omega;
face = where(tmp == Integer(2),one,zero );
tmp = Cshift(omega,mu,1);
tmp = tmp + omegabar;
face = where(tmp == Integer(2),one,face );
nface = nface + face;
sp_proj = 0.5*(f+G*f*rsgn);
projected= where(face,sp_proj,projected);
}
}
// Initial Zero() where nface==0.
// Keep the spin projected faces where nface==1
// Full spinor where nface>=2
projected = where(nface>Integer(1),f,projected);
f=projected;
}
void ProjectDomain(FermionField &f,int domain) void ProjectDomain(FermionField &f,int domain)
{ {
/*
GridBase *grid = f.Grid(); GridBase *grid = f.Grid();
int dims = grid->Nd(); int dims = grid->Nd();
int isDWF= (dims==Nd+1); int isDWF= (dims==Nd+1);
@ -225,6 +315,9 @@ public:
domaincb = domaincb + div(coor,Block[d]); domaincb = domaincb + div(coor,Block[d]);
} }
f = where(mod(domaincb,2)==Integer(domain),f,zz); f = where(mod(domaincb,2)==Integer(domain),f,zz);
*/
Domains.ProjectDomain(f,domain);
}; };
void ProjectOmegaBar (FermionField &f) {ProjectDomain(f,OmegaBar);} void ProjectOmegaBar (FermionField &f) {ProjectDomain(f,OmegaBar);}
void ProjectOmega (FermionField &f) {ProjectDomain(f,Omega);} void ProjectOmega (FermionField &f) {ProjectDomain(f,Omega);}
@ -331,6 +424,7 @@ public:
void dOmegaInvAndOmegaBarInv(FermionField &in,FermionField &out) void dOmegaInvAndOmegaBarInv(FermionField &in,FermionField &out)
{ {
MxPCG OmegaSolver(tol, MxPCG OmegaSolver(tol,
tolinner,
maxinnerit, maxinnerit,
maxouterit, maxouterit,
DirichletFermOpF.FermionRedBlackGrid(), DirichletFermOpF.FermionRedBlackGrid(),
@ -344,6 +438,7 @@ public:
void dOmegaDagInvAndOmegaBarDagInv(FermionField &in,FermionField &out) void dOmegaDagInvAndOmegaBarDagInv(FermionField &in,FermionField &out)
{ {
MxDagPCG OmegaDagSolver(tol, MxDagPCG OmegaDagSolver(tol,
tolinner,
maxinnerit, maxinnerit,
maxouterit, maxouterit,
DirichletFermOpF.FermionRedBlackGrid(), DirichletFermOpF.FermionRedBlackGrid(),
@ -408,6 +503,7 @@ public:
void Dinverse(FermionField &in,FermionField &out) void Dinverse(FermionField &in,FermionField &out)
{ {
MxPCG DSolver(tol, MxPCG DSolver(tol,
tolinner,
maxinnerit, maxinnerit,
maxouterit, maxouterit,
PeriodicFermOpF.FermionRedBlackGrid(), PeriodicFermOpF.FermionRedBlackGrid(),
@ -421,6 +517,7 @@ public:
void DinverseDag(FermionField &in,FermionField &out) void DinverseDag(FermionField &in,FermionField &out)
{ {
MxDagPCG DdagSolver(tol, MxDagPCG DdagSolver(tol,
tolinner,
maxinnerit, maxinnerit,
maxouterit, maxouterit,
PeriodicFermOpF.FermionRedBlackGrid(), PeriodicFermOpF.FermionRedBlackGrid(),