Grid 0.7.0
WilsonFermion5DImplementation.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/WilsonFermion5D.cc
6
7 Copyright (C) 2015
8
9Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
10Author: Peter Boyle <pabobyle@ph.ed.ac.uk>
11Author: Peter Boyle <paboyle@ph.ed.ac.uk>
12Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local>
13Author: paboyle <paboyle@ph.ed.ac.uk>
14Author: Guido Cossu <guido.cossu@ed.ac.uk>
15Author: Andrew Lawson <andrew.lawson1991@gmail.com>
16Author: Vera Guelpers <V.M.Guelpers@soton.ac.uk>
17Author: Christoph Lehner <christoph@lhnr.de>
18
19 This program is free software; you can redistribute it and/or modify
20 it under the terms of the GNU General Public License as published by
21 the Free Software Foundation; either version 2 of the License, or
22 (at your option) any later version.
23
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 GNU General Public License for more details.
28
29 You should have received a copy of the GNU General Public License along
30 with this program; if not, write to the Free Software Foundation, Inc.,
31 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32
33 See the full license in the file "LICENSE" in the top level distribution directory
34 *************************************************************************************/
35 /* END LEGAL */
39
41
42 // 5d lattice for DWF.
43template<class Impl>
45 GridCartesian &FiveDimGrid,
46 GridRedBlackCartesian &FiveDimRedBlackGrid,
47 GridCartesian &FourDimGrid,
48 GridRedBlackCartesian &FourDimRedBlackGrid,
49 RealD _M5,const ImplParams &p) :
50 Kernels(p),
51 _FiveDimGrid (&FiveDimGrid),
52 _FiveDimRedBlackGrid(&FiveDimRedBlackGrid),
53 _FourDimGrid (&FourDimGrid),
54 _FourDimRedBlackGrid(&FourDimRedBlackGrid),
58 M5(_M5),
62 _tmp(&FiveDimRedBlackGrid),
63 Dirichlet(0)
64{
65 // some assertions
66 assert(FiveDimGrid._ndimension==5);
67 assert(FourDimGrid._ndimension==4);
68 assert(FourDimRedBlackGrid._ndimension==4);
69 assert(FiveDimRedBlackGrid._ndimension==5);
70 assert(FiveDimRedBlackGrid._checker_dim==1); // Don't checker the s direction
71
72 // extent of fifth dim and not spread out
73 Ls=FiveDimGrid._fdimensions[0];
74 assert(FiveDimRedBlackGrid._fdimensions[0]==Ls);
75 assert(FiveDimGrid._processors[0] ==1);
76 assert(FiveDimRedBlackGrid._processors[0] ==1);
77
78 // Other dimensions must match the decomposition of the four-D fields
79 for(int d=0;d<4;d++){
80
81 assert(FiveDimGrid._processors[d+1] ==FourDimGrid._processors[d]);
82 assert(FiveDimRedBlackGrid._processors[d+1] ==FourDimGrid._processors[d]);
83 assert(FourDimRedBlackGrid._processors[d] ==FourDimGrid._processors[d]);
84
85 assert(FiveDimGrid._fdimensions[d+1] ==FourDimGrid._fdimensions[d]);
86 assert(FiveDimRedBlackGrid._fdimensions[d+1]==FourDimGrid._fdimensions[d]);
87 assert(FourDimRedBlackGrid._fdimensions[d] ==FourDimGrid._fdimensions[d]);
88
89 assert(FiveDimGrid._simd_layout[d+1] ==FourDimGrid._simd_layout[d]);
90 assert(FiveDimRedBlackGrid._simd_layout[d+1]==FourDimGrid._simd_layout[d]);
91 assert(FourDimRedBlackGrid._simd_layout[d] ==FourDimGrid._simd_layout[d]);
92 }
93
94 if ( p.dirichlet.size() == Nd+1) {
95 Coordinate block = p.dirichlet;
96 if ( block[0] || block[1] || block[2] || block[3] || block[4] ){
97 Dirichlet = 1;
98 std::cout << GridLogMessage << " WilsonFermion: non-trivial Dirichlet condition "<< block << std::endl;
99 std::cout << GridLogMessage << " WilsonFermion: partial Dirichlet "<< p.partialDirichlet << std::endl;
100 Block = block;
101 }
102 } else {
103 Coordinate block(Nd+1,0);
104 Block = block;
107 if (Impl::LsVectorised) {
108
109 int nsimd = Simd::Nsimd();
111 // Dimension zero of the five-d is the Ls direction
112 assert(FiveDimGrid._simd_layout[0] ==nsimd);
113 assert(FiveDimRedBlackGrid._simd_layout[0]==nsimd);
114
115 for(int d=0;d<4;d++){
116 assert(FourDimGrid._simd_layout[d]==1);
117 assert(FourDimRedBlackGrid._simd_layout[d]==1);
118 assert(FiveDimRedBlackGrid._simd_layout[d+1]==1);
121 } else {
123 // Dimension zero of the five-d is the Ls direction
124 assert(FiveDimRedBlackGrid._simd_layout[0]==1);
125 assert(FiveDimGrid._simd_layout[0] ==1);
126
129 // Allocate the required comms buffer
130 ImportGauge(_Umu);
131 // Build lists of exterior only nodes
132 int LLs = FiveDimGrid._rdimensions[0];
133 int vol4;
134 vol4=FourDimGrid.oSites();
135 Stencil.BuildSurfaceList(LLs,vol4);
136
137 vol4=FourDimRedBlackGrid.oSites();
138 StencilEven.BuildSurfaceList(LLs,vol4);
139 StencilOdd.BuildSurfaceList(LLs,vol4);
140
141}
143template<class Impl>
144void WilsonFermion5D<Impl>::ImportGauge(const GaugeField &_Umu)
145{
146 GaugeField HUmu(_Umu.Grid());
147 HUmu = _Umu*(-0.5);
148 if ( Dirichlet ) {
149
150 if ( this->Params.partialDirichlet ) {
151 std::cout << GridLogMessage << " partialDirichlet BCs " <<Block<<std::endl;
152 } else {
153 std::cout << GridLogMessage << " FULL Dirichlet BCs " <<Block<<std::endl;
155
156 std:: cout << GridLogMessage << "Checking block size multiple of rank boundaries for Dirichlet"<<std::endl;
157 for(int d=0;d<Nd;d++) {
158 int GaugeBlock = Block[d+1];
159 int ldim=GaugeGrid()->LocalDimensions()[d];
160 if (GaugeBlock) assert( (GaugeBlock%ldim)==0);
162
163 if (!this->Params.partialDirichlet) {
164 std::cout << GridLogMessage << " Dirichlet filtering gauge field BCs block " <<Block<<std::endl;
165 Coordinate GaugeBlock(Nd);
166 for(int d=0;d<Nd;d++) GaugeBlock[d] = Block[d+1];
167 DirichletFilter<GaugeField> Filter(GaugeBlock);
168 Filter.applyFilter(HUmu);
169 } else {
170 std::cout << GridLogMessage << " Dirichlet "<< Dirichlet << " NOT filtered gauge field" <<std::endl;
171 }
172 }
173 Impl::DoubleStore(GaugeGrid(),Umu,HUmu);
174 pickCheckerboard(Even,UmuEven,Umu);
175 pickCheckerboard(Odd ,UmuOdd,Umu);
176}
177template<class Impl>
178void WilsonFermion5D<Impl>::DhopDir(const FermionField &in, FermionField &out,int dir5,int disp)
179{
180 int dir = dir5-1; // Maps to the ordering above in "directions" that is passed to stencil
181 // we drop off the innermost fifth dimension
182 // assert( (disp==1)||(disp==-1) );
183 // assert( (dir>=0)&&(dir<4) ); //must do x,y,z or t;
184
185 int skip = (disp==1) ? 0 : 1;
186 int dirdisp = dir+skip*4;
187 int gamma = dir+(1-skip)*4;
188
189 Compressor compressor(DaggerNo);
190 Stencil.HaloExchange(in,compressor);
191
192 uint64_t Nsite = Umu.Grid()->oSites();
193 Kernels::DhopDirKernel(Stencil,Umu,Stencil.CommBuf(),Ls,Nsite,in,out,dirdisp,gamma);
194
195};
196template<class Impl>
197void WilsonFermion5D<Impl>::DhopDirAll(const FermionField &in, std::vector<FermionField> &out)
198{
199 Compressor compressor(DaggerNo);
200 Stencil.HaloExchange(in,compressor);
201 uint64_t Nsite = Umu.Grid()->oSites();
202 Kernels::DhopDirAll(Stencil,Umu,Stencil.CommBuf(),Ls,Nsite,in,out);
203};
204
205
206template<class Impl>
208 DoubledGaugeField & U,
209 GaugeField &mat,
210 const FermionField &A,
211 const FermionField &B,
212 int dag)
213{
214 assert((dag==DaggerNo) ||(dag==DaggerYes));
215
216 conformable(st.Grid(),A.Grid());
217 conformable(st.Grid(),B.Grid());
218
219 Compressor compressor(dag);
220
221 FermionField Btilde(B.Grid());
222 FermionField Atilde(B.Grid());
223
224 st.HaloExchange(B,compressor);
225
226 Atilde=A;
227 int LLs = B.Grid()->_rdimensions[0];
228
229
230 for (int mu = 0; mu < Nd; mu++) {
232 // Flip gamma if dag
234 int gamma = mu;
235 if (!dag) gamma += Nd;
236
238 // Call the single hop
240
241 int Usites = U.Grid()->oSites();
242
243 Kernels::DhopDirKernel(st, U, st.CommBuf(), Ls, Usites, B, Btilde, mu,gamma);
244
246 // spin trace outer product
248 Impl::InsertForce5D(mat, Btilde, Atilde, mu);
249 }
250}
251
252template<class Impl>
254 const FermionField &A,
255 const FermionField &B,
256 int dag)
257{
258 conformable(A.Grid(),FermionGrid());
259 conformable(A.Grid(),B.Grid());
260
261 //conformable(GaugeGrid(),mat.Grid());// this is not general! leaving as a comment
262
263 mat.Checkerboard() = A.Checkerboard();
264 // mat.checkerboard = A.checkerboard;
265
266 DerivInternal(Stencil,Umu,mat,A,B,dag);
267}
268
269template<class Impl>
271 const FermionField &A,
272 const FermionField &B,
273 int dag)
274{
276 conformable(A.Grid(),B.Grid());
277
278 assert(B.Checkerboard()==Odd);
279 assert(A.Checkerboard()==Even);
280 mat.Checkerboard() = Even;
281
283}
284
285
286template<class Impl>
288 const FermionField &A,
289 const FermionField &B,
290 int dag)
291{
293 conformable(A.Grid(),B.Grid());
294
295 assert(B.Checkerboard()==Even);
296 assert(A.Checkerboard()==Odd);
297 mat.Checkerboard() = Odd;
298
300}
301
302template<class Impl>
304 DoubledGaugeField & U,
305 const FermionField &in, FermionField &out,int dag)
306{
308 DhopInternalOverlappedComms(st,U,in,out,dag);
309 else
310 DhopInternalSerialComms(st,U,in,out,dag);
311}
312
313
314template<class Impl>
316 DoubledGaugeField & U,
317 const FermionField &in, FermionField &out,int dag)
318{
319 GRID_TRACE("DhopInternalOverlappedComms");
320 Compressor compressor(dag);
321
322 int LLs = in.Grid()->_rdimensions[0];
323 int len = U.Grid()->oSites();
324
326 // Start comms // Gather intranode and extra node differentiated??
328 {
329 // std::cout << " WilsonFermion5D gather " <<std::endl;
330 GRID_TRACE("Gather");
331 st.HaloExchangeOptGather(in,compressor); // Put the barrier in the routine
332 }
333
334 // std::cout << " WilsonFermion5D Communicate Begin " <<std::endl;
335 std::vector<std::vector<CommsRequest_t> > requests;
336
337#if 1
339 // Overlap with comms
341 st.CommunicateBegin(requests);
342 st.CommsMergeSHM(compressor);// Could do this inside parallel region overlapped with comms
343#endif
344
346 // do the compute interior
348 int Opt = WilsonKernelsStatic::Opt; // Why pass this. Kernels should know
349 if (dag == DaggerYes) {
350 GRID_TRACE("DhopDagInterior");
351 Kernels::DhopDagKernel(Opt,st,U,st.CommBuf(),LLs,U.oSites(),in,out,1,0);
352 } else {
353 GRID_TRACE("DhopInterior");
354 Kernels::DhopKernel (Opt,st,U,st.CommBuf(),LLs,U.oSites(),in,out,1,0);
355 }
356
357 //ifdef GRID_ACCELERATED
358#if 0
360 // Overlap with comms -- on GPU the interior kernel call is nonblocking
362 st.CommunicateBegin(requests);
363 st.CommsMergeSHM(compressor);// Could do this inside parallel region overlapped with comms
364#endif
365
366
368 // Complete comms
370 // std::cout << " WilsonFermion5D Comms Complete " <<std::endl;
371 st.CommunicateComplete(requests);
372 // traceStop(id);
373
375 // do the compute exterior
377 {
378 // std::cout << " WilsonFermion5D Comms Merge " <<std::endl;
379 GRID_TRACE("Merge");
380 st.CommsMerge(compressor);
381 }
382
383
384 // std::cout << " WilsonFermion5D Exterior " <<std::endl;
385 if (dag == DaggerYes) {
386 GRID_TRACE("DhopDagExterior");
387 Kernels::DhopDagKernel(Opt,st,U,st.CommBuf(),LLs,U.oSites(),in,out,0,1);
388 } else {
389 GRID_TRACE("DhopExterior");
390 Kernels::DhopKernel (Opt,st,U,st.CommBuf(),LLs,U.oSites(),in,out,0,1);
391 }
392 // std::cout << " WilsonFermion5D Done " <<std::endl;
393}
394
395
396template<class Impl>
398 DoubledGaugeField & U,
399 const FermionField &in,
400 FermionField &out,int dag)
401{
402 GRID_TRACE("DhopInternalSerialComms");
403 Compressor compressor(dag);
404
405 int LLs = in.Grid()->_rdimensions[0];
406
407 // std::cout << " WilsonFermion5D Halo exch " <<std::endl;
408 {
409 GRID_TRACE("HaloExchange");
410 st.HaloExchangeOpt(in,compressor);
411 }
412
413 // std::cout << " WilsonFermion5D Dhop " <<std::endl;
415 if (dag == DaggerYes) {
416 GRID_TRACE("DhopDag");
417 Kernels::DhopDagKernel(Opt,st,U,st.CommBuf(),LLs,U.oSites(),in,out);
418 } else {
419 GRID_TRACE("Dhop");
420 Kernels::DhopKernel(Opt,st,U,st.CommBuf(),LLs,U.oSites(),in,out);
421 }
422 // std::cout << " WilsonFermion5D Done " <<std::endl;
423}
424
425
426template<class Impl>
427void WilsonFermion5D<Impl>::DhopOE(const FermionField &in, FermionField &out,int dag)
428{
429 conformable(in.Grid(),FermionRedBlackGrid()); // verifies half grid
430 conformable(in.Grid(),out.Grid()); // drops the cb check
431
432 assert(in.Checkerboard()==Even);
433 out.Checkerboard() = Odd;
434
435 DhopInternal(StencilEven,UmuOdd,in,out,dag);
436}
437template<class Impl>
438void WilsonFermion5D<Impl>::DhopEO(const FermionField &in, FermionField &out,int dag)
439{
440 conformable(in.Grid(),FermionRedBlackGrid()); // verifies half grid
441 conformable(in.Grid(),out.Grid()); // drops the cb check
442
443 assert(in.Checkerboard()==Odd);
444 out.Checkerboard() = Even;
445
446 DhopInternal(StencilOdd,UmuEven,in,out,dag);
447}
448template<class Impl>
449void WilsonFermion5D<Impl>::DhopComms(const FermionField &in, FermionField &out)
450{
451 int dag =0 ;
452 conformable(in.Grid(),FermionGrid()); // verifies full grid
453 conformable(in.Grid(),out.Grid());
454 out.Checkerboard() = in.Checkerboard();
455 Compressor compressor(dag);
456 Stencil.HaloExchangeOpt(in,compressor);
457}
458template<class Impl>
459void WilsonFermion5D<Impl>::DhopCalc(const FermionField &in, FermionField &out,uint64_t *ids)
460{
461 conformable(in.Grid(),FermionGrid()); // verifies full grid
462 conformable(in.Grid(),out.Grid());
463
464 out.Checkerboard() = in.Checkerboard();
465
466 int LLs = in.Grid()->_rdimensions[0];
468 Kernels::DhopKernel(Opt,Stencil,Umu,Stencil.CommBuf(),LLs,Umu.oSites(),in,out,ids);
469}
470
471template<class Impl>
472void WilsonFermion5D<Impl>::Dhop(const FermionField &in, FermionField &out,int dag)
473{
474 conformable(in.Grid(),FermionGrid()); // verifies full grid
475 conformable(in.Grid(),out.Grid());
476
477 out.Checkerboard() = in.Checkerboard();
478
479 DhopInternal(Stencil,Umu,in,out,dag);
480}
481template<class Impl>
482void WilsonFermion5D<Impl>::DW(const FermionField &in, FermionField &out,int dag)
483{
484 out.Checkerboard()=in.Checkerboard();
485 Dhop(in,out,dag); // -0.5 is included
486 axpy(out,4.0-M5,in,out);
487}
488template <class Impl>
489void WilsonFermion5D<Impl>::Meooe(const FermionField &in, FermionField &out)
490{
491 if (in.Checkerboard() == Odd) {
492 DhopEO(in, out, DaggerNo);
493 } else {
494 DhopOE(in, out, DaggerNo);
495 }
496}
497
498template <class Impl>
499void WilsonFermion5D<Impl>::MeooeDag(const FermionField &in, FermionField &out)
500{
501 if (in.Checkerboard() == Odd) {
502 DhopEO(in, out, DaggerYes);
503 } else {
504 DhopOE(in, out, DaggerYes);
505 }
506}
507
508template <class Impl>
509void WilsonFermion5D<Impl>::Mooee(const FermionField &in, FermionField &out)
510{
511 out.Checkerboard() = in.Checkerboard();
512 typename FermionField::scalar_type scal(4.0 + M5);
513 out = scal * in;
514}
515
516template <class Impl>
517void WilsonFermion5D<Impl>::MooeeDag(const FermionField &in, FermionField &out)
518{
519 out.Checkerboard() = in.Checkerboard();
520 Mooee(in, out);
521}
522
523template<class Impl>
524void WilsonFermion5D<Impl>::MooeeInv(const FermionField &in, FermionField &out)
525{
526 out.Checkerboard() = in.Checkerboard();
527 out = (1.0/(4.0 + M5))*in;
528}
529
530template<class Impl>
531void WilsonFermion5D<Impl>::MooeeInvDag(const FermionField &in, FermionField &out)
532{
533 out.Checkerboard() = in.Checkerboard();
534 MooeeInv(in,out);
535}
536
537template<class Impl>
538void WilsonFermion5D<Impl>::MomentumSpacePropagatorHt_5d(FermionField &out,const FermionField &in, RealD mass,std::vector<double> twist)
539{
540 // what type LatticeComplex
541 GridBase *_grid = _FourDimGrid;
542 GridBase *_5dgrid = _FiveDimGrid;
543
544 conformable(_5dgrid,out.Grid());
545
546 FermionField PRsource(_5dgrid);
547 FermionField PLsource(_5dgrid);
548 FermionField buf1_4d(_grid);
549 FermionField buf2_4d(_grid);
550 FermionField GR(_5dgrid);
551 FermionField GL(_5dgrid);
552 FermionField bufL_4d(_grid);
553 FermionField bufR_4d(_grid);
554
555 unsigned int Ls = in.Grid()->_rdimensions[0];
556
557 typedef typename FermionField::vector_type vector_type;
558 typedef typename FermionField::scalar_type ScalComplex;
559 typedef iSinglet<ScalComplex> Tcomplex;
560 typedef Lattice<iSinglet<vector_type> > LatComplex;
561
562 Gamma::Algebra Gmu [] = {
563 Gamma::Algebra::GammaX,
564 Gamma::Algebra::GammaY,
565 Gamma::Algebra::GammaZ,
566 Gamma::Algebra::GammaT
567 };
568
569 Gamma g5(Gamma::Algebra::Gamma5);
570
571 Coordinate latt_size = _grid->_fdimensions;
572
573 LatComplex sk(_grid); sk = Zero();
574 LatComplex sk2(_grid); sk2= Zero();
575 LatComplex W(_grid); W= Zero();
576 LatComplex one (_grid); one = ScalComplex(1.0,0.0);
577 LatComplex cosha(_grid);
578 LatComplex kmu(_grid);
579 LatComplex Wea(_grid);
580 LatComplex Wema(_grid);
581 LatComplex ea(_grid);
582 LatComplex ema(_grid);
583 LatComplex eaLs(_grid);
584 LatComplex emaLs(_grid);
585 LatComplex ea2Ls(_grid);
586 LatComplex ema2Ls(_grid);
587 LatComplex sinha(_grid);
588 LatComplex sinhaLs(_grid);
589 LatComplex coshaLs(_grid);
590 LatComplex A(_grid);
591 LatComplex F(_grid);
592 LatComplex App(_grid);
593 LatComplex Amm(_grid);
594 LatComplex Bpp(_grid);
595 LatComplex Bmm(_grid);
596 LatComplex ABpm(_grid); //Apm=Amp=Bpm=Bmp
597 LatComplex signW(_grid);
598
599 ScalComplex ci(0.0,1.0);
600
601 for(int mu=0;mu<Nd;mu++) {
602
603 LatticeCoordinate(kmu,mu);
604
605 RealD TwoPiL = M_PI * 2.0/ latt_size[mu];
606
607 kmu = TwoPiL * kmu;
608 kmu = kmu + TwoPiL * one * twist[mu];//momentum for twisted boundary conditions
609
610 sk2 = sk2 + 2.0*sin(kmu*0.5)*sin(kmu*0.5);
611 sk = sk + sin(kmu) *sin(kmu);
612 }
613
614 W = one - M5 + sk2;
615
617 // Cosh alpha -> alpha
619 cosha = (one + W*W + sk) / (abs(W)*2.0);
620
621 ea = (cosha + sqrt(cosha*cosha-one));
622 ema= (cosha - sqrt(cosha*cosha-one));
623 eaLs = pow(ea,Ls);
624 emaLs= pow(ema,Ls);
625 ea2Ls = pow(ea,2.0*Ls);
626 ema2Ls= pow(ema,2.0*Ls);
627 Wea= abs(W) * ea;
628 Wema= abs(W) * ema;
629 // a=log(ea);
630
631 sinha = 0.5*(ea - ema);
632 sinhaLs = 0.5*(eaLs-emaLs);
633 coshaLs = 0.5*(eaLs+emaLs);
634
635 A = one / (abs(W) * sinha * 2.0) * one / (sinhaLs * 2.0);
636 F = eaLs * (one - Wea + (Wema - one) * mass*mass);
637 F = F + emaLs * (Wema - one + (one - Wea) * mass*mass);
638 F = F - abs(W) * sinha * 4.0 * mass;
639
640 Bpp = (A/F) * (ema2Ls - one) * (one - Wema) * (one - mass*mass * one);
641 Bmm = (A/F) * (one - ea2Ls) * (one - Wea) * (one - mass*mass * one);
642 App = (A/F) * (ema2Ls - one) * ema * (ema - abs(W)) * (one - mass*mass * one);
643 Amm = (A/F) * (one - ea2Ls) * ea * (ea - abs(W)) * (one - mass*mass * one);
644 ABpm = (A/F) * abs(W) * sinha * 2.0 * (one + mass * coshaLs * 2.0 + mass*mass * one);
645
646 //P+ source, P- source
647 PRsource = (in + g5 * in) * 0.5;
648 PLsource = (in - g5 * in) * 0.5;
649
650 //calculate GR, GL
651 for(unsigned int ss=1;ss<=Ls;ss++)
652 {
653 bufR_4d = Zero();
654 bufL_4d = Zero();
655 for(unsigned int tt=1;tt<=Ls;tt++)
656 {
657 //possible sign if W<0
658 if((ss+tt)%2==1) signW = abs(W)/W;
659 else signW = one;
660
661 unsigned int f = (ss > tt) ? ss-tt : tt-ss; //f = abs(ss-tt)
662 //GR
663 buf1_4d = Zero();
664 ExtractSlice(buf1_4d, PRsource, (tt-1), 0);
665 //G(s,t)
666 bufR_4d = bufR_4d + A * eaLs * pow(ema,f) * signW * buf1_4d + A * emaLs * pow(ea,f) * signW * buf1_4d;
667 //A++*exp(a(s+t))
668 bufR_4d = bufR_4d + App * pow(ea,ss) * pow(ea,tt) * signW * buf1_4d ;
669 //A+-*exp(a(s-t))
670 bufR_4d = bufR_4d + ABpm * pow(ea,ss) * pow(ema,tt) * signW * buf1_4d ;
671 //A-+*exp(a(-s+t))
672 bufR_4d = bufR_4d + ABpm * pow(ema,ss) * pow(ea,tt) * signW * buf1_4d ;
673 //A--*exp(a(-s-t))
674 bufR_4d = bufR_4d + Amm * pow(ema,ss) * pow(ema,tt) * signW * buf1_4d ;
675
676 //GL
677 buf2_4d = Zero();
678 ExtractSlice(buf2_4d, PLsource, (tt-1), 0);
679 //G(s,t)
680 bufL_4d = bufL_4d + A * eaLs * pow(ema,f) * signW * buf2_4d + A * emaLs * pow(ea,f) * signW * buf2_4d;
681 //B++*exp(a(s+t))
682 bufL_4d = bufL_4d + Bpp * pow(ea,ss) * pow(ea,tt) * signW * buf2_4d ;
683 //B+-*exp(a(s-t))
684 bufL_4d = bufL_4d + ABpm * pow(ea,ss) * pow(ema,tt) * signW * buf2_4d ;
685 //B-+*exp(a(-s+t))
686 bufL_4d = bufL_4d + ABpm * pow(ema,ss) * pow(ea,tt) * signW * buf2_4d ;
687 //B--*exp(a(-s-t))
688 bufL_4d = bufL_4d + Bmm * pow(ema,ss) * pow(ema,tt) * signW * buf2_4d ;
689 }
690 InsertSlice(bufR_4d, GR, (ss-1), 0);
691 InsertSlice(bufL_4d, GL, (ss-1), 0);
692 }
693
694//calculate propagator
695 for(unsigned int ss=1;ss<=Ls;ss++)
696 {
697 bufR_4d = Zero();
698 bufL_4d = Zero();
699
700 //(i*gamma_mu*sin(p_mu) - W)*(GL*P- source)
701 buf1_4d = Zero();
702 ExtractSlice(buf1_4d, GL, (ss-1), 0);
703 buf2_4d = Zero();
704 for(int mu=0;mu<Nd;mu++) {
705 LatticeCoordinate(kmu,mu);
706 RealD TwoPiL = M_PI * 2.0/ latt_size[mu];
707 kmu = TwoPiL * kmu + TwoPiL * one * twist[mu];//twisted boundary
708 buf2_4d = buf2_4d + sin(kmu)*ci*(Gamma(Gmu[mu])*buf1_4d);
709 }
710 bufL_4d = buf2_4d - W * buf1_4d;
711
712 //(i*gamma_mu*sin(p_mu) - W)*(GR*P+ source)
713 buf1_4d = Zero();
714 ExtractSlice(buf1_4d, GR, (ss-1), 0);
715 buf2_4d = Zero();
716 for(int mu=0;mu<Nd;mu++) {
717 LatticeCoordinate(kmu,mu);
718 RealD TwoPiL = M_PI * 2.0/ latt_size[mu];
719 kmu = TwoPiL * kmu + TwoPiL * one * twist[mu];//twisted boundary
720 buf2_4d = buf2_4d + sin(kmu)*ci*(Gamma(Gmu[mu])*buf1_4d);
721 }
722 bufR_4d = buf2_4d - W * buf1_4d;
723
724 //(delta(s-1,u) - m*delta(s,1)*delta(u,Ls))*GL
725 if(ss==1){
726 ExtractSlice(buf1_4d, GL, (Ls-1), 0);
727 bufL_4d = bufL_4d - mass*buf1_4d;
728 }
729 else {
730 ExtractSlice(buf1_4d, GL, (ss-2), 0);
731 bufL_4d = bufL_4d + buf1_4d;
732 }
733
734 //(delta(s+1,u) - m*delta(s,Ls)*delta(u,1))*GR
735 if(ss==Ls){
736 ExtractSlice(buf1_4d, GR, 0, 0);
737 bufR_4d = bufR_4d - mass*buf1_4d;
738 }
739 else {
740 ExtractSlice(buf1_4d, GR, ss, 0);
741 bufR_4d = bufR_4d + buf1_4d;
742 }
743 buf1_4d = bufL_4d + bufR_4d;
744 InsertSlice(buf1_4d, out, (ss-1), 0);
745 }
746
747
748 out = out * (-1.0);
749}
750
751template<class Impl>
752void WilsonFermion5D<Impl>::MomentumSpacePropagatorHt(FermionField &out,const FermionField &in, RealD mass,std::vector<double> twist)
753{
754 // what type LatticeComplex
755 GridBase *_grid = _FourDimGrid;
756 conformable(_grid,out.Grid());
757
758 typedef typename FermionField::vector_type vector_type;
759 typedef typename FermionField::scalar_type ScalComplex;
760 typedef iSinglet<ScalComplex> Tcomplex;
761 typedef Lattice<iSinglet<vector_type> > LatComplex;
762
763 Gamma::Algebra Gmu [] = {
764 Gamma::Algebra::GammaX,
765 Gamma::Algebra::GammaY,
766 Gamma::Algebra::GammaZ,
767 Gamma::Algebra::GammaT
768 };
769
770 Coordinate latt_size = _grid->_fdimensions;
771
772
773 FermionField num (_grid); num = Zero();
774
775 LatComplex sk(_grid); sk = Zero();
776 LatComplex sk2(_grid); sk2= Zero();
777 LatComplex W(_grid); W= Zero();
778 LatComplex a(_grid); a= Zero();
779 LatComplex one (_grid); one = ScalComplex(1.0,0.0);
780 LatComplex denom(_grid); denom= Zero();
781 LatComplex cosha(_grid);
782 LatComplex kmu(_grid);
783 LatComplex Wea(_grid);
784 LatComplex Wema(_grid);
785
786 ScalComplex ci(0.0,1.0);
787
788 for(int mu=0;mu<Nd;mu++) {
789
790 LatticeCoordinate(kmu,mu);
791
792 RealD TwoPiL = M_PI * 2.0/ latt_size[mu];
793
794 kmu = TwoPiL * kmu;
795 kmu = kmu + TwoPiL * one * twist[mu];//momentum for twisted boundary conditions
796
797 sk2 = sk2 + 2.0*sin(kmu*0.5)*sin(kmu*0.5);
798 sk = sk + sin(kmu) *sin(kmu);
799
800 num = num - sin(kmu)*ci*(Gamma(Gmu[mu])*in);
801
802 }
803
804 W = one - M5 + sk2;
805
807 // Cosh alpha -> exp(+/- alpha)
809 cosha = (one + W*W + sk) / (abs(W)*2.0);
810
811 Wea = abs(W)*(cosha + sqrt(cosha*cosha-one));
812 Wema= abs(W)*(cosha - sqrt(cosha*cosha-one));
813
814 num = num + ( one - Wema ) * mass * in;
815 denom= ( Wea - one ) + mass*mass * (one - Wema);
816 out = num/denom;
817}
818
819template<class Impl>
820void WilsonFermion5D<Impl>::MomentumSpacePropagatorHw(FermionField &out,const FermionField &in,RealD mass,std::vector<double> twist)
821{
822 std::vector<double> empty_q(Nd,0.0);
823 MomentumSpacePropagatorHwQ(out,in,mass,twist,empty_q);
824}
825template<class Impl>
826void WilsonFermion5D<Impl>::MomentumSpacePropagatorHwQ(FermionField &out,const FermionField &in,
827 RealD mass,
828 std::vector<double> twist,
829 std::vector<double> qmu)
830{
831 Gamma::Algebra Gmu [] = {
832 Gamma::Algebra::GammaX,
833 Gamma::Algebra::GammaY,
834 Gamma::Algebra::GammaZ,
835 Gamma::Algebra::GammaT
836 };
837
838 GridBase *_grid = _FourDimGrid;
839 conformable(_grid,out.Grid());
840
841 typedef typename FermionField::vector_type vector_type;
842 typedef typename FermionField::scalar_type ScalComplex;
843
844 typedef Lattice<iSinglet<vector_type> > LatComplex;
845 typedef iSpinMatrix<ScalComplex> SpinMat;
846
847
848 Coordinate latt_size = _grid->_fdimensions;
849
850 LatComplex sk(_grid); sk = Zero();
851 LatComplex sk2(_grid); sk2= Zero();
852
853 LatComplex w_k(_grid); w_k= Zero();
854 LatComplex b_k(_grid); b_k= Zero();
855
856 LatComplex one (_grid); one = ScalComplex(1.0,0.0);
857
858 FermionField num (_grid); num = Zero();
859 LatComplex denom(_grid); denom= Zero();
860 LatComplex kmu(_grid);
861 ScalComplex ci(0.0,1.0);
862
863 std::cout<< "Feynman Rule" << "qmu ("<<qmu[0]<<","<<qmu[1]<<","<<qmu[2]<<","<<qmu[3]<<")"<<std::endl;
864
865 for(int mu=0;mu<Nd;mu++) {
866
867 LatticeCoordinate(kmu,mu);
868
869 RealD TwoPiL = M_PI * 2.0/ latt_size[mu];
870
871 kmu = TwoPiL * kmu;
872 kmu = kmu + TwoPiL * one * twist[mu];//momentum for twisted boundary conditions
873
874 sk2 = sk2 + 2.0*sin(kmu*0.5)*sin(kmu*0.5);
875
876 sk = sk + (sin(kmu)+qmu[mu])*(sin(kmu)+qmu[mu]);
877
878 // Terms for boosted Fermion
879 // 1/2 [ -i gamma.(sin p + q ) ]
880 // [ --------------------- + 1 ]
881 // [ wq + b ]
882 //
883 // wq = sqrt( (sinp+q)^2 + b^2 )
884 //
885
886 num = num - (sin(kmu)+qmu[mu])*ci*(Gamma(Gmu[mu])*in);
887
888 }
889 num = num + mass * in ;
890
891 b_k = sk2 - M5;
892
893 w_k = sqrt(sk + b_k*b_k);
894
895 denom= ( w_k + b_k + mass*mass) ;
896
897 denom= one/denom;
898 out = num*denom;
899
900}
901
902/*******************************************************************************
903 * Conserved current utilities for Wilson fermions, for contracting propagators
904 * to make a conserved current sink or inserting the conserved current
905 * sequentially.
906
907// Helper macro to reverse Simd vector. Fixme: slow, generic implementation.
908#define REVERSE_LS(qSite, qSiteRev, Nsimd) \
909{ \
910 ExtractBuffer<typename SitePropagator::scalar_object> qSiteVec(Nsimd); \
911 extract(qSite, qSiteVec); \
912 for (int i = 0; i < Nsimd / 2; ++i) \
913 { \
914 typename SitePropagator::scalar_object tmp = qSiteVec[i]; \
915 qSiteVec[i] = qSiteVec[Nsimd - i - 1]; \
916 qSiteVec[Nsimd - i - 1] = tmp; \
917 } \
918 merge(qSiteRev, qSiteVec); \
919}
920
921 ******************************************************************************/
922
923
924
925
927
928
929
930
#define one
Definition BGQQPX.h:108
static const int Even
static const int Odd
AcceleratorVector< int, MaxDims > Coordinate
Definition Coordinate.h:95
accelerator_inline Grid_simd< S, V > abs(const Grid_simd< S, V > &r)
accelerator_inline Grid_simd< S, V > sin(const Grid_simd< S, V > &r)
accelerator_inline Grid_simd< S, V > sqrt(const Grid_simd< S, V > &r)
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 LatticeCoordinate(Lattice< iobj > &l, int mu)
void InsertSlice(const Lattice< vobj > &lowDim, Lattice< vobj > &higherDim, int slice, int orthog)
void ExtractSlice(Lattice< vobj > &lowDim, const Lattice< vobj > &higherDim, int slice, int orthog)
void pickCheckerboard(int cb, Lattice< vobj > &half, const Lattice< vobj > &full)
Lattice< obj > pow(const Lattice< obj > &rhs_i, RealD y)
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
#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
iScalar< iScalar< iScalar< vtype > > > iSinglet
Definition QCD.h:102
static constexpr int DaggerNo
Definition QCD.h:69
iScalar< iMatrix< iScalar< vtype >, Ns > > iSpinMatrix
Definition QCD.h:103
double RealD
Definition Simd.h:61
#define GRID_TRACE(name)
Definition Tracing.h:68
static INTERNAL_PRECISION U
Definition Zolotarev.cc:230
static INTERNAL_PRECISION F
Definition Zolotarev.cc:230
#define M_PI
Definition Zolotarev.cc:41
Definition Gamma.h:10
Coordinate _fdimensions
int oSites(void) const
Coordinate _rdimensions
Coordinate _simd_layout
static const std::vector< int > displacements
static constexpr int npoint
static const std::vector< int > directions
void ImportGauge(const GaugeField &_Umu)
StencilImpl StencilOdd
void DhopInternalOverlappedComms(StencilImpl &st, DoubledGaugeField &U, const FermionField &in, FermionField &out, int dag)
DoubledGaugeField UmuOdd
virtual void MooeeInvDag(const FermionField &in, FermionField &out)
GridBase * _FiveDimGrid
virtual void MooeeDag(const FermionField &in, FermionField &out)
void DhopComms(const FermionField &in, FermionField &out)
DoubledGaugeField UmuEven
GridBase * _FiveDimRedBlackGrid
void MomentumSpacePropagatorHwQ(FermionField &out, const FermionField &in, RealD mass, std::vector< double > twist, std::vector< double > qmu)
WilsonKernels< Impl > Kernels
void DhopCalc(const FermionField &in, FermionField &out, uint64_t *ids)
virtual void MooeeInv(const FermionField &in, FermionField &out)
FermionField _tmp
void DhopInternal(StencilImpl &st, DoubledGaugeField &U, const FermionField &in, FermionField &out, int dag)
virtual void Meooe(const FermionField &in, FermionField &out)
void DhopInternalSerialComms(StencilImpl &st, DoubledGaugeField &U, const FermionField &in, FermionField &out, int dag)
void MomentumSpacePropagatorHt(FermionField &out, const FermionField &in, RealD mass, std::vector< double > twist)
GridBase * _FourDimGrid
GridBase * FermionGrid(void)
virtual void DhopDerivEO(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
void DW(const FermionField &in, FermionField &out, int dag)
void DhopDir(const FermionField &in, FermionField &out, int dir, int disp)
void DhopDirAll(const FermionField &in, std::vector< FermionField > &out)
void MomentumSpacePropagatorHw(FermionField &out, const FermionField &in, RealD mass, std::vector< double > twist)
virtual void MeooeDag(const FermionField &in, FermionField &out)
WilsonFermion5D(GaugeField &_Umu, GridCartesian &FiveDimGrid, GridRedBlackCartesian &FiveDimRedBlackGrid, GridCartesian &FourDimGrid, GridRedBlackCartesian &FourDimRedBlackGrid, double _M5, const ImplParams &p=ImplParams())
virtual void DhopDeriv(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
void DhopEO(const FermionField &in, FermionField &out, int dag)
GridBase * _FourDimRedBlackGrid
StencilImpl Stencil
StencilImpl StencilEven
GridBase * FermionRedBlackGrid(void)
virtual void DhopDerivOE(GaugeField &mat, const FermionField &U, const FermionField &V, int dag)
virtual void Mooee(const FermionField &in, FermionField &out)
void Dhop(const FermionField &in, FermionField &out, int dag)
DoubledGaugeField Umu
void DerivInternal(StencilImpl &st, DoubledGaugeField &U, GaugeField &mat, const FermionField &A, const FermionField &B, int dag)
void DhopOE(const FermionField &in, FermionField &out, int dag)
void MomentumSpacePropagatorHt_5d(FermionField &out, const FermionField &in, RealD mass, std::vector< double > twist)
static void DhopDagKernel(int Opt, StencilImpl &st, DoubledGaugeField &U, SiteHalfSpinor *buf, int Ls, int Nsite, const FermionField &in, FermionField &out, int interior=1, int exterior=1)
static void DhopDirKernel(StencilImpl &st, DoubledGaugeField &U, SiteHalfSpinor *buf, int Ls, int Nsite, const FermionField &in, FermionField &out, int dirdisp, int gamma)
static void DhopDirAll(StencilImpl &st, DoubledGaugeField &U, SiteHalfSpinor *buf, int Ls, int Nsite, const FermionField &in, std::vector< FermionField > &out)
static void DhopKernel(int Opt, StencilImpl &st, DoubledGaugeField &U, SiteHalfSpinor *buf, int Ls, int Nsite, const FermionField &in, FermionField &out, int interior=1, int exterior=1)
Definition Simd.h:194
void applyFilter(MomentaField &P) const override