1
0
mirror of https://github.com/paboyle/Grid.git synced 2025-06-14 13:57:07 +01:00

Merge branch 'develop' into feature/gparity_HMC

This commit is contained in:
Christopher Kelly
2021-03-22 15:33:13 -04:00
64 changed files with 2350 additions and 1183 deletions

View File

@ -40,9 +40,9 @@ int main (int argc, char ** argv)
int N=16;
std::vector<int> latt_size ({N,4,4});
std::vector<int> simd_layout({vComplexD::Nsimd(),1,1});
std::vector<int> mpi_layout ({1,1,1});
std::vector<int> latt_size ({N,N,N,N});
std::vector<int> simd_layout({vComplexD::Nsimd(),1,1,1});
std::vector<int> mpi_layout ({1,1,1,1});
int vol = 1;
int nd = latt_size.size();
@ -69,7 +69,7 @@ int main (int argc, char ** argv)
for(int t=0;t<latt_size[mu];t++){
LatticeCoordinate(coor,mu);
sl=where(coor==Integer(t),rn,zz);
std::cout <<GridLogMessage<< " sl " << sl<<std::endl;
// std::cout <<GridLogMessage<< " sl " << sl<<std::endl;
std::cout <<GridLogMessage<<" slice "<<t<<" " << norm2(sl)<<std::endl;
ns=ns+norm2(sl);
}

View File

@ -0,0 +1,143 @@
/*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid
Source file: ./tests/Test_poisson_fft.cc
Copyright (C) 2015
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
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 */
#include <Grid/Grid.h>
using namespace Grid;
;
int main (int argc, char ** argv)
{
Grid_init(&argc,&argv);
int threads = GridThread::GetThreads();
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
int N=16;
std::vector<int> latt_size ({N,4,4});
std::vector<int> simd_layout({vComplexD::Nsimd(),1,1});
std::vector<int> mpi_layout ({1,1,1});
int vol = 1;
int nd = latt_size.size();
for(int d=0;d<nd;d++){
vol = vol * latt_size[d];
}
GridCartesian GRID(latt_size,simd_layout,mpi_layout);
GridParallelRNG RNG(&GRID);
RNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
std::cout<<GridLogMessage<<"=============================================================="<<std::endl;
std::cout<<GridLogMessage<<"== LatticeComplex =="<<std::endl;
std::cout<<GridLogMessage<<"=============================================================="<<std::endl;
{
LatticeComplexD zz(&GRID);
LatticeInteger coor(&GRID);
LatticeComplexD rn(&GRID);
LatticeComplexD sl(&GRID);
zz = ComplexD(0.0,0.0);
gaussian(RNG,rn);
RealD nn=norm2(rn);
for(int mu=0;mu<nd;mu++){
RealD ns=0.0;
for(int t=0;t<latt_size[mu];t++){
LatticeCoordinate(coor,mu);
sl=where(coor==Integer(t),rn,zz);
std::cout <<GridLogMessage<<" slice "<<t<<" " << norm2(sl)<<std::endl;
ns=ns+norm2(sl);
}
std::cout <<GridLogMessage <<" sliceNorm" <<mu<<" "<< nn <<" "<<ns<<" err " << nn-ns<<std::endl;
assert(abs(nn-ns) < 1.0e-10);
}
}
std::cout<<GridLogMessage<<"=============================================================="<<std::endl;
std::cout<<GridLogMessage<<"== LatticeFermion =="<<std::endl;
std::cout<<GridLogMessage<<"=============================================================="<<std::endl;
{
LatticeFermionD zz(&GRID);
LatticeInteger coor(&GRID);
LatticeFermionD rn(&GRID);
LatticeFermionD sl(&GRID);
zz = ComplexD(0.0,0.0);
gaussian(RNG,rn);
RealD nn=norm2(rn);
for(int mu=0;mu<nd;mu++){
RealD ns=0.0;
for(int t=0;t<latt_size[mu];t++){
LatticeCoordinate(coor,mu);
sl=where(coor==Integer(t),rn,zz);
std::cout <<GridLogMessage<<" slice "<<t<<" " << norm2(sl)<<std::endl;
ns=ns+norm2(sl);
}
std::cout <<GridLogMessage <<" sliceNorm" <<mu<<" "<< nn <<" "<<ns<<" err " << nn-ns<<std::endl;
assert(abs(nn-ns) < 1.0e-10);
}
}
std::cout<<GridLogMessage<<"=============================================================="<<std::endl;
std::cout<<GridLogMessage<<"== LatticePropagator =="<<std::endl;
std::cout<<GridLogMessage<<"=============================================================="<<std::endl;
{
LatticePropagatorD zz(&GRID);
LatticeInteger coor(&GRID);
LatticePropagatorD rn(&GRID);
LatticePropagatorD sl(&GRID);
zz = ComplexD(0.0,0.0);
gaussian(RNG,rn);
RealD nn=norm2(rn);
for(int mu=0;mu<nd;mu++){
RealD ns=0.0;
for(int t=0;t<latt_size[mu];t++){
LatticeCoordinate(coor,mu);
sl=where(coor==Integer(t),rn,zz);
std::cout <<GridLogMessage<<" slice "<<t<<" " << norm2(sl)<<std::endl;
ns=ns+norm2(sl);
}
std::cout <<GridLogMessage <<" sliceNorm" <<mu<<" "<< nn <<" "<<ns<<" err " << nn-ns<<std::endl;
assert(abs(nn-ns) < 1.0e-10);
}
}
Grid_finalize();
}

