void pt_mat(int N, IFloat **fout, IFloat **fin, const int *dir){ IFloat *u, *v; int s[4], spm[4]; Matrix ud; Matrix *vin[N],*vout[N]; for(int d=0; d<N; d++){ vin[d] = (Matrix *)fin[d]; vout[d] = (Matrix *)fout[d]; int mu = dir[d]; bool backwards = mu%2 ? true : false; mu /= 2; for(spm[3]=s[3]=0; s[3]<GJP.TnodeSites(); spm[3]++, s[3]++) for(spm[2]=s[2]=0; s[2]<GJP.ZnodeSites(); spm[2]++, s[2]++) for(spm[1]=s[1]=0; s[1]<GJP.YnodeSites(); spm[1]++, s[1]++) for(spm[0]=s[0]=0; s[0]<GJP.XnodeSites(); spm[0]++, s[0]++) { if(backwards){ spm[mu] = (s[mu]-1+GJP.NodeSites(mu))%GJP.NodeSites(mu); u = (IFloat*)(Lat->GaugeField()+Lat->GsiteOffset(spm)+mu); v = (IFloat*)&vin[d][Lat->FsiteOffset(spm)]; mDotMEqual((IFloat*)&vout[d][Lat->FsiteOffset(s)], u, v); }else{ spm[mu] = (s[mu]+1)%GJP.NodeSites(mu); ud.Dagger(*(Lat->GaugeField()+Lat->GsiteOffset(s)+mu)); u = (IFloat*)&ud; v = (IFloat*)&vin[d][Lat->FsiteOffset(spm)]; // STAG stores hermitian conjugate links mDotMEqual((IFloat*)&vout[d][Lat->FsiteOffset(s)], u, v); } spm[mu] = s[mu]; } } }
CPS_START_NAMESPACE //---------------------------------------------------------- // // alg_tcharge.C // // measures a simple defintion of the // topological charge // // Using Clover Leaf c.f hep-lat/010610 Eq (6) -- (10) //----------------------------------------------------------- /*! takes the imaginary part of a matrix */ void ZeroReal(Matrix& m) { Matrix temp; temp.Dagger( m ); m-=temp; m*=0.5; }
//----------------------------------------------------------------------- // Rotate gauge of the lattice (from Min) //----------------------------------------------------------------------- void rotate_gauge_explicit(Lattice &lat,int dir) { const char *cname="none"; const char *fname="rotate_gauge_explicit"; VRB.Func(cname,fname); if ((dir<0)||(dir>3)){ VRB.Result(cname,fname,"Error:: direction should be 0,1,2,3\n"); return; } int NX(GJP.XnodeSites()); int NY(GJP.YnodeSites()); int NZ(GJP.ZnodeSites()); int NT(GJP.TnodeSites()); //--------------------------------------------------------------- // Set up the gauge fixing and other required conditions //--------------------------------------------------------------- int num_nodes[4] = { GJP.Xnodes(), GJP.Ynodes(), GJP.Znodes(), GJP.Tnodes() } ; int node_sites[4] = { GJP.XnodeSites(), GJP.YnodeSites(), GJP.ZnodeSites(), GJP.TnodeSites() } ; int Size[4]; for (int i=0; i<4; i++){ Size[i] = num_nodes[i]*node_sites[i]; } int *plns; plns = (int*) smalloc(Size[dir]*sizeof(int)); for (int i=0; i<Size[dir]; i++){ plns[i] = i; } int npln = Size[dir]; FixGaugeType normdir; if (dir==3) normdir = FIX_GAUGE_COULOMB_T; else if (dir==0) normdir = FIX_GAUGE_COULOMB_X; else if (dir==1) normdir = FIX_GAUGE_COULOMB_Y; else normdir = FIX_GAUGE_COULOMB_Z; //---------------------------------------------------------------------- //initialize the parameters need to gauge fixing --------------------- //---------------------------------------------------------------------- Matrix *L; Matrix **Gp; int ii; int volume = NX*NY*NZ*NT; L = (Matrix*) smalloc(4*volume*sizeof(Matrix)); Gp = (Matrix**) smalloc(npln*sizeof(Matrix*)); for(ii=0; ii<npln; ii++) Gp[ii] = (Matrix*) smalloc(volume/node_sites[dir] * sizeof(Matrix)); //----------------------------------------------------------------------------- //GAUGE FIXING MATRICES //----------------------------------------------------------------------------- for (int slice=0; slice<node_sites[dir]; slice++) for(int cnt=0; cnt<volume/node_sites[dir]; cnt++) Gp[slice][cnt]=lat.FixGaugePtr()[slice][cnt]; //------------------------------------------------------------------------------- //------------------------------------------------------------------------------- // TRY TO Transform the Lattice to the Coulomb Gauge and store it --------------- //------------------------------------------------------------------------------- int tt,xx,yy,zz,temp_ind; int slice_ind[3]; //slice_ind[3] stores the 3 directions on the 'dir' slice with indices increasing temp_ind = 0; for (int i=0; i<4; i++){ if (i!=dir) { slice_ind[temp_ind] = i; temp_ind++; } } VRB.Result(cname,fname,"dir == %d \n",dir); VRB.Result(cname,fname,"slice index == %d %d %d\n",slice_ind[0],slice_ind[1],slice_ind[2]); // the dummy node_sites for each dummy dirction int NN[4]; NN[0] = node_sites[slice_ind[0]]; NN[1] = node_sites[slice_ind[1]]; NN[2] = node_sites[slice_ind[2]]; NN[3] = node_sites[dir]; int s[4]; for (int i=0; i<3; i++) s[i] = slice_ind[i]; s[3] = dir; //--------------------------------------------------------------------------------- //copy the old lattice config to matrix array L, transform L and then copy back //--------------------------------------------------------------------------------- lat.CopyGaugeField(L); int x[4]; // xx yy zz tt are dummy position vector, as tt represents the gfixing direction for (x[3]=0; x[3]<node_sites[3]; x[3]++) for (x[2]=0; x[2]<node_sites[2]; x[2]++) for (x[1]=0; x[1]<node_sites[1]; x[1]++) for (x[0]=0; x[0]<node_sites[0]; x[0]++) { xx = x[slice_ind[0]]; yy = x[slice_ind[1]]; zz = x[slice_ind[2]]; tt = x[dir]; Matrix g = Gp[tt][(zz*NN[1]+yy)*NN[0]+xx]; Matrix D; Matrix gg ; Matrix transmit; //----------------- T Direction ---------------------------- if (tt+1<NN[3]) gg = Gp[tt+1][(zz*NN[1]+yy)*NN[0]+xx]; else { transmit = Gp[0][(zz*NN[1]+yy)*NN[0]+xx]; getPlusData((IFloat *)&gg, (IFloat *)&transmit, sizeof(Matrix)/sizeof(IFloat), dir) ; } D.Dagger(gg); L[IND(x[0],x[1],x[2],x[3],dir)] = g*L[IND(x[0],x[1],x[2],x[3],dir)]*D; //----------------- Z Direction ---------------------------- if (zz+1<NN[2]) gg = Gp[tt][((zz+1)*NN[1]+yy)*NN[0]+xx]; else { transmit = Gp[tt][((zz+1)%NN[2]*NN[1]+yy)*NN[0]+xx]; getPlusData((IFloat *)&gg, (IFloat *)&transmit, sizeof(Matrix)/sizeof(IFloat), slice_ind[2]) ; } D.Dagger(gg); L[IND(x[0],x[1],x[2],x[3],slice_ind[2])] = g*L[IND(x[0],x[1],x[2],x[3],slice_ind[2])]*D; //----------------- Y Direction ---------------------------- if (yy+1<NN[1]) gg = Gp[tt][(zz*NN[1]+(yy+1))*NN[0]+xx]; else { transmit = Gp[tt][(zz*NN[1]+(yy+1)%NN[1])*NN[0]+xx]; getPlusData((IFloat *)&gg, (IFloat *)&transmit, sizeof(Matrix)/sizeof(IFloat), slice_ind[1]) ; } D.Dagger(gg); L[IND(x[0],x[1],x[2],x[3],slice_ind[1])] = g*L[IND(x[0],x[1],x[2],x[3],slice_ind[1])]*D; //----------------- X Direction ---------------------------- if (xx+1<NN[0]) gg = Gp[tt][(zz*NN[1]+yy)*NN[0]+(xx+1)]; else { transmit = Gp[tt][(zz*NN[1]+yy)*NN[0]+(xx+1)%NN[0]]; getPlusData((IFloat *)&gg, (IFloat *)&transmit, sizeof(Matrix)/sizeof(IFloat), slice_ind[0]) ; } D.Dagger(gg); L[IND(x[0],x[1],x[2],x[3],slice_ind[0])] = g*L[IND(x[0],x[1],x[2],x[3],slice_ind[0])]*D; } lat.GaugeField(L); //--------------------------------Free L and Gp ------------------------------------- sfree(L); for (ii=0; ii<npln; ii++) sfree(Gp[ii]); sfree(Gp); sfree(plns); }
/*! Computes \f[ \mbox{Trace}(\mbox{seqQ} \, \gamma_{\mu_1} \, \gamma_{\mu_2} \, \gamma_{\mu_3}\, \stackrel{\displaystyle \leftrightarrow}{D}_\nu \stackrel{\displaystyle \leftrightarrow}{D}_\rho ... e^{-i mom . x}\, \mbox{Quark}) \f] where \f$\mu\f$ is the member int gamma and ThreeMom mom is the momentum injected at the operator. The string of derivatives gets broken up in strings of forward and backward hops. For each term the quark and anti-quark are sitting on different sites and they are connected with the gauge connection U. The gauge connection U is calculated using the PathOrdPlus routine given the location of the anti-quark (starting point) and a list of hops. The Derivative class is used not only to do the break-up of the string of derivatives in strings of hops, but also to compute the locations of the quark and the anti-quark and provide the list of links needed to compute the gauge connection U for each term. In order to speed up the code first we compute for all sites all derivative terms with the derivatives applied on the quark i.e the anti-quark is not displaced. These terms are not summed up but they are stored individually in the DTerms Terms class. Then I we go again through the all sites and construct the derivatives. If for a given term the anti-quark is displaced we just have to communicate a single Complex number from that site. The DTerms class handles all that. The routine Derivative :: DTermIndx() is the mapping of the derivative terms to a particular storage order. The DTerm class does not have to know the storage order. Only the Derivative class knows about it. NOTE: The quark is at the sink of the Quark propagator while the anti-quark is at to source of the sequential propagator. **/ void Nuc3ptStru::InsertOp(CorrFunc& tmp,QPropW& seqQ, QPropW& Quark) { char *fname = "InsertOp()"; VRB.Func(cname, fname); if(seqQ.GFixedSnk() || Quark.GFixedSnk()) ERR.General(cname,fname,"Gauge Fixed sinks!\n") ; Lattice& lat=seqQ.AlgLattice() ; // The lattice #ifdef DEBUG printf("%s:: NDTerms= %i\n",cname,D.NDTerms()); #endif DTerms Terms(D.NDTerms()); // The derivative terms Matrix U ; WilsonMatrix aQ ; // the anti-quark WilsonMatrix Q ; // quark WilsonMatrix aQU ; // anti-quark times Gauge path WilsonMatrix buff ; // Buffer needed for communication int aq_vec[4]; // Anti-quark location int q_vec[4] ; // quark location int *dirs = new int[D.N()]; if(dirs == 0) ERR.Pointer(cname, fname, "dirs"); Site s ; //first compute all derivatives terms on quarks for(s.Begin();s.End();s.nextSite()) // Loop over sites { aQ=seqQ[s.Index()] ; // Apply the gamma matrices on the sequential propagator // We multiply the source indices of the sequential propagator // which are the anti-quark for(int mu(0);mu<G.N();mu++) aQ.gr(G[mu]) ; // Multiply by gamma_mu // Loop over all derivative terms on the Quark for(D.Start();D.NotEnd();D.NextQuark()) { // Calculate the endpoints of the shift D.CalcEndPoints(aq_vec,q_vec,s); // The sink indices of the quark propagator are the quark Q=Quark.GetMatrix(q_vec,buff) ; D.CalcListOfLinks(dirs); #ifdef DEBUG printf("\n%s:: dirs ",cname); for(int i(0);i<D.N();i++) printf("%i ",dirs[i]); printf(" aq_vec: "); for(int i(0);i<4;i++) printf("%i ",aq_vec[i]); printf(" q_vec: ") ; for(int i(0);i<4;i++) printf("%i ",q_vec[i]); #endif // Start from the anti-quark and move along the path described // by the list of dirs multiplying all the encountered links // at the end of the day you should be at the position of the quark if(D.N()>1) { U.ZeroMatrix(); lat.PathOrdProdPlus(U,aq_vec,dirs,D.N()) ; //lat.PathOrdProd(U,aq_vec,dirs,D.N()) ; } else //if D.N()==1 PathOrdPlus does not work { int abs_dir = dirs[0]&3; //abs_dir is {0,1,2,3} if(abs_dir == dirs[0]) // dir is forward U = *(lat.GetBufferedLink(aq_vec, abs_dir)); else // dir is backward. q_vec is now the site where the link is U.Dagger(*(lat.GetBufferedLink(q_vec, abs_dir))); } #ifdef DEBUG Complex cboo(U.Tr()) ; printf(" TrU= (%g %g)\n",cboo.real(),cboo.imag()); #endif //Now that the gauge connection is constructed multiply it on //the quark i.e the source indices of the anti-quark propagator aQU.UMultSource(U,aQ) ; Terms(D.DTermIndx(),s.Index()) = Trace(aQU,Q) ; #ifdef DEBUG printf(" (anti-Q, Q) aQU = (%6.3f %6.3f), (%6.3f %6.3f) (%6.3f %6.3f)\n", aQ.Trace().real(),aQ.Trace().imag(), Q.Trace().real(),Q.Trace().imag(), aQU.Trace().real(),aQU.Trace().imag()); printf("%s:: DTermIndx(): %i site: %i Value: ( %6.3f %6.3f ) \n", cname,D.DTermIndx(),s.Index(), Terms(D.DTermIndx(),s.Index()).real(), Terms(D.DTermIndx(),s.Index()).imag()); #endif } } Complex tt ; // Loop over sites and construct the operator for(s.Begin();s.End();s.nextSite()) { int t(s.physT()) ; for(D.Start();D.NotEnd();D.Next()) // Loop over all derivative terms { //Calculate the endpoints of the shift //aq_vec : anti quark location // q_vec : quark location D.CalcEndPoints(aq_vec,q_vec,s); Complex cc(Terms.GetTerm(D.DTermIndx(),aq_vec,tt)) ; //Finaly the momentum factors cc *= mom.Fact(s) ; // The momentum factor exp(-ipx) cc *= D.Fact() ; /* The sign and the normalization factor for the current derivative term */ tmp[t] += cc ; #ifdef DEBUG printf("%s:: DTermIndx(): %i site: %i Fact: %9.6f Value: ( %6.3f %6.3f ) \n", cname, D.DTermIndx(),s.Index(),D.Fact(),cc.real(),cc.imag()); #endif } } delete [] dirs ; }