/* do measurements: load density, ploop, etc. and phases onto lattice */ void measure() { register int i,j,k, c, is_even; register site *s; int dx,dy,dz; /* separation for correlated observables */ int dir; /* direction of separation */ msg_tag *tag; register complex cc,dd; /*scratch*/ complex ztr, zcof, znum, zdet, TC, zd, density, zphase; complex p[4]; /* probabilities of n quarks at a site */ complex np[4]; /* probabilities at neighbor site */ complex pp[4][4]; /* joint probabilities of n here and m there */ complex zplp, plp_even, plp_odd; Real locphase, phase; /* First make T (= timelike P-loop) from s->ploop_t T stored in s->tempmat1 */ ploop_less_slice(nt-1,EVEN); ploop_less_slice(nt-1,ODD); phase = 0.; density = plp_even = plp_odd = cmplx(0.0, 0.0); for(j=0;j<4;j++){ p[j]=cmplx(0.0,0.0); for(k=0;k<4;k++)pp[j][k]=cmplx(0.0,0.0); } FORALLSITES(i,s) { if(s->t != nt-1) continue; if( ((s->x+s->y+s->z)&0x1)==0 ) is_even=1; else is_even=0; mult_su3_nn(&(s->link[TUP]), &(s->ploop_t), &(s->tempmat1)); zplp = trace_su3(&(s->tempmat1)); if( is_even){CSUM(plp_even, zplp)} else {CSUM(plp_odd, zplp)} ztr = trace_su3(&(s->tempmat1)); CONJG(ztr, zcof); if(is_even){ for(c=0; c<3; ++c) s->tempmat1.e[c][c].real += C; zdet = det_su3(&(s->tempmat1)); znum = numer(C, ztr, zcof); CDIV(znum, zdet, zd); CSUM(density, zd); /* store n_quark probabilities at this site in lattice variable qprob[], accumulate sum over lattice in p[] */ cc= cmplx(C*C*C,0.0); CDIV(cc,zdet,s->qprob[0]); CSUM(p[0],s->qprob[0]); CMULREAL(ztr,C*C,cc); CDIV(cc,zdet,s->qprob[1]); CSUM(p[1],s->qprob[1]); CMULREAL(zcof,C,cc); CDIV(cc,zdet,s->qprob[2]); CSUM(p[2],s->qprob[2]); cc = cmplx(1.0,0.0); CDIV(cc,zdet,s->qprob[3]); CSUM(p[3],s->qprob[3]); locphase = carg(&zdet); phase += locphase; } }
/****************************************************************************** FUNCTION: check_unitarity ******************************************************************************/ void check_unitarity(su2_matrix *psub) { complex sum; complex conj; complex prod; Real tol; tol = 0.0001; sum.real = 0.0; sum.imag = 0.0; CONJG(psub->e[0][0], conj); CMUL(psub->e[0][0], conj, prod); CSUM(sum, prod); CONJG(psub->e[1][0], conj); CMUL(psub->e[1][0], conj, prod); CSUM(sum, prod); if (sum.real < 1.0 - tol || sum.real > 1.0 + tol || sum.imag < -tol || sum.imag > tol) { printf("%g\t%g\n", sum.real, sum.imag); } }
/* adjoint matrix times vector multiply */ void mult_adj_su3_mat_vec( su3_matrix *a, su3_vector *b, su3_vector *c ){ register int i,j; register complex x,y,z; for(i=0;i<3;i++){ x.real=x.imag=0.0; for(j=0;j<3;j++){ CONJG( a->e[j][i], z ); CMUL( z , b->c[j], y ) CSUM( x , y ); } c->c[i] = x; } }
void accum_gauge_hit(int gauge_dir,int parity) { /* Accumulates sums and differences of link matrices for determining optimum */ /* hit for gauge fixing */ /* Differences are kept in diffmat and the diagonal elements of the sums */ /* in sumvec */ register int j; register complex *m1,*m2; register complex temp; register int dir,i; register site *s; /* Clear sumvec and diffmat */ FORSOMEPARITY(i,s,parity) { //diffmatp[i].real = diffmatp[i].imag = 0.; sumvecp[i].real = sumvecp[i].imag = 0.; //clear_su3mat(&diffmatp[i]); //clearvec(&sumvecp[i]); } /* Subtract upward link contributions */ FORSOMEPARITY(i,s,parity) { //FORALLUPDIRBUT(gauge_dir,dir) //{ /* Upward link matrix */ m1 = &(s->link[TUP]); CONJG(*m1, temp); //CSUB(diffmatp[i], *m1, diffmatp[i]); CSUM(sumvecp[i], temp); //sub_su3_matrix( &diffmatp[i], m1, &diffmatp[i]); //for(j=0;j<3;j++)CSUM( sumvecp[i].c[j],m1->e[j][j]); // } }
void meson_cont_mom(complex prop[], field_offset src1,field_offset src2, int base_pt, int q_stride, int op_stride, gamma_corr gamma_table[], int no_gamma_corr) { register int i; register site *s; double theta ; double factx = 2.0*PI/(1.0*nx) ; double facty = 2.0*PI/(1.0*ny) ; double factz = 2.0*PI/(1.0*nz) ; Real px,py,pz; complex phase_fact ; int my_t; int cf, sf, si; int i_gamma_corr,q_pt,prop_pt; complex g1,g2; spin_wilson_vector localmat,localmat2; /* temporary storage */ spin_wilson_vector quark; /* temporary storage for quark */ spin_wilson_vector antiquark; /* temporary storage for antiquark */ FORALLSITES(i,s) { my_t = s->t; /* copy src2 into quark */ for(si=0;si<4;si++) for(sf=0;sf<4;sf++) for(cf=0;cf<3;cf++) { quark.d[si].d[sf].c[cf] = ((spin_wilson_vector *)F_PT(s,src2))->d[si].d[sf].c[cf]; } /* next, construct antiquark from src1 */ /*first, dirac multiplication by the source gamma matrices (on left) */ /* antiquark = c.c. of quark propagator */ for(si=0;si<4;si++) for(sf=0;sf<4;sf++) for(cf=0;cf<3;cf++) { CONJG(((spin_wilson_vector *)F_PT(s,src1))->d[si].d[sf].c[cf], antiquark.d[sf].d[si].c[cf]); } /* left multiply antiquark by source gamma matrices, beginning with gamma_5 for quark -> antiquark */ mult_sw_by_gamma_l( &antiquark, &localmat, G5); /* right dirac multiplication by gamma-5 (finishing up antiquark) */ mult_sw_by_gamma_r( &localmat, &antiquark, G5); /* Run through the table of source-sink gamma matrices */ for(i_gamma_corr=0; i_gamma_corr<no_gamma_corr; i_gamma_corr++) { /* left multiply by the particular source dirac matrices */ /* result in localmat2 */ mult_sw_by_gamma_l( &antiquark, &localmat, gamma_table[i_gamma_corr].gin); mult_sw_by_gamma_r( &localmat, &localmat2, gamma_table[i_gamma_corr].gout); /* Run through all sink momenta */ for(q_pt=0; q_pt<no_q_values; q_pt++) { px = q_momstore[q_pt][0]; py = q_momstore[q_pt][1]; pz = q_momstore[q_pt][2]; theta = factx*(s->x)*px + facty*(s->y)*py + factz*(s->z)*pz; phase_fact = cmplx((Real) cos(theta) , (Real) sin(theta)) ; prop_pt = my_t + base_pt + q_pt * q_stride + i_gamma_corr * op_stride; /* trace over propagators */ for(si=0;si<4;si++) for(sf=0;sf<4;sf++) for(cf=0;cf<3;cf++) { g1 = localmat2.d[si].d[sf].c[cf]; CMUL( quark.d[sf].d[si].c[cf] , phase_fact, g2); prop[prop_pt ].real += (g1.real*g2.real - g1.imag*g2.imag); prop[prop_pt ].imag += (g1.real*g2.imag + g1.imag*g2.real); } } } } /**** end of the loop over lattice sites ******/
/* do measurements: load density, ploop, etc. and phases onto lattice */ void measure() { register int i,j,k, c; register site *s; int dx,dy,dz; /* separation for correlated observables */ int dir; /* direction of separation */ msg_tag *tag; register complex cc,dd; /*scratch*/ complex ztr, zcof, znum, zdet, TC, zd, density, zphase; complex p[4]; /* probabilities of n quarks at a site */ complex np[4]; /* probabilities at neighbor site */ complex pp[4][4]; /* joint probabilities of n here and m there */ complex zplp, plp; Real locphase, phase; /* First make T (= timelike P-loop) from s->ploop_t T stored in s->tempmat1 */ ploop_less_slice(nt-1,EVEN); ploop_less_slice(nt-1,ODD); phase = 0.; density = plp = cmplx(0.0, 0.0); for(j=0;j<4;j++){ p[j]=cmplx(0.0,0.0); for(k=0;k<4;k++)pp[j][k]=cmplx(0.0,0.0); } FORALLSITES(i,s) { if(s->t != nt-1) continue; mult_su3_nn(&(s->link[TUP]), &(s->ploop_t), &(s->tempmat1)); zplp = trace_su3(&(s->tempmat1)); CSUM(plp, zplp); ztr = trace_su3(&(s->tempmat1)); CONJG(ztr, zcof); for(c=0; c<3; ++c) s->tempmat1.e[c][c].real += C; zdet = det_su3(&(s->tempmat1)); znum = numer(C, ztr, zcof); CDIV(znum, zdet, zd); CSUM(density, zd); /* store n_quark probabilities at this site in lattice variable qprob[], accumulate sum over lattice in p[] */ cc = cmplx(C*C*C,0.0); CDIV(cc,zdet,s->qprob[0]); CSUM(p[0],s->qprob[0]); CMULREAL(ztr,C*C,cc); CDIV(cc,zdet,s->qprob[1]); CSUM(p[1],s->qprob[1]); CMULREAL(zcof,C,cc); CDIV(cc,zdet,s->qprob[2]); CSUM(p[2],s->qprob[2]); cc = cmplx(1.0,0.0); CDIV(cc,zdet,s->qprob[3]); CSUM(p[3],s->qprob[3]); locphase = carg(&zdet); phase += locphase; } g_floatsum( &phase ); g_complexsum( &density ); g_complexsum( &p[0] ); g_complexsum( &p[1] ); g_complexsum( &p[2] ); g_complexsum( &p[3] ); g_complexsum( &plp ); CDIVREAL(density,(Real)(nx*ny*nz),density); CDIVREAL(p[0],(Real)(nx*ny*nz),p[0]); CDIVREAL(p[1],(Real)(nx*ny*nz),p[1]); CDIVREAL(p[2],(Real)(nx*ny*nz),p[2]); CDIVREAL(p[3],(Real)(nx*ny*nz),p[3]); CDIVREAL(plp,(Real)(nx*ny*nz),plp); zphase = ce_itheta(phase); if(this_node == 0) { printf("ZMES\t%e\t%e\t%e\t%e\t%e\t%e\n", zphase.real, zphase.imag, density.real, density.imag, plp.real, plp.imag); printf("PMES\t%e\t%e\t%e\t%e\t%e\t%e\t%e\t%e\n", p[0].real, p[0].imag, p[1].real, p[1].imag, p[2].real, p[2].imag, p[3].real, p[3].imag ); } #ifdef PPCORR dx=1; dy=0; dz=0; /* Temporary - right now we just do nearest neighbor */ for(dir=XUP;dir<=ZUP;dir++){ tag = start_gather_site( F_OFFSET(qprob[0]), 4*sizeof(complex), dir, EVENANDODD, gen_pt[0] ); wait_gather(tag); FORALLSITES(i,s)if(s->t==nt-1){ for(j=0;j<4;j++)for(k=0;k<4;k++){ CMUL( (s->qprob)[j],((complex *)gen_pt[0][i])[k],cc); CSUM(pp[j][k],cc); } } cleanup_gather(tag); } /* density correlation format: PP dx dy dz n1 n2 real imag */ for(j=0;j<4;j++)for(k=0;k<4;k++){ g_complexsum( &pp[j][k] ); CDIVREAL(pp[j][k],(Real)(3*nx*ny*nz),pp[j][k]); if(this_node==0) printf("PP %d %d %d %d %d %e %e\n",dx,dy,dz,j,k, pp[j][k].real,pp[j][k].imag); } #endif /*PPCORR*/ }
void meson_cont_p(field_offset src1,field_offset src2, int *gamma_in,int *gamma_out,int n_in,int n_out, Real prop[MAX_P][MAX_NT]) /* src1 and src2 are type spin_wilson_vector */ { register int i,t; register site *s; int my_t,j; int cf, sf, si; int i_in,i_out; complex g1,g2; /* for nonzero momentum */ Real cx,cy,cz,cxy,cyz,cxz,c111; spin_wilson_vector localmat; /* temporary storage for quark */ spin_wilson_vector quark; /* temporary storage for quark */ spin_wilson_vector antiquark; /* temporary storage for antiquark */ void mult_by_gamma_l( spin_wilson_vector *src, spin_wilson_vector *dest, int dir); void mult_by_gamma_r( spin_wilson_vector *src, spin_wilson_vector *dest, int dir); FORALLSITES(i,s) { my_t = s->t; /*first, dirac multiplication by the source gamma matrices (on left) */ /* antiquark = c.c. of quark propagator */ for(si=0; si<4; si++) for(sf=0; sf<4; sf++) for(cf=0; cf<3; cf++) { CONJG(((spin_wilson_vector *)F_PT(s,src1))->d[si].d[sf].c[cf], antiquark.d[si].d[sf].c[cf]); } /* left multiply antiquark by source gamma matrices, beginning with gamma_5 for quark -> antiquark */ mult_by_gamma_l( &antiquark, &localmat, GAMMAFIVE); /* right dirac multiplication by gamma-5 (finishing up antiquark) */ mult_by_gamma_r( &localmat, &antiquark, GAMMAFIVE); /* left multiply by the particular source dirac matrices */ for(i_in=0; i_in<n_in; i_in++) { mult_by_gamma_l( &antiquark, &localmat, gamma_in[i_in]); antiquark = localmat; } /* right dirac multiplication by the sink gamma matrices */ for(i_out=0; i_out<n_out; i_out++) { mult_by_gamma_r( &antiquark, &localmat, gamma_out[i_out]); antiquark = localmat; } /* copy into quark */ /* 2/27/98 Simplify and avoid bug in Origin compiler UMH */ quark = *(spin_wilson_vector *)F_PT(s,src2); /* trace over propagators */ for(si=0; si<4; si++) for(sf=0; sf<4; sf++) for(cf=0; cf<3; cf++) { g1 = antiquark.d[si].d[sf].c[cf]; g2 = quark.d[si].d[sf].c[cf]; for(j=0; j<3; j++) { cz=cos(2.0*PI/(Real)nz*(Real)(s->z)*(Real)j); cx=cos(2.0*PI/(Real)nx*(Real)(s->x)*(Real)j); cy=cos(2.0*PI/(Real)ny*(Real)(s->y)*(Real)j); prop[j][my_t] += (g1.real*g2.real - g1.imag*g2.imag)* (cx+cy+cz)/3.0; } cxy=cos(2.0*PI/(Real)nz*(Real)(s->x +s->y)); cxz=cos(2.0*PI/(Real)nz*(Real)(s->x +s->z)); cyz=cos(2.0*PI/(Real)nz*(Real)(s->y +s->z)); c111=cos(2.0*PI/(Real)nz*(Real)(s->x +s->y + s->z)); prop[3][my_t] += (g1.real*g2.real - g1.imag*g2.imag)* (cxy+cyz+cxz)/3.0; prop[4][my_t] += (g1.real*g2.real -g1.imag*g2.imag)* c111; } }
/* Hadron wave functions. */ void wavefunc_t() { register int i,j,n; register site *s; register complex cc; msg_tag *tag; Real finalrsq,scale,x; int tmin,tmax,cgn,color; /* for baryon code */ int ca,ca1,ca2,cb,cb1,cb2; void symmetry_combine(field_offset src,field_offset space,int size,int dir); void block_fourier( field_offset src, /* src is field to be transformed */ field_offset space, /* space is working space, same size as src */ int size, /* Size of field in bytes. The field must consist of size/sizeof(complex) consecutive complex numbers. For example, an su3_vector is 3 complex numbers. */ int isign); /* 1 for x -> k, -1 for k -> x */ void fourier( field_offset src, /* src is field to be transformed */ field_offset space, /* space is working space, same size as src */ int size, /* Size of field in bytes. The field must consist of size/sizeof(complex) consecutive complex numbers. For example, an su3_vector is 3 complex numbers. */ int isign); /* 1 for x -> k, -1 for k -> x */ void write_wf(field_offset src,char *string,int tmin,int tmax); /* Fix TUP Coulomb gauge - gauge links only*/ rephase( OFF ); gaugefix(TUP,(Real)1.8,500,(Real)GAUGE_FIX_TOL); rephase( ON ); for(color=0;color<3;color++){ /* Make wall source */ FORALLSITES(i,s){ for(j=0;j<3;j++)s->phi.c[j]=cmplx(0.0,0.0); if( s->x%2==0 && s->y%2==0 && s->z%2==0 && s->t==0 ){ s->phi.c[color] = cmplx(-1.0,0.0); } } /* do a C.G. (source in phi, result in xxx) */ load_ferm_links(&fn_links); cgn = ks_congrad(F_OFFSET(phi),F_OFFSET(xxx),mass, niter, rsqprop, PRECISION, EVEN, &finalrsq, &fn_links); /* Multiply by -Madjoint, result in propmat[color] */ dslash_site( F_OFFSET(xxx), F_OFFSET(propmat[color]), ODD, &fn_links); scalar_mult_latvec( F_OFFSET(xxx), (Real)(-2.0*mass), F_OFFSET(propmat[color]), EVEN); } /* construct the diquark propagator--uses tempmat1 and do this before you fft the quark propagator */ FORALLSITES(i,s){ for(ca=0;ca<3;ca++)for(cb=0;cb<3;cb++){ ca1= (ca+1)%3; ca2= (ca+2)%3; cb1= (cb+1)%3; cb2= (cb+2)%3; CMUL((s->propmat[ca1].c[cb1]),(s->propmat[ca2].c[cb2]), (s->tempmat1.e[ca][cb])); CMUL((s->propmat[ca1].c[cb2]),(s->propmat[ca2].c[cb1]), cc); CSUB((s->tempmat1.e[ca][cb]),cc,(s->tempmat1.e[ca][cb])); } } /* complex conjugate the diquark prop */ FORALLSITES(i,s){ for(ca=0;ca<3;ca++)for(cb=0;cb<3;cb++){ CONJG((s->tempmat1.e[ca][cb]),(s->tempmat1.e[ca][cb])); } } /* Transform the diquark propagator. */ block_fourier( F_OFFSET(tempmat1), F_OFFSET(tempvec[0]), 3*sizeof(su3_vector), FORWARDS); /* complex conjugate the diquark prop. Now we have D(-k) for convolution */ FORALLSITES(i,s){ for(ca=0;ca<3;ca++)for(cb=0;cb<3;cb++){ CONJG((s->tempmat1.e[ca][cb]),(s->tempmat1.e[ca][cb])); } } /* Transform the propagator. */ block_fourier( F_OFFSET(propmat[0]), F_OFFSET(tempvec[0]), 3*sizeof(su3_vector), FORWARDS); /* CODE SPECIFIC TO PARTICULAR PARTICLES */ /* MESON CODE */ /* Square the result, component by component, sum over source and sink colors, result in ttt.c[0] */ FORALLSITES(i,s){ s->ttt.c[0].real = s->ttt.c[0].imag = 0.0; for(color=0;color<3;color++){ s->ttt.c[0].real += magsq_su3vec( &(s->propmat[color]) ); } }
/* adjoint of an SU3 matrix */ void su3_adjoint( su3_matrix *a, su3_matrix *b ){ register int i,j; for(i=0;i<3;i++)for(j=0;j<3;j++){ CONJG( a->e[j][i], b->e[i][j] ); } }