mirror of
https://github.com/paboyle/Grid.git
synced 2025-08-27 00:17:09 +01:00
Merge GPU support (upstream/develop) into distillation branch.
This compiles and looks right ... but may need some testing * develop: (762 commits) Tensor ambiguous fix Fix for GCC preprocessor/pragma handling bug Trips up NVCC for reasons I dont understand on summit Fix GCC complaint Zero() change Force a couple of things to compile on NVCC Remove debug code nvcc error suppress Merge develop Reduction finished and hopefully fixes CI regression fail on single precisoin and force Double precision variants for summation accuracy Update todo list Freeze the seed Fix compiling of MSource::Gauss for single precision Think the reduction is now sorted and cleaned up Fix force term Printing improvement GPU reduction fix and also exit backtrace option GPU friendly Simplify the comms benchmark ... # Conflicts: # Grid/communicator/SharedMemoryMPI.cc # Grid/qcd/action/fermion/WilsonKernelsAsm.cc # Grid/qcd/action/fermion/implementation/StaggeredKernelsAsm.h # Grid/qcd/smearing/StoutSmearing.h # Hadrons/Modules.hpp # Hadrons/Utilities/Contractor.cc # Hadrons/modules.inc # tests/forces/Test_dwf_force_eofa.cc # tests/forces/Test_dwf_gpforce_eofa.cc
This commit is contained in:
@@ -25,134 +25,128 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
See the full license in the file "LICENSE" in the top level distribution
|
||||
directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
/*!
|
||||
@brief Declaration of Smear_APE class for APE smearing
|
||||
*/
|
||||
/* END LEGAL */
|
||||
/*!
|
||||
@brief Declaration of Smear_APE class for APE smearing
|
||||
*/
|
||||
|
||||
#ifndef APE_SMEAR_
|
||||
#define APE_SMEAR_
|
||||
#pragma once
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
NAMESPACE_BEGIN(Grid);
|
||||
|
||||
/*! @brief APE type smearing of link variables. */
|
||||
template <class Gimpl>
|
||||
class Smear_APE: public Smear<Gimpl>{
|
||||
private:
|
||||
const std::vector<double> rho;/*!< Array of weights */
|
||||
|
||||
//This member must be private - we do not want to control from outside
|
||||
std::vector<double> set_rho(const double common_rho) const {
|
||||
std::vector<double> res;
|
||||
|
||||
for(int mn=0; mn<Nd*Nd; ++mn) res.push_back(common_rho);
|
||||
for(int mu=0; mu<Nd; ++mu) res[mu + mu*Nd] = 0.0;
|
||||
return res;
|
||||
}
|
||||
|
||||
public:
|
||||
// Defines the gauge field types
|
||||
INHERIT_GIMPL_TYPES(Gimpl)
|
||||
|
||||
|
||||
/*! @brief APE type smearing of link variables. */
|
||||
template <class Gimpl>
|
||||
class Smear_APE: public Smear<Gimpl>{
|
||||
private:
|
||||
const std::vector<double> rho;/*!< Array of weights */
|
||||
// Constructors and destructors
|
||||
Smear_APE(const std::vector<double>& rho_):rho(rho_){} // check vector size
|
||||
Smear_APE(double rho_val):rho(set_rho(rho_val)){}
|
||||
Smear_APE():rho(set_rho(1.0)){}
|
||||
~Smear_APE(){}
|
||||
|
||||
//This member must be private - we do not want to control from outside
|
||||
std::vector<double> set_rho(const double common_rho) const {
|
||||
std::vector<double> res;
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void smear(GaugeField& u_smr, const GaugeField& U)const{
|
||||
GridBase *grid = U.Grid();
|
||||
GaugeLinkField Cup(grid), tmp_stpl(grid);
|
||||
WilsonLoops<Gimpl> WL;
|
||||
u_smr = Zero();
|
||||
|
||||
for(int mn=0; mn<Nd*Nd; ++mn) res.push_back(common_rho);
|
||||
for(int mu=0; mu<Nd; ++mu) res[mu + mu*Nd] = 0.0;
|
||||
return res;
|
||||
}
|
||||
for(int mu=0; mu<Nd; ++mu){
|
||||
Cup = Zero();
|
||||
for(int nu=0; nu<Nd; ++nu){
|
||||
if (nu != mu) {
|
||||
// get the staple in direction mu, nu
|
||||
WL.Staple(tmp_stpl, U, mu, nu); //nb staple conventions of IroIro and Grid differ by a dagger
|
||||
Cup += tmp_stpl*rho[mu + Nd * nu];
|
||||
}
|
||||
}
|
||||
// save the Cup link-field on the u_smr gauge-field
|
||||
pokeLorentz(u_smr, adj(Cup), mu); // u_smr[mu] = Cup^dag see conventions for Staple
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
// Defines the gauge field types
|
||||
INHERIT_GIMPL_TYPES(Gimpl)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void derivative(GaugeField& SigmaTerm,
|
||||
const GaugeField& iLambda,
|
||||
const GaugeField& U)const{
|
||||
|
||||
|
||||
// Constructors and destructors
|
||||
Smear_APE(const std::vector<double>& rho_):rho(rho_){} // check vector size
|
||||
Smear_APE(double rho_val):rho(set_rho(rho_val)){}
|
||||
Smear_APE():rho(set_rho(1.0)){}
|
||||
~Smear_APE(){}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void smear(GaugeField& u_smr, const GaugeField& U)const{
|
||||
GridBase *grid = U._grid;
|
||||
GaugeLinkField Cup(grid), tmp_stpl(grid);
|
||||
WilsonLoops<Gimpl> WL;
|
||||
u_smr = zero;
|
||||
|
||||
for(int mu=0; mu<Nd; ++mu){
|
||||
Cup = zero;
|
||||
for(int nu=0; nu<Nd; ++nu){
|
||||
if (nu != mu) {
|
||||
// get the staple in direction mu, nu
|
||||
WL.Staple(tmp_stpl, U, mu, nu); //nb staple conventions of IroIro and Grid differ by a dagger
|
||||
Cup += tmp_stpl*rho[mu + Nd * nu];
|
||||
}
|
||||
}
|
||||
// save the Cup link-field on the u_smr gauge-field
|
||||
pokeLorentz(u_smr, adj(Cup), mu); // u_smr[mu] = Cup^dag see conventions for Staple
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void derivative(GaugeField& SigmaTerm,
|
||||
const GaugeField& iLambda,
|
||||
const GaugeField& U)const{
|
||||
|
||||
// Reference
|
||||
// Morningstar, Peardon, Phys.Rev.D69,054501(2004)
|
||||
// Equation 75
|
||||
// Reference
|
||||
// Morningstar, Peardon, Phys.Rev.D69,054501(2004)
|
||||
// Equation 75
|
||||
// Computing Sigma_mu, derivative of S[fat links] with respect to the thin links
|
||||
// Output SigmaTerm
|
||||
|
||||
GridBase *grid = U._grid;
|
||||
GridBase *grid = U.Grid();
|
||||
|
||||
WilsonLoops<Gimpl> WL;
|
||||
GaugeLinkField staple(grid), u_tmp(grid);
|
||||
GaugeLinkField iLambda_mu(grid), iLambda_nu(grid);
|
||||
GaugeLinkField U_mu(grid), U_nu(grid);
|
||||
GaugeLinkField sh_field(grid), temp_Sigma(grid);
|
||||
Real rho_munu, rho_numu;
|
||||
WilsonLoops<Gimpl> WL;
|
||||
GaugeLinkField staple(grid), u_tmp(grid);
|
||||
GaugeLinkField iLambda_mu(grid), iLambda_nu(grid);
|
||||
GaugeLinkField U_mu(grid), U_nu(grid);
|
||||
GaugeLinkField sh_field(grid), temp_Sigma(grid);
|
||||
Real rho_munu, rho_numu;
|
||||
|
||||
for(int mu = 0; mu < Nd; ++mu){
|
||||
U_mu = peekLorentz( U, mu);
|
||||
iLambda_mu = peekLorentz(iLambda, mu);
|
||||
for(int mu = 0; mu < Nd; ++mu){
|
||||
U_mu = peekLorentz( U, mu);
|
||||
iLambda_mu = peekLorentz(iLambda, mu);
|
||||
|
||||
for(int nu = 0; nu < Nd; ++nu){
|
||||
if(nu==mu) continue;
|
||||
U_nu = peekLorentz( U, nu);
|
||||
iLambda_nu = peekLorentz(iLambda, nu);
|
||||
for(int nu = 0; nu < Nd; ++nu){
|
||||
if(nu==mu) continue;
|
||||
U_nu = peekLorentz( U, nu);
|
||||
iLambda_nu = peekLorentz(iLambda, nu);
|
||||
|
||||
rho_munu = rho[mu + Nd * nu];
|
||||
rho_numu = rho[nu + Nd * mu];
|
||||
rho_munu = rho[mu + Nd * nu];
|
||||
rho_numu = rho[nu + Nd * mu];
|
||||
|
||||
WL.StapleUpper(staple, U, mu, nu);
|
||||
WL.StapleUpper(staple, U, mu, nu);
|
||||
|
||||
temp_Sigma = -rho_numu*staple*iLambda_nu; //ok
|
||||
//-r_numu*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)*Lambda_nu(x)
|
||||
Gimpl::AddLink(SigmaTerm, temp_Sigma, mu);
|
||||
temp_Sigma = -rho_numu*staple*iLambda_nu; //ok
|
||||
//-r_numu*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)*Lambda_nu(x)
|
||||
Gimpl::AddLink(SigmaTerm, temp_Sigma, mu);
|
||||
|
||||
sh_field = Cshift(iLambda_nu, mu, 1);// general also for Gparity?
|
||||
sh_field = Cshift(iLambda_nu, mu, 1);// general also for Gparity?
|
||||
|
||||
temp_Sigma = rho_numu*sh_field*staple; //ok
|
||||
//r_numu*Lambda_nu(mu)*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)
|
||||
Gimpl::AddLink(SigmaTerm, temp_Sigma, mu);
|
||||
temp_Sigma = rho_numu*sh_field*staple; //ok
|
||||
//r_numu*Lambda_nu(mu)*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)
|
||||
Gimpl::AddLink(SigmaTerm, temp_Sigma, mu);
|
||||
|
||||
sh_field = Cshift(iLambda_mu, nu, 1);
|
||||
sh_field = Cshift(iLambda_mu, nu, 1);
|
||||
|
||||
temp_Sigma = -rho_munu*staple*U_nu*sh_field*adj(U_nu); //ok
|
||||
//-r_munu*U_nu(x+mu)*Udag_mu(x+nu)*Lambda_mu(x+nu)*Udag_nu(x)
|
||||
Gimpl::AddLink(SigmaTerm, temp_Sigma, mu);
|
||||
temp_Sigma = -rho_munu*staple*U_nu*sh_field*adj(U_nu); //ok
|
||||
//-r_munu*U_nu(x+mu)*Udag_mu(x+nu)*Lambda_mu(x+nu)*Udag_nu(x)
|
||||
Gimpl::AddLink(SigmaTerm, temp_Sigma, mu);
|
||||
|
||||
staple = zero;
|
||||
sh_field = Cshift(U_nu, mu, 1);
|
||||
staple = Zero();
|
||||
sh_field = Cshift(U_nu, mu, 1);
|
||||
|
||||
temp_Sigma = -rho_munu*adj(sh_field)*adj(U_mu)*iLambda_mu*U_nu;
|
||||
temp_Sigma += rho_numu*adj(sh_field)*adj(U_mu)*iLambda_nu*U_nu;
|
||||
temp_Sigma = -rho_munu*adj(sh_field)*adj(U_mu)*iLambda_mu*U_nu;
|
||||
temp_Sigma += rho_numu*adj(sh_field)*adj(U_mu)*iLambda_nu*U_nu;
|
||||
|
||||
u_tmp = adj(U_nu)*iLambda_nu;
|
||||
sh_field = Cshift(u_tmp, mu, 1);
|
||||
temp_Sigma += -rho_numu*sh_field*adj(U_mu)*U_nu;
|
||||
sh_field = Cshift(temp_Sigma, nu, -1);
|
||||
Gimpl::AddLink(SigmaTerm, sh_field, mu);
|
||||
u_tmp = adj(U_nu)*iLambda_nu;
|
||||
sh_field = Cshift(u_tmp, mu, 1);
|
||||
temp_Sigma += -rho_numu*sh_field*adj(U_mu)*U_nu;
|
||||
sh_field = Cshift(temp_Sigma, nu, -1);
|
||||
Gimpl::AddLink(SigmaTerm, sh_field, mu);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
NAMESPACE_END(Grid);
|
||||
|
||||
|
||||
}// namespace QCD
|
||||
}//namespace Grid
|
||||
#endif
|
||||
|
@@ -29,9 +29,8 @@ directory
|
||||
/*
|
||||
@brief Declares base smearing class Smear
|
||||
*/
|
||||
#ifndef BASE_SMEAR_
|
||||
#define BASE_SMEAR_
|
||||
|
||||
#pragma once
|
||||
NAMESPACE_BEGIN(Grid);
|
||||
template <class Gimpl>
|
||||
class Smear{
|
||||
public:
|
||||
@@ -41,4 +40,5 @@ public:
|
||||
virtual void smear (GaugeField&,const GaugeField&)const = 0;
|
||||
virtual void derivative(GaugeField&, const GaugeField&,const GaugeField&) const = 0;
|
||||
};
|
||||
#endif
|
||||
NAMESPACE_END(Grid);
|
||||
|
||||
|
@@ -3,31 +3,26 @@
|
||||
|
||||
@brief Declares the GaugeConfiguration class
|
||||
*/
|
||||
#ifndef GAUGE_CONFIG_
|
||||
#define GAUGE_CONFIG_
|
||||
#pragma once
|
||||
|
||||
namespace Grid
|
||||
{
|
||||
|
||||
namespace QCD
|
||||
{
|
||||
NAMESPACE_BEGIN(Grid);
|
||||
|
||||
//trivial class for no smearing
|
||||
template <class Impl>
|
||||
template< class Impl >
|
||||
class NoSmearing
|
||||
{
|
||||
public:
|
||||
INHERIT_FIELD_TYPES(Impl);
|
||||
|
||||
Field *ThinField;
|
||||
Field* ThinField;
|
||||
|
||||
NoSmearing() : ThinField(NULL) {}
|
||||
NoSmearing(): ThinField(NULL) {}
|
||||
|
||||
void set_Field(Field &U) { ThinField = &U; }
|
||||
void set_Field(Field& U) { ThinField = &U; }
|
||||
|
||||
void smeared_force(Field &) const {}
|
||||
void smeared_force(Field&) const {}
|
||||
|
||||
Field &get_SmearedU() { return *ThinField; }
|
||||
Field& get_SmearedU() { return *ThinField; }
|
||||
|
||||
Field &get_U(bool smeared = false)
|
||||
{
|
||||
@@ -61,7 +56,7 @@ private:
|
||||
//====================================================================
|
||||
void fill_smearedSet(GaugeField &U)
|
||||
{
|
||||
ThinLinks = &U; // attach the smearing routine to the field U
|
||||
ThinLinks = &U; // attach the smearing routine to the field U
|
||||
|
||||
// check the pointer is not null
|
||||
if (ThinLinks == NULL)
|
||||
@@ -72,7 +67,7 @@ private:
|
||||
{
|
||||
std::cout << GridLogDebug
|
||||
<< "[SmearedConfiguration] Filling SmearedSet\n";
|
||||
GaugeField previous_u(ThinLinks->_grid);
|
||||
GaugeField previous_u(ThinLinks->Grid());
|
||||
|
||||
previous_u = *ThinLinks;
|
||||
for (int smearLvl = 0; smearLvl < smearingLevels; ++smearLvl)
|
||||
@@ -88,10 +83,10 @@ private:
|
||||
}
|
||||
}
|
||||
//====================================================================
|
||||
GaugeField AnalyticSmearedForce(const GaugeField &SigmaKPrime,
|
||||
const GaugeField &GaugeK) const
|
||||
GaugeField AnalyticSmearedForce(const GaugeField& SigmaKPrime,
|
||||
const GaugeField& GaugeK) const
|
||||
{
|
||||
GridBase *grid = GaugeK._grid;
|
||||
GridBase* grid = GaugeK.Grid();
|
||||
GaugeField C(grid), SigmaK(grid), iLambda(grid);
|
||||
GaugeLinkField iLambda_mu(grid);
|
||||
GaugeLinkField iQ(grid), e_iQ(grid);
|
||||
@@ -99,8 +94,8 @@ private:
|
||||
GaugeLinkField GaugeKmu(grid), Cmu(grid);
|
||||
|
||||
StoutSmearing.BaseSmear(C, GaugeK);
|
||||
SigmaK = zero;
|
||||
iLambda = zero;
|
||||
SigmaK = Zero();
|
||||
iLambda = Zero();
|
||||
|
||||
for (int mu = 0; mu < Nd; mu++)
|
||||
{
|
||||
@@ -113,7 +108,7 @@ private:
|
||||
pokeLorentz(iLambda, iLambda_mu, mu);
|
||||
}
|
||||
StoutSmearing.derivative(SigmaK, iLambda,
|
||||
GaugeK); // derivative of SmearBase
|
||||
GaugeK); // derivative of SmearBase
|
||||
return SigmaK;
|
||||
}
|
||||
|
||||
@@ -124,11 +119,11 @@ private:
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
void set_iLambda(GaugeLinkField &iLambda, GaugeLinkField &e_iQ,
|
||||
const GaugeLinkField &iQ, const GaugeLinkField &Sigmap,
|
||||
const GaugeLinkField &GaugeK) const
|
||||
void set_iLambda(GaugeLinkField& iLambda, GaugeLinkField& e_iQ,
|
||||
const GaugeLinkField& iQ, const GaugeLinkField& Sigmap,
|
||||
const GaugeLinkField& GaugeK) const
|
||||
{
|
||||
GridBase *grid = iQ._grid;
|
||||
GridBase* grid = iQ.Grid();
|
||||
GaugeLinkField iQ2(grid), iQ3(grid), B1(grid), B2(grid), USigmap(grid);
|
||||
GaugeLinkField unity(grid);
|
||||
unity = 1.0;
|
||||
@@ -141,7 +136,7 @@ private:
|
||||
LatticeComplex r01(grid), r11(grid), r21(grid), r02(grid), r12(grid);
|
||||
LatticeComplex r22(grid), tr1(grid), tr2(grid);
|
||||
LatticeComplex b10(grid), b11(grid), b12(grid), b20(grid), b21(grid),
|
||||
b22(grid);
|
||||
b22(grid);
|
||||
LatticeComplex LatticeUnitComplex(grid);
|
||||
|
||||
LatticeUnitComplex = 1.0;
|
||||
@@ -165,19 +160,19 @@ private:
|
||||
e2iu = cos(2.0 * u) + timesI(sin(2.0 * u));
|
||||
|
||||
r01 = (2.0 * u + timesI(2.0 * (u2 - w2))) * e2iu +
|
||||
emiu * ((16.0 * u * cosw + 2.0 * u * (3.0 * u2 + w2) * xi0) +
|
||||
timesI(-8.0 * u2 * cosw + 2.0 * (9.0 * u2 + w2) * xi0));
|
||||
emiu * ((16.0 * u * cosw + 2.0 * u * (3.0 * u2 + w2) * xi0) +
|
||||
timesI(-8.0 * u2 * cosw + 2.0 * (9.0 * u2 + w2) * xi0));
|
||||
|
||||
r11 = (2.0 * LatticeUnitComplex + timesI(4.0 * u)) * e2iu +
|
||||
emiu * ((-2.0 * cosw + (3.0 * u2 - w2) * xi0) +
|
||||
timesI((2.0 * u * cosw + 6.0 * u * xi0)));
|
||||
emiu * ((-2.0 * cosw + (3.0 * u2 - w2) * xi0) +
|
||||
timesI((2.0 * u * cosw + 6.0 * u * xi0)));
|
||||
|
||||
r21 =
|
||||
2.0 * timesI(e2iu) + emiu * (-3.0 * u * xi0 + timesI(cosw - 3.0 * xi0));
|
||||
2.0 * timesI(e2iu) + emiu * (-3.0 * u * xi0 + timesI(cosw - 3.0 * xi0));
|
||||
|
||||
r02 = -2.0 * e2iu +
|
||||
emiu * (-8.0 * u2 * xi0 +
|
||||
timesI(2.0 * u * (cosw + xi0 + 3.0 * u2 * xi1)));
|
||||
emiu * (-8.0 * u2 * xi0 +
|
||||
timesI(2.0 * u * (cosw + xi0 + 3.0 * u2 * xi1)));
|
||||
|
||||
r12 = emiu * (2.0 * u * xi0 + timesI(-cosw - xi0 + 3.0 * u2 * xi1));
|
||||
|
||||
@@ -211,19 +206,19 @@ private:
|
||||
GaugeLinkField USQ = USigmap * iQ;
|
||||
|
||||
GaugeLinkField iGamma = tr1 * iQ - timesI(tr2) * iQ2 +
|
||||
timesI(f1) * USigmap + f2 * QUS + f2 * USQ;
|
||||
timesI(f1) * USigmap + f2 * QUS + f2 * USQ;
|
||||
|
||||
iLambda = Ta(iGamma);
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
public:
|
||||
GaugeField *
|
||||
GaugeField*
|
||||
ThinLinks; /* Pointer to the thin links configuration */
|
||||
|
||||
/* Standard constructor */
|
||||
SmearedConfiguration(GridCartesian *UGrid, unsigned int Nsmear,
|
||||
Smear_Stout<Gimpl> &Stout)
|
||||
SmearedConfiguration(GridCartesian* UGrid, unsigned int Nsmear,
|
||||
Smear_Stout<Gimpl>& Stout)
|
||||
: smearingLevels(Nsmear), StoutSmearing(Stout), ThinLinks(NULL)
|
||||
{
|
||||
for (unsigned int i = 0; i < smearingLevels; ++i)
|
||||
@@ -232,7 +227,7 @@ public:
|
||||
|
||||
/*! For just thin links */
|
||||
SmearedConfiguration()
|
||||
: smearingLevels(0), StoutSmearing(), SmearedSet(), ThinLinks(NULL) {}
|
||||
: smearingLevels(0), StoutSmearing(), SmearedSet(), ThinLinks(NULL) {}
|
||||
|
||||
// attach the smeared routines to the thin links U and fill the smeared set
|
||||
void set_Field(GaugeField &U)
|
||||
@@ -251,7 +246,7 @@ public:
|
||||
{
|
||||
double start = usecond();
|
||||
GaugeField force = SigmaTilde; // actually = U*SigmaTilde
|
||||
GaugeLinkField tmp_mu(SigmaTilde._grid);
|
||||
GaugeLinkField tmp_mu(SigmaTilde.Grid());
|
||||
|
||||
for (int mu = 0; mu < Nd; mu++)
|
||||
{
|
||||
@@ -273,11 +268,11 @@ public:
|
||||
double end = usecond();
|
||||
double time = (end - start)/ 1e3;
|
||||
std::cout << GridLogMessage << "Smearing force in " << time << " ms" << std::endl;
|
||||
} // if smearingLevels = 0 do nothing
|
||||
} // if smearingLevels = 0 do nothing
|
||||
}
|
||||
//====================================================================
|
||||
|
||||
GaugeField &get_SmearedU() { return SmearedSet[smearingLevels - 1]; }
|
||||
GaugeField& get_SmearedU() { return SmearedSet[smearingLevels - 1]; }
|
||||
|
||||
GaugeField &get_U(bool smeared = false)
|
||||
{
|
||||
@@ -287,7 +282,7 @@ public:
|
||||
if (smearingLevels)
|
||||
{
|
||||
RealD impl_plaq =
|
||||
WilsonLoops<Gimpl>::avgPlaquette(SmearedSet[smearingLevels - 1]);
|
||||
WilsonLoops<Gimpl>::avgPlaquette(SmearedSet[smearingLevels - 1]);
|
||||
std::cout << GridLogDebug << "getting Usmr Plaq: " << impl_plaq
|
||||
<< std::endl;
|
||||
return get_SmearedU();
|
||||
@@ -309,7 +304,6 @@ public:
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
NAMESPACE_END(Grid);
|
||||
|
||||
|
@@ -1,5 +1,4 @@
|
||||
#ifndef GRID_QCD_SMEARING_H
|
||||
#define GRID_QCD_SMEARING_H
|
||||
#pragma once
|
||||
|
||||
#include <Grid/qcd/smearing/BaseSmearing.h>
|
||||
#include <Grid/qcd/smearing/APEsmearing.h>
|
||||
@@ -7,4 +6,3 @@
|
||||
#include <Grid/qcd/smearing/GaugeConfiguration.h>
|
||||
#include <Grid/qcd/smearing/WilsonFlow.h>
|
||||
|
||||
#endif
|
||||
|
@@ -31,11 +31,9 @@
|
||||
@file StoutSmearing.h
|
||||
@brief Declares Stout smearing class
|
||||
*/
|
||||
#ifndef STOUT_SMEAR_
|
||||
#define STOUT_SMEAR_
|
||||
#pragma once
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
NAMESPACE_BEGIN(Grid);
|
||||
|
||||
/*! @brief Stout smearing of link variable. */
|
||||
template <class Gimpl>
|
||||
@@ -90,8 +88,8 @@ public:
|
||||
~Smear_Stout() {} // delete SmearBase...
|
||||
|
||||
void smear(GaugeField& u_smr, const GaugeField& U) const {
|
||||
GaugeField C(U._grid);
|
||||
GaugeLinkField tmp(U._grid), iq_mu(U._grid), Umu(U._grid);
|
||||
GaugeField C(U.Grid());
|
||||
GaugeLinkField tmp(U.Grid()), iq_mu(U.Grid()), Umu(U.Grid());
|
||||
|
||||
std::cout << GridLogDebug << "Stout smearing started" << std::endl;
|
||||
|
||||
@@ -136,7 +134,7 @@ public:
|
||||
// the i sign is coming from outside
|
||||
// input matrix is anti-hermitian NOT hermitian
|
||||
|
||||
GridBase* grid = iQ._grid;
|
||||
GridBase* grid = iQ.Grid();
|
||||
GaugeLinkField unity(grid);
|
||||
unity = 1.0;
|
||||
|
||||
@@ -159,7 +157,7 @@ public:
|
||||
Complex one_over_three = 1.0 / 3.0;
|
||||
Complex one_over_two = 1.0 / 2.0;
|
||||
|
||||
GridBase* grid = u._grid;
|
||||
GridBase* grid = u.Grid();
|
||||
LatticeComplex c0(grid), c1(grid), tmp(grid), c0max(grid), theta(grid);
|
||||
|
||||
// sign in c0 from the conventions on the Ta
|
||||
@@ -178,7 +176,7 @@ public:
|
||||
|
||||
void set_fj(LatticeComplex& f0, LatticeComplex& f1, LatticeComplex& f2,
|
||||
const LatticeComplex& u, const LatticeComplex& w) const {
|
||||
GridBase* grid = u._grid;
|
||||
GridBase* grid = u.Grid();
|
||||
LatticeComplex xi0(grid), u2(grid), w2(grid), cosw(grid);
|
||||
LatticeComplex fden(grid);
|
||||
LatticeComplex h0(grid), h1(grid), h2(grid);
|
||||
@@ -219,7 +217,5 @@ public:
|
||||
return cos(w) / (w * w) - sin(w) / (w * w * w);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
NAMESPACE_END(Grid);
|
||||
|
@@ -25,59 +25,57 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
See the full license in the file "LICENSE" in the top level distribution
|
||||
directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
/* END LEGAL */
|
||||
|
||||
#ifndef WILSONFLOW_H
|
||||
#define WILSONFLOW_H
|
||||
#pragma once
|
||||
|
||||
namespace Grid {
|
||||
namespace QCD {
|
||||
NAMESPACE_BEGIN(Grid);
|
||||
|
||||
template <class Gimpl>
|
||||
class WilsonFlow: public Smear<Gimpl>{
|
||||
unsigned int Nstep;
|
||||
unsigned int measure_interval;
|
||||
mutable RealD epsilon, taus;
|
||||
unsigned int Nstep;
|
||||
unsigned int measure_interval;
|
||||
mutable RealD epsilon, taus;
|
||||
|
||||
|
||||
mutable WilsonGaugeAction<Gimpl> SG;
|
||||
mutable WilsonGaugeAction<Gimpl> SG;
|
||||
|
||||
void evolve_step(typename Gimpl::GaugeField&) const;
|
||||
void evolve_step_adaptive(typename Gimpl::GaugeField&, RealD);
|
||||
RealD tau(unsigned int t)const {return epsilon*(t+1.0); }
|
||||
void evolve_step(typename Gimpl::GaugeField&) const;
|
||||
void evolve_step_adaptive(typename Gimpl::GaugeField&, RealD);
|
||||
RealD tau(unsigned int t)const {return epsilon*(t+1.0); }
|
||||
|
||||
public:
|
||||
INHERIT_GIMPL_TYPES(Gimpl)
|
||||
public:
|
||||
INHERIT_GIMPL_TYPES(Gimpl)
|
||||
|
||||
explicit WilsonFlow(unsigned int Nstep, RealD epsilon, unsigned int interval = 1):
|
||||
Nstep(Nstep),
|
||||
epsilon(epsilon),
|
||||
measure_interval(interval),
|
||||
SG(WilsonGaugeAction<Gimpl>(3.0)) {
|
||||
// WilsonGaugeAction with beta 3.0
|
||||
assert(epsilon > 0.0);
|
||||
LogMessage();
|
||||
}
|
||||
explicit WilsonFlow(unsigned int Nstep, RealD epsilon, unsigned int interval = 1):
|
||||
Nstep(Nstep),
|
||||
epsilon(epsilon),
|
||||
measure_interval(interval),
|
||||
SG(WilsonGaugeAction<Gimpl>(3.0)) {
|
||||
// WilsonGaugeAction with beta 3.0
|
||||
assert(epsilon > 0.0);
|
||||
LogMessage();
|
||||
}
|
||||
|
||||
void LogMessage() {
|
||||
std::cout << GridLogMessage
|
||||
<< "[WilsonFlow] Nstep : " << Nstep << std::endl;
|
||||
std::cout << GridLogMessage
|
||||
<< "[WilsonFlow] epsilon : " << epsilon << std::endl;
|
||||
std::cout << GridLogMessage
|
||||
<< "[WilsonFlow] full trajectory : " << Nstep * epsilon << std::endl;
|
||||
}
|
||||
void LogMessage() {
|
||||
std::cout << GridLogMessage
|
||||
<< "[WilsonFlow] Nstep : " << Nstep << std::endl;
|
||||
std::cout << GridLogMessage
|
||||
<< "[WilsonFlow] epsilon : " << epsilon << std::endl;
|
||||
std::cout << GridLogMessage
|
||||
<< "[WilsonFlow] full trajectory : " << Nstep * epsilon << std::endl;
|
||||
}
|
||||
|
||||
virtual void smear(GaugeField&, const GaugeField&) const;
|
||||
virtual void smear(GaugeField&, const GaugeField&) const;
|
||||
|
||||
virtual void derivative(GaugeField&, const GaugeField&, const GaugeField&) const {
|
||||
assert(0);
|
||||
// undefined for WilsonFlow
|
||||
}
|
||||
virtual void derivative(GaugeField&, const GaugeField&, const GaugeField&) const {
|
||||
assert(0);
|
||||
// undefined for WilsonFlow
|
||||
}
|
||||
|
||||
void smear_adaptive(GaugeField&, const GaugeField&, RealD maxTau);
|
||||
RealD energyDensityPlaquette(unsigned int step, const GaugeField& U) const;
|
||||
RealD energyDensityPlaquette(const GaugeField& U) const;
|
||||
void smear_adaptive(GaugeField&, const GaugeField&, RealD maxTau);
|
||||
RealD energyDensityPlaquette(unsigned int step, const GaugeField& U) const;
|
||||
RealD energyDensityPlaquette(const GaugeField& U) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -86,74 +84,74 @@ class WilsonFlow: public Smear<Gimpl>{
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <class Gimpl>
|
||||
void WilsonFlow<Gimpl>::evolve_step(typename Gimpl::GaugeField &U) const{
|
||||
GaugeField Z(U._grid);
|
||||
GaugeField tmp(U._grid);
|
||||
SG.deriv(U, Z);
|
||||
Z *= 0.25; // Z0 = 1/4 * F(U)
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // U = W1 = exp(ep*Z0)*W0
|
||||
GaugeField Z(U.Grid());
|
||||
GaugeField tmp(U.Grid());
|
||||
SG.deriv(U, Z);
|
||||
Z *= 0.25; // Z0 = 1/4 * F(U)
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // U = W1 = exp(ep*Z0)*W0
|
||||
|
||||
Z *= -17.0/8.0;
|
||||
SG.deriv(U, tmp); Z += tmp; // -17/32*Z0 +Z1
|
||||
Z *= 8.0/9.0; // Z = -17/36*Z0 +8/9*Z1
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // U_= W2 = exp(ep*Z)*W1
|
||||
Z *= -17.0/8.0;
|
||||
SG.deriv(U, tmp); Z += tmp; // -17/32*Z0 +Z1
|
||||
Z *= 8.0/9.0; // Z = -17/36*Z0 +8/9*Z1
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // U_= W2 = exp(ep*Z)*W1
|
||||
|
||||
Z *= -4.0/3.0;
|
||||
SG.deriv(U, tmp); Z += tmp; // 4/3*(17/36*Z0 -8/9*Z1) +Z2
|
||||
Z *= 3.0/4.0; // Z = 17/36*Z0 -8/9*Z1 +3/4*Z2
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // V(t+e) = exp(ep*Z)*W2
|
||||
Z *= -4.0/3.0;
|
||||
SG.deriv(U, tmp); Z += tmp; // 4/3*(17/36*Z0 -8/9*Z1) +Z2
|
||||
Z *= 3.0/4.0; // Z = 17/36*Z0 -8/9*Z1 +3/4*Z2
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // V(t+e) = exp(ep*Z)*W2
|
||||
}
|
||||
|
||||
template <class Gimpl>
|
||||
void WilsonFlow<Gimpl>::evolve_step_adaptive(typename Gimpl::GaugeField &U, RealD maxTau) {
|
||||
if (maxTau - taus < epsilon){
|
||||
epsilon = maxTau-taus;
|
||||
}
|
||||
//std::cout << GridLogMessage << "Integration epsilon : " << epsilon << std::endl;
|
||||
GaugeField Z(U._grid);
|
||||
GaugeField Zprime(U._grid);
|
||||
GaugeField tmp(U._grid), Uprime(U._grid);
|
||||
Uprime = U;
|
||||
SG.deriv(U, Z);
|
||||
Zprime = -Z;
|
||||
Z *= 0.25; // Z0 = 1/4 * F(U)
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // U = W1 = exp(ep*Z0)*W0
|
||||
if (maxTau - taus < epsilon){
|
||||
epsilon = maxTau-taus;
|
||||
}
|
||||
//std::cout << GridLogMessage << "Integration epsilon : " << epsilon << std::endl;
|
||||
GaugeField Z(U.Grid());
|
||||
GaugeField Zprime(U.Grid());
|
||||
GaugeField tmp(U.Grid()), Uprime(U.Grid());
|
||||
Uprime = U;
|
||||
SG.deriv(U, Z);
|
||||
Zprime = -Z;
|
||||
Z *= 0.25; // Z0 = 1/4 * F(U)
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // U = W1 = exp(ep*Z0)*W0
|
||||
|
||||
Z *= -17.0/8.0;
|
||||
SG.deriv(U, tmp); Z += tmp; // -17/32*Z0 +Z1
|
||||
Zprime += 2.0*tmp;
|
||||
Z *= 8.0/9.0; // Z = -17/36*Z0 +8/9*Z1
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // U_= W2 = exp(ep*Z)*W1
|
||||
Z *= -17.0/8.0;
|
||||
SG.deriv(U, tmp); Z += tmp; // -17/32*Z0 +Z1
|
||||
Zprime += 2.0*tmp;
|
||||
Z *= 8.0/9.0; // Z = -17/36*Z0 +8/9*Z1
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // U_= W2 = exp(ep*Z)*W1
|
||||
|
||||
|
||||
Z *= -4.0/3.0;
|
||||
SG.deriv(U, tmp); Z += tmp; // 4/3*(17/36*Z0 -8/9*Z1) +Z2
|
||||
Z *= 3.0/4.0; // Z = 17/36*Z0 -8/9*Z1 +3/4*Z2
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // V(t+e) = exp(ep*Z)*W2
|
||||
Z *= -4.0/3.0;
|
||||
SG.deriv(U, tmp); Z += tmp; // 4/3*(17/36*Z0 -8/9*Z1) +Z2
|
||||
Z *= 3.0/4.0; // Z = 17/36*Z0 -8/9*Z1 +3/4*Z2
|
||||
Gimpl::update_field(Z, U, -2.0*epsilon); // V(t+e) = exp(ep*Z)*W2
|
||||
|
||||
// Ramos
|
||||
Gimpl::update_field(Zprime, Uprime, -2.0*epsilon); // V'(t+e) = exp(ep*Z')*W0
|
||||
// Compute distance as norm^2 of the difference
|
||||
GaugeField diffU = U - Uprime;
|
||||
RealD diff = norm2(diffU);
|
||||
// adjust integration step
|
||||
// Ramos
|
||||
Gimpl::update_field(Zprime, Uprime, -2.0*epsilon); // V'(t+e) = exp(ep*Z')*W0
|
||||
// Compute distance as norm^2 of the difference
|
||||
GaugeField diffU = U - Uprime;
|
||||
RealD diff = norm2(diffU);
|
||||
// adjust integration step
|
||||
|
||||
taus += epsilon;
|
||||
//std::cout << GridLogMessage << "Adjusting integration step with distance: " << diff << std::endl;
|
||||
taus += epsilon;
|
||||
//std::cout << GridLogMessage << "Adjusting integration step with distance: " << diff << std::endl;
|
||||
|
||||
epsilon = epsilon*0.95*std::pow(1e-4/diff,1./3.);
|
||||
//std::cout << GridLogMessage << "New epsilon : " << epsilon << std::endl;
|
||||
epsilon = epsilon*0.95*std::pow(1e-4/diff,1./3.);
|
||||
//std::cout << GridLogMessage << "New epsilon : " << epsilon << std::endl;
|
||||
|
||||
}
|
||||
|
||||
template <class Gimpl>
|
||||
RealD WilsonFlow<Gimpl>::energyDensityPlaquette(unsigned int step, const GaugeField& U) const {
|
||||
RealD td = tau(step);
|
||||
return 2.0 * td * td * SG.S(U)/U._grid->gSites();
|
||||
RealD td = tau(step);
|
||||
return 2.0 * td * td * SG.S(U)/U.Grid()->gSites();
|
||||
}
|
||||
|
||||
template <class Gimpl>
|
||||
RealD WilsonFlow<Gimpl>::energyDensityPlaquette(const GaugeField& U) const {
|
||||
return 2.0 * taus * taus * SG.S(U)/U._grid->gSites();
|
||||
return 2.0 * taus * taus * SG.S(U)/U.Grid()->gSites();
|
||||
}
|
||||
|
||||
|
||||
@@ -163,51 +161,48 @@ RealD WilsonFlow<Gimpl>::energyDensityPlaquette(const GaugeField& U) const {
|
||||
|
||||
template <class Gimpl>
|
||||
void WilsonFlow<Gimpl>::smear(GaugeField& out, const GaugeField& in) const {
|
||||
out = in;
|
||||
for (unsigned int step = 1; step <= Nstep; step++) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
evolve_step(out);
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> diff = end - start;
|
||||
#ifdef WF_TIMING
|
||||
std::cout << "Time to evolve " << diff.count() << " s\n";
|
||||
#endif
|
||||
std::cout << GridLogMessage << "[WilsonFlow] Energy density (plaq) : "
|
||||
out = in;
|
||||
for (unsigned int step = 1; step <= Nstep; step++) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
evolve_step(out);
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> diff = end - start;
|
||||
#ifdef WF_TIMING
|
||||
std::cout << "Time to evolve " << diff.count() << " s\n";
|
||||
#endif
|
||||
std::cout << GridLogMessage << "[WilsonFlow] Energy density (plaq) : "
|
||||
<< step << " " << tau(step) << " "
|
||||
<< energyDensityPlaquette(step,out) << std::endl;
|
||||
if( step % measure_interval == 0){
|
||||
std::cout << GridLogMessage << "[WilsonFlow] Top. charge : "
|
||||
<< step << " "
|
||||
<< WilsonLoops<PeriodicGimplR>::TopologicalCharge(out) << std::endl;
|
||||
}
|
||||
<< energyDensityPlaquette(step,out) << std::endl;
|
||||
if( step % measure_interval == 0){
|
||||
std::cout << GridLogMessage << "[WilsonFlow] Top. charge : "
|
||||
<< step << " "
|
||||
<< WilsonLoops<PeriodicGimplR>::TopologicalCharge(out) << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Gimpl>
|
||||
void WilsonFlow<Gimpl>::smear_adaptive(GaugeField& out, const GaugeField& in, RealD maxTau){
|
||||
out = in;
|
||||
taus = epsilon;
|
||||
unsigned int step = 0;
|
||||
do{
|
||||
step++;
|
||||
//std::cout << GridLogMessage << "Evolution time :"<< taus << std::endl;
|
||||
evolve_step_adaptive(out, maxTau);
|
||||
std::cout << GridLogMessage << "[WilsonFlow] Energy density (plaq) : "
|
||||
out = in;
|
||||
taus = epsilon;
|
||||
unsigned int step = 0;
|
||||
do{
|
||||
step++;
|
||||
//std::cout << GridLogMessage << "Evolution time :"<< taus << std::endl;
|
||||
evolve_step_adaptive(out, maxTau);
|
||||
std::cout << GridLogMessage << "[WilsonFlow] Energy density (plaq) : "
|
||||
<< step << " " << taus << " "
|
||||
<< energyDensityPlaquette(out) << std::endl;
|
||||
if( step % measure_interval == 0){
|
||||
std::cout << GridLogMessage << "[WilsonFlow] Top. charge : "
|
||||
<< step << " "
|
||||
<< WilsonLoops<PeriodicGimplR>::TopologicalCharge(out) << std::endl;
|
||||
}
|
||||
} while (taus < maxTau);
|
||||
<< energyDensityPlaquette(out) << std::endl;
|
||||
if( step % measure_interval == 0){
|
||||
std::cout << GridLogMessage << "[WilsonFlow] Top. charge : "
|
||||
<< step << " "
|
||||
<< WilsonLoops<PeriodicGimplR>::TopologicalCharge(out) << std::endl;
|
||||
}
|
||||
} while (taus < maxTau);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
NAMESPACE_END(Grid);
|
||||
|
||||
} // namespace QCD
|
||||
} // namespace Grid
|
||||
|
||||
#endif // WILSONFLOW_H
|
||||
|
Reference in New Issue
Block a user