mirror of
https://github.com/paboyle/Grid.git
synced 2024-11-15 02:05:37 +00:00
203 lines
7.1 KiB
C++
203 lines
7.1 KiB
C++
/*************************************************************************************
|
|
|
|
Grid physics library, www.github.com/paboyle/Grid
|
|
|
|
Source file: ./tests/Test_padded_cell.cc
|
|
|
|
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 */
|
|
#include <Grid/Grid.h>
|
|
#include <Grid/lattice/PaddedCell.h>
|
|
#include <Grid/stencil/GeneralLocalStencil.h>
|
|
|
|
using namespace std;
|
|
using namespace Grid;
|
|
|
|
// This is to optimize the SIMD
|
|
template<class vobj> void gpermute(vobj & inout,int perm){
|
|
vobj tmp=inout;
|
|
if (perm & 0x1 ) { permute(inout,tmp,0); tmp=inout;}
|
|
if (perm & 0x2 ) { permute(inout,tmp,1); tmp=inout;}
|
|
if (perm & 0x4 ) { permute(inout,tmp,2); tmp=inout;}
|
|
if (perm & 0x8 ) { permute(inout,tmp,3); tmp=inout;}
|
|
}
|
|
|
|
|
|
int main (int argc, char ** argv)
|
|
{
|
|
Grid_init(&argc,&argv);
|
|
|
|
Coordinate latt_size = GridDefaultLatt();
|
|
Coordinate simd_layout= GridDefaultSimd(Nd,vComplexD::Nsimd());
|
|
Coordinate mpi_layout = GridDefaultMpi();
|
|
std::cout << GridLogMessage << " mpi "<<mpi_layout<<std::endl;
|
|
std::cout << GridLogMessage << " simd "<<simd_layout<<std::endl;
|
|
std::cout << GridLogMessage << " latt "<<latt_size<<std::endl;
|
|
GridCartesian GRID(latt_size,simd_layout,mpi_layout);
|
|
|
|
// Initialize configuration as hot start.
|
|
GridParallelRNG pRNG(&GRID);
|
|
LatticeGaugeField Umu(&GRID);
|
|
pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}));
|
|
SU<Nc>::HotConfiguration(pRNG,Umu);
|
|
|
|
Real plaq=WilsonLoops<PeriodicGimplR>::avgPlaquette(Umu);
|
|
LatticeComplex trplaq(&GRID);
|
|
|
|
// Store Umu in U. Peek/Poke mean respectively getElement/setElement.
|
|
std::vector<LatticeColourMatrix> U(Nd, Umu.Grid());
|
|
for (int mu = 0; mu < Nd; mu++) {
|
|
U[mu] = PeekIndex<LorentzIndex>(Umu, mu);
|
|
}
|
|
|
|
std::cout << GridLogMessage << " Average plaquette "<<plaq<<std::endl;
|
|
|
|
LatticeComplex cplaq(&GRID); cplaq=Zero();
|
|
|
|
// Create a padded cell of extra padding depth=1
|
|
int depth = 1;
|
|
PaddedCell Ghost(depth,&GRID);
|
|
LatticeGaugeField Ughost = Ghost.Exchange(Umu);
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
// Temporary debug Hack for single rank sim:
|
|
// Check the contents of the cell are periodcally replicated
|
|
// In future ONLY pad those dimensions that are not local to node
|
|
///////////////////////////////////////////////////////////////////
|
|
#if 0
|
|
{
|
|
double diff=0;
|
|
double n=0;
|
|
{
|
|
autoView( Ug_v , Ughost, CpuRead);
|
|
autoView( Ul_v , Umu , CpuRead);
|
|
for(int x=0;x<latt_size[0]+2;x++){
|
|
for(int y=0;y<latt_size[1]+2;y++){
|
|
for(int z=0;z<latt_size[2]+2;z++){
|
|
for(int t=0;t<latt_size[3]+2;t++){
|
|
int lx=(x-1+latt_size[0])%latt_size[0];
|
|
int ly=(y-1+latt_size[1])%latt_size[1];
|
|
int lz=(z-1+latt_size[2])%latt_size[2];
|
|
int lt=(t-1+latt_size[3])%latt_size[3];
|
|
Coordinate gcoor({x,y,z,t});
|
|
Coordinate lcoor({lx,ly,lz,lt});
|
|
LorentzColourMatrix g;
|
|
LorentzColourMatrix l;
|
|
peekLocalSite(g,Ug_v,gcoor);
|
|
peekLocalSite(l,Ul_v,lcoor);
|
|
g=g-l;
|
|
assert(norm2(g)==0);
|
|
diff = diff + norm2(g);
|
|
n = n + norm2(l);
|
|
}}}}
|
|
}
|
|
std::cout << "padded field check diff "<< diff <<" / "<< n<<std::endl;
|
|
std::cout << norm2(Ughost)<< " " << norm2(Umu)<<std::endl;
|
|
}
|
|
#endif
|
|
|
|
// Array for the site plaquette
|
|
GridBase *GhostGrid = Ughost.Grid();
|
|
LatticeComplex gplaq(GhostGrid);
|
|
|
|
// Now we're going to put together the "stencil" that will be useful to us when
|
|
// calculating the plaquette. Our eventual goal is to make the product
|
|
// Umu(x) Unu(x+mu) Umu^dag(x+nu) Unu^dag(x),
|
|
// which requires, in order, the sites x, x+mu, x+nu, and x. We arrive at these
|
|
// sites relative to x through "shifts", which is represented here by a 4-d
|
|
// vector of 0s (no movement) and 1s (shift one unit) at each site. The
|
|
// "stencil" is the set of all these shifts.
|
|
std::vector<Coordinate> shifts;
|
|
for(int mu=0;mu<Nd;mu++){
|
|
for(int nu=mu+1;nu<Nd;nu++){
|
|
Coordinate shift_0(Nd,0);
|
|
Coordinate shift_mu(Nd,0); shift_mu[mu]=1;
|
|
Coordinate shift_nu(Nd,0); shift_nu[nu]=1;
|
|
// push_back creates an element at the end of shifts and
|
|
// assigns the data in the argument to it.
|
|
shifts.push_back(shift_0);
|
|
shifts.push_back(shift_mu);
|
|
shifts.push_back(shift_nu);
|
|
shifts.push_back(shift_0);
|
|
}
|
|
}
|
|
GeneralLocalStencil gStencil(GhostGrid,shifts);
|
|
|
|
gplaq=Zero();
|
|
|
|
// Before doing accelerator stuff, there is an opening and closing of "Views". I guess the
|
|
// "Views" are stored in *_v variables listed below.
|
|
autoView( gp_v , gplaq, CpuWrite);
|
|
autoView( t_v , trplaq, CpuRead);
|
|
autoView( U_v , Ughost, CpuRead);
|
|
|
|
// This is now a loop over stencil shift elements. That is, s increases as we make our
|
|
// way through the spacetimes sites, but also as we make our way around the plaquette.
|
|
for(int ss=0;ss<gp_v.size();ss++){
|
|
int s=0;
|
|
for(int mu=0;mu<Nd;mu++){
|
|
for(int nu=mu+1;nu<Nd;nu++){
|
|
|
|
auto SE0 = gStencil.GetEntry(s+0,ss);
|
|
auto SE1 = gStencil.GetEntry(s+1,ss);
|
|
auto SE2 = gStencil.GetEntry(s+2,ss);
|
|
auto SE3 = gStencil.GetEntry(s+3,ss);
|
|
|
|
// Due to our strategy, each offset corresponds to a site.
|
|
int o0 = SE0->_offset;
|
|
int o1 = SE1->_offset;
|
|
int o2 = SE2->_offset;
|
|
int o3 = SE3->_offset;
|
|
|
|
auto U0 = U_v[o0](mu);
|
|
auto U1 = U_v[o1](nu);
|
|
auto U2 = adj(U_v[o2](mu));
|
|
auto U3 = adj(U_v[o3](nu));
|
|
|
|
gpermute(U0,SE0->_permute);
|
|
gpermute(U1,SE1->_permute);
|
|
gpermute(U2,SE2->_permute);
|
|
gpermute(U3,SE3->_permute);
|
|
|
|
gp_v[ss]() =gp_v[ss]() + trace( U0*U1*U2*U3 );
|
|
s=s+4;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Here is my understanding of this part: The padded cell has its own periodic BCs, so
|
|
// if I take a step to the right at the right-most side of the cell, I end up on the
|
|
// left-most side. This means that the plaquettes in the padding are wrong. Luckily
|
|
// all we care about are the plaquettes in the cell, which we obtain from Extract.
|
|
cplaq = Ghost.Extract(gplaq);
|
|
RealD vol = cplaq.Grid()->gSites();
|
|
RealD faces = (Nd * (Nd-1))/2;
|
|
auto p = TensorRemove(sum(cplaq));
|
|
auto result = p.real()/vol/faces/Nc;
|
|
|
|
std::cout << GridLogMessage << " Average plaquette via padded cell "<<result<<std::endl;
|
|
std::cout << GridLogMessage << " Diff "<<result-plaq<<std::endl;
|
|
|
|
assert(fabs(result-plaq)<1.0e-8);
|
|
Grid_finalize();
|
|
}
|