void bj_to_weyl(wilson_vector * src, wilson_vector * dest) { register int i; /* color */ complex z1, z2; Real sqrt2inv; sqrt2inv = (Real) (1./ (sqrt(2.))); for (i = 0; i < 3; i++) { CSUB(src->d[3].c[i], src->d[1].c[i], z1); TIMESPLUSI(z1, z2); CMULREAL(z2, sqrt2inv, dest->d[0].c[i]); CSUB(src->d[0].c[i], src->d[2].c[i], z1); TIMESPLUSI(z1, z2); CMULREAL(z2, sqrt2inv, dest->d[1].c[i]); CADD(src->d[3].c[i], src->d[1].c[i], z1); TIMESMINUSI(z1, z2); CMULREAL(z2, sqrt2inv, dest->d[2].c[i]); CADD(src->d[0].c[i], src->d[2].c[i], z1); TIMESPLUSI(z1, z2); CMULREAL(z2, sqrt2inv, dest->d[3].c[i]); } }
/* 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; } }
complex numer(Real c, complex T, complex cof) { complex z1, z2; CMULREAL(T, c*c, z1); CMULREAL(cof, 2.*c, z2); CSUM(z1,z2); z1.real += 3.; return(z1); }
/* Make traceless */ FORALLSITES(i,s){ cc = trace_su3(&FIELD_STRENGTH(component)); CMULREAL(cc,0.33333333333333333,cc); for(j=0;j<3;j++) CSUB(FIELD_STRENGTH(component).e[j][j],cc, FIELD_STRENGTH(component).e[j][j]); }
void reunitarize() { register su3_matrix *mat; register int i,dir; register site *s; int errcount = 0; int errors; max_deviation = 0.; av_deviation = 0.; FORALLSITES(i,s){ #ifdef SCHROED_FUN for(dir=XUP; dir<=TUP; dir++ ) if(dir==TUP || s->t>0 ){ #else for(dir=XUP; dir<=TUP; dir++ ){ #endif mat = (su3_matrix *)&(s->link[dir]); errors = reunit_su3( mat ); errcount += errors; if(errors)reunit_report_problem_matrix(mat,i,dir); if(errcount > MAXERRCOUNT) { printf("Unitarity error count exceeded.\n"); terminate(1); } } } #ifdef UNIDEBUG printf("Deviation from unitarity on node %d: max %.3e, avrg %.3e\n", mynode(), max_deviation, av_deviation); #endif if(max_deviation> TOLERANCE) { printf("reunitarize: Node %d unitarity problem, maximum deviation=%e\n", mynode(),max_deviation); errcount++; if(errcount > MAXERRCOUNT) { printf("Unitarity error count exceeded.\n"); terminate(1); } } } /* reunitarize2 */ void reunitarize_u1() { register complex *mat; register int i,dir; register site *s; double norm; double deviation; int errcount = 0; int errors; max_deviation = 0.; av_deviation = 0.; FORALLSITES(i,s){ #ifdef SCHROED_FUN for(dir=XUP; dir<=TUP; dir++ ) if(dir==TUP || s->t>0 ){ #else for(dir=XUP; dir<=TUP; dir++ ){ #endif mat = (complex *)&(s->link[dir]); //reunitarize link norm = (double)cabs( mat ); CMULREAL( *mat, 1./norm, *mat ); //deviation = fabs(norm - 1.); deviation = fabs(norm*norm - 1.); errors = check_deviation(deviation); errcount += errors; if(errors){ reunit_report_problem_u1(mat,i,dir); printf("deviation = %e, tol = %e\n", deviation, TOLERANCE); } if(errcount > MAXERRCOUNT) { printf("Unitarity error count exceeded.\n"); terminate(1); } } } #ifdef UNIDEBUG printf("Deviation from unitarity on node %d: max %.3e, avrg %.3e\n", mynode(), max_deviation, av_deviation); #endif if(max_deviation> TOLERANCE) { printf("reunitarize: Node %d unitarity problem, maximum deviation=%e\n", mynode(),max_deviation); errcount++; if(errcount > MAXERRCOUNT) { printf("Unitarity error count exceeded.\n"); terminate(1); } } } /* reunitarize_u1 */
/* 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 setup_lambda() { int i, j, k, l, count; complex inv_sqrt = cmplx(1.0 / sqrt(2.0), 0.0); complex i_inv_sqrt = cmplx(0.0, 1.0 / sqrt(2.0)); #ifdef DEBUG_CHECK int a; complex trace, tt; node0_printf("Computing generators for U(N)\n"); #endif // Make sure Lambda matrices are initialized for (i = 0; i < DIMF; i++) clear_mat(&(Lambda[i])); // N * (N - 1) off-diagonal SU(N) generators // (T^{ij, +})_{kl} = i * (de_{ki} de_{lj} + de_{kj} de_{li}) / sqrt(2) // (T^{ij, -})_{kl} = (de_{ki} de_{lj} - de_{kj} de_{ki}) / sqrt(2) // Sign in second chosen to match previous values count = 0; for (i = 0; i < NCOL; i++) { for (j = i + 1; j < NCOL; j++) { for (k = 0; k < NCOL; k++) { for (l = 0; l < NCOL; l++) { if (k == i && l == j) { CSUM(Lambda[count].e[k][l], i_inv_sqrt); CSUM(Lambda[count + 1].e[k][l], inv_sqrt); } else if (k == j && l == i) { CSUM(Lambda[count].e[k][l], i_inv_sqrt); CDIF(Lambda[count + 1].e[k][l], inv_sqrt); } } } count += 2; } } if (count != NCOL * (NCOL - 1)) { node0_printf("ERROR: Wrong number of off-diagonal generators, "); node0_printf("%d vs. %d\n", count, NCOL * (NCOL - 1)); terminate(1); } // N - 1 diagonal SU(N) generators // T^k = i * diag(1, 1, ..., -k, 0, ..., 0) / sqrt(k * (k + 1)) for (i = 0; i < NCOL - 1; i++) { j = NCOL * (NCOL - 1) + i; // Index after +/- above k = i + 1; i_inv_sqrt = cmplx(0.0, 1.0 / sqrt(k * (k + 1.0))); for (l = 0; l <= k; l++) Lambda[j].e[l][l] = i_inv_sqrt; CMULREAL(Lambda[j].e[k][k], -1.0 * k, Lambda[j].e[k][k]); } // U(1) generator i * I_N / sqrt(N) if (DIMF == NCOL * NCOL) { // Allow SU(N) compilation for now i_inv_sqrt = cmplx(0.0, sqrt(one_ov_N)); clear_mat(&(Lambda[DIMF - 1])); for (i = 0; i < NCOL; i++) Lambda[DIMF - 1].e[i][i] = i_inv_sqrt; } #ifdef DEBUG_CHECK // Print Lambdas for (i = 0; i < DIMF; i++){ node0_printf("Lambda[%d]\n",i); if (this_node == 0) dumpmat(&(Lambda[i])); } // Test group theory node0_printf("Check group theory "); node0_printf("Sum_a Lambda^a_{kl} Lambda^a_{ij} = -delta_kj delta_il\n"); for (i = 0; i < NCOL; i++) { for (j = 0; j < NCOL; j++) { for (k = 0; k < NCOL; k++) { for (l = 0; l < NCOL; l++) { trace = cmplx(0, 0); for (a = 0; a < DIMF; a++) { CMUL(Lambda[a].e[k][l], Lambda[a].e[i][j], tt); CSUM(trace, tt); } if (cabs_sq(&trace) > IMAG_TOL) node0_printf("Sum_a La^a_{%d%d} La^a_{%d%d} = (%.4g, %.4g)\n", k, j, i, l, trace.real, trace.imag); } } } } #endif // Test orthogonality and compute products of Lambdas for fermion forces #ifdef DEBUG_CHECK for (i = 0; i < DIMF; i++) { for (j = 0; j < DIMF; j++) { mult_nn(&(Lambda[i]), &(Lambda[j]), &tmat); trace = trace(&tmat); if (trace.real * trace.real > IMAG_TOL) node0_printf("Tr[T_%d T_%d] = (%.4g, %.4g)\n", i, j, trace.real, trace.imag); } } #endif }
static double dirac_v_tr_gamma(complex *tr, dirac_matrix_v *src, int gamma, int phase[], Real factor[], int ct[], int nc, int p_index[]) { int s2,s; /* spin indices */ int k, c, p, ph; complex z = {0.,0.}; Real fact; double flops = 0; /* One value for each momentum */ for(k=0; k<nc; k++) tr[k].real = tr[k].imag = 0; /* For each momentum in list, multiply by gamma and take trace */ for(s=0;s<4;s++){ s2 = gamma_mat(gamma).row[s].column; switch (gamma_mat(gamma).row[s].phase){ case 0: for(k=0; k<nc; k++){ c = ct[k]; p = p_index[c]; z = src->d[s2].d[s].e[p]; CSUM(tr[k],z); } break; case 1: for(k=0; k<nc; k++){ c = ct[k]; p = p_index[c]; TIMESPLUSI( src->d[s2].d[s].e[p], z); CSUM(tr[k],z); } break; case 2: for(k=0; k<nc; k++){ c = ct[k]; p = p_index[c]; TIMESMINUSONE( src->d[s2].d[s].e[p], z); CSUM(tr[k],z); } break; case 3: for(k=0; k<nc; k++){ c = ct[k]; p = p_index[c]; TIMESMINUSI( src->d[s2].d[s].e[p], z); CSUM(tr[k],z); } } } /* Normalization and phase */ for(k=0; k<nc; k++){ c = ct[k]; ph = phase[c]; fact = factor[c]; switch(ph){ case 0: z = tr[k]; break; case 1: TIMESPLUSI( tr[k], z); break; case 2: TIMESMINUSONE( tr[k], z); break; case 3: TIMESMINUSI( tr[k], z); } CMULREAL(z,fact,tr[k]); } flops = 4*nc; return flops; } /* dirac_v_tr_gamma */
int congrad_xxx( field_offset src, /* type wilson_vector (where source is to be created)*/ Real cgmass, /* unused here*/ int source_chirality /* chirality sector for inversion (NOT USED) */ ) { register int i; register site *s; int j,k, avs_iters, avm_iters,status,flag; int MaxCG; int ksource, spin,color,my_chirality,chb,che,chbo,cheo,ii,jj; Real *RsdCG; Real size_r,one_minus_m,r02inv; wilson_vector **psim; void setup_multi(); w_prop_file *fp_out_w[MAX_MASSES]; /* For propagator files */ w_prop_file *fp_in_w[MAX_MASSES]; /* For propagator files */ w_prop_file *h0_out_w[MAX_MASSES]; /* For intermediate propagator files */ #ifdef EIGO wilson_vector wproj; complex ctmp,cd,*cproj; int l; int icount, ivec; int *chiral_check; Real cdp, cdm; Real *ca, *cb; Real eps, mu, denom; #endif double source_norm; RsdCG=resid; MaxCG=niter; avs_iters=0; r02inv= -0.5/R0; #ifdef MINN do_minn=1; #endif setup_multi(); #ifdef EIGO if(Nvecs_hov != 0)cproj = (complex *)malloc(Nvecs_hov*sizeof(complex)); /* check chirality of your modes (to identify zero modes) */ if(Nvecs_hov != 0)chiral_check= (int *)malloc(Nvecs_hov*sizeof(int)); for(j=0;j<Nvecs_hov;j++){ cdp=0.0; cdm=0.0; FORALLSITES(i,s){ for(l=0;l<2;l++)for(k=0;k<3;k++){ cdp += cabs_sq(&(eigVec[j][i].d[l].c[k])); } for(l=2;l<4;l++)for(k=0;k<3;k++){ cdm += cabs_sq(&(eigVec[j][i].d[l].c[k])); } } g_floatsum(&cdp); g_floatsum(&cdm); if(cdm< 1.e-6 && cdp >1.e-6) chiral_check[j] =1; else if (cdm >1.e-6 && cdp < 1.e-6) chiral_check[j] = -1; else if (cdm >1.e-6 && cdp > 1.e-6) chiral_check[j] =0; else{ node0_printf("eigVec0[%d] is a null vector!\n",j); exit(1); } } /* the mode propagator matrix */ /* I am stupid--how to do this in a 2-d array?? */ if(Nvecs_hov != 0){ ca= (Real *)malloc(num_masses*Nvecs_hov*sizeof(Real)); cb= (Real *)malloc(num_masses*Nvecs_hov*sizeof(Real)); } /* initialize the coefficients of the propagator matrix for modes */ for(k=0;k<num_masses;k++)for(ivec=0;ivec<Nvecs_hov;ivec++){ icount=Nvecs_hov*k + ivec; if(chiral_check[ivec]==0){ mu=mass[k]/(2.0*R0); eps= sqrt(eigVal[ivec])/(2.0*R0); denom= (mu*mu+eps*eps*(1.0-mu*mu))*2.0*R0; ca[icount]= mu*(1.0-eps*eps)/denom; cb[icount]= eps*sqrt(1.0-eps*eps)/denom; } else{ ca[icount]= 1.0/mass[k]; cb[icount]= 0.0; } node0_printf("mass %e mode %d %d %e %e\n",mass[k],ivec, chiral_check[ivec],ca[icount],cb[icount]); } #endif /* open the prop files */ for(k=0;k<num_masses;k++){ fp_in_w[k] = r_open_wprop(startflag_w[k], startfile_w[k]); fp_out_w[k] = w_open_wprop(saveflag_w[k], savefile_w[k], wqs.type); #ifdef H0INV h0_out_w[k] = w_open_wprop(saveflag_w3[k], savefile_w3[k], wqs.type); #endif } for(ksource = 0; ksource < wqs.nsource; ksource++){ spin = convert_ksource_to_spin(ksource); color = convert_ksource_to_color(ksource); // /* Loop over source spins */ // for(spin=0;spin<4;spin++){ // /* Loop over source colors */ // for(color=0;color<3;color++){ node0_printf("Propagator color %d spin %d\n",color,spin); if(startflag_w[0] == FRESH){flag=0;} else{ /* check if there's a propagator already there--Do for all masses */ flag=1; for(k=0;k<num_masses && flag==1 ;k++){ #ifdef IOTIME status = reload_wprop_sc_to_site( startflag_w[k], fp_in_w[k], &wqs, spin, color, F_OFFSET(psi),1); #else status = reload_wprop_sc_to_site( startflag_w[k], fp_in_w[k], &wqs, spin, color, F_OFFSET(psi),0); #endif if(status != 0){ node0_printf("congrad_outer_p: computing prop\n"); /* reload_wprop_sc_to_site( FRESH, fp_in_w[k], &wqs, spin, color, F_OFFSET(psi),0); */ flag = 0; } else{ /* status = 1--put the propagator in the new output file so all the elements are in one place. This will fail if the propagator generation did not write the same number of elements for each mass value propagator */ #ifdef IOTIME save_wprop_sc_from_site( saveflag_w[k],fp_out_w[k], &wqs, spin,color,F_OFFSET(psi),1); #else save_wprop_sc_from_site( saveflag_w[k],fp_out_w[k], &wqs, spin,color,F_OFFSET(psi),0); #endif } } /* k loop */ } /*startflag_w != FRESH */ if(flag==0){ /* proceed to inversion */ if(spin<2){my_chirality=1;chb=0;che=2;chbo=2;cheo=4;} else {my_chirality= -1;chb=2,che=4;chbo=0;cheo=2;} chirality_flag=my_chirality; /* Make source */ /* Complete the source structure */ /* NEEDS FIXING!! */ // wqs.color = color; // wqs.spin = spin; /* For wilson_info */ wqstmp = wqs; // status = w_source_site(src,&wqs); status = wv_source_site(src,&wqs); /* check original source size... */ source_norm=0.0; FORALLSITES(i,s){ source_norm += (double)magsq_wvec(((wilson_vector *)F_PT(s,src)) ); } g_doublesum( &source_norm ); if(this_node==0){ printf("Original: source_norm = %e\n",source_norm); fflush(stdout); } FORALLSITES(i,s) copy_wvec((wilson_vector *)F_PT(s,src),&(s->chi0)); #ifdef EIGO /* project out the eigenvectors from the source */ node0_printf("removing %d modes from source\n",Nvecs_hov); for(j=0;j<Nvecs_hov;j++){ cd=cmplx(0.0,0.0); FORALLSITES(i,s){ /* wproj will hold the chiral projections-- recall we have ``packed'' two chiralities into eigVec */ clear_wvec(&wproj); for(ii=chb;ii<che;ii++)for(jj=0;jj<3;jj++){ wproj.d[ii].c[jj]=eigVec[j][i].d[ii].c[jj]; } ctmp = wvec_dot( &(wproj),(wilson_vector *)F_PT(s,src)); CSUM(cd,ctmp); } g_complexsum(&cd); cproj[j]=cd; node0_printf("projector %d %e %e\n",j,cproj[j].real,cproj[j].imag); CMULREAL(cd,-1.0,cd); FORALLSITES(i,s){ clear_wvec(&wproj); for(ii=chb;ii<che;ii++)for(jj=0;jj<3;jj++){ wproj.d[ii].c[jj]=eigVec[j][i].d[ii].c[jj]; } c_scalar_mult_add_wvec(&(s->chi0), &(wproj), &cd, &(s->chi0) ); } }