/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/action/gauge/GaugeImpl.h Copyright (C) 2015 Author: paboyle 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 */ #ifndef GRID_QCD_GAUGE_IMPL_H #define GRID_QCD_GAUGE_IMPL_H namespace Grid { namespace QCD { //////////////////////////////////////////////////////////////////////// // Implementation dependent gauge types //////////////////////////////////////////////////////////////////////// template class WilsonLoops; // #define INHERIT_GIMPL_TYPES(GImpl) \ typedef typename GImpl::Simd Simd; \ typedef typename GImpl::LinkField GaugeLinkField; \ typedef typename GImpl::Field GaugeField; \ typedef typename GImpl::SiteField SiteGaugeField; \ typedef typename GImpl::SiteLink SiteGaugeLink; #define INHERIT_FIELD_TYPES(Impl) \ typedef typename Impl::Simd Simd; \ typedef typename Impl::SiteField SiteField; \ typedef typename Impl::Field Field; // hard codes the exponential approximation in the template template class GaugeImplTypes { public: typedef S Simd; template using iImplGaugeLink = iScalar>>; template using iImplGaugeField = iVector>, Nd>; typedef iImplGaugeLink SiteLink; typedef iImplGaugeField SiteField; typedef Lattice LinkField; typedef Lattice Field; // Move this elsewhere? FIXME static inline void AddLink(Field &U, LinkField &W, int mu) { // U[mu] += W PARALLEL_FOR_LOOP for (auto ss = 0; ss < U._grid->oSites(); ss++) { U._odata[ss]._internal[mu] = U._odata[ss]._internal[mu] + W._odata[ss]._internal; } } /////////////////////////////////////////////////////////// // Move these to another class // HMC auxiliary functions static inline void generate_momenta(Field& P, GridParallelRNG& pRNG){ // specific for SU gauge fields LinkField Pmu(P._grid); Pmu = zero; for (int mu = 0; mu < Nd; mu++) { SU::GaussianFundamentalLieAlgebraMatrix(pRNG, Pmu); PokeIndex(P, Pmu, mu); } } static inline Field projectForce(Field& P){ return Ta(P); } static inline void update_field(Field& P, Field& U, double ep){ for (int mu = 0; mu < Nd; mu++) { auto Umu = PeekIndex(U, mu); auto Pmu = PeekIndex(P, mu); Umu = expMat(Pmu, ep, Nexp) * Umu; PokeIndex(U, ProjectOnGroup(Umu), mu); } } static inline RealD FieldSquareNorm(Field& U){ LatticeComplex Hloc(U._grid); Hloc = zero; for (int mu = 0; mu < Nd; mu++) { auto Umu = PeekIndex(U, mu); Hloc += trace(Umu * Umu); } Complex Hsum = sum(Hloc); return Hsum.real(); } static inline void HotConfiguration(GridParallelRNG &pRNG, Field &U) { SU::HotConfiguration(pRNG, U); } static inline void TepidConfiguration(GridParallelRNG &pRNG, Field &U) { SU::TepidConfiguration(pRNG, U); } static inline void ColdConfiguration(GridParallelRNG &pRNG, Field &U) { SU::ColdConfiguration(pRNG, U); } }; // Composition with smeared link, bc's etc.. probably need multiple inheritance // Variable precision "S" and variable Nc template class PeriodicGaugeImpl : public GimplTypes { public: INHERIT_GIMPL_TYPES(GimplTypes); //////////////////////////////////////////////////////////////////////////////////////////////////////////// // Support needed for the assembly of loops including all boundary condition // effects such as conjugate bcs //////////////////////////////////////////////////////////////////////////////////////////////////////////// template static inline Lattice CovShiftForward(const GaugeLinkField &Link, int mu, const Lattice &field) { return PeriodicBC::CovShiftForward(Link, mu, field); } template static inline Lattice CovShiftBackward(const GaugeLinkField &Link, int mu, const Lattice &field) { return PeriodicBC::CovShiftBackward(Link, mu, field); } static inline GaugeLinkField CovShiftIdentityBackward(const GaugeLinkField &Link, int mu) { return Cshift(adj(Link), mu, -1); } static inline GaugeLinkField CovShiftIdentityForward(const GaugeLinkField &Link, int mu) { return Link; } static inline GaugeLinkField ShiftStaple(const GaugeLinkField &Link, int mu) { return Cshift(Link, mu, 1); } static inline bool isPeriodicGaugeField(void) { return true; } }; // Composition with smeared link, bc's etc.. probably need multiple inheritance // Variable precision "S" and variable Nc template class ConjugateGaugeImpl : public GimplTypes { public: INHERIT_GIMPL_TYPES(GimplTypes); //////////////////////////////////////////////////////////////////////////////////////////////////////////// // Support needed for the assembly of loops including all boundary condition // effects such as Gparity. //////////////////////////////////////////////////////////////////////////////////////////////////////////// template static Lattice CovShiftForward(const GaugeLinkField &Link, int mu, const Lattice &field) { return ConjugateBC::CovShiftForward(Link, mu, field); } template static Lattice CovShiftBackward(const GaugeLinkField &Link, int mu, const Lattice &field) { return ConjugateBC::CovShiftBackward(Link, mu, field); } static inline GaugeLinkField CovShiftIdentityBackward(const GaugeLinkField &Link, int mu) { GridBase *grid = Link._grid; int Lmu = grid->GlobalDimensions()[mu] - 1; Lattice> coor(grid); LatticeCoordinate(coor, mu); GaugeLinkField tmp(grid); tmp = adj(Link); tmp = where(coor == Lmu, conjugate(tmp), tmp); return Cshift(tmp, mu, -1); // moves towards positive mu } static inline GaugeLinkField CovShiftIdentityForward(const GaugeLinkField &Link, int mu) { return Link; } static inline GaugeLinkField ShiftStaple(const GaugeLinkField &Link, int mu) { GridBase *grid = Link._grid; int Lmu = grid->GlobalDimensions()[mu] - 1; Lattice> coor(grid); LatticeCoordinate(coor, mu); GaugeLinkField tmp(grid); tmp = Cshift(Link, mu, 1); tmp = where(coor == Lmu, conjugate(tmp), tmp); return tmp; } static inline bool isPeriodicGaugeField(void) { return false; } }; typedef GaugeImplTypes GimplTypesR; typedef GaugeImplTypes GimplTypesF; typedef GaugeImplTypes GimplTypesD; typedef GaugeImplTypes::AdjointDimension> GimplAdjointTypesR; typedef GaugeImplTypes::AdjointDimension> GimplAdjointTypesF; typedef GaugeImplTypes::AdjointDimension> GimplAdjointTypesD; typedef PeriodicGaugeImpl PeriodicGimplR; // Real.. whichever prec typedef PeriodicGaugeImpl PeriodicGimplF; // Float typedef PeriodicGaugeImpl PeriodicGimplD; // Double typedef PeriodicGaugeImpl PeriodicGimplAdjR; // Real.. whichever prec typedef PeriodicGaugeImpl PeriodicGimplAdjF; // Float typedef PeriodicGaugeImpl PeriodicGimplAdjD; // Double typedef ConjugateGaugeImpl ConjugateGimplR; // Real.. whichever prec typedef ConjugateGaugeImpl ConjugateGimplF; // Float typedef ConjugateGaugeImpl ConjugateGimplD; // Double } } #endif