/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/action/fermion/FermionOperatorImpl.h Copyright (C) 2015 Author: Peter Boyle 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 */ #pragma once NAMESPACE_BEGIN(Grid); ///////////////////////////////////////////////////////////////////////////// // Single flavour four spinors with colour index ///////////////////////////////////////////////////////////////////////////// template class WilsonImpl : public PeriodicGaugeImpl > { public: static const int Dimension = Representation::Dimension; static const bool isFundamental = Representation::isFundamental; static const bool LsVectorised=false; static const bool isGparity=false; static const int Nhcs = Options::Nhcs; typedef PeriodicGaugeImpl > Gimpl; INHERIT_GIMPL_TYPES(Gimpl); //Necessary? constexpr bool is_fundamental() const{return Dimension == Nc ? 1 : 0;} typedef typename Options::_Coeff_t Coeff_t; typedef typename Options::template PrecisionMapper::LowerPrecVector SimdL; template using iImplSpinor = iScalar, Ns> >; template using iImplPropagator = iScalar, Ns> >; template using iImplHalfSpinor = iScalar, Nhs> >; template using iImplHalfCommSpinor = iScalar, Nhcs> >; template using iImplDoubledGaugeField = iVector >, Nds>; typedef iImplSpinor SiteSpinor; typedef iImplPropagator SitePropagator; typedef iImplHalfSpinor SiteHalfSpinor; typedef iImplHalfCommSpinor SiteHalfCommSpinor; typedef iImplDoubledGaugeField SiteDoubledGaugeField; typedef Lattice FermionField; typedef Lattice PropagatorField; typedef Lattice DoubledGaugeField; typedef WilsonCompressor Compressor; typedef WilsonImplParams ImplParams; typedef WilsonStencil StencilImpl; typedef const typename StencilImpl::View_type StencilView; ImplParams Params; WilsonImpl(const ImplParams &p = ImplParams()) : Params(p){ assert(Params.boundary_phases.size() == Nd); }; template static accelerator_inline void multLink(_Spinor &phi, const SiteDoubledGaugeField &U, const _Spinor &chi, int mu) { auto UU = coalescedRead(U(mu)); mult(&phi(), &UU, &chi()); } template static accelerator_inline void multLink(_Spinor &phi, const SiteDoubledGaugeField &U, const _Spinor &chi, int mu, StencilEntry *SE, StencilView &St) { multLink(phi,U,chi,mu); } template inline void multLinkField(_SpinorField & out, const DoubledGaugeField &Umu, const _SpinorField & phi, int mu) { const int Nsimd = SiteHalfSpinor::Nsimd(); autoView( out_v, out, AcceleratorWrite); autoView( phi_v, phi, AcceleratorRead); autoView( Umu_v, Umu, AcceleratorRead); typedef decltype(coalescedRead(out_v[0])) calcSpinor; accelerator_for(sss,out.Grid()->oSites(),Nsimd,{ calcSpinor tmp; multLink(tmp,Umu_v[sss],phi_v(sss),mu); coalescedWrite(out_v[sss],tmp); }); } template static accelerator_inline void loadLinkElement(Simd ®, ref &memory) { reg = memory; } inline void DoubleStore(GridBase *GaugeGrid, DoubledGaugeField &Uds, const GaugeField &Umu) { typedef typename Simd::scalar_type scalar_type; conformable(Uds.Grid(), GaugeGrid); conformable(Umu.Grid(), GaugeGrid); GaugeLinkField U(GaugeGrid); GaugeLinkField tmp(GaugeGrid); Lattice > coor(GaugeGrid); //////////////////////////////////////////////////// // apply any boundary phase or twists //////////////////////////////////////////////////// for (int mu = 0; mu < Nd; mu++) { ////////// boundary phase ///////////// auto pha = Params.boundary_phases[mu]; scalar_type phase( real(pha),imag(pha) ); int L = GaugeGrid->GlobalDimensions()[mu]; int Lmu = L - 1; LatticeCoordinate(coor, mu); U = PeekIndex(Umu, mu); // apply any twists RealD theta = Params.twist_n_2pi_L[mu] * 2*M_PI / L; if ( theta != 0.0) { scalar_type twphase(::cos(theta),::sin(theta)); U = twphase*U; std::cout << GridLogMessage << " Twist ["<(Uds, tmp, mu); U = adj(Cshift(U, mu, -1)); U = where(coor == 0, conjugate(phase) * U, U); PokeIndex(Uds, U, mu + 4); } } inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A,int mu){ GaugeLinkField link(mat.Grid()); link = TraceIndex(outerProduct(Btilde,A)); PokeIndex(mat,link,mu); } inline void outerProductImpl(PropagatorField &mat, const FermionField &B, const FermionField &A){ mat = outerProduct(B,A); } inline void TraceSpinImpl(GaugeLinkField &mat, PropagatorField&P) { mat = TraceIndex(P); } inline void extractLinkField(std::vector &mat, DoubledGaugeField &Uds) { for (int mu = 0; mu < Nd; mu++) mat[mu] = PeekIndex(Uds, mu); } inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã,int mu) { #undef USE_OLD_INSERT_FORCE int Ls=Btilde.Grid()->_fdimensions[0]; autoView( mat_v , mat, AcceleratorWrite); #ifdef USE_OLD_INSERT_FORCE GaugeLinkField tmp(mat.Grid()); tmp = Zero(); { const int Nsimd = SiteSpinor::Nsimd(); autoView( tmp_v , tmp, AcceleratorWrite); autoView( Btilde_v , Btilde, AcceleratorRead); autoView( Atilde_v , Atilde, AcceleratorRead); accelerator_for(sss,tmp.Grid()->oSites(),1,{ int sU=sss; for(int s=0;s(outerProduct(Btilde_v[sF],Atilde_v[sF])); // ordering here } }); } PokeIndex(mat,tmp,mu); #else { const int Nsimd = SiteSpinor::Nsimd(); autoView( Btilde_v , Btilde, AcceleratorRead); autoView( Atilde_v , Atilde, AcceleratorRead); accelerator_for(sss,mat.Grid()->oSites(),Nsimd,{ int sU=sss; typedef decltype(coalescedRead(mat_v[sU](mu)() )) ColorMatrixType; ColorMatrixType sum; zeroit(sum); for(int s=0;s WilsonImplR; // Real.. whichever prec typedef WilsonImpl WilsonImplF; // Float typedef WilsonImpl WilsonImplD; // Double typedef WilsonImpl WilsonImplD2; // Double typedef WilsonImpl ZWilsonImplR; // Real.. whichever prec typedef WilsonImpl ZWilsonImplF; // Float typedef WilsonImpl ZWilsonImplD; // Double typedef WilsonImpl ZWilsonImplD2; // Double typedef WilsonImpl WilsonAdjImplR; // Real.. whichever prec typedef WilsonImpl WilsonAdjImplF; // Float typedef WilsonImpl WilsonAdjImplD; // Double typedef WilsonImpl WilsonTwoIndexSymmetricImplR; // Real.. whichever prec typedef WilsonImpl WilsonTwoIndexSymmetricImplF; // Float typedef WilsonImpl WilsonTwoIndexSymmetricImplD; // Double typedef WilsonImpl WilsonTwoIndexAntiSymmetricImplR; // Real.. whichever prec typedef WilsonImpl WilsonTwoIndexAntiSymmetricImplF; // Float typedef WilsonImpl WilsonTwoIndexAntiSymmetricImplD; // Double NAMESPACE_END(Grid);