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