00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00014 void set_cold(gauge_field &U) {
00015 begin_function("set_cold");
00016 mdp << "Creating a cold gauge configuration" << '\n';
00017 register site x(U.lattice());
00018 int mu;
00019 forallsites(x)
00020 for(mu=0; mu<U.ndim; mu++)
00021 U(x,mu)=mdp_identity(U.nc);
00022 U.update();
00023 end_function("set_cold");
00024 }
00025
00027 void set_hot(gauge_field &U) {
00028 begin_function("set_hot");
00029 mdp << "Creating a hot gauge configuration" << '\n';
00030 register site x(U.lattice());
00031 int mu;
00032 forallsites(x)
00033 for(mu=0; mu<U.ndim; mu++)
00034 U(x,mu)=U.lattice().random(x).SU(U.nc);
00035 U.update();
00036 end_function("set_hot");
00037 }
00038
00040 void check_unitarity(gauge_field &U, double precision=PRECISION) {
00041 begin_function("check_unitarity");
00042 site x(U.lattice());
00043 int mu;
00044 long how_many=0;
00045 for(x.idx=0; x.idx<U.lattice().nvol; x.idx++)
00046 for(mu=0; mu<U.ndim; mu++)
00047 if(max(inv(U(x,mu))-hermitian(U(x,mu)))>precision) how_many++;
00048 mdp.add(how_many);
00049 mdp << "Non unitary links found=" << how_many << '\n';
00050 end_function("check_unitarity");
00051 }
00052
00054 mdp_real average_plaquette(gauge_field &U,int mu,int nu) {
00055 mdp_real tmp=0;
00056 site x(U.lattice());
00057
00058 forallsites(x)
00059 tmp+=real(trace(plaquette(U,x,mu,nu)));
00060 mdp.add(tmp);
00061 return tmp/(U.lattice().nvol_gl*U.nc);
00062 }
00063
00065 mdp_real average_plaquette(gauge_field &U) {
00066 mdp_real tmp=0;
00067 site x(U.lattice());
00068
00069 int mu,nu;
00070 forallsites(x)
00071 for(mu=0; mu<U.ndim-1; mu++)
00072 for(nu=mu+1; nu<U.ndim; nu++)
00073 tmp+=real(trace(plaquette(U,x,mu,nu)));
00074 mdp.add(tmp);
00075 return 2.0*tmp/(U.ndim*(U.ndim-1)*U.lattice().nvol_gl*U.nc);
00076 }
00077
00079 void compute_em_field(gauge_field &U) {
00080 int nc=U.nc;
00081 site x(U.lattice());
00082
00083 U.em.deallocate_memory();
00084 U.em.allocate_em_field(U.lattice(), U.nc);
00085 mdp_matrix A(nc,nc);
00086 mdp_matrix b1(nc,nc), b2(nc,nc);
00087
00088
00089
00090
00091 int mu,nu;
00092 forallsites(x)
00093 for(mu=0; mu<U.ndim-1; mu++)
00094 for(nu=mu+1; nu<U.ndim; nu++) {
00095
00096 A=
00097 U(x,mu)*U(x+mu,nu)*hermitian(U(x,nu)*U(x+nu,mu))+
00098 hermitian(U(x-nu,nu))*U(x-nu,mu)*
00099 U((x-nu)+mu,nu)*hermitian(U(x,mu))+
00100 hermitian(U((x-mu)-nu,nu)*U(x-mu,mu))*U((x-mu)-nu,mu)*U(x-nu,nu)+
00101 U(x,nu)*hermitian(U(x-mu,nu)*U((x+nu)-mu,mu))*U(x-mu,mu);
00102
00103 U.em(x,mu,nu)=((mdp_real) 0.125)*(A-hermitian(A));
00104
00105 }
00106 U.em.update();
00107 }
00108
00109
00110
00111
00112
00113
00114
00124 void compute_long_links(gauge_field &U, gauge_field &V, int length=2) {
00125 if((&(U.lattice())!=&(V.lattice())) || (U.nc!=V.nc) || (U.ndim!=V.ndim))
00126 error("fermiqcd_gauge_auxiliary_functions/compute_long_links: U and V are not compatible lattices");
00127 if(V.lattice().next_next<length)
00128 error("fermiqcd_gauge_auxiliary_functions/compute_long_links: next_next is not big enough");
00129
00130 U.long_links.deallocate_memory();
00131 U.long_links.allocate_mdp_nmatrix_field(V.lattice(),U.ndim, U.nc, U.nc);
00132 site x(U.lattice());
00133 int mu;
00134 if(length==2)
00135 forallsites(x)
00136 for(mu=0; mu<V.ndim; mu++)
00137 U.long_links(x,mu)=V(x,mu)*V(x+mu,mu);
00138 if(length==3)
00139 forallsites(x)
00140 for(mu=0; mu<V.ndim; mu++)
00141 U.long_links(x,mu)=V(x,mu)*V(x+mu,mu)*V((x+mu)+mu,mu);
00142 U.long_links.update();
00143 }
00144
00145
00146
00147
00148
00149
00150
00159 void set_antiperiodic_phases(gauge_field &U, int mu=0, int check=TRUE) {
00160 begin_function("set_antiperiodic_phases");
00161 site x(U.lattice());
00162 int i,j;
00163 if(check)
00164 mdp << "Setting antiperiodic boundary conditions on mu=" << mu << '\n';
00165 else
00166 mdp << "Removing antiperiodic boundary conditions on mu=" << mu << '\n';
00167 forallsites(x)
00168 if(x(mu)==U.lattice().size(mu)-1) {
00169 for(i=0; i<U.nc; i++)
00170 for(j=0; j<U.nc; j++)
00171 U(x,mu,i,j)*=-1;
00172 }
00173 end_function("set_antiperiodic_phases");
00174 }
00175
00176
00179 mdp_matrix project_SU(mdp_matrix M, int nstep=1) {
00180 int i,j,k,l,step,nc=M.rowmax();
00181 mdp_real e0,e1,e2,e3,dk,d;
00182 mdp_complex dc,u0,u1,u2,u3;
00183 mdp_matrix B(nc,nc);
00184 mdp_matrix C(nc,nc);
00185 mdp_matrix S(nc,nc);
00186
00187 C=M;
00188
00189
00190
00191 for(i=0; i<nc; i++) {
00192 for(j=0; j<i; j++) {
00193 dc=0;
00194 for(k=0; k<nc; k++)
00195 dc+=conj(C(k,j))*C(k,i);
00196 for(k=0; k<nc; k++)
00197 C(k,i)-=dc*C(k,j);
00198 }
00199 d=0;
00200 for(k=0; k<nc; k++)
00201 d+=pow((double)abs(C(k,i)),(double)2.0);
00202 d=sqrt(d);
00203 for(k=0; k<nc; k++)
00204 C(k,i)/=d;
00205 }
00206
00207
00208
00209 for(i=0; i<nc; i++)
00210 for(j=0; j<nc; j++)
00211 for(k=0; k<nc; k++)
00212 B(i,j)+=conj(M(k,i))*C(k,j);
00213 for(step=0; step<nstep; step++) {
00214 for(i=0; i<nc-1; i++)
00215 for(j=i+1; j<nc; j++) {
00216 e0=real(B(i,i))+real(B(j,j));
00217 e1=imag(B(i,j))+imag(B(j,i));
00218 e2=real(B(i,j))-real(B(j,i));
00219 e3=imag(B(i,i))-imag(B(j,j));
00220 dk=sqrt(e0*e0+e1*e1+e2*e2+e3*e3);
00221 u0=mdp_complex(e0,-e3)/dk;
00222 u1=mdp_complex(e2,-e1)/dk;
00223 u2=mdp_complex(-e2,-e1)/dk;
00224 u3=mdp_complex(e0,e3)/dk;
00225
00226 for(k=0; k<nc; k++) {
00227 S(k,i)=C(k,i)*u0+C(k,j)*u1;
00228 S(k,j)=C(k,i)*u2+C(k,j)*u3;
00229 }
00230 if((i==nc-2) && (j==nc-1))
00231 for(k=0; k<nc; k++)
00232 for(l=0; l<nc-2; l++)
00233 S(k,l)=C(k,l);
00234 if((i!=nc-2) || (j!=nc-1) || (step!=nstep-1))
00235 for(k=0; k<nc; k++) {
00236 C(k,i)=B(k,i)*u0+B(k,j)*u1;
00237 C(k,j)=B(k,i)*u2+B(k,j)*u3;
00238 B(k,i)=C(k,i);
00239 B(k,j)=C(k,j);
00240 C(k,i)=S(k,i);
00241 C(k,j)=S(k,j);
00242 }
00243 }
00244 }
00245 return S;
00246 }
00247
00259 mdp_complex average_path(gauge_field &U, int length, int d[][2]) {
00260 mdp_matrix_field psi1(U.lattice(),U.nc,U.nc);
00261 mdp_matrix_field psi2(U.lattice(),U.nc,U.nc);
00262 mdp_site x(U.lattice());
00263 mdp_complex sum=0;
00264 for(int i=0; i<length; i++) {
00265 if(i==0)
00266 forallsites(x)
00267 psi1(x)=U(x,d[i][0],d[i][1]);
00268 else
00269 forallsites(x)
00270 psi1(x)=psi1(x)*U(x,d[i][0],d[i][1]);
00271 if(i<length-1) {
00272 psi1.update();
00273 if(d[i][0]==+1)
00274 forallsites(x) psi2(x)=psi1(x+d[i][1]);
00275 else if(d[i][0]==-1)
00276 forallsites(x) psi2(x)=psi1(x-d[i][1]);
00277 psi1=psi2;
00278 }
00279 }
00280 forallsites(x) sum+=trace(psi1(x));
00281 return sum/(U.lattice().nvol_gl*U.nc);
00282 }
00283
00296 mdp_matrix build_path(gauge_field &U, site x, int length, int d[][2]) {
00297 int nc=U.nc;
00298 site y(U.lattice());
00299 mdp_matrix tmp(nc,nc);
00300 tmp=U(x,d[0][0],d[0][1]);
00301 if(d[0][0]<0) y=x-d[0][1];
00302 else y=x+d[0][1];
00303 for(int i=1; i<length; i++) {
00304 tmp=tmp*U(y,d[i][0],d[i][1]);
00305 if(d[i][0]<0) y=y-d[i][1];
00306 else y=y+d[i][1];
00307 }
00308 return tmp;
00309 }
00310
00311 void copy_path(int length, int d[][2], int c[][2]) {
00312 for(int i=0; i<length; i++) {
00313 c[i][0]=d[i][0];
00314 c[i][1]=d[i][1];
00315 }
00316 }
00317
00318 void invert_path(int mu, int length, int d[][2]) {
00319 for(int i=0; i<length; i++)
00320 if(d[i][1]==mu) d[i][0]*=-1;
00321 }
00322
00323 void rotate_path(int angle, int mu, int nu, int length, int d[][2]) {
00324 angle=(angle+360)% 360;
00325 if(angle==90)
00326 for(int i=0; i<length; i++) {
00327 if(d[i][1]==mu) d[i][1]=nu;
00328 if(d[i][1]==nu) { d[i][0]*=-1; d[i][1]=mu;}
00329 }
00330 if(angle==180)
00331 for(int i=0; i<length; i++) {
00332 if(d[i][1]==mu) d[i][0]*=-1;
00333 if(d[i][1]==nu) d[i][0]*=-1;
00334 }
00335 if(angle==270)
00336 for(int i=0; i<length; i++) {
00337 if(d[i][1]==mu) {d[i][0]*=-1; d[i][1]=nu; }
00338 if(d[i][1]==nu) d[i][1]=mu;
00339 }
00340 }
00341