/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/qcd/action/fermion/CayleyFermion5D.cc Copyright (C) 2015 Author: Peter Boyle Author: Peter Boyle Author: Peter Boyle 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 */ #include #include #include NAMESPACE_BEGIN(Grid); template CayleyFermion5D::CayleyFermion5D(GaugeField &_Umu, GridCartesian &FiveDimGrid, GridRedBlackCartesian &FiveDimRedBlackGrid, GridCartesian &FourDimGrid, GridRedBlackCartesian &FourDimRedBlackGrid, RealD _mass,RealD _M5,const ImplParams &p) : WilsonFermion5D(_Umu, FiveDimGrid, FiveDimRedBlackGrid, FourDimGrid, FourDimRedBlackGrid,_M5,p), mass_plus(_mass), mass_minus(_mass) { } /////////////////////////////////////////////////////////////// // Physical surface field utilities /////////////////////////////////////////////////////////////// template void CayleyFermion5D::ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d) { int Ls = this->Ls; FermionField tmp(this->FermionGrid()); tmp = solution5d; conformable(solution5d.Grid(),this->FermionGrid()); conformable(exported4d.Grid(),this->GaugeGrid()); axpby_ssp_pminus(tmp, 0., solution5d, 1., solution5d, 0, 0); axpby_ssp_pplus (tmp, 1., tmp , 1., solution5d, 0, Ls-1); ExtractSlice(exported4d, tmp, 0, 0); } template void CayleyFermion5D::P(const FermionField &psi, FermionField &chi) { int Ls= this->Ls; chi=Zero(); for(int s=0;s void CayleyFermion5D::Pdag(const FermionField &psi, FermionField &chi) { int Ls= this->Ls; chi=Zero(); for(int s=0;s void CayleyFermion5D::ExportPhysicalFermionSource(const FermionField &solution5d,FermionField &exported4d) { int Ls = this->Ls; FermionField tmp(this->FermionGrid()); tmp = solution5d; conformable(solution5d.Grid(),this->FermionGrid()); conformable(exported4d.Grid(),this->GaugeGrid()); axpby_ssp_pplus (tmp, 0., solution5d, 1., solution5d, 0, 0); axpby_ssp_pminus(tmp, 1., tmp , 1., solution5d, 0, Ls-1); ExtractSlice(exported4d, tmp, 0, 0); } template void CayleyFermion5D::ImportUnphysicalFermion(const FermionField &input4d,FermionField &imported5d) { int Ls = this->Ls; FermionField tmp(this->FermionGrid()); conformable(imported5d.Grid(),this->FermionGrid()); conformable(input4d.Grid() ,this->GaugeGrid()); tmp = Zero(); InsertSlice(input4d, tmp, 0 , 0); InsertSlice(input4d, tmp, Ls-1, 0); axpby_ssp_pplus (tmp, 0., tmp, 1., tmp, 0, 0); axpby_ssp_pminus(tmp, 0., tmp, 1., tmp, Ls-1, Ls-1); imported5d=tmp; } template void CayleyFermion5D::ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d) { int Ls = this->Ls; FermionField tmp(this->FermionGrid()); conformable(imported5d.Grid(),this->FermionGrid()); conformable(input4d.Grid() ,this->GaugeGrid()); tmp = Zero(); InsertSlice(input4d, tmp, 0 , 0); InsertSlice(input4d, tmp, Ls-1, 0); axpby_ssp_pplus (tmp, 0., tmp, 1., tmp, 0, 0); axpby_ssp_pminus(tmp, 0., tmp, 1., tmp, Ls-1, Ls-1); Dminus(tmp,imported5d); } template void CayleyFermion5D::Dminus(const FermionField &psi, FermionField &chi) { int Ls=this->Ls; FermionField tmp_f(this->FermionGrid()); this->DW(psi,tmp_f,DaggerNo); for(int s=0;s void CayleyFermion5D::DminusDag(const FermionField &psi, FermionField &chi) { int Ls=this->Ls; FermionField tmp_f(this->FermionGrid()); this->DW(psi,tmp_f,DaggerYes); for(int s=0;s void CayleyFermion5D::M5D (const FermionField &psi, FermionField &chi) { int Ls=this->Ls; Vector diag (Ls,1.0); Vector upper(Ls,-1.0); upper[Ls-1]=mass_minus; Vector lower(Ls,-1.0); lower[0] =mass_plus; M5D(psi,chi,chi,lower,diag,upper); } template void CayleyFermion5D::Meooe5D (const FermionField &psi, FermionField &Din) { int Ls=this->Ls; Vector diag = bs; Vector upper= cs; Vector lower= cs; upper[Ls-1]=-mass_minus*upper[Ls-1]; lower[0] =-mass_plus*lower[0]; M5D(psi,psi,Din,lower,diag,upper); } // FIXME Redunant with the above routine; check this and eliminate template void CayleyFermion5D::Meo5D (const FermionField &psi, FermionField &chi) { int Ls=this->Ls; Vector diag = beo; Vector upper(Ls); Vector lower(Ls); for(int i=0;i void CayleyFermion5D::Mooee (const FermionField &psi, FermionField &chi) { int Ls=this->Ls; Vector diag = bee; Vector upper(Ls); Vector lower(Ls); for(int i=0;i void CayleyFermion5D::MooeeDag (const FermionField &psi, FermionField &chi) { int Ls=this->Ls; Vector diag = bee; Vector upper(Ls); Vector lower(Ls); for (int s=0;s void CayleyFermion5D::M5Ddag (const FermionField &psi, FermionField &chi) { int Ls=this->Ls; Vector diag(Ls,1.0); Vector upper(Ls,-1.0); Vector lower(Ls,-1.0); upper[Ls-1]=-mass_plus*upper[Ls-1]; lower[0] =-mass_minus*lower[0]; M5Ddag(psi,chi,chi,lower,diag,upper); } template void CayleyFermion5D::MeooeDag5D (const FermionField &psi, FermionField &Din) { int Ls=this->Ls; Vector diag =bs; Vector upper=cs; Vector lower=cs; for (int s=0;s void CayleyFermion5D::M (const FermionField &psi, FermionField &chi) { FermionField Din(psi.Grid()); // Assemble Din Meooe5D(psi,Din); this->DW(Din,chi,DaggerNo); // ((b D_W + D_w hop terms +1) on s-diag axpby(chi,1.0,1.0,chi,psi); M5D(psi,chi); } template void CayleyFermion5D::Mdag (const FermionField &psi, FermionField &chi) { // Under adjoint //D1+ D1- P- -> D1+^dag P+ D2-^dag //D2- P+ D2+ P-D1-^dag D2+dag FermionField Din(psi.Grid()); // Apply Dw this->DW(psi,Din,DaggerYes); MeooeDag5D(Din,chi); M5Ddag(psi,chi); // ((b D_W + D_w hop terms +1) on s-diag axpby (chi,1.0,1.0,chi,psi); } // half checkerboard operations template void CayleyFermion5D::Meooe (const FermionField &psi, FermionField &chi) { Meooe5D(psi,this->tmp()); if ( psi.Checkerboard() == Odd ) { this->DhopEO(this->tmp(),chi,DaggerNo); } else { this->DhopOE(this->tmp(),chi,DaggerNo); } } template void CayleyFermion5D::MeooeDag (const FermionField &psi, FermionField &chi) { // Apply 4d dslash if ( psi.Checkerboard() == Odd ) { this->DhopEO(psi,this->tmp(),DaggerYes); } else { this->DhopOE(psi,this->tmp(),DaggerYes); } MeooeDag5D(this->tmp(),chi); } template void CayleyFermion5D::Mdir (const FermionField &psi, FermionField &chi,int dir,int disp) { FermionField tmp(psi.Grid()); Meo5D(psi,tmp); this->DhopDir(tmp,chi,dir,disp); } template void CayleyFermion5D::MdirAll(const FermionField &psi, std::vector &out) { FermionField tmp(psi.Grid()); Meo5D(psi,tmp); this->DhopDirAll(tmp,out); } // force terms; five routines; default to Dhop on diagonal template void CayleyFermion5D::MDeriv (GaugeField &mat,const FermionField &U,const FermionField &V,int dag) { FermionField Din(V.Grid()); if ( dag == DaggerNo ) { // U d/du [D_w D5] V = U d/du DW D5 V Meooe5D(V,Din); this->DhopDeriv(mat,U,Din,dag); } else { // U d/du [D_w D5]^dag V = U D5^dag d/du DW^dag Y // implicit adj on U in call Meooe5D(U,Din); this->DhopDeriv(mat,Din,V,dag); } }; template void CayleyFermion5D::MoeDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag) { FermionField Din(V.Grid()); if ( dag == DaggerNo ) { // U d/du [D_w D5] V = U d/du DW D5 V Meooe5D(V,Din); this->DhopDerivOE(mat,U,Din,dag); } else { // U d/du [D_w D5]^dag V = U D5^dag d/du DW^dag Y // implicit adj on U in call Meooe5D(U,Din); this->DhopDerivOE(mat,Din,V,dag); } }; template void CayleyFermion5D::MeoDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag) { FermionField Din(V.Grid()); if ( dag == DaggerNo ) { // U d/du [D_w D5] V = U d/du DW D5 V Meooe5D(V,Din); this->DhopDerivEO(mat,U,Din,dag); } else { // U d/du [D_w D5]^dag V = U D5^dag d/du DW^dag Y // implicit adj on U in call Meooe5D(U,Din); this->DhopDerivEO(mat,Din,V,dag); } }; // Tanh template void CayleyFermion5D::SetCoefficientsTanh(Approx::zolotarev_data *zdata,RealD b,RealD c) { Vector gamma(this->Ls); for(int s=0;sLs;s++) gamma[s] = zdata->gamma[s]; SetCoefficientsInternal(1.0,gamma,b,c); } //Zolo template void CayleyFermion5D::SetCoefficientsZolotarev(RealD zolo_hi,Approx::zolotarev_data *zdata,RealD b,RealD c) { Vector gamma(this->Ls); for(int s=0;sLs;s++) gamma[s] = zdata->gamma[s]; SetCoefficientsInternal(zolo_hi,gamma,b,c); } //Zolo template void CayleyFermion5D::SetCoefficientsInternal(RealD zolo_hi,Vector & gamma,RealD b,RealD c) { int Ls=this->Ls; /////////////////////////////////////////////////////////// // The Cayley coeffs (unprec) /////////////////////////////////////////////////////////// assert(gamma.size()==Ls); omega.resize(Ls); bs.resize(Ls); cs.resize(Ls); as.resize(Ls); // // Ts = ( [bs+cs]Dw )^-1 ( (bs+cs) Dw ) // -(g5 ------- -1 ) ( g5 --------- + 1 ) // ( {2+(bs-cs)Dw} ) ( 2+(bs-cs) Dw ) // // bs = 1/2( (1/omega_s + 1)*b + (1/omega - 1)*c ) = 1/2( 1/omega(b+c) + (b-c) ) // cs = 1/2( (1/omega_s - 1)*b + (1/omega + 1)*c ) = 1/2( 1/omega(b+c) - (b-c) ) // // bs+cs = 0.5*( 1/omega(b+c) + (b-c) + 1/omega(b+c) - (b-c) ) = 1/omega(b+c) // bs-cs = 0.5*( 1/omega(b+c) + (b-c) - 1/omega(b+c) + (b-c) ) = b-c // // So // // Ts = ( [b+c]Dw/omega_s )^-1 ( (b+c) Dw /omega_s ) // -(g5 ------- -1 ) ( g5 --------- + 1 ) // ( {2+(b-c)Dw} ) ( 2+(b-c) Dw ) // // Ts = ( [b+c]Dw )^-1 ( (b+c) Dw ) // -(g5 ------- -omega_s) ( g5 --------- + omega_s ) // ( {2+(b-c)Dw} ) ( 2+(b-c) Dw ) // double bpc = b+c; double bmc = b-c; _b = b; _c = c; _gamma = gamma; // Save the parameters so we can change mass later. _zolo_hi= zolo_hi; for(int i=0; i < Ls; i++){ as[i] = 1.0; omega[i] = _gamma[i]*_zolo_hi; //NB reciprocal relative to Chroma NEF code assert(omega[i]!=Coeff_t(0.0)); bs[i] = 0.5*(bpc/omega[i] + bmc); cs[i] = 0.5*(bpc/omega[i] - bmc); } //////////////////////////////////////////////////////// // Constants for the preconditioned matrix Cayley form //////////////////////////////////////////////////////// bee.resize(Ls); cee.resize(Ls); beo.resize(Ls); ceo.resize(Ls); for(int i=0;iM5) +1.0); assert(bee[i]!=Coeff_t(0.0)); cee[i]=as[i]*(1.0-cs[i]*(4.0-this->M5)); beo[i]=as[i]*bs[i]; ceo[i]=-as[i]*cs[i]; } aee.resize(Ls); aeo.resize(Ls); for(int i=0;iMooeeInternalCompute(0,inv,MatpInv,MatmInv); // this->MooeeInternalCompute(1,inv,MatpInvDag,MatmInvDag); } template void CayleyFermion5D::ContractJ5q(FermionField &q_in,ComplexField &J5q) { conformable(this->GaugeGrid(), J5q.Grid()); conformable(q_in.Grid(), this->FermionGrid()); Gamma G5(Gamma::Algebra::Gamma5); // 4d field int Ls = this->Ls; FermionField psi(this->GaugeGrid()); FermionField p_plus (this->GaugeGrid()); FermionField p_minus(this->GaugeGrid()); FermionField p(this->GaugeGrid()); ExtractSlice(p_plus , q_in, Ls/2-1 , 0); ExtractSlice(p_minus, q_in, Ls/2 , 0); p_plus = p_plus + G5*p_plus; p_minus= p_minus - G5*p_minus; p=0.5*(p_plus+p_minus); J5q = localInnerProduct(p,p); } template void CayleyFermion5D::ContractJ5q(PropagatorField &q_in,ComplexField &J5q) { conformable(this->GaugeGrid(), J5q.Grid()); conformable(q_in.Grid(), this->FermionGrid()); Gamma G5(Gamma::Algebra::Gamma5); // 4d field int Ls = this->Ls; PropagatorField psi(this->GaugeGrid()); PropagatorField p_plus (this->GaugeGrid()); PropagatorField p_minus(this->GaugeGrid()); PropagatorField p(this->GaugeGrid()); ExtractSlice(p_plus , q_in, Ls/2-1 , 0); ExtractSlice(p_minus, q_in, Ls/2 , 0); p_plus = p_plus + G5*p_plus; p_minus= p_minus - G5*p_minus; p=0.5*(p_plus+p_minus); J5q = localInnerProduct(p,p); } #define Pp(Q) (0.5*(Q+g5*Q)) #define Pm(Q) (0.5*(Q-g5*Q)) #define Q_4d(Q) (Pm((Q)[0]) + Pp((Q)[Ls-1])) #define TopRowWithSource(Q) (phys_src + (1.0-mass)*Q_4d(Q)) template void CayleyFermion5D::ContractConservedCurrent( PropagatorField &q_in_1, PropagatorField &q_in_2, PropagatorField &q_out, PropagatorField &phys_src, Current curr_type, unsigned int mu) { assert(mass_plus == mass_minus); RealD mass = mass_plus; Gamma::Algebra Gmu [] = { Gamma::Algebra::GammaX, Gamma::Algebra::GammaY, Gamma::Algebra::GammaZ, Gamma::Algebra::GammaT, Gamma::Algebra::Gamma5 }; auto UGrid= this->GaugeGrid(); auto FGrid= this->FermionGrid(); RealD sgn=1.0; if ( curr_type == Current::Axial ) sgn = -1.0; int Ls = this->Ls; std::vector L_Q(Ls,UGrid); std::vector R_Q(Ls,UGrid); for(int s=0;s R_TmLsGq(Ls,UGrid); std::vector L_TmLsGq(Ls,UGrid); for(int s=0;sbs[s]; auto c=this->cs[s]; auto bpc = 1.0/(b+c); // -0.5 factor in gauge links if (s == 0) { p5d =(b*Pm(L_TmLsGq[Ls-1])+ c*Pp(L_TmLsGq[Ls-1]) + b*Pp(L_TmLsTmp) + c*Pm(L_TmLsTmp )); tmp =(b*Pm(R_TmLsGq0) + c*Pp(R_TmLsGq0 ) + b*Pp(R_TmLsGq[1]) + c*Pm(R_TmLsGq[1])); } else if (s == Ls-1) { p5d =(b*Pm(L_TmLsGq0) + c*Pp(L_TmLsGq0 ) + b*Pp(L_TmLsGq[1]) + c*Pm(L_TmLsGq[1])); tmp =(b*Pm(R_TmLsGq[Ls-1])+ c*Pp(R_TmLsGq[Ls-1]) + b*Pp(R_TmLsTmp) + c*Pm(R_TmLsTmp )); } else { p5d =(b*Pm(L_TmLsGq[sr]) + c*Pp(L_TmLsGq[sr])+ b*Pp(L_TmLsGq[srp])+ c*Pm(L_TmLsGq[srp])); tmp =(b*Pm(R_TmLsGq[s]) + c*Pp(R_TmLsGq[s]) + b*Pp(R_TmLsGq[sp ])+ c*Pm(R_TmLsGq[sp])); } tmp = Cshift(tmp,mu,1); Impl::multLinkField(us_p5d,this->Umu,tmp,mu); gp5d=g5*p5d*g5; gus_p5d=gmu*us_p5d; C = bpc*(adj(gp5d)*us_p5d); C-= bpc*(adj(gp5d)*gus_p5d); if (s == 0) { p5d =(b*Pm(R_TmLsGq0) + c*Pp(R_TmLsGq0 ) + b*Pp(R_TmLsGq[1]) + c*Pm(R_TmLsGq[1])); tmp =(b*Pm(L_TmLsGq[Ls-1])+ c*Pp(L_TmLsGq[Ls-1]) + b*Pp(L_TmLsTmp) + c*Pm(L_TmLsTmp )); } else if (s == Ls-1) { p5d =(b*Pm(R_TmLsGq[Ls-1])+ c*Pp(R_TmLsGq[Ls-1]) + b*Pp(R_TmLsTmp) + c*Pm(R_TmLsTmp )); tmp =(b*Pm(L_TmLsGq0) + c*Pp(L_TmLsGq0 ) + b*Pp(L_TmLsGq[1]) + c*Pm(L_TmLsGq[1])); } else { p5d =(b*Pm(R_TmLsGq[s]) + c*Pp(R_TmLsGq[s]) + b*Pp(R_TmLsGq[sp ])+ c*Pm(R_TmLsGq[sp])); tmp =(b*Pm(L_TmLsGq[sr]) + c*Pp(L_TmLsGq[sr]) + b*Pp(L_TmLsGq[srp])+ c*Pm(L_TmLsGq[srp])); } tmp = Cshift(tmp,mu,1); Impl::multLinkField(us_p5d,this->Umu,tmp,mu); gp5d=gmu*p5d; gus_p5d=g5*us_p5d*g5; C-= bpc*(adj(gus_p5d)*gp5d); C-= bpc*(adj(gus_p5d)*p5d); if (s < Ls/2) q_out += sgn*C; else q_out += C; } } template void CayleyFermion5D::SeqConservedCurrent(PropagatorField &q_in, PropagatorField &q_out, PropagatorField &phys_src, Current curr_type, unsigned int mu, unsigned int tmin, unsigned int tmax, ComplexField &ph)// Complex phase factor { assert(mu>=0); assert(muLs; auto UGrid= this->GaugeGrid(); auto FGrid= this->FermionGrid(); Gamma::Algebra Gmu [] = { Gamma::Algebra::GammaX, Gamma::Algebra::GammaY, Gamma::Algebra::GammaZ, Gamma::Algebra::GammaT }; Gamma gmu=Gamma(Gmu[mu]); PropagatorField L_Q(UGrid); PropagatorField R_Q(UGrid); PropagatorField tmp(UGrid); PropagatorField Utmp(UGrid); PropagatorField zz (UGrid); zz=0.0; LatticeInteger lcoor(UGrid); LatticeCoordinate(lcoor,Nd-1); for (int s=0;sUmu,tmp,mu); tmp = G_s*( Utmp*ph - gmu*Utmp*ph ); // Forward hop tmp = where((lcoor>=tmin),tmp,zz); // Mask the time tmp = where((lcoor<=tmax),tmp,zz); L_Q = tmp; tmp = R_Q*ph; tmp = Cshift(tmp,mu,-1); Impl::multLinkField(Utmp,this->Umu,tmp,mu+Nd);// Adjoint link tmp = -G_s*( Utmp + gmu*Utmp ); tmp = where((lcoor>=tmin+tshift),tmp,zz); // Mask the time tmp = where((lcoor<=tmax+tshift),tmp,zz); // Position of current complicated L_Q= L_Q+tmp; InsertSlice(L_Q, q_out, s , 0); } #endif int tshift = (mu == Nd-1) ? 1 : 0; unsigned int LLt = GridDefaultLatt()[Tp]; //////////////////////////////////////////////// // GENERAL CAYLEY CASE //////////////////////////////////////////////// Gamma::Algebra Gmu [] = { Gamma::Algebra::GammaX, Gamma::Algebra::GammaY, Gamma::Algebra::GammaZ, Gamma::Algebra::GammaT, Gamma::Algebra::Gamma5 }; Gamma gmu=Gamma(Gmu[mu]); Gamma g5(Gamma::Algebra::Gamma5); int Ls = this->Ls; auto UGrid= this->GaugeGrid(); auto FGrid= this->FermionGrid(); std::vector R_Q(Ls,UGrid); PropagatorField L_Q(UGrid); PropagatorField tmp(UGrid); PropagatorField Utmp(UGrid); PropagatorField zz (UGrid); zz=0.0; LatticeInteger lcoor(UGrid); LatticeCoordinate(lcoor,Nd-1); for(int s=0;s R_TmLsGq(Ls,UGrid); for(int s=0;s G_s(Ls,1.0); RealD sign = 1.0; // sign flip for vector/tadpole if ( curr_type == Current::Axial ) { for(int s=0;s_b; auto c=this->_c; if ( b == 1 && c == 0 ) { sign = -1.0; } else { std::cerr << "Error: Tadpole implementation currently unavailable for non-Shamir actions." << std::endl; assert(b==1 && c==0); } } for(int s=0;sbs[s]; auto c=this->cs[s]; // auto bpc = G_s[s]*1.0/(b+c); // -0.5 factor in gauge links if (s == 0) { tmp =(b*Pm(R_TmLsGq0) + c*Pp(R_TmLsGq0 ) + b*Pp(R_TmLsGq[1]) + c*Pm(R_TmLsGq[1])); } else if (s == Ls-1) { tmp =(b*Pm(R_TmLsGq[Ls-1])+ c*Pp(R_TmLsGq[Ls-1]) + b*Pp(R_TmLsTmp) + c*Pm(R_TmLsTmp )); } else { tmp =(b*Pm(R_TmLsGq[s]) + c*Pp(R_TmLsGq[s]) + b*Pp(R_TmLsGq[sp ])+ c*Pm(R_TmLsGq[sp])); } tmp = Cshift(tmp,mu,1); Impl::multLinkField(Utmp,this->Umu,tmp,mu); tmp = sign*G_s[s]*( Utmp*ph - gmu*Utmp*ph ); // Forward hop tmp = where((lcoor>=tmin),tmp,zz); // Mask the time L_Q = where((lcoor<=tmax),tmp,zz); // Position of current complicated if (s == 0) { tmp =(b*Pm(R_TmLsGq0) + c*Pp(R_TmLsGq0 ) + b*Pp(R_TmLsGq[1]) + c*Pm(R_TmLsGq[1])); } else if (s == Ls-1) { tmp =(b*Pm(R_TmLsGq[Ls-1])+ c*Pp(R_TmLsGq[Ls-1]) + b*Pp(R_TmLsTmp) + c*Pm(R_TmLsTmp )); } else { tmp =(b*Pm(R_TmLsGq[s]) + c*Pp(R_TmLsGq[s]) + b*Pp(R_TmLsGq[sp])+ c*Pm(R_TmLsGq[sp])); } tmp = tmp *ph; tmp = Cshift(tmp,mu,-1); Impl::multLinkField(Utmp,this->Umu,tmp,mu+Nd); // Adjoint link tmp = -G_s[s]*( Utmp + gmu*Utmp ); // Mask the time if (tmax == LLt - 1 && tshift == 1){ // quick fix to include timeslice 0 if tmax + tshift is over the last timeslice unsigned int t0 = 0; tmp = where(((lcoor==t0) || (lcoor>=tmin+tshift)),tmp,zz); } else { tmp = where((lcoor>=tmin+tshift),tmp,zz); } L_Q += where((lcoor<=tmax+tshift),tmp,zz); // Position of current complicated InsertSlice(L_Q, q_out, s , 0); } } #undef Pp #undef Pm #undef Q_4d #undef TopRowWithSource NAMESPACE_END(Grid);