Grid 0.7.0
CloverHelpers.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/WilsonCloverFermionImplementation.h
6
7 Copyright (C) 2017 - 2022
8
9 Author: paboyle <paboyle@ph.ed.ac.uk>
10 Author: Daniel Richtmann <daniel.richtmann@gmail.com>
11 Author: Mattia Bruno <mattia.bruno@cern.ch>
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#pragma once
32
33#include <Grid/Grid.h>
34#include <Grid/qcd/spin/Dirac.h>
36
38// Standard Clover
39// (4+m0) + csw * clover_term
40// Exp Clover
41// (4+m0) * exp(csw/(4+m0) clover_term)
42// = (4+m0) + csw * clover_term + ...
44
46
47
49// Generic Standard Clover
51
52template<class Impl>
54public:
55
58
60
61 static void Instantiate(CloverField& CloverTerm, CloverField& CloverTermInv, RealD csw_t, RealD diag_mass) {
62 GridBase *grid = CloverTerm.Grid();
63 CloverTerm += diag_mass;
64
65 int lvol = grid->lSites();
66 int DimRep = Impl::Dimension;
67 {
68 autoView(CTv,CloverTerm,CpuRead);
69 autoView(CTIv,CloverTermInv,CpuWrite);
70 thread_for(site, lvol, {
71 Coordinate lcoor;
72 grid->LocalIndexToLocalCoor(site, lcoor);
73 Eigen::MatrixXcd EigenCloverOp = Eigen::MatrixXcd::Zero(Ns * DimRep, Ns * DimRep);
74 Eigen::MatrixXcd EigenInvCloverOp = Eigen::MatrixXcd::Zero(Ns * DimRep, Ns * DimRep);
75 typename SiteClover::scalar_object Qx = Zero(), Qxinv = Zero();
76 peekLocalSite(Qx, CTv, lcoor);
77
78 for (int j = 0; j < Ns; j++)
79 for (int k = 0; k < Ns; k++)
80 for (int a = 0; a < DimRep; a++)
81 for (int b = 0; b < DimRep; b++){
82 auto zz = Qx()(j, k)(a, b);
83 EigenCloverOp(a + j * DimRep, b + k * DimRep) = std::complex<double>(zz);
84 }
85
86 EigenInvCloverOp = EigenCloverOp.inverse();
87 for (int j = 0; j < Ns; j++)
88 for (int k = 0; k < Ns; k++)
89 for (int a = 0; a < DimRep; a++)
90 for (int b = 0; b < DimRep; b++)
91 Qxinv()(j, k)(a, b) = EigenInvCloverOp(a + j * DimRep, b + k * DimRep);
92 pokeLocalSite(Qxinv, CTIv, lcoor);
93 });
94 }
95 }
96
97 static GaugeLinkField Cmunu(std::vector<GaugeLinkField> &U, GaugeLinkField &lambda, int mu, int nu) {
98 return Helpers::Cmunu(U, lambda, mu, nu);
99 }
100
101};
102
103
105// Generic Exp Clover
107
108template<class Impl>
110public:
111
114
117
118 // Can this be avoided?
119 static void IdentityTimesC(const CloverField& in, RealD c) {
120 int DimRep = Impl::Dimension;
121
122 autoView(in_v, in, AcceleratorWrite);
123
124 accelerator_for(ss, in.Grid()->oSites(), 1, {
125 for (int sa=0; sa<Ns; sa++)
126 for (int ca=0; ca<DimRep; ca++)
127 in_v[ss]()(sa,sa)(ca,ca) = c;
128 });
129 }
130
131 static int getNMAX(RealD prec, RealD R) {
132 /* compute stop condition for exponential */
133 int NMAX=1;
134 RealD cond=R*R/2.;
135
136 while (cond*std::exp(R)>prec) {
137 NMAX++;
138 cond*=R/(double)(NMAX+1);
139 }
140 return NMAX;
141 }
142
143 static int getNMAX(Lattice<iImplClover<vComplexD2>> &t, RealD R) {return getNMAX(1e-12,R);}
144 static int getNMAX(Lattice<iImplClover<vComplexD>> &t, RealD R) {return getNMAX(1e-12,R);}
145 static int getNMAX(Lattice<iImplClover<vComplexF>> &t, RealD R) {return getNMAX(1e-6,R);}
146
147 static void Instantiate(CloverField& Clover, CloverField& CloverInv, RealD csw_t, RealD diag_mass) {
148 GridBase* grid = Clover.Grid();
149 CloverField ExpClover(grid);
150
151 int NMAX = getNMAX(Clover, 3.*csw_t/diag_mass);
152
153 Clover *= (1.0/diag_mass);
154
155 // Taylor expansion, slow but generic
156 // Horner scheme: a0 + a1 x + a2 x^2 + .. = a0 + x (a1 + x(...))
157 // qN = cN
158 // qn = cn + qn+1 X
159 std::vector<RealD> cn(NMAX+1);
160 cn[0] = 1.0;
161 for (int i=1; i<=NMAX; i++)
162 cn[i] = cn[i-1] / RealD(i);
163
164 ExpClover = Zero();
165 IdentityTimesC(ExpClover, cn[NMAX]);
166 for (int i=NMAX-1; i>=0; i--)
167 ExpClover = ExpClover * Clover + cn[i];
168
169 // prepare inverse
170 CloverInv = (-1.0)*Clover;
171
172 Clover = ExpClover * diag_mass;
173
174 ExpClover = Zero();
175 IdentityTimesC(ExpClover, cn[NMAX]);
176 for (int i=NMAX-1; i>=0; i--)
177 ExpClover = ExpClover * CloverInv + cn[i];
178
179 CloverInv = ExpClover * (1.0/diag_mass);
180
181 }
182
183 static GaugeLinkField Cmunu(std::vector<GaugeLinkField> &U, GaugeLinkField &lambda, int mu, int nu) {
184 assert(0);
185 return lambda;
186 }
187
188};
189
190
192// Compact Standard Clover
194
195
196template<class Impl>
198 public WilsonCloverHelpers<Impl> {
199public:
200
204
207
208 static void InstantiateClover(CloverField& Clover, CloverField& CloverInv, RealD csw_t, RealD diag_mass) {
209 Clover += diag_mass;
210 }
211
212 static void InvertClover(CloverField& InvClover,
213 const CloverDiagonalField& diagonal,
214 const CloverTriangleField& triangle,
215 CloverDiagonalField& diagonalInv,
216 CloverTriangleField& triangleInv,
217 bool fixedBoundaries) {
218
219 CompactHelpers::Invert(diagonal, triangle, diagonalInv, triangleInv);
220 }
221
222 // TODO: implement Cmunu for better performances with compact layout, but don't do it
223 // here, but rather in WilsonCloverHelpers.h -> CompactWilsonCloverHelpers
224 static GaugeLinkField Cmunu(std::vector<GaugeLinkField> &U, GaugeLinkField &lambda, int mu, int nu) {
225 return Helpers::Cmunu(U, lambda, mu, nu);
226 }
227};
228
230// Compact Exp Clover
232
233template<class Impl>
235public:
236
240
243
244 // Can this be avoided?
245 static void IdentityTimesC(const CloverField& in, RealD c) {
246 int DimRep = Impl::Dimension;
247
248 autoView(in_v, in, AcceleratorWrite);
249
250 accelerator_for(ss, in.Grid()->oSites(), 1, {
251 for (int sa=0; sa<Ns; sa++)
252 for (int ca=0; ca<DimRep; ca++)
253 in_v[ss]()(sa,sa)(ca,ca) = c;
254 });
255 }
256
257 static int getNMAX(RealD prec, RealD R) {
258 /* compute stop condition for exponential */
259 int NMAX=1;
260 RealD cond=R*R/2.;
261
262 while (cond*std::exp(R)>prec) {
263 NMAX++;
264 cond*=R/(double)(NMAX+1);
265 }
266 return NMAX;
267 }
268
269 static int getNMAX(Lattice<iImplClover<vComplexD>> &t, RealD R) {return getNMAX(1e-12,R);}
270 static int getNMAX(Lattice<iImplClover<vComplexF>> &t, RealD R) {return getNMAX(1e-6,R);}
271
272 static void InstantiateClover(CloverField& Clover, CloverField& CloverInv, RealD csw_t, RealD diag_mass) {
273
274 GridBase* grid = Clover.Grid();
275 CloverField ExpClover(grid);
276
277 int NMAX = getNMAX(Clover, 3.*csw_t/diag_mass);
278
279 Clover *= (1.0/diag_mass);
280
281 // Taylor expansion, slow but generic
282 // Horner scheme: a0 + a1 x + a2 x^2 + .. = a0 + x (a1 + x(...))
283 // qN = cN
284 // qn = cn + qn+1 X
285 std::vector<RealD> cn(NMAX+1);
286 cn[0] = 1.0;
287 for (int i=1; i<=NMAX; i++)
288 cn[i] = cn[i-1] / RealD(i);
289
290 ExpClover = Zero();
291 IdentityTimesC(ExpClover, cn[NMAX]);
292 for (int i=NMAX-1; i>=0; i--)
293 ExpClover = ExpClover * Clover + cn[i];
294
295 // prepare inverse
296 CloverInv = (-1.0)*Clover;
297
298 Clover = ExpClover * diag_mass;
299
300 ExpClover = Zero();
301 IdentityTimesC(ExpClover, cn[NMAX]);
302 for (int i=NMAX-1; i>=0; i--)
303 ExpClover = ExpClover * CloverInv + cn[i];
304
305 CloverInv = ExpClover * (1.0/diag_mass);
306
307 }
308
309 static void InvertClover(CloverField& InvClover,
310 const CloverDiagonalField& diagonal,
311 const CloverTriangleField& triangle,
312 CloverDiagonalField& diagonalInv,
313 CloverTriangleField& triangleInv,
314 bool fixedBoundaries) {
315
316 if (fixedBoundaries)
317 {
318 CompactHelpers::Invert(diagonal, triangle, diagonalInv, triangleInv);
319 }
320 else
321 {
322 CompactHelpers::ConvertLayout(InvClover, diagonalInv, triangleInv);
323 }
324 }
325
326 static GaugeLinkField Cmunu(std::vector<GaugeLinkField> &U, GaugeLinkField &lambda, int mu, int nu) {
327 assert(0);
328 return lambda;
329 }
330
331};
332
333
#define accelerator_for(iterator, num, nsimd,...)
AcceleratorVector< int, MaxDims > Coordinate
Definition Coordinate.h:95
void peekLocalSite(sobj &s, const LatticeView< vobj > &l, Coordinate &site)
void pokeLocalSite(const sobj &s, LatticeView< vobj > &l, Coordinate &site)
#define autoView(l_v, l, mode)
@ CpuRead
@ AcceleratorWrite
@ CpuWrite
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
static constexpr int Ns
Definition QCD.h:51
double RealD
Definition Simd.h:61
#define thread_for(i, num,...)
Definition Threads.h:60
static INTERNAL_PRECISION U
Definition Zolotarev.cc:230
static GaugeLinkField Cmunu(std::vector< GaugeLinkField > &U, GaugeLinkField &lambda, int mu, int nu)
INHERIT_IMPL_TYPES(Impl)
INHERIT_CLOVER_TYPES(Impl)
static void Instantiate(CloverField &CloverTerm, CloverField &CloverTermInv, RealD csw_t, RealD diag_mass)
WilsonCloverHelpers< Impl > Helpers
CompactWilsonCloverHelpers< Impl > CompactHelpers
static void InstantiateClover(CloverField &Clover, CloverField &CloverInv, RealD csw_t, RealD diag_mass)
static GaugeLinkField Cmunu(std::vector< GaugeLinkField > &U, GaugeLinkField &lambda, int mu, int nu)
static void InvertClover(CloverField &InvClover, const CloverDiagonalField &diagonal, const CloverTriangleField &triangle, CloverDiagonalField &diagonalInv, CloverTriangleField &triangleInv, bool fixedBoundaries)
WilsonCloverHelpers< Impl > Helpers
INHERIT_COMPACT_CLOVER_TYPES(Impl)
iScalar< iMatrix< iMatrix< vtype, Impl::Dimension >, Ns > > iImplClover
CompactWilsonCloverHelpers< Impl > CompactHelpers
static int getNMAX(Lattice< iImplClover< vComplexF > > &t, RealD R)
static GaugeLinkField Cmunu(std::vector< GaugeLinkField > &U, GaugeLinkField &lambda, int mu, int nu)
static void InvertClover(CloverField &InvClover, const CloverDiagonalField &diagonal, const CloverTriangleField &triangle, CloverDiagonalField &diagonalInv, CloverTriangleField &triangleInv, bool fixedBoundaries)
static int getNMAX(Lattice< iImplClover< vComplexD > > &t, RealD R)
static int getNMAX(RealD prec, RealD R)
static void IdentityTimesC(const CloverField &in, RealD c)
static void InstantiateClover(CloverField &Clover, CloverField &CloverInv, RealD csw_t, RealD diag_mass)
static void Invert(const CloverDiagonalField &diagonal, const CloverTriangleField &triangle, CloverDiagonalField &diagonalInv, CloverTriangleField &triangleInv)
static void ConvertLayout(const CloverField &full, CloverDiagonalField &diagonal, CloverTriangleField &triangle)
static void Instantiate(CloverField &Clover, CloverField &CloverInv, RealD csw_t, RealD diag_mass)
INHERIT_CLOVER_TYPES(Impl)
static int getNMAX(RealD prec, RealD R)
static int getNMAX(Lattice< iImplClover< vComplexD > > &t, RealD R)
static int getNMAX(Lattice< iImplClover< vComplexD2 > > &t, RealD R)
INHERIT_IMPL_TYPES(Impl)
WilsonCloverHelpers< Impl > Helpers
static int getNMAX(Lattice< iImplClover< vComplexF > > &t, RealD R)
static GaugeLinkField Cmunu(std::vector< GaugeLinkField > &U, GaugeLinkField &lambda, int mu, int nu)
static void IdentityTimesC(const CloverField &in, RealD c)
iScalar< iMatrix< iMatrix< vtype, Impl::Dimension >, Ns > > iImplClover
void LocalIndexToLocalCoor(int lidx, Coordinate &lcoor)
int lSites(void) const
static GaugeLinkField Cmunu(std::vector< GaugeLinkField > &U, GaugeLinkField &lambda, int mu, int nu)
Definition Simd.h:194