Grid 0.7.0
ImprovedStaggeredFermionImplementation.h
Go to the documentation of this file.
1/*************************************************************************************
2
3Grid physics library, www.github.com/paboyle/Grid
4
5Source file: ./lib/qcd/action/fermion/ImprovedStaggeredFermion.cc
6
7Copyright (C) 2015
8
9Author: Azusa Yamaguchi, Peter Boyle
10
11This program is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation; either version 2 of the License, or
14(at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19GNU General Public License for more details.
20
21You should have received a copy of the GNU General Public License along
22with this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25See the full license in the file "LICENSE" in the top level distribution
26directory
27*************************************************************************************/
28/* END LEGAL */
29#include <Grid/Grid.h>
30
31#pragma once
32
34
36// Constructor and gauge import
38
39template <class Impl>
41 RealD _mass,
42 RealD _c1, RealD _c2,RealD _u0,
43 const ImplParams &p)
44 : Kernels(p),
45 _grid(&Fgrid),
46 _cbgrid(&Hgrid),
48 StencilEven(&Hgrid, npoint, Even, directions, displacements,p), // source is Even
49 StencilOdd(&Hgrid, npoint, Odd, directions, displacements,p), // source is Odd
50 mass(_mass),
51 Umu(&Fgrid),
52 UmuEven(&Hgrid),
53 UmuOdd(&Hgrid),
54 UUUmu(&Fgrid),
55 UUUmuEven(&Hgrid),
56 UUUmuOdd(&Hgrid) ,
57 _tmp(&Hgrid)
58{
59 int vol4;
60 int LLs=1;
61 c1=_c1;
62 c2=_c2;
63 u0=_u0;
64 vol4= _grid->oSites();
65 Stencil.BuildSurfaceList(LLs,vol4);
66 vol4= _cbgrid->oSites();
67 StencilEven.BuildSurfaceList(LLs,vol4);
68 StencilOdd.BuildSurfaceList(LLs,vol4);
69}
70
71template <class Impl>
72ImprovedStaggeredFermion<Impl>::ImprovedStaggeredFermion(GaugeField &_Uthin, GaugeField &_Ufat, GridCartesian &Fgrid,
73 GridRedBlackCartesian &Hgrid, RealD _mass,
74 RealD _c1, RealD _c2,RealD _u0,
75 const ImplParams &p)
76 : ImprovedStaggeredFermion(Fgrid,Hgrid,_mass,_c1,_c2,_u0,p)
77{
78 ImportGauge(_Uthin,_Ufat);
79}
80
82// Momentum space propagator should be
83// https://arxiv.org/pdf/hep-lat/9712010.pdf
84//
85// mom space action.
86// gamma_mu i ( c1 sin pmu + c2 sin 3 pmu ) + m
87//
88// must track through staggered flavour/spin reduction in literature to
89// turn to free propagator for the one component chi field, a la page 4/5
90// of above link to implmement fourier based solver.
92template <class Impl>
93void ImprovedStaggeredFermion<Impl>::ImportGaugeSimple(const GaugeField &_Utriple,const GaugeField &_Ufat)
94{
96 // Trivial import; phases and fattening and such like preapplied
98 GaugeLinkField U(GaugeGrid());
99
100 for (int mu = 0; mu < Nd; mu++) {
101
102 U = PeekIndex<LorentzIndex>(_Utriple, mu);
104
105 U = adj( Cshift(U, mu, -3));
107
108 U = PeekIndex<LorentzIndex>(_Ufat, mu);
110
111 U = adj( Cshift(U, mu, -1));
113
114 }
116}
117template <class Impl>
118void ImprovedStaggeredFermion<Impl>::ImportGaugeSimple(const DoubledGaugeField &_UUU,const DoubledGaugeField &_U)
119{
120
121 Umu = _U;
122 UUUmu = _UUU;
124}
125
126template <class Impl>
134template <class Impl>
135void ImprovedStaggeredFermion<Impl>::ImportGauge(const GaugeField &_Uthin,const GaugeField &_Ufat)
136{
137 GaugeLinkField U(GaugeGrid());
138
140 // Double Store should take two fields for Naik and one hop separately.
142 Impl::DoubleStore(GaugeGrid(), UUUmu, Umu, _Uthin, _Ufat );
143
145 // Apply scale factors to get the right fermion Kinetic term
146 // Could pass coeffs into the double store to save work.
147 // 0.5 ( U p(x+mu) - Udag(x-mu) p(x-mu) )
149 for (int mu = 0; mu < Nd; mu++) {
150
152 PokeIndex<LorentzIndex>(Umu, U*( 0.5*c1/u0), mu );
153
155 PokeIndex<LorentzIndex>(Umu, U*(-0.5*c1/u0), mu+4);
156
158 PokeIndex<LorentzIndex>(UUUmu, U*( 0.5*c2/u0/u0/u0), mu );
159
161 PokeIndex<LorentzIndex>(UUUmu, U*(-0.5*c2/u0/u0/u0), mu+4);
162 }
163
165}
166
168// Implement the interface
170
171template <class Impl>
172void ImprovedStaggeredFermion<Impl>::M(const FermionField &in, FermionField &out)
173{
174 out.Checkerboard() = in.Checkerboard();
175 Dhop(in, out, DaggerNo);
176 axpy(out, mass, in, out);
177}
178
179template <class Impl>
180void ImprovedStaggeredFermion<Impl>::Mdag(const FermionField &in, FermionField &out)
181{
182 out.Checkerboard() = in.Checkerboard();
183 Dhop(in, out, DaggerYes);
184 axpy(out, mass, in, out);
185}
186
187template <class Impl>
188void ImprovedStaggeredFermion<Impl>::Meooe(const FermionField &in, FermionField &out)
189{
190 if (in.Checkerboard() == Odd) {
191 DhopEO(in, out, DaggerNo);
192 } else {
193 DhopOE(in, out, DaggerNo);
194 }
195}
196template <class Impl>
197void ImprovedStaggeredFermion<Impl>::MeooeDag(const FermionField &in, FermionField &out)
198{
199 if (in.Checkerboard() == Odd) {
200 DhopEO(in, out, DaggerYes);
201 } else {
202 DhopOE(in, out, DaggerYes);
203 }
204}
205
206template <class Impl>
207void ImprovedStaggeredFermion<Impl>::Mooee(const FermionField &in, FermionField &out)
208{
209 out.Checkerboard() = in.Checkerboard();
210 typename FermionField::scalar_type scal(mass);
211 out = scal * in;
212}
213
214template <class Impl>
215void ImprovedStaggeredFermion<Impl>::MooeeDag(const FermionField &in, FermionField &out)
216{
217 out.Checkerboard() = in.Checkerboard();
218 Mooee(in, out);
219}
220
221template <class Impl>
222void ImprovedStaggeredFermion<Impl>::MooeeInv(const FermionField &in, FermionField &out)
223{
224 out.Checkerboard() = in.Checkerboard();
225 out = (1.0 / (mass)) * in;
226}
227
228template <class Impl>
229void ImprovedStaggeredFermion<Impl>::MooeeInvDag(const FermionField &in,FermionField &out)
230{
231 out.Checkerboard() = in.Checkerboard();
232 MooeeInv(in, out);
233}
234
236// Internal
238
239template <class Impl>
240void ImprovedStaggeredFermion<Impl>::DerivInternal(StencilImpl &st, DoubledGaugeField &U, DoubledGaugeField &UUU,
241 GaugeField & mat,
242 const FermionField &A, const FermionField &B, int dag)
243{
244 assert((dag == DaggerNo) || (dag == DaggerYes));
245
246 Compressor compressor;
247
248 FermionField Btilde(B.Grid());
249 FermionField Atilde(B.Grid());
250 Atilde = A;
251
252 st.HaloExchange(B, compressor);
253
254 for (int mu = 0; mu < Nd; mu++) {
255
257 // Call the single hop
259 autoView( U_v , U, CpuRead);
260 autoView( UUU_v , UUU, CpuRead);
261 autoView( B_v , B, CpuWrite);
262 autoView( Btilde_v , Btilde, CpuWrite);
263 thread_for(sss,B.Grid()->oSites(),{
264 Kernels::DhopDirKernel(st, U_v, UUU_v, st.CommBuf(), sss, sss, B_v, Btilde_v, mu,1);
265 });
266
267 // Force in three link terms
268 //
269 // Impl::InsertForce4D(mat, Btilde, Atilde, mu);
270 //
271 // dU_ac(x)/dt = i p_ab U_bc(x)
272 //
273 // => dS_f/dt = dS_f/dU_ac(x) . dU_ac(x)/dt = i p_ab U_bc(x) dS_f/dU_ac(x)
274 //
275 // One link: form fragments S_f = A U B
276 //
277 // write Btilde = U(x) B(x+mu)
278 //
279 // mat+= TraceIndex<SpinIndex>(outerProduct(Btilde,A));
280 //
281 // Three link: form fragments S_f = A UUU B
282 //
283 // mat+= outer ( A, UUUB) <-- Best take DhopDeriv with one linke or identity matrix
284 // mat+= outer ( AU, UUB) <-- and then use covariant cshift?
285 // mat+= outer ( AUU, UB) <-- Returned from call to DhopDir
286
287 assert(0);// need to figure out the force interface with a blasted three link term.
288
289 }
290}
291
292template <class Impl>
293void ImprovedStaggeredFermion<Impl>::DhopDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
294{
295 conformable(U.Grid(), _grid);
296 conformable(U.Grid(), V.Grid());
297 conformable(U.Grid(), mat.Grid());
298
299 mat.Checkerboard() = U.Checkerboard();
300
301 DerivInternal(Stencil, Umu, UUUmu, mat, U, V, dag);
302}
303
304template <class Impl>
305void ImprovedStaggeredFermion<Impl>::DhopDerivOE(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
306{
307 conformable(U.Grid(), _cbgrid);
308 conformable(U.Grid(), V.Grid());
309 conformable(U.Grid(), mat.Grid());
310
311 assert(V.Checkerboard() == Even);
312 assert(U.Checkerboard() == Odd);
313 mat.Checkerboard() = Odd;
314
315 DerivInternal(StencilEven, UmuOdd, UUUmuOdd, mat, U, V, dag);
316}
317
318template <class Impl>
319void ImprovedStaggeredFermion<Impl>::DhopDerivEO(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
320{
321 conformable(U.Grid(), _cbgrid);
322 conformable(U.Grid(), V.Grid());
323 conformable(U.Grid(), mat.Grid());
324
325 assert(V.Checkerboard() == Odd);
326 assert(U.Checkerboard() == Even);
327 mat.Checkerboard() = Even;
328
329 DerivInternal(StencilOdd, UmuEven, UUUmuEven, mat, U, V, dag);
330}
331
332template <class Impl>
333void ImprovedStaggeredFermion<Impl>::Dhop(const FermionField &in, FermionField &out, int dag)
334{
335 conformable(in.Grid(), _grid); // verifies full grid
336 conformable(in.Grid(), out.Grid());
337
338 out.Checkerboard() = in.Checkerboard();
339
340 DhopInternal(Stencil, Umu, UUUmu, in, out, dag);
341}
342
343template <class Impl>
344void ImprovedStaggeredFermion<Impl>::DhopOE(const FermionField &in, FermionField &out, int dag)
345{
346 conformable(in.Grid(), _cbgrid); // verifies half grid
347 conformable(in.Grid(), out.Grid()); // drops the cb check
348
349 assert(in.Checkerboard() == Even);
350 out.Checkerboard() = Odd;
351
352 DhopInternal(StencilEven, UmuOdd, UUUmuOdd, in, out, dag);
353}
354
355template <class Impl>
356void ImprovedStaggeredFermion<Impl>::DhopEO(const FermionField &in, FermionField &out, int dag)
357{
358 conformable(in.Grid(), _cbgrid); // verifies half grid
359 conformable(in.Grid(), out.Grid()); // drops the cb check
360
361 assert(in.Checkerboard() == Odd);
362 out.Checkerboard() = Even;
363
364 DhopInternal(StencilOdd, UmuEven, UUUmuEven, in, out, dag);
365}
366
367template <class Impl>
368void ImprovedStaggeredFermion<Impl>::Mdir(const FermionField &in, FermionField &out, int dir, int disp)
369{
370 DhopDir(in, out, dir, disp);
371}
372template <class Impl>
373void ImprovedStaggeredFermion<Impl>::MdirAll(const FermionField &in, std::vector<FermionField> &out)
374{
375 assert(0); // Not implemented yet
376}
377
378template <class Impl>
379void ImprovedStaggeredFermion<Impl>::DhopDir(const FermionField &in, FermionField &out, int dir, int disp)
380{
381
382 Compressor compressor;
383 Stencil.HaloExchange(in, compressor);
384 autoView( Umu_v , Umu, CpuRead);
385 autoView( UUUmu_v , UUUmu, CpuRead);
386 autoView( in_v , in, CpuRead);
387 autoView( out_v , out, CpuWrite);
388 thread_for( sss, in.Grid()->oSites(),{
389 Kernels::DhopDirKernel(Stencil, Umu_v, UUUmu_v, Stencil.CommBuf(), sss, sss, in_v, out_v, dir, disp);
390 });
391};
392
393
394template <class Impl>
396 DoubledGaugeField &U,
397 DoubledGaugeField &UUU,
398 const FermionField &in,
399 FermionField &out, int dag)
400{
402 DhopInternalOverlappedComms(st,U,UUU,in,out,dag);
403 else
404 DhopInternalSerialComms(st,U,UUU,in,out,dag);
405}
406template <class Impl>
408 DoubledGaugeField &U,
409 DoubledGaugeField &UUU,
410 const FermionField &in,
411 FermionField &out, int dag)
412{
413 Compressor compressor;
414 int len = U.Grid()->oSites();
415
416 st.Prepare();
417 st.HaloGather(in,compressor);
418
419 std::vector<std::vector<CommsRequest_t> > requests;
420 st.CommunicateBegin(requests);
421
422 st.CommsMergeSHM(compressor);
423
425 // Removed explicit thread comms
427 {
428 int interior=1;
429 int exterior=0;
430 Kernels::DhopImproved(st,U,UUU,in,out,dag,interior,exterior);
431 }
432
433 st.CommunicateComplete(requests);
434
435 // First to enter, last to leave timing
436 st.CommsMerge(compressor);
437
438 {
439 int interior=0;
440 int exterior=1;
441 Kernels::DhopImproved(st,U,UUU,in,out,dag,interior,exterior);
442 }
443}
444
445
446template <class Impl>
448 DoubledGaugeField &U,
449 DoubledGaugeField &UUU,
450 const FermionField &in,
451 FermionField &out, int dag)
452{
453 assert((dag == DaggerNo) || (dag == DaggerYes));
454
455 Compressor compressor;
456 st.HaloExchange(in, compressor);
457
458 {
459 int interior=1;
460 int exterior=1;
461 Kernels::DhopImproved(st,U,UUU,in,out,dag,interior,exterior);
462 }
463};
464
466// Conserved current - not yet implemented.
468template <class Impl>
470 PropagatorField &q_in_2,
471 PropagatorField &q_out,
472 PropagatorField &src,
473 Current curr_type,
474 unsigned int mu)
475{
476 assert(0);
477}
478
479template <class Impl>
481 PropagatorField &q_out,
482 PropagatorField &src,
483 Current curr_type,
484 unsigned int mu,
485 unsigned int tmin,
486 unsigned int tmax,
487 ComplexField &lattice_cmplx)
488{
489 assert(0);
490
491}
492
static const int Even
static const int Odd
auto Cshift(const Expression &expr, int dim, int shift) -> decltype(closure(expr))
Definition Cshift.h:55
B
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 PokeIndex(Lattice< vobj > &lhs, const Lattice< decltype(peekIndex< Index >(vobj(), 0))> &rhs, int i)
auto PeekIndex(const Lattice< vobj > &lhs, int i) -> Lattice< decltype(peekIndex< Index >(vobj(), i))>
Lattice< vobj > adj(const Lattice< vobj > &lhs)
void pickCheckerboard(int cb, Lattice< vobj > &half, const Lattice< vobj > &full)
#define autoView(l_v, l, mode)
@ CpuRead
@ CpuWrite
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
static constexpr int DaggerYes
Definition QCD.h:70
static constexpr int Nd
Definition QCD.h:52
static constexpr int DaggerNo
Definition QCD.h:69
double RealD
Definition Simd.h:61
#define thread_for(i, num,...)
Definition Threads.h:60
static INTERNAL_PRECISION U
Definition Zolotarev.cc:230
static const std::vector< int > displacements
static const std::vector< int > directions
void ImportGauge(const GaugeField &_Uthin)
void M(const FermionField &in, FermionField &out)
void Meooe(const FermionField &in, FermionField &out)
void MooeeInvDag(const FermionField &in, FermionField &out)
void DhopDerivEO(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
void MooeeInv(const FermionField &in, FermionField &out)
void DhopDir(const FermionField &in, FermionField &out, int dir, int disp)
void Mdag(const FermionField &in, FermionField &out)
void MdirAll(const FermionField &in, std::vector< FermionField > &out)
void Mdir(const FermionField &in, FermionField &out, int dir, int disp)
void Mooee(const FermionField &in, FermionField &out)
void ImportGaugeSimple(const GaugeField &_UUU, const GaugeField &_U)
void SeqConservedCurrent(PropagatorField &q_in, PropagatorField &q_out, PropagatorField &srct, Current curr_type, unsigned int mu, unsigned int tmin, unsigned int tmax, ComplexField &lattice_cmplx)
void MooeeDag(const FermionField &in, FermionField &out)
void DhopDerivOE(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
void Dhop(const FermionField &in, FermionField &out, int dag)
void DhopOE(const FermionField &in, FermionField &out, int dag)
void DerivInternal(StencilImpl &st, DoubledGaugeField &U, DoubledGaugeField &UUU, GaugeField &mat, const FermionField &A, const FermionField &B, int dag)
void DhopDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
void DhopEO(const FermionField &in, FermionField &out, int dag)
void DhopInternalSerialComms(StencilImpl &st, DoubledGaugeField &U, DoubledGaugeField &UUU, const FermionField &in, FermionField &out, int dag)
void MeooeDag(const FermionField &in, FermionField &out)
void DhopInternal(StencilImpl &st, DoubledGaugeField &U, DoubledGaugeField &UUU, const FermionField &in, FermionField &out, int dag)
void DhopInternalOverlappedComms(StencilImpl &st, DoubledGaugeField &U, DoubledGaugeField &UUU, const FermionField &in, FermionField &out, int dag)
StaggeredKernels< Impl > Kernels
ImprovedStaggeredFermion(GaugeField &_Uthin, GaugeField &_Ufat, GridCartesian &Fgrid, GridRedBlackCartesian &Hgrid, RealD _mass, RealD _c1, RealD _c2, RealD _u0, const ImplParams &p=ImplParams())
void ContractConservedCurrent(PropagatorField &q_in_1, PropagatorField &q_in_2, PropagatorField &q_out, PropagatorField &src, Current curr_type, unsigned int mu)
void DhopImproved(StencilImpl &st, DoubledGaugeField &U, DoubledGaugeField &UUU, const FermionField &in, FermionField &out, int dag, int interior, int exterior)