Grid 0.7.0
CompactWilsonCloverFermion5DImplementation.h
Go to the documentation of this file.
1/*************************************************************************************
2
3 Grid physics library, www.github.com/paboyle/Grid
4
5 Source file: ./lib/qcd/action/fermion/CompactWilsonCloverFermion5DImplementation.h
6
7 Copyright (C) 2017 - 2025
8
9 Author: paboyle <paboyle@ph.ed.ac.uk>
10 Author: Guido Cossu <guido.cossu@ed.ac.uk>
11 Author: Daniel Richtmann <daniel.richtmann@gmail.com>
12 Author: Christoph Lehner <christoph@lhnr.de>
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License along
25 with this program; if not, write to the Free Software Foundation, Inc.,
26 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27
28 See the full license in the file "LICENSE" in the top level distribution directory
29 *************************************************************************************/
30/* END LEGAL */
31
32#include <Grid/Grid.h>
33#include <Grid/qcd/spin/Dirac.h>
35
36
38template<class Impl, class CloverHelpers>
40 GridCartesian &FiveDimGrid,
41 GridRedBlackCartesian &FiveDimRedBlackGrid,
42 GridCartesian &FourDimGrid,
43 GridRedBlackCartesian &FourDimRedBlackGrid,
44 const RealD _mass,
45 const RealD _csw_r,
46 const RealD _csw_t,
47 const RealD _cF,
48 const ImplParams& impl_p)
49 : WilsonBase(_Umu, FiveDimGrid, FiveDimRedBlackGrid, FourDimGrid, FourDimRedBlackGrid, _mass, impl_p)
50 , csw_r(_csw_r)
51 , csw_t(_csw_t)
52 , cF(_cF)
53 , fixedBoundaries(impl_p.boundary_phases[Nd-1] == 0.0)
54 , Diagonal(&FourDimGrid), Triangle(&FourDimGrid)
55 , DiagonalEven(&FourDimRedBlackGrid), TriangleEven(&FourDimRedBlackGrid)
56 , DiagonalOdd(&FourDimRedBlackGrid), TriangleOdd(&FourDimRedBlackGrid)
57 , DiagonalInv(&FourDimGrid), TriangleInv(&FourDimGrid)
58 , DiagonalInvEven(&FourDimRedBlackGrid), TriangleInvEven(&FourDimRedBlackGrid)
59 , DiagonalInvOdd(&FourDimRedBlackGrid), TriangleInvOdd(&FourDimRedBlackGrid)
60 , Tmp(&FiveDimGrid)
61 , BoundaryMask(&FiveDimGrid)
62 , BoundaryMaskEven(&FiveDimRedBlackGrid), BoundaryMaskOdd(&FiveDimRedBlackGrid)
63{
64 assert(Nd == 4 && Nc == 3 && Ns == 4 && Impl::Dimension == 3);
65
66 csw_r *= 0.5;
67 csw_t *= 0.5;
68 //if (clover_anisotropy.isAnisotropic)
69 // csw_r /= clover_anisotropy.xi_0;
70
71 ImportGauge(_Umu);
72 if (fixedBoundaries) {
73 this->BoundaryMaskEven.Checkerboard() = Even;
74 this->BoundaryMaskOdd.Checkerboard() = Odd;
76 }
77}
78
79template<class Impl, class CloverHelpers>
80void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::Dhop(const FermionField& in, FermionField& out, int dag) {
81 WilsonBase::Dhop(in, out, dag);
83}
84
85template<class Impl, class CloverHelpers>
86void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::DhopOE(const FermionField& in, FermionField& out, int dag) {
87 WilsonBase::DhopOE(in, out, dag);
89}
90
91template<class Impl, class CloverHelpers>
92void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::DhopEO(const FermionField& in, FermionField& out, int dag) {
93 WilsonBase::DhopEO(in, out, dag);
95}
96
97template<class Impl, class CloverHelpers>
98void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::DhopDir(const FermionField& in, FermionField& out, int dir, int disp) {
99 WilsonBase::DhopDir(in, out, dir, disp);
100 if(this->fixedBoundaries) ApplyBoundaryMask(out);
101}
102
103template<class Impl, class CloverHelpers>
104void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::DhopDirAll(const FermionField& in, std::vector<FermionField>& out) {
105 WilsonBase::DhopDirAll(in, out);
106 if(this->fixedBoundaries) {
107 for(auto& o : out) ApplyBoundaryMask(o);
108 }
109}
110
111template<class Impl, class CloverHelpers>
112void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::M(const FermionField& in, FermionField& out) {
113 out.Checkerboard() = in.Checkerboard();
114 WilsonBase::Dhop(in, out, DaggerNo); // call base to save applying bc
115 Mooee(in, Tmp);
116 axpy(out, 1.0, out, Tmp);
118}
119
120template<class Impl, class CloverHelpers>
121void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::Mdag(const FermionField& in, FermionField& out) {
122 out.Checkerboard() = in.Checkerboard();
123 WilsonBase::Dhop(in, out, DaggerYes); // call base to save applying bc
124 MooeeDag(in, Tmp);
125 axpy(out, 1.0, out, Tmp);
127}
128
129template<class Impl, class CloverHelpers>
130void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::Meooe(const FermionField& in, FermionField& out) {
131 WilsonBase::Meooe(in, out);
133}
134
135template<class Impl, class CloverHelpers>
136void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::MeooeDag(const FermionField& in, FermionField& out) {
137 WilsonBase::MeooeDag(in, out);
139}
140
141template<class Impl, class CloverHelpers>
142void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::Mooee(const FermionField& in, FermionField& out) {
143 if(in.Grid()->_isCheckerBoarded) {
144 if(in.Checkerboard() == Odd) {
146 } else {
148 }
149 } else {
151 }
153}
154
155template<class Impl, class CloverHelpers>
156void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::MooeeDag(const FermionField& in, FermionField& out) {
157 Mooee(in, out); // blocks are hermitian
158}
159
160template<class Impl, class CloverHelpers>
161void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::MooeeInv(const FermionField& in, FermionField& out) {
162 if(in.Grid()->_isCheckerBoarded) {
163 if(in.Checkerboard() == Odd) {
165 } else {
167 }
168 } else {
170 }
172}
173
174template<class Impl, class CloverHelpers>
175void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::MooeeInvDag(const FermionField& in, FermionField& out) {
176 MooeeInv(in, out); // blocks are hermitian
177}
178
179template<class Impl, class CloverHelpers>
180void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::Mdir(const FermionField& in, FermionField& out, int dir, int disp) {
181 DhopDir(in, out, dir, disp);
182}
183
184template<class Impl, class CloverHelpers>
185void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::MdirAll(const FermionField& in, std::vector<FermionField>& out) {
186 DhopDirAll(in, out);
187}
188
189template<class Impl, class CloverHelpers>
190void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::MDeriv(GaugeField& force, const FermionField& X, const FermionField& Y, int dag) {
191 assert(!fixedBoundaries); // TODO check for changes required for open bc
192
193 // NOTE: code copied from original clover term
194 conformable(X.Grid(), Y.Grid());
195 conformable(X.Grid(), force.Grid());
196 GaugeLinkField force_mu(force.Grid()), lambda(force.Grid());
197 GaugeField clover_force(force.Grid());
198 PropagatorField Lambda(force.Grid());
199
200 // Guido: Here we are hitting some performance issues:
201 // need to extract the components of the DoubledGaugeField
202 // for each call
203 // Possible solution
204 // Create a vector object to store them? (cons: wasting space)
205 std::vector<GaugeLinkField> U(Nd, this->Umu.Grid());
206
207 Impl::extractLinkField(U, this->Umu);
208
209 force = Zero();
210 // Derivative of the Wilson hopping term
211 this->DhopDeriv(force, X, Y, dag);
212
214 // Clover term derivative
216 Impl::outerProductImpl(Lambda, X, Y);
217 //std::cout << "Lambda:" << Lambda << std::endl;
218
219 Gamma::Algebra sigma[] = {
220 Gamma::Algebra::SigmaXY,
221 Gamma::Algebra::SigmaXZ,
222 Gamma::Algebra::SigmaXT,
223 Gamma::Algebra::MinusSigmaXY,
224 Gamma::Algebra::SigmaYZ,
225 Gamma::Algebra::SigmaYT,
226 Gamma::Algebra::MinusSigmaXZ,
227 Gamma::Algebra::MinusSigmaYZ,
228 Gamma::Algebra::SigmaZT,
229 Gamma::Algebra::MinusSigmaXT,
230 Gamma::Algebra::MinusSigmaYT,
231 Gamma::Algebra::MinusSigmaZT};
232
233 /*
234 sigma_{\mu \nu}=
235 | 0 sigma[0] sigma[1] sigma[2] |
236 | sigma[3] 0 sigma[4] sigma[5] |
237 | sigma[6] sigma[7] 0 sigma[8] |
238 | sigma[9] sigma[10] sigma[11] 0 |
239 */
240
241 int count = 0;
242 clover_force = Zero();
243 for (int mu = 0; mu < 4; mu++)
244 {
245 force_mu = Zero();
246 for (int nu = 0; nu < 4; nu++)
247 {
248 if (mu == nu)
249 continue;
250
251 RealD factor;
252 if (nu == 4 || mu == 4)
253 {
254 factor = 2.0 * csw_t;
255 }
256 else
257 {
258 factor = 2.0 * csw_r;
259 }
260 PropagatorField Slambda = Gamma(sigma[count]) * Lambda; // sigma checked
261 Impl::TraceSpinImpl(lambda, Slambda); // traceSpin ok
262 force_mu -= factor*CloverHelpers::Cmunu(U, lambda, mu, nu); // checked
263 count++;
264 }
265
266 pokeLorentz(clover_force, U[mu] * force_mu, mu);
267 }
268 //clover_force *= csw;
269 force += clover_force;
270}
271
272template<class Impl, class CloverHelpers>
273void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::MooDeriv(GaugeField& mat, const FermionField& U, const FermionField& V, int dag) {
274 assert(0);
275}
276
277template<class Impl, class CloverHelpers>
278void CompactWilsonCloverFermion5D<Impl, CloverHelpers>::MeeDeriv(GaugeField& mat, const FermionField& U, const FermionField& V, int dag) {
279 assert(0);
280}
281
282template<class Impl, class CloverHelpers>
284 FermionField& out,
285 const CloverDiagonalField& diagonal,
286 const CloverTriangleField& triangle) {
287 assert(in.Checkerboard() == Odd || in.Checkerboard() == Even);
288 out.Checkerboard() = in.Checkerboard();
289 conformable(in, out);
290 CompactHelpers::MooeeKernel(diagonal.oSites(), this->Ls, in, out, diagonal, triangle);
291}
292
293template<class Impl, class CloverHelpers>
295 // NOTE: parts copied from original implementation
296
297 // Import gauge into base class
298 double t0 = usecond();
299 WilsonBase::ImportGauge(_Umu); // NOTE: called here and in wilson constructor -> performed twice, but can't avoid that
300
301 // Initialize temporary variables
302 double t1 = usecond();
303 conformable(_Umu.Grid(), this->GaugeGrid());
304 GridBase* grid = _Umu.Grid();
305 typename Impl::GaugeLinkField Bx(grid), By(grid), Bz(grid), Ex(grid), Ey(grid), Ez(grid);
306 CloverField TmpOriginal(grid);
307 CloverField TmpInverse(grid);
308
309 // Compute the field strength terms mu>nu
310 double t2 = usecond();
317
318 // Compute the Clover Operator acting on Colour and Spin
319 // multiply here by the clover coefficients for the anisotropy
320 double t3 = usecond();
321 TmpOriginal = Helpers::fillCloverYZ(Bx) * csw_r;
322 TmpOriginal += Helpers::fillCloverXZ(By) * csw_r;
323 TmpOriginal += Helpers::fillCloverXY(Bz) * csw_r;
324 TmpOriginal += Helpers::fillCloverXT(Ex) * csw_t;
325 TmpOriginal += Helpers::fillCloverYT(Ey) * csw_t;
326 TmpOriginal += Helpers::fillCloverZT(Ez) * csw_t;
327
328 // Instantiate the clover term
329 // - In case of the standard clover the mass term is added
330 // - In case of the exponential clover the clover term is exponentiated
331 double t4 = usecond();
332 CloverHelpers::InstantiateClover(TmpOriginal, TmpInverse, csw_t, 4.0 + this->M5 /*this->diag_mass*/);
333
334 // Convert the data layout of the clover term
335 double t5 = usecond();
337
338 // Modify the clover term at the temporal boundaries in case of open boundary conditions
339 double t6 = usecond();
340 if(fixedBoundaries) CompactHelpers::ModifyBoundaries(Diagonal, Triangle, csw_t, cF, 4.0 + this->M5 /*this->diag_mass*/);
341
342 // Invert the Clover term
343 // In case of the exponential clover with (anti-)periodic boundary conditions exp(-Clover) saved
344 // in TmpInverse can be used. In all other cases the clover term has to be explictly inverted.
345 // TODO: For now this inversion is explictly done on the CPU
346 double t7 = usecond();
347 CloverHelpers::InvertClover(TmpInverse, Diagonal, Triangle, DiagonalInv, TriangleInv, fixedBoundaries);
348
349 // Fill the remaining clover fields
350 double t8 = usecond();
359
360 // Report timings
361 double t9 = usecond();
362
363 std::cout << GridLogDebug << "CompactWilsonCloverFermion5D::ImportGauge timings:" << std::endl;
364 std::cout << GridLogDebug << "WilsonFermion::Importgauge = " << (t1 - t0) / 1e6 << std::endl;
365 std::cout << GridLogDebug << "allocations = " << (t2 - t1) / 1e6 << std::endl;
366 std::cout << GridLogDebug << "field strength = " << (t3 - t2) / 1e6 << std::endl;
367 std::cout << GridLogDebug << "fill clover = " << (t4 - t3) / 1e6 << std::endl;
368 std::cout << GridLogDebug << "instantiate clover = " << (t5 - t4) / 1e6 << std::endl;
369 std::cout << GridLogDebug << "convert layout = " << (t6 - t5) / 1e6 << std::endl;
370 std::cout << GridLogDebug << "modify boundaries = " << (t7 - t6) / 1e6 << std::endl;
371 std::cout << GridLogDebug << "invert clover = " << (t8 - t7) / 1e6 << std::endl;
372 std::cout << GridLogDebug << "pick cbs = " << (t9 - t8) / 1e6 << std::endl;
373 std::cout << GridLogDebug << "total = " << (t9 - t0) / 1e6 << std::endl;
374}
375
static const int Even
static const int Odd
void axpy(Lattice< vobj > &ret, sobj a, const Lattice< vobj > &x, const Lattice< vobj > &y)
void conformable(const Lattice< obj1 > &lhs, const Lattice< obj2 > &rhs)
void pickCheckerboard(int cb, Lattice< vobj > &half, const Lattice< vobj > &full)
GridLogger GridLogDebug(1, "Debug", GridLogColours, "PURPLE")
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
void pokeLorentz(Lattice< vobj > &lhs, const Lattice< decltype(peekIndex< LorentzIndex >(vobj(), 0))> &rhs, int i)
Definition QCD.h:487
static constexpr int DaggerYes
Definition QCD.h:70
static constexpr int Ns
Definition QCD.h:51
static constexpr int Nd
Definition QCD.h:52
static constexpr int Nc
Definition QCD.h:50
static constexpr int Xdir
Definition QCD.h:36
static constexpr int Tdir
Definition QCD.h:39
static constexpr int Zdir
Definition QCD.h:38
static constexpr int DaggerNo
Definition QCD.h:69
static constexpr int Ydir
Definition QCD.h:37
double RealD
Definition Simd.h:61
double usecond(void)
Definition Timer.h:50
static INTERNAL_PRECISION U
Definition Zolotarev.cc:230
static GaugeLinkField Cmunu(std::vector< GaugeLinkField > &U, GaugeLinkField &lambda, int mu, int nu)
void MooeeInternal(const FermionField &in, FermionField &out, const CloverDiagonalField &diagonal, const CloverTriangleField &triangle)
void MdirAll(const FermionField &in, std::vector< FermionField > &out) override
void MooeeInvDag(const FermionField &in, FermionField &out) override
void MooeeInv(const FermionField &in, FermionField &out) override
void MeeDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag) override
void Mdir(const FermionField &in, FermionField &out, int dir, int disp) override
void DhopDir(const FermionField &in, FermionField &out, int dir, int disp) override
CompactWilsonCloverFermion5D(GaugeField &_Umu, GridCartesian &FiveDimGrid, GridRedBlackCartesian &FiveDimRedBlackGrid, GridCartesian &FourDimGrid, GridRedBlackCartesian &FourDimRedBlackGrid, const RealD _mass, const RealD _csw_r=0.0, const RealD _csw_t=0.0, const RealD _cF=1.0, const ImplParams &impl_p=ImplParams())
void MooDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag) override
void Mooee(const FermionField &in, FermionField &out) override
void MeooeDag(const FermionField &in, FermionField &out) override
void M(const FermionField &in, FermionField &out) override
void Dhop(const FermionField &in, FermionField &out, int dag) override
void MooeeDag(const FermionField &in, FermionField &out) override
void Meooe(const FermionField &in, FermionField &out) override
void Mdag(const FermionField &in, FermionField &out) override
void MDeriv(GaugeField &force, const FermionField &X, const FermionField &Y, int dag) override
void DhopOE(const FermionField &in, FermionField &out, int dag) override
void ImportGauge(const GaugeField &_Umu) override
void DhopEO(const FermionField &in, FermionField &out, int dag) override
void DhopDirAll(const FermionField &in, std::vector< FermionField > &out)
static void ModifyBoundaries(CloverDiagonalField &diagonal, CloverTriangleField &triangle, RealD csw_t, RealD cF, RealD diag_mass)
static void MooeeKernel(int Nsite, int Ls, const FermionField &in, FermionField &out, const CloverDiagonalField &diagonal, const CloverTriangleField &triangle)
static void ConvertLayout(const CloverField &full, CloverDiagonalField &diagonal, CloverTriangleField &triangle)
static void SetupMasks(MaskField &full, MaskField &even, MaskField &odd)
Definition Gamma.h:10
static CloverField fillCloverYZ(const GaugeLinkField &F)
static CloverField fillCloverXT(const GaugeLinkField &F)
static CloverField fillCloverXZ(const GaugeLinkField &F)
static CloverField fillCloverXY(const GaugeLinkField &F)
static CloverField fillCloverZT(const GaugeLinkField &F)
static CloverField fillCloverYT(const GaugeLinkField &F)
void ImportGauge(const GaugeField &_Umu)
virtual void Meooe(const FermionField &in, FermionField &out)
void DhopDir(const FermionField &in, FermionField &out, int dir, int disp)
void DhopDirAll(const FermionField &in, std::vector< FermionField > &out)
virtual void MeooeDag(const FermionField &in, FermionField &out)
virtual void DhopDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
void DhopEO(const FermionField &in, FermionField &out, int dag)
void Dhop(const FermionField &in, FermionField &out, int dag)
DoubledGaugeField Umu
void DhopOE(const FermionField &in, FermionField &out, int dag)
static void FieldStrength(GaugeMat &FS, const GaugeLorentz &Umu, int mu, int nu)
Definition Simd.h:194