Grid 0.7.0
GaugeConfigurationMasked.h
Go to the documentation of this file.
1
6#pragma once
7
9
10
11template<class T> void Dump(const Lattice<T> & lat,
12 std::string s,
13 Coordinate site = Coordinate({0,0,0,0}))
14{
15 typename T::scalar_object tmp;
16 peekSite(tmp,lat,site);
17 std::cout << " Dump "<<s<<" "<<tmp<<std::endl;
18}
19
23template <class Gimpl>
25{
26public:
28
29private:
30 // These live in base class
31 // const unsigned int smearingLevels;
32 // Smear_Stout<Gimpl> *StoutSmearing;
33 // std::vector<GaugeField> SmearedSet;
34
35 std::vector<LatticeLorentzComplex> masks;
36
40
41 void BaseSmearDerivative(GaugeField& SigmaTerm,
42 const GaugeField& iLambda,
43 const GaugeField& U,
44 int mmu, RealD rho)
45 {
46 // Reference
47 // Morningstar, Peardon, Phys.Rev.D69,054501(2004)
48 // Equation 75
49 // Computing Sigma_mu, derivative of S[fat links] with respect to the thin links
50 // Output SigmaTerm
51
52 GridBase *grid = U.Grid();
53
55 GaugeLinkField staple(grid), u_tmp(grid);
56 GaugeLinkField iLambda_mu(grid), iLambda_nu(grid);
57 GaugeLinkField U_mu(grid), U_nu(grid);
58 GaugeLinkField sh_field(grid), temp_Sigma(grid);
59 Real rho_munu, rho_numu;
60
61 rho_munu = rho;
62 rho_numu = rho;
63 for(int mu = 0; mu < Nd; ++mu){
64 U_mu = peekLorentz( U, mu);
65 iLambda_mu = peekLorentz(iLambda, mu);
66
67 for(int nu = 0; nu < Nd; ++nu){
68 if(nu==mu) continue;
69
70 U_nu = peekLorentz( U, nu);
71
72 // Nd(nd-1) = 12 staples normally.
73 // We must compute 6 of these
74 // in FTHMC case
75 if ( (mu==mmu)||(nu==mmu) )
76 WL.StapleUpper(staple, U, mu, nu);
77
78 if(nu==mmu) {
79 iLambda_nu = peekLorentz(iLambda, nu);
80
81 temp_Sigma = -rho_numu*staple*iLambda_nu; //ok
82 //-r_numu*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)*Lambda_nu(x)
83 Gimpl::AddLink(SigmaTerm, temp_Sigma, mu);
84
85 sh_field = Cshift(iLambda_nu, mu, 1);// general also for Gparity?
86
87 temp_Sigma = rho_numu*sh_field*staple; //ok
88 //r_numu*Lambda_nu(mu)*U_nu(x+mu)*Udag_mu(x+nu)*Udag_nu(x)
89 Gimpl::AddLink(SigmaTerm, temp_Sigma, mu);
90 }
91
92 if ( mu == mmu ) {
93 sh_field = Cshift(iLambda_mu, nu, 1);
94
95 temp_Sigma = -rho_munu*staple*U_nu*sh_field*adj(U_nu); //ok
96 //-r_munu*U_nu(x+mu)*Udag_mu(x+nu)*Lambda_mu(x+nu)*Udag_nu(x)
97 Gimpl::AddLink(SigmaTerm, temp_Sigma, mu);
98 }
99
100 // staple = Zero();
101 sh_field = Cshift(U_nu, mu, 1);
102
103 temp_Sigma = Zero();
104
105 if ( mu == mmu )
106 temp_Sigma = -rho_munu*adj(sh_field)*adj(U_mu)*iLambda_mu*U_nu;
107
108 if ( nu == mmu ) {
109 temp_Sigma += rho_numu*adj(sh_field)*adj(U_mu)*iLambda_nu*U_nu;
110
111 u_tmp = adj(U_nu)*iLambda_nu;
112 sh_field = Cshift(u_tmp, mu, 1);
113 temp_Sigma += -rho_numu*sh_field*adj(U_mu)*U_nu;
114 }
115
116 sh_field = Cshift(temp_Sigma, nu, -1);
117 Gimpl::AddLink(SigmaTerm, sh_field, mu);
118
119 }
120 }
121 }
122
123 void BaseSmear(GaugeLinkField& Cup, const GaugeField& U,int mu,RealD rho) {
124 GridBase *grid = U.Grid();
125 GaugeLinkField tmp_stpl(grid);
127 Cup = Zero();
128 for(int nu=0; nu<Nd; ++nu){
129 if (nu != mu) {
130 // get the staple in direction mu, nu
131 WL.Staple(tmp_stpl, U, mu, nu); //nb staple conventions of IroIro and Grid differ by a dagger
132 Cup += adj(tmp_stpl*rho);
133 }
134 }
135 }
136 // Adjoint vector to GaugeField force
137 void InsertForce(GaugeField &Fdet,AdjVectorField &Fdet_nu,int nu)
138 {
139 Complex ci(0,1);
140 GaugeLinkField Fdet_pol(Fdet.Grid());
141 Fdet_pol=Zero();
142 for(int e=0;e<8;e++){
143 ColourMatrix te;
144 SU3::generator(e, te);
145 auto tmp=peekColour(Fdet_nu,e);
146 Fdet_pol=Fdet_pol + ci*tmp*te; // but norm of te is different.. why?
147 }
148 pokeLorentz(Fdet, Fdet_pol, nu);
149 }
150 void Compute_MpInvJx_dNxxdSy(const GaugeLinkField &PlaqL,const GaugeLinkField &PlaqR, AdjMatrixField MpInvJx,AdjVectorField &Fdet2 )
151 {
152 GaugeLinkField UtaU(PlaqL.Grid());
153 GaugeLinkField D(PlaqL.Grid());
154 AdjMatrixField Dbc(PlaqL.Grid());
155 AdjMatrixField Dbc_opt(PlaqL.Grid());
156 LatticeComplex tmp(PlaqL.Grid());
157 const int Ngen = SU3Adjoint::Dimension;
158 Complex ci(0,1);
159 ColourMatrix ta,tb,tc;
160 RealD t=0;
161 RealD tp=0;
162 RealD tta=0;
163 RealD tpk=0;
164 t-=usecond();
165 for(int a=0;a<Ngen;a++) {
166 tta-=usecond();
167 SU3::generator(a, ta);
168 ta = 2.0 * ci * ta;
169 // Qlat Tb = 2i Tb^Grid
170 UtaU= adj(PlaqL)*ta*PlaqR; // 6ms
171 tta+=usecond();
173 // Could add this entire C-loop to a projection routine
174 // for performance. Could also pick checkerboard on UtaU
175 // and set checkerboard on result for 2x perf
177 for(int c=0;c<Ngen;c++) {
178 SU3::generator(c, tc);
179 tc = 2.0*ci*tc;
180 tp-=usecond();
181 D = Ta( tc *UtaU); // 2ms
182#if 1
183 SU3::LieAlgebraProject(Dbc_opt,D,c); // 5.5ms
184#else
185 for(int b=0;b<Ngen;b++){
186 SU3::generator(b, tb);
187 tmp =-trace(ci*tb*D);
188 PokeIndex<ColourIndex>(Dbc,tmp,b,c); // Adjoint rep
189 }
190#endif
191 tp+=usecond();
192 }
193 // Dump(Dbc_opt,"Dbc_opt");
194 // Dump(Dbc,"Dbc");
195 tpk-=usecond();
196 tmp = trace(MpInvJx * Dbc_opt);
197 PokeIndex<ColourIndex>(Fdet2,tmp,a);
198 tpk+=usecond();
199 }
200 t+=usecond();
201 std::cout << GridLogPerformance << " Compute_MpInvJx_dNxxdSy " << t/1e3 << " ms proj "<<tp/1e3<< " ms"
202 << " ta "<<tta/1e3<<" ms" << " poke "<<tpk/1e3<< " ms"<<std::endl;
203 }
204
205 void ComputeNxy(const GaugeLinkField &PlaqL,const GaugeLinkField &PlaqR,AdjMatrixField &NxAd)
206 {
207 GaugeLinkField Nx(PlaqL.Grid());
208 const int Ngen = SU3Adjoint::Dimension;
209 Complex ci(0,1);
210 ColourMatrix tb;
211 ColourMatrix tc;
212 for(int b=0;b<Ngen;b++) {
213 SU3::generator(b, tb);
214 tb = 2.0 * ci * tb;
215 Nx = Ta( adj(PlaqL)*tb * PlaqR );
216#if 1
217 SU3::LieAlgebraProject(NxAd,Nx,b);
218#else
219 for(int c=0;c<Ngen;c++) {
220 SU3::generator(c, tc);
221 auto tmp =closure( -trace(ci*tc*Nx));
222 PokeIndex<ColourIndex>(NxAd,tmp,c,b);
223 }
224#endif
225 }
226 }
227 void ApplyMask(GaugeField &U,int smr)
228 {
229 LatticeComplex tmp(U.Grid());
230 GaugeLinkField Umu(U.Grid());
231 for(int mu=0;mu<Nd;mu++){
233 tmp=PeekIndex<LorentzIndex>(masks[smr],mu);
234 Umu=Umu*tmp;
235 PokeIndex<LorentzIndex>(U, Umu, mu);
236 }
237 }
238public:
239
240 void logDetJacobianForceLevel(const GaugeField &U, GaugeField &force ,int smr)
241 {
242 GridBase* grid = U.Grid();
243 ColourMatrix tb;
244 ColourMatrix tc;
245 ColourMatrix ta;
246 GaugeField C(grid);
247 GaugeField Umsk(grid);
248 std::vector<GaugeLinkField> Umu(Nd,grid);
249 GaugeLinkField Cmu(grid); // U and staple; C contains factor of epsilon
250 GaugeLinkField Zx(grid); // U times Staple, contains factor of epsilon
251 GaugeLinkField Nxx(grid); // Nxx fundamental space
252 GaugeLinkField Utmp(grid);
253 GaugeLinkField PlaqL(grid);
254 GaugeLinkField PlaqR(grid);
255 const int Ngen = SU3Adjoint::Dimension;
256 AdjMatrix TRb;
257 ColourMatrix Ident;
258 LatticeComplex cplx(grid);
259
260 AdjVectorField dJdXe_nMpInv(grid);
261 AdjVectorField dJdXe_nMpInv_y(grid);
262 AdjMatrixField MpAd(grid); // Mprime luchang's notes
263 AdjMatrixField MpAdInv(grid); // Mprime inverse
264 AdjMatrixField NxxAd(grid); // Nxx in adjoint space
265 AdjMatrixField JxAd(grid);
266 AdjMatrixField ZxAd(grid);
267 AdjMatrixField mZxAd(grid);
268 AdjMatrixField X(grid);
269 Complex ci(0,1);
270
271 RealD t0 = usecond();
272 Ident = ComplexD(1.0);
273 for(int d=0;d<Nd;d++){
274 Umu[d] = peekLorentz(U, d);
275 }
276 int mu= (smr/2) %Nd;
277
279 // Mask the gauge field
281 auto mask=PeekIndex<LorentzIndex>(masks[smr],mu); // the cb mask
282
283 Umsk = U;
284 ApplyMask(Umsk,smr);
285 Utmp = peekLorentz(Umsk,mu);
286
288 // Retrieve the eps/rho parameter(s) -- could allow all different but not so far
290 double rho=this->StoutSmearing->SmearRho[1];
291 int idx=0;
292 for(int mu=0;mu<4;mu++){
293 for(int nu=0;nu<4;nu++){
294 if ( mu!=nu) assert(this->StoutSmearing->SmearRho[idx]==rho);
295 else assert(this->StoutSmearing->SmearRho[idx]==0.0);
296 idx++;
297 }}
299 // Assemble the N matrix
301 // Computes ALL the staples -- could compute one only and do it here
302 RealD time;
303 time=-usecond();
304 BaseSmear(Cmu, U,mu,rho);
305
307 // Assemble Luscher exp diff map J matrix
309 // Ta so Z lives in Lie algabra
310 Zx = Ta(Cmu * adj(Umu[mu]));
311 time+=usecond();
312 std::cout << GridLogMessage << "Z took "<<time<< " us"<<std::endl;
313
314 time=-usecond();
315 // Move Z to the Adjoint Rep == make_adjoint_representation
316 ZxAd = Zero();
317 for(int b=0;b<8;b++) {
318 // Adj group sets traceless antihermitian T's -- Guido, really????
319 SU3::generator(b, tb); // Fund group sets traceless hermitian T's
321 TRb=-TRb;
322 cplx = 2.0*trace(ci*tb*Zx); // my convention 1/2 delta ba
323 ZxAd = ZxAd + cplx * TRb; // is this right? YES - Guido used Anti herm Ta's and with bloody wrong sign.
324 }
325 time+=usecond();
326 std::cout << GridLogMessage << "ZxAd took "<<time<< " us"<<std::endl;
327
329 // J(x) = 1 + Sum_k=1..N (-Zac)^k/(k+1)!
331 time=-usecond();
332 X=1.0;
333 JxAd = X;
334 mZxAd = (-1.0)*ZxAd;
335 RealD kpfac = 1;
336 for(int k=1;k<12;k++){
337 X=X*mZxAd;
338 kpfac = kpfac /(k+1);
339 JxAd = JxAd + X * kpfac;
340 }
341 time+=usecond();
342 std::cout << GridLogMessage << "Jx took "<<time<< " us"<<std::endl;
343
345 // dJ(x)/dxe
347 time=-usecond();
348#if 1
349 std::vector<AdjMatrixField> dJdX; dJdX.resize(8,grid);
350 std::vector<AdjMatrix> TRb_s; TRb_s.resize(8);
351 AdjMatrixField tbXn(grid);
352 AdjMatrixField sumXtbX(grid);
353 AdjMatrixField t2(grid);
354 AdjMatrixField dt2(grid);
355 AdjMatrixField t3(grid);
356 AdjMatrixField dt3(grid);
357 AdjMatrixField aunit(grid);
358
359 for(int b=0;b<8;b++){
360 SU3Adjoint::generator(b, TRb_s[b]);
361 dJdX[b] = TRb_s[b];
362 }
363 aunit = ComplexD(1.0);
364 // Could put into an accelerator_for
365 X = (-1.0)*ZxAd;
366 t2 = X;
367 for (int j = 12; j > 1; --j) {
368 t3 = t2*(1.0 / (j + 1)) + aunit;
369 t2 = X * t3;
370 for(int b=0;b<8;b++){
371 dJdX[b]= TRb_s[b] * t3 + X * dJdX[b]*(1.0 / (j + 1));
372 }
373 }
374 for(int b=0;b<8;b++){
375 dJdX[b] = -dJdX[b];
376 }
377#else
378 std::vector<AdjMatrixField> dJdX; dJdX.resize(8,grid);
379 AdjMatrixField tbXn(grid);
380 AdjMatrixField sumXtbX(grid);
381 AdjMatrixField t2(grid);
382 AdjMatrixField dt2(grid);
383 AdjMatrixField t3(grid);
384 AdjMatrixField dt3(grid);
385 AdjMatrixField aunit(grid);
386 for(int b=0;b<8;b++){
387 aunit = ComplexD(1.0);
388 SU3Adjoint::generator(b, TRb); //dt2
389
390 X = (-1.0)*ZxAd;
391 t2 = X;
392 dt2 = TRb;
393 for (int j = 12; j > 1; --j) {
394 t3 = t2*(1.0 / (j + 1)) + aunit;
395 dt3 = dt2*(1.0 / (j + 1));
396 t2 = X * t3;
397 dt2 = TRb * t3 + X * dt3;
398 }
399 dJdX[b] = -dt2;
400 }
401#endif
402 time+=usecond();
403 std::cout << GridLogMessage << "dJx took "<<time<< " us"<<std::endl;
405 // Mask Umu for this link
407 time=-usecond();
408 PlaqL = Ident;
409 PlaqR = Utmp*adj(Cmu);
410 ComputeNxy(PlaqL,PlaqR,NxxAd);
411 time+=usecond();
412 std::cout << GridLogMessage << "ComputeNxy took "<<time<< " us"<<std::endl;
413
415 // Mab
417 MpAd = Complex(1.0,0.0);
418 MpAd = MpAd - JxAd * NxxAd;
419
421 // invert the 8x8
423 time=-usecond();
424 MpAdInv = Inverse(MpAd);
425 time+=usecond();
426 std::cout << GridLogMessage << "MpAdInv took "<<time<< " us"<<std::endl;
427
428 RealD t3a = usecond();
430 // Nxx Mp^-1
432 AdjVectorField FdetV(grid);
433 AdjVectorField Fdet1_nu(grid);
434 AdjVectorField Fdet2_nu(grid);
435 AdjVectorField Fdet2_mu(grid);
436 AdjVectorField Fdet1_mu(grid);
437
438 AdjMatrixField nMpInv(grid);
439 nMpInv= NxxAd *MpAdInv;
440
441 AdjMatrixField MpInvJx(grid);
442 AdjMatrixField MpInvJx_nu(grid);
443 MpInvJx = (-1.0)*MpAdInv * JxAd;// rho is on the plaq factor
444
445 Compute_MpInvJx_dNxxdSy(PlaqL,PlaqR,MpInvJx,FdetV);
446 Fdet2_mu=FdetV;
447 Fdet1_mu=Zero();
448
449 for(int e =0 ; e<8 ; e++){
450 LatticeComplexD tr(grid);
451 // ColourMatrix te;
452 // SU3::generator(e, te);
453 tr = trace(dJdX[e] * nMpInv);
454 pokeColour(dJdXe_nMpInv,tr,e);
455 }
457 // Mask it off
459 auto tmp=PeekIndex<LorentzIndex>(masks[smr],mu);
460 dJdXe_nMpInv = dJdXe_nMpInv*tmp;
461
462 // dJdXe_nMpInv needs to multiply:
463 // Nxx_mu (site local) (1)
464 // Nxy_mu one site forward in each nu direction (3)
465 // Nxy_mu one site backward in each nu direction (3)
466 // Nxy_nu 0,0 ; +mu,0; 0,-nu; +mu-nu [ 3x4 = 12]
467 // 19 terms.
468 AdjMatrixField Nxy(grid);
469
470 GaugeField Fdet1(grid);
471 GaugeField Fdet2(grid);
472 GaugeLinkField Fdet_pol(grid); // one polarisation
473
474 RealD t4 = usecond();
475 for(int nu=0;nu<Nd;nu++){
476
477 if (nu!=mu) {
479 // __
480 // | |
481 // x== // nu polarisation -- clockwise
482
483 time=-usecond();
484 PlaqL=Ident;
485
486 PlaqR=(-rho)*Gimpl::CovShiftForward(Umu[nu], nu,
487 Gimpl::CovShiftForward(Umu[mu], mu,
488 Gimpl::CovShiftBackward(Umu[nu], nu,
489 Gimpl::CovShiftIdentityBackward(Utmp, mu))));
490 time+=usecond();
491 std::cout << GridLogMessage << "PlaqLR took "<<time<< " us"<<std::endl;
492
493 time=-usecond();
494 dJdXe_nMpInv_y = dJdXe_nMpInv;
495 ComputeNxy(PlaqL,PlaqR,Nxy);
496 Fdet1_nu = transpose(Nxy)*dJdXe_nMpInv_y;
497 time+=usecond();
498 std::cout << GridLogMessage << "ComputeNxy (occurs 6x) took "<<time<< " us"<<std::endl;
499
500 time=-usecond();
501 PlaqR=(-1.0)*PlaqR;
502 Compute_MpInvJx_dNxxdSy(PlaqL,PlaqR,MpInvJx,FdetV);
503 Fdet2_nu = FdetV;
504 time+=usecond();
505 std::cout << GridLogMessage << "Compute_MpInvJx_dNxxSy (occurs 6x) took "<<time<< " us"<<std::endl;
506
507 // x==
508 // | |
509 // .__| // nu polarisation -- anticlockwise
510
511 PlaqR=(rho)*Gimpl::CovShiftForward(Umu[nu], nu,
512 Gimpl::CovShiftBackward(Umu[mu], mu,
513 Gimpl::CovShiftIdentityBackward(Umu[nu], nu)));
514
515 PlaqL=Gimpl::CovShiftIdentityBackward(Utmp, mu);
516
517 dJdXe_nMpInv_y = Cshift(dJdXe_nMpInv,mu,-1);
518 ComputeNxy(PlaqL, PlaqR,Nxy);
519 Fdet1_nu = Fdet1_nu+transpose(Nxy)*dJdXe_nMpInv_y;
520
521
522 MpInvJx_nu = Cshift(MpInvJx,mu,-1);
523 Compute_MpInvJx_dNxxdSy(PlaqL,PlaqR,MpInvJx_nu,FdetV);
524 Fdet2_nu = Fdet2_nu+FdetV;
525
527 // __
528 // | |
529 // x== // nu polarisation -- clockwise
530
531 PlaqL=(rho)* Gimpl::CovShiftForward(Umu[mu], mu,
532 Gimpl::CovShiftForward(Umu[nu], nu,
533 Gimpl::CovShiftIdentityBackward(Utmp, mu)));
534
535 PlaqR = Gimpl::CovShiftIdentityForward(Umu[nu], nu);
536
537 dJdXe_nMpInv_y = Cshift(dJdXe_nMpInv,nu,1);
538 ComputeNxy(PlaqL,PlaqR,Nxy);
539 Fdet1_nu = Fdet1_nu + transpose(Nxy)*dJdXe_nMpInv_y;
540
541 MpInvJx_nu = Cshift(MpInvJx,nu,1);
542 Compute_MpInvJx_dNxxdSy(PlaqL,PlaqR,MpInvJx_nu,FdetV);
543 Fdet2_nu = Fdet2_nu+FdetV;
544
545 // x==
546 // | |
547 // |__| // nu polarisation
548
549 PlaqL=(-rho)*Gimpl::CovShiftForward(Umu[nu], nu,
550 Gimpl::CovShiftIdentityBackward(Utmp, mu));
551
552 PlaqR=Gimpl::CovShiftBackward(Umu[mu], mu,
553 Gimpl::CovShiftIdentityForward(Umu[nu], nu));
554
555 dJdXe_nMpInv_y = Cshift(dJdXe_nMpInv,mu,-1);
556 dJdXe_nMpInv_y = Cshift(dJdXe_nMpInv_y,nu,1);
557
558 ComputeNxy(PlaqL,PlaqR,Nxy);
559 Fdet1_nu = Fdet1_nu + transpose(Nxy)*dJdXe_nMpInv_y;
560
561 MpInvJx_nu = Cshift(MpInvJx,mu,-1);
562 MpInvJx_nu = Cshift(MpInvJx_nu,nu,1);
563 Compute_MpInvJx_dNxxdSy(PlaqL,PlaqR,MpInvJx_nu,FdetV);
564 Fdet2_nu = Fdet2_nu+FdetV;
565
567 // Set up the determinant force contribution in 3x3 algebra basis
569 InsertForce(Fdet1,Fdet1_nu,nu);
570 InsertForce(Fdet2,Fdet2_nu,nu);
571
573 // Parallel direction terms
575
576 // __
577 // | "
578 // |__"x // mu polarisation
579 PlaqL=(-rho)*Gimpl::CovShiftForward(Umu[mu], mu,
580 Gimpl::CovShiftBackward(Umu[nu], nu,
581 Gimpl::CovShiftIdentityBackward(Utmp, mu)));
582
583 PlaqR=Gimpl::CovShiftIdentityBackward(Umu[nu], nu);
584
585 dJdXe_nMpInv_y = Cshift(dJdXe_nMpInv,nu,-1);
586
587 ComputeNxy(PlaqL,PlaqR,Nxy);
588 Fdet1_mu = Fdet1_mu + transpose(Nxy)*dJdXe_nMpInv_y;
589
590 MpInvJx_nu = Cshift(MpInvJx,nu,-1);
591
592 Compute_MpInvJx_dNxxdSy(PlaqL,PlaqR,MpInvJx_nu,FdetV);
593 Fdet2_mu = Fdet2_mu+FdetV;
594
595 // __
596 // " |
597 // x__| // mu polarisation
598
599 PlaqL=(-rho)*Gimpl::CovShiftForward(Umu[mu], mu,
600 Gimpl::CovShiftForward(Umu[nu], nu,
601 Gimpl::CovShiftIdentityBackward(Utmp, mu)));
602
603 PlaqR=Gimpl::CovShiftIdentityForward(Umu[nu], nu);
604
605 dJdXe_nMpInv_y = Cshift(dJdXe_nMpInv,nu,1);
606
607 ComputeNxy(PlaqL,PlaqR,Nxy);
608 Fdet1_mu = Fdet1_mu + transpose(Nxy)*dJdXe_nMpInv_y;
609
610 MpInvJx_nu = Cshift(MpInvJx,nu,1);
611
612 Compute_MpInvJx_dNxxdSy(PlaqL,PlaqR,MpInvJx_nu,FdetV);
613 Fdet2_mu = Fdet2_mu+FdetV;
614
615 }
616 }
617 RealD t5 = usecond();
618
619 Fdet1_mu = Fdet1_mu + transpose(NxxAd)*dJdXe_nMpInv;
620
621 InsertForce(Fdet1,Fdet1_mu,mu);
622 InsertForce(Fdet2,Fdet2_mu,mu);
623
624 force= (-0.5)*( Fdet1 + Fdet2);
625 RealD t1 = usecond();
626 std::cout << GridLogMessage << " logDetJacobianForce level took "<<t1-t0<<" us "<<std::endl;
627 std::cout << GridLogMessage << " logDetJacobianForce t3-t0 "<<t3a-t0<<" us "<<std::endl;
628 std::cout << GridLogMessage << " logDetJacobianForce t4-t3 dJdXe_nMpInv "<<t4-t3a<<" us "<<std::endl;
629 std::cout << GridLogMessage << " logDetJacobianForce t5-t4 mu nu loop "<<t5-t4<<" us "<<std::endl;
630 std::cout << GridLogMessage << " logDetJacobianForce t1-t5 "<<t1-t5<<" us "<<std::endl;
631 std::cout << GridLogMessage << " logDetJacobianForce level took "<<t1-t0<<" us "<<std::endl;
632 }
633 RealD logDetJacobianLevel(const GaugeField &U,int smr)
634 {
635 GridBase* grid = U.Grid();
636 GaugeField C(grid);
637 GaugeLinkField Nb(grid);
638 GaugeLinkField Z(grid);
639 GaugeLinkField Umu(grid), Cmu(grid);
640 ColourMatrix Tb;
641 ColourMatrix Tc;
642 typedef typename SU3Adjoint::AMatrix AdjMatrix;
645 const int Ngen = SU3Adjoint::Dimension;
646 AdjMatrix TRb;
647 LatticeComplex cplx(grid);
648 AdjVectorField AlgV(grid);
649 AdjMatrixField Mab(grid);
650 AdjMatrixField Ncb(grid);
651 AdjMatrixField Jac(grid);
652 AdjMatrixField Zac(grid);
653 AdjMatrixField mZac(grid);
654 AdjMatrixField X(grid);
655
656 int mu= (smr/2) %Nd;
657
658 auto mask=PeekIndex<LorentzIndex>(masks[smr],mu); // the cb mask
659
661 // Assemble the N matrix
663 double rho=this->StoutSmearing->SmearRho[1];
664 BaseSmear(Cmu, U,mu,rho);
665
666 Umu = peekLorentz(U, mu);
667 Complex ci(0,1);
668 for(int b=0;b<Ngen;b++) {
669 SU3::generator(b, Tb);
670 // Qlat Tb = 2i Tb^Grid
671 Nb = (2.0)*Ta( ci*Tb * Umu * adj(Cmu));
672 // FIXME -- replace this with LieAlgebraProject
673#if 0
674 SU3::LieAlgebraProject(Ncb,tmp,b);
675#else
676 for(int c=0;c<Ngen;c++) {
677 SU3::generator(c, Tc);
678 auto tmp = -trace(ci*Tc*Nb); // Luchang's norm: (2Tc) (2Td) N^db = -2 delta cd N^db // - was important
679 PokeIndex<ColourIndex>(Ncb,tmp,c,b);
680 }
681#endif
682 }
683
685 // Assemble Luscher exp diff map J matrix
687 // Ta so Z lives in Lie algabra
688 Z = Ta(Cmu * adj(Umu));
689
690 // Move Z to the Adjoint Rep == make_adjoint_representation
691 Zac = Zero();
692 for(int b=0;b<8;b++) {
693 // Adj group sets traceless antihermitian T's -- Guido, really????
694 // Is the mapping of these the same? Same structure constants
695 // Might never have been checked.
696 SU3::generator(b, Tb); // Fund group sets traceless hermitian T's
698 TRb=-TRb;
699 cplx = 2.0*trace(ci*Tb*Z); // my convention 1/2 delta ba
700 Zac = Zac + cplx * TRb; // is this right? YES - Guido used Anti herm Ta's and with bloody wrong sign.
701 }
702
704 // J(x) = 1 + Sum_k=1..N (-Zac)^k/(k+1)!
706 X=1.0;
707 Jac = X;
708 mZac = (-1.0)*Zac;
709 RealD kpfac = 1;
710 for(int k=1;k<12;k++){
711 X=X*mZac;
712 kpfac = kpfac /(k+1);
713 Jac = Jac + X * kpfac;
714 }
715
717 // Mab
719 Mab = Complex(1.0,0.0);
720 Mab = Mab - Jac * Ncb;
721
723 // det
725 LatticeComplex det(grid);
726 det = Determinant(Mab);
727
729 // ln det
731 LatticeComplex ln_det(grid);
732 ln_det = log(det);
733
735 // Masked sum
737 ln_det = ln_det * mask;
738 Complex result = sum(ln_det);
739 return result.real();
740 }
741public:
743 {
744 RealD ln_det = 0;
745 if (this->smearingLevels > 0)
746 {
747 double start = usecond();
748 for (int ismr = this->smearingLevels - 1; ismr > 0; --ismr) {
749 ln_det+= logDetJacobianLevel(this->get_smeared_conf(ismr-1),ismr);
750 }
751 ln_det +=logDetJacobianLevel(*(this->ThinLinks),0);
752
753 double end = usecond();
754 double time = (end - start)/ 1e3;
755 std::cout << GridLogMessage << "GaugeConfigurationMasked: logDetJacobian took " << time << " ms" << std::endl;
756 }
757 return ln_det;
758 }
759 void logDetJacobianForce(GaugeField &force)
760 {
761 force =Zero();
762 GaugeField force_det(force.Grid());
763
764 if (this->smearingLevels > 0)
765 {
766 double start = usecond();
767
768 GaugeLinkField tmp_mu(force.Grid());
769
770 for (int ismr = this->smearingLevels - 1; ismr > 0; --ismr) {
771
772 // remove U in UdSdU...
773 for (int mu = 0; mu < Nd; mu++) {
774 tmp_mu = adj(peekLorentz(this->get_smeared_conf(ismr), mu)) * peekLorentz(force, mu);
775 pokeLorentz(force, tmp_mu, mu);
776 }
777
778 // Propagate existing force
779 force = this->AnalyticSmearedForce(force, this->get_smeared_conf(ismr - 1), ismr);
780
781 // Add back U in UdSdU...
782 for (int mu = 0; mu < Nd; mu++) {
783 tmp_mu = peekLorentz(this->get_smeared_conf(ismr - 1), mu) * peekLorentz(force, mu);
784 pokeLorentz(force, tmp_mu, mu);
785 }
786
787 // Get this levels determinant force
788 force_det = Zero();
789 logDetJacobianForceLevel(this->get_smeared_conf(ismr-1),force_det,ismr);
790
791 // Sum the contributions
792 force = force + force_det;
793 }
794
795 // remove U in UdSdU...
796 for (int mu = 0; mu < Nd; mu++) {
797 tmp_mu = adj(peekLorentz(this->get_smeared_conf(0), mu)) * peekLorentz(force, mu);
798 pokeLorentz(force, tmp_mu, mu);
799 }
800
801 force = this->AnalyticSmearedForce(force, *this->ThinLinks,0);
802
803 for (int mu = 0; mu < Nd; mu++) {
804 tmp_mu = peekLorentz(*this->ThinLinks, mu) * peekLorentz(force, mu);
805 pokeLorentz(force, tmp_mu, mu);
806 }
807
808 force_det = Zero();
809
810 logDetJacobianForceLevel(*this->ThinLinks,force_det,0);
811
812 force = force + force_det;
813
814 force=Ta(force); // Ta
815
816 double end = usecond();
817 double time = (end - start)/ 1e3;
818 std::cout << GridLogMessage << "GaugeConfigurationMasked: lnDetJacobianForce took " << time << " ms" << std::endl;
819 } // if smearingLevels = 0 do nothing
820 }
821
822private:
823 //====================================================================
824 // Override base clas here to mask it
825 virtual void fill_smearedSet(GaugeField &U)
826 {
827 this->ThinLinks = &U; // attach the smearing routine to the field U
828
829 // check the pointer is not null
830 if (this->ThinLinks == NULL)
831 std::cout << GridLogError << "[SmearedConfigurationMasked] Error in ThinLinks pointer\n";
832
833 if (this->smearingLevels > 0)
834 {
835 std::cout << GridLogMessage << "[SmearedConfigurationMasked] Filling SmearedSet\n";
836 GaugeField previous_u(this->ThinLinks->Grid());
837
838 GaugeField smeared_A(this->ThinLinks->Grid());
839 GaugeField smeared_B(this->ThinLinks->Grid());
840
841 previous_u = *this->ThinLinks;
842 double start = usecond();
843 for (int smearLvl = 0; smearLvl < this->smearingLevels; ++smearLvl)
844 {
845 this->StoutSmearing->smear(smeared_A, previous_u);
846 ApplyMask(smeared_A,smearLvl);
847 smeared_B = previous_u;
848 ApplyMask(smeared_B,smearLvl);
849 // Replace only the masked portion
850 this->SmearedSet[smearLvl] = previous_u-smeared_B + smeared_A;
851 previous_u = this->SmearedSet[smearLvl];
852
853 // For debug purposes
854 RealD impl_plaq = WilsonLoops<Gimpl>::avgPlaquette(previous_u);
855 std::cout << GridLogMessage << "[SmearedConfigurationMasked] smeared Plaq: " << impl_plaq << std::endl;
856 }
857 double end = usecond();
858 double time = (end - start)/ 1e3;
859 std::cout << GridLogMessage << "GaugeConfigurationMasked: Link smearing took " << time << " ms" << std::endl;
860 }
861 }
862 //====================================================================
863 // Override base to add masking
864 virtual GaugeField AnalyticSmearedForce(const GaugeField& SigmaKPrime,
865 const GaugeField& GaugeK,int level)
866 {
867 GridBase* grid = GaugeK.Grid();
868 GaugeField SigmaK(grid), iLambda(grid);
869 GaugeField SigmaKPrimeA(grid);
870 GaugeField SigmaKPrimeB(grid);
871 GaugeLinkField iLambda_mu(grid);
872 GaugeLinkField iQ(grid), e_iQ(grid);
873 GaugeLinkField SigmaKPrime_mu(grid);
874 GaugeLinkField GaugeKmu(grid), Cmu(grid);
875
876 int mmu= (level/2) %Nd;
877 int cb= (level%2);
878 double rho=this->StoutSmearing->SmearRho[1];
879
880 // Can override this to do one direction only.
881 SigmaK = Zero();
882 iLambda = Zero();
883
884 SigmaKPrimeA = SigmaKPrime;
885 ApplyMask(SigmaKPrimeA,level);
886 SigmaKPrimeB = SigmaKPrime - SigmaKPrimeA;
887
888 // Could get away with computing only one polarisation here
889 // int mu= (smr/2) %Nd;
890 // SigmaKprime_A has only one component
891#if 0
892 BaseSmear(Cmu, GaugeK,mu,rho);
893 GaugeKmu = peekLorentz(GaugeK, mu);
894 SigmaKPrime_mu = peekLorentz(SigmaKPrimeA, mu);
895 iQ = Ta(Cmu * adj(GaugeKmu));
896 this->set_iLambda(iLambda_mu, e_iQ, iQ, SigmaKPrime_mu, GaugeKmu);
897 pokeLorentz(SigmaK, SigmaKPrime_mu * e_iQ + adj(Cmu) * iLambda_mu, mu);
898 pokeLorentz(iLambda, iLambda_mu, mu);
899 BaseSmearDerivative(SigmaK, iLambda,GaugeK,mu,rho); // derivative of SmearBase
900#else
901 // GaugeField C(grid);
902 // this->StoutSmearing->BaseSmear(C, GaugeK);
903 // for (int mu = 0; mu < Nd; mu++)
904 int mu =mmu;
905 BaseSmear(Cmu, GaugeK,mu,rho);
906 {
907 // Cmu = peekLorentz(C, mu);
908 GaugeKmu = peekLorentz(GaugeK, mu);
909 SigmaKPrime_mu = peekLorentz(SigmaKPrimeA, mu);
910 iQ = Ta(Cmu * adj(GaugeKmu));
911 this->set_iLambda(iLambda_mu, e_iQ, iQ, SigmaKPrime_mu, GaugeKmu);
912 pokeLorentz(SigmaK, SigmaKPrime_mu * e_iQ + adj(Cmu) * iLambda_mu, mu);
913 pokeLorentz(iLambda, iLambda_mu, mu);
914 std::cout << " mu "<<mu<<" SigmaKPrime_mu"<<norm2(SigmaKPrime_mu)<< " iLambda_mu " <<norm2(iLambda_mu)<<std::endl;
915 }
916 // GaugeField SigmaKcopy(grid);
917 // SigmaKcopy = SigmaK;
918 BaseSmearDerivative(SigmaK, iLambda,GaugeK,mu,rho); // derivative of SmearBase
919 // this->StoutSmearing->derivative(SigmaK, iLambda,GaugeK); // derivative of SmearBase
920 // SigmaKcopy = SigmaKcopy - SigmaK;
921 // std::cout << " BaseSmearDerivative fast path error" <<norm2(SigmaKcopy)<<std::endl;
922#endif
924 // propagate the rest of the force as identity map, just add back
926 SigmaK = SigmaK+SigmaKPrimeB;
927
928 return SigmaK;
929 }
930
931public:
932
933 /* Standard constructor */
934 SmearedConfigurationMasked(GridCartesian* _UGrid, unsigned int Nsmear, Smear_Stout<Gimpl>& Stout)
935 : SmearedConfiguration<Gimpl>(_UGrid, Nsmear,Stout)
936 {
937 assert(Nsmear%(2*Nd)==0); // Or multiply by 8??
938
939 // was resized in base class
940 assert(this->SmearedSet.size()==Nsmear);
941
942 GridRedBlackCartesian * UrbGrid;
944 LatticeComplex one(_UGrid); one = ComplexD(1.0,0.0);
945 LatticeComplex tmp(_UGrid);
946
947 for (unsigned int i = 0; i < this->smearingLevels; ++i) {
948
949 masks.push_back(*(new LatticeLorentzComplex(_UGrid)));
950
951 int mu= (i/2) %Nd;
952 int cb= (i%2);
953 LatticeComplex tmpcb(UrbGrid);
954
955 masks[i]=Zero();
957 // Setup the mask
959 tmp = Zero();
960 pickCheckerboard(cb,tmpcb,one);
961 setCheckerboard(tmp,tmpcb);
962 PokeIndex<LorentzIndex>(masks[i],tmp, mu);
963
964 }
965 delete UrbGrid;
966 }
967
968 virtual void smeared_force(GaugeField &SigmaTilde)
969 {
970 if (this->smearingLevels > 0)
971 {
972 double start = usecond();
973 GaugeField force = SigmaTilde; // actually = U*SigmaTilde
974 GaugeLinkField tmp_mu(SigmaTilde.Grid());
975
976 // Remove U from UdSdU
977 for (int mu = 0; mu < Nd; mu++)
978 {
979 // to get just SigmaTilde
980 tmp_mu = adj(peekLorentz(this->SmearedSet[this->smearingLevels - 1], mu)) * peekLorentz(force, mu);
981 pokeLorentz(force, tmp_mu, mu);
982 }
983
984 for (int ismr = this->smearingLevels - 1; ismr > 0; --ismr) {
985 force = this->AnalyticSmearedForce(force, this->get_smeared_conf(ismr - 1),ismr);
986 }
987
988 force = this->AnalyticSmearedForce(force, *this->ThinLinks,0);
989
990 // Add U to UdSdU
991 for (int mu = 0; mu < Nd; mu++)
992 {
993 tmp_mu = peekLorentz(*this->ThinLinks, mu) * peekLorentz(force, mu);
994 pokeLorentz(SigmaTilde, tmp_mu, mu);
995 }
996
997
998 double end = usecond();
999 double time = (end - start)/ 1e3;
1000 std::cout << GridLogMessage << " GaugeConfigurationMasked: Smeared Force chain rule took " << time << " ms" << std::endl;
1001
1002 } // if smearingLevels = 0 do nothing
1003 SigmaTilde=Gimpl::projectForce(SigmaTilde); // Ta
1004 }
1005
1006};
1007
1009
#define one
Definition BGQQPX.h:108
AcceleratorVector< int, MaxDims > Coordinate
Definition Coordinate.h:95
auto Cshift(const Expression &expr, int dim, int shift) -> decltype(closure(expr))
Definition Cshift.h:55
void Dump(const Lattice< T > &lat, std::string s, Coordinate site=Coordinate({0, 0, 0, 0}))
accelerator_inline Grid_simd2< S, V > trace(const Grid_simd2< S, V > &arg)
accelerator_inline Grid_simd< S, V > log(const Grid_simd< S, V > &r)
auto closure(const LatticeUnaryExpression< Op, T1 > &expr) -> Lattice< typename std::remove_const< decltype(expr.op.func(vecEval(0, expr.arg1)))>::type >
Definition Lattice_ET.h:492
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))>
vobj::scalar_object peekSite(const Lattice< vobj > &l, const Coordinate &site)
Lattice< vobj > adj(const Lattice< vobj > &lhs)
vobj::scalar_object sum(const vobj *arg, Integer osites)
RealD norm2(const Lattice< vobj > &arg)
Lattice< iScalar< iScalar< iScalar< Vec > > > > Determinant(const Lattice< iScalar< iScalar< iMatrix< Vec, N > > > > &Umu)
Lattice< iScalar< iScalar< iMatrix< vComplexD, N > > > > Inverse(const Lattice< iScalar< iScalar< iMatrix< vComplexD, N > > > > &Umu)
void setCheckerboard(Lattice< vobj > &full, const Lattice< vobj > &half)
void pickCheckerboard(int cb, Lattice< vobj > &half, const Lattice< vobj > &full)
GridLogger GridLogError(1, "Error", GridLogColours, "RED")
GridLogger GridLogPerformance(1, "Performance", GridLogColours, "GREEN")
GridLogger GridLogMessage(1, "Message", GridLogColours, "NORMAL")
#define NAMESPACE_BEGIN(A)
Definition Namespace.h:35
#define NAMESPACE_END(A)
Definition Namespace.h:36
iColourMatrix< Complex > ColourMatrix
Definition QCD.h:133
void pokeLorentz(Lattice< vobj > &lhs, const Lattice< decltype(peekIndex< LorentzIndex >(vobj(), 0))> &rhs, int i)
Definition QCD.h:487
Lattice< vTComplexD > LatticeComplexD
Definition QCD.h:361
static constexpr int Nd
Definition QCD.h:52
Lattice< vLorentzComplex > LatticeLorentzComplex
Definition QCD.h:320
auto peekColour(const vobj &rhs, int i) -> decltype(PeekIndex< ColourIndex >(rhs, 0))
Definition QCD.h:429
Lattice< vTComplex > LatticeComplex
Definition QCD.h:359
void pokeColour(Lattice< vobj > &lhs, const Lattice< decltype(peekIndex< ColourIndex >(vobj(), 0))> &rhs, int i)
Definition QCD.h:459
auto peekLorentz(const vobj &rhs, int i) -> decltype(PeekIndex< LorentzIndex >(rhs, 0))
Definition QCD.h:446
RealF Real
Definition Simd.h:65
std::complex< RealD > ComplexD
Definition Simd.h:79
std::complex< Real > Complex
Definition Simd.h:80
double RealD
Definition Simd.h:61
accelerator_inline iScalar< vtype > Ta(const iScalar< vtype > &r)
Definition Tensor_Ta.h:45
accelerator_inline ComplexD transpose(ComplexD &rhs)
double usecond(void)
Definition Timer.h:50
static INTERNAL_PRECISION U
Definition Zolotarev.cc:230
static void LieAlgebraProject(LatticeAlgebraMatrix &out, const LatticeMatrix &in, int b)
Definition GaugeGroup.h:406
static void generator(int lieIndex, iGroupMatrix< cplx > &ta, GroupName::SU)
Definition GaugeGroup.h:66
void resize(uint64_t size)
static void generator(int Index, iSUnAdjointMatrix< cplx > &iAdjTa)
Definition SUnAdjoint.h:61
iSUnAdjointMatrix< Complex > AMatrix
Definition SUnAdjoint.h:38
Lattice< vAMatrix > LatticeAdjMatrix
Definition SUnAdjoint.h:46
static const int Dimension
Definition SUnAdjoint.h:30
Lattice< iScalar< iScalar< iVector< vComplex, Dimension > > > > LatticeAdjVector
Definition SUnAdjoint.h:58
Stout smearing of link variable.
void ComputeNxy(const GaugeLinkField &PlaqL, const GaugeLinkField &PlaqR, AdjMatrixField &NxAd)
void Compute_MpInvJx_dNxxdSy(const GaugeLinkField &PlaqL, const GaugeLinkField &PlaqR, AdjMatrixField MpInvJx, AdjVectorField &Fdet2)
SU3Adjoint::LatticeAdjVector AdjVectorField
virtual void smeared_force(GaugeField &SigmaTilde)
void BaseSmear(GaugeLinkField &Cup, const GaugeField &U, int mu, RealD rho)
virtual GaugeField AnalyticSmearedForce(const GaugeField &SigmaKPrime, const GaugeField &GaugeK, int level)
virtual void fill_smearedSet(GaugeField &U)
RealD logDetJacobianLevel(const GaugeField &U, int smr)
void logDetJacobianForceLevel(const GaugeField &U, GaugeField &force, int smr)
void logDetJacobianForce(GaugeField &force)
void InsertForce(GaugeField &Fdet, AdjVectorField &Fdet_nu, int nu)
void ApplyMask(GaugeField &U, int smr)
SU3Adjoint::LatticeAdjMatrix AdjMatrixField
std::vector< LatticeLorentzComplex > masks
void BaseSmearDerivative(GaugeField &SigmaTerm, const GaugeField &iLambda, const GaugeField &U, int mmu, RealD rho)
SmearedConfigurationMasked(GridCartesian *_UGrid, unsigned int Nsmear, Smear_Stout< Gimpl > &Stout)
const unsigned int smearingLevels
const GaugeField & get_smeared_conf(int Level) const
Returns smeared configuration at level 'Level'.
Smear_Stout< Gimpl > * StoutSmearing
SmearedConfiguration(GridCartesian *UGrid, unsigned int Nsmear, Smear_Stout< Gimpl > &Stout)
void set_iLambda(GaugeLinkField &iLambda, GaugeLinkField &e_iQ, const GaugeLinkField &iQ, const GaugeLinkField &Sigmap, const GaugeLinkField &GaugeK) const
std::vector< GaugeField > SmearedSet
static GridRedBlackCartesian * makeFourDimRedBlackGrid(const GridCartesian *FourDimGrid)
static RealD avgPlaquette(const GaugeLorentz &Umu)
static void StapleUpper(GaugeMat &staple, const GaugeLorentz &Umu, int mu, int nu)
static void Staple(GaugeMat &staple, const GaugeLorentz &Umu, int mu, int nu)
Definition Simd.h:194