Grid 0.7.0
WilsonCloverFermionImplementation.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: 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
36
37template<class Impl, class CloverHelpers>
39 GridCartesian& Fgrid,
41 const RealD _mass,
42 const RealD _csw_r,
43 const RealD _csw_t,
44 const WilsonAnisotropyCoefficients& clover_anisotropy,
45 const ImplParams& impl_p)
46 : WilsonFermion<Impl>(_Umu, Fgrid, Hgrid, _mass, impl_p, clover_anisotropy)
47 , CloverTerm(&Fgrid)
48 , CloverTermInv(&Fgrid)
49 , CloverTermEven(&Hgrid)
50 , CloverTermOdd(&Hgrid)
51 , CloverTermInvEven(&Hgrid)
52 , CloverTermInvOdd(&Hgrid)
53 , CloverTermDagEven(&Hgrid)
54 , CloverTermDagOdd(&Hgrid)
55 , CloverTermInvDagEven(&Hgrid)
56 , CloverTermInvDagOdd(&Hgrid) {
57 assert(Nd == 4); // require 4 dimensions
58
59 if(clover_anisotropy.isAnisotropic) {
60 csw_r = _csw_r * 0.5 / clover_anisotropy.xi_0;
61 diag_mass = _mass + 1.0 + (Nd - 1) * (clover_anisotropy.nu / clover_anisotropy.xi_0);
62 } else {
63 csw_r = _csw_r * 0.5;
64 diag_mass = 4.0 + _mass;
65 }
66 csw_t = _csw_t * 0.5;
67
68 if(csw_r == 0)
69 std::cout << GridLogWarning << "Initializing WilsonCloverFermion with csw_r = 0" << std::endl;
70 if(csw_t == 0)
71 std::cout << GridLogWarning << "Initializing WilsonCloverFermion with csw_t = 0" << std::endl;
72
73 ImportGauge(_Umu);
74}
75
76// *NOT* EO
77template<class Impl, class CloverHelpers>
78void WilsonCloverFermion<Impl, CloverHelpers>::M(const FermionField &in, FermionField &out)
79{
80 FermionField temp(out.Grid());
81
82 // Wilson term
83 out.Checkerboard() = in.Checkerboard();
84 this->Dhop(in, out, DaggerNo);
85
86 // Clover term
87 Mooee(in, temp);
88
89 out += temp;
90}
91
92template<class Impl, class CloverHelpers>
93void WilsonCloverFermion<Impl, CloverHelpers>::Mdag(const FermionField &in, FermionField &out)
94{
95 FermionField temp(out.Grid());
96
97 // Wilson term
98 out.Checkerboard() = in.Checkerboard();
99 this->Dhop(in, out, DaggerYes);
100
101 // Clover term
102 MooeeDag(in, temp);
103
104 out += temp;
105}
106
107template<class Impl, class CloverHelpers>
109{
110 double t0 = usecond();
112 double t1 = usecond();
113 GridBase *grid = _Umu.Grid();
114 typename Impl::GaugeLinkField Bx(grid), By(grid), Bz(grid), Ex(grid), Ey(grid), Ez(grid);
115
116 double t2 = usecond();
117 // Compute the field strength terms mu>nu
124
125 double t3 = usecond();
126 // Compute the Clover Operator acting on Colour and Spin
127 // multiply here by the clover coefficients for the anisotropy
134
135 double t4 = usecond();
137
138 double t5 = usecond();
139 // Separate the even and odd parts
142
145
148
151 double t6 = usecond();
152
153 std::cout << GridLogDebug << "WilsonCloverFermion::ImportGauge timings:" << std::endl;
154 std::cout << GridLogDebug << "WilsonFermion::Importgauge = " << (t1 - t0) / 1e6 << std::endl;
155 std::cout << GridLogDebug << "allocations = " << (t2 - t1) / 1e6 << std::endl;
156 std::cout << GridLogDebug << "field strength = " << (t3 - t2) / 1e6 << std::endl;
157 std::cout << GridLogDebug << "fill clover = " << (t4 - t3) / 1e6 << std::endl;
158 std::cout << GridLogDebug << "instantiation = " << (t5 - t4) / 1e6 << std::endl;
159 std::cout << GridLogDebug << "pick cbs = " << (t6 - t5) / 1e6 << std::endl;
160 std::cout << GridLogDebug << "total = " << (t6 - t0) / 1e6 << std::endl;
161}
162
163template<class Impl, class CloverHelpers>
164void WilsonCloverFermion<Impl, CloverHelpers>::Mooee(const FermionField &in, FermionField &out)
165{
166 this->MooeeInternal(in, out, DaggerNo, InverseNo);
167}
168
169template<class Impl, class CloverHelpers>
170void WilsonCloverFermion<Impl, CloverHelpers>::MooeeDag(const FermionField &in, FermionField &out)
171{
172 this->MooeeInternal(in, out, DaggerYes, InverseNo);
173}
174
175template<class Impl, class CloverHelpers>
176void WilsonCloverFermion<Impl, CloverHelpers>::MooeeInv(const FermionField &in, FermionField &out)
177{
178 this->MooeeInternal(in, out, DaggerNo, InverseYes);
179}
180
181template<class Impl, class CloverHelpers>
182void WilsonCloverFermion<Impl, CloverHelpers>::MooeeInvDag(const FermionField &in, FermionField &out)
183{
184 this->MooeeInternal(in, out, DaggerYes, InverseYes);
185}
186
187template<class Impl, class CloverHelpers>
188void WilsonCloverFermion<Impl, CloverHelpers>::MooeeInternal(const FermionField &in, FermionField &out, int dag, int inv)
189{
190 out.Checkerboard() = in.Checkerboard();
191 CloverField *Clover;
192 assert(in.Checkerboard() == Odd || in.Checkerboard() == Even);
193
194 if (dag)
195 {
196 if (in.Grid()->_isCheckerBoarded)
197 {
198 if (in.Checkerboard() == Odd)
199 {
200 Clover = (inv) ? &CloverTermInvDagOdd : &CloverTermDagOdd;
201 }
202 else
203 {
204 Clover = (inv) ? &CloverTermInvDagEven : &CloverTermDagEven;
205 }
206 Helpers::multCloverField(out, *Clover, in);
207 }
208 else
209 {
210 Clover = (inv) ? &CloverTermInv : &CloverTerm;
211 Helpers::multCloverField(out, *Clover, in); // don't bother with adj, hermitian anyway
212 }
213 }
214 else
215 {
216 if (in.Grid()->_isCheckerBoarded)
217 {
218
219 if (in.Checkerboard() == Odd)
220 {
221 // std::cout << "Calling clover term Odd" << std::endl;
222 Clover = (inv) ? &CloverTermInvOdd : &CloverTermOdd;
223 }
224 else
225 {
226 // std::cout << "Calling clover term Even" << std::endl;
227 Clover = (inv) ? &CloverTermInvEven : &CloverTermEven;
228 }
229 Helpers::multCloverField(out, *Clover, in);
230 // std::cout << GridLogMessage << "*Clover.Checkerboard() " << (*Clover).Checkerboard() << std::endl;
231 }
232 else
233 {
234 Clover = (inv) ? &CloverTermInv : &CloverTerm;
235 Helpers::multCloverField(out, *Clover, in);
236 }
237 }
238} // MooeeInternal
239
240// Derivative parts unpreconditioned pseudofermions
241template<class Impl, class CloverHelpers>
242void WilsonCloverFermion<Impl, CloverHelpers>::MDeriv(GaugeField &force, const FermionField &X, const FermionField &Y, int dag)
243{
244 conformable(X.Grid(), Y.Grid());
245 conformable(X.Grid(), force.Grid());
246 GaugeLinkField force_mu(force.Grid()), lambda(force.Grid());
247 GaugeField clover_force(force.Grid());
248 PropagatorField Lambda(force.Grid());
249
250 // Guido: Here we are hitting some performance issues:
251 // need to extract the components of the DoubledGaugeField
252 // for each call
253 // Possible solution
254 // Create a vector object to store them? (cons: wasting space)
255 std::vector<GaugeLinkField> U(Nd, this->Umu.Grid());
256
257 Impl::extractLinkField(U, this->Umu);
258
259 force = Zero();
260 // Derivative of the Wilson hopping term
261 this->DhopDeriv(force, X, Y, dag);
262
264 // Clover term derivative
266 Impl::outerProductImpl(Lambda, X, Y);
267 //std::cout << "Lambda:" << Lambda << std::endl;
268
269 Gamma::Algebra sigma[] = {
270 Gamma::Algebra::SigmaXY,
271 Gamma::Algebra::SigmaXZ,
272 Gamma::Algebra::SigmaXT,
273 Gamma::Algebra::MinusSigmaXY,
274 Gamma::Algebra::SigmaYZ,
275 Gamma::Algebra::SigmaYT,
276 Gamma::Algebra::MinusSigmaXZ,
277 Gamma::Algebra::MinusSigmaYZ,
278 Gamma::Algebra::SigmaZT,
279 Gamma::Algebra::MinusSigmaXT,
280 Gamma::Algebra::MinusSigmaYT,
281 Gamma::Algebra::MinusSigmaZT};
282
283 /*
284 sigma_{\mu \nu}=
285 | 0 sigma[0] sigma[1] sigma[2] |
286 | sigma[3] 0 sigma[4] sigma[5] |
287 | sigma[6] sigma[7] 0 sigma[8] |
288 | sigma[9] sigma[10] sigma[11] 0 |
289 */
290
291 int count = 0;
292 clover_force = Zero();
293 for (int mu = 0; mu < 4; mu++)
294 {
295 force_mu = Zero();
296 for (int nu = 0; nu < 4; nu++)
297 {
298 if (mu == nu)
299 continue;
300
301 RealD factor;
302 if (nu == 4 || mu == 4)
303 {
304 factor = 2.0 * csw_t;
305 }
306 else
307 {
308 factor = 2.0 * csw_r;
309 }
310 PropagatorField Slambda = Gamma(sigma[count]) * Lambda; // sigma checked
311 Impl::TraceSpinImpl(lambda, Slambda); // traceSpin ok
312 force_mu -= factor*CloverHelpers::Cmunu(U, lambda, mu, nu); // checked
313 count++;
314 }
315
316 pokeLorentz(clover_force, U[mu] * force_mu, mu);
317 }
318 //clover_force *= csw;
319 force += clover_force;
320}
321
322// Derivative parts
323template<class Impl, class CloverHelpers>
324void WilsonCloverFermion<Impl, CloverHelpers>::MooDeriv(GaugeField &mat, const FermionField &X, const FermionField &Y, int dag)
325{
326 assert(0);
327}
328
329// Derivative parts
330template<class Impl, class CloverHelpers>
331void WilsonCloverFermion<Impl, CloverHelpers>::MeeDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
332{
333 assert(0); // not implemented yet
334}
335
static const int Even
static const int Odd
void conformable(const Lattice< obj1 > &lhs, const Lattice< obj2 > &rhs)
Lattice< vobj > adj(const Lattice< vobj > &lhs)
void pickCheckerboard(int cb, Lattice< vobj > &half, const Lattice< vobj > &full)
GridLogger GridLogDebug(1, "Debug", GridLogColours, "PURPLE")
GridLogger GridLogWarning(1, "Warning", GridLogColours, "YELLOW")
#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 Nd
Definition QCD.h:52
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
static constexpr int InverseNo
Definition QCD.h:71
static constexpr int InverseYes
Definition QCD.h:72
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)
static void Instantiate(CloverField &CloverTerm, CloverField &CloverTermInv, RealD csw_t, RealD diag_mass)
Definition Gamma.h:10
virtual void MooeeInternal(const FermionField &in, FermionField &out, int dag, int inv)
virtual void MeeDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
virtual void MooeeInv(const FermionField &in, FermionField &out)
WilsonCloverFermion(GaugeField &_Umu, GridCartesian &Fgrid, GridRedBlackCartesian &Hgrid, const RealD _mass, const RealD _csw_r=0.0, const RealD _csw_t=0.0, const WilsonAnisotropyCoefficients &clover_anisotropy=WilsonAnisotropyCoefficients(), const ImplParams &impl_p=ImplParams())
void MDeriv(GaugeField &force, const FermionField &X, const FermionField &Y, int dag)
virtual void Mdag(const FermionField &in, FermionField &out)
virtual void Mooee(const FermionField &in, FermionField &out)
virtual void M(const FermionField &in, FermionField &out)
virtual void MooeeInvDag(const FermionField &in, FermionField &out)
void ImportGauge(const GaugeField &_Umu)
virtual void MooDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
virtual void MooeeDag(const FermionField &in, FermionField &out)
static CloverField fillCloverYZ(const GaugeLinkField &F)
void multCloverField(_SpinorField &out, const CloverField &C, const _SpinorField &phi)
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
WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid, GridRedBlackCartesian &Hgrid, RealD _mass, const ImplParams &p=ImplParams(), const WilsonAnisotropyCoefficients &anis=WilsonAnisotropyCoefficients())
void Dhop(const FermionField &in, FermionField &out, int dag)
void ImportGauge(const GaugeField &_Umu)
void DhopDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
static void FieldStrength(GaugeMat &FS, const GaugeLorentz &Umu, int mu, int nu)
Definition Simd.h:194