View File

@ -33,13 +33,14 @@ using namespace Grid;
template<class What>
void TestConserved(What & Ddwf, What & Ddwfrev,
void TestConserved(What & Ddwf,
LatticeGaugeField &Umu,
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
RealD mass, RealD M5,
GridParallelRNG *RNG4,
GridParallelRNG *RNG5);
GridParallelRNG *RNG5,
What *Ddwfrev=nullptr);
Gamma::Algebra Gmu [] = {
Gamma::Algebra::GammaX,
@ -102,10 +103,11 @@ int main (int argc, char ** argv)
GridRedBlackCartesian * FrbGridF = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGridF);
std::vector<int> seeds4({1,2,3,4});
std::vector<int> seeds5({5,6,7,8});
GridParallelRNG RNG5(FGrid); RNG5.SeedFixedIntegers(seeds5);
GridParallelRNG RNG4(UGrid); RNG4.SeedFixedIntegers(seeds4);
GridParallelRNG RNG4(UGrid);
std::vector<int> seeds4({1,2,3,4}); RNG4.SeedFixedIntegers(seeds4);
//const std::string seeds4{ "test-gauge-3000" }; RNG4.SeedUniqueString( seeds4 );
LatticeGaugeField Umu(UGrid);
if( argc > 1 && argv[1][0] != '-' )
@ -116,8 +118,8 @@ int main (int argc, char ** argv)
}
else
{
std::cout<<GridLogMessage <<"Using cold configuration"<<std::endl;
//SU<Nc>::ColdConfiguration(Umu);
std::cout<<GridLogMessage <<"Using hot configuration"<<std::endl;
// SU<Nc>::ColdConfiguration(Umu);
SU<Nc>::HotConfiguration(RNG4,Umu);
}
@ -127,7 +129,7 @@ int main (int argc, char ** argv)
std::cout<<GridLogMessage <<"DomainWallFermion test"<<std::endl;
std::cout<<GridLogMessage <<"======================"<<std::endl;
DomainWallFermionR Ddwf(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
TestConserved<DomainWallFermionR>(Ddwf,Ddwf,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
TestConserved<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;
@ -137,13 +139,13 @@ int main (int argc, char ** argv)
std::cout<<GridLogMessage <<"MobiusFermion test"<<std::endl;
std::cout<<GridLogMessage <<"======================"<<std::endl;
MobiusFermionR Dmob(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,b,c);
TestConserved<MobiusFermionR>(Dmob,Dmob,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
TestConserved<MobiusFermionR>(Dmob,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);
TestConserved<ScaledShamirFermionR>(Dsham,Dsham,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
TestConserved<ScaledShamirFermionR>(Dsham,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
std::cout<<GridLogMessage <<"======================"<<std::endl;
std::cout<<GridLogMessage <<"ZMobiusFermion test"<<std::endl;
@ -152,8 +154,7 @@ int main (int argc, char ** argv)
// for(int s=0;s<Ls;s++) omegasrev[s]=omegas[Ls-1-s];
ZMobiusFermionR ZDmob(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,omegas,b,c);
ZMobiusFermionR ZDmobrev(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,omegasrev,b,c);
TestConserved<ZMobiusFermionR>(ZDmob,ZDmobrev,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5);
TestConserved<ZMobiusFermionR>(ZDmob,Umu,FGrid,FrbGrid,UGrid,UrbGrid,mass,M5,&RNG4,&RNG5,&ZDmobrev);
Grid_finalize();
}
@ -161,22 +162,17 @@ int main (int argc, char ** argv)
template<class Action>
void TestConserved(Action & Ddwf,
Action & Ddwfrev,
void TestConserved(Action & Ddwf,
LatticeGaugeField &Umu,
GridCartesian * FGrid, GridRedBlackCartesian * FrbGrid,
GridCartesian * UGrid, GridRedBlackCartesian * UrbGrid,
RealD mass, RealD M5,
GridParallelRNG *RNG4,
GridParallelRNG *RNG5)
GridParallelRNG *RNG5,
Action * Ddwfrev)
{
int Ls=Ddwf.Ls;
LatticePropagator phys_src(UGrid);
std::vector<LatticeColourMatrix> U(4,UGrid);
LatticePropagator seqsrc(FGrid);
LatticePropagator phys_src(UGrid);
LatticePropagator seqsrc(FGrid);
LatticePropagator prop5(FGrid);
LatticePropagator prop5rev(FGrid);
LatticePropagator prop4(UGrid);
@ -194,9 +190,9 @@ void TestConserved(Action & Ddwf,
phys_src=Zero();
pokeSite(kronecker,phys_src,coor);
MdagMLinearOperator<Action,LatticeFermion> HermOp(Ddwf);
MdagMLinearOperator<Action,LatticeFermion> HermOprev(Ddwfrev);
ConjugateGradient<LatticeFermion> CG(1.0e-16,100000);
SchurRedBlackDiagTwoSolve<LatticeFermion> schur(CG);
ZeroGuesser<LatticeFermion> zpg;
for(int s=0;s<Nd;s++){
for(int c=0;c<Nc;c++){
LatticeFermion src4 (UGrid);
@ -206,20 +202,20 @@ void TestConserved(Action & Ddwf,
Ddwf.ImportPhysicalFermionSource(src4,src5);
LatticeFermion result5(FGrid); result5=Zero();
// CGNE
LatticeFermion Mdagsrc5 (FGrid);
Ddwf.Mdag(src5,Mdagsrc5);
CG(HermOp,Mdagsrc5,result5);
schur(Ddwf,src5,result5,zpg);
std::cout<<GridLogMessage<<"spin "<<s<<" color "<<c<<" norm2(sourc5d) "<<norm2(src5)
<<" norm2(result5d) "<<norm2(result5)<<std::endl;
FermToProp<Action>(prop5,result5,s,c);
LatticeFermion result4(UGrid);
Ddwf.ExportPhysicalFermionSolution(result5,result4);
FermToProp<Action>(prop4,result4,s,c);
Ddwfrev.ImportPhysicalFermionSource(src4,src5);
Ddwfrev.Mdag(src5,Mdagsrc5);
CG(HermOprev,Mdagsrc5,result5);
if( Ddwfrev ) {
Ddwfrev->ImportPhysicalFermionSource(src4,src5);
result5 = Zero();
schur(*Ddwfrev,src5,result5,zpg);
}
FermToProp<Action>(prop5rev,result5,s,c);
}
}
@ -251,11 +247,7 @@ void TestConserved(Action & Ddwf,
PropToFerm<Action>(src5,seqsrc,s,c);
LatticeFermion result5(FGrid); result5=Zero();
// CGNE
LatticeFermion Mdagsrc5 (FGrid);
Ddwf.Mdag(src5,Mdagsrc5);
CG(HermOp,Mdagsrc5,result5);
schur(Ddwf,src5,result5,zpg);
LatticeFermion result4(UGrid);
Ddwf.ExportPhysicalFermionSolution(result5,result4);
@ -276,10 +268,10 @@ void TestConserved(Action & Ddwf,
Ddwf.ContractConservedCurrent(prop5rev,prop5,Vector_mu,phys_src,Current::Vector,Tdir);
Ddwf.ContractJ5q(prop5,PJ5q);
PA = trace(g5*Axial_mu);
SV = trace(Vector_mu);
VV = trace(gT*Vector_mu);
PP = trace(adj(prop4)*prop4);
PA = trace(g5*Axial_mu); // Pseudoscalar-Axial conserved current
SV = trace(Vector_mu); // Scalar-Vector conserved current
VV = trace(gT*Vector_mu); // (local) Vector-Vector conserved current
PP = trace(adj(prop4)*prop4); // Pseudoscalar density
// Spatial sum
sliceSum(PA,sumPA,Tdir);
@ -288,15 +280,17 @@ void TestConserved(Action & Ddwf,
sliceSum(PP,sumPP,Tdir);
sliceSum(PJ5q,sumPJ5q,Tdir);
int Nt=sumPA.size();
const int Nt{static_cast<int>(sumPA.size())};
std::cout<<GridLogMessage<<"Vector Ward identity by timeslice (~ 0)"<<std::endl;
for(int t=0;t<Nt;t++){
std::cout <<" SV "<<real(TensorRemove(sumSV[t]));
std::cout <<" VV "<<real(TensorRemove(sumVV[t]))<<std::endl;
std::cout<<GridLogMessage <<" t "<<t<<" SV "<<real(TensorRemove(sumSV[t]))<<" VV "<<real(TensorRemove(sumVV[t]))<<std::endl;
}
std::cout<<GridLogMessage<<"Axial Ward identity by timeslice (defect ~ 0)"<<std::endl;
for(int t=0;t<Nt;t++){
std::cout <<" PAc "<<real(TensorRemove(sumPA[t]));
std::cout <<" PJ5q "<<real(TensorRemove(sumPJ5q[t]));
std::cout <<" Ward Identity defect " <<real(TensorRemove(sumPA[t]-sumPA[(t-1+Nt)%Nt] - 2.0*(Ddwf.mass*sumPP[t] + sumPJ5q[t]) ))<<"\n";
const RealD DmuPAmu{real(TensorRemove(sumPA[t]-sumPA[(t-1+Nt)%Nt]))};
std::cout<<GridLogMessage<<" t "<<t<<" DmuPAmu "<<DmuPAmu
<<" PP "<<real(TensorRemove(sumPP[t]))<<" PJ5q "<<real(TensorRemove(sumPJ5q[t]))
<<" Ward Identity defect " <<(DmuPAmu - 2.*real(TensorRemove(Ddwf.mass*sumPP[t] + sumPJ5q[t])))<<std::endl;
}
///////////////////////////////

View File

@ -86,7 +86,9 @@ int main (int argc, char** argv)
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, CG, CG, CG, CG, Params, true);
Meofa.refresh(U, RNG5);
GridSerialRNG sRNG; sRNG.SeedFixedIntegers(seeds4);
Meofa.refresh(U, sRNG, RNG5 );
RealD S = Meofa.S(U); // pdag M p
// get the deriv of phidag M phi with respect to "U"

View File

@ -84,6 +84,13 @@ int main (int argc, char ** argv)
GparityDomainWallFermionR::ImplParams params;
params.twists = twists;
/*
params.boundary_phases[0] = 1.0;
params.boundary_phases[1] = 1.0;
params.boundary_phases[2] = 1.0;
params.boundary_phases[3] =- 1.0;
*/
GparityDomainWallFermionR Dw(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,params);
Dw.M (phi,Mphi);
@ -96,6 +103,16 @@ int main (int argc, char ** argv)
Dw.MDeriv(tmp , Mphi, phi,DaggerNo ); UdSdU=tmp;
Dw.MDeriv(tmp , phi, Mphi,DaggerYes ); UdSdU=(UdSdU+tmp);
// *****************************************************************************************
// *** There is a funny negative sign in all derivatives. This is - UdSdU. ***
// *** ***
// *** Deriv in both Wilson gauge action and the TwoFlavour.h seems to miss a minus sign ***
// *** UdSdU is negated relative to what I think - call what is returned mUdSdU, ***
// *** and insert minus sign ***
// *****************************************************************************************
UdSdU = - UdSdU ; // Follow sign convention of actions in Grid. Seems crazy.
FermionField Ftmp (FGrid);
@ -106,7 +123,7 @@ int main (int argc, char ** argv)
RealD Hmom = 0.0;
RealD Hmomprime = 0.0;
LatticeColourMatrix mommu(UGrid);
LatticeColourMatrix forcemu(UGrid);
LatticeColourMatrix mUdSdUmu(UGrid);
LatticeGaugeField mom(UGrid);
LatticeGaugeField Uprime(UGrid);
@ -114,10 +131,20 @@ int main (int argc, char ** argv)
SU<Nc>::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
Hmom -= real(sum(trace(mommu*mommu)));
// Momentum Hamiltonian is - trace(p^2)/HMC_MOM_DENOMINATOR
//
// Integrator.h: RealD H = - FieldImplementation::FieldSquareNorm(P)/HMC_MOMENTUM_DENOMINATOR; // - trace (P*P)/denom // GaugeImplTypes.h: Hloc += trace(Pmu * Pmu);
// Sign comes from a sneaky multiply by "i" in GaussianFundemantalLie algebra
// P is i P^a_\mu T^a, not Pa Ta
//
// Integrator.h: H = Hmom + sum S(action)
Hmom -= real(sum(trace(mommu*mommu)))/ HMC_MOMENTUM_DENOMINATOR;
PokeIndex<LorentzIndex>(mom,mommu,mu);
// -- Drops factor of "i" in the U update: U' = e^{P dt} U [ _not_ e^{iPdt}U ]. P is anti hermitian already
// -- Udot = p U
// fourth order exponential approx
autoView( mom_v, mom, CpuRead);
autoView( U_v , U, CpuRead);
@ -134,8 +161,8 @@ int main (int argc, char ** argv)
;
});
}
std::cout << GridLogMessage <<"Initial mom hamiltonian is "<< Hmom <<std::endl;
Dw.ImportGauge(Uprime);
Dw.M (phi,MphiPrime);
@ -145,53 +172,60 @@ int main (int argc, char ** argv)
// Use derivative to estimate dS
//////////////////////////////////////////////
for(int mu=0;mu<Nd;mu++){
std::cout << "" <<std::endl;
mommu = PeekIndex<LorentzIndex>(mom,mu);
std::cout << GridLogMessage<< " Mommu " << norm2(mommu)<<std::endl;
mommu = mommu+adj(mommu);
std::cout << GridLogMessage<< " Mommu + Mommudag " << norm2(mommu)<<std::endl;
mommu = PeekIndex<LorentzIndex>(UdSdU,mu);
std::cout << GridLogMessage<< " dsdumu " << norm2(mommu)<<std::endl;
mommu = mommu+adj(mommu);
std::cout << GridLogMessage<< " dsdumu + dag " << norm2(mommu)<<std::endl;
}
//
// Ta has 1/2([ F - adj(F) ])_traceless and want the UdSdU _and_ UdagdSdUdag terms so 2x.
//
LatticeComplex dS(UGrid); dS = Zero();
LatticeComplex dSmom(UGrid); dSmom = Zero();
LatticeComplex dSmom2(UGrid); dSmom2 = Zero();
for(int mu=0;mu<Nd;mu++){
mommu = PeekIndex<LorentzIndex>(UdSdU,mu);
mommu=Ta(mommu)*2.0;
mommu=Ta(mommu); // projectForce , GaugeImplTypes.h
PokeIndex<LorentzIndex>(UdSdU,mommu,mu);
}
for(int mu=0;mu<Nd;mu++){
mommu = PeekIndex<LorentzIndex>(mom,mu);
std::cout << GridLogMessage<< " Mommu " << norm2(mommu)<<std::endl;
mommu = mommu+adj(mommu);
std::cout << GridLogMessage<< " Mommu + Mommudag " << norm2(mommu)<<std::endl;
mommu = PeekIndex<LorentzIndex>(UdSdU,mu);
std::cout << GridLogMessage<< " dsdumu " << norm2(mommu)<<std::endl;
mommu = mommu+adj(mommu);
std::cout << GridLogMessage<< " dsdumu + dag " << norm2(mommu)<<std::endl;
}
for(int mu=0;mu<Nd;mu++){
forcemu = PeekIndex<LorentzIndex>(UdSdU,mu);
mUdSdUmu= PeekIndex<LorentzIndex>(UdSdU,mu);
mommu = PeekIndex<LorentzIndex>(mom,mu);
// Update PF action density
dS = dS+trace(mommu*forcemu)*dt;
//
// Derive HMC eom:
//
// Sdot = - 2 trace( p p^dot ) / D - trace( p [ mUdSdU - h.c. ] ) = 0
//
//
// Sdot = 0 = - 2 trace( p p^dot ) / D - 2 trace( p Ta( mUdSdU ) = 0
//
// EOM:
//
// pdot = - D Ta( mUdSdU ) -- source of sign is the "funny sign" above
//
// dSqcd_dt = - 2.0*trace(mommu* Ta(mUdSdU) )*dt -- i.e. mUdSdU with adjoint term -> force has a 2x implicit
//
// dH_mom/dt = - 2 trace (p pdot)/Denom
//
// dH_tot / dt = 0 <= pdot = - Denom * mUdSdU
//
// dH_mom/dt = 2 trace (p mUdSdU )
//
// True Momentum delta H has a dt^2 piece
//
// dSmom = [ trace mom*mom - trace ( (mom-Denom*f*dt)(mom-Denom*f*dt) ) ] / Denom
// = 2*trace(mom*f) dt - Denom*dt*dt * trace(f*f).
// = dSmom + dSmom2
//
dSmom = dSmom - trace(mommu*forcemu) * dt;
dSmom2 = dSmom2 - trace(forcemu*forcemu) *(0.25* dt*dt);
dS = dS - 2.0*trace(mommu*mUdSdUmu)*dt; // U and Udagger derivs hence 2x.
// Update mom action density
mommu = mommu + forcemu*(dt*0.5);
dSmom = dSmom + 2.0*trace(mommu*mUdSdUmu) * dt; // this 2.0 coms from derivative of p^2
dSmom2 = dSmom2 - trace(mUdSdUmu*mUdSdUmu) * dt*dt* HMC_MOMENTUM_DENOMINATOR; // Remnant
Hmomprime -= real(sum(trace(mommu*mommu)));
// Update mom action density . Verbatim update_P in Integrator.h
mommu = mommu - mUdSdUmu * dt* HMC_MOMENTUM_DENOMINATOR;;
Hmomprime -= real(sum(trace(mommu*mommu))) / HMC_MOMENTUM_DENOMINATOR;
}
@ -199,20 +233,25 @@ int main (int argc, char ** argv)
ComplexD dSm = sum(dSmom);
ComplexD dSm2 = sum(dSmom2);
std::cout << GridLogMessage <<"dSm "<< dSm<<std::endl;
std::cout << GridLogMessage <<"dSm2 "<< dSm2<<std::endl;
std::cout << GridLogMessage <<"Initial mom hamiltonian is "<< Hmom <<std::endl;
std::cout << GridLogMessage <<"Final mom hamiltonian is "<< Hmomprime <<std::endl;
std::cout << GridLogMessage <<"Delta mom hamiltonian is "<< Hmomprime-Hmom <<std::endl;
std::cout << GridLogMessage << " S "<<S<<std::endl;
std::cout << GridLogMessage << " Sprime "<<Sprime<<std::endl;
std::cout << GridLogMessage << "dS "<<Sprime-S<<std::endl;
std::cout << GridLogMessage << "predict dS "<< dSpred <<std::endl;
std::cout << GridLogMessage <<"dSm "<< dSm<<std::endl;
std::cout << GridLogMessage <<"dSm2"<< dSm2<<std::endl;
std::cout << GridLogMessage <<"Delta mom hamiltonian is "<< Hmomprime-Hmom <<std::endl;
std::cout << GridLogMessage <<"predict Delta mom hamiltonian is "<< dSm+dSm2 <<std::endl;
std::cout << GridLogMessage << "Initial S "<<S<<std::endl;
std::cout << GridLogMessage << "Final S "<<Sprime<<std::endl;
std::cout << GridLogMessage << "Delta S "<<Sprime-S<<std::endl;
std::cout << GridLogMessage << "predict delta S"<< dSpred <<std::endl;
std::cout << GridLogMessage << "defect "<< Sprime-S-dSpred <<std::endl;
std::cout << GridLogMessage << "Total dS "<< Hmomprime - Hmom + Sprime - S <<std::endl;
std::cout << GridLogMessage << "dS - dt^2 term "<< Hmomprime - Hmom + Sprime - S - dSm2 <<std::endl;
assert( fabs(real(Sprime-S-dSpred)) < 5.0 ) ;
std::cout<< GridLogMessage << "Done" <<std::endl;

View File

@ -90,7 +90,8 @@ int main (int argc, char** argv)
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, CG, CG, CG, CG, Params, true);
Meofa.refresh(U, RNG5);
GridSerialRNG sRNG; sRNG.SeedFixedIntegers(seeds4);
Meofa.refresh(U, sRNG, RNG5);
RealD S = Meofa.S(U); // pdag M p
// get the deriv of phidag M phi with respect to "U"

View File

@ -46,6 +46,7 @@ int main (int argc, char ** argv)
std::vector<int> seeds({1,2,3,4});
GridSerialRNG sRNG; sRNG.SeedFixedIntegers({4,5,6,7});
GridParallelRNG pRNG(&Grid);
pRNG.SeedFixedIntegers(std::vector<int>({15,91,21,3}));
@ -67,7 +68,7 @@ int main (int argc, char ** argv)
LaplacianAdjointField<PeriodicGimplR> Laplacian(&Grid, CG, LapPar, Kappa);
GeneralisedMomenta<PeriodicGimplR> LaplacianMomenta(&Grid, Laplacian);
LaplacianMomenta.M.ImportGauge(U);
LaplacianMomenta.MomentaDistribution(pRNG);// fills the Momenta with the correct distr
LaplacianMomenta.MomentaDistribution(sRNG,pRNG);// fills the Momenta with the correct distr
std::cout << std::setprecision(15);

View File

@ -69,7 +69,14 @@ int main (int argc, char ** argv)
RealD M5=1.8;
RealD b=0.5;
RealD c=0.5;
MobiusFermionR Ddwf(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,b,c);
WilsonImplParams p;
p.boundary_phases[0] = 1.0;
p.boundary_phases[1] = 1.0;
p.boundary_phases[2] = 1.0;
p.boundary_phases[3] =- 1.0;
MobiusFermionR Ddwf(U,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,b,c,p);
Ddwf.M (phi,Mphi);
ComplexD S = innerProduct(Mphi,Mphi); // pdag MdagM p
@ -82,24 +89,44 @@ int main (int argc, char ** argv)
Ddwf.MDeriv(tmp , Mphi, phi,DaggerNo ); UdSdU=tmp;
Ddwf.MDeriv(tmp , phi, Mphi,DaggerYes ); UdSdU=(UdSdU+tmp);
// *****************************************************************************************
// *** There is a funny negative sign in all derivatives. This is - UdSdU. ***
// *** ***
// *** Deriv in both Wilson gauge action and the TwoFlavour.h seems to miss a minus sign ***
// *** UdSdU is negated relative to what I think - call what is returned mUdSdU, ***
// *** and insert minus sign ***
// *****************************************************************************************
UdSdU = - UdSdU ; // Follow sign convention of actions in Grid. Seems crazy.
LatticeFermion Ftmp (FGrid);
////////////////////////////////////
// Modify the gauge field a little
////////////////////////////////////
RealD dt = 0.0001;
RealD dt = 0.001;
RealD Hmom = 0.0;
RealD Hmomprime = 0.0;
LatticeColourMatrix mommu(UGrid);
LatticeColourMatrix forcemu(UGrid);
LatticeColourMatrix mUdSdUmu(UGrid);
LatticeGaugeField mom(UGrid);
LatticeGaugeField Uprime(UGrid);
for(int mu=0;mu<Nd;mu++){
SU<Nc>::GaussianFundamentalLieAlgebraMatrix(RNG4, mommu); // Traceless antihermitian momentum; gaussian in lie alg
PokeIndex<LorentzIndex>(mom,mommu,mu);
// Momentum Hamiltonian is - trace(p^2)/HMC_MOM_DENOMINATOR
//
// Integrator.h: RealD H = - FieldImplementation::FieldSquareNorm(P)/HMC_MOMENTUM_DENOMINATOR; // - trace (P*P)/denom // GaugeImplTypes.h: Hloc += trace(Pmu * Pmu);
// Sign comes from a sneaky multiply by "i" in GaussianFundemantalLie algebra
// P is i P^a_\mu T^a, not Pa Ta
//
// Integrator.h: H = Hmom + sum S(action)
Hmom -= real(sum(trace(mommu*mommu)))/ HMC_MOMENTUM_DENOMINATOR;
// fourth order exponential approx
autoView( U_v , U, CpuRead);
autoView( mom_v, mom, CpuRead);
@ -115,6 +142,7 @@ int main (int argc, char ** argv)
;
});
}
std::cout << GridLogMessage <<"Initial mom hamiltonian is "<< Hmom <<std::endl;
Ddwf.ImportGauge(Uprime);
Ddwf.M (phi,MphiPrime);
@ -125,32 +153,87 @@ int main (int argc, char ** argv)
// Use derivative to estimate dS
//////////////////////////////////////////////
LatticeComplex dS(UGrid); dS = Zero();
LatticeComplex dSmom(UGrid); dSmom = Zero();
LatticeComplex dSmom2(UGrid); dSmom2 = Zero();
for(int mu=0;mu<Nd;mu++){
mommu = PeekIndex<LorentzIndex>(UdSdU,mu);
mommu=Ta(mommu)*2.0;
mommu=Ta(mommu);
PokeIndex<LorentzIndex>(UdSdU,mommu,mu);
}
for(int mu=0;mu<Nd;mu++){
forcemu = PeekIndex<LorentzIndex>(UdSdU,mu);
mUdSdUmu= PeekIndex<LorentzIndex>(UdSdU,mu);
mommu = PeekIndex<LorentzIndex>(mom,mu);
// Update PF action density
dS = dS+trace(mommu*forcemu)*dt;
//
// Derive HMC eom:
//
// Sdot = - 2 trace( p p^dot ) / D - trace( p [ mUdSdU - h.c. ] ) = 0
//
//
// Sdot = 0 = - 2 trace( p p^dot ) / D - 2 trace( p Ta( mUdSdU ) = 0
//
// EOM:
//
// pdot = - D Ta( mUdSdU ) -- source of sign is the "funny sign" above
//
// dSqcd_dt = - 2.0*trace(mommu* Ta(mUdSdU) )*dt -- i.e. mUdSdU with adjoint term -> force has a 2x implicit
//
// dH_mom/dt = - 2 trace (p pdot)/Denom
//
// dH_tot / dt = 0 <= pdot = - Denom * mUdSdU
//
// dH_mom/dt = 2 trace (p mUdSdU )
//
// True Momentum delta H has a dt^2 piece
//
// dSmom = [ trace mom*mom - trace ( (mom-Denom*f*dt)(mom-Denom*f*dt) ) ] / Denom
// = 2*trace(mom*f) dt - Denom*dt*dt * trace(f*f).
// = dSmom + dSmom2
//
dS = dS - 2.0*trace(mommu*mUdSdUmu)*dt; // U and Udagger derivs hence 2x.
dSmom = dSmom + 2.0*trace(mommu*mUdSdUmu) * dt; // this 2.0 coms from derivative of p^2
dSmom2 = dSmom2 - trace(mUdSdUmu*mUdSdUmu) * dt*dt* HMC_MOMENTUM_DENOMINATOR; // Remnant
mommu = mommu - mUdSdUmu * dt* HMC_MOMENTUM_DENOMINATOR;;
Hmomprime -= real(sum(trace(mommu*mommu))) / HMC_MOMENTUM_DENOMINATOR;
}
ComplexD dSpred = sum(dS);
ComplexD dSm = sum(dSmom);
ComplexD dSm2 = sum(dSmom2);
std::cout << GridLogMessage << " -- S "<<S<<std::endl;
std::cout << GridLogMessage << " -- Sprime "<<Sprime<<std::endl;
std::cout << GridLogMessage << "dS "<<Sprime-S<<std::endl;
std::cout << GridLogMessage << "predict dS "<< dSpred <<std::endl;
std::cout << GridLogMessage <<"dSm "<< dSm<<std::endl;
std::cout << GridLogMessage <<"dSm2 "<< dSm2<<std::endl;
std::cout << GridLogMessage <<"Initial mom hamiltonian is "<< Hmom <<std::endl;
std::cout << GridLogMessage <<"Final mom hamiltonian is "<< Hmomprime <<std::endl;
std::cout << GridLogMessage <<"Delta mom hamiltonian is "<< Hmomprime-Hmom <<std::endl;
std::cout << GridLogMessage <<"predict Delta mom hamiltonian is "<< dSm+dSm2 <<std::endl;
std::cout << GridLogMessage << "Initial S "<<S<<std::endl;
std::cout << GridLogMessage << "Final S "<<Sprime<<std::endl;
std::cout << GridLogMessage << "Delta S "<<Sprime-S<<std::endl;
std::cout << GridLogMessage << "predict delta S"<< dSpred <<std::endl;
std::cout << GridLogMessage << "defect "<< Sprime-S-dSpred <<std::endl;
std::cout << GridLogMessage << "Total dS "<< Hmomprime - Hmom + Sprime - S <<std::endl;
std::cout << GridLogMessage << "dS - dt^2 term "<< Hmomprime - Hmom + Sprime - S - dSm2 <<std::endl;
assert( fabs(real(Sprime-S-dSpred)) < 1.0 ) ;
std::cout<< GridLogMessage << "Done" <<std::endl;
Grid_finalize();
}

View File

@ -88,7 +88,8 @@ int main (int argc, char** argv)
ConjugateGradient<LatticeFermion> CG(1.0e-12, 5000);
ExactOneFlavourRatioPseudoFermionAction<WilsonImplR> Meofa(Lop, Rop, CG, CG, CG, CG, CG, Params, false);
Meofa.refresh(U, RNG5);
GridSerialRNG sRNG; sRNG.SeedFixedIntegers(seeds4);
Meofa.refresh(U, sRNG, RNG5 );
RealD S = Meofa.S(U); // pdag M p
// get the deriv of phidag M phi with respect to "U"

View File

@ -93,7 +93,8 @@ int main (int argc, char** argv)
ConjugateGradient<FermionField> CG(1.0e-12, 5000);
ExactOneFlavourRatioPseudoFermionAction<FermionImplPolicy> Meofa(Lop, Rop, CG, CG, CG, CG, CG, Params, false);
Meofa.refresh(U, RNG5);
GridSerialRNG sRNG; sRNG.SeedFixedIntegers(seeds4);
Meofa.refresh(U, sRNG, RNG5 );
RealD S = Meofa.S(U); // pdag M p
// get the deriv of phidag M phi with respect to "U"

View File

@ -0,0 +1,154 @@
/*************************************************************************************
Grid physics library, www.github.com/paboyle/Grid
Source file: ./tests/Test_wilson_force.cc
Copyright (C) 2015
Author: Christopher Kelly <ckelly@bnl.gov>
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 */
#include <Grid/Grid.h>
using namespace std;
using namespace Grid;
//Get the mu-directected links on the upper boundary and the bulk remainder
template<typename Field>
void getLinksBoundaryBulk(Field &bound, Field &bulk, Field &from, const Coordinate &latt_size){
bound = Zero(); bulk = Zero();
for(int mu=0;mu<Nd;mu++){
LatticeInteger mucoor(bound.Grid());
LatticeCoordinate(mucoor, mu);
bound = where( mucoor == (Integer)(latt_size[mu] - 1), from, bound );
bulk = where( mucoor != (Integer)(latt_size[mu] - 1), from, bulk );
}
}
int main (int argc, char ** argv)
{
Grid_init(&argc,&argv);
Coordinate latt_size = GridDefaultLatt();
Coordinate simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
Coordinate mpi_layout = GridDefaultMpi();
GridCartesian Grid(latt_size,simd_layout,mpi_layout);
GridRedBlackCartesian RBGrid(&Grid);
int threads = GridThread::GetThreads();
std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
std::vector<int> seeds({1,2,3,4});
GridParallelRNG pRNG(&Grid);
pRNG.SeedFixedIntegers(seeds);
typedef PeriodicGimplR Gimpl;
typedef WilsonGaugeAction<Gimpl> GaugeAction;
typedef NoHirep Representation; //fundamental
typedef NoSmearing<Gimpl> Smearing;
typedef MinimumNorm2<Gimpl, Smearing> Omelyan;
typedef Gimpl::Field Field;
typedef MomentumFilterApplyPhase<Field> Filter;
Filter filter(&Grid);
//Setup a filter that disables link update on links passing through the global lattice boundary
typedef Filter::LatticeLorentzScalarType MaskType;
typedef Filter::LorentzScalarType MaskSiteType;
MaskSiteType zero, one;
for(int mu=0;mu<Nd;mu++){
zero(mu)()() = 0.;
one(mu)()() = 1.;
}
MaskType zeroField(&Grid), oneField(&Grid);
zeroField = zero;
oneField = one;
filter.phase = oneField; //make every site 1.0
//Zero mu-directed links at upper boundary
for(int mu=0;mu<Nd;mu++){
LatticeInteger mucoor(&Grid);
LatticeCoordinate(mucoor, mu);
filter.phase = where( mucoor == (Integer)(latt_size[mu] - 1) , zeroField, filter.phase );
}
//Start with a random gauge field
Field U(&Grid);
SU<Nc>::HotConfiguration(pRNG,U);
//Get the original links on the bulk and boundary for later use
Field Ubnd_orig(&Grid), Ubulk_orig(&Grid);
getLinksBoundaryBulk(Ubnd_orig, Ubulk_orig, U, latt_size);
ActionSet<Field,Representation> actions(1);
double beta=6;
GaugeAction gauge_action(beta);
actions[0].push_back(&gauge_action);
Smearing smear;
IntegratorParameters params(1,1.); //1 MD step
Omelyan integrator(&Grid, params, actions, smear);
integrator.setMomentumFilter(filter);
integrator.refresh(U, pRNG); //doesn't actually change the gauge field
//Check the momentum is zero on the boundary
const auto &P = integrator.getMomentum();
Field Pbnd(&Grid), Pbulk(&Grid);
getLinksBoundaryBulk(Pbnd, Pbulk, const_cast<Field&>(P), latt_size);
RealD Pbnd_nrm = norm2(Pbnd); //expect zero
std::cout << GridLogMessage << "After refresh, norm2 of mu-directed conjugate momentum on boundary is: " << Pbnd_nrm << " (expect 0)" << std::endl;
RealD Pbulk_nrm = norm2(Pbulk); //expect non-zero
std::cout << GridLogMessage << "After refresh, norm2 of bulk conjugate momentum is: " << Pbulk_nrm << " (expect non-zero)" << std::endl;
//Evolve the gauge field
integrator.integrate(U);
//Check momentum is still zero on boundary
getLinksBoundaryBulk(Pbnd, Pbulk, const_cast<Field&>(P), latt_size);
Pbnd_nrm = norm2(Pbnd); //expect zero
std::cout << GridLogMessage << "After integrate, norm2 of mu-directed conjugate momentum on boundary is: " << Pbnd_nrm << " (expect 0)" << std::endl;
Pbulk_nrm = norm2(Pbulk); //expect non-zero
std::cout << GridLogMessage << "After integrate, norm2 of bulk conjugate momentum is: " << Pbulk_nrm << " (expect non-zero)" << std::endl;
//Get the new bulk and bound links
Field Ubnd_new(&Grid), Ubulk_new(&Grid);
getLinksBoundaryBulk(Ubnd_new, Ubulk_new, U, latt_size);
Field Ubnd_diff = Ubnd_new - Ubnd_orig;
Field Ubulk_diff = Ubulk_new - Ubulk_orig;
RealD Ubnd_change = norm2( Ubnd_diff );
RealD Ubulk_change = norm2( Ubulk_diff );
std::cout << GridLogMessage << "After integrate, norm2 of change in mu-directed boundary links is : " << Ubnd_change << " (expect 0)" << std::endl;
std::cout << GridLogMessage << "After integrate, norm2 of change in bulk links is : " << Ubulk_change << " (expect non-zero)" << std::endl;
Grid_finalize();
